openbot 0.5.8 → 0.5.10
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 +1 -1
- package/dist/app/active-runs.js +70 -0
- package/dist/app/cli.js +1 -1
- package/dist/app/lifecycle-events.js +27 -0
- package/dist/app/run-event-handler.js +37 -0
- package/dist/app/server.js +127 -123
- package/dist/app/slack-webhook.js +81 -0
- package/dist/app/webhook-routing.js +52 -0
- package/dist/harness/index.js +18 -15
- package/dist/harness/merge-plugin-config.js +26 -0
- package/dist/plugins/slack-webhook/index.js +51 -0
- package/dist/plugins/storage/index.js +72 -14
- package/dist/plugins/storage/service.js +11 -6
- package/dist/services/plugins/enrich-openbot-plugin.js +38 -0
- package/dist/services/plugins/host.js +0 -3
- package/dist/services/plugins/model-registry.js +1 -1
- package/docs/plugins.md +27 -0
- package/package.json +2 -2
- package/src/app/active-runs.ts +95 -0
- package/src/app/cli.ts +1 -1
- package/src/app/lifecycle-events.ts +46 -0
- package/src/app/run-event-handler.ts +55 -0
- package/src/app/server.ts +147 -154
- package/src/app/types.ts +33 -4
- package/src/app/webhook-routing.ts +70 -0
- package/src/harness/index.ts +19 -20
- package/src/harness/merge-plugin-config.ts +35 -0
- package/src/plugins/storage/index.ts +432 -372
- package/src/plugins/storage/service.ts +13 -13
- package/src/services/plugins/enrich-openbot-plugin.ts +41 -0
- package/src/services/plugins/host.ts +0 -6
- package/src/services/plugins/types.ts +0 -8
- package/src/services/plugins/model-registry.ts +0 -178
|
@@ -33,10 +33,7 @@ import {
|
|
|
33
33
|
import type { PluginRef } from '../../services/plugins/types.js';
|
|
34
34
|
import { OPENBOT_PLUGIN_ID } from '../../app/openbot-plugin.js';
|
|
35
35
|
import { listBuiltInPlugins, parsePluginModule } from '../../services/plugins/registry.js';
|
|
36
|
-
import {
|
|
37
|
-
enrichOpenbotPluginDescriptor,
|
|
38
|
-
listRegistryModelOptions,
|
|
39
|
-
} from '../../services/plugins/model-registry.js';
|
|
36
|
+
import { enrichOpenbotPluginDescriptor } from '../../services/plugins/enrich-openbot-plugin.js';
|
|
40
37
|
import { OpenBotEvent, OpenBotState } from '../../app/types.js';
|
|
41
38
|
import { processService } from '../../services/process.js';
|
|
42
39
|
import { memoryService } from '../memory/service.js';
|
|
@@ -1056,17 +1053,14 @@ export const storageService = {
|
|
|
1056
1053
|
return Array.from(deduped.values()).filter((agent) => !agent.hidden);
|
|
1057
1054
|
},
|
|
1058
1055
|
getPlugins: async (): Promise<PluginDescriptor[]> => {
|
|
1059
|
-
const [builtIn, fromDisk
|
|
1056
|
+
const [builtIn, fromDisk] = await Promise.all([
|
|
1060
1057
|
listBuiltInPluginDescriptors(),
|
|
1061
1058
|
listPluginsFromDisk(),
|
|
1062
|
-
listRegistryModelOptions(),
|
|
1063
1059
|
]);
|
|
1064
1060
|
|
|
1065
|
-
const
|
|
1066
|
-
enrichOpenbotPluginDescriptor(plugin, modelOptions),
|
|
1067
|
-
);
|
|
1061
|
+
const enrichPlugin = (plugin: PluginDescriptor) => enrichOpenbotPluginDescriptor(plugin);
|
|
1068
1062
|
|
|
1069
|
-
const merged = [...
|
|
1063
|
+
const merged = [...builtIn.map(enrichPlugin), ...fromDisk.map(enrichPlugin)];
|
|
1070
1064
|
const deduped = new Map<string, PluginDescriptor>();
|
|
1071
1065
|
for (const plugin of merged) {
|
|
1072
1066
|
if (!deduped.has(plugin.id)) {
|
|
@@ -1756,11 +1750,17 @@ export const storageService = {
|
|
|
1756
1750
|
getOpenBotState: async (options: {
|
|
1757
1751
|
runId: string;
|
|
1758
1752
|
agentId: string;
|
|
1759
|
-
channelId: string;
|
|
1760
|
-
threadId?: string;
|
|
1761
1753
|
event: OpenBotEvent;
|
|
1762
1754
|
}): Promise<OpenBotState> => {
|
|
1763
|
-
const { runId, agentId,
|
|
1755
|
+
const { runId, agentId, event } = options;
|
|
1756
|
+
const channelId =
|
|
1757
|
+
typeof event.meta?.channelId === 'string'
|
|
1758
|
+
? event.meta.channelId.trim() || undefined
|
|
1759
|
+
: undefined;
|
|
1760
|
+
const threadId =
|
|
1761
|
+
typeof event.meta?.threadId === 'string'
|
|
1762
|
+
? event.meta.threadId.trim() || undefined
|
|
1763
|
+
: undefined;
|
|
1764
1764
|
|
|
1765
1765
|
let agentDetails: AgentDetails;
|
|
1766
1766
|
try {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { OPENBOT_PLUGIN_ID } from '../../app/openbot-plugin.js';
|
|
2
|
+
import { DEFAULT_CLOUD_OPENBOT_AUTH_MODE, isCloudMode } from '../../app/cloud-mode.js';
|
|
3
|
+
import type { ConfigSchema, PluginDescriptor } from './domain.js';
|
|
4
|
+
|
|
5
|
+
/** Injects cloud platform fields into the openbot plugin descriptor for settings UI. */
|
|
6
|
+
export function enrichOpenbotPluginDescriptor(descriptor: PluginDescriptor): PluginDescriptor {
|
|
7
|
+
if (descriptor.id !== OPENBOT_PLUGIN_ID || !descriptor.configSchema) return descriptor;
|
|
8
|
+
if (!isCloudMode()) return descriptor;
|
|
9
|
+
|
|
10
|
+
const { authMode: _authMode, ...otherProperties } = descriptor.configSchema.properties;
|
|
11
|
+
|
|
12
|
+
const cloudAuthModeProperty: ConfigSchema['properties'][string] = {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Credits uses OpenBot platform billing. BYOK uses your own API keys.',
|
|
15
|
+
enum: ['credits', 'byok'],
|
|
16
|
+
default: DEFAULT_CLOUD_OPENBOT_AUTH_MODE,
|
|
17
|
+
options: [
|
|
18
|
+
{
|
|
19
|
+
label: 'Credits',
|
|
20
|
+
value: 'credits',
|
|
21
|
+
description: 'Use OpenBot platform credits.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: 'Bring your own key',
|
|
25
|
+
value: 'byok',
|
|
26
|
+
description: 'Use your own provider API keys.',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
...descriptor,
|
|
33
|
+
configSchema: {
|
|
34
|
+
...descriptor.configSchema,
|
|
35
|
+
properties: {
|
|
36
|
+
authMode: cloudAuthModeProperty,
|
|
37
|
+
...otherProperties,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -8,10 +8,6 @@ import {
|
|
|
8
8
|
import { ORCHESTRATOR_AGENT_ID } from '../../app/agent-ids.js';
|
|
9
9
|
import { OPENBOT_PLUGIN_ID } from '../../app/openbot-plugin.js';
|
|
10
10
|
import { getBaseDir, resolvePath, saveConfig } from '../../app/config.js';
|
|
11
|
-
import {
|
|
12
|
-
listApiKeyProvidersFromRegistry,
|
|
13
|
-
resolveModelRegistry,
|
|
14
|
-
} from './model-registry.js';
|
|
15
11
|
import type { PluginHost, RunAgentHostOptions } from './types.js';
|
|
16
12
|
|
|
17
13
|
export function createPluginHost(
|
|
@@ -22,8 +18,6 @@ export function createPluginHost(
|
|
|
22
18
|
isCloudSystemAgent,
|
|
23
19
|
isCloudMode,
|
|
24
20
|
parseOpenbotAuthMode,
|
|
25
|
-
resolveModelRegistry,
|
|
26
|
-
listApiKeyProvidersFromRegistry,
|
|
27
21
|
saveConfig,
|
|
28
22
|
getBaseDir,
|
|
29
23
|
resolvePath,
|
|
@@ -25,8 +25,6 @@ export interface RunAgentHostOptions {
|
|
|
25
25
|
runId: string;
|
|
26
26
|
agentId: string;
|
|
27
27
|
event: OpenBotEvent;
|
|
28
|
-
channelId: string;
|
|
29
|
-
threadId?: string;
|
|
30
28
|
persistEvents?: boolean;
|
|
31
29
|
publicBaseUrl?: string;
|
|
32
30
|
onEvent: (event: OpenBotEvent, state?: OpenBotState) => Promise<void>;
|
|
@@ -38,12 +36,6 @@ export interface PluginHost {
|
|
|
38
36
|
isCloudSystemAgent: (agentId: string) => boolean;
|
|
39
37
|
isCloudMode: () => boolean;
|
|
40
38
|
parseOpenbotAuthMode: (value: unknown) => 'credits' | 'byok';
|
|
41
|
-
resolveModelRegistry: () => ReturnType<
|
|
42
|
-
typeof import('./model-registry.js').resolveModelRegistry
|
|
43
|
-
>;
|
|
44
|
-
listApiKeyProvidersFromRegistry: (
|
|
45
|
-
registry: Awaited<ReturnType<PluginHost['resolveModelRegistry']>>,
|
|
46
|
-
) => Array<{ id: string; label: string }>;
|
|
47
39
|
saveConfig: (patch: Record<string, unknown>) => void;
|
|
48
40
|
getBaseDir: () => string;
|
|
49
41
|
resolvePath: (p: string) => string;
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_MARKETPLACE_REGISTRY_URL,
|
|
3
|
-
loadConfig,
|
|
4
|
-
} from '../../app/config.js';
|
|
5
|
-
import { OPENBOT_PLUGIN_ID } from '../../app/openbot-plugin.js';
|
|
6
|
-
import {
|
|
7
|
-
DEFAULT_CLOUD_OPENBOT_AUTH_MODE,
|
|
8
|
-
isCloudMode,
|
|
9
|
-
} from '../../app/cloud-mode.js';
|
|
10
|
-
import type { ConfigSchema, PluginDescriptor } from './domain.js';
|
|
11
|
-
|
|
12
|
-
export type RegistryProviderCatalog = Record<
|
|
13
|
-
string,
|
|
14
|
-
{
|
|
15
|
-
label: string;
|
|
16
|
-
models: Array<{ id: string; label: string; description: string }>;
|
|
17
|
-
}
|
|
18
|
-
>;
|
|
19
|
-
|
|
20
|
-
export type ModelRegistry = {
|
|
21
|
-
providers?: RegistryProviderCatalog;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type RegistryModelOption = {
|
|
25
|
-
value: string;
|
|
26
|
-
label: string;
|
|
27
|
-
description?: string;
|
|
28
|
-
provider: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let cachedRegistry: ModelRegistry | null = null;
|
|
32
|
-
let cacheUrl: string | null = null;
|
|
33
|
-
|
|
34
|
-
function getRegistryUrl(): string {
|
|
35
|
-
const { marketplaceRegistryUrl } = loadConfig();
|
|
36
|
-
return marketplaceRegistryUrl?.trim() || DEFAULT_MARKETPLACE_REGISTRY_URL;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function resolveModelRegistry(): Promise<ModelRegistry> {
|
|
40
|
-
const url = getRegistryUrl();
|
|
41
|
-
if (cachedRegistry && cacheUrl === url) return cachedRegistry;
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const res = await fetch(url, {
|
|
45
|
-
headers: { Accept: 'application/json' },
|
|
46
|
-
signal: AbortSignal.timeout(15_000),
|
|
47
|
-
});
|
|
48
|
-
if (!res.ok) {
|
|
49
|
-
throw new Error(`Registry HTTP ${res.status} ${res.statusText}`);
|
|
50
|
-
}
|
|
51
|
-
cachedRegistry = (await res.json()) as ModelRegistry;
|
|
52
|
-
cacheUrl = url;
|
|
53
|
-
return cachedRegistry;
|
|
54
|
-
} catch (err) {
|
|
55
|
-
console.warn(
|
|
56
|
-
'[model-registry] fetch failed:',
|
|
57
|
-
err instanceof Error ? err.message : err,
|
|
58
|
-
);
|
|
59
|
-
return { providers: {} };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function listModelOptionsFromRegistry(registry: ModelRegistry): RegistryModelOption[] {
|
|
64
|
-
const providers = registry.providers ?? {};
|
|
65
|
-
const out: RegistryModelOption[] = [];
|
|
66
|
-
|
|
67
|
-
for (const [providerId, provider] of Object.entries(providers)) {
|
|
68
|
-
for (const model of provider.models ?? []) {
|
|
69
|
-
out.push({
|
|
70
|
-
value: `${providerId}/${model.id}`,
|
|
71
|
-
label: `${provider.label} — ${model.label}`,
|
|
72
|
-
description: model.description,
|
|
73
|
-
provider: providerId,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return out;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function listRegistryModelOptions(): Promise<RegistryModelOption[]> {
|
|
82
|
-
const registry = await resolveModelRegistry();
|
|
83
|
-
return listModelOptionsFromRegistry(registry);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function listApiKeyProvidersFromRegistry(
|
|
87
|
-
registry: ModelRegistry,
|
|
88
|
-
): Array<{ id: string; label: string }> {
|
|
89
|
-
const providers = registry.providers ?? {};
|
|
90
|
-
return Object.entries(providers).map(([id, provider]) => ({
|
|
91
|
-
id,
|
|
92
|
-
label: provider.label,
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function pickDefaultModelValue(options: RegistryModelOption[]): string | undefined {
|
|
97
|
-
if (options.length === 0) return undefined;
|
|
98
|
-
const values = options.map((option) => option.value);
|
|
99
|
-
const preferred = values.find((value) => value.startsWith('openai/'));
|
|
100
|
-
return preferred ?? values[0];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function enrichOpenbotPluginDescriptor(
|
|
104
|
-
descriptor: PluginDescriptor,
|
|
105
|
-
modelOptions: RegistryModelOption[],
|
|
106
|
-
): PluginDescriptor {
|
|
107
|
-
if (descriptor.id !== OPENBOT_PLUGIN_ID || !descriptor.configSchema) return descriptor;
|
|
108
|
-
|
|
109
|
-
const modelProperty = descriptor.configSchema.properties.model;
|
|
110
|
-
if (!modelProperty) return descriptor;
|
|
111
|
-
|
|
112
|
-
const values = modelOptions.map((option) => option.value);
|
|
113
|
-
const staticDefault =
|
|
114
|
-
typeof modelProperty.default === 'string' ? modelProperty.default : undefined;
|
|
115
|
-
const defaultModel =
|
|
116
|
-
staticDefault && values.includes(staticDefault)
|
|
117
|
-
? staticDefault
|
|
118
|
-
: pickDefaultModelValue(modelOptions) ?? staticDefault;
|
|
119
|
-
|
|
120
|
-
const nextModelProperty: ConfigSchema['properties'][string] = {
|
|
121
|
-
...modelProperty,
|
|
122
|
-
description: 'Model from the hosted marketplace registry.',
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
if (values.length > 0) {
|
|
126
|
-
nextModelProperty.enum = values;
|
|
127
|
-
nextModelProperty.options = modelOptions.map((option) => ({
|
|
128
|
-
label: option.label,
|
|
129
|
-
value: option.value,
|
|
130
|
-
description: option.description,
|
|
131
|
-
}));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (defaultModel) {
|
|
135
|
-
nextModelProperty.default = defaultModel;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const { model: _model, authMode: _authMode, ...otherProperties } =
|
|
139
|
-
descriptor.configSchema.properties;
|
|
140
|
-
|
|
141
|
-
const cloudAuthModeProperty: ConfigSchema['properties'][string] = {
|
|
142
|
-
type: 'string',
|
|
143
|
-
description: 'Credits uses OpenBot platform billing. BYOK uses your own API keys.',
|
|
144
|
-
enum: ['credits', 'byok'],
|
|
145
|
-
default: DEFAULT_CLOUD_OPENBOT_AUTH_MODE,
|
|
146
|
-
options: [
|
|
147
|
-
{
|
|
148
|
-
label: 'Credits',
|
|
149
|
-
value: 'credits',
|
|
150
|
-
description: 'Use OpenBot platform credits.',
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
label: 'Bring your own key',
|
|
154
|
-
value: 'byok',
|
|
155
|
-
description: 'Use your own provider API keys.',
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const nextProperties: ConfigSchema['properties'] = isCloudMode()
|
|
161
|
-
? {
|
|
162
|
-
authMode: cloudAuthModeProperty,
|
|
163
|
-
model: nextModelProperty,
|
|
164
|
-
...otherProperties,
|
|
165
|
-
}
|
|
166
|
-
: {
|
|
167
|
-
model: nextModelProperty,
|
|
168
|
-
...otherProperties,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
return {
|
|
172
|
-
...descriptor,
|
|
173
|
-
configSchema: {
|
|
174
|
-
...descriptor.configSchema,
|
|
175
|
-
properties: nextProperties,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
}
|