openzoo 0.50.70 → 0.50.71

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 +16 -11
  2. package/package.json +1 -1
package/lib/proxy.js CHANGED
@@ -309,8 +309,10 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
309
309
  // (OpenRouter) was out of credits. Paying again buys nothing, and the
310
310
  // "wallet underfunded" copy blamed the user's burner. When the paid 402 says
311
311
  // upstream credits, stop paying for a minute and say what is actually wrong.
312
- let upstreamOutageUntil = 0;
313
- let upstreamOutageMsg = '';
312
+ // Keyed by model: an OpenRouter outage must not gate a door-only id like
313
+ // bare grok-4.6 that never touches OpenRouter.
314
+ const upstreamOutage_ = new Map(); // model -> { until, msg }
315
+ const outageKey = (init) => { try { return String(JSON.parse(String(init?.body || '{}')).model || ''); } catch { return ''; } };
314
316
  const upstreamOutage = (body) => {
315
317
  const m = String(body?.error?.message || body?.message || '');
316
318
  const src = String(body?.error?.metadata?.limit_source || '');
@@ -696,10 +698,13 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
696
698
  }
697
699
 
698
700
  try {
699
- if (Date.now() < upstreamOutageUntil) {
700
- log('upstream outage: not paying (gate)');
701
- jsonErr(res, 503, upstreamOutageMsg);
702
- return;
701
+ {
702
+ const gate = upstreamOutage_.get(outageKey(init));
703
+ if (gate && Date.now() < gate.until) {
704
+ log(`upstream outage: not paying (gate) model=${outageKey(init)}`);
705
+ jsonErr(res, 503, gate.msg);
706
+ return;
707
+ }
703
708
  }
704
709
  const result = await client.fetch(url, init);
705
710
  const { response, paid, receipt, accept } = result;
@@ -808,13 +813,13 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
808
813
  if (paid && upstreamOutage(q402)) {
809
814
  const settle = q402?.x402?.settle;
810
815
  const tx = settle?.transaction || result.receipt?.tx || '';
811
- upstreamOutageMsg = 'openzoo gateway upstream is out of credits (OpenRouter: "Insufficient credits"). '
816
+ const msg = 'openzoo gateway upstream is out of credits (OpenRouter: "Insufficient credits"). '
812
817
  + `Your payment settled${tx ? ` (tx ${tx})` : ''} — this is NOT your wallet. `
813
818
  + 'The gateway operator must top up OpenRouter or route this model to another upstream. '
814
- + 'Pausing paid retries for 60s.';
815
- upstreamOutageUntil = Date.now() + 60_000;
816
- log(`upstream outage: ${upstreamOutageMsg.slice(0, 120)}`);
817
- jsonErr(res, 503, upstreamOutageMsg);
819
+ + `Pausing paid retries for ${outageKey(init) || 'this model'} for 60s.`;
820
+ upstreamOutage_.set(outageKey(init), { until: Date.now() + 60_000, msg });
821
+ log(`upstream outage: model=${outageKey(init)} ${msg.slice(0, 100)}`);
822
+ jsonErr(res, 503, msg);
818
823
  return;
819
824
  }
820
825
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.50.70",
3
+ "version": "0.50.71",
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",