openbot 0.3.6 → 0.4.2
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 +10 -19
- package/dist/app/server.js +208 -17
- package/dist/bus/services.js +34 -124
- 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 +95 -47
- 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 +109 -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 +120 -149
- package/dist/plugins/bash/index.js +195 -0
- package/dist/plugins/delegation/index.js +121 -32
- package/dist/plugins/memory/index.js +103 -14
- package/dist/plugins/memory/service.js +152 -0
- package/dist/plugins/openbot/context.js +125 -0
- package/dist/plugins/openbot/history.js +144 -0
- package/dist/plugins/openbot/index.js +71 -0
- package/dist/plugins/openbot/runtime.js +381 -0
- package/dist/plugins/openbot/system-prompt.js +25 -0
- package/dist/plugins/plugin-manager/index.js +189 -0
- package/dist/plugins/shell/index.js +2 -1
- package/dist/plugins/storage/files.js +67 -0
- package/dist/plugins/storage/index.js +750 -0
- package/dist/plugins/storage/service.js +1316 -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 +109 -180
- package/dist/registry/plugins.js +3 -9
- package/dist/services/abort.js +43 -0
- package/dist/services/plugins/domain.js +1 -0
- package/dist/services/plugins/plugin-cache.js +9 -0
- package/dist/services/plugins/registry.js +112 -0
- package/dist/services/plugins/service.js +232 -0
- package/dist/services/plugins/types.js +1 -0
- package/dist/services/process.js +29 -0
- package/dist/services/storage.js +11 -10
- package/dist/services/thread-naming.js +81 -0
- package/docs/agents.md +15 -12
- package/docs/architecture.md +2 -2
- package/docs/plugins.md +29 -17
- package/docs/templates/AGENT.example.md +8 -14
- 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 +14 -31
- package/src/app/server.ts +243 -19
- package/src/app/types.ts +331 -187
- package/src/harness/index.ts +166 -0
- package/src/plugins/approval/index.ts +107 -188
- package/src/plugins/bash/index.ts +232 -0
- package/src/plugins/delegation/index.ts +139 -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 +140 -0
- package/src/plugins/openbot/history.ts +158 -0
- package/src/plugins/openbot/index.ts +79 -0
- package/src/plugins/openbot/runtime.ts +478 -0
- package/src/plugins/openbot/system-prompt.ts +27 -0
- package/src/plugins/plugin-manager/index.ts +224 -0
- package/src/plugins/storage/files.ts +81 -0
- package/src/plugins/storage/index.ts +823 -0
- package/src/{services/storage.ts → plugins/storage/service.ts} +485 -105
- package/src/plugins/ui/index.ts +117 -221
- package/src/services/abort.ts +46 -0
- package/src/{bus/types.ts → services/plugins/domain.ts} +50 -8
- package/src/services/plugins/plugin-cache.ts +13 -0
- package/src/{registry/plugins.ts → services/plugins/registry.ts} +28 -28
- package/src/services/plugins/service.ts +318 -0
- package/src/{bus/plugin.ts → services/plugins/types.ts} +7 -3
- package/src/bus/services.ts +0 -954
- package/src/harness/context.ts +0 -365
- 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/shell/index.ts +0 -123
- package/src/plugins/storage-tools/index.ts +0 -90
- package/src/plugins/todo/index.ts +0 -64
- package/src/services/plugins.ts +0 -133
- /package/src/{harness → services}/process.ts +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { OpenBotState } from '../../app/types.js';
|
|
2
|
+
import { Storage } from '../../services/plugins/domain.js';
|
|
3
|
+
import { OPENBOT_SYSTEM_PROMPT } from './system-prompt.js';
|
|
4
|
+
|
|
5
|
+
export const DEFAULT_CONTEXT_BUDGET = 8000;
|
|
6
|
+
export const MAX_CONTEXT_FILES = 50;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns the known context window budget (in tokens) for a given model string.
|
|
10
|
+
*/
|
|
11
|
+
export const getContextBudgetForModel = (modelString: string): number => {
|
|
12
|
+
const budgets: Record<string, number> = {
|
|
13
|
+
'openai/gpt-4o': 128000,
|
|
14
|
+
'openai/gpt-4o-mini': 128000,
|
|
15
|
+
'openai/o1-preview': 128000,
|
|
16
|
+
'openai/o1-mini': 128000,
|
|
17
|
+
'anthropic/claude-3-5-sonnet-20240620': 200000,
|
|
18
|
+
'anthropic/claude-3-5-sonnet-latest': 200000,
|
|
19
|
+
'anthropic/claude-3-opus-20240229': 200000,
|
|
20
|
+
'anthropic/claude-3-sonnet-20240229': 200000,
|
|
21
|
+
'anthropic/claude-3-haiku-20240307': 200000,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return budgets[modelString] || DEFAULT_CONTEXT_BUDGET;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Built-in orchestrator agent id. */
|
|
28
|
+
export const ORCHESTRATOR_AGENT_ID = 'system';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if a channel is a solo DM (only the agent is present).
|
|
32
|
+
*/
|
|
33
|
+
export function isDmSoloChannel(participants: string[], agentId: string): boolean {
|
|
34
|
+
return participants.length === 0 || (participants.length === 1 && participants[0] === agentId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Simplified context builder for MVP.
|
|
39
|
+
*/
|
|
40
|
+
export async function buildContext(state: OpenBotState, storage?: Storage): Promise<string> {
|
|
41
|
+
const { channelId, threadId, channelDetails, agentId, threadDetails, agentDetails } = state;
|
|
42
|
+
const participants = channelDetails?.participants || [];
|
|
43
|
+
const isDm = isDmSoloChannel(participants, agentId);
|
|
44
|
+
|
|
45
|
+
const sections: string[] = [];
|
|
46
|
+
|
|
47
|
+
// Fetch agents once if storage is available
|
|
48
|
+
const allAgents = storage?.getAgents ? await storage.getAgents().catch(() => []) : [];
|
|
49
|
+
|
|
50
|
+
// 1. User
|
|
51
|
+
if (state.currentUser?.userName) {
|
|
52
|
+
sections.push(`## HUMAN\n- Name: ${state.currentUser.userName}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 2. Environment
|
|
56
|
+
let env = '## ENVIRONMENT\n';
|
|
57
|
+
if (isDm) {
|
|
58
|
+
env += '- Mode: Direct Message (Solo)\n';
|
|
59
|
+
} else {
|
|
60
|
+
const channelName = channelDetails?.name || channelId;
|
|
61
|
+
env += `- Mode: Channel (#${channelName})\n`;
|
|
62
|
+
if (channelDetails?.cwd) {
|
|
63
|
+
env += `- Workspace: ${channelDetails.cwd}\n`;
|
|
64
|
+
}
|
|
65
|
+
if (threadId) {
|
|
66
|
+
env += `- Thread: ${threadDetails?.name || threadId}\n`;
|
|
67
|
+
}
|
|
68
|
+
const peerIds = participants.filter((id: string) => id !== agentId);
|
|
69
|
+
const participantLabels = peerIds.map((id) => {
|
|
70
|
+
const agent = allAgents.find((a) => a.id === id);
|
|
71
|
+
return agent ? `${agent.name} (${id})` : id;
|
|
72
|
+
});
|
|
73
|
+
env += `- Participants: ${participantLabels.length > 0 ? participantLabels.join(', ') : 'None'}\n`;
|
|
74
|
+
}
|
|
75
|
+
sections.push(env);
|
|
76
|
+
|
|
77
|
+
// 2.5 Installed Agents
|
|
78
|
+
if (allAgents.length > 0) {
|
|
79
|
+
const formatted = allAgents
|
|
80
|
+
.map((a) => `- ${a.id}: ${a.name}${a.description ? ` - ${a.description}` : ''}`)
|
|
81
|
+
.join('\n');
|
|
82
|
+
sections.push(`## INSTALLED AGENTS\n${formatted}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 3. Channel Spec
|
|
86
|
+
const spec = channelDetails?.spec?.trim();
|
|
87
|
+
if (spec) {
|
|
88
|
+
sections.push(`## CHANNEL SPECIFICATION\n${spec}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 4. Files
|
|
92
|
+
if (storage?.listFiles && channelId && channelDetails?.cwd) {
|
|
93
|
+
try {
|
|
94
|
+
const files = await storage.listFiles({ channelId });
|
|
95
|
+
if (files.length > 0) {
|
|
96
|
+
const limited = files.slice(0, MAX_CONTEXT_FILES);
|
|
97
|
+
const formatted = limited
|
|
98
|
+
.map((f) => `- ${f.name}${f.isDirectory ? '/' : ''}`)
|
|
99
|
+
.join('\n');
|
|
100
|
+
let fileSection = `## FILES\n${formatted}`;
|
|
101
|
+
if (files.length > MAX_CONTEXT_FILES) {
|
|
102
|
+
fileSection += `\n- ... and ${files.length - MAX_CONTEXT_FILES} more files`;
|
|
103
|
+
}
|
|
104
|
+
sections.push(fileSection);
|
|
105
|
+
} else {
|
|
106
|
+
sections.push('## FILES\n- (No files in workspace)');
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.warn('[context] Failed to fetch files:', error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 5. Agent Instructions
|
|
114
|
+
const rawInstructions = agentDetails?.instructions?.trim();
|
|
115
|
+
if (
|
|
116
|
+
rawInstructions &&
|
|
117
|
+
rawInstructions !== OPENBOT_SYSTEM_PROMPT.trim()
|
|
118
|
+
) {
|
|
119
|
+
sections.push(`## Instructions\n${rawInstructions}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 6. Memories
|
|
123
|
+
if (storage?.listMemories) {
|
|
124
|
+
try {
|
|
125
|
+
const scopes = ['global', `agent:${agentId}`];
|
|
126
|
+
if (channelId) scopes.push(`channel:${channelId}`);
|
|
127
|
+
const records = await storage.listMemories({ scopes, limit: 20 });
|
|
128
|
+
if (records.length > 0) {
|
|
129
|
+
const formatted = records
|
|
130
|
+
.map((r: any) => `- (${r.scope}) ${r.content}`)
|
|
131
|
+
.join('\n');
|
|
132
|
+
sections.push(`## MEMORIES\n${formatted}`);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.warn('[context] Failed to fetch memories:', error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return sections.join('\n\n');
|
|
140
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { OpenBotEvent } from '../../app/types.js';
|
|
2
|
+
import { ToolResultPart, type ModelMessage } from 'ai';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Ensures every tool-call has a matching tool-result before calling the LLM.
|
|
6
|
+
* Orphaned calls (interrupted run, missing :result event, etc.) get an empty
|
|
7
|
+
* result so the conversation can resume instead of failing validation.
|
|
8
|
+
*/
|
|
9
|
+
function fillMissingToolResults(messages: ModelMessage[]): ModelMessage[] {
|
|
10
|
+
const filled: ModelMessage[] = [];
|
|
11
|
+
const pending = new Map<string, string>();
|
|
12
|
+
|
|
13
|
+
const flushPending = () => {
|
|
14
|
+
if (pending.size === 0) return;
|
|
15
|
+
filled.push({
|
|
16
|
+
role: 'tool',
|
|
17
|
+
content: [...pending.entries()].map(([toolCallId, toolName]) => ({
|
|
18
|
+
type: 'tool-result' as const,
|
|
19
|
+
toolCallId,
|
|
20
|
+
toolName,
|
|
21
|
+
output: { type: 'text' as const, value: '' },
|
|
22
|
+
})),
|
|
23
|
+
});
|
|
24
|
+
pending.clear();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
for (const message of messages) {
|
|
28
|
+
if (message.role === 'tool' && Array.isArray(message.content)) {
|
|
29
|
+
filled.push(message);
|
|
30
|
+
for (const part of message.content) {
|
|
31
|
+
if ((part as ToolResultPart).type === 'tool-result') {
|
|
32
|
+
pending.delete((part as ToolResultPart).toolCallId);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
flushPending();
|
|
39
|
+
filled.push(message);
|
|
40
|
+
|
|
41
|
+
if (message.role === 'assistant' && Array.isArray(message.content)) {
|
|
42
|
+
for (const part of message.content) {
|
|
43
|
+
if ((part as { type?: string; toolCallId?: string; toolName?: string }).type === 'tool-call') {
|
|
44
|
+
const toolCall = part as { toolCallId: string; toolName: string };
|
|
45
|
+
pending.set(toolCall.toolCallId, toolCall.toolName);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
flushPending();
|
|
52
|
+
return filled;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Converts a raw event log into a valid chain of ModelMessages for the AI SDK.
|
|
57
|
+
*
|
|
58
|
+
* This is a basic implementation that maps events to messages and filters out
|
|
59
|
+
* events from sub-processes (delegation) to avoid duplication in history.
|
|
60
|
+
*/
|
|
61
|
+
export function eventsToModelMessages(events: OpenBotEvent[]): ModelMessage[] {
|
|
62
|
+
const messages: ModelMessage[] = [];
|
|
63
|
+
|
|
64
|
+
for (const event of events) {
|
|
65
|
+
// Skip events that belong to a sub-process (like delegation)
|
|
66
|
+
// so they don't pollute the main conversation history.
|
|
67
|
+
if (event.meta?.parentToolCallId) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
switch (event.type) {
|
|
72
|
+
case 'agent:output': {
|
|
73
|
+
const last = messages[messages.length - 1];
|
|
74
|
+
if (last && last.role === 'assistant' && typeof last.content === 'string') {
|
|
75
|
+
last.content += event.data.content;
|
|
76
|
+
} else {
|
|
77
|
+
messages.push({ role: 'assistant', content: event.data.content });
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case 'agent:invoke': {
|
|
83
|
+
const invokeEvent = event as any;
|
|
84
|
+
if (invokeEvent.data?.content && invokeEvent.data?.role) {
|
|
85
|
+
messages.push({
|
|
86
|
+
role: invokeEvent.data.role,
|
|
87
|
+
content: invokeEvent.data.content
|
|
88
|
+
} as ModelMessage);
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
default:
|
|
94
|
+
// Handle tool calls (action:*)
|
|
95
|
+
if (event.type.startsWith('action:') && !event.type.endsWith(':result')) {
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
const toolName = event.type.slice(7);
|
|
99
|
+
const toolCallId = event.meta?.toolCallId;
|
|
100
|
+
if (!toolCallId) break;
|
|
101
|
+
|
|
102
|
+
const toolCall = {
|
|
103
|
+
type: 'tool-call' as const,
|
|
104
|
+
toolCallId,
|
|
105
|
+
toolName,
|
|
106
|
+
input: (event as any).data,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const last = messages[messages.length - 1];
|
|
110
|
+
|
|
111
|
+
if (last && last.role === 'assistant') {
|
|
112
|
+
if (typeof last.content === 'string') {
|
|
113
|
+
last.content = [
|
|
114
|
+
{ type: 'text', text: last.content },
|
|
115
|
+
toolCall,
|
|
116
|
+
];
|
|
117
|
+
} else if (Array.isArray(last.content)) {
|
|
118
|
+
(last.content as any[]).push(toolCall);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
messages.push({
|
|
122
|
+
role: 'assistant',
|
|
123
|
+
content: [toolCall],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Handle tool results (action:*:result)
|
|
128
|
+
else if (event.type.startsWith('action:') && event.type.endsWith(':result')) {
|
|
129
|
+
const toolName = event.type.slice(7, -7);
|
|
130
|
+
const toolCallId = event.meta?.toolCallId;
|
|
131
|
+
if (!toolCallId) break;
|
|
132
|
+
|
|
133
|
+
const toolResult: ToolResultPart = {
|
|
134
|
+
type: 'tool-result' as const,
|
|
135
|
+
toolCallId,
|
|
136
|
+
toolName,
|
|
137
|
+
output: {
|
|
138
|
+
type: 'text',
|
|
139
|
+
value: (event as any)?.data?.output || "No output", // ?.output is from delegation result
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const last = messages[messages.length - 1];
|
|
144
|
+
if (last && last.role === 'tool' && Array.isArray(last.content)) {
|
|
145
|
+
(last.content as any[]).push(toolResult);
|
|
146
|
+
} else {
|
|
147
|
+
messages.push({
|
|
148
|
+
role: 'tool',
|
|
149
|
+
content: [toolResult],
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return fillMissingToolResults(messages);
|
|
158
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Plugin } from '../../services/plugins/types.js';
|
|
2
|
+
import { openbotRuntime } from './runtime.js';
|
|
3
|
+
import { bashPlugin } from '../bash/index.js';
|
|
4
|
+
import { memoryPlugin } from '../memory/index.js';
|
|
5
|
+
import { approvalPlugin } from '../approval/index.js';
|
|
6
|
+
import { storagePlugin } from '../storage/index.js';
|
|
7
|
+
import { delegationPlugin } from '../delegation/index.js';
|
|
8
|
+
import { uiPlugin } from '../ui/index.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `openbot` — the standard, opinionated OpenBot agent runtime.
|
|
12
|
+
*
|
|
13
|
+
* This is the canonical execution loop for OpenBot agents. It handles
|
|
14
|
+
* `agent:invoke`, manages short-term memory, assembles context, and
|
|
15
|
+
* orchestrates tool calls.
|
|
16
|
+
*
|
|
17
|
+
* It comes with a "batteries-included" set of inbuilt tools: bash, memory,
|
|
18
|
+
* storage, delegation, and approval.
|
|
19
|
+
*/
|
|
20
|
+
export const openbotPlugin: Plugin = {
|
|
21
|
+
id: 'openbot',
|
|
22
|
+
name: 'OpenBot Agent',
|
|
23
|
+
description:
|
|
24
|
+
'The standard OpenBot agent runtime with inbuilt tools (bash, memory, storage, delegation, and approval).',
|
|
25
|
+
configSchema: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
model: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description:
|
|
31
|
+
'Provider model string, e.g. openai/gpt-4o-mini, anthropic/claude-3-5-sonnet-20240620',
|
|
32
|
+
default: 'openai/gpt-4o-mini',
|
|
33
|
+
},
|
|
34
|
+
approval: {
|
|
35
|
+
type: 'object',
|
|
36
|
+
description: 'Configuration for the inbuilt approval plugin.',
|
|
37
|
+
properties: {
|
|
38
|
+
actions: {
|
|
39
|
+
type: 'array',
|
|
40
|
+
items: { type: 'string' },
|
|
41
|
+
description: 'List of actions that require manual approval.',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
toolDefinitions: {
|
|
48
|
+
...bashPlugin.toolDefinitions,
|
|
49
|
+
...memoryPlugin.toolDefinitions,
|
|
50
|
+
...storagePlugin.toolDefinitions,
|
|
51
|
+
...delegationPlugin.toolDefinitions,
|
|
52
|
+
...uiPlugin.toolDefinitions,
|
|
53
|
+
},
|
|
54
|
+
factory: (context) => (builder) => {
|
|
55
|
+
const { config, storage, tools, abortSignal } = context;
|
|
56
|
+
|
|
57
|
+
// Register inbuilt plugins
|
|
58
|
+
bashPlugin.factory(context)(builder);
|
|
59
|
+
memoryPlugin.factory(context)(builder);
|
|
60
|
+
storagePlugin.factory(context)(builder);
|
|
61
|
+
delegationPlugin.factory(context)(builder);
|
|
62
|
+
uiPlugin.factory(context)(builder);
|
|
63
|
+
|
|
64
|
+
// Approval plugin configuration
|
|
65
|
+
const approvalConfig = (config?.approval as any) || {
|
|
66
|
+
actions: ['action:bash', 'action:create_channel', 'action:delete_channel'],
|
|
67
|
+
};
|
|
68
|
+
approvalPlugin.factory({ ...context, config: approvalConfig })(builder);
|
|
69
|
+
|
|
70
|
+
return openbotRuntime({
|
|
71
|
+
model: config?.model as string,
|
|
72
|
+
storage,
|
|
73
|
+
toolDefinitions: tools,
|
|
74
|
+
abortSignal,
|
|
75
|
+
})(builder);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default openbotPlugin;
|