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 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 30+ tools:
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 = sona.SonaEngine ? new sona.SonaEngine() : new sona.SonaCoordinator();
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 = sona.SonaEngine ? new sona.SonaEngine() : new sona.SonaCoordinator();
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 = sona.SonaEngine ? new sona.SonaEngine() : new sona.SonaCoordinator();
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 = sona.SonaEngine ? new sona.SonaEngine() : new sona.SonaCoordinator();
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 = sona.SonaEngine ? new sona.SonaEngine() : new sona.SonaCoordinator();
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.3',
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.3'
3790
+ version: '0.2.4'
3529
3791
  }));
3530
3792
 
3531
3793
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ruvector",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "High-performance vector database for Node.js with automatic native/WASM fallback",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",