openbot 0.2.12 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.prettierrc +8 -0
  2. package/AGENTS.md +68 -0
  3. package/CONTRIBUTING.md +74 -0
  4. package/LICENSE +21 -0
  5. package/README.md +117 -14
  6. package/dist/agents/system.js +106 -0
  7. package/dist/app/cli.js +27 -0
  8. package/dist/app/config.js +64 -0
  9. package/dist/app/server.js +237 -0
  10. package/dist/app/utils.js +35 -0
  11. package/dist/harness/agent-harness.js +45 -0
  12. package/dist/harness/mcp.js +61 -0
  13. package/dist/harness/orchestrator.js +273 -0
  14. package/dist/harness/process.js +7 -0
  15. package/dist/plugins/ai-sdk.js +141 -0
  16. package/dist/plugins/delegation.js +52 -0
  17. package/dist/plugins/mcp.js +140 -0
  18. package/dist/plugins/storage.js +502 -0
  19. package/dist/plugins/ui.js +47 -0
  20. package/dist/registry/plugins.js +73 -0
  21. package/dist/services/storage.js +724 -0
  22. package/docs/README.md +7 -0
  23. package/docs/agents.md +83 -0
  24. package/docs/architecture.md +34 -0
  25. package/docs/plugins.md +77 -0
  26. package/logo-black.png +0 -0
  27. package/{dist/assets/logo.js → logo-black.svg} +24 -24
  28. package/{dist/ui/sidebar.js → logo-white.svg} +23 -88
  29. package/package.json +10 -9
  30. package/src/agents/system.ts +112 -0
  31. package/src/app/cli.ts +38 -0
  32. package/src/app/config.ts +104 -0
  33. package/src/app/server.ts +284 -0
  34. package/src/app/types.ts +476 -0
  35. package/src/app/utils.ts +43 -0
  36. package/src/assets/icon.svg +1 -0
  37. package/src/harness/agent-harness.ts +58 -0
  38. package/src/harness/mcp.ts +78 -0
  39. package/src/harness/orchestrator.ts +342 -0
  40. package/src/harness/process.ts +9 -0
  41. package/src/harness/types.ts +34 -0
  42. package/src/plugins/ai-sdk.ts +197 -0
  43. package/src/plugins/delegation.ts +60 -0
  44. package/src/plugins/mcp.ts +154 -0
  45. package/src/plugins/storage.ts +725 -0
  46. package/src/plugins/ui.ts +57 -0
  47. package/src/registry/plugins.ts +85 -0
  48. package/src/services/storage.ts +957 -0
  49. package/tsconfig.json +18 -0
  50. package/dist/agents/agent-creator.js +0 -74
  51. package/dist/agents/browser-agent.js +0 -31
  52. package/dist/agents/os-agent.js +0 -32
  53. package/dist/agents/planner-agent.js +0 -32
  54. package/dist/agents/topic-agent.js +0 -46
  55. package/dist/architecture/execution-engine.js +0 -151
  56. package/dist/architecture/intent-classifier.js +0 -26
  57. package/dist/architecture/planner.js +0 -106
  58. package/dist/automation-worker.js +0 -121
  59. package/dist/automations.js +0 -52
  60. package/dist/cli.js +0 -279
  61. package/dist/config.js +0 -53
  62. package/dist/core/agents.js +0 -41
  63. package/dist/core/delegation.js +0 -230
  64. package/dist/core/manager.js +0 -96
  65. package/dist/core/plugins.js +0 -74
  66. package/dist/core/router.js +0 -191
  67. package/dist/handlers/init.js +0 -29
  68. package/dist/handlers/session-change.js +0 -21
  69. package/dist/handlers/settings.js +0 -47
  70. package/dist/handlers/tab-change.js +0 -14
  71. package/dist/installers.js +0 -156
  72. package/dist/marketplace.js +0 -80
  73. package/dist/model-catalog.js +0 -132
  74. package/dist/model-defaults.js +0 -25
  75. package/dist/models.js +0 -47
  76. package/dist/open-bot.js +0 -51
  77. package/dist/orchestrator/direct-invocation.js +0 -13
  78. package/dist/orchestrator/events.js +0 -36
  79. package/dist/orchestrator/state.js +0 -54
  80. package/dist/orchestrator.js +0 -422
  81. package/dist/plugins/agent/index.js +0 -81
  82. package/dist/plugins/approval/index.js +0 -100
  83. package/dist/plugins/brain/identity.js +0 -77
  84. package/dist/plugins/brain/index.js +0 -204
  85. package/dist/plugins/brain/memory.js +0 -120
  86. package/dist/plugins/brain/prompt.js +0 -46
  87. package/dist/plugins/brain/types.js +0 -45
  88. package/dist/plugins/brain/ui.js +0 -7
  89. package/dist/plugins/browser/index.js +0 -629
  90. package/dist/plugins/browser/ui.js +0 -13
  91. package/dist/plugins/file-system/index.js +0 -171
  92. package/dist/plugins/file-system/ui.js +0 -6
  93. package/dist/plugins/llm/context-budget.js +0 -139
  94. package/dist/plugins/llm/context-shaping.js +0 -177
  95. package/dist/plugins/llm/index.js +0 -380
  96. package/dist/plugins/memory/index.js +0 -220
  97. package/dist/plugins/memory/memory.js +0 -122
  98. package/dist/plugins/memory/prompt.js +0 -55
  99. package/dist/plugins/memory/types.js +0 -45
  100. package/dist/plugins/meta-agent/index.js +0 -570
  101. package/dist/plugins/meta-agent/ui.js +0 -11
  102. package/dist/plugins/shell/index.js +0 -100
  103. package/dist/plugins/shell/ui.js +0 -6
  104. package/dist/plugins/skills/index.js +0 -286
  105. package/dist/plugins/skills/types.js +0 -50
  106. package/dist/plugins/skills/ui.js +0 -12
  107. package/dist/registry/agent-registry.js +0 -35
  108. package/dist/registry/index.js +0 -2
  109. package/dist/registry/plugin-loader.js +0 -499
  110. package/dist/registry/plugin-registry.js +0 -44
  111. package/dist/registry/ts-agent-loader.js +0 -82
  112. package/dist/registry/yaml-agent-loader.js +0 -246
  113. package/dist/runtime/execution-trace.js +0 -41
  114. package/dist/runtime/intent-routing.js +0 -26
  115. package/dist/runtime/openbot-runtime.js +0 -354
  116. package/dist/server.js +0 -890
  117. package/dist/session.js +0 -179
  118. package/dist/ui/block.js +0 -12
  119. package/dist/ui/header.js +0 -52
  120. package/dist/ui/layout.js +0 -26
  121. package/dist/ui/navigation.js +0 -15
  122. package/dist/ui/settings.js +0 -106
  123. package/dist/ui/skills.js +0 -7
  124. package/dist/ui/thread.js +0 -16
  125. package/dist/ui/widgets/action-list.js +0 -2
  126. package/dist/ui/widgets/approval-card.js +0 -9
  127. package/dist/ui/widgets/code-snippet.js +0 -2
  128. package/dist/ui/widgets/data-block.js +0 -2
  129. package/dist/ui/widgets/data-table.js +0 -2
  130. package/dist/ui/widgets/delegation.js +0 -29
  131. package/dist/ui/widgets/empty-state.js +0 -2
  132. package/dist/ui/widgets/index.js +0 -23
  133. package/dist/ui/widgets/inquiry.js +0 -7
  134. package/dist/ui/widgets/key-value.js +0 -2
  135. package/dist/ui/widgets/progress-step.js +0 -2
  136. package/dist/ui/widgets/resource-card.js +0 -2
  137. package/dist/ui/widgets/status.js +0 -2
  138. package/dist/ui/widgets/todo-list.js +0 -2
  139. package/dist/version.js +0 -62
  140. /package/dist/{types.js → app/types.js} +0 -0
  141. /package/dist/{architecture/contracts.js → harness/types.js} +0 -0
@@ -1,204 +0,0 @@
1
- import { ui } from "@melony/ui-kit/server";
2
- import * as fs from "node:fs/promises";
3
- import * as path from "node:path";
4
- import { createMemoryModule } from "./memory.js";
5
- import { buildBrainPrompt } from "./prompt.js";
6
- import { statusWidget } from "../../ui/widgets/status.js";
7
- // Re-exports
8
- export { brainToolDefinitions } from "./types.js";
9
- export { buildBrainPrompt } from "./prompt.js";
10
- function expandPath(p) {
11
- if (p.startsWith("~/")) {
12
- return path.join(process.env.HOME || "", p.slice(2));
13
- }
14
- return p;
15
- }
16
- /**
17
- * Create a prompt-builder function bound to a baseDir.
18
- * Returns the brain's portion of the system prompt (base context + memory).
19
- */
20
- export function createBrainPromptBuilder(baseDir, baseContext) {
21
- const expandedBase = expandPath(baseDir);
22
- const modules = {
23
- memory: createMemoryModule(expandedBase),
24
- };
25
- return async (context) => buildBrainPrompt(expandedBase, modules, baseContext || "", context);
26
- }
27
- // --- Plugin ---
28
- /**
29
- * Brain Plugin for Melony
30
- *
31
- * Provides memory capabilities (long-term memory + recall).
32
- * Skills are managed by the separate skills plugin.
33
- *
34
- * Architecture: thin facade over memory module.
35
- */
36
- export const brainPlugin = (options) => (builder) => {
37
- const { baseDir } = options;
38
- const expandedBase = expandPath(baseDir);
39
- // Create sub-module
40
- const memory = createMemoryModule(expandedBase);
41
- // ─── Initialization ───────────────────────────────────────────────
42
- builder.on("init", async function* (_event) {
43
- yield {
44
- type: "brain:status",
45
- data: { message: "Initializing memory..." },
46
- };
47
- await fs.mkdir(expandedBase, { recursive: true, mode: 0o700 });
48
- await memory.initialize();
49
- yield {
50
- type: "brain:status",
51
- data: { message: "Memory initialized", severity: "success" },
52
- };
53
- });
54
- // ─── Memory: Remember ─────────────────────────────────────────────
55
- builder.on("action:remember", async function* (event) {
56
- const { content, tags = [], toolCallId } = event.data;
57
- try {
58
- const entry = await memory.store(content, tags);
59
- yield {
60
- type: "brain:status",
61
- data: { message: "Remembered", severity: "success" },
62
- };
63
- yield {
64
- type: "action:result",
65
- data: {
66
- action: "remember",
67
- toolCallId,
68
- result: {
69
- success: true,
70
- memoryId: entry.id,
71
- message: `Stored in memory with id ${entry.id}`,
72
- },
73
- },
74
- };
75
- }
76
- catch (error) {
77
- yield {
78
- type: "brain:status",
79
- data: {
80
- message: `Failed to remember: ${error.message}`,
81
- severity: "error",
82
- },
83
- };
84
- yield {
85
- type: "action:result",
86
- data: {
87
- action: "remember",
88
- toolCallId,
89
- result: { error: error.message },
90
- },
91
- };
92
- }
93
- });
94
- // ─── Memory: Recall ────────────────────────────────────────────────
95
- builder.on("action:recall", async function* (event) {
96
- const { query, tags, limit, toolCallId } = event.data;
97
- try {
98
- const results = await memory.recall(query, { tags, limit });
99
- yield {
100
- type: "action:result",
101
- data: {
102
- action: "recall",
103
- toolCallId,
104
- result: {
105
- count: results.length,
106
- memories: results.map((e) => ({
107
- id: e.id,
108
- content: e.content,
109
- tags: e.tags,
110
- createdAt: e.createdAt,
111
- })),
112
- },
113
- },
114
- };
115
- }
116
- catch (error) {
117
- yield {
118
- type: "action:result",
119
- data: {
120
- action: "recall",
121
- toolCallId,
122
- result: { error: error.message },
123
- },
124
- };
125
- }
126
- });
127
- // ─── Memory: Forget ────────────────────────────────────────────────
128
- builder.on("action:forget", async function* (event) {
129
- const { memoryId, toolCallId } = event.data;
130
- try {
131
- const removed = await memory.forget(memoryId);
132
- yield {
133
- type: "brain:status",
134
- data: {
135
- message: removed ? "Memory removed" : "Memory not found",
136
- severity: removed ? "success" : "error",
137
- },
138
- };
139
- yield {
140
- type: "action:result",
141
- data: {
142
- action: "forget",
143
- toolCallId,
144
- result: {
145
- success: removed,
146
- message: removed
147
- ? "Memory removed"
148
- : `Memory "${memoryId}" not found`,
149
- },
150
- },
151
- };
152
- }
153
- catch (error) {
154
- yield {
155
- type: "action:result",
156
- data: {
157
- action: "forget",
158
- toolCallId,
159
- result: { error: error.message },
160
- },
161
- };
162
- }
163
- });
164
- // ─── Memory: Journal ───────────────────────────────────────────────
165
- builder.on("action:journal", async function* (event) {
166
- const { content, toolCallId } = event.data;
167
- try {
168
- await memory.addJournalEntry(content);
169
- yield {
170
- type: "brain:status",
171
- data: { message: "Journal entry added", severity: "success" },
172
- };
173
- yield {
174
- type: "action:result",
175
- data: {
176
- action: "journal",
177
- toolCallId,
178
- result: { success: true, message: "Journal entry added" },
179
- },
180
- };
181
- }
182
- catch (error) {
183
- yield {
184
- type: "brain:status",
185
- data: {
186
- message: `Failed to journal: ${error.message}`,
187
- severity: "error",
188
- },
189
- };
190
- yield {
191
- type: "action:result",
192
- data: {
193
- action: "journal",
194
- toolCallId,
195
- result: { error: error.message },
196
- },
197
- };
198
- }
199
- });
200
- builder.on("brain:status", async function* (event) {
201
- yield ui.event(statusWidget(event.data.message, event.data.severity));
202
- });
203
- };
204
- export default brainPlugin;
@@ -1,120 +0,0 @@
1
- import * as fs from "node:fs/promises";
2
- import * as path from "node:path";
3
- // --- Factory ---
4
- export function createMemoryModule(baseDir) {
5
- const memoryDir = path.join(baseDir, "memory");
6
- const indexPath = path.join(memoryDir, "index.json");
7
- const journalDir = path.join(memoryDir, "journal");
8
- // --- Helpers ---
9
- async function loadIndex() {
10
- try {
11
- const data = await fs.readFile(indexPath, "utf-8");
12
- return JSON.parse(data);
13
- }
14
- catch {
15
- return { entries: [] };
16
- }
17
- }
18
- async function saveIndex(index) {
19
- await fs.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
20
- }
21
- function generateId() {
22
- const timestamp = Date.now().toString(36);
23
- const random = Math.random().toString(36).substring(2, 6);
24
- return `mem_${timestamp}_${random}`;
25
- }
26
- /**
27
- * Simple keyword-based relevance scoring.
28
- * Splits query into terms (ignoring short words) and counts how many
29
- * appear in the entry's content + tags. Returns a 0-1 score.
30
- */
31
- function scoreMatch(entry, query) {
32
- const queryTerms = query
33
- .toLowerCase()
34
- .split(/\s+/)
35
- .filter((t) => t.length > 2);
36
- if (queryTerms.length === 0)
37
- return 0;
38
- const searchable = `${entry.content} ${entry.tags.join(" ")}`.toLowerCase();
39
- let matched = 0;
40
- for (const term of queryTerms) {
41
- if (searchable.includes(term)) {
42
- matched++;
43
- }
44
- }
45
- return matched / queryTerms.length;
46
- }
47
- // --- Module ---
48
- return {
49
- async initialize() {
50
- await fs.mkdir(memoryDir, { recursive: true });
51
- await fs.mkdir(journalDir, { recursive: true });
52
- try {
53
- await fs.access(indexPath);
54
- }
55
- catch {
56
- await saveIndex({ entries: [] });
57
- }
58
- },
59
- async store(content, tags = []) {
60
- const index = await loadIndex();
61
- const entry = {
62
- id: generateId(),
63
- content,
64
- tags,
65
- createdAt: new Date().toISOString(),
66
- };
67
- index.entries.push(entry);
68
- await saveIndex(index);
69
- return entry;
70
- },
71
- async recall(query, options) {
72
- const { tags, limit = 5 } = options || {};
73
- const index = await loadIndex();
74
- let candidates = index.entries;
75
- // Filter by tags if provided
76
- if (tags && tags.length > 0) {
77
- candidates = candidates.filter((entry) => tags.some((tag) => entry.tags.includes(tag)));
78
- }
79
- // Score and sort by relevance
80
- const scored = candidates
81
- .map((entry) => ({ entry, score: scoreMatch(entry, query) }))
82
- .filter(({ score }) => score > 0)
83
- .sort((a, b) => b.score - a.score)
84
- .slice(0, limit);
85
- // If no keyword matches found, fall back to most recent entries
86
- if (scored.length === 0) {
87
- return candidates.slice(-limit).reverse();
88
- }
89
- return scored.map(({ entry }) => entry);
90
- },
91
- async forget(memoryId) {
92
- const index = await loadIndex();
93
- const before = index.entries.length;
94
- index.entries = index.entries.filter((e) => e.id !== memoryId);
95
- if (index.entries.length < before) {
96
- await saveIndex(index);
97
- return true;
98
- }
99
- return false;
100
- },
101
- async addJournalEntry(content) {
102
- const today = new Date().toISOString().split("T")[0]; // e.g., "2026-02-12"
103
- const journalPath = path.join(journalDir, `${today}.md`);
104
- const timestamp = new Date().toLocaleTimeString();
105
- const entry = `\n## ${timestamp}\n${content}\n`;
106
- try {
107
- await fs.access(journalPath);
108
- await fs.appendFile(journalPath, entry, "utf-8");
109
- }
110
- catch {
111
- const header = `# Journal - ${today}\n`;
112
- await fs.writeFile(journalPath, header + entry, "utf-8");
113
- }
114
- },
115
- async getRecentFacts(limit = 3) {
116
- const index = await loadIndex();
117
- return (index?.entries ?? []).slice(-limit);
118
- },
119
- };
120
- }
@@ -1,46 +0,0 @@
1
- // --- Prompt Builder ---
2
- /**
3
- * Build the brain's section of the system prompt.
4
- *
5
- * Includes only what the brain owns:
6
- * - Environment context
7
- * - Base context from settings (optional)
8
- * - A handful of the most recent memories
9
- * - Memory capability instructions
10
- *
11
- * Skills are handled by the separate skills plugin and composed
12
- * at the top level in open-bot.ts.
13
- */
14
- export async function buildBrainPrompt(baseDir, modules, baseContext, context) {
15
- const parts = [];
16
- const state = context?.state;
17
- const currentCwd = state?.cwd || process.cwd();
18
- // 1. Environment context
19
- const now = new Date();
20
- parts.push(`<environment>
21
- - Time: ${now.toLocaleString()} (${Intl.DateTimeFormat().resolvedOptions().timeZone})
22
- - CWD: ${currentCwd}
23
- - Bot Home: ${baseDir}
24
- </environment>`);
25
- // 2. Base context from settings (optional)
26
- if (baseContext.trim()) {
27
- parts.push(`<base_context>\n${baseContext.trim()}\n</base_context>`);
28
- }
29
- // 3. Recent memories (lean — just a few to keep context fresh)
30
- const recentFacts = await modules.memory.getRecentFacts(5);
31
- if (recentFacts.length > 0) {
32
- const factsList = recentFacts
33
- .map((f) => `- ${f.content}${f.tags.length > 0 ? ` [${f.tags.join(", ")}]` : ""}`)
34
- .join("\n");
35
- parts.push(`<recent_memories>\n${factsList}\n</recent_memories>`);
36
- }
37
- // 4. Memory capabilities
38
- parts.push(`<brain_tools>
39
- Use these to manage your persistent state:
40
- - \`remember(content, tags)\`: Store facts/preferences
41
- - \`recall(query, tags)\`: Search long-term memory
42
- - \`forget(memoryId)\`: Remove outdated info
43
- - \`journal(content)\`: Record session reflections
44
- </brain_tools>`);
45
- return `\n${parts.join("\n\n")}\n`;
46
- }
@@ -1,45 +0,0 @@
1
- import { z } from "zod";
2
- // --- Tool Definitions ---
3
- export const brainToolDefinitions = {
4
- // Memory tools
5
- remember: {
6
- description: "Store something important in long-term memory. Use for user preferences, learned facts, project context, etc.",
7
- inputSchema: z.object({
8
- content: z
9
- .string()
10
- .describe("The information to remember"),
11
- tags: z
12
- .array(z.string())
13
- .optional()
14
- .describe("Tags for categorization (e.g., 'user-preference', 'project', 'learning')"),
15
- }),
16
- },
17
- recall: {
18
- description: "Search your memory for relevant information. Use before answering questions that might relate to past interactions.",
19
- inputSchema: z.object({
20
- query: z.string().describe("What to search for in memory"),
21
- tags: z
22
- .array(z.string())
23
- .optional()
24
- .describe("Filter by specific tags"),
25
- limit: z
26
- .number()
27
- .optional()
28
- .describe("Max results to return (default: 5)"),
29
- }),
30
- },
31
- forget: {
32
- description: "Remove a specific memory entry by ID.",
33
- inputSchema: z.object({
34
- memoryId: z
35
- .string()
36
- .describe("The ID of the memory entry to remove"),
37
- }),
38
- },
39
- journal: {
40
- description: "Add a journal entry for today. Use for session notes, learnings, and reflections.",
41
- inputSchema: z.object({
42
- content: z.string().describe("Journal entry content"),
43
- }),
44
- },
45
- };
@@ -1,7 +0,0 @@
1
- import { ui } from "@melony/ui-kit/server";
2
- // --- UI Plugin ---
3
- export const brainUIPlugin = () => (builder) => {
4
- builder.on("brain:status", async function* (event) {
5
- yield ui.event(ui.status(event.data.message, event.data.severity));
6
- });
7
- };