ruvector 0.2.3 → 0.2.4
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 +30 -1
- package/bin/cli.js +328 -5
- package/bin/mcp-server.js +264 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ npx ruvector hooks init --pretrain --build-agents quality
|
|
|
56
56
|
|
|
57
57
|
### MCP Server Integration
|
|
58
58
|
|
|
59
|
-
RuVector includes an MCP server for Claude Code with
|
|
59
|
+
RuVector includes an MCP server for Claude Code with 103 tools:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
# Add to Claude Code
|
|
@@ -72,6 +72,35 @@ claude mcp add ruvector -- npx ruvector mcp start
|
|
|
72
72
|
- `hooks_security_scan` — Vulnerability detection
|
|
73
73
|
- `hooks_rag_context` — Semantic context retrieval
|
|
74
74
|
- `hooks_attention_info`, `hooks_gnn_info` — Neural capabilities
|
|
75
|
+
- `brain_search`, `brain_share`, `brain_status` — Shared brain knowledge
|
|
76
|
+
- `brain_agi_status`, `brain_sona_stats`, `brain_temporal`, `brain_explore` — AGI diagnostics
|
|
77
|
+
- `brain_midstream`, `brain_flags` — Midstream platform + feature flags
|
|
78
|
+
- `midstream_status`, `midstream_attractor`, `midstream_scheduler` — Streaming analysis
|
|
79
|
+
- `midstream_benchmark`, `midstream_search`, `midstream_health` — Latency benchmarks + health
|
|
80
|
+
|
|
81
|
+
### Brain AGI Commands
|
|
82
|
+
|
|
83
|
+
Access all 8 AGI subsystems deployed at π.ruv.io:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx ruvector brain agi status # Combined AGI + midstream diagnostics
|
|
87
|
+
npx ruvector brain agi sona # SONA patterns, trajectories, ticks
|
|
88
|
+
npx ruvector brain agi temporal # Knowledge evolution velocity
|
|
89
|
+
npx ruvector brain agi explore # Meta-learning curiosity & regret
|
|
90
|
+
npx ruvector brain agi midstream # Scheduler, attractor, solver, strange-loop
|
|
91
|
+
npx ruvector brain agi flags # Feature flag state
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Midstream Commands
|
|
95
|
+
|
|
96
|
+
Real-time streaming analysis platform:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npx ruvector midstream status # Platform overview
|
|
100
|
+
npx ruvector midstream attractor # Lyapunov attractor analysis
|
|
101
|
+
npx ruvector midstream scheduler # Nanosecond scheduler metrics
|
|
102
|
+
npx ruvector midstream benchmark # Latency benchmark (p50/p90/p99)
|
|
103
|
+
```
|
|
75
104
|
|
|
76
105
|
---
|
|
77
106
|
|
package/bin/cli.js
CHANGED
|
@@ -7880,6 +7880,7 @@ brainCmd.command('search <query>')
|
|
|
7880
7880
|
.option('--url <url>', 'Brain server URL')
|
|
7881
7881
|
.option('--key <key>', 'Pi key')
|
|
7882
7882
|
.option('--json', 'Output as JSON')
|
|
7883
|
+
.option('--verbose', 'Show detailed scoring and metadata per result')
|
|
7883
7884
|
.action(async (query, opts) => {
|
|
7884
7885
|
const piBrain = await requirePiBrain();
|
|
7885
7886
|
const config = getBrainConfig(opts);
|
|
@@ -7893,6 +7894,14 @@ brainCmd.command('search <query>')
|
|
|
7893
7894
|
console.log(` ${chalk.yellow(i + 1 + '.')} ${chalk.bold(r.title || r.id)}`);
|
|
7894
7895
|
if (r.category) console.log(` ${chalk.dim('Category:')} ${r.category}`);
|
|
7895
7896
|
if (r.score) console.log(` ${chalk.dim('Score:')} ${r.score.toFixed(3)}`);
|
|
7897
|
+
if (opts.verbose) {
|
|
7898
|
+
if (r.quality_score !== undefined) console.log(` ${chalk.dim('Quality:')} ${typeof r.quality_score === 'number' ? r.quality_score.toFixed(3) : r.quality_score}`);
|
|
7899
|
+
if (r.votes_up !== undefined || r.votes_down !== undefined) console.log(` ${chalk.dim('Votes:')} ${r.votes_up || 0}↑ ${r.votes_down || 0}↓`);
|
|
7900
|
+
if (r.witness_hash) console.log(` ${chalk.dim('Witness:')} ${r.witness_hash.slice(0, 12)}...`);
|
|
7901
|
+
if (r.contributor_id) console.log(` ${chalk.dim('Contributor:')} ${r.contributor_id}`);
|
|
7902
|
+
if (r.created_at) console.log(` ${chalk.dim('Created:')} ${r.created_at}`);
|
|
7903
|
+
if (r.tags && r.tags.length) console.log(` ${chalk.dim('Tags:')} ${r.tags.join(', ')}`);
|
|
7904
|
+
}
|
|
7896
7905
|
console.log();
|
|
7897
7906
|
});
|
|
7898
7907
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
@@ -8003,6 +8012,20 @@ brainCmd.command('status')
|
|
|
8003
8012
|
Object.entries(status).forEach(([k, v]) => {
|
|
8004
8013
|
console.log(` ${chalk.bold(k + ':')} ${v}`);
|
|
8005
8014
|
});
|
|
8015
|
+
// AGI subsystem fields
|
|
8016
|
+
if (status.sona_patterns !== undefined) {
|
|
8017
|
+
console.log(chalk.bold('\n AGI Subsystems'));
|
|
8018
|
+
if (status.sona_patterns !== undefined) console.log(` ${chalk.dim('SONA Patterns:')} ${status.sona_patterns} ${chalk.dim('Trajectories:')} ${status.sona_trajectories || 0}`);
|
|
8019
|
+
if (status.gwt_workspace_load !== undefined) console.log(` ${chalk.dim('GWT Load:')} ${status.gwt_workspace_load} ${chalk.dim('Avg Salience:')} ${status.gwt_avg_salience || 0}`);
|
|
8020
|
+
if (status.knowledge_velocity !== undefined) console.log(` ${chalk.dim('Temporal Velocity:')} ${status.knowledge_velocity}/hr ${chalk.dim('Deltas:')} ${status.temporal_deltas || 0}`);
|
|
8021
|
+
if (status.meta_avg_regret !== undefined) console.log(` ${chalk.dim('Meta Regret:')} ${status.meta_avg_regret} ${chalk.dim('Plateau:')} ${status.meta_plateau_status || 'unknown'}`);
|
|
8022
|
+
}
|
|
8023
|
+
if (status.midstream_scheduler_ticks !== undefined) {
|
|
8024
|
+
console.log(chalk.bold('\n Midstream'));
|
|
8025
|
+
console.log(` ${chalk.dim('Scheduler Ticks:')} ${status.midstream_scheduler_ticks}`);
|
|
8026
|
+
console.log(` ${chalk.dim('Attractor Categories:')} ${status.midstream_attractor_categories || 0}`);
|
|
8027
|
+
console.log(` ${chalk.dim('Strange-Loop:')} v${status.midstream_strange_loop_version || '?'}`);
|
|
8028
|
+
}
|
|
8006
8029
|
console.log();
|
|
8007
8030
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8008
8031
|
});
|
|
@@ -8173,6 +8196,299 @@ brainCmd.command('node <action> [args...]')
|
|
|
8173
8196
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8174
8197
|
});
|
|
8175
8198
|
|
|
8199
|
+
// ── Brain AGI Subcommands ── AGI subsystem diagnostics ──────────────────
|
|
8200
|
+
const agiCmd = brainCmd.command('agi').description('AGI subsystem diagnostics — SONA, GWT, temporal, meta-learning, midstream');
|
|
8201
|
+
|
|
8202
|
+
async function fetchBrainEndpoint(config, endpoint) {
|
|
8203
|
+
const url = (config.url || 'https://pi.ruv.io') + endpoint;
|
|
8204
|
+
const headers = {};
|
|
8205
|
+
if (config.key) headers['Authorization'] = `Bearer ${config.key}`;
|
|
8206
|
+
const resp = await fetch(url, { headers });
|
|
8207
|
+
if (!resp.ok) throw new Error(`${resp.status} ${resp.statusText}`);
|
|
8208
|
+
return resp.json();
|
|
8209
|
+
}
|
|
8210
|
+
|
|
8211
|
+
agiCmd.command('status')
|
|
8212
|
+
.description('Combined AGI + midstream diagnostics from π.ruv.io')
|
|
8213
|
+
.option('--url <url>', 'Brain server URL')
|
|
8214
|
+
.option('--key <key>', 'Pi key')
|
|
8215
|
+
.option('--json', 'Output as JSON')
|
|
8216
|
+
.action(async (opts) => {
|
|
8217
|
+
const config = getBrainConfig(opts);
|
|
8218
|
+
try {
|
|
8219
|
+
const status = await fetchBrainEndpoint(config, '/v1/status');
|
|
8220
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(status, null, 2)); return; }
|
|
8221
|
+
console.log(chalk.bold.cyan('\n π.ruv.io AGI Diagnostics\n'));
|
|
8222
|
+
console.log(chalk.bold(' SONA'));
|
|
8223
|
+
console.log(` Patterns: ${status.sona_patterns || 0} Trajectories: ${status.sona_trajectories || 0}`);
|
|
8224
|
+
console.log(` Background ticks: ${status.sona_background_ticks || 0}`);
|
|
8225
|
+
console.log(chalk.bold('\n GWT Attention'));
|
|
8226
|
+
console.log(` Workspace load: ${status.gwt_workspace_load || 0}`);
|
|
8227
|
+
console.log(` Avg salience: ${status.gwt_avg_salience || 0}`);
|
|
8228
|
+
console.log(chalk.bold('\n Temporal'));
|
|
8229
|
+
console.log(` Total deltas: ${status.temporal_deltas || 0}`);
|
|
8230
|
+
console.log(` Velocity: ${status.knowledge_velocity || 0}/hr`);
|
|
8231
|
+
console.log(` Trend: ${status.temporal_trend || 'unknown'}`);
|
|
8232
|
+
console.log(chalk.bold('\n Meta-Learning'));
|
|
8233
|
+
console.log(` Avg regret: ${status.meta_avg_regret || 0}`);
|
|
8234
|
+
console.log(` Plateau: ${status.meta_plateau_status || 'unknown'}`);
|
|
8235
|
+
console.log(chalk.bold('\n Midstream'));
|
|
8236
|
+
console.log(` Scheduler ticks: ${status.midstream_scheduler_ticks || 0}`);
|
|
8237
|
+
console.log(` Attractor categories: ${status.midstream_attractor_categories || 0}`);
|
|
8238
|
+
console.log(` Strange-loop: v${status.midstream_strange_loop_version || '?'}`);
|
|
8239
|
+
console.log();
|
|
8240
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8241
|
+
});
|
|
8242
|
+
|
|
8243
|
+
agiCmd.command('sona')
|
|
8244
|
+
.description('SONA learning engine — patterns, trajectories, background ticks')
|
|
8245
|
+
.option('--url <url>', 'Brain server URL')
|
|
8246
|
+
.option('--key <key>', 'Pi key')
|
|
8247
|
+
.option('--json', 'Output as JSON')
|
|
8248
|
+
.action(async (opts) => {
|
|
8249
|
+
const config = getBrainConfig(opts);
|
|
8250
|
+
try {
|
|
8251
|
+
const data = await fetchBrainEndpoint(config, '/v1/sona/stats');
|
|
8252
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8253
|
+
console.log(chalk.bold.cyan('\n SONA Learning Engine\n'));
|
|
8254
|
+
Object.entries(data).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
8255
|
+
console.log();
|
|
8256
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8257
|
+
});
|
|
8258
|
+
|
|
8259
|
+
agiCmd.command('temporal')
|
|
8260
|
+
.description('Temporal delta tracking — velocity, trend, total deltas')
|
|
8261
|
+
.option('--url <url>', 'Brain server URL')
|
|
8262
|
+
.option('--key <key>', 'Pi key')
|
|
8263
|
+
.option('--json', 'Output as JSON')
|
|
8264
|
+
.action(async (opts) => {
|
|
8265
|
+
const config = getBrainConfig(opts);
|
|
8266
|
+
try {
|
|
8267
|
+
const data = await fetchBrainEndpoint(config, '/v1/temporal');
|
|
8268
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8269
|
+
console.log(chalk.bold.cyan('\n Temporal Delta Tracking\n'));
|
|
8270
|
+
Object.entries(data).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
8271
|
+
console.log();
|
|
8272
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8273
|
+
});
|
|
8274
|
+
|
|
8275
|
+
agiCmd.command('explore')
|
|
8276
|
+
.description('Meta-learning exploration — curiosity, regret, plateau, Pareto')
|
|
8277
|
+
.option('--url <url>', 'Brain server URL')
|
|
8278
|
+
.option('--key <key>', 'Pi key')
|
|
8279
|
+
.option('--json', 'Output as JSON')
|
|
8280
|
+
.action(async (opts) => {
|
|
8281
|
+
const config = getBrainConfig(opts);
|
|
8282
|
+
try {
|
|
8283
|
+
const data = await fetchBrainEndpoint(config, '/v1/explore');
|
|
8284
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8285
|
+
console.log(chalk.bold.cyan('\n Meta-Learning Exploration\n'));
|
|
8286
|
+
Object.entries(data).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
8287
|
+
console.log();
|
|
8288
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8289
|
+
});
|
|
8290
|
+
|
|
8291
|
+
agiCmd.command('midstream')
|
|
8292
|
+
.description('Midstream platform — scheduler, attractor, solver, strange-loop')
|
|
8293
|
+
.option('--url <url>', 'Brain server URL')
|
|
8294
|
+
.option('--key <key>', 'Pi key')
|
|
8295
|
+
.option('--json', 'Output as JSON')
|
|
8296
|
+
.action(async (opts) => {
|
|
8297
|
+
const config = getBrainConfig(opts);
|
|
8298
|
+
try {
|
|
8299
|
+
const data = await fetchBrainEndpoint(config, '/v1/midstream');
|
|
8300
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8301
|
+
console.log(chalk.bold.cyan('\n Midstream Platform\n'));
|
|
8302
|
+
Object.entries(data).forEach(([k, v]) => {
|
|
8303
|
+
if (typeof v === 'object' && v !== null) {
|
|
8304
|
+
console.log(` ${chalk.bold(k + ':')}`);
|
|
8305
|
+
Object.entries(v).forEach(([sk, sv]) => console.log(` ${chalk.dim(sk + ':')} ${sv}`));
|
|
8306
|
+
} else {
|
|
8307
|
+
console.log(` ${chalk.bold(k + ':')} ${v}`);
|
|
8308
|
+
}
|
|
8309
|
+
});
|
|
8310
|
+
console.log();
|
|
8311
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8312
|
+
});
|
|
8313
|
+
|
|
8314
|
+
agiCmd.command('flags')
|
|
8315
|
+
.description('Show feature flag state from backend')
|
|
8316
|
+
.option('--url <url>', 'Brain server URL')
|
|
8317
|
+
.option('--key <key>', 'Pi key')
|
|
8318
|
+
.option('--json', 'Output as JSON')
|
|
8319
|
+
.action(async (opts) => {
|
|
8320
|
+
const config = getBrainConfig(opts);
|
|
8321
|
+
try {
|
|
8322
|
+
const status = await fetchBrainEndpoint(config, '/v1/status');
|
|
8323
|
+
const flags = {};
|
|
8324
|
+
for (const [k, v] of Object.entries(status)) {
|
|
8325
|
+
if (typeof v === 'boolean' || k.startsWith('rvf_') || k.endsWith('_enabled')) {
|
|
8326
|
+
flags[k] = v;
|
|
8327
|
+
}
|
|
8328
|
+
}
|
|
8329
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(flags, null, 2)); return; }
|
|
8330
|
+
console.log(chalk.bold.cyan('\n Feature Flags\n'));
|
|
8331
|
+
Object.entries(flags).forEach(([k, v]) => {
|
|
8332
|
+
const icon = v ? chalk.green('●') : chalk.red('○');
|
|
8333
|
+
console.log(` ${icon} ${chalk.bold(k)}: ${v}`);
|
|
8334
|
+
});
|
|
8335
|
+
console.log();
|
|
8336
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8337
|
+
});
|
|
8338
|
+
|
|
8339
|
+
// ============================================================================
|
|
8340
|
+
// Midstream Commands — Real-time streaming analysis platform
|
|
8341
|
+
// ============================================================================
|
|
8342
|
+
|
|
8343
|
+
const midstreamCmd = program.command('midstream').description('Real-time streaming analysis — attractor, scheduler, benchmark');
|
|
8344
|
+
|
|
8345
|
+
midstreamCmd.command('status')
|
|
8346
|
+
.description('Midstream platform overview')
|
|
8347
|
+
.option('--url <url>', 'Brain server URL')
|
|
8348
|
+
.option('--key <key>', 'Pi key')
|
|
8349
|
+
.option('--json', 'Output as JSON')
|
|
8350
|
+
.action(async (opts) => {
|
|
8351
|
+
const config = getBrainConfig(opts);
|
|
8352
|
+
try {
|
|
8353
|
+
const data = await fetchBrainEndpoint(config, '/v1/midstream');
|
|
8354
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8355
|
+
console.log(chalk.bold.cyan('\n Midstream Platform Status\n'));
|
|
8356
|
+
Object.entries(data).forEach(([k, v]) => {
|
|
8357
|
+
if (typeof v === 'object' && v !== null) {
|
|
8358
|
+
console.log(` ${chalk.bold(k + ':')}`);
|
|
8359
|
+
Object.entries(v).forEach(([sk, sv]) => console.log(` ${chalk.dim(sk + ':')} ${sv}`));
|
|
8360
|
+
} else {
|
|
8361
|
+
console.log(` ${chalk.bold(k + ':')} ${v}`);
|
|
8362
|
+
}
|
|
8363
|
+
});
|
|
8364
|
+
console.log();
|
|
8365
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8366
|
+
});
|
|
8367
|
+
|
|
8368
|
+
midstreamCmd.command('attractor [category]')
|
|
8369
|
+
.description('Lyapunov attractor analysis per category')
|
|
8370
|
+
.option('--url <url>', 'Brain server URL')
|
|
8371
|
+
.option('--key <key>', 'Pi key')
|
|
8372
|
+
.option('--json', 'Output as JSON')
|
|
8373
|
+
.action(async (category, opts) => {
|
|
8374
|
+
const config = getBrainConfig(opts);
|
|
8375
|
+
try {
|
|
8376
|
+
const data = await fetchBrainEndpoint(config, '/v1/midstream');
|
|
8377
|
+
const attractors = data.attractor_categories || data.attractors || {};
|
|
8378
|
+
if (category) {
|
|
8379
|
+
const entry = typeof attractors === 'object' ? attractors[category] : null;
|
|
8380
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(entry || { error: 'Category not found' }, null, 2)); return; }
|
|
8381
|
+
if (!entry) { console.log(chalk.yellow(` No attractor data for category: ${category}`)); return; }
|
|
8382
|
+
console.log(chalk.bold.cyan(`\n Attractor: ${category}\n`));
|
|
8383
|
+
Object.entries(entry).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
8384
|
+
} else {
|
|
8385
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(attractors, null, 2)); return; }
|
|
8386
|
+
console.log(chalk.bold.cyan('\n Attractor Categories\n'));
|
|
8387
|
+
if (typeof attractors === 'object' && Object.keys(attractors).length > 0) {
|
|
8388
|
+
Object.entries(attractors).forEach(([cat, info]) => {
|
|
8389
|
+
console.log(` ${chalk.yellow(cat + ':')} ${typeof info === 'object' ? JSON.stringify(info) : info}`);
|
|
8390
|
+
});
|
|
8391
|
+
} else {
|
|
8392
|
+
console.log(chalk.dim(` ${typeof attractors === 'number' ? attractors + ' categories tracked' : 'No attractor data available'}`));
|
|
8393
|
+
}
|
|
8394
|
+
}
|
|
8395
|
+
console.log();
|
|
8396
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8397
|
+
});
|
|
8398
|
+
|
|
8399
|
+
midstreamCmd.command('scheduler')
|
|
8400
|
+
.description('Nanosecond scheduler performance metrics')
|
|
8401
|
+
.option('--url <url>', 'Brain server URL')
|
|
8402
|
+
.option('--key <key>', 'Pi key')
|
|
8403
|
+
.option('--json', 'Output as JSON')
|
|
8404
|
+
.action(async (opts) => {
|
|
8405
|
+
const config = getBrainConfig(opts);
|
|
8406
|
+
try {
|
|
8407
|
+
const data = await fetchBrainEndpoint(config, '/v1/midstream');
|
|
8408
|
+
const sched = data.scheduler || { ticks: data.scheduler_ticks || 0 };
|
|
8409
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(sched, null, 2)); return; }
|
|
8410
|
+
console.log(chalk.bold.cyan('\n Nanosecond Scheduler\n'));
|
|
8411
|
+
if (typeof sched === 'object') {
|
|
8412
|
+
Object.entries(sched).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
8413
|
+
} else {
|
|
8414
|
+
console.log(` ${chalk.bold('Ticks:')} ${sched}`);
|
|
8415
|
+
}
|
|
8416
|
+
console.log();
|
|
8417
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8418
|
+
});
|
|
8419
|
+
|
|
8420
|
+
midstreamCmd.command('benchmark')
|
|
8421
|
+
.description('Run latency benchmark against brain backend')
|
|
8422
|
+
.option('--url <url>', 'Brain server URL')
|
|
8423
|
+
.option('--key <key>', 'Pi key')
|
|
8424
|
+
.option('-n, --concurrent <n>', 'Concurrent search requests', '20')
|
|
8425
|
+
.option('--json', 'Output as JSON')
|
|
8426
|
+
.action(async (opts) => {
|
|
8427
|
+
const config = getBrainConfig(opts);
|
|
8428
|
+
const baseUrl = config.url || 'https://pi.ruv.io';
|
|
8429
|
+
const headers = {};
|
|
8430
|
+
if (config.key) headers['Authorization'] = `Bearer ${config.key}`;
|
|
8431
|
+
const concurrentN = Math.min(parseInt(opts.concurrent) || 20, 100);
|
|
8432
|
+
|
|
8433
|
+
async function timeRequest(url, label) {
|
|
8434
|
+
const start = performance.now();
|
|
8435
|
+
const resp = await fetch(url, { headers });
|
|
8436
|
+
const elapsed = performance.now() - start;
|
|
8437
|
+
return { label, status: resp.status, elapsed };
|
|
8438
|
+
}
|
|
8439
|
+
|
|
8440
|
+
function percentile(sorted, p) {
|
|
8441
|
+
const idx = Math.ceil(sorted.length * p / 100) - 1;
|
|
8442
|
+
return sorted[Math.max(0, idx)];
|
|
8443
|
+
}
|
|
8444
|
+
|
|
8445
|
+
try {
|
|
8446
|
+
if (!opts.json && process.stdout.isTTY) console.log(chalk.bold.cyan('\n Midstream Benchmark\n'));
|
|
8447
|
+
|
|
8448
|
+
// Sequential tests (3 each)
|
|
8449
|
+
const endpoints = [
|
|
8450
|
+
{ path: '/v1/health', label: 'health' },
|
|
8451
|
+
{ path: '/v1/status', label: 'status' },
|
|
8452
|
+
{ path: '/v1/memories/search?q=test&limit=3', label: 'search' },
|
|
8453
|
+
{ path: '/v1/midstream', label: 'midstream' },
|
|
8454
|
+
];
|
|
8455
|
+
|
|
8456
|
+
const sequential = {};
|
|
8457
|
+
for (const ep of endpoints) {
|
|
8458
|
+
const times = [];
|
|
8459
|
+
for (let i = 0; i < 3; i++) {
|
|
8460
|
+
const r = await timeRequest(baseUrl + ep.path, ep.label);
|
|
8461
|
+
times.push(r.elapsed);
|
|
8462
|
+
}
|
|
8463
|
+
sequential[ep.label] = { avg: times.reduce((a, b) => a + b, 0) / times.length, min: Math.min(...times), max: Math.max(...times) };
|
|
8464
|
+
}
|
|
8465
|
+
|
|
8466
|
+
// Concurrent search test
|
|
8467
|
+
const concurrentTimes = [];
|
|
8468
|
+
const promises = [];
|
|
8469
|
+
for (let i = 0; i < concurrentN; i++) {
|
|
8470
|
+
promises.push(timeRequest(baseUrl + '/v1/memories/search?q=test&limit=3', 'concurrent'));
|
|
8471
|
+
}
|
|
8472
|
+
const results = await Promise.all(promises);
|
|
8473
|
+
const sorted = results.map(r => r.elapsed).sort((a, b) => a - b);
|
|
8474
|
+
const p50 = percentile(sorted, 50);
|
|
8475
|
+
const p90 = percentile(sorted, 90);
|
|
8476
|
+
const p99 = percentile(sorted, 99);
|
|
8477
|
+
|
|
8478
|
+
const benchResult = { sequential, concurrent: { count: concurrentN, p50, p90, p99 } };
|
|
8479
|
+
|
|
8480
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(benchResult, null, 2)); return; }
|
|
8481
|
+
|
|
8482
|
+
console.log(chalk.bold(' Sequential (3 rounds each):'));
|
|
8483
|
+
for (const [label, data] of Object.entries(sequential)) {
|
|
8484
|
+
console.log(` ${chalk.yellow(label.padEnd(12))} avg: ${data.avg.toFixed(1)}ms min: ${data.min.toFixed(1)}ms max: ${data.max.toFixed(1)}ms`);
|
|
8485
|
+
}
|
|
8486
|
+
console.log(chalk.bold(`\n Concurrent (${concurrentN}x search):`));
|
|
8487
|
+
console.log(` p50: ${p50.toFixed(1)}ms p90: ${p90.toFixed(1)}ms p99: ${p99.toFixed(1)}ms`);
|
|
8488
|
+
console.log();
|
|
8489
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8490
|
+
});
|
|
8491
|
+
|
|
8176
8492
|
// ============================================================================
|
|
8177
8493
|
// Edge Commands — Distributed compute via @ruvector/edge-net
|
|
8178
8494
|
// ============================================================================
|
|
@@ -8439,13 +8755,20 @@ function loadSona() {
|
|
|
8439
8755
|
}
|
|
8440
8756
|
}
|
|
8441
8757
|
|
|
8758
|
+
const SONA_DEFAULT_DIM = 128;
|
|
8759
|
+
function createSonaEngine(sona) {
|
|
8760
|
+
if (sona.SonaEngine) return new sona.SonaEngine(SONA_DEFAULT_DIM);
|
|
8761
|
+
if (sona.SonaCoordinator) return new sona.SonaCoordinator(SONA_DEFAULT_DIM);
|
|
8762
|
+
throw new Error('No SONA engine class found');
|
|
8763
|
+
}
|
|
8764
|
+
|
|
8442
8765
|
sonaCmd.command('status')
|
|
8443
8766
|
.description('Show SONA learning engine status')
|
|
8444
8767
|
.option('--json', 'Output as JSON')
|
|
8445
8768
|
.action((opts) => {
|
|
8446
8769
|
const sona = loadSona();
|
|
8447
8770
|
try {
|
|
8448
|
-
const engine =
|
|
8771
|
+
const engine = createSonaEngine(sona);
|
|
8449
8772
|
const status = engine.getStatus ? engine.getStatus() : { ready: true };
|
|
8450
8773
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(status, null, 2)); return; }
|
|
8451
8774
|
console.log(chalk.bold.cyan('\nSONA Status\n'));
|
|
@@ -8461,7 +8784,7 @@ sonaCmd.command('patterns <query>')
|
|
|
8461
8784
|
.action((query, opts) => {
|
|
8462
8785
|
const sona = loadSona();
|
|
8463
8786
|
try {
|
|
8464
|
-
const engine =
|
|
8787
|
+
const engine = createSonaEngine(sona);
|
|
8465
8788
|
const patterns = engine.findPatterns ? engine.findPatterns(query, { threshold: parseFloat(opts.threshold) }) : [];
|
|
8466
8789
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(patterns, null, 2)); return; }
|
|
8467
8790
|
console.log(chalk.bold.cyan('\nLearned Patterns\n'));
|
|
@@ -8477,7 +8800,7 @@ sonaCmd.command('train <data>')
|
|
|
8477
8800
|
.action((data, opts) => {
|
|
8478
8801
|
const sona = loadSona();
|
|
8479
8802
|
try {
|
|
8480
|
-
const engine =
|
|
8803
|
+
const engine = createSonaEngine(sona);
|
|
8481
8804
|
if (engine.recordTrajectory) { engine.recordTrajectory(data, opts.outcome); }
|
|
8482
8805
|
else if (engine.train) { engine.train(data); }
|
|
8483
8806
|
console.log(chalk.green('Training trajectory recorded.'));
|
|
@@ -8490,7 +8813,7 @@ sonaCmd.command('export')
|
|
|
8490
8813
|
.action((opts) => {
|
|
8491
8814
|
const sona = loadSona();
|
|
8492
8815
|
try {
|
|
8493
|
-
const engine =
|
|
8816
|
+
const engine = createSonaEngine(sona);
|
|
8494
8817
|
const weights = engine.exportWeights ? engine.exportWeights() : engine.export ? engine.export() : {};
|
|
8495
8818
|
fs.writeFileSync(opts.output, JSON.stringify(weights, null, 2));
|
|
8496
8819
|
console.log(chalk.green(`Exported to ${opts.output}`));
|
|
@@ -8503,7 +8826,7 @@ sonaCmd.command('stats')
|
|
|
8503
8826
|
.action((opts) => {
|
|
8504
8827
|
const sona = loadSona();
|
|
8505
8828
|
try {
|
|
8506
|
-
const engine =
|
|
8829
|
+
const engine = createSonaEngine(sona);
|
|
8507
8830
|
const stats = engine.getStats ? engine.getStats() : engine.stats ? engine.stats() : {};
|
|
8508
8831
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(stats, null, 2)); return; }
|
|
8509
8832
|
console.log(chalk.bold.cyan('\nSONA Statistics\n'));
|
package/bin/mcp-server.js
CHANGED
|
@@ -363,7 +363,7 @@ class Intelligence {
|
|
|
363
363
|
const server = new Server(
|
|
364
364
|
{
|
|
365
365
|
name: 'ruvector',
|
|
366
|
-
version: '0.2.
|
|
366
|
+
version: '0.2.4',
|
|
367
367
|
},
|
|
368
368
|
{
|
|
369
369
|
capabilities: {
|
|
@@ -1396,6 +1396,85 @@ const TOOLS = [
|
|
|
1396
1396
|
}
|
|
1397
1397
|
}
|
|
1398
1398
|
},
|
|
1399
|
+
// ── Brain AGI Tools (6) ── AGI subsystem diagnostics via direct fetch ──
|
|
1400
|
+
{
|
|
1401
|
+
name: 'brain_agi_status',
|
|
1402
|
+
description: 'Combined AGI subsystem diagnostics — SONA, GWT, temporal, meta-learning, midstream',
|
|
1403
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
name: 'brain_sona_stats',
|
|
1407
|
+
description: 'SONA learning engine stats — patterns, trajectories, background ticks',
|
|
1408
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
name: 'brain_temporal',
|
|
1412
|
+
description: 'Temporal delta tracking — velocity, trend, total deltas',
|
|
1413
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1414
|
+
},
|
|
1415
|
+
{
|
|
1416
|
+
name: 'brain_explore',
|
|
1417
|
+
description: 'Meta-learning exploration — curiosity, regret, plateau status, Pareto frontier',
|
|
1418
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
name: 'brain_midstream',
|
|
1422
|
+
description: 'Midstream platform diagnostics — scheduler, attractor, solver, strange-loop',
|
|
1423
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
name: 'brain_flags',
|
|
1427
|
+
description: 'Show backend feature flag state (RVF, AGI, midstream flags)',
|
|
1428
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1429
|
+
},
|
|
1430
|
+
// ── Midstream Tools (6) ── Real-time streaming analysis platform ──
|
|
1431
|
+
{
|
|
1432
|
+
name: 'midstream_status',
|
|
1433
|
+
description: 'Full midstream platform diagnostics — scheduler, attractor, solver, strange-loop',
|
|
1434
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1435
|
+
},
|
|
1436
|
+
{
|
|
1437
|
+
name: 'midstream_attractor',
|
|
1438
|
+
description: 'Attractor categories with Lyapunov exponent analysis',
|
|
1439
|
+
inputSchema: {
|
|
1440
|
+
type: 'object',
|
|
1441
|
+
properties: {
|
|
1442
|
+
category: { type: 'string', description: 'Optional category to filter (e.g., pattern, solution)' }
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
},
|
|
1446
|
+
{
|
|
1447
|
+
name: 'midstream_scheduler',
|
|
1448
|
+
description: 'Nanosecond scheduler performance metrics — ticks, tasks/sec',
|
|
1449
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
name: 'midstream_benchmark',
|
|
1453
|
+
description: 'Run sequential + concurrent latency benchmark against brain backend',
|
|
1454
|
+
inputSchema: {
|
|
1455
|
+
type: 'object',
|
|
1456
|
+
properties: {
|
|
1457
|
+
concurrent_count: { type: 'number', description: 'Number of concurrent search requests (default 20, max 100)' }
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
},
|
|
1461
|
+
{
|
|
1462
|
+
name: 'midstream_search',
|
|
1463
|
+
description: 'Semantic search with midstream scoring metadata in response',
|
|
1464
|
+
inputSchema: {
|
|
1465
|
+
type: 'object',
|
|
1466
|
+
properties: {
|
|
1467
|
+
query: { type: 'string', description: 'Search query' },
|
|
1468
|
+
limit: { type: 'number', description: 'Max results (default 10)' }
|
|
1469
|
+
},
|
|
1470
|
+
required: ['query']
|
|
1471
|
+
}
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
name: 'midstream_health',
|
|
1475
|
+
description: 'Combined health + midstream subsystem check',
|
|
1476
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1477
|
+
},
|
|
1399
1478
|
// ── Edge Tools (4) ── Distributed compute via @ruvector/edge-net ──
|
|
1400
1479
|
{
|
|
1401
1480
|
name: 'edge_status',
|
|
@@ -3239,6 +3318,189 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3239
3318
|
}
|
|
3240
3319
|
}
|
|
3241
3320
|
|
|
3321
|
+
// ── Brain AGI Tool Handlers ────────────────────────────────────────────
|
|
3322
|
+
case 'brain_agi_status':
|
|
3323
|
+
case 'brain_sona_stats':
|
|
3324
|
+
case 'brain_temporal':
|
|
3325
|
+
case 'brain_explore':
|
|
3326
|
+
case 'brain_midstream':
|
|
3327
|
+
case 'brain_flags': {
|
|
3328
|
+
try {
|
|
3329
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3330
|
+
const brainKey = process.env.PI;
|
|
3331
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3332
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3333
|
+
|
|
3334
|
+
const endpointMap = {
|
|
3335
|
+
brain_agi_status: '/v1/status',
|
|
3336
|
+
brain_sona_stats: '/v1/sona/stats',
|
|
3337
|
+
brain_temporal: '/v1/temporal',
|
|
3338
|
+
brain_explore: '/v1/explore',
|
|
3339
|
+
brain_midstream: '/v1/midstream',
|
|
3340
|
+
brain_flags: '/v1/status',
|
|
3341
|
+
};
|
|
3342
|
+
const endpoint = endpointMap[name];
|
|
3343
|
+
const resp = await fetch(`${brainUrl}${endpoint}`, { headers: hdrs });
|
|
3344
|
+
if (!resp.ok) {
|
|
3345
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3346
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3347
|
+
}
|
|
3348
|
+
let data = await resp.json();
|
|
3349
|
+
|
|
3350
|
+
// For brain_flags, extract only flag-related fields
|
|
3351
|
+
if (name === 'brain_flags') {
|
|
3352
|
+
const flags = {};
|
|
3353
|
+
for (const [k, v] of Object.entries(data)) {
|
|
3354
|
+
if (typeof v === 'boolean' || k.startsWith('rvf_') || k.endsWith('_enabled') || (k.startsWith('midstream_') && typeof v === 'boolean')) {
|
|
3355
|
+
flags[k] = v;
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
data = flags;
|
|
3359
|
+
}
|
|
3360
|
+
|
|
3361
|
+
// For brain_agi_status, extract AGI-specific fields
|
|
3362
|
+
if (name === 'brain_agi_status') {
|
|
3363
|
+
const agiFields = {};
|
|
3364
|
+
const agiKeys = ['sona_patterns', 'sona_trajectories', 'sona_background_ticks', 'gwt_workspace_load', 'gwt_avg_salience', 'knowledge_velocity', 'temporal_deltas', 'temporal_trend', 'meta_avg_regret', 'meta_plateau_status', 'midstream_scheduler_ticks', 'midstream_attractor_categories', 'midstream_strange_loop_version'];
|
|
3365
|
+
for (const k of agiKeys) {
|
|
3366
|
+
if (data[k] !== undefined) agiFields[k] = data[k];
|
|
3367
|
+
}
|
|
3368
|
+
data = Object.keys(agiFields).length > 0 ? agiFields : data;
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...data }, null, 2) }] };
|
|
3372
|
+
} catch (e) {
|
|
3373
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
// ── Midstream Tool Handlers ────────────────────────────────────────────
|
|
3378
|
+
case 'midstream_status':
|
|
3379
|
+
case 'midstream_attractor':
|
|
3380
|
+
case 'midstream_scheduler': {
|
|
3381
|
+
try {
|
|
3382
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3383
|
+
const brainKey = process.env.PI;
|
|
3384
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3385
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3386
|
+
|
|
3387
|
+
const resp = await fetch(`${brainUrl}/v1/midstream`, { headers: hdrs });
|
|
3388
|
+
if (!resp.ok) {
|
|
3389
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3390
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3391
|
+
}
|
|
3392
|
+
let data = await resp.json();
|
|
3393
|
+
|
|
3394
|
+
if (name === 'midstream_attractor') {
|
|
3395
|
+
data = data.attractor_categories || data.attractors || data;
|
|
3396
|
+
if (args.category && typeof data === 'object') data = data[args.category] || { error: `Category '${args.category}' not found` };
|
|
3397
|
+
} else if (name === 'midstream_scheduler') {
|
|
3398
|
+
data = data.scheduler || { ticks: data.scheduler_ticks || 0 };
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...data }, null, 2) }] };
|
|
3402
|
+
} catch (e) {
|
|
3403
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
case 'midstream_benchmark': {
|
|
3408
|
+
try {
|
|
3409
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3410
|
+
const brainKey = process.env.PI;
|
|
3411
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3412
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3413
|
+
const concurrentN = Math.min(args.concurrent_count || 20, 100);
|
|
3414
|
+
|
|
3415
|
+
async function timeFetch(url) {
|
|
3416
|
+
const start = performance.now();
|
|
3417
|
+
const resp = await fetch(url, { headers: hdrs });
|
|
3418
|
+
return { status: resp.status, elapsed: performance.now() - start };
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3421
|
+
// Sequential tests
|
|
3422
|
+
const endpoints = [
|
|
3423
|
+
{ path: '/v1/health', label: 'health' },
|
|
3424
|
+
{ path: '/v1/status', label: 'status' },
|
|
3425
|
+
{ path: '/v1/memories/search?q=test&limit=3', label: 'search' },
|
|
3426
|
+
{ path: '/v1/midstream', label: 'midstream' },
|
|
3427
|
+
];
|
|
3428
|
+
|
|
3429
|
+
const sequential = {};
|
|
3430
|
+
for (const ep of endpoints) {
|
|
3431
|
+
const times = [];
|
|
3432
|
+
for (let i = 0; i < 3; i++) {
|
|
3433
|
+
const r = await timeFetch(brainUrl + ep.path);
|
|
3434
|
+
times.push(r.elapsed);
|
|
3435
|
+
}
|
|
3436
|
+
sequential[ep.label] = {
|
|
3437
|
+
avg_ms: +(times.reduce((a, b) => a + b, 0) / times.length).toFixed(1),
|
|
3438
|
+
min_ms: +Math.min(...times).toFixed(1),
|
|
3439
|
+
max_ms: +Math.max(...times).toFixed(1)
|
|
3440
|
+
};
|
|
3441
|
+
}
|
|
3442
|
+
|
|
3443
|
+
// Concurrent search
|
|
3444
|
+
const promises = [];
|
|
3445
|
+
for (let i = 0; i < concurrentN; i++) {
|
|
3446
|
+
promises.push(timeFetch(brainUrl + '/v1/memories/search?q=test&limit=3'));
|
|
3447
|
+
}
|
|
3448
|
+
const results = await Promise.all(promises);
|
|
3449
|
+
const sorted = results.map(r => r.elapsed).sort((a, b) => a - b);
|
|
3450
|
+
const pct = (p) => +(sorted[Math.max(0, Math.ceil(sorted.length * p / 100) - 1)]).toFixed(1);
|
|
3451
|
+
|
|
3452
|
+
return { content: [{ type: 'text', text: JSON.stringify({
|
|
3453
|
+
success: true,
|
|
3454
|
+
sequential,
|
|
3455
|
+
concurrent: { count: concurrentN, p50_ms: pct(50), p90_ms: pct(90), p99_ms: pct(99) }
|
|
3456
|
+
}, null, 2) }] };
|
|
3457
|
+
} catch (e) {
|
|
3458
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3462
|
+
case 'midstream_search': {
|
|
3463
|
+
try {
|
|
3464
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3465
|
+
const brainKey = process.env.PI;
|
|
3466
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3467
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3468
|
+
const limit = Math.min(Math.max(parseInt(args.limit) || 10, 1), 100);
|
|
3469
|
+
const q = encodeURIComponent(args.query);
|
|
3470
|
+
const resp = await fetch(`${brainUrl}/v1/memories/search?q=${q}&limit=${limit}`, { headers: hdrs });
|
|
3471
|
+
if (!resp.ok) {
|
|
3472
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3473
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3474
|
+
}
|
|
3475
|
+
const data = await resp.json();
|
|
3476
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, results: data, count: Array.isArray(data) ? data.length : 0 }, null, 2) }] };
|
|
3477
|
+
} catch (e) {
|
|
3478
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
case 'midstream_health': {
|
|
3483
|
+
try {
|
|
3484
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3485
|
+
const brainKey = process.env.PI;
|
|
3486
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3487
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3488
|
+
|
|
3489
|
+
const [healthResp, midResp] = await Promise.all([
|
|
3490
|
+
fetch(`${brainUrl}/v1/health`, { headers: hdrs }).then(r => r.json()).catch(e => ({ error: e.message })),
|
|
3491
|
+
fetch(`${brainUrl}/v1/midstream`, { headers: hdrs }).then(r => r.json()).catch(e => ({ error: e.message })),
|
|
3492
|
+
]);
|
|
3493
|
+
|
|
3494
|
+
return { content: [{ type: 'text', text: JSON.stringify({
|
|
3495
|
+
success: true,
|
|
3496
|
+
health: healthResp,
|
|
3497
|
+
midstream: midResp
|
|
3498
|
+
}, null, 2) }] };
|
|
3499
|
+
} catch (e) {
|
|
3500
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3242
3504
|
// ── Edge Tool Handlers ───────────────────────────────────────────────
|
|
3243
3505
|
case 'edge_status':
|
|
3244
3506
|
case 'edge_join':
|
|
@@ -3525,7 +3787,7 @@ async function main() {
|
|
|
3525
3787
|
transport: 'sse',
|
|
3526
3788
|
sessions: sessions.size,
|
|
3527
3789
|
tools: 91,
|
|
3528
|
-
version: '0.2.
|
|
3790
|
+
version: '0.2.4'
|
|
3529
3791
|
}));
|
|
3530
3792
|
|
|
3531
3793
|
} else {
|