@open1s/ezbos 1.3.0 → 1.3.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 CHANGED
@@ -315,6 +315,38 @@ const mcpTools = await started.listMcpTools();
315
315
  console.log(`MCP tools available: ${mcpTools.length}`);
316
316
  ```
317
317
 
318
+ ### MCP Status Callback
319
+
320
+ Get real-time notifications when each MCP server connects or fails. Useful for UI status updates.
321
+
322
+ ```ts
323
+ const agent = brain.agent('my-agent', {
324
+ onMcpStatus: (namespace, status, error) => {
325
+ console.log(`[MCP] ${namespace}: ${status}`);
326
+ // Update UI status indicator
327
+ },
328
+ })
329
+ .with_mcp_process('files', 'npx', ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'])
330
+ .with_mcp_http('api', 'http://localhost:3000/mcp');
331
+
332
+ const started = await agent.start();
333
+ ```
334
+
335
+ Callback parameters:
336
+ - `namespace` - MCP server name
337
+ - `status` - `'connected'` | `'failed'`
338
+ - `error` - error message string (only present when `status === 'failed'`)
339
+
340
+ The build continues even if an MCP server fails — use the callback to track which ones succeeded or failed.
341
+
342
+ Also works with `BrainOS.with()`:
343
+
344
+ ```ts
345
+ const agent = await BrainOS.with('my-agent', {
346
+ onMcpStatus: (ns, s, e) => { /* ... */ },
347
+ });
348
+ ```
349
+
318
350
  ## Skills
319
351
 
320
352
  Add domain-specific instructions to the system prompt.
package/dist/agent.d.ts CHANGED
@@ -8,6 +8,7 @@ export interface JsContent {
8
8
  base64?: string;
9
9
  name?: string;
10
10
  }
11
+ export type McpStatusCallback = (namespace: string, status: 'connected' | 'failed', error?: string) => void;
11
12
  export declare class AgentBuilder {
12
13
  private _inner;
13
14
  private _tools;
@@ -16,6 +17,7 @@ export declare class AgentBuilder {
16
17
  private _mcp;
17
18
  private _skillsDirs;
18
19
  private _inlineSkills;
20
+ private _onMcpStatus?;
19
21
  private _config;
20
22
  constructor(name: string, options?: {
21
23
  model?: string;
@@ -30,6 +32,7 @@ export declare class AgentBuilder {
30
32
  rateLimitCapacity?: number;
31
33
  rateLimitWindowSecs?: number;
32
34
  rateLimitMaxRetries?: number;
35
+ onMcpStatus?: McpStatusCallback;
33
36
  });
34
37
  with_model(model: string): this;
35
38
  with_baseUrl(url: string): this;
@@ -56,16 +59,16 @@ export declare class AgentBuilder {
56
59
  }): this;
57
60
  start(): Promise<Agent>;
58
61
  private rebuildAgentWithPrompt;
59
- ask(prompt: string): Promise<string>;
60
- runSimple(prompt: string): Promise<string>;
61
- react(task: string): Promise<string>;
62
+ ask(prompt: string | Array<JsContent>): Promise<string>;
63
+ runSimple(prompt: string | Array<JsContent>): Promise<string>;
64
+ react(task: string | Array<JsContent>): Promise<string>;
62
65
  stop(): Promise<void>;
63
66
  }
64
67
  export declare class Agent {
65
68
  private _inner;
66
69
  constructor(_inner: jsbos.Agent);
67
70
  private _resolveContent;
68
- run(task: string): Promise<string>;
71
+ run(task: string | Array<JsContent>): Promise<string>;
69
72
  ask(prompt: string | Array<JsContent>): Promise<string>;
70
73
  runSimple(prompt: string | Array<JsContent>): Promise<string>;
71
74
  react(task: string | Array<JsContent>): Promise<string>;
package/dist/agent.js CHANGED
@@ -11,6 +11,7 @@ export class AgentBuilder {
11
11
  _mcp = [];
12
12
  _skillsDirs = [];
13
13
  _inlineSkills = [];
14
+ _onMcpStatus;
14
15
  _config;
15
16
  constructor(name, options = {}) {
16
17
  this._config = {
@@ -28,6 +29,7 @@ export class AgentBuilder {
28
29
  rateLimitWindowSecs: options.rateLimitWindowSecs,
29
30
  rateLimitMaxRetries: options.rateLimitMaxRetries,
30
31
  };
32
+ this._onMcpStatus = options.onMcpStatus;
31
33
  }
32
34
  with_model(model) {
33
35
  this._config.model = model;
@@ -159,11 +161,18 @@ export class AgentBuilder {
159
161
  }) : undefined);
160
162
  }
161
163
  for (const mcp of this._mcp) {
162
- if (mcp.type === 'process' && mcp.command && mcp.args) {
163
- await this._inner.addMcpServer(mcp.namespace, mcp.command, mcp.args);
164
+ try {
165
+ if (mcp.type === 'process' && mcp.command && mcp.args) {
166
+ await this._inner.addMcpServer(mcp.namespace, mcp.command, mcp.args);
167
+ }
168
+ else if (mcp.type === 'http' && mcp.url) {
169
+ await this._inner.addMcpServerHttp(mcp.namespace, mcp.url);
170
+ }
171
+ this._onMcpStatus?.(mcp.namespace, 'connected');
164
172
  }
165
- else if (mcp.type === 'http' && mcp.url) {
166
- await this._inner.addMcpServerHttp(mcp.namespace, mcp.url);
173
+ catch (err) {
174
+ this._onMcpStatus?.(mcp.namespace, 'failed', String(err));
175
+ console.warn(`[agent] MCP server "${mcp.namespace}" connection failed, skipping:`, err);
167
176
  }
168
177
  }
169
178
  let systemPrompt = this._config.systemPrompt || '';
package/dist/brainos.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import * as jsbos from '@open1s/jsbos';
2
- import { AgentBuilder, Agent } from './agent.js';
2
+ import { AgentBuilder, Agent, McpStatusCallback } from './agent.js';
3
3
  interface BrainOSOptions {
4
4
  model?: string;
5
5
  baseUrl?: string;
6
6
  apiKey?: string;
7
+ onMcpStatus?: McpStatusCallback;
7
8
  }
8
9
  interface BusOptions {
9
10
  mode?: string;
@@ -29,6 +30,7 @@ export declare class BrainOS {
29
30
  temperature?: number;
30
31
  timeoutSecs?: number;
31
32
  maxTokens?: number;
33
+ onMcpStatus?: McpStatusCallback;
32
34
  }): AgentBuilder;
33
35
  get bus(): jsbos.Bus;
34
36
  publish(topic: string, payload: any, isJson?: boolean): Promise<void>;
package/dist/brainos.js CHANGED
@@ -47,11 +47,8 @@ export class BrainOS {
47
47
  throw new Error('BrainOS not started. Call start() first.');
48
48
  }
49
49
  return new AgentBuilder(name, {
50
- ...this._options,
51
50
  ...options,
52
- apiKey: options.apiKey || this._options.apiKey,
53
- model: options.model || this._options.model,
54
- baseUrl: options.baseUrl || this._options.baseUrl,
51
+ ...this._options,
55
52
  });
56
53
  }
57
54
  get bus() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open1s/ezbos",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Simple BrainOS - Easy wrapper for @open1s/jsbos",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
- "@open1s/jsbos": "^2.3.0"
43
+ "@open1s/jsbos": "^2.3.2"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@modelcontextprotocol/sdk": "^1.29.0",
package/src/agent.ts CHANGED
@@ -17,6 +17,8 @@ export interface JsContent {
17
17
  const DEFAULT_MODEL = 'nvidia/meta/llama-3.1-8b-instruct';
18
18
  const DEFAULT_BASE_URL = 'https://integrate.api.nvidia.com/v1';
19
19
 
20
+ export type McpStatusCallback = (namespace: string, status: 'connected' | 'failed', error?: string) => void;
21
+
20
22
  export class AgentBuilder {
21
23
  private _inner: jsbos.Agent | null = null;
22
24
  private _tools: InternalToolDef[] = [];
@@ -25,6 +27,7 @@ export class AgentBuilder {
25
27
  private _mcp: Array<{ type: 'process' | 'http', namespace: string, command?: string, args?: string[], url?: string }> = [];
26
28
  private _skillsDirs: string[] = [];
27
29
  private _inlineSkills: SkillDef[] = [];
30
+ private _onMcpStatus?: McpStatusCallback;
28
31
  private _config: {
29
32
  name: string;
30
33
  model: string;
@@ -54,6 +57,7 @@ export class AgentBuilder {
54
57
  rateLimitCapacity?: number;
55
58
  rateLimitWindowSecs?: number;
56
59
  rateLimitMaxRetries?: number;
60
+ onMcpStatus?: McpStatusCallback;
57
61
  } = {}) {
58
62
  this._config = {
59
63
  name,
@@ -70,6 +74,7 @@ export class AgentBuilder {
70
74
  rateLimitWindowSecs: options.rateLimitWindowSecs,
71
75
  rateLimitMaxRetries: options.rateLimitMaxRetries,
72
76
  };
77
+ this._onMcpStatus = options.onMcpStatus;
73
78
  }
74
79
 
75
80
  with_model(model: string): this {
@@ -233,10 +238,16 @@ export class AgentBuilder {
233
238
  }
234
239
 
235
240
  for (const mcp of this._mcp) {
236
- if (mcp.type === 'process' && mcp.command && mcp.args) {
237
- await this._inner.addMcpServer(mcp.namespace, mcp.command, mcp.args);
238
- } else if (mcp.type === 'http' && mcp.url) {
239
- await this._inner.addMcpServerHttp(mcp.namespace, mcp.url);
241
+ try {
242
+ if (mcp.type === 'process' && mcp.command && mcp.args) {
243
+ await this._inner.addMcpServer(mcp.namespace, mcp.command, mcp.args);
244
+ } else if (mcp.type === 'http' && mcp.url) {
245
+ await this._inner.addMcpServerHttp(mcp.namespace, mcp.url);
246
+ }
247
+ this._onMcpStatus?.(mcp.namespace, 'connected');
248
+ } catch (err) {
249
+ this._onMcpStatus?.(mcp.namespace, 'failed', String(err));
250
+ console.warn(`[agent] MCP server "${mcp.namespace}" connection failed, skipping:`, err);
240
251
  }
241
252
  }
242
253
 
@@ -290,17 +301,17 @@ export class AgentBuilder {
290
301
  return newAgent;
291
302
  }
292
303
 
293
- async ask(prompt: string): Promise<string> {
304
+ async ask(prompt: string | Array<JsContent>): Promise<string> {
294
305
  if (!this._inner) await this.start();
295
306
  return this._inner!.react(prompt);
296
307
  }
297
308
 
298
- async runSimple(prompt: string): Promise<string> {
309
+ async runSimple(prompt: string | Array<JsContent>): Promise<string> {
299
310
  if (!this._inner) await this.start();
300
311
  return this._inner!.runSimple(prompt);
301
312
  }
302
313
 
303
- async react(task: string): Promise<string> {
314
+ async react(task: string | Array<JsContent>): Promise<string> {
304
315
  if (!this._inner) await this.start();
305
316
  return this._inner!.react(task);
306
317
  }
@@ -344,7 +355,7 @@ export class Agent {
344
355
  return [{ type: 'text', text: String(input) }];
345
356
  }
346
357
 
347
- async run(task: string): Promise<string> {
358
+ async run(task: string | Array<JsContent>): Promise<string> {
348
359
  return this._inner.runSimple(this._resolveContent(task) as any);
349
360
  }
350
361
 
package/src/brainos.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import * as jsbos from '@open1s/jsbos';
2
- import { AgentBuilder, Agent } from './agent.js';
2
+ import { AgentBuilder, Agent, McpStatusCallback } from './agent.js';
3
3
 
4
4
  interface BrainOSOptions {
5
5
  model?: string;
6
6
  baseUrl?: string;
7
7
  apiKey?: string;
8
+ onMcpStatus?: McpStatusCallback;
8
9
  }
9
10
 
10
11
  interface BusOptions {
@@ -73,16 +74,14 @@ export class BrainOS {
73
74
  temperature?: number;
74
75
  timeoutSecs?: number;
75
76
  maxTokens?: number;
77
+ onMcpStatus?: McpStatusCallback;
76
78
  } = {}): AgentBuilder {
77
79
  if (!this._started) {
78
80
  throw new Error('BrainOS not started. Call start() first.');
79
81
  }
80
82
  return new AgentBuilder(name, {
81
- ...this._options,
82
83
  ...options,
83
- apiKey: options.apiKey || this._options.apiKey,
84
- model: options.model || this._options.model,
85
- baseUrl: options.baseUrl || this._options.baseUrl,
84
+ ...this._options,
86
85
  });
87
86
  }
88
87