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,286 +0,0 @@
1
- import { uiEvent, block } from "../../ui/block.js";
2
- import * as fs from "node:fs/promises";
3
- import * as path from "node:path";
4
- import matter from "gray-matter";
5
- import { statusWidget } from "../../ui/widgets/status.js";
6
- import { resourceCardWidget } from "../../ui/widgets/resource-card.js";
7
- // Re-exports
8
- export { skillsToolDefinitions } from "./types.js";
9
- // --- Helpers ---
10
- function expandPath(p) {
11
- if (p.startsWith("~/")) {
12
- return path.join(process.env.HOME || "", p.slice(2));
13
- }
14
- return p;
15
- }
16
- // --- Skills Module (internal) ---
17
- function createSkillsModule(skillsDir) {
18
- async function list() {
19
- const skills = [];
20
- try {
21
- const folders = await fs.readdir(skillsDir);
22
- for (const folder of folders) {
23
- if (folder.startsWith("_") || folder.startsWith("."))
24
- continue;
25
- const skillPath = path.join(skillsDir, folder, "SKILL.md");
26
- try {
27
- const content = await fs.readFile(skillPath, "utf-8");
28
- const { data } = matter(content);
29
- skills.push({
30
- id: folder,
31
- title: data.title || folder,
32
- description: data.description || "No description",
33
- version: data.version,
34
- tools: data.tools,
35
- triggers: data.triggers,
36
- });
37
- }
38
- catch {
39
- // Invalid skill, skip
40
- }
41
- }
42
- }
43
- catch {
44
- // Skills directory doesn't exist yet
45
- }
46
- return skills;
47
- }
48
- return {
49
- async initialize() {
50
- await fs.mkdir(skillsDir, { recursive: true });
51
- },
52
- list,
53
- async load(skillId) {
54
- const skillPath = path.join(skillsDir, skillId, "SKILL.md");
55
- const content = await fs.readFile(skillPath, "utf-8");
56
- const { data, content: body } = matter(content);
57
- return { meta: data, instructions: body.trim() };
58
- },
59
- async create(id, title, description, content) {
60
- if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(id)) {
61
- throw new Error("Skill id must be kebab-case (e.g., 'my-skill')");
62
- }
63
- const skillDir = path.join(skillsDir, id);
64
- await fs.mkdir(skillDir, { recursive: true });
65
- const skillContent = `---
66
- title: ${title}
67
- description: ${description}
68
- version: 1.0.0
69
- createdAt: ${new Date().toISOString()}
70
- ---
71
-
72
- ${content}`;
73
- await fs.writeFile(path.join(skillDir, "SKILL.md"), skillContent, "utf-8");
74
- return `skills/${id}/SKILL.md`;
75
- },
76
- async update(id, content, title, description) {
77
- const skillPath = path.join(skillsDir, id, "SKILL.md");
78
- const existingContent = await fs.readFile(skillPath, "utf-8");
79
- const { data: existingData } = matter(existingContent);
80
- const newTitle = title || existingData.title || id;
81
- const newDescription = description || existingData.description || "No description";
82
- // Bump patch version
83
- let version = existingData.version || "1.0.0";
84
- const parts = version.split(".");
85
- if (parts.length === 3) {
86
- parts[2] = (parseInt(parts[2]) + 1).toString();
87
- version = parts.join(".");
88
- }
89
- const skillContent = `---
90
- title: ${newTitle}
91
- description: ${newDescription}
92
- version: ${version}
93
- updatedAt: ${new Date().toISOString()}
94
- createdAt: ${existingData.createdAt || new Date().toISOString()}
95
- ---
96
-
97
- ${content}`;
98
- await fs.writeFile(skillPath, skillContent, "utf-8");
99
- return version;
100
- },
101
- async getIndex() {
102
- const skills = await list();
103
- if (skills.length > 0) {
104
- return `## Available Skills
105
-
106
- You have the following skills available. Use \`loadSkill\` with the skill id to get full instructions before executing.
107
-
108
- ${skills.map((s) => `- **${s.title}** (\`${s.id}\`): ${s.description}`).join("\n")}`;
109
- }
110
- return `## Skills
111
-
112
- You have no skills yet. When you learn reusable patterns, create skills using \`createSkill\` so you can use them again later.`;
113
- },
114
- };
115
- }
116
- // --- Prompt Builder ---
117
- /**
118
- * Create a prompt builder that generates the skills section
119
- * of the system prompt. Use alongside the memory prompt builder.
120
- */
121
- export function createSkillsPromptBuilder(baseDir) {
122
- const expandedBase = expandPath(baseDir);
123
- const skills = createSkillsModule(path.join(expandedBase, "skills"));
124
- return async () => skills.getIndex();
125
- }
126
- // --- Plugin ---
127
- /**
128
- * Skills Plugin for Melony
129
- *
130
- * Manages reusable skill definitions: load, create, update, list.
131
- * Fully independent from the memory plugin.
132
- */
133
- export const skillsPlugin = (options) => (builder) => {
134
- const expandedBase = expandPath(options.baseDir);
135
- const skills = createSkillsModule(path.join(expandedBase, "skills"));
136
- // ─── Initialization ───────────────────────────────────────────────
137
- builder.on("init", async function* () {
138
- await skills.initialize();
139
- yield {
140
- type: "skills:status",
141
- data: { message: "Skills initialized", severity: "success" },
142
- };
143
- });
144
- // ─── Load ─────────────────────────────────────────────────────────
145
- builder.on("action:loadSkill", async function* (event) {
146
- const { skillId, toolCallId } = event.data;
147
- try {
148
- const { meta, instructions } = await skills.load(skillId);
149
- yield {
150
- type: "skills:loaded",
151
- data: {
152
- skillId,
153
- title: meta.title || skillId,
154
- instructions: meta.description || "No description",
155
- },
156
- };
157
- yield {
158
- type: "action:result",
159
- data: {
160
- action: "loadSkill",
161
- toolCallId,
162
- result: { id: skillId, meta, instructions },
163
- },
164
- };
165
- }
166
- catch {
167
- yield {
168
- type: "action:result",
169
- data: {
170
- action: "loadSkill",
171
- toolCallId,
172
- result: { error: `Skill "${skillId}" not found` },
173
- },
174
- };
175
- }
176
- });
177
- // ─── List ─────────────────────────────────────────────────────────
178
- builder.on("action:listSkills", async function* (event) {
179
- const { toolCallId } = event.data;
180
- const skillsList = await skills.list();
181
- yield {
182
- type: "action:result",
183
- data: {
184
- action: "listSkills",
185
- toolCallId,
186
- result: { skills: skillsList },
187
- },
188
- };
189
- });
190
- // ─── Create ───────────────────────────────────────────────────────
191
- builder.on("action:createSkill", async function* (event) {
192
- const { id, title, description, content, toolCallId } = event.data;
193
- try {
194
- const skillPath = await skills.create(id, title, description, content);
195
- yield {
196
- type: "skills:status",
197
- data: { message: `Skill "${title}" created`, severity: "success" },
198
- };
199
- yield {
200
- type: "action:result",
201
- data: {
202
- action: "createSkill",
203
- toolCallId,
204
- result: {
205
- success: true,
206
- path: skillPath,
207
- message: `Skill "${title}" created successfully`,
208
- },
209
- },
210
- };
211
- }
212
- catch (error) {
213
- yield {
214
- type: "skills:status",
215
- data: {
216
- message: `Failed to create skill: ${error.message}`,
217
- severity: "error",
218
- },
219
- };
220
- yield {
221
- type: "action:result",
222
- data: {
223
- action: "createSkill",
224
- toolCallId,
225
- result: { error: error.message },
226
- },
227
- };
228
- }
229
- });
230
- // ─── Update ───────────────────────────────────────────────────────
231
- builder.on("action:updateSkill", async function* (event) {
232
- const { id, title, description, content, toolCallId } = event.data;
233
- try {
234
- const version = await skills.update(id, content, title, description);
235
- yield {
236
- type: "skills:status",
237
- data: {
238
- message: `Skill updated to v${version}`,
239
- severity: "success",
240
- },
241
- };
242
- yield {
243
- type: "action:result",
244
- data: {
245
- action: "updateSkill",
246
- toolCallId,
247
- result: {
248
- success: true,
249
- path: `skills/${id}/SKILL.md`,
250
- version,
251
- message: `Skill updated to version ${version}`,
252
- },
253
- },
254
- };
255
- }
256
- catch (error) {
257
- const errorMsg = error.code === "ENOENT"
258
- ? `Skill "${id}" does not exist`
259
- : error.message;
260
- yield {
261
- type: "skills:status",
262
- data: {
263
- message: `Failed to update skill: ${errorMsg}`,
264
- severity: "error",
265
- },
266
- };
267
- yield {
268
- type: "action:result",
269
- data: {
270
- action: "updateSkill",
271
- toolCallId,
272
- result: { error: errorMsg },
273
- },
274
- };
275
- }
276
- });
277
- builder.on("skills:status", async function* (event) {
278
- yield uiEvent(statusWidget(event.data.message, event.data.severity));
279
- });
280
- builder.on("skills:loaded", async function* (event) {
281
- yield uiEvent(resourceCardWidget(event.data.title, "", [
282
- block('text', { value: event.data.instructions }),
283
- ]));
284
- });
285
- };
286
- export default skillsPlugin;
@@ -1,50 +0,0 @@
1
- import { z } from "zod";
2
- // --- Tool Definitions ---
3
- export const skillsToolDefinitions = {
4
- loadSkill: {
5
- description: "Load a skill's full instructions when you need to use it. Call this before executing a skill.",
6
- inputSchema: z.object({
7
- skillId: z
8
- .string()
9
- .describe("The skill folder name (e.g., 'code-review')"),
10
- }),
11
- },
12
- createSkill: {
13
- description: "Create a new skill from learned knowledge. Use when you discover a reusable pattern.",
14
- inputSchema: z.object({
15
- id: z
16
- .string()
17
- .describe("Skill folder name in kebab-case (e.g., 'web-search')"),
18
- title: z.string().describe("Human-readable skill title"),
19
- description: z
20
- .string()
21
- .describe("Brief description of what the skill does"),
22
- content: z
23
- .string()
24
- .describe("Full skill instructions in markdown"),
25
- }),
26
- },
27
- updateSkill: {
28
- description: "Update an existing skill with new knowledge or improvements.",
29
- inputSchema: z.object({
30
- id: z
31
- .string()
32
- .describe("The skill folder name (e.g., 'code-review')"),
33
- title: z
34
- .string()
35
- .optional()
36
- .describe("New title for the skill"),
37
- description: z
38
- .string()
39
- .optional()
40
- .describe("New description for the skill"),
41
- content: z
42
- .string()
43
- .describe("Updated full skill instructions in markdown"),
44
- }),
45
- },
46
- listSkills: {
47
- description: "List all available skills with their metadata.",
48
- inputSchema: z.object({}),
49
- },
50
- };
@@ -1,12 +0,0 @@
1
- import { ui } from "@melony/ui-kit/server";
2
- // --- UI Plugin ---
3
- export const skillsUIPlugin = () => (builder) => {
4
- builder.on("skills:status", async function* (event) {
5
- yield ui.event(ui.status(event.data.message, event.data.severity));
6
- });
7
- builder.on("skills:loaded", async function* (event) {
8
- yield ui.event(ui.resourceCard(event.data.title, "", [
9
- ui.text(event.data.instructions),
10
- ]));
11
- });
12
- };
@@ -1,35 +0,0 @@
1
- /**
2
- * Agent Registry
3
- *
4
- * Collects all available agents (built-in + discovered).
5
- * Used by the manager to dynamically build the delegation tool schema
6
- * and wire up generic bridge-back handlers.
7
- */
8
- export class AgentRegistry {
9
- constructor() {
10
- this.agents = new Map();
11
- }
12
- register(entry) {
13
- if (this.agents.has(entry.name)) {
14
- console.warn(`Agent "${entry.name}" is already registered — overwriting`);
15
- }
16
- this.agents.set(entry.name, entry);
17
- }
18
- get(name) {
19
- return this.agents.get(name);
20
- }
21
- has(name) {
22
- return this.agents.has(name);
23
- }
24
- getAll() {
25
- return Array.from(this.agents.values());
26
- }
27
- /** Returns agent names as a tuple suitable for z.enum() */
28
- getNames() {
29
- const names = Array.from(this.agents.keys());
30
- if (names.length === 0) {
31
- throw new Error("No agents registered — at least one agent is required");
32
- }
33
- return names;
34
- }
35
- }
@@ -1,2 +0,0 @@
1
- export { PluginRegistry } from "./plugin-registry.js";
2
- export { discoverPlugins, listPlugins, readAgentConfig, getPluginMetadata, ensurePluginReady, } from "./plugin-loader.js";