openbot 0.5.4 → 0.5.6
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/CLAUDE.md +5 -4
- package/deploy/README.md +2 -4
- package/dist/app/cli.js +3 -1
- package/dist/app/cloud-mode.js +5 -16
- package/dist/app/ensure-default-stack.js +54 -0
- package/dist/app/openbot-plugin.js +4 -0
- package/dist/app/server.js +2 -3
- package/dist/harness/index.js +3 -0
- package/dist/plugins/openbot/index.js +6 -5
- package/dist/plugins/openbot/model.js +2 -41
- package/dist/plugins/openbot/runtime.js +9 -4
- package/dist/plugins/storage/index.js +3 -325
- package/dist/plugins/storage/service.js +18 -21
- package/dist/services/plugins/host.js +21 -0
- package/dist/services/plugins/model-registry.js +34 -9
- package/dist/services/plugins/registry.js +26 -42
- package/dist/services/plugins/service.js +5 -1
- package/dist/services/todo/types.js +1 -0
- package/docs/plugins.md +14 -12
- package/docs/templates/AGENT.example.md +8 -14
- package/package.json +2 -2
- package/src/app/cli.ts +3 -1
- package/src/app/cloud-mode.ts +7 -22
- package/src/app/ensure-default-stack.ts +63 -0
- package/src/app/openbot-plugin.ts +5 -0
- package/src/app/server.ts +2 -5
- package/src/app/types.ts +4 -8
- package/src/harness/index.ts +4 -0
- package/src/plugins/storage/index.ts +3 -368
- package/src/plugins/storage/service.ts +17 -22
- package/src/services/plugins/host.ts +36 -0
- package/src/services/plugins/model-registry.ts +41 -9
- package/src/services/plugins/registry.ts +28 -43
- package/src/services/plugins/service.ts +13 -12
- package/src/services/plugins/types.ts +36 -2
- package/src/services/todo/types.ts +12 -0
- package/src/plugins/approval/index.ts +0 -147
- package/src/plugins/bash/index.ts +0 -545
- package/src/plugins/delegation/index.ts +0 -153
- package/src/plugins/memory/index.ts +0 -182
- package/src/plugins/openbot/context.ts +0 -137
- package/src/plugins/openbot/history.ts +0 -158
- package/src/plugins/openbot/index.ts +0 -95
- package/src/plugins/openbot/model.ts +0 -76
- package/src/plugins/openbot/runtime.ts +0 -504
- package/src/plugins/openbot/system-prompt.ts +0 -57
- package/src/plugins/preview/index.ts +0 -323
- package/src/plugins/todo/index.ts +0 -166
- package/src/plugins/todo/service.ts +0 -123
- package/src/plugins/ui/index.ts +0 -130
package/docs/plugins.md
CHANGED
|
@@ -28,7 +28,7 @@ export interface Plugin {
|
|
|
28
28
|
export interface PluginContext {
|
|
29
29
|
agentId: string;
|
|
30
30
|
agentDetails: AgentDetails;
|
|
31
|
-
config: Record<string, unknown>;
|
|
31
|
+
config: Record<string, unknown>; // from AGENT.md plugins[].config
|
|
32
32
|
storage: Storage;
|
|
33
33
|
tools: Record<string, ToolDefinition>; // merged from all tool plugins
|
|
34
34
|
}
|
|
@@ -49,16 +49,16 @@ model as the tool result (`history.ts`). Structured fields (e.g. `list`,
|
|
|
49
49
|
|
|
50
50
|
## Built-in plugins
|
|
51
51
|
|
|
52
|
-
| Id
|
|
53
|
-
|
|
|
54
|
-
| `openbot`
|
|
55
|
-
| `claude-code`
|
|
56
|
-
| `gemini-cli`
|
|
57
|
-
| `bash`
|
|
58
|
-
| `storage`
|
|
59
|
-
| `memory`
|
|
60
|
-
| `todo`
|
|
61
|
-
| `plugin-manager
|
|
52
|
+
| Id | Role | Notes |
|
|
53
|
+
| ---------------- | ------- | ------------------------------------------------------------- |
|
|
54
|
+
| `openbot` | Runtime | Standard batteries-included OpenBot agent runtime. |
|
|
55
|
+
| `claude-code` | Runtime | Claude Agent SDK; owns its own tool loop |
|
|
56
|
+
| `gemini-cli` | Runtime | Google `gemini` CLI in headless mode |
|
|
57
|
+
| `bash` | Tool | `bash` (inbuilt in `openbot`) |
|
|
58
|
+
| `storage` | Tool | `create_channel`, `patch_*`, ... (inbuilt in `openbot`) |
|
|
59
|
+
| `memory` | Tool | `remember`, `recall`, `forget` (inbuilt in `openbot`) |
|
|
60
|
+
| `todo` | Tool | `todo_write`, `todo_read` (inbuilt in `openbot`) |
|
|
61
|
+
| `plugin-manager` | Infra | Marketplace list, npm plugin install/uninstall, agent install |
|
|
62
62
|
|
|
63
63
|
## Batteries-included: `openbot` runtime
|
|
64
64
|
|
|
@@ -96,7 +96,9 @@ plugins:
|
|
|
96
96
|
|
|
97
97
|
On first use OpenBot installs the package into
|
|
98
98
|
`~/.openbot/plugins/<npm-name>/` (scoped packages live under
|
|
99
|
-
`~/.openbot/plugins/@scope/<name>/`).
|
|
99
|
+
`~/.openbot/plugins/@scope/<name>/`). Publish `action:plugin:install` with no
|
|
100
|
+
`version` to ensure a plugin is present; pass `version: "latest"` to upgrade an
|
|
101
|
+
existing install to npm's latest tag, or a concrete semver to pin.
|
|
100
102
|
|
|
101
103
|
## Approval plugin
|
|
102
104
|
|
|
@@ -8,27 +8,21 @@ name: Example Agent
|
|
|
8
8
|
description: One-line description shown in agent pickers and lists.
|
|
9
9
|
|
|
10
10
|
# Plugins compose the agent. Order matters for tool collisions (first wins).
|
|
11
|
-
# At least one plugin must handle `agent:invoke
|
|
12
|
-
# `
|
|
13
|
-
#
|
|
14
|
-
# plugin can consume them.
|
|
11
|
+
# At least one plugin must handle `agent:invoke`. Use the monolithic runtime:
|
|
12
|
+
# `@meetopenbot/openbot` (batteries-included: shell, memory, todo, storage tools,
|
|
13
|
+
# delegation, approval, preview).
|
|
15
14
|
#
|
|
16
|
-
#
|
|
17
|
-
# storage-tools, approval.
|
|
15
|
+
# Core built-in plugin ids: storage, plugin-manager.
|
|
18
16
|
#
|
|
19
17
|
# Community plugins are referenced by their npm package name (e.g.
|
|
20
|
-
# `openbot-plugin-search` or `@
|
|
18
|
+
# `openbot-plugin-search` or `@meetopenbot/openbot`) and are auto-installed
|
|
21
19
|
# on first use into ~/.openbot/plugins/<id>/.
|
|
22
20
|
plugins:
|
|
23
|
-
- id: openbot
|
|
21
|
+
- id: '@meetopenbot/openbot'
|
|
24
22
|
config:
|
|
25
23
|
model: openai/gpt-4o-mini
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- id: storage
|
|
29
|
-
- id: approval
|
|
30
|
-
config:
|
|
31
|
-
actions: [action:shell_exec]
|
|
24
|
+
approval:
|
|
25
|
+
actions: [action:shell_exec]
|
|
32
26
|
---
|
|
33
27
|
|
|
34
28
|
<!--
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openbot",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"build": "tsc && mkdir -p dist/assets && cp src/assets/icon.svg dist/assets/icon.svg",
|
|
12
12
|
"start": "node dist/app/cli.js start",
|
|
13
13
|
"format": "prettier --write .",
|
|
14
|
-
"push": "fly deploy --build-only --push --config deploy/fly.toml -a openbot-runtime --image-label v0.5.
|
|
14
|
+
"push": "fly deploy --build-only --push --config deploy/fly.toml -a openbot-runtime --image-label v0.5.6"
|
|
15
15
|
},
|
|
16
16
|
"bin": {
|
|
17
17
|
"openbot": "./dist/app/cli.js"
|
package/src/app/cli.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { bootstrap } from './bootstrap.js';
|
|
4
|
+
import { ensureDefaultStack } from './ensure-default-stack.js';
|
|
4
5
|
import { startServer } from './server.js';
|
|
5
6
|
|
|
6
7
|
const program = new Command();
|
|
@@ -26,7 +27,7 @@ function checkNodeVersion() {
|
|
|
26
27
|
|
|
27
28
|
checkNodeVersion();
|
|
28
29
|
|
|
29
|
-
program.name('openbot').description('OpenBot CLI').version('0.5.
|
|
30
|
+
program.name('openbot').description('OpenBot CLI').version('0.5.6');
|
|
30
31
|
|
|
31
32
|
program
|
|
32
33
|
.command('start')
|
|
@@ -34,6 +35,7 @@ program
|
|
|
34
35
|
.option('-p, --port <number>', 'Port to listen on')
|
|
35
36
|
.action(async (options) => {
|
|
36
37
|
await bootstrap();
|
|
38
|
+
await ensureDefaultStack();
|
|
37
39
|
await startServer(options);
|
|
38
40
|
});
|
|
39
41
|
|
package/src/app/cloud-mode.ts
CHANGED
|
@@ -1,35 +1,20 @@
|
|
|
1
1
|
import { ORCHESTRATOR_AGENT_ID } from './agent-ids.js';
|
|
2
2
|
|
|
3
|
-
/** Platform-managed OpenBot (Fly
|
|
3
|
+
/** Platform-managed OpenBot (Fly). Self-hosted when unset. */
|
|
4
4
|
export const isCloudMode = (): boolean => process.env.OPENBOT_CLOUD_MODE === '1';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
export
|
|
6
|
+
/** How the cloud system agent authenticates to LLM providers. */
|
|
7
|
+
export type OpenbotAuthMode = 'credits' | 'byok';
|
|
8
8
|
|
|
9
|
-
/** Default cloud
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
export interface CloudIntegrationsConfig {
|
|
13
|
-
baseUrl: string;
|
|
14
|
-
token: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getCloudIntegrationsConfig(): CloudIntegrationsConfig | null {
|
|
18
|
-
if (!isCloudMode()) return null;
|
|
19
|
-
|
|
20
|
-
const baseUrl = process.env.OPENBOT_INTEGRATIONS_BASE_URL?.trim();
|
|
21
|
-
const token = process.env.OPENBOT_INTEGRATIONS_TOKEN?.trim();
|
|
22
|
-
if (!baseUrl || !token) return null;
|
|
23
|
-
|
|
24
|
-
return { baseUrl: baseUrl.replace(/\/$/, ''), token };
|
|
25
|
-
}
|
|
9
|
+
/** Default cloud openbot plugin auth mode. */
|
|
10
|
+
export const DEFAULT_CLOUD_OPENBOT_AUTH_MODE: OpenbotAuthMode = 'credits';
|
|
26
11
|
|
|
27
12
|
export function isCloudSystemAgent(agentId: string): boolean {
|
|
28
13
|
return isCloudMode() && agentId === ORCHESTRATOR_AGENT_ID;
|
|
29
14
|
}
|
|
30
15
|
|
|
31
|
-
export function
|
|
32
|
-
return
|
|
16
|
+
export function parseOpenbotAuthMode(value: unknown): OpenbotAuthMode {
|
|
17
|
+
return value === 'byok' ? 'byok' : 'credits';
|
|
33
18
|
}
|
|
34
19
|
|
|
35
20
|
export function assertCloudSystemAgentPluginsMutable(
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import matter from 'gray-matter';
|
|
5
|
+
import { ORCHESTRATOR_AGENT_ID } from './agent-ids.js';
|
|
6
|
+
import { DEFAULT_SYSTEM_AGENT_MODEL, OPENBOT_PLUGIN_ID } from './openbot-plugin.js';
|
|
7
|
+
import { DEFAULT_CLOUD_OPENBOT_AUTH_MODE, isCloudMode } from './cloud-mode.js';
|
|
8
|
+
import { DEFAULT_AGENTS_DIR, getBaseDir } from './config.js';
|
|
9
|
+
import { pluginService } from '../services/plugins/service.js';
|
|
10
|
+
|
|
11
|
+
function systemAgentMdPath(): string {
|
|
12
|
+
return path.join(getBaseDir(), DEFAULT_AGENTS_DIR, ORCHESTRATOR_AGENT_ID, 'AGENT.md');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function defaultSystemPluginConfig(): Record<string, unknown> {
|
|
16
|
+
const config: Record<string, unknown> = {
|
|
17
|
+
model: DEFAULT_SYSTEM_AGENT_MODEL,
|
|
18
|
+
};
|
|
19
|
+
if (isCloudMode()) {
|
|
20
|
+
config.authMode = DEFAULT_CLOUD_OPENBOT_AUTH_MODE;
|
|
21
|
+
}
|
|
22
|
+
return config;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function ensureOpenbotPluginInstalled(): Promise<void> {
|
|
26
|
+
if (await pluginService.isInstalled(OPENBOT_PLUGIN_ID)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`[bootstrap] Installing ${OPENBOT_PLUGIN_ID} from npm`);
|
|
31
|
+
await pluginService.install({ packageName: OPENBOT_PLUGIN_ID });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function ensureSystemAgentMaterialized(): Promise<void> {
|
|
35
|
+
const agentMdPath = systemAgentMdPath();
|
|
36
|
+
if (existsSync(agentMdPath)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const agentDir = path.dirname(agentMdPath);
|
|
41
|
+
await fs.mkdir(agentDir, { recursive: true });
|
|
42
|
+
|
|
43
|
+
const frontmatter = {
|
|
44
|
+
name: 'OpenBot',
|
|
45
|
+
description: 'First-party orchestration agent for OpenBot.',
|
|
46
|
+
plugins: [
|
|
47
|
+
{
|
|
48
|
+
id: OPENBOT_PLUGIN_ID,
|
|
49
|
+
config: defaultSystemPluginConfig(),
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const content = matter.stringify('', frontmatter);
|
|
55
|
+
await fs.writeFile(agentMdPath, content, 'utf-8');
|
|
56
|
+
console.log(`[bootstrap] Materialized system agent at ${agentMdPath}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Install the default agent plugin from npm and materialize the system agent on first boot. */
|
|
60
|
+
export async function ensureDefaultStack(): Promise<void> {
|
|
61
|
+
await ensureOpenbotPluginInstalled();
|
|
62
|
+
await ensureSystemAgentMaterialized();
|
|
63
|
+
}
|
package/src/app/server.ts
CHANGED
|
@@ -9,7 +9,7 @@ const require = createRequire(import.meta.url);
|
|
|
9
9
|
const pkg = require('../../package.json');
|
|
10
10
|
import { generateId } from 'melony';
|
|
11
11
|
import { getBaseDir, loadConfig } from '../app/config.js';
|
|
12
|
-
import { isCloudMode
|
|
12
|
+
import { isCloudMode } from './cloud-mode.js';
|
|
13
13
|
import { ActiveRunsSnapshotEvent, OpenBotEvent, OpenBotState } from './types.js';
|
|
14
14
|
import { processService } from '../services/process.js';
|
|
15
15
|
import { runAgent, STATE_AGENT_ID, ORCHESTRATOR_AGENT_ID } from '../harness/index.js';
|
|
@@ -48,10 +48,7 @@ export async function startServer(options: ServerOptions = {}) {
|
|
|
48
48
|
processService.syncWorkspaceVariablesToProcessEnv();
|
|
49
49
|
|
|
50
50
|
if (isCloudMode()) {
|
|
51
|
-
|
|
52
|
-
console.log(
|
|
53
|
-
`[server] Cloud mode enabled${integrations ? '' : ' (integrations proxy env not set)'}`,
|
|
54
|
-
);
|
|
51
|
+
console.log('[server] Cloud mode enabled');
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
const openBotDir = getBaseDir();
|
package/src/app/types.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '../services/plugins/domain.js';
|
|
10
10
|
import type { PluginRef } from '../services/plugins/types.js';
|
|
11
11
|
import type { MemoryRecord } from '../plugins/memory/service.js';
|
|
12
|
-
import type { TodoList } from '../
|
|
12
|
+
import type { TodoList } from '../services/todo/types.js';
|
|
13
13
|
|
|
14
14
|
export interface OpenBotState {
|
|
15
15
|
agentId: string;
|
|
@@ -324,7 +324,7 @@ export type PatchThreadDetailsResultEvent = BaseEvent & {
|
|
|
324
324
|
type: 'action:patch_thread_details:result';
|
|
325
325
|
data: {
|
|
326
326
|
success: boolean;
|
|
327
|
-
updatedFields:
|
|
327
|
+
updatedFields: 'state'[];
|
|
328
328
|
};
|
|
329
329
|
};
|
|
330
330
|
|
|
@@ -658,12 +658,7 @@ export type UIWidgetField = {
|
|
|
658
658
|
defaultValue?: unknown;
|
|
659
659
|
};
|
|
660
660
|
|
|
661
|
-
export type UIWidgetListItemStatusVariant =
|
|
662
|
-
| 'default'
|
|
663
|
-
| 'success'
|
|
664
|
-
| 'warning'
|
|
665
|
-
| 'danger'
|
|
666
|
-
| 'info';
|
|
661
|
+
export type UIWidgetListItemStatusVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';
|
|
667
662
|
|
|
668
663
|
export type UIWidgetListItem = {
|
|
669
664
|
id: string;
|
|
@@ -880,6 +875,7 @@ export type InstallPluginEvent = BaseEvent & {
|
|
|
880
875
|
type: 'action:plugin:install';
|
|
881
876
|
data: {
|
|
882
877
|
name: string;
|
|
878
|
+
/** Concrete semver, or `"latest"` to upgrade an existing install. Omit to ensure present. */
|
|
883
879
|
version?: string;
|
|
884
880
|
};
|
|
885
881
|
};
|
package/src/harness/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { ToolDefinition } from '../services/plugins/types.js';
|
|
|
8
8
|
import { abortRegistry, abortKey } from '../services/abort.js';
|
|
9
9
|
import { loadConfig } from '../app/config.js';
|
|
10
10
|
import { getPublicBaseUrl } from '../plugins/storage/files.js';
|
|
11
|
+
import { createPluginHost } from '../services/plugins/host.js';
|
|
11
12
|
|
|
12
13
|
export { STATE_AGENT_ID, ORCHESTRATOR_AGENT_ID };
|
|
13
14
|
|
|
@@ -119,6 +120,8 @@ export async function runAgent(options: RunAgentOptions): Promise<void> {
|
|
|
119
120
|
|
|
120
121
|
const builder = melony<OpenBotState, OpenBotEvent>().initialState(state);
|
|
121
122
|
|
|
123
|
+
const pluginHost = createPluginHost(runAgent);
|
|
124
|
+
|
|
122
125
|
for (const ref of pluginRefs) {
|
|
123
126
|
const plugin = await resolvePlugin(ref.id);
|
|
124
127
|
if (!plugin) continue;
|
|
@@ -132,6 +135,7 @@ export async function runAgent(options: RunAgentOptions): Promise<void> {
|
|
|
132
135
|
tools,
|
|
133
136
|
publicBaseUrl,
|
|
134
137
|
abortSignal,
|
|
138
|
+
host: pluginHost,
|
|
135
139
|
}),
|
|
136
140
|
);
|
|
137
141
|
}
|