ruvector 0.2.6 → 0.2.8
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 +102 -15
- package/bin/mcp-server.js +79 -11
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -115,6 +115,76 @@ function loadGnn() {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
// ── Proxy-aware fetch wrapper ───────────────────────────────────────────────
|
|
119
|
+
// Detects HTTP_PROXY / HTTPS_PROXY / ALL_PROXY env vars and routes traffic
|
|
120
|
+
// through the proxy when configured. Falls back to native fetch() when no
|
|
121
|
+
// proxy is set or the target matches NO_PROXY.
|
|
122
|
+
let _proxyDispatcherSet = false;
|
|
123
|
+
|
|
124
|
+
function getProxyUrl(targetUrl) {
|
|
125
|
+
const NO_PROXY = process.env.NO_PROXY || process.env.no_proxy || '';
|
|
126
|
+
if (NO_PROXY === '*') return null;
|
|
127
|
+
if (NO_PROXY) {
|
|
128
|
+
try {
|
|
129
|
+
const host = new URL(targetUrl).hostname.toLowerCase();
|
|
130
|
+
const patterns = NO_PROXY.split(',').map(p => p.trim().toLowerCase());
|
|
131
|
+
for (const p of patterns) {
|
|
132
|
+
if (!p) continue;
|
|
133
|
+
if (host === p || host.endsWith(p.startsWith('.') ? p : '.' + p)) return null;
|
|
134
|
+
}
|
|
135
|
+
} catch {}
|
|
136
|
+
}
|
|
137
|
+
return process.env.HTTPS_PROXY || process.env.https_proxy
|
|
138
|
+
|| process.env.HTTP_PROXY || process.env.http_proxy
|
|
139
|
+
|| process.env.ALL_PROXY || process.env.all_proxy
|
|
140
|
+
|| null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function proxyFetch(url, opts) {
|
|
144
|
+
const target = typeof url === 'string' ? url : url.toString();
|
|
145
|
+
const proxy = getProxyUrl(target);
|
|
146
|
+
if (!proxy) return fetch(url, opts);
|
|
147
|
+
|
|
148
|
+
// Try undici ProxyAgent (bundled in Node 18+)
|
|
149
|
+
if (!_proxyDispatcherSet) {
|
|
150
|
+
try {
|
|
151
|
+
const undici = require('undici');
|
|
152
|
+
if (undici.ProxyAgent && undici.setGlobalDispatcher) {
|
|
153
|
+
undici.setGlobalDispatcher(new undici.ProxyAgent(proxy));
|
|
154
|
+
_proxyDispatcherSet = true;
|
|
155
|
+
}
|
|
156
|
+
} catch {}
|
|
157
|
+
}
|
|
158
|
+
if (_proxyDispatcherSet) return fetch(url, opts);
|
|
159
|
+
|
|
160
|
+
// Fallback: shell out to curl (which natively respects proxy env vars)
|
|
161
|
+
const { execFileSync } = require('child_process');
|
|
162
|
+
const args = ['-sS', '-L', '--max-time', '30'];
|
|
163
|
+
if (opts && opts.method) { args.push('-X', opts.method); }
|
|
164
|
+
if (opts && opts.headers) {
|
|
165
|
+
for (const [k, v] of Object.entries(opts.headers)) {
|
|
166
|
+
args.push('-H', `${k}: ${v}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (opts && opts.body) { args.push('-d', typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body)); }
|
|
170
|
+
args.push(target);
|
|
171
|
+
try {
|
|
172
|
+
const stdout = execFileSync('curl', args, { encoding: 'utf8', timeout: 35000 });
|
|
173
|
+
const body = stdout.trim();
|
|
174
|
+
return {
|
|
175
|
+
ok: true,
|
|
176
|
+
status: 200,
|
|
177
|
+
statusText: 'OK',
|
|
178
|
+
text: async () => body,
|
|
179
|
+
json: async () => JSON.parse(body),
|
|
180
|
+
headers: new Map(),
|
|
181
|
+
};
|
|
182
|
+
} catch (e) {
|
|
183
|
+
const msg = e.stderr ? e.stderr.toString().trim() : e.message;
|
|
184
|
+
throw new Error(`Proxy curl failed: ${msg}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
118
188
|
// Lazy load Attention (optional - loaded on first use, not at startup)
|
|
119
189
|
let _attentionModule = undefined;
|
|
120
190
|
let DotProductAttention, MultiHeadAttention, HyperbolicAttention, FlashAttention, LinearAttention, MoEAttention;
|
|
@@ -7250,7 +7320,7 @@ async function getRvfManifest(opts = {}) {
|
|
|
7250
7320
|
|
|
7251
7321
|
// Try GCS
|
|
7252
7322
|
try {
|
|
7253
|
-
const resp = await
|
|
7323
|
+
const resp = await proxyFetch(GCS_MANIFEST_URL, { signal: AbortSignal.timeout(15000) });
|
|
7254
7324
|
if (resp.ok) {
|
|
7255
7325
|
const manifest = await resp.json();
|
|
7256
7326
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
@@ -7877,11 +7947,12 @@ async function brainFetch(config, endpoint, opts = {}) {
|
|
|
7877
7947
|
const fetchOpts = { headers: brainHeaders(config), signal: AbortSignal.timeout(30000) };
|
|
7878
7948
|
if (opts.method) fetchOpts.method = opts.method;
|
|
7879
7949
|
if (opts.body) { fetchOpts.method = opts.method || 'POST'; fetchOpts.body = JSON.stringify(opts.body); }
|
|
7880
|
-
const resp = await
|
|
7950
|
+
const resp = await proxyFetch(url.toString(), fetchOpts);
|
|
7881
7951
|
if (!resp.ok) {
|
|
7882
7952
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
7883
7953
|
throw new Error(`${resp.status} ${errText}`);
|
|
7884
7954
|
}
|
|
7955
|
+
if (resp.status === 204 || resp.headers.get('content-length') === '0') return {};
|
|
7885
7956
|
return resp.json();
|
|
7886
7957
|
}
|
|
7887
7958
|
|
|
@@ -7927,10 +7998,12 @@ brainCmd.command('share <title>')
|
|
|
7927
7998
|
.option('--code <snippet>', 'Code snippet')
|
|
7928
7999
|
.option('--url <url>', 'Brain server URL')
|
|
7929
8000
|
.option('--key <key>', 'Pi key')
|
|
8001
|
+
.option('--json', 'Output as JSON')
|
|
7930
8002
|
.action(async (title, opts) => {
|
|
7931
8003
|
const config = getBrainConfig(opts);
|
|
7932
8004
|
try {
|
|
7933
8005
|
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 } });
|
|
8006
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
7934
8007
|
console.log(chalk.green(`Shared: ${result.id || 'OK'}`));
|
|
7935
8008
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7936
8009
|
});
|
|
@@ -7957,10 +8030,12 @@ brainCmd.command('vote <id> <direction>')
|
|
|
7957
8030
|
.description('Quality vote on a memory (up or down)')
|
|
7958
8031
|
.option('--url <url>', 'Brain server URL')
|
|
7959
8032
|
.option('--key <key>', 'Pi key')
|
|
8033
|
+
.option('--json', 'Output as JSON')
|
|
7960
8034
|
.action(async (id, direction, opts) => {
|
|
7961
8035
|
const config = getBrainConfig(opts);
|
|
7962
8036
|
try {
|
|
7963
|
-
await brainFetch(config, `/v1/memories/${id}/vote`, { body: { direction } });
|
|
8037
|
+
const result = await brainFetch(config, `/v1/memories/${id}/vote`, { body: { direction } });
|
|
8038
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
7964
8039
|
console.log(chalk.green(`Voted ${direction} on ${id}`));
|
|
7965
8040
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7966
8041
|
});
|
|
@@ -7972,14 +8047,21 @@ brainCmd.command('list')
|
|
|
7972
8047
|
.option('--url <url>', 'Brain server URL')
|
|
7973
8048
|
.option('--key <key>', 'Pi key')
|
|
7974
8049
|
.option('--json', 'Output as JSON')
|
|
8050
|
+
.option('--offset <n>', 'Skip first N results (pagination)', '0')
|
|
8051
|
+
.option('--sort <field>', 'Sort by: updated_at, quality, votes', 'updated_at')
|
|
8052
|
+
.option('--tags <tags>', 'Filter by tags (comma-separated)')
|
|
7975
8053
|
.action(async (opts) => {
|
|
7976
8054
|
const config = getBrainConfig(opts);
|
|
7977
8055
|
try {
|
|
7978
|
-
const
|
|
7979
|
-
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(
|
|
8056
|
+
const data = await brainFetch(config, '/v1/memories/list', { params: { category: opts.category, limit: opts.limit, offset: opts.offset, sort: opts.sort, tags: opts.tags } });
|
|
8057
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
7980
8058
|
console.log(chalk.bold.cyan('\nShared Brain Memories\n'));
|
|
7981
|
-
|
|
7982
|
-
|
|
8059
|
+
const memories = Array.isArray(data) ? data : data.memories || [];
|
|
8060
|
+
if (data.total_count !== undefined) {
|
|
8061
|
+
console.log(chalk.dim(` Showing ${memories.length} of ${data.total_count} (offset ${data.offset || 0})\n`));
|
|
8062
|
+
}
|
|
8063
|
+
if (!memories.length) { console.log(chalk.dim(' No memories found.\n')); return; }
|
|
8064
|
+
memories.forEach((r, i) => {
|
|
7983
8065
|
console.log(` ${chalk.yellow(i + 1 + '.')} ${chalk.bold(r.title || r.id)} ${chalk.dim(`[${r.category || 'unknown'}]`)}`);
|
|
7984
8066
|
});
|
|
7985
8067
|
console.log();
|
|
@@ -7990,10 +8072,12 @@ brainCmd.command('delete <id>')
|
|
|
7990
8072
|
.description('Delete your own contribution')
|
|
7991
8073
|
.option('--url <url>', 'Brain server URL')
|
|
7992
8074
|
.option('--key <key>', 'Pi key')
|
|
8075
|
+
.option('--json', 'Output as JSON')
|
|
7993
8076
|
.action(async (id, opts) => {
|
|
7994
8077
|
const config = getBrainConfig(opts);
|
|
7995
8078
|
try {
|
|
7996
|
-
await brainFetch(config, `/v1/memories/${id}`, { method: 'DELETE' });
|
|
8079
|
+
const result = await brainFetch(config, `/v1/memories/${id}`, { method: 'DELETE' });
|
|
8080
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
7997
8081
|
console.log(chalk.green(`Deleted: ${id}`));
|
|
7998
8082
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
7999
8083
|
});
|
|
@@ -8088,10 +8172,12 @@ brainCmd.command('sync [direction]')
|
|
|
8088
8172
|
.description('Synchronize LoRA weights (pull, push, or both)')
|
|
8089
8173
|
.option('--url <url>', 'Brain server URL')
|
|
8090
8174
|
.option('--key <key>', 'Pi key')
|
|
8175
|
+
.option('--json', 'Output as JSON')
|
|
8091
8176
|
.action(async (direction, opts) => {
|
|
8092
8177
|
const config = getBrainConfig(opts);
|
|
8093
8178
|
try {
|
|
8094
8179
|
const result = await brainFetch(config, '/v1/lora/latest', { params: { direction: direction || 'both' } });
|
|
8180
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8095
8181
|
console.log(chalk.green(`Sync ${direction || 'both'}: ${result.status || 'OK'}`));
|
|
8096
8182
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8097
8183
|
});
|
|
@@ -8191,7 +8277,7 @@ async function fetchBrainEndpoint(config, endpoint) {
|
|
|
8191
8277
|
const url = (config.url || 'https://pi.ruv.io') + endpoint;
|
|
8192
8278
|
const headers = {};
|
|
8193
8279
|
if (config.key) headers['Authorization'] = `Bearer ${config.key}`;
|
|
8194
|
-
const resp = await
|
|
8280
|
+
const resp = await proxyFetch(url, { headers, signal: AbortSignal.timeout(30000) });
|
|
8195
8281
|
if (!resp.ok) throw new Error(`${resp.status} ${resp.statusText}`);
|
|
8196
8282
|
return resp.json();
|
|
8197
8283
|
}
|
|
@@ -8420,7 +8506,7 @@ midstreamCmd.command('benchmark')
|
|
|
8420
8506
|
|
|
8421
8507
|
async function timeRequest(url, label) {
|
|
8422
8508
|
const start = performance.now();
|
|
8423
|
-
const resp = await
|
|
8509
|
+
const resp = await proxyFetch(url, { headers, signal: AbortSignal.timeout(30000) });
|
|
8424
8510
|
const elapsed = performance.now() - start;
|
|
8425
8511
|
return { label, status: resp.status, elapsed };
|
|
8426
8512
|
}
|
|
@@ -8490,7 +8576,7 @@ edgeCmd.command('status')
|
|
|
8490
8576
|
.option('--json', 'Output as JSON')
|
|
8491
8577
|
.action(async (opts) => {
|
|
8492
8578
|
try {
|
|
8493
|
-
const resp = await
|
|
8579
|
+
const resp = await proxyFetch(`${EDGE_GENESIS}/status`, { signal: AbortSignal.timeout(30000) });
|
|
8494
8580
|
const data = await resp.json();
|
|
8495
8581
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8496
8582
|
console.log(chalk.bold.cyan('\nEdge Network Status\n'));
|
|
@@ -8506,10 +8592,11 @@ edgeCmd.command('join')
|
|
|
8506
8592
|
const piKey = process.env.PI;
|
|
8507
8593
|
if (!piKey) { console.error(chalk.red('Set PI environment variable first. Run: npx ruvector identity generate')); process.exit(1); }
|
|
8508
8594
|
try {
|
|
8509
|
-
const resp = await
|
|
8595
|
+
const resp = await proxyFetch(`${EDGE_GENESIS}/join`, {
|
|
8510
8596
|
method: 'POST',
|
|
8511
8597
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${piKey}` },
|
|
8512
|
-
body: JSON.stringify({ contribution: parseFloat(opts.contribution), pi_key: piKey })
|
|
8598
|
+
body: JSON.stringify({ contribution: parseFloat(opts.contribution), pi_key: piKey }),
|
|
8599
|
+
signal: AbortSignal.timeout(30000)
|
|
8513
8600
|
});
|
|
8514
8601
|
const data = await resp.json();
|
|
8515
8602
|
console.log(chalk.green(`Joined edge network: ${data.node_id || 'OK'}`));
|
|
@@ -8524,7 +8611,7 @@ edgeCmd.command('balance')
|
|
|
8524
8611
|
if (!piKey) { console.error(chalk.red('Set PI environment variable first.')); process.exit(1); }
|
|
8525
8612
|
try {
|
|
8526
8613
|
const pseudonym = require('crypto').createHash('shake256', { outputLength: 16 }).update(piKey).digest('hex');
|
|
8527
|
-
const resp = await
|
|
8614
|
+
const resp = await proxyFetch(`${EDGE_GENESIS}/balance/${pseudonym}`, { headers: { 'Authorization': `Bearer ${piKey}` }, signal: AbortSignal.timeout(30000) });
|
|
8528
8615
|
if (!resp.ok) { console.error(chalk.red(`Edge network returned ${resp.status} ${resp.statusText}`)); process.exit(1); }
|
|
8529
8616
|
const data = await resp.json();
|
|
8530
8617
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
@@ -8540,7 +8627,7 @@ edgeCmd.command('tasks')
|
|
|
8540
8627
|
.option('--json', 'Output as JSON')
|
|
8541
8628
|
.action(async (opts) => {
|
|
8542
8629
|
try {
|
|
8543
|
-
const resp = await
|
|
8630
|
+
const resp = await proxyFetch(`${EDGE_GENESIS}/tasks?limit=${opts.limit}`, { signal: AbortSignal.timeout(30000) });
|
|
8544
8631
|
const data = await resp.json();
|
|
8545
8632
|
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(data, null, 2)); return; }
|
|
8546
8633
|
console.log(chalk.bold.cyan('\nEdge Compute Tasks\n'));
|
package/bin/mcp-server.js
CHANGED
|
@@ -95,6 +95,71 @@ function sanitizeNumericArg(arg, defaultVal) {
|
|
|
95
95
|
return Number.isFinite(n) && n > 0 ? n : (defaultVal || 0);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// ── Proxy-aware fetch wrapper ───────────────────────────────────────────────
|
|
99
|
+
let _proxyDispatcherSet = false;
|
|
100
|
+
|
|
101
|
+
function getProxyUrl(targetUrl) {
|
|
102
|
+
const NO_PROXY = process.env.NO_PROXY || process.env.no_proxy || '';
|
|
103
|
+
if (NO_PROXY === '*') return null;
|
|
104
|
+
if (NO_PROXY) {
|
|
105
|
+
try {
|
|
106
|
+
const host = new URL(targetUrl).hostname.toLowerCase();
|
|
107
|
+
const patterns = NO_PROXY.split(',').map(p => p.trim().toLowerCase());
|
|
108
|
+
for (const p of patterns) {
|
|
109
|
+
if (!p) continue;
|
|
110
|
+
if (host === p || host.endsWith(p.startsWith('.') ? p : '.' + p)) return null;
|
|
111
|
+
}
|
|
112
|
+
} catch {}
|
|
113
|
+
}
|
|
114
|
+
return process.env.HTTPS_PROXY || process.env.https_proxy
|
|
115
|
+
|| process.env.HTTP_PROXY || process.env.http_proxy
|
|
116
|
+
|| process.env.ALL_PROXY || process.env.all_proxy
|
|
117
|
+
|| null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function proxyFetch(url, opts) {
|
|
121
|
+
const target = typeof url === 'string' ? url : url.toString();
|
|
122
|
+
const proxy = getProxyUrl(target);
|
|
123
|
+
if (!proxy) return fetch(url, opts);
|
|
124
|
+
|
|
125
|
+
if (!_proxyDispatcherSet) {
|
|
126
|
+
try {
|
|
127
|
+
const undici = require('undici');
|
|
128
|
+
if (undici.ProxyAgent && undici.setGlobalDispatcher) {
|
|
129
|
+
undici.setGlobalDispatcher(new undici.ProxyAgent(proxy));
|
|
130
|
+
_proxyDispatcherSet = true;
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
133
|
+
}
|
|
134
|
+
if (_proxyDispatcherSet) return fetch(url, opts);
|
|
135
|
+
|
|
136
|
+
const { execFileSync } = require('child_process');
|
|
137
|
+
const args = ['-sS', '-L', '--max-time', '30'];
|
|
138
|
+
if (opts && opts.method) { args.push('-X', opts.method); }
|
|
139
|
+
if (opts && opts.headers) {
|
|
140
|
+
for (const [k, v] of Object.entries(opts.headers)) {
|
|
141
|
+
args.push('-H', `${k}: ${v}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (opts && opts.body) { args.push('-d', typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body)); }
|
|
145
|
+
args.push(target);
|
|
146
|
+
try {
|
|
147
|
+
const stdout = execFileSync('curl', args, { encoding: 'utf8', timeout: 35000 });
|
|
148
|
+
const body = stdout.trim();
|
|
149
|
+
return {
|
|
150
|
+
ok: true,
|
|
151
|
+
status: 200,
|
|
152
|
+
statusText: 'OK',
|
|
153
|
+
text: async () => body,
|
|
154
|
+
json: async () => JSON.parse(body),
|
|
155
|
+
headers: new Map(),
|
|
156
|
+
};
|
|
157
|
+
} catch (e) {
|
|
158
|
+
const msg = e.stderr ? e.stderr.toString().trim() : e.message;
|
|
159
|
+
throw new Error(`Proxy curl failed: ${msg}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
98
163
|
// Try to load the full IntelligenceEngine
|
|
99
164
|
let IntelligenceEngine = null;
|
|
100
165
|
let engineAvailable = false;
|
|
@@ -363,7 +428,7 @@ class Intelligence {
|
|
|
363
428
|
const server = new Server(
|
|
364
429
|
{
|
|
365
430
|
name: 'ruvector',
|
|
366
|
-
version: '0.2.
|
|
431
|
+
version: '0.2.8',
|
|
367
432
|
},
|
|
368
433
|
{
|
|
369
434
|
capabilities: {
|
|
@@ -3122,7 +3187,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3122
3187
|
// Fetch from GCS if no fresh cache
|
|
3123
3188
|
if (!manifest) {
|
|
3124
3189
|
try {
|
|
3125
|
-
const resp = await
|
|
3190
|
+
const resp = await proxyFetch(GCS_MANIFEST, { signal: AbortSignal.timeout(15000) });
|
|
3126
3191
|
if (resp.ok) {
|
|
3127
3192
|
manifest = await resp.json();
|
|
3128
3193
|
try {
|
|
@@ -3320,6 +3385,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3320
3385
|
const p = new URLSearchParams();
|
|
3321
3386
|
if (args.category) p.set('category', args.category);
|
|
3322
3387
|
p.set('limit', String(args.limit || 20));
|
|
3388
|
+
if (args.offset) p.set('offset', String(args.offset));
|
|
3389
|
+
if (args.sort) p.set('sort', args.sort);
|
|
3390
|
+
if (args.tags) p.set('tags', args.tags);
|
|
3323
3391
|
url = `${brainUrl}/v1/memories/list?${p}`;
|
|
3324
3392
|
break;
|
|
3325
3393
|
}
|
|
@@ -3350,7 +3418,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3350
3418
|
}
|
|
3351
3419
|
case 'sync': url = `${brainUrl}/v1/lora/latest`; break;
|
|
3352
3420
|
}
|
|
3353
|
-
const resp = await
|
|
3421
|
+
const resp = await proxyFetch(url, fetchOpts);
|
|
3354
3422
|
if (!resp.ok) {
|
|
3355
3423
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
3356
3424
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
@@ -3384,7 +3452,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3384
3452
|
brain_flags: '/v1/status',
|
|
3385
3453
|
};
|
|
3386
3454
|
const endpoint = endpointMap[name];
|
|
3387
|
-
const resp = await
|
|
3455
|
+
const resp = await proxyFetch(`${brainUrl}${endpoint}`, { headers: hdrs, signal: AbortSignal.timeout(30000) });
|
|
3388
3456
|
if (!resp.ok) {
|
|
3389
3457
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
3390
3458
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
@@ -3428,7 +3496,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3428
3496
|
const hdrs = { 'Content-Type': 'application/json' };
|
|
3429
3497
|
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3430
3498
|
|
|
3431
|
-
const resp = await
|
|
3499
|
+
const resp = await proxyFetch(`${brainUrl}/v1/midstream`, { headers: hdrs, signal: AbortSignal.timeout(30000) });
|
|
3432
3500
|
if (!resp.ok) {
|
|
3433
3501
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
3434
3502
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
@@ -3458,7 +3526,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3458
3526
|
|
|
3459
3527
|
async function timeFetch(url) {
|
|
3460
3528
|
const start = performance.now();
|
|
3461
|
-
const resp = await
|
|
3529
|
+
const resp = await proxyFetch(url, { headers: hdrs });
|
|
3462
3530
|
return { status: resp.status, elapsed: performance.now() - start };
|
|
3463
3531
|
}
|
|
3464
3532
|
|
|
@@ -3511,7 +3579,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3511
3579
|
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3512
3580
|
const limit = Math.min(Math.max(parseInt(args.limit) || 10, 1), 100);
|
|
3513
3581
|
const q = encodeURIComponent(args.query);
|
|
3514
|
-
const resp = await
|
|
3582
|
+
const resp = await proxyFetch(`${brainUrl}/v1/memories/search?q=${q}&limit=${limit}`, { headers: hdrs, signal: AbortSignal.timeout(30000) });
|
|
3515
3583
|
if (!resp.ok) {
|
|
3516
3584
|
const errText = await resp.text().catch(() => resp.statusText);
|
|
3517
3585
|
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: `${resp.status} ${errText}` }, null, 2) }], isError: true };
|
|
@@ -3531,8 +3599,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3531
3599
|
if (brainKey) hdrs['Authorization'] = `Bearer ${brainKey}`;
|
|
3532
3600
|
|
|
3533
3601
|
const [healthResp, midResp] = await Promise.all([
|
|
3534
|
-
|
|
3535
|
-
|
|
3602
|
+
proxyFetch(`${brainUrl}/v1/health`, { headers: hdrs, signal: AbortSignal.timeout(15000) }).then(r => r.json()).catch(e => ({ error: e.message })),
|
|
3603
|
+
proxyFetch(`${brainUrl}/v1/midstream`, { headers: hdrs, signal: AbortSignal.timeout(15000) }).then(r => r.json()).catch(e => ({ error: e.message })),
|
|
3536
3604
|
]);
|
|
3537
3605
|
|
|
3538
3606
|
return { content: [{ type: 'text', text: JSON.stringify({
|
|
@@ -3560,7 +3628,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3560
3628
|
case 'balance': { const ps = process.env.PI ? require('crypto').createHash('shake256', { outputLength: 16 }).update(process.env.PI).digest('hex') : 'anonymous'; endpoint = `/balance/${ps}`; break; }
|
|
3561
3629
|
case 'tasks': endpoint = `/tasks?limit=${args.limit || 20}`; break;
|
|
3562
3630
|
}
|
|
3563
|
-
const resp = await
|
|
3631
|
+
const resp = await proxyFetch(`${genesisUrl}${endpoint}`, {
|
|
3564
3632
|
method,
|
|
3565
3633
|
headers: { 'Content-Type': 'application/json', ...(process.env.PI ? { 'Authorization': `Bearer ${process.env.PI}` } : {}) },
|
|
3566
3634
|
...(body ? { body } : {})
|
|
@@ -3831,7 +3899,7 @@ async function main() {
|
|
|
3831
3899
|
transport: 'sse',
|
|
3832
3900
|
sessions: sessions.size,
|
|
3833
3901
|
tools: 91,
|
|
3834
|
-
version: '0.2.
|
|
3902
|
+
version: '0.2.8'
|
|
3835
3903
|
}));
|
|
3836
3904
|
|
|
3837
3905
|
} else {
|