openzoo 0.35.0 → 0.35.2
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/lib/mcp.js +41 -0
- package/lib/proxy.js +24 -3
- package/package.json +1 -1
package/lib/mcp.js
CHANGED
|
@@ -292,6 +292,47 @@ export function buildMcpServer() {
|
|
|
292
292
|
}
|
|
293
293
|
});
|
|
294
294
|
|
|
295
|
+
// leCore's own catalog — leCore docs/ZOO.md §1. Rule-0 for the model: ask the
|
|
296
|
+
// engine whether a faculty exists BEFORE writing the algorithm yourself.
|
|
297
|
+
// 3,214 capabilities; a curated tools/list would hide almost all of them, so
|
|
298
|
+
// discovery is a search and execution is one generic tool, exactly as leCore
|
|
299
|
+
// ships it over its own MCP.
|
|
300
|
+
server.registerTool('zoo_lecore_find', {
|
|
301
|
+
description:
|
|
302
|
+
'BEFORE implementing any algorithm, search leCore for it — 3,214 verified capabilities '
|
|
303
|
+
+ '(nearest-neighbour search, float compression, mesh ops, certified image operators, physics '
|
|
304
|
+
+ 'stepping, forecasting, corpus QA, bootstrap CIs, void/discovery, program-to-weights). '
|
|
305
|
+
+ 'Hand-rolling what this returns is wasted tokens and worse code. Free, no payment.',
|
|
306
|
+
inputSchema: {
|
|
307
|
+
query: z.string().describe('What you are trying to do, in plain words: "nearest neighbour search", "compress floats".'),
|
|
308
|
+
top: z.number().int().positive().optional().describe('How many hits. Default 8.'),
|
|
309
|
+
},
|
|
310
|
+
}, async ({ query, top }) => {
|
|
311
|
+
const r = await fetch(`${config.apiBase}/v1/lecore/find`, {
|
|
312
|
+
method: 'POST', headers: withNamespace({ 'content-type': 'application/json' }),
|
|
313
|
+
body: JSON.stringify({ query, top: top ?? 8 }),
|
|
314
|
+
});
|
|
315
|
+
return text(await r.json());
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
server.registerTool('zoo_lecore_invoke', {
|
|
319
|
+
description:
|
|
320
|
+
'Run any leCore capability by name (find it first with zoo_lecore_find). Returns the result plus '
|
|
321
|
+
+ 'measured cost {elapsed_ms, payload_bytes} and a determinism receipt {input_sha256, output_sha256} — '
|
|
322
|
+
+ 'the same call with the same args always produces the same output hash, so results are verifiable '
|
|
323
|
+
+ 'and cacheable. Free, no payment.',
|
|
324
|
+
inputSchema: {
|
|
325
|
+
name: z.string().describe('Capability name exactly as zoo_lecore_find returned it.'),
|
|
326
|
+
args: z.record(z.any()).optional().describe('Arguments object for the capability.'),
|
|
327
|
+
},
|
|
328
|
+
}, async ({ name, args }) => {
|
|
329
|
+
const r = await fetch(`${config.apiBase}/v1/lecore/invoke`, {
|
|
330
|
+
method: 'POST', headers: withNamespace({ 'content-type': 'application/json' }),
|
|
331
|
+
body: JSON.stringify({ name, args: args || {} }),
|
|
332
|
+
});
|
|
333
|
+
return text(await r.json());
|
|
334
|
+
});
|
|
335
|
+
|
|
295
336
|
server.registerTool('zoo_contexts', {
|
|
296
337
|
description: 'List corpora already bound to the zoo\'s holographic memory (local manifest). A listed corpus is never re-uploaded — asks against it are near-free.',
|
|
297
338
|
inputSchema: {},
|
package/lib/proxy.js
CHANGED
|
@@ -194,8 +194,29 @@ function serveAsSse(res, data, upstream) {
|
|
|
194
194
|
*/
|
|
195
195
|
const REPLAY_TTL_MS = 30_000;
|
|
196
196
|
const replayCache = new Map(); // sha256(body) -> { at, data, settle }
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
/**
|
|
198
|
+
* The key MUST include the routing headers, not just the body.
|
|
199
|
+
*
|
|
200
|
+
* Keying on the body alone was a correctness bug, not merely a caching one:
|
|
201
|
+
* N shards asking the SAME question of N DIFFERENT bound corpora send
|
|
202
|
+
* byte-identical bodies and differ only in X-HRR-Context. They collided on one
|
|
203
|
+
* key, so shards 2..N were served shard 1's answer — REPRODUCED in the field:
|
|
204
|
+
* 10 shards, 7 byte-identical replies across corpora known to differ, and the
|
|
205
|
+
* batch finished in 12s where a single uncached call took ~7s.
|
|
206
|
+
*
|
|
207
|
+
* Wrong answers attributed to the wrong corpus is a far worse failure than the
|
|
208
|
+
* double-billing this cache exists to prevent, so every header that can change
|
|
209
|
+
* the ANSWER joins the key.
|
|
210
|
+
*/
|
|
211
|
+
const REPLAY_KEY_HEADERS = ['x-hrr-context', 'x-hrr-top-k', 'x-hrr-gate', 'x-openzoo-namespace'];
|
|
212
|
+
|
|
213
|
+
function replayKey(bodyBuf, headers = {}) {
|
|
214
|
+
const h = crypto.createHash('sha256').update(bodyBuf);
|
|
215
|
+
for (const name of REPLAY_KEY_HEADERS) {
|
|
216
|
+
const v = headers[name];
|
|
217
|
+
if (v) h.update(`\n${name}:${v}`);
|
|
218
|
+
}
|
|
219
|
+
return h.digest('hex');
|
|
199
220
|
}
|
|
200
221
|
function replayGet(key) {
|
|
201
222
|
const hit = replayCache.get(key);
|
|
@@ -531,7 +552,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
531
552
|
// Retry of a body we answered seconds ago? Serve the cached completion —
|
|
532
553
|
// never pay twice for a harness's reconnect loop.
|
|
533
554
|
const isChat = req.method === 'POST' && (req.url || '').includes('/chat/completions');
|
|
534
|
-
const rKey = isChat ? replayKey(bodyBuf) : null;
|
|
555
|
+
const rKey = isChat ? replayKey(bodyBuf, req.headers) : null;
|
|
535
556
|
if (rKey) {
|
|
536
557
|
const hit = replayGet(rKey);
|
|
537
558
|
if (hit) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.2",
|
|
4
4
|
"description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|