openzoo 0.48.59 → 0.48.61

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.
Files changed (3) hide show
  1. package/lib/mcp.js +13 -13
  2. package/lib/proxy.js +13 -3
  3. package/package.json +1 -1
package/lib/mcp.js CHANGED
@@ -32,14 +32,14 @@ export function buildMcpServer() {
32
32
  'openzoo — pay-per-call access to ~435 models (openzoo.fun). No API key, no account: each call is paid',
33
33
  'from the operator\'s local burner wallet via x402 (Solana / Base / Robinhood Chain).',
34
34
  '',
35
- 'CONTEXT IS EFFECTIVELY UNBOUNDED. Pass big bodies to zoo_ask\'s `corpus` WHOLE do not summarise,',
36
- 'truncate, or chunk-to-fit. leCore holographic memory sits in front of every model: the corpus is bound',
37
- 'once (client-usable ceiling ~128M tokens; keep a single call under ~9.8M) and the model reads only a few',
38
- 'thousand tokens of it. A corpus already bound is never re-uploaded later asks against it are near-free,',
39
- 'so ask many questions of the same corpus rather than re-sending it. zoo_contexts lists what is bound.',
35
+ 'Long bodies: zoo_ask\'s `corpus` accepts a whole document. leCore holographic memory sits in front of',
36
+ 'every model, so a corpus is bound once and the model reads a few thousand tokens of it — summarising or',
37
+ 'chunking to fit is not required here. Client-usable ceiling is ~128M tokens; a single call stays under',
38
+ '~9.8M. A corpus already bound is not re-uploaded, so later asks against it are near-free — asking many',
39
+ 'questions of one corpus costs less than re-sending it. zoo_contexts lists what is bound.',
40
40
  '',
41
- 'Never search the machine for API keys or endpoints — there are none to find. zoo_wallet shows funding',
42
- 'state, zoo_models lists what is served with live pricing.',
41
+ 'There are no API keys or endpoints on the machine to find payment is per-call from the wallet. zoo_wallet',
42
+ 'shows funding state; zoo_models lists what is served with live pricing.',
43
43
  '',
44
44
  // Agents previously probed zoo_ask, got text back, and concluded the zoo
45
45
  // could not do media at all — the text upstream serves NO video models.
@@ -48,9 +48,9 @@ export function buildMcpServer() {
48
48
  ' zoo_video asynchronous, returns a job id (Sora 2, Veo 3.1, Kling, Seedance, Wan, pixverse…)',
49
49
  ' zoo_video_result poll the job id — free, the render was paid for at submit',
50
50
  'In zoo_models these carry kind="image" / kind="video" and are priced per image or per clip, not per token.',
51
- 'leCore does NOT participate in a render: a diffusion prompt never reaches the spill threshold, so do not',
52
- 'claim holographic memory improved the picture. To ground a render in your own material, use zoo_ask to',
53
- 'WRITE the prompt from a bound corpus, then pass that prompt to zoo_image / zoo_video.',
51
+ 'leCore does not participate in a render: a diffusion prompt never reaches the spill threshold, so holographic',
52
+ 'memory has no effect on the picture. To ground a render in existing material, zoo_ask can',
53
+ 'write the prompt from a bound corpus, and that prompt goes to zoo_image / zoo_video.',
54
54
  '',
55
55
  // ROUTING, STATED UNCONDITIONALLY. An agent whose OWN inference is not
56
56
  // routed through the proxy never receives lib/brief.js, so it answers
@@ -74,7 +74,7 @@ export function buildMcpServer() {
74
74
  server.registerTool('zoo_ask', {
75
75
  description:
76
76
  'Ask a question through openzoo.fun, paying the x402 quote transparently from the local burner wallet. '
77
- + 'PASS BIG CONTEXT WHOLE in `corpus` — do not summarise, truncate or chunk it to fit a context window. '
77
+ + 'Big context can go WHOLE into `corpus` — summarising, truncating or chunking to fit a context window is not required here. '
78
78
  + 'leCore holographic memory sits in front of every model, so a corpus far past the model\'s own limit '
79
79
  + '(client-usable ceiling ~128M tokens; keep one call under ~9.8M) is bound once and the model reads only '
80
80
  + 'a few thousand tokens of it. Re-asking against an already-bound corpus is near-free and much faster, so '
@@ -160,7 +160,7 @@ export function buildMcpServer() {
160
160
  balances,
161
161
  fundWith: rails ? railFundingHint(rails.live) : 'USDC or TOKEN on Solana',
162
162
  solanaMints: Object.fromEntries(FUNDING_ASSETS.map((a) => [a.symbol, a.mint])),
163
- tellTheUser: 'Report this verbatim the operator must fund the wallet above; you cannot fix it yourself, and retrying will fail identically until they do.',
163
+ tellTheUser: 'The wallet above needs funding by the operator. This is not fixable from inside the conversation, and a retry fails identically until it is funded.',
164
164
  }),
165
165
  isError: true,
166
166
  };
@@ -411,7 +411,7 @@ export function buildMcpServer() {
411
411
  files: out.files.length,
412
412
  parts: out.parts,
413
413
  reused: out.reused,
414
- next: `Call zoo_ask with context_id="${out.contextId}" and your question. Do NOT paste the corpus into the prompt it is already bound.`,
414
+ next: `zoo_ask with context_id="${out.contextId}" and a question answers from this corpus; it is already bound, so pasting it into the prompt would send it twice.`,
415
415
  });
416
416
  } catch (e) {
417
417
  return text({ error: e.message });
package/lib/proxy.js CHANGED
@@ -1266,7 +1266,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
1266
1266
  } catch (err) {
1267
1267
  log(`context cache skipped for this call: ${err.message}`);
1268
1268
  }
1269
- const send = (buf, ctxId, topK) => client.fetch(url, {
1269
+ const send = (buf, ctxId, topK, corpusChars) => client.fetch(url, {
1270
1270
  ...init,
1271
1271
  body: buf,
1272
1272
  headers: ctxId
@@ -1275,6 +1275,16 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
1275
1275
  'x-hrr-context': ctxId,
1276
1276
  // Only on the spill path — a caller that set its own top-k keeps it.
1277
1277
  ...(topK ? { 'x-hrr-top-k': String(topK) } : {}),
1278
+ // TELL THE GATEWAY HOW BIG THE CORPUS IS. It has been guessing:
1279
+ // `contextChars` is populated only when a bind passes through the
1280
+ // gateway itself, so on an APPEND — and on every corpus that
1281
+ // includes files the agent read, which never appear in a request
1282
+ // body at all — it has no idea and falls back to the body size.
1283
+ // That is why the counterfactual logged `corpus ?` all day and why
1284
+ // a call whose corpus held 40,777 tokens priced as if it held
1285
+ // 4,303. The proxy assembled the corpus; it is the only party that
1286
+ // knows.
1287
+ ...(corpusChars ? { 'x-hrr-corpus-chars': String(corpusChars) } : {}),
1278
1288
  }
1279
1289
  : init.headers,
1280
1290
  });
@@ -1285,7 +1295,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
1285
1295
  didSpill = true;
1286
1296
  spilledChars += cached.corpus?.length || 0;
1287
1297
  if (cached.reused) spillReuses += 1;
1288
- result = await send(cached.body, cached.contextId, cached.topK);
1298
+ result = await send(cached.body, cached.contextId, cached.topK, cached.corpus?.length);
1289
1299
  // Sidecar wiped between runs: the gateway 404s BEFORE the 402 (nothing
1290
1300
  // paid). Never fail on a stale manifest — re-bind once and retry.
1291
1301
  if (result.response.status === 404) {
@@ -1294,7 +1304,7 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
1294
1304
  log('bound context is gone on the zoo — re-binding once...');
1295
1305
  forgetContext(config.apiBase, cached.hash);
1296
1306
  const rebound = await bindCorpus(cached.corpus, { force: true });
1297
- result = await send(cached.body, rebound.contextId, cached.topK);
1307
+ result = await send(cached.body, rebound.contextId, cached.topK, cached.corpus?.length);
1298
1308
  } else {
1299
1309
  res.writeHead(404, { 'content-type': 'application/json' });
1300
1310
  res.end(text);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.48.59",
3
+ "version": "0.48.61",
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",