openzoo 0.48.49 → 0.48.50

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
@@ -93,7 +93,7 @@ Builds a ~965k-token document with one planted fact, shows that buying direct re
93
93
 
94
94
  ```
95
95
  bound once in 14.8s: 3.7MB → context ctx_01KZZY8YQE…
96
- quote for the ask: $0.000480 · pricing=markup (a tiny body — the 3.7MB corpus is not re-priced)
96
+ quote for the ask: $0.000480 · pricing=markup (a tiny body — the 3.7MB corpus is not re-priced)
97
97
  ```
98
98
 
99
99
  If the wallet is funded with USDC or TOKEN it pays (capped at `OPENZOO_DEMO_MAX_USD`, default $0.01) and prints the answer, the tokens the model actually read, and the receipt. If not, it prints exactly what to fund. Long waits (the one-time upload, pricing, payment, the answer) show a live progress line with stage + elapsed seconds.
@@ -111,7 +111,7 @@ If the wallet is funded with USDC or TOKEN it pays (capped at `OPENZOO_DEMO_MAX_
111
111
  The zoo keeps your corpus in leCore holographic memory; the shim keeps a manifest at `~/.openzoo/contexts.json` (chmod 600) mapping `sha256(corpus)` → the zoo's `context_id`, scoped per API base. When a request carries a corpus the manifest already knows:
112
112
 
113
113
  - **nothing big is uploaded** — the ask ships alone with an `X-HRR-Context` header,
114
- - **the 402 prices the tiny ask** (markup basis, honestly labeled `pricing=markup`), typically a few hundredths of a cent instead of re-pricing megabytes,
114
+ - **the 402 prices the tiny ask** (honestly labeled `pricing=markup`), typically a few hundredths of a cent instead of re-pricing megabytes,
115
115
  - **the answer still comes from your corpus** — the zoo recalls the relevant slices server-side.
116
116
 
117
117
  This works in all three fronts: the **proxy** (a big pasted body in the last message is split at its last blank line, bound once, and reused on every later call — even with a different question), the **MCP** `zoo_ask` `corpus` parameter, and the **demo**. If the zoo ever forgets a context (sidecar wipe), the gateway answers 404 *before* any payment and the shim transparently re-binds once and retries — a stale manifest never fails a call.
@@ -175,9 +175,9 @@ Pin the key with `OPENZOO_TUNNEL_TOKEN` if your IDE stores it. Keys never leave
175
175
  ## Honest pricing note
176
176
 
177
177
  Two bases, reported per call in the 402 (`extra.pricing`):
178
- - **Short prompts price at a markup** (3× provider cost) there's nothing to spill, you're paying for passthrough.
178
+ - **Short prompts price at cost.** There's nothing to spill, so there's no saving to share — you pay what the call cost us, reconciled against the provider's own metered figure after it completes.
179
179
  - **Big bodies price at a counterfactual discount** (~10× cheaper than buying the same call direct) — the zoo's leCore memory means it never forwards your whole body upstream, and passes the savings on. Measured numbers at [benches.openzoo.fun](https://benches.openzoo.fun).
180
- - **Asks against a bound corpus price on the markup basis** (3× a tiny body — the receipt says `pricing=markup`). That is not a discount trick: 3× of a few hundred tokens is normally far below even the counterfactual price of shipping the corpus, which is the whole point of binding once.
180
+ - **Asks against a bound corpus price on the small forwarded body** (the receipt says `pricing=markup`). That is not a discount trick: a few hundred tokens at cost is far below the counterfactual price of shipping the corpus, which is the whole point of binding once.
181
181
 
182
182
  The receipt names which base you got; `extra.directUsd` / `extra.savesVsDirect` let you check the math.
183
183
 
package/lib/proxy.js CHANGED
@@ -391,6 +391,29 @@ async function spillTranscript(body, log) {
391
391
  }
392
392
  if (tailStart > cut) cut = tailStart;
393
393
 
394
+ // NEVER SPILL THE CURRENT ASK.
395
+ //
396
+ // The tail budget walks BACKWARD accumulating bytes, and in an agent loop the
397
+ // last few messages are tool results — file reads, greps, build output. Those
398
+ // alone blow through 6,000 chars, so the cut lands AFTER the user's actual
399
+ // instruction and the instruction goes into the bound corpus instead of the
400
+ // forwarded window. It then only comes back if top-k recall happens to surface
401
+ // it against its own text, which is exactly the query it is least likely to
402
+ // match.
403
+ //
404
+ // OBSERVED: "sending 2/578 turns", and the model replying "I don't have a
405
+ // specific request to act on — your message came through empty", then
406
+ // re-reading the plan doc to work out where it was, every single turn. A loop
407
+ // that looks like amnesia and is actually us deleting the question.
408
+ //
409
+ // Retrieval is for CONTEXT. The ask itself is never context, and must survive
410
+ // any budget.
411
+ let lastUser = -1;
412
+ for (let i = msgs.length - 1; i > firstSpillable; i--) {
413
+ if (msgs[i].role === 'user' && msgText(msgs[i]).trim()) { lastUser = i; break; }
414
+ }
415
+ if (lastUser > firstSpillable && cut > lastUser) cut = lastUser;
416
+
394
417
  const head = msgs.slice(0, firstSpillable); // system block, always kept
395
418
  const corpus = msgs.slice(firstSpillable, cut).map(msgText).filter(Boolean).join('\n\n');
396
419
  if (corpus.length <= BIND_MIN_CHARS) return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.48.49",
3
+ "version": "0.48.50",
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",