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.
@@ -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, modelOptions] = await Promise.all([
1056
+ const [builtIn, fromDisk] = await Promise.all([
1060
1057
  listBuiltInPluginDescriptors(),
1061
1058
  listPluginsFromDisk(),
1062
- listRegistryModelOptions(),
1063
1059
  ]);
1064
1060
 
1065
- const enrichedBuiltIn = builtIn.map((plugin) =>
1066
- enrichOpenbotPluginDescriptor(plugin, modelOptions),
1067
- );
1061
+ const enrichPlugin = (plugin: PluginDescriptor) => enrichOpenbotPluginDescriptor(plugin);
1068
1062
 
1069
- const merged = [...enrichedBuiltIn, ...fromDisk];
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, channelId, threadId, event } = options;
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
- }