ruvector 0.2.7 → 0.2.9
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/bin/cli.js +21 -8
- package/bin/mcp-server.js +226 -5
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -159,7 +159,7 @@ async function proxyFetch(url, opts) {
|
|
|
159
159
|
|
|
160
160
|
// Fallback: shell out to curl (which natively respects proxy env vars)
|
|
161
161
|
const { execFileSync } = require('child_process');
|
|
162
|
-
const args = ['-sS', '-L', '--max-time', '30'];
|
|
162
|
+
const args = ['-sS', '-L', '--max-time', '30', '-w', '\n%{http_code}'];
|
|
163
163
|
if (opts && opts.method) { args.push('-X', opts.method); }
|
|
164
164
|
if (opts && opts.headers) {
|
|
165
165
|
for (const [k, v] of Object.entries(opts.headers)) {
|
|
@@ -170,13 +170,16 @@ async function proxyFetch(url, opts) {
|
|
|
170
170
|
args.push(target);
|
|
171
171
|
try {
|
|
172
172
|
const stdout = execFileSync('curl', args, { encoding: 'utf8', timeout: 35000 });
|
|
173
|
-
const
|
|
173
|
+
const lines = stdout.trimEnd().split('\n');
|
|
174
|
+
const statusCode = parseInt(lines.pop(), 10) || 200;
|
|
175
|
+
const body = lines.join('\n').trim();
|
|
176
|
+
const ok = statusCode >= 200 && statusCode < 300;
|
|
174
177
|
return {
|
|
175
|
-
ok
|
|
176
|
-
status:
|
|
177
|
-
statusText: 'OK'
|
|
178
|
+
ok,
|
|
179
|
+
status: statusCode,
|
|
180
|
+
statusText: ok ? 'OK' : `HTTP ${statusCode}`,
|
|
178
181
|
text: async () => body,
|
|
179
|
-
json: async () => JSON.parse(body),
|
|
182
|
+
json: async () => body ? JSON.parse(body) : {},
|
|
180
183
|
headers: new Map(),
|
|
181
184
|
};
|
|
182
185
|
} catch (e) {
|
|
@@ -7952,6 +7955,7 @@ async function brainFetch(config, endpoint, opts = {}) {
|
|
|
7952
7955
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
7953
7956
|
throw new Error(`${resp.status} ${errText}`);
|
|
7954
7957
|
}
|
|
7958
|
+
if (resp.status === 204 || resp.headers.get('content-length') === '0') return {};
|
|
7955
7959
|
return resp.json();
|
|
7956
7960
|
}
|
|
7957
7961
|
|
|
@@ -7997,10 +8001,12 @@ brainCmd.command('share <title>')
|
|
|
7997
8001
|
.option('--code <snippet>', 'Code snippet')
|
|
7998
8002
|
.option('--url <url>', 'Brain server URL')
|
|
7999
8003
|
.option('--key <key>', 'Pi key')
|
|
8004
|
+
.option('--json', 'Output as JSON')
|
|
8000
8005
|
.action(async (title, opts) => {
|
|
8001
8006
|
const config = getBrainConfig(opts);
|
|
8002
8007
|
try {
|
|
8003
8008
|
const result = await brainFetch(config, '/v1/memories', { body: { title, content: opts.content || title, category: opts.category, tags: opts.tags ? opts.tags.split(',').map(t => t.trim()) : [], code_snippet: opts.code } });
|
|
8009
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8004
8010
|
console.log(chalk.green(`Shared: ${result.id || 'OK'}`));
|
|
8005
8011
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8006
8012
|
});
|
|
@@ -8027,10 +8033,12 @@ brainCmd.command('vote <id> <direction>')
|
|
|
8027
8033
|
.description('Quality vote on a memory (up or down)')
|
|
8028
8034
|
.option('--url <url>', 'Brain server URL')
|
|
8029
8035
|
.option('--key <key>', 'Pi key')
|
|
8036
|
+
.option('--json', 'Output as JSON')
|
|
8030
8037
|
.action(async (id, direction, opts) => {
|
|
8031
8038
|
const config = getBrainConfig(opts);
|
|
8032
8039
|
try {
|
|
8033
|
-
await brainFetch(config, `/v1/memories/${id}/vote`, { body: { direction } });
|
|
8040
|
+
const result = await brainFetch(config, `/v1/memories/${id}/vote`, { body: { direction } });
|
|
8041
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8034
8042
|
console.log(chalk.green(`Voted ${direction} on ${id}`));
|
|
8035
8043
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8036
8044
|
});
|
|
@@ -8067,10 +8075,12 @@ brainCmd.command('delete <id>')
|
|
|
8067
8075
|
.description('Delete your own contribution')
|
|
8068
8076
|
.option('--url <url>', 'Brain server URL')
|
|
8069
8077
|
.option('--key <key>', 'Pi key')
|
|
8078
|
+
.option('--json', 'Output as JSON')
|
|
8070
8079
|
.action(async (id, opts) => {
|
|
8071
8080
|
const config = getBrainConfig(opts);
|
|
8072
8081
|
try {
|
|
8073
|
-
await brainFetch(config, `/v1/memories/${id}`, { method: 'DELETE' });
|
|
8082
|
+
const result = await brainFetch(config, `/v1/memories/${id}`, { method: 'DELETE' });
|
|
8083
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8074
8084
|
console.log(chalk.green(`Deleted: ${id}`));
|
|
8075
8085
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8076
8086
|
});
|
|
@@ -8165,10 +8175,12 @@ brainCmd.command('sync [direction]')
|
|
|
8165
8175
|
.description('Synchronize LoRA weights (pull, push, or both)')
|
|
8166
8176
|
.option('--url <url>', 'Brain server URL')
|
|
8167
8177
|
.option('--key <key>', 'Pi key')
|
|
8178
|
+
.option('--json', 'Output as JSON')
|
|
8168
8179
|
.action(async (direction, opts) => {
|
|
8169
8180
|
const config = getBrainConfig(opts);
|
|
8170
8181
|
try {
|
|
8171
8182
|
const result = await brainFetch(config, '/v1/lora/latest', { params: { direction: direction || 'both' } });
|
|
8183
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8172
8184
|
console.log(chalk.green(`Sync ${direction || 'both'}: ${result.status || 'OK'}`));
|
|
8173
8185
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8174
8186
|
});
|
|
@@ -8270,6 +8282,7 @@ async function fetchBrainEndpoint(config, endpoint) {
|
|
|
8270
8282
|
if (config.key) headers['Authorization'] = `Bearer ${config.key}`;
|
|
8271
8283
|
const resp = await proxyFetch(url, { headers, signal: AbortSignal.timeout(30000) });
|
|
8272
8284
|
if (!resp.ok) throw new Error(`${resp.status} ${resp.statusText}`);
|
|
8285
|
+
if (resp.status === 204 || resp.headers.get('content-length') === '0') return {};
|
|
8273
8286
|
return resp.json();
|
|
8274
8287
|
}
|
|
8275
8288
|
|
package/bin/mcp-server.js
CHANGED
|
@@ -428,7 +428,7 @@ class Intelligence {
|
|
|
428
428
|
const server = new Server(
|
|
429
429
|
{
|
|
430
430
|
name: 'ruvector',
|
|
431
|
-
version: '0.2.
|
|
431
|
+
version: '0.2.9',
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
capabilities: {
|
|
@@ -1395,7 +1395,10 @@ const TOOLS = [
|
|
|
1395
1395
|
type: 'object',
|
|
1396
1396
|
properties: {
|
|
1397
1397
|
category: { type: 'string', description: 'Filter by category' },
|
|
1398
|
-
limit: { type: 'number', description: 'Max results (default 20)' }
|
|
1398
|
+
limit: { type: 'number', description: 'Max results (default 20)' },
|
|
1399
|
+
offset: { type: 'number', description: 'Skip first N results for pagination (default 0)' },
|
|
1400
|
+
sort: { type: 'string', description: 'Sort by: updated_at, quality, votes (default updated_at)' },
|
|
1401
|
+
tags: { type: 'string', description: 'Filter by tags (comma-separated)' }
|
|
1399
1402
|
}
|
|
1400
1403
|
}
|
|
1401
1404
|
},
|
|
@@ -1492,6 +1495,117 @@ const TOOLS = [
|
|
|
1492
1495
|
description: 'Show backend feature flag state (RVF, AGI, midstream flags)',
|
|
1493
1496
|
inputSchema: { type: 'object', properties: {} }
|
|
1494
1497
|
},
|
|
1498
|
+
// ── Brainpedia Page Tools (5) ── Knowledge page management ──
|
|
1499
|
+
{
|
|
1500
|
+
name: 'brain_page_list',
|
|
1501
|
+
description: 'List Brainpedia knowledge pages with pagination and status filter',
|
|
1502
|
+
inputSchema: {
|
|
1503
|
+
type: 'object',
|
|
1504
|
+
properties: {
|
|
1505
|
+
limit: { type: 'number', description: 'Max pages to return (default 20)' },
|
|
1506
|
+
offset: { type: 'number', description: 'Skip first N pages for pagination (default 0)' },
|
|
1507
|
+
status: { type: 'string', description: 'Filter by status: draft, canonical, contested, archived' }
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
name: 'brain_page_get',
|
|
1513
|
+
description: 'Get a Brainpedia page by ID with delta log and evidence links',
|
|
1514
|
+
inputSchema: {
|
|
1515
|
+
type: 'object',
|
|
1516
|
+
properties: {
|
|
1517
|
+
id: { type: 'string', description: 'Page ID (UUID or slug)' }
|
|
1518
|
+
},
|
|
1519
|
+
required: ['id']
|
|
1520
|
+
}
|
|
1521
|
+
},
|
|
1522
|
+
{
|
|
1523
|
+
name: 'brain_page_create',
|
|
1524
|
+
description: 'Create a new Brainpedia knowledge page (requires reputation >= 0.5)',
|
|
1525
|
+
inputSchema: {
|
|
1526
|
+
type: 'object',
|
|
1527
|
+
properties: {
|
|
1528
|
+
title: { type: 'string', description: 'Page title' },
|
|
1529
|
+
content: { type: 'string', description: 'Page content body' },
|
|
1530
|
+
category: { type: 'string', description: 'Category (pattern, solution, architecture, convention, security, performance, tooling)' },
|
|
1531
|
+
tags: { type: 'string', description: 'Comma-separated tags' },
|
|
1532
|
+
code_snippet: { type: 'string', description: 'Optional code snippet' }
|
|
1533
|
+
},
|
|
1534
|
+
required: ['title', 'content', 'category']
|
|
1535
|
+
}
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
name: 'brain_page_update',
|
|
1539
|
+
description: 'Submit a delta (correction, extension, evidence) to a Brainpedia page',
|
|
1540
|
+
inputSchema: {
|
|
1541
|
+
type: 'object',
|
|
1542
|
+
properties: {
|
|
1543
|
+
page_id: { type: 'string', description: 'Page ID to update' },
|
|
1544
|
+
delta_type: { type: 'string', description: 'Delta type: correction, extension, evidence, deprecation' },
|
|
1545
|
+
content_diff: { type: 'string', description: 'Content diff or new content' },
|
|
1546
|
+
evidence_links: { type: 'string', description: 'JSON array of evidence links' }
|
|
1547
|
+
},
|
|
1548
|
+
required: ['page_id', 'content_diff']
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
name: 'brain_page_delete',
|
|
1553
|
+
description: 'Delete a Brainpedia page by ID',
|
|
1554
|
+
inputSchema: {
|
|
1555
|
+
type: 'object',
|
|
1556
|
+
properties: {
|
|
1557
|
+
id: { type: 'string', description: 'Page ID to delete' }
|
|
1558
|
+
},
|
|
1559
|
+
required: ['id']
|
|
1560
|
+
}
|
|
1561
|
+
},
|
|
1562
|
+
// ── WASM Node Tools (4) ── Executable compute node management ──
|
|
1563
|
+
{
|
|
1564
|
+
name: 'brain_node_list',
|
|
1565
|
+
description: 'List published WASM compute nodes',
|
|
1566
|
+
inputSchema: {
|
|
1567
|
+
type: 'object',
|
|
1568
|
+
properties: {
|
|
1569
|
+
limit: { type: 'number', description: 'Max nodes to return (default 20)' }
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
{
|
|
1574
|
+
name: 'brain_node_get',
|
|
1575
|
+
description: 'Get WASM compute node metadata and conformance vectors',
|
|
1576
|
+
inputSchema: {
|
|
1577
|
+
type: 'object',
|
|
1578
|
+
properties: {
|
|
1579
|
+
id: { type: 'string', description: 'Node ID' }
|
|
1580
|
+
},
|
|
1581
|
+
required: ['id']
|
|
1582
|
+
}
|
|
1583
|
+
},
|
|
1584
|
+
{
|
|
1585
|
+
name: 'brain_node_publish',
|
|
1586
|
+
description: 'Publish a WASM compute node to the shared brain network',
|
|
1587
|
+
inputSchema: {
|
|
1588
|
+
type: 'object',
|
|
1589
|
+
properties: {
|
|
1590
|
+
name: { type: 'string', description: 'Node name' },
|
|
1591
|
+
wasm_base64: { type: 'string', description: 'Base64-encoded WASM binary' },
|
|
1592
|
+
description: { type: 'string', description: 'Node description' },
|
|
1593
|
+
conformance_vectors: { type: 'string', description: 'JSON array of conformance test vectors' }
|
|
1594
|
+
},
|
|
1595
|
+
required: ['name', 'wasm_base64']
|
|
1596
|
+
}
|
|
1597
|
+
},
|
|
1598
|
+
{
|
|
1599
|
+
name: 'brain_node_revoke',
|
|
1600
|
+
description: 'Revoke a published WASM compute node',
|
|
1601
|
+
inputSchema: {
|
|
1602
|
+
type: 'object',
|
|
1603
|
+
properties: {
|
|
1604
|
+
id: { type: 'string', description: 'Node ID to revoke' }
|
|
1605
|
+
},
|
|
1606
|
+
required: ['id']
|
|
1607
|
+
}
|
|
1608
|
+
},
|
|
1495
1609
|
// ── Midstream Tools (6) ── Real-time streaming analysis platform ──
|
|
1496
1610
|
{
|
|
1497
1611
|
name: 'midstream_status',
|
|
@@ -3416,20 +3530,127 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3416
3530
|
fetchOpts.body = JSON.stringify({ source_domain: args.source_domain, target_domain: args.target_domain });
|
|
3417
3531
|
break;
|
|
3418
3532
|
}
|
|
3419
|
-
case 'sync':
|
|
3533
|
+
case 'sync': {
|
|
3534
|
+
const p = new URLSearchParams();
|
|
3535
|
+
if (args.direction) p.set('direction', args.direction);
|
|
3536
|
+
url = `${brainUrl}/v1/lora/latest${p.toString() ? '?' + p : ''}`;
|
|
3537
|
+
break;
|
|
3538
|
+
}
|
|
3420
3539
|
}
|
|
3421
3540
|
const resp = await proxyFetch(url, fetchOpts);
|
|
3422
3541
|
if (!resp.ok) {
|
|
3423
3542
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
3424
3543
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3425
3544
|
}
|
|
3426
|
-
const result = await resp.json();
|
|
3545
|
+
const result = (resp.status === 204 || resp.headers.get('content-length') === '0') ? {} : await resp.json();
|
|
3427
3546
|
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...result }, null, 2) }] };
|
|
3428
3547
|
} catch (e) {
|
|
3429
3548
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3430
3549
|
}
|
|
3431
3550
|
}
|
|
3432
3551
|
|
|
3552
|
+
// ── Brainpedia Page Tool Handlers ────────────────────────────────────
|
|
3553
|
+
case 'brain_page_list':
|
|
3554
|
+
case 'brain_page_get':
|
|
3555
|
+
case 'brain_page_create':
|
|
3556
|
+
case 'brain_page_update':
|
|
3557
|
+
case 'brain_page_delete': {
|
|
3558
|
+
try {
|
|
3559
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3560
|
+
const brainKey = process.env.PI;
|
|
3561
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3562
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3563
|
+
let url, fetchOpts = { headers: hdrs, signal: AbortSignal.timeout(30000) };
|
|
3564
|
+
const subCmd = name.replace('brain_page_', '');
|
|
3565
|
+
switch (subCmd) {
|
|
3566
|
+
case 'list': {
|
|
3567
|
+
const p = new URLSearchParams();
|
|
3568
|
+
if (args.limit) p.set('limit', String(args.limit));
|
|
3569
|
+
if (args.offset) p.set('offset', String(args.offset));
|
|
3570
|
+
if (args.status) p.set('status', args.status);
|
|
3571
|
+
url = `${brainUrl}/v1/pages${p.toString() ? '?' + p : ''}`;
|
|
3572
|
+
break;
|
|
3573
|
+
}
|
|
3574
|
+
case 'get': url = `${brainUrl}/v1/pages/${args.id}`; break;
|
|
3575
|
+
case 'create': {
|
|
3576
|
+
url = `${brainUrl}/v1/pages`;
|
|
3577
|
+
fetchOpts.method = 'POST';
|
|
3578
|
+
fetchOpts.body = JSON.stringify({ title: args.title, content: args.content, category: args.category, tags: args.tags ? args.tags.split(',').map(t => t.trim()) : [], code_snippet: args.code_snippet, evidence_links: [], embedding: [], witness_hash: '' });
|
|
3579
|
+
break;
|
|
3580
|
+
}
|
|
3581
|
+
case 'update': {
|
|
3582
|
+
url = `${brainUrl}/v1/pages/${args.page_id}/deltas`;
|
|
3583
|
+
fetchOpts.method = 'POST';
|
|
3584
|
+
let evidence = [];
|
|
3585
|
+
try { if (args.evidence_links) evidence = JSON.parse(args.evidence_links); } catch {}
|
|
3586
|
+
fetchOpts.body = JSON.stringify({ delta_type: args.delta_type || 'extension', content_diff: args.content_diff, evidence_links: evidence, witness_hash: '' });
|
|
3587
|
+
break;
|
|
3588
|
+
}
|
|
3589
|
+
case 'delete': {
|
|
3590
|
+
url = `${brainUrl}/v1/pages/${args.id}`;
|
|
3591
|
+
fetchOpts.method = 'DELETE';
|
|
3592
|
+
break;
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
const resp = await proxyFetch(url, fetchOpts);
|
|
3596
|
+
if (!resp.ok) {
|
|
3597
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3598
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3599
|
+
}
|
|
3600
|
+
const result = (resp.status === 204 || resp.headers.get('content-length') === '0') ? {} : await resp.json();
|
|
3601
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...result }, null, 2) }] };
|
|
3602
|
+
} catch (e) {
|
|
3603
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3607
|
+
// ── WASM Node Tool Handlers ────────────────────────────────────────────
|
|
3608
|
+
case 'brain_node_list':
|
|
3609
|
+
case 'brain_node_get':
|
|
3610
|
+
case 'brain_node_publish':
|
|
3611
|
+
case 'brain_node_revoke': {
|
|
3612
|
+
try {
|
|
3613
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3614
|
+
const brainKey = process.env.PI;
|
|
3615
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3616
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3617
|
+
let url, fetchOpts = { headers: hdrs, signal: AbortSignal.timeout(30000) };
|
|
3618
|
+
const subCmd = name.replace('brain_node_', '');
|
|
3619
|
+
switch (subCmd) {
|
|
3620
|
+
case 'list': {
|
|
3621
|
+
const p = new URLSearchParams();
|
|
3622
|
+
if (args.limit) p.set('limit', String(args.limit));
|
|
3623
|
+
url = `${brainUrl}/v1/nodes${p.toString() ? '?' + p : ''}`;
|
|
3624
|
+
break;
|
|
3625
|
+
}
|
|
3626
|
+
case 'get': url = `${brainUrl}/v1/nodes/${args.id}`; break;
|
|
3627
|
+
case 'publish': {
|
|
3628
|
+
url = `${brainUrl}/v1/nodes`;
|
|
3629
|
+
fetchOpts.method = 'POST';
|
|
3630
|
+
let vectors = [];
|
|
3631
|
+
try { if (args.conformance_vectors) vectors = JSON.parse(args.conformance_vectors); } catch {}
|
|
3632
|
+
fetchOpts.body = JSON.stringify({ name: args.name, wasm_base64: args.wasm_base64, description: args.description || '', conformance_vectors: vectors });
|
|
3633
|
+
break;
|
|
3634
|
+
}
|
|
3635
|
+
case 'revoke': {
|
|
3636
|
+
url = `${brainUrl}/v1/nodes/${args.id}/revoke`;
|
|
3637
|
+
fetchOpts.method = 'POST';
|
|
3638
|
+
fetchOpts.body = JSON.stringify({});
|
|
3639
|
+
break;
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
const resp = await proxyFetch(url, fetchOpts);
|
|
3643
|
+
if (!resp.ok) {
|
|
3644
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3645
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3646
|
+
}
|
|
3647
|
+
const result = (resp.status === 204 || resp.headers.get('content-length') === '0') ? {} : await resp.json();
|
|
3648
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...(Array.isArray(result) ? { items: result, count: result.length } : result) }, null, 2) }] };
|
|
3649
|
+
} catch (e) {
|
|
3650
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3433
3654
|
// ── Brain AGI Tool Handlers ────────────────────────────────────────────
|
|
3434
3655
|
case 'brain_agi_status':
|
|
3435
3656
|
case 'brain_sona_stats':
|
|
@@ -3899,7 +4120,7 @@ async function main() {
|
|
|
3899
4120
|
transport: 'sse',
|
|
3900
4121
|
sessions: sessions.size,
|
|
3901
4122
|
tools: 91,
|
|
3902
|
-
version: '0.2.
|
|
4123
|
+
version: '0.2.9'
|
|
3903
4124
|
}));
|
|
3904
4125
|
|
|
3905
4126
|
} else {
|