openzoo 0.51.24 → 0.51.25

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 (2) hide show
  1. package/lib/proxy.js +22 -0
  2. package/package.json +1 -1
package/lib/proxy.js CHANGED
@@ -998,6 +998,28 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
998
998
  result = await client.fetch(url, init);
999
999
  }
1000
1000
  }
1001
+ // A 5xx from the gateway: its upstream errored on a retired/renamed door
1002
+ // — e.g. gpt-6-astra maps to an upstream id the provider 404s
1003
+ // (`unknown model openai-gpt-6-astra`). It comes back BOTH ways: an
1004
+ // UNPAID 500 (the id cannot be priced, so no x402 quote is even reached)
1005
+ // and a PAID 502 (settled, then the upstream call failed). Left raw,
1006
+ // either makes the harness storm retries ("Reconnecting 5/5"). Route
1007
+ // once to the x402 door and gate the model 60s, same as the credits
1008
+ // outage above. 501/505 excluded — shape/protocol errors a different
1009
+ // model would hit too.
1010
+ const RETRYABLE_5XX = new Set([500, 502, 503, 504]);
1011
+ if (!usedFallback && FALLBACK_MODEL && outageKey(init) !== FALLBACK_MODEL
1012
+ && RETRYABLE_5XX.has(result.response?.status)) {
1013
+ const st = result.response.status;
1014
+ let detail = '';
1015
+ try { const j = await result.response.clone().json(); detail = String(j?.error?.message || j?.error || '').slice(0, 120); } catch { /* opaque 5xx */ }
1016
+ const msg = `openzoo gateway upstream errored (HTTP ${st}${detail ? `: ${detail}` : ''}) for ${outageKey(init)}. Routing to ${FALLBACK_MODEL} (x402 door) for 60s.`;
1017
+ upstreamOutage_.set(outageKey(init), { until: Date.now() + 60_000, msg });
1018
+ log(`upstream ${st}: ${outageKey(init)} -> ${FALLBACK_MODEL}${detail ? ` (${detail})` : ''}`);
1019
+ init = withModel(init, FALLBACK_MODEL);
1020
+ usedFallback = true;
1021
+ result = await client.fetch(url, init);
1022
+ }
1001
1023
  // A PAID 400 `invalid_tools` on a Responses body we did not flatten:
1002
1024
  // this model is a function-tools-only door we had not learned yet.
1003
1025
  // 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.24",
3
+ "version": "0.51.25",
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",