openbot 0.3.5 → 0.4.0
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.
- package/README.md +15 -16
- package/dist/app/agent-ids.js +4 -0
- package/dist/app/cli.js +1 -1
- package/dist/app/config.js +0 -19
- package/dist/app/server.js +8 -14
- package/dist/assets/icon.svg +9 -3
- package/dist/bus/services.js +78 -132
- package/dist/harness/agent-invoke-run.js +44 -0
- package/dist/harness/agent-turn.js +99 -0
- package/dist/harness/channel-participants.js +40 -0
- package/dist/harness/constants.js +2 -0
- package/dist/harness/context-meter.js +97 -0
- package/dist/harness/context.js +98 -45
- package/dist/harness/dispatch.js +144 -0
- package/dist/harness/dispatcher.js +45 -156
- package/dist/harness/history.js +177 -0
- package/dist/harness/index.js +91 -0
- package/dist/harness/orchestration.js +88 -0
- package/dist/harness/participants.js +22 -0
- package/dist/harness/run-harness.js +154 -0
- package/dist/harness/run.js +98 -0
- package/dist/harness/runtime-factory.js +0 -34
- package/dist/harness/runtime.js +57 -0
- package/dist/harness/todo-dispatch.js +51 -0
- package/dist/harness/todos.js +5 -0
- package/dist/harness/turn.js +79 -0
- package/dist/plugins/approval/index.js +105 -149
- package/dist/plugins/delegation/index.js +119 -32
- package/dist/plugins/memory/index.js +103 -14
- package/dist/plugins/memory/service.js +152 -0
- package/dist/plugins/openbot/context.js +80 -0
- package/dist/plugins/openbot/history.js +98 -0
- package/dist/plugins/openbot/index.js +31 -0
- package/dist/plugins/openbot/runtime.js +317 -0
- package/dist/plugins/openbot/system-prompt.js +5 -0
- package/dist/plugins/plugin-manager/index.js +105 -0
- package/dist/plugins/storage/index.js +573 -0
- package/dist/plugins/storage/service.js +1159 -0
- package/dist/plugins/storage-tools/index.js +2 -2
- package/dist/plugins/thread-namer/index.js +72 -0
- package/dist/plugins/thread-naming/generate-title.js +44 -0
- package/dist/plugins/thread-naming/index.js +103 -0
- package/dist/plugins/threads/index.js +114 -0
- package/dist/plugins/todo/index.js +24 -25
- package/dist/plugins/ui/index.js +2 -32
- package/dist/registry/plugins.js +3 -9
- package/dist/services/plugins/domain.js +1 -0
- package/dist/services/plugins/plugin-cache.js +9 -0
- package/dist/services/plugins/registry.js +110 -0
- package/dist/services/plugins/service.js +177 -0
- package/dist/services/plugins/types.js +1 -0
- package/dist/services/process.js +29 -0
- package/dist/services/storage.js +41 -15
- package/dist/services/thread-naming.js +81 -0
- package/docs/agents.md +16 -10
- package/docs/architecture.md +2 -2
- package/docs/plugins.md +6 -15
- package/docs/templates/AGENT.example.md +7 -13
- package/package.json +1 -2
- package/src/app/agent-ids.ts +5 -0
- package/src/app/cli.ts +1 -1
- package/src/app/config.ts +1 -31
- package/src/app/server.ts +8 -16
- package/src/app/types.ts +70 -190
- package/src/assets/icon.svg +9 -3
- package/src/harness/index.ts +145 -0
- package/src/plugins/approval/index.ts +91 -189
- package/src/plugins/delegation/index.ts +136 -39
- package/src/plugins/memory/index.ts +112 -15
- package/src/{services/memory.ts → plugins/memory/service.ts} +1 -1
- package/src/plugins/openbot/context.ts +91 -0
- package/src/plugins/openbot/history.ts +107 -0
- package/src/plugins/openbot/index.ts +37 -0
- package/src/plugins/openbot/runtime.ts +384 -0
- package/src/plugins/openbot/system-prompt.ts +7 -0
- package/src/plugins/plugin-manager/index.ts +122 -0
- package/src/plugins/shell/index.ts +1 -1
- package/src/plugins/storage/index.ts +633 -0
- package/src/{services/storage.ts → plugins/storage/service.ts} +257 -72
- package/src/{bus/types.ts → services/plugins/domain.ts} +20 -7
- package/src/services/plugins/plugin-cache.ts +13 -0
- package/src/{registry/plugins.ts → services/plugins/registry.ts} +25 -27
- package/src/services/{plugins.ts → plugins/service.ts} +96 -2
- package/src/{bus/plugin.ts → services/plugins/types.ts} +3 -3
- package/src/bus/services.ts +0 -908
- package/src/harness/context.ts +0 -356
- package/src/harness/dispatcher.ts +0 -379
- package/src/harness/mcp.ts +0 -78
- package/src/harness/runtime-factory.ts +0 -129
- package/src/harness/todo-advance.ts +0 -128
- package/src/plugins/ai-sdk/index.ts +0 -41
- package/src/plugins/ai-sdk/runtime.ts +0 -468
- package/src/plugins/ai-sdk/system-prompt.ts +0 -18
- package/src/plugins/mcp/index.ts +0 -128
- package/src/plugins/storage-tools/index.ts +0 -90
- package/src/plugins/todo/index.ts +0 -64
- package/src/plugins/ui/index.ts +0 -227
- /package/src/{harness → services}/process.ts +0 -0
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
import type { Plugin } from '
|
|
5
|
-
import {
|
|
6
|
-
import { shellPlugin } from '
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
4
|
+
import type { Plugin } from './types.js';
|
|
5
|
+
import { openbotPlugin } from '../../plugins/openbot/index.js';
|
|
6
|
+
import { shellPlugin } from '../../plugins/shell/index.js';
|
|
7
|
+
import { storagePlugin } from '../../plugins/storage/index.js';
|
|
8
|
+
import { approvalPlugin } from '../../plugins/approval/index.js';
|
|
9
|
+
import { memoryPlugin } from '../../plugins/memory/index.js';
|
|
10
|
+
import { delegationPlugin } from '../../plugins/delegation/index.js';
|
|
11
|
+
import { pluginManagerPlugin } from '../../plugins/plugin-manager/index.js';
|
|
12
|
+
import { DEFAULT_PLUGINS_DIR, DEFAULT_BASE_DIR, loadConfig, resolvePath } from '../../app/config.js';
|
|
13
|
+
import {
|
|
14
|
+
invalidatePlugin as clearResolvedPluginEntry,
|
|
15
|
+
loadedCommunityPlugins,
|
|
16
|
+
resolvedPluginCache,
|
|
17
|
+
} from './plugin-cache.js';
|
|
15
18
|
|
|
16
19
|
let pluginsDir: string | null = null;
|
|
17
|
-
const loadedPlugins = new Set<string>();
|
|
18
|
-
const cache = new Map<string, Plugin>();
|
|
19
20
|
|
|
20
21
|
const BUILT_IN: Record<string, Plugin> = {
|
|
21
|
-
[
|
|
22
|
+
[openbotPlugin.id]: openbotPlugin,
|
|
22
23
|
[shellPlugin.id]: shellPlugin,
|
|
23
|
-
[
|
|
24
|
-
[delegationPlugin.id]: delegationPlugin,
|
|
25
|
-
[storageToolsPlugin.id]: storageToolsPlugin,
|
|
26
|
-
[uiPlugin.id]: uiPlugin,
|
|
24
|
+
[storagePlugin.id]: storagePlugin,
|
|
27
25
|
[approvalPlugin.id]: approvalPlugin,
|
|
28
26
|
[memoryPlugin.id]: memoryPlugin,
|
|
29
|
-
[
|
|
27
|
+
[delegationPlugin.id]: delegationPlugin,
|
|
28
|
+
[pluginManagerPlugin.id]: pluginManagerPlugin,
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
/**
|
|
@@ -78,14 +77,14 @@ export function initPlugins(dir?: string) {
|
|
|
78
77
|
|
|
79
78
|
/**
|
|
80
79
|
* Resolve a Plugin by id. The id is either:
|
|
81
|
-
* - a built-in id (e.g. "
|
|
80
|
+
* - a built-in id (e.g. "openbot", "shell"), or
|
|
82
81
|
* - an npm package name (e.g. "openbot-plugin-foo" or "@scope/foo"),
|
|
83
82
|
* in which case the folder layout is `plugins/<id>/dist/index.js`.
|
|
84
83
|
*/
|
|
85
84
|
export async function resolvePlugin(id: string): Promise<Plugin | null> {
|
|
86
|
-
if (
|
|
85
|
+
if (resolvedPluginCache.has(id)) return resolvedPluginCache.get(id)!;
|
|
87
86
|
if (BUILT_IN[id]) {
|
|
88
|
-
|
|
87
|
+
resolvedPluginCache.set(id, BUILT_IN[id]);
|
|
89
88
|
return BUILT_IN[id];
|
|
90
89
|
}
|
|
91
90
|
|
|
@@ -109,10 +108,10 @@ export async function resolvePlugin(id: string): Promise<Plugin | null> {
|
|
|
109
108
|
return null;
|
|
110
109
|
}
|
|
111
110
|
const plugin: Plugin = { id, ...parsed, name: parsed.name || id };
|
|
112
|
-
|
|
113
|
-
if (!
|
|
111
|
+
resolvedPluginCache.set(id, plugin);
|
|
112
|
+
if (!loadedCommunityPlugins.has(id)) {
|
|
114
113
|
console.log(`[plugins] Loaded community plugin "${id}" from ${distPath}`);
|
|
115
|
-
|
|
114
|
+
loadedCommunityPlugins.add(id);
|
|
116
115
|
}
|
|
117
116
|
return plugin;
|
|
118
117
|
} catch (e) {
|
|
@@ -123,8 +122,7 @@ export async function resolvePlugin(id: string): Promise<Plugin | null> {
|
|
|
123
122
|
|
|
124
123
|
/** Drop a single id from the in-memory cache (e.g. after fresh install). */
|
|
125
124
|
export function invalidatePlugin(id: string): void {
|
|
126
|
-
|
|
127
|
-
loadedPlugins.delete(id);
|
|
125
|
+
clearResolvedPluginEntry(id);
|
|
128
126
|
}
|
|
129
127
|
|
|
130
128
|
/** List built-in plugins (for marketplace/registry views). */
|
|
@@ -6,10 +6,12 @@ import { promisify } from 'node:util';
|
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_PLUGINS_DIR,
|
|
8
8
|
DEFAULT_BASE_DIR,
|
|
9
|
+
DEFAULT_MARKETPLACE_REGISTRY_URL,
|
|
9
10
|
loadConfig,
|
|
10
11
|
resolvePath,
|
|
11
|
-
} from '
|
|
12
|
-
import { invalidatePlugin } from '
|
|
12
|
+
} from '../../app/config.js';
|
|
13
|
+
import { invalidatePlugin } from './plugin-cache.js';
|
|
14
|
+
import { PluginRef } from './types.js';
|
|
13
15
|
|
|
14
16
|
const execAsync = promisify(exec);
|
|
15
17
|
|
|
@@ -24,6 +26,97 @@ export interface InstalledPlugin {
|
|
|
24
26
|
version: string;
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
/** One marketplace entry; matches `action:marketplace:list:result` agent shape. */
|
|
30
|
+
export type MarketplaceAgentListing = {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
image?: string;
|
|
35
|
+
instructions: string;
|
|
36
|
+
plugins: PluginRef[];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const DEFAULT_MARKETPLACE_AGENTS: MarketplaceAgentListing[] = [];
|
|
40
|
+
|
|
41
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
42
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Parses JSON from a remote registry file. Supports either
|
|
47
|
+
* `{ "agents": [ ... ] }` or a top-level array.
|
|
48
|
+
*/
|
|
49
|
+
export function parseMarketplaceRegistryJson(data: unknown): MarketplaceAgentListing[] {
|
|
50
|
+
const rawAgents: unknown =
|
|
51
|
+
Array.isArray(data) ? data : isRecord(data) && Array.isArray(data.agents) ? data.agents : null;
|
|
52
|
+
if (!Array.isArray(rawAgents)) {
|
|
53
|
+
throw new Error('Registry JSON must be an array or an object with an "agents" array');
|
|
54
|
+
}
|
|
55
|
+
return rawAgents.map((item, i) => {
|
|
56
|
+
if (!isRecord(item)) {
|
|
57
|
+
throw new Error(`agents[${i}]: expected object`);
|
|
58
|
+
}
|
|
59
|
+
const id = item.id;
|
|
60
|
+
const name = item.name;
|
|
61
|
+
const description = item.description;
|
|
62
|
+
const instructions = item.instructions;
|
|
63
|
+
const pluginsRaw = item.plugins;
|
|
64
|
+
if (typeof id !== 'string' || !id) throw new Error(`agents[${i}].id must be a non-empty string`);
|
|
65
|
+
if (typeof name !== 'string') throw new Error(`agents[${i}].name must be a string`);
|
|
66
|
+
if (typeof description !== 'string') throw new Error(`agents[${i}].description must be a string`);
|
|
67
|
+
if (typeof instructions !== 'string') {
|
|
68
|
+
throw new Error(`agents[${i}].instructions must be a string`);
|
|
69
|
+
}
|
|
70
|
+
if (!Array.isArray(pluginsRaw)) throw new Error(`agents[${i}].plugins must be an array`);
|
|
71
|
+
const plugins: PluginRef[] = pluginsRaw.map((p, j) => {
|
|
72
|
+
if (!isRecord(p) || typeof p.id !== 'string' || !p.id) {
|
|
73
|
+
throw new Error(`agents[${i}].plugins[${j}]: expected { "id": string, "config"?: object }`);
|
|
74
|
+
}
|
|
75
|
+
const ref: PluginRef = { id: p.id };
|
|
76
|
+
if (p.config !== undefined) {
|
|
77
|
+
if (!isRecord(p.config)) throw new Error(`agents[${i}].plugins[${j}].config must be an object`);
|
|
78
|
+
ref.config = p.config;
|
|
79
|
+
}
|
|
80
|
+
return ref;
|
|
81
|
+
});
|
|
82
|
+
const listing: MarketplaceAgentListing = { id, name, description, instructions, plugins };
|
|
83
|
+
if (item.image !== undefined) {
|
|
84
|
+
if (typeof item.image !== 'string') throw new Error(`agents[${i}].image must be a string`);
|
|
85
|
+
listing.image = item.image;
|
|
86
|
+
}
|
|
87
|
+
return listing;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function fetchMarketplaceAgentsFromUrl(url: string): Promise<MarketplaceAgentListing[]> {
|
|
92
|
+
const res = await fetch(url, {
|
|
93
|
+
headers: { Accept: 'application/json' },
|
|
94
|
+
signal: AbortSignal.timeout(15_000),
|
|
95
|
+
});
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
throw new Error(`Registry HTTP ${res.status} ${res.statusText}`);
|
|
98
|
+
}
|
|
99
|
+
const json: unknown = await res.json();
|
|
100
|
+
return parseMarketplaceRegistryJson(json);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Resolves marketplace agent listings from configured registry URL, or falls back to an empty list.
|
|
105
|
+
*/
|
|
106
|
+
export async function resolveMarketplaceAgentList(): Promise<MarketplaceAgentListing[]> {
|
|
107
|
+
const { marketplaceRegistryUrl } = loadConfig();
|
|
108
|
+
const registryUrl = marketplaceRegistryUrl?.trim() || DEFAULT_MARKETPLACE_REGISTRY_URL;
|
|
109
|
+
try {
|
|
110
|
+
return await fetchMarketplaceAgentsFromUrl(registryUrl);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.warn(
|
|
113
|
+
`[plugins] marketplace registry fetch failed (${registryUrl}), using built-in list:`,
|
|
114
|
+
err instanceof Error ? err.message : err,
|
|
115
|
+
);
|
|
116
|
+
return DEFAULT_MARKETPLACE_AGENTS;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
27
120
|
const getPluginsDir = (): string => {
|
|
28
121
|
const config = loadConfig();
|
|
29
122
|
const baseDir = resolvePath(config.baseDir || DEFAULT_BASE_DIR);
|
|
@@ -131,3 +224,4 @@ export const pluginService = {
|
|
|
131
224
|
}
|
|
132
225
|
},
|
|
133
226
|
};
|
|
227
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { MelonyPlugin } from 'melony';
|
|
2
|
-
import { OpenBotEvent, OpenBotState } from '
|
|
3
|
-
import { AgentDetails, ConfigSchema, Storage } from './
|
|
2
|
+
import { OpenBotEvent, OpenBotState } from '../../app/types.js';
|
|
3
|
+
import { AgentDetails, ConfigSchema, Storage } from './domain.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Reference to a plugin from an agent's AGENT.md frontmatter.
|
|
7
7
|
*
|
|
8
|
-
* The `id` is either a built-in plugin id (e.g. `
|
|
8
|
+
* The `id` is either a built-in plugin id (e.g. `openbot`, `shell`) or an npm
|
|
9
9
|
* package name (e.g. `openbot-plugin-codex`, `@scope/openbot-plugin-foo`).
|
|
10
10
|
* Each entry may carry plugin-specific `config`.
|
|
11
11
|
*/
|