ruvector 0.2.4 → 0.2.6
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 +51 -59
- package/bin/mcp-server.js +67 -23
- package/package.json +1 -3
package/bin/cli.js
CHANGED
|
@@ -7851,19 +7851,9 @@ mcpCmd.command('test')
|
|
|
7851
7851
|
});
|
|
7852
7852
|
|
|
7853
7853
|
// ============================================================================
|
|
7854
|
-
// Brain Commands — Shared intelligence via
|
|
7854
|
+
// Brain Commands — Shared intelligence via pi.ruv.io REST API (direct fetch)
|
|
7855
7855
|
// ============================================================================
|
|
7856
7856
|
|
|
7857
|
-
async function requirePiBrain() {
|
|
7858
|
-
try {
|
|
7859
|
-
return require('@ruvector/pi-brain');
|
|
7860
|
-
} catch {
|
|
7861
|
-
console.error(chalk.red('Brain commands require @ruvector/pi-brain'));
|
|
7862
|
-
console.error(chalk.yellow(' npm install @ruvector/pi-brain'));
|
|
7863
|
-
process.exit(1);
|
|
7864
|
-
}
|
|
7865
|
-
}
|
|
7866
|
-
|
|
7867
7857
|
function getBrainConfig(opts) {
|
|
7868
7858
|
return {
|
|
7869
7859
|
url: opts.url || process.env.BRAIN_URL || 'https://pi.ruv.io',
|
|
@@ -7871,6 +7861,30 @@ function getBrainConfig(opts) {
|
|
|
7871
7861
|
};
|
|
7872
7862
|
}
|
|
7873
7863
|
|
|
7864
|
+
function brainHeaders(config) {
|
|
7865
|
+
const h = { 'Content-Type': 'application/json' };
|
|
7866
|
+
if (config.key) h['Authorization'] = `Bearer ${config.key}`;
|
|
7867
|
+
return h;
|
|
7868
|
+
}
|
|
7869
|
+
|
|
7870
|
+
async function brainFetch(config, endpoint, opts = {}) {
|
|
7871
|
+
const url = new URL(endpoint, config.url);
|
|
7872
|
+
if (opts.params) {
|
|
7873
|
+
for (const [k, v] of Object.entries(opts.params)) {
|
|
7874
|
+
if (v !== undefined && v !== null) url.searchParams.set(k, String(v));
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
const fetchOpts = { headers: brainHeaders(config), signal: AbortSignal.timeout(30000) };
|
|
7878
|
+
if (opts.method) fetchOpts.method = opts.method;
|
|
7879
|
+
if (opts.body) { fetchOpts.method = opts.method || 'POST'; fetchOpts.body = JSON.stringify(opts.body); }
|
|
7880
|
+
const resp = await fetch(url.toString(), fetchOpts);
|
|
7881
|
+
if (!resp.ok) {
|
|
7882
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
7883
|
+
throw new Error(`${resp.status} ${errText}`);
|
|
7884
|
+
}
|
|
7885
|
+
return resp.json();
|
|
7886
|
+
}
|
|
7887
|
+
|
|
7874
7888
|
const brainCmd = program.command('brain').description('Shared intelligence — search, share, and manage collective knowledge');
|
|
7875
7889
|
|
|
7876
7890
|
brainCmd.command('search <query>')
|
|
@@ -7882,11 +7896,9 @@ brainCmd.command('search <query>')
|
|
|
7882
7896
|
.option('--json', 'Output as JSON')
|
|
7883
7897
|
.option('--verbose', 'Show detailed scoring and metadata per result')
|
|
7884
7898
|
.action(async (query, opts) => {
|
|
7885
|
-
const piBrain = await requirePiBrain();
|
|
7886
7899
|
const config = getBrainConfig(opts);
|
|
7887
7900
|
try {
|
|
7888
|
-
const
|
|
7889
|
-
const results = await client.search(query, { category: opts.category, limit: parseInt(opts.limit) });
|
|
7901
|
+
const results = await brainFetch(config, '/v1/memories/search', { params: { q: query, category: opts.category, limit: opts.limit } });
|
|
7890
7902
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(results, null, 2)); return; }
|
|
7891
7903
|
console.log(chalk.bold.cyan(`\nBrain Search: "${query}"\n`));
|
|
7892
7904
|
if (!results.length) { console.log(chalk.dim(' No results found.\n')); return; }
|
|
@@ -7916,11 +7928,9 @@ brainCmd.command('share <title>')
|
|
|
7916
7928
|
.option('--url <url>', 'Brain server URL')
|
|
7917
7929
|
.option('--key <key>', 'Pi key')
|
|
7918
7930
|
.action(async (title, opts) => {
|
|
7919
|
-
const piBrain = await requirePiBrain();
|
|
7920
7931
|
const config = getBrainConfig(opts);
|
|
7921
7932
|
try {
|
|
7922
|
-
const
|
|
7923
|
-
const result = await client.share({ title, content: opts.content || title, category: opts.category, tags: opts.tags ? opts.tags.split(',').map(t => t.trim()) : [], code_snippet: opts.code });
|
|
7933
|
+
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 } });
|
|
7924
7934
|
console.log(chalk.green(`Shared: ${result.id || 'OK'}`));
|
|
7925
7935
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7926
7936
|
});
|
|
@@ -7931,11 +7941,9 @@ brainCmd.command('get <id>')
|
|
|
7931
7941
|
.option('--key <key>', 'Pi key')
|
|
7932
7942
|
.option('--json', 'Output as JSON')
|
|
7933
7943
|
.action(async (id, opts) => {
|
|
7934
|
-
const piBrain = await requirePiBrain();
|
|
7935
7944
|
const config = getBrainConfig(opts);
|
|
7936
7945
|
try {
|
|
7937
|
-
const
|
|
7938
|
-
const result = await client.get(id);
|
|
7946
|
+
const result = await brainFetch(config, `/v1/memories/${id}`);
|
|
7939
7947
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
7940
7948
|
console.log(chalk.bold.cyan(`\nMemory: ${id}\n`));
|
|
7941
7949
|
if (result.title) console.log(` ${chalk.bold('Title:')} ${result.title}`);
|
|
@@ -7950,11 +7958,9 @@ brainCmd.command('vote <id> <direction>')
|
|
|
7950
7958
|
.option('--url <url>', 'Brain server URL')
|
|
7951
7959
|
.option('--key <key>', 'Pi key')
|
|
7952
7960
|
.action(async (id, direction, opts) => {
|
|
7953
|
-
const piBrain = await requirePiBrain();
|
|
7954
7961
|
const config = getBrainConfig(opts);
|
|
7955
7962
|
try {
|
|
7956
|
-
|
|
7957
|
-
await client.vote(id, direction);
|
|
7963
|
+
await brainFetch(config, `/v1/memories/${id}/vote`, { body: { direction } });
|
|
7958
7964
|
console.log(chalk.green(`Voted ${direction} on ${id}`));
|
|
7959
7965
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7960
7966
|
});
|
|
@@ -7967,11 +7973,9 @@ brainCmd.command('list')
|
|
|
7967
7973
|
.option('--key <key>', 'Pi key')
|
|
7968
7974
|
.option('--json', 'Output as JSON')
|
|
7969
7975
|
.action(async (opts) => {
|
|
7970
|
-
const piBrain = await requirePiBrain();
|
|
7971
7976
|
const config = getBrainConfig(opts);
|
|
7972
7977
|
try {
|
|
7973
|
-
const
|
|
7974
|
-
const results = await client.list({ category: opts.category, limit: parseInt(opts.limit) });
|
|
7978
|
+
const results = await brainFetch(config, '/v1/memories/list', { params: { category: opts.category, limit: opts.limit } });
|
|
7975
7979
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(results, null, 2)); return; }
|
|
7976
7980
|
console.log(chalk.bold.cyan('\nShared Brain Memories\n'));
|
|
7977
7981
|
if (!results.length) { console.log(chalk.dim(' No memories found.\n')); return; }
|
|
@@ -7987,11 +7991,9 @@ brainCmd.command('delete <id>')
|
|
|
7987
7991
|
.option('--url <url>', 'Brain server URL')
|
|
7988
7992
|
.option('--key <key>', 'Pi key')
|
|
7989
7993
|
.action(async (id, opts) => {
|
|
7990
|
-
const piBrain = await requirePiBrain();
|
|
7991
7994
|
const config = getBrainConfig(opts);
|
|
7992
7995
|
try {
|
|
7993
|
-
|
|
7994
|
-
await client.delete(id);
|
|
7996
|
+
await brainFetch(config, `/v1/memories/${id}`, { method: 'DELETE' });
|
|
7995
7997
|
console.log(chalk.green(`Deleted: ${id}`));
|
|
7996
7998
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7997
7999
|
});
|
|
@@ -8002,11 +8004,9 @@ brainCmd.command('status')
|
|
|
8002
8004
|
.option('--key <key>', 'Pi key')
|
|
8003
8005
|
.option('--json', 'Output as JSON')
|
|
8004
8006
|
.action(async (opts) => {
|
|
8005
|
-
const piBrain = await requirePiBrain();
|
|
8006
8007
|
const config = getBrainConfig(opts);
|
|
8007
8008
|
try {
|
|
8008
|
-
const
|
|
8009
|
-
const status = await client.status();
|
|
8009
|
+
const status = await brainFetch(config, '/v1/status');
|
|
8010
8010
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(status, null, 2)); return; }
|
|
8011
8011
|
console.log(chalk.bold.cyan('\nBrain Status\n'));
|
|
8012
8012
|
Object.entries(status).forEach(([k, v]) => {
|
|
@@ -8037,11 +8037,9 @@ brainCmd.command('drift')
|
|
|
8037
8037
|
.option('--key <key>', 'Pi key')
|
|
8038
8038
|
.option('--json', 'Output as JSON')
|
|
8039
8039
|
.action(async (opts) => {
|
|
8040
|
-
const piBrain = await requirePiBrain();
|
|
8041
8040
|
const config = getBrainConfig(opts);
|
|
8042
8041
|
try {
|
|
8043
|
-
const
|
|
8044
|
-
const report = await client.drift({ domain: opts.domain });
|
|
8042
|
+
const report = await brainFetch(config, '/v1/drift', { params: { domain: opts.domain } });
|
|
8045
8043
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(report, null, 2)); return; }
|
|
8046
8044
|
console.log(chalk.bold.cyan('\nDrift Report\n'));
|
|
8047
8045
|
console.log(` ${chalk.bold('Drifting:')} ${report.is_drifting ? chalk.red('Yes') : chalk.green('No')}`);
|
|
@@ -8058,11 +8056,9 @@ brainCmd.command('partition')
|
|
|
8058
8056
|
.option('--key <key>', 'Pi key')
|
|
8059
8057
|
.option('--json', 'Output as JSON')
|
|
8060
8058
|
.action(async (opts) => {
|
|
8061
|
-
const piBrain = await requirePiBrain();
|
|
8062
8059
|
const config = getBrainConfig(opts);
|
|
8063
8060
|
try {
|
|
8064
|
-
const
|
|
8065
|
-
const result = await client.partition({ domain: opts.domain, min_cluster_size: parseInt(opts.minSize) });
|
|
8061
|
+
const result = await brainFetch(config, '/v1/partition', { params: { domain: opts.domain, min_cluster_size: opts.minSize } });
|
|
8066
8062
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8067
8063
|
console.log(chalk.bold.cyan('\nKnowledge Partitions\n'));
|
|
8068
8064
|
if (result.clusters) {
|
|
@@ -8080,11 +8076,9 @@ brainCmd.command('transfer <source> <target>')
|
|
|
8080
8076
|
.option('--key <key>', 'Pi key')
|
|
8081
8077
|
.option('--json', 'Output as JSON')
|
|
8082
8078
|
.action(async (source, target, opts) => {
|
|
8083
|
-
const piBrain = await requirePiBrain();
|
|
8084
8079
|
const config = getBrainConfig(opts);
|
|
8085
8080
|
try {
|
|
8086
|
-
const
|
|
8087
|
-
const result = await client.transfer(source, target);
|
|
8081
|
+
const result = await brainFetch(config, '/v1/transfer', { body: { source_domain: source, target_domain: target } });
|
|
8088
8082
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8089
8083
|
console.log(chalk.green(`Transfer ${source} -> ${target}: ${result.status || 'OK'}`));
|
|
8090
8084
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
@@ -8095,11 +8089,9 @@ brainCmd.command('sync [direction]')
|
|
|
8095
8089
|
.option('--url <url>', 'Brain server URL')
|
|
8096
8090
|
.option('--key <key>', 'Pi key')
|
|
8097
8091
|
.action(async (direction, opts) => {
|
|
8098
|
-
const piBrain = await requirePiBrain();
|
|
8099
8092
|
const config = getBrainConfig(opts);
|
|
8100
8093
|
try {
|
|
8101
|
-
const
|
|
8102
|
-
const result = await client.sync(direction || 'both');
|
|
8094
|
+
const result = await brainFetch(config, '/v1/lora/latest', { params: { direction: direction || 'both' } });
|
|
8103
8095
|
console.log(chalk.green(`Sync ${direction || 'both'}: ${result.status || 'OK'}`));
|
|
8104
8096
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8105
8097
|
});
|
|
@@ -8110,30 +8102,28 @@ brainCmd.command('page <action> [args...]')
|
|
|
8110
8102
|
.option('--key <key>', 'Pi key')
|
|
8111
8103
|
.option('--json', 'Output as JSON')
|
|
8112
8104
|
.action(async (action, args, opts) => {
|
|
8113
|
-
const piBrain = await requirePiBrain();
|
|
8114
8105
|
const config = getBrainConfig(opts);
|
|
8115
8106
|
try {
|
|
8116
|
-
const client = new piBrain.PiBrainClient(config);
|
|
8117
8107
|
let result;
|
|
8118
8108
|
switch (action) {
|
|
8119
8109
|
case 'list':
|
|
8120
|
-
result = await
|
|
8110
|
+
result = await brainFetch(config, '/v1/pages', { params: { limit: 20 } }).catch(() => ({ pages: [], message: 'Brainpedia endpoint not available' }));
|
|
8121
8111
|
break;
|
|
8122
8112
|
case 'get':
|
|
8123
8113
|
if (!args[0]) { console.error(chalk.red('Usage: brain page get <slug>')); process.exit(1); }
|
|
8124
|
-
result = await
|
|
8114
|
+
result = await brainFetch(config, `/v1/pages/${args[0]}`);
|
|
8125
8115
|
break;
|
|
8126
8116
|
case 'create':
|
|
8127
8117
|
if (!args[0]) { console.error(chalk.red('Usage: brain page create <title> [--content <text>]')); process.exit(1); }
|
|
8128
|
-
result = await
|
|
8118
|
+
result = await brainFetch(config, '/v1/pages', { body: { title: args[0], content: opts.content || '' } });
|
|
8129
8119
|
break;
|
|
8130
8120
|
case 'update':
|
|
8131
8121
|
if (!args[0]) { console.error(chalk.red('Usage: brain page update <slug> [--content <text>]')); process.exit(1); }
|
|
8132
|
-
result = await
|
|
8122
|
+
result = await brainFetch(config, `/v1/pages/${args[0]}/deltas`, { body: { content: opts.content || '' } });
|
|
8133
8123
|
break;
|
|
8134
8124
|
case 'delete':
|
|
8135
8125
|
if (!args[0]) { console.error(chalk.red('Usage: brain page delete <slug>')); process.exit(1); }
|
|
8136
|
-
result = await
|
|
8126
|
+
result = await brainFetch(config, `/v1/pages/${args[0]}`, { method: 'DELETE' }).catch(() => ({ error: 'Delete not available' }));
|
|
8137
8127
|
break;
|
|
8138
8128
|
default:
|
|
8139
8129
|
console.error(chalk.red(`Unknown page action: ${action}. Use: list, get, create, update, delete`));
|
|
@@ -8159,10 +8149,8 @@ brainCmd.command('node <action> [args...]')
|
|
|
8159
8149
|
.option('--key <key>', 'Pi key')
|
|
8160
8150
|
.option('--json', 'Output as JSON')
|
|
8161
8151
|
.action(async (action, args, opts) => {
|
|
8162
|
-
const piBrain = await requirePiBrain();
|
|
8163
8152
|
const config = getBrainConfig(opts);
|
|
8164
8153
|
try {
|
|
8165
|
-
const client = new piBrain.PiBrainClient(config);
|
|
8166
8154
|
let result;
|
|
8167
8155
|
switch (action) {
|
|
8168
8156
|
case 'publish':
|
|
@@ -8170,14 +8158,14 @@ brainCmd.command('node <action> [args...]')
|
|
|
8170
8158
|
const wasmPath = path.resolve(args[0]);
|
|
8171
8159
|
if (!fs.existsSync(wasmPath)) { console.error(chalk.red(`File not found: ${wasmPath}`)); process.exit(1); }
|
|
8172
8160
|
const wasmBytes = fs.readFileSync(wasmPath);
|
|
8173
|
-
result = await
|
|
8161
|
+
result = await brainFetch(config, '/v1/nodes', { body: { name: path.basename(wasmPath, '.wasm'), wasm_base64: wasmBytes.toString('base64') } });
|
|
8174
8162
|
break;
|
|
8175
8163
|
case 'list':
|
|
8176
|
-
result = await
|
|
8164
|
+
result = await brainFetch(config, '/v1/nodes', { params: { limit: 20 } }).catch(() => ({ nodes: [], message: 'WASM node listing not available' }));
|
|
8177
8165
|
break;
|
|
8178
8166
|
case 'status':
|
|
8179
8167
|
if (!args[0]) { console.error(chalk.red('Usage: brain node status <node-id>')); process.exit(1); }
|
|
8180
|
-
result = await
|
|
8168
|
+
result = await brainFetch(config, `/v1/nodes/${args[0]}`);
|
|
8181
8169
|
break;
|
|
8182
8170
|
default:
|
|
8183
8171
|
console.error(chalk.red(`Unknown node action: ${action}. Use: publish, list, status`));
|
|
@@ -8761,6 +8749,10 @@ function createSonaEngine(sona) {
|
|
|
8761
8749
|
if (sona.SonaCoordinator) return new sona.SonaCoordinator(SONA_DEFAULT_DIM);
|
|
8762
8750
|
throw new Error('No SONA engine class found');
|
|
8763
8751
|
}
|
|
8752
|
+
function parseSonaResult(val) {
|
|
8753
|
+
if (typeof val === 'string') { try { return JSON.parse(val); } catch { return val; } }
|
|
8754
|
+
return val;
|
|
8755
|
+
}
|
|
8764
8756
|
|
|
8765
8757
|
sonaCmd.command('status')
|
|
8766
8758
|
.description('Show SONA learning engine status')
|
|
@@ -8769,7 +8761,7 @@ sonaCmd.command('status')
|
|
|
8769
8761
|
const sona = loadSona();
|
|
8770
8762
|
try {
|
|
8771
8763
|
const engine = createSonaEngine(sona);
|
|
8772
|
-
const status = engine.getStatus ? engine.getStatus() : {
|
|
8764
|
+
const status = engine.getStatus ? parseSonaResult(engine.getStatus()) : { enabled: engine.isEnabled ? engine.isEnabled() : true, ...parseSonaResult(engine.getStats ? engine.getStats() : {}) };
|
|
8773
8765
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(status, null, 2)); return; }
|
|
8774
8766
|
console.log(chalk.bold.cyan('\nSONA Status\n'));
|
|
8775
8767
|
Object.entries(status).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
|
@@ -8814,7 +8806,7 @@ sonaCmd.command('export')
|
|
|
8814
8806
|
const sona = loadSona();
|
|
8815
8807
|
try {
|
|
8816
8808
|
const engine = createSonaEngine(sona);
|
|
8817
|
-
const weights = engine.exportWeights ? engine.exportWeights() : engine.
|
|
8809
|
+
const weights = parseSonaResult(engine.exportWeights ? engine.exportWeights() : engine.getStats ? engine.getStats() : {});
|
|
8818
8810
|
fs.writeFileSync(opts.output, JSON.stringify(weights, null, 2));
|
|
8819
8811
|
console.log(chalk.green(`Exported to ${opts.output}`));
|
|
8820
8812
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); }
|
|
@@ -8827,7 +8819,7 @@ sonaCmd.command('stats')
|
|
|
8827
8819
|
const sona = loadSona();
|
|
8828
8820
|
try {
|
|
8829
8821
|
const engine = createSonaEngine(sona);
|
|
8830
|
-
const stats = engine.getStats ? engine.getStats() : engine.stats ? engine.stats() : {};
|
|
8822
|
+
const stats = parseSonaResult(engine.getStats ? engine.getStats() : engine.stats ? engine.stats() : {});
|
|
8831
8823
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(stats, null, 2)); return; }
|
|
8832
8824
|
console.log(chalk.bold.cyan('\nSONA Statistics\n'));
|
|
8833
8825
|
Object.entries(stats).forEach(([k, v]) => console.log(` ${chalk.bold(k + ':')} ${v}`));
|
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.6',
|
|
367
367
|
},
|
|
368
368
|
{
|
|
369
369
|
capabilities: {
|
|
@@ -3276,7 +3276,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3276
3276
|
}
|
|
3277
3277
|
}
|
|
3278
3278
|
|
|
3279
|
-
// ── Brain Tool Handlers
|
|
3279
|
+
// ── Brain Tool Handlers (direct fetch to pi.ruv.io) ─────────────────
|
|
3280
3280
|
case 'brain_search':
|
|
3281
3281
|
case 'brain_share':
|
|
3282
3282
|
case 'brain_get':
|
|
@@ -3289,31 +3289,75 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3289
3289
|
case 'brain_transfer':
|
|
3290
3290
|
case 'brain_sync': {
|
|
3291
3291
|
try {
|
|
3292
|
-
const
|
|
3293
|
-
const
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
});
|
|
3292
|
+
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3293
|
+
const brainKey = process.env.PI;
|
|
3294
|
+
const hdrs = { 'Content-Type': 'application/json' };
|
|
3295
|
+
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3297
3296
|
const subCmd = name.replace('brain_', '');
|
|
3298
|
-
let
|
|
3297
|
+
let url, fetchOpts = { headers: hdrs, signal: AbortSignal.timeout(30000) };
|
|
3299
3298
|
switch (subCmd) {
|
|
3300
|
-
case 'search':
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
case '
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3299
|
+
case 'search': {
|
|
3300
|
+
const p = new URLSearchParams({ q: args.query || '' });
|
|
3301
|
+
if (args.category) p.set('category', args.category);
|
|
3302
|
+
if (args.limit) p.set('limit', String(args.limit));
|
|
3303
|
+
url = `${brainUrl}/v1/memories/search?${p}`;
|
|
3304
|
+
break;
|
|
3305
|
+
}
|
|
3306
|
+
case 'share': {
|
|
3307
|
+
url = `${brainUrl}/v1/memories`;
|
|
3308
|
+
fetchOpts.method = 'POST';
|
|
3309
|
+
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 });
|
|
3310
|
+
break;
|
|
3311
|
+
}
|
|
3312
|
+
case 'get': url = `${brainUrl}/v1/memories/${args.id}`; break;
|
|
3313
|
+
case 'vote': {
|
|
3314
|
+
url = `${brainUrl}/v1/memories/${args.id}/vote`;
|
|
3315
|
+
fetchOpts.method = 'POST';
|
|
3316
|
+
fetchOpts.body = JSON.stringify({ direction: args.direction });
|
|
3317
|
+
break;
|
|
3318
|
+
}
|
|
3319
|
+
case 'list': {
|
|
3320
|
+
const p = new URLSearchParams();
|
|
3321
|
+
if (args.category) p.set('category', args.category);
|
|
3322
|
+
p.set('limit', String(args.limit || 20));
|
|
3323
|
+
url = `${brainUrl}/v1/memories/list?${p}`;
|
|
3324
|
+
break;
|
|
3325
|
+
}
|
|
3326
|
+
case 'delete': {
|
|
3327
|
+
url = `${brainUrl}/v1/memories/${args.id}`;
|
|
3328
|
+
fetchOpts.method = 'DELETE';
|
|
3329
|
+
break;
|
|
3330
|
+
}
|
|
3331
|
+
case 'status': url = `${brainUrl}/v1/status`; break;
|
|
3332
|
+
case 'drift': {
|
|
3333
|
+
const p = new URLSearchParams();
|
|
3334
|
+
if (args.domain) p.set('domain', args.domain);
|
|
3335
|
+
url = `${brainUrl}/v1/drift?${p}`;
|
|
3336
|
+
break;
|
|
3337
|
+
}
|
|
3338
|
+
case 'partition': {
|
|
3339
|
+
const p = new URLSearchParams();
|
|
3340
|
+
if (args.domain) p.set('domain', args.domain);
|
|
3341
|
+
if (args.min_cluster_size) p.set('min_cluster_size', String(args.min_cluster_size));
|
|
3342
|
+
url = `${brainUrl}/v1/partition?${p}`;
|
|
3343
|
+
break;
|
|
3344
|
+
}
|
|
3345
|
+
case 'transfer': {
|
|
3346
|
+
url = `${brainUrl}/v1/transfer`;
|
|
3347
|
+
fetchOpts.method = 'POST';
|
|
3348
|
+
fetchOpts.body = JSON.stringify({ source_domain: args.source_domain, target_domain: args.target_domain });
|
|
3349
|
+
break;
|
|
3350
|
+
}
|
|
3351
|
+
case 'sync': url = `${brainUrl}/v1/lora/latest`; break;
|
|
3311
3352
|
}
|
|
3353
|
+
const resp = await fetch(url, fetchOpts);
|
|
3354
|
+
if (!resp.ok) {
|
|
3355
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
3356
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
3357
|
+
}
|
|
3358
|
+
const result = await resp.json();
|
|
3312
3359
|
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...result }, null, 2) }] };
|
|
3313
3360
|
} catch (e) {
|
|
3314
|
-
if (e.code === 'MODULE_NOT_FOUND') {
|
|
3315
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Brain tools require @ruvector/pi-brain. Install with: npm install @ruvector/pi-brain' }, null, 2) }], isError: true };
|
|
3316
|
-
}
|
|
3317
3361
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: e.message }, null, 2) }], isError: true };
|
|
3318
3362
|
}
|
|
3319
3363
|
}
|
|
@@ -3787,7 +3831,7 @@ async function main() {
|
|
|
3787
3831
|
transport: 'sse',
|
|
3788
3832
|
sessions: sessions.size,
|
|
3789
3833
|
tools: 91,
|
|
3790
|
-
version: '0.2.
|
|
3834
|
+
version: '0.2.6'
|
|
3791
3835
|
}));
|
|
3792
3836
|
|
|
3793
3837
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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",
|
|
@@ -80,12 +80,10 @@
|
|
|
80
80
|
"typescript": "^5.3.3"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
|
-
"@ruvector/pi-brain": ">=0.1.0",
|
|
84
83
|
"@ruvector/ruvllm": ">=2.0.0",
|
|
85
84
|
"@ruvector/router": ">=0.1.0"
|
|
86
85
|
},
|
|
87
86
|
"peerDependenciesMeta": {
|
|
88
|
-
"@ruvector/pi-brain": { "optional": true },
|
|
89
87
|
"@ruvector/ruvllm": { "optional": true },
|
|
90
88
|
"@ruvector/router": { "optional": true }
|
|
91
89
|
},
|