openzoo 0.51.24 → 0.51.28
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/proxy.js +30 -0
- package/package.json +1 -1
package/lib/proxy.js
CHANGED
|
@@ -998,6 +998,36 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
998
998
|
result = await client.fetch(url, init);
|
|
999
999
|
}
|
|
1000
1000
|
}
|
|
1001
|
+
// A 5xx IS NOT A REASON TO CHANGE THE MODEL. An earlier build routed any
|
|
1002
|
+
// gateway 5xx to OPENZOO_OUTAGE_FALLBACK and gated the model 60s. That
|
|
1003
|
+
// was wrong twice over: `/model fable-5.1` then reported `x402 door for
|
|
1004
|
+
// grok-4.6 failed`, so the caller read an error for a model they never
|
|
1005
|
+
// picked, and a silent substitution bills them for a DIFFERENT model's
|
|
1006
|
+
// answer than the one they chose and are reading. When the requested
|
|
1007
|
+
// model's door is down, say so about THAT model and let the caller
|
|
1008
|
+
// decide. Only the 402 "insufficient credits" branch above still
|
|
1009
|
+
// reroutes, because there the gateway itself refunds and the request
|
|
1010
|
+
// was never served at all.
|
|
1011
|
+
const RETRYABLE_5XX = new Set([500, 502, 503, 504]);
|
|
1012
|
+
if (RETRYABLE_5XX.has(result.response?.status)) {
|
|
1013
|
+
let detail = '';
|
|
1014
|
+
try { const j = await result.response.clone().json(); detail = String(j?.error?.message || j?.error || '').slice(0, 300); } catch { /* opaque 5xx */ }
|
|
1015
|
+
log(`upstream ${result.response.status} for ${outageKey(init)}${detail ? `: ${detail}` : ''} — surfacing as-is, model NOT swapped`);
|
|
1016
|
+
// "no door quoted <model>: … wrong asset/rail (base)" is a DOOR-SIDE
|
|
1017
|
+
// quote failure, and measurement says it is TRANSIENT — not an empty
|
|
1018
|
+
// wallet and not a dead model. 2026-09-13, five minutes apart on the
|
|
1019
|
+
// same funded wallet: grok-4.6, deepseek-v4-flash and claude-fable-5-1
|
|
1020
|
+
// all 502'd at 264.68 USDC, then all returned 200 at 259.00 USDC. The
|
|
1021
|
+
// balance went DOWN across the recovery, so funding was never the
|
|
1022
|
+
// variable. Do NOT print fund-me copy here — that sends a caller with
|
|
1023
|
+
// $260 to a top-up page. Just name the model they asked for and say
|
|
1024
|
+
// the door failed to quote, so a retry is the obvious next move.
|
|
1025
|
+
if (/no door quoted|wrong asset\/rail/i.test(detail)) {
|
|
1026
|
+
const msg = `${outageKey(init)}: the x402 door failed to quote this model, so the request never reached it and nothing was charged. This is usually transient — retry in a minute. Gateway said: ${detail}`;
|
|
1027
|
+
jsonErr(res, 503, msg);
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1001
1031
|
// A PAID 400 `invalid_tools` on a Responses body we did not flatten:
|
|
1002
1032
|
// this model is a function-tools-only door we had not learned yet.
|
|
1003
1033
|
// Flatten, remember it, and buy the turn once more — one billed miss
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.51.
|
|
3
|
+
"version": "0.51.28",
|
|
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",
|