openzoo 0.48.43 → 0.48.45
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/launch.js +34 -1
- package/lib/proxy.js +36 -0
- package/package.json +1 -1
package/lib/launch.js
CHANGED
|
@@ -177,6 +177,19 @@ export async function launchClaude(argv) {
|
|
|
177
177
|
const SAFE = /^claude-(opus|sonnet|fable)-/;
|
|
178
178
|
if (SAFE.test(bare)) env.ANTHROPIC_MODEL = `openzoo-${bare}`;
|
|
179
179
|
}
|
|
180
|
+
// THE ACTUAL SWITCHES. Three earlier attempts missed these entirely:
|
|
181
|
+
// autoCompactEnabled in settings (global, trapped a session), a raised
|
|
182
|
+
// CLAUDE_CODE_MAX_CONTEXT_TOKENS (clamped to 200k by the model table), and an
|
|
183
|
+
// unrecognised model alias (resolves fine, still compacted). DISABLE_COMPACT
|
|
184
|
+
// and DISABLE_AUTO_COMPACT are in the binary and are the direct controls.
|
|
185
|
+
//
|
|
186
|
+
// Correct here for the same reason as everything else in this block: the
|
|
187
|
+
// proxy binds the prefix and forwards a bounded tail, so the request that
|
|
188
|
+
// leaves this machine stays small no matter how long the conversation runs.
|
|
189
|
+
if (process.env.OPENZOO_KEEP_COMPACT !== '1') {
|
|
190
|
+
env.DISABLE_COMPACT = process.env.DISABLE_COMPACT || '1';
|
|
191
|
+
env.DISABLE_AUTO_COMPACT = process.env.DISABLE_AUTO_COMPACT || '1';
|
|
192
|
+
}
|
|
180
193
|
// RAISE THE CEILING, because the proxy already removed it.
|
|
181
194
|
//
|
|
182
195
|
// Claude Code counts the WHOLE local transcript against the model's window and
|
|
@@ -235,7 +248,14 @@ export async function launchClaude(argv) {
|
|
|
235
248
|
+ 'const lbl=(isFinite(sx2)&&sx2>0)?"x on spilled":"x vs direct";'
|
|
236
249
|
+ 'const col2=(on>1)?"\\x1b[32m":"\\x1b[90m";'
|
|
237
250
|
+ 'const save=(on==null||!isFinite(on))?"":(" \\u00b7 "+col2+on.toFixed(4)+lbl+(sv>0?(" ($"+sv.toFixed(4)+" saved)"):"")+"\\x1b[0m");'
|
|
238
|
-
|
|
251
|
+
// REAL upstream cost, metered by OpenRouter (`usage.cost`), not our
|
|
252
|
+
// catalog estimate. Everything else on this line is derived from
|
|
253
|
+
// `max_tokens`, which callers set as a ceiling — measured 2026-08-19, a
|
|
254
|
+
// $0.9858 quote covered $0.007962 of actual inference. Showing the two
|
|
255
|
+
// side by side is the only way the markup is visible while it is happening.
|
|
256
|
+
+ 'const ac=j.actual||{};'
|
|
257
|
+
+ 'const real=(ac.calls>0)?(" \\u00b7 $"+Number(ac.upstreamUsd||0).toFixed(4)+" real"+(ac.markupX?(" ("+ac.markupX+"x)"):"")):"";'
|
|
258
|
+
+ 'process.stdout.write("\\x1b[38;5;208m\\u25cf\\x1b[0m openzoo $"+(Number(j.spendUsd)||0).toFixed(4)+" "+(j.paidCalls||0)+" call"+((j.paidCalls||0)===1?"":"s")+save+real+spill+cr+" \\u00b7 x402")}'
|
|
239
259
|
+ 'catch{process.stdout.write("\\x1b[38;5;208m\\u25cf\\x1b[0m openzoo \\u00b7 x402")}})\'\n');
|
|
240
260
|
fs.chmodSync(scriptPath, 0o755);
|
|
241
261
|
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
@@ -428,6 +448,19 @@ export async function launchHarness(cmd, args) {
|
|
|
428
448
|
const SAFE = /^claude-(opus|sonnet|fable)-/;
|
|
429
449
|
if (SAFE.test(bare)) env.ANTHROPIC_MODEL = `openzoo-${bare}`;
|
|
430
450
|
}
|
|
451
|
+
// THE ACTUAL SWITCHES. Three earlier attempts missed these entirely:
|
|
452
|
+
// autoCompactEnabled in settings (global, trapped a session), a raised
|
|
453
|
+
// CLAUDE_CODE_MAX_CONTEXT_TOKENS (clamped to 200k by the model table), and an
|
|
454
|
+
// unrecognised model alias (resolves fine, still compacted). DISABLE_COMPACT
|
|
455
|
+
// and DISABLE_AUTO_COMPACT are in the binary and are the direct controls.
|
|
456
|
+
//
|
|
457
|
+
// Correct here for the same reason as everything else in this block: the
|
|
458
|
+
// proxy binds the prefix and forwards a bounded tail, so the request that
|
|
459
|
+
// leaves this machine stays small no matter how long the conversation runs.
|
|
460
|
+
if (process.env.OPENZOO_KEEP_COMPACT !== '1') {
|
|
461
|
+
env.DISABLE_COMPACT = process.env.DISABLE_COMPACT || '1';
|
|
462
|
+
env.DISABLE_AUTO_COMPACT = process.env.DISABLE_AUTO_COMPACT || '1';
|
|
463
|
+
}
|
|
431
464
|
// RAISE THE CEILING, because the proxy already removed it.
|
|
432
465
|
//
|
|
433
466
|
// Claude Code counts the WHOLE local transcript against the model's window and
|
package/lib/proxy.js
CHANGED
|
@@ -565,6 +565,22 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
565
565
|
// while spilled calls and offloaded tokens both sat completely still.
|
|
566
566
|
let spillSpend = 0;
|
|
567
567
|
let spillDirect = 0;
|
|
568
|
+
// ACTUAL UPSTREAM SPEND, FROM THE PROVIDER — not our estimate of it.
|
|
569
|
+
//
|
|
570
|
+
// Every other dollar figure here is derived from OpenRouter's CATALOG price
|
|
571
|
+
// times a token count we guessed, and the guess is bad in a specific
|
|
572
|
+
// direction: output is priced on `max_tokens`, which callers set as a ceiling.
|
|
573
|
+
// MEASURED 2026-08-19: a call we quoted at $0.9858 (32,000 reserved output
|
|
574
|
+
// tokens) actually cost $0.007962 — OpenRouter's own number, 124x smaller.
|
|
575
|
+
//
|
|
576
|
+
// OpenRouter returns `usage.cost` on every completion, so the real figure is
|
|
577
|
+
// already in the response body and needs no extra request and no account-level
|
|
578
|
+
// lookup. That last part matters: /api/v1/credits reports the WHOLE key's
|
|
579
|
+
// lifetime usage, and this key also pays for ttfx direct runs and other work,
|
|
580
|
+
// so the account total can never attribute a dollar to this proxy. Per-call
|
|
581
|
+
// cost can.
|
|
582
|
+
let sessionActual = 0;
|
|
583
|
+
let actualCalls = 0;
|
|
568
584
|
// CREDIT, CACHED. Users cannot tell prepaid credit from wallet balance and
|
|
569
585
|
// have to guess whether a call was even paid for ("I don't think x402 made me
|
|
570
586
|
// pay this at all"). The status line runs EVERY turn, so this is refreshed at
|
|
@@ -708,6 +724,18 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
708
724
|
savedUsd: Math.max(0, sessionDirect - sessionSpent),
|
|
709
725
|
savingX: sessionSpent > 0 ? Number((sessionDirect / sessionSpent).toFixed(4)) : null,
|
|
710
726
|
paidCalls,
|
|
727
|
+
// WHAT THE INFERENCE ACTUALLY COST, as reported by OpenRouter on each
|
|
728
|
+
// completion (`usage.cost`). Every other figure above is a catalog
|
|
729
|
+
// estimate built on `max_tokens`; this is metered. `margin` is the
|
|
730
|
+
// honest gross on this session — the number that says whether the
|
|
731
|
+
// pricing is sane, which no estimate can.
|
|
732
|
+
actual: {
|
|
733
|
+
calls: actualCalls,
|
|
734
|
+
upstreamUsd: Number(sessionActual.toFixed(6)),
|
|
735
|
+
billedUsd: Number(sessionSpent.toFixed(6)),
|
|
736
|
+
marginUsd: Number((sessionSpent - sessionActual).toFixed(6)),
|
|
737
|
+
markupX: sessionActual > 0 ? Number((sessionSpent / sessionActual).toFixed(2)) : null,
|
|
738
|
+
},
|
|
711
739
|
mcp: `${self.replace(/\/v1$/, '')}/mcp`,
|
|
712
740
|
upstream: config.apiBase,
|
|
713
741
|
payment: 'x402 per request from the operator\'s local burner wallet — no API key, no account',
|
|
@@ -1093,6 +1121,14 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
1093
1121
|
if (isChat && response.ok && upCt.includes('application/json')) {
|
|
1094
1122
|
let data = null;
|
|
1095
1123
|
try { data = await response.clone().json(); } catch { /* not JSON after all */ }
|
|
1124
|
+
// WHAT IT REALLY COST, straight from the provider. This rides every
|
|
1125
|
+
// completion already — no extra call, and unlike the account-level
|
|
1126
|
+
// /api/v1/credits total it is attributable to THIS proxy even though the
|
|
1127
|
+
// same OpenRouter key also pays for ttfx and everything else.
|
|
1128
|
+
if (typeof data?.usage?.cost === 'number' && data.usage.cost >= 0) {
|
|
1129
|
+
sessionActual += data.usage.cost;
|
|
1130
|
+
actualCalls += 1;
|
|
1131
|
+
}
|
|
1096
1132
|
// PREPAID CALLS STILL COST MONEY. The block above only meters calls
|
|
1097
1133
|
// where THIS proxy answered a 402 and paid. When prepaid credit covers
|
|
1098
1134
|
// the quote the gateway serves 200 on the FIRST request, so there is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.45",
|
|
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",
|