openzoo 0.50.8 → 0.50.10

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/models.js CHANGED
@@ -366,9 +366,41 @@ export function augmentModelList(payload, { aliases: withAliases = true } = {})
366
366
  }
367
367
  }
368
368
 
369
+ // FAMILY SHORTCUTS — `/model grok`, `/model deepseek`, `/model gemini`.
370
+ //
371
+ // PROVEN NECESSARY on a live VM: the proxy's fuzzy /v1/models/<id> probe
372
+ // answered `grok -> x-ai/grok-4.6` with a 200, and Claude Code v2.1.246
373
+ // REFUSED THE ID ANYWAY — this client validates /model purely against the
374
+ // list it fetched at startup and never probes per-id. So the only fuzzy a
375
+ // list-validating harness can have is fuzzy that is already IN the list.
376
+ //
377
+ // One row per vendor family, resolved through the same scorer as the POST
378
+ // path, so `grok` lands on the family flagship rather than a hardcoded pick.
379
+ const FAMILY_TOKENS = ['gpt', 'claude', 'gemini', 'grok', 'deepseek', 'qwen',
380
+ 'mistral', 'llama', 'glm', 'kimi', 'minimax', 'command', 'nova', 'sonar'];
381
+ const family = [];
382
+ if (withAliases) {
383
+ const ids = data.map((m) => m.id);
384
+ const taken2 = new Set([...have, ...aliases.map((a) => a.id), ...bare.map((b) => b.id)]);
385
+ for (const tok of FAMILY_TOKENS) {
386
+ if (taken2.has(tok)) continue;
387
+ const target = data.find((m) => m.id === resolveModel(tok, ids));
388
+ if (!target) continue;
389
+ taken2.add(tok);
390
+ family.push({
391
+ id: tok,
392
+ object: 'model',
393
+ owned_by: 'openzoo-alias',
394
+ ...(target.context_length ? { context_length: target.context_length, context_window: target.context_window ?? target.context_length } : {}),
395
+ ...(target.pricing ? { pricing: target.pricing } : {}),
396
+ served_by: target.id,
397
+ });
398
+ }
399
+ }
400
+
369
401
  // Auto is no longer published: routing lives on the backend, and a shim
370
402
  // that advertises openzoo/auto would have to route it.
371
- return { ...payload, object: payload?.object || 'list', data: [...data, ...aliases, ...bare] };
403
+ return { ...payload, object: payload?.object || 'list', data: [...data, ...aliases, ...bare, ...family] };
372
404
  }
373
405
 
374
406
  /**
package/lib/proxy.js CHANGED
@@ -752,6 +752,25 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
752
752
  rememberSpend();
753
753
  say(`credit -> $${x.billedUsd.toFixed(6)} · session $${sessionSpent.toFixed(6)}`);
754
754
  };
755
+ // A 402 AFTER we attempted payment is a SETTLEMENT failure, not a quote —
756
+ // the client-side balance check is advisory, so a wallet that looks
757
+ // fundable can still fail on-chain, and the gateway answers the paid
758
+ // retry with a fresh 402. Relaying that raw meant Claude Code printed a
759
+ // half-kilobyte accepts[] blob at the user instead of the one thing they
760
+ // need: the price, what the wallet holds, and where to send funds.
761
+ if (response.status === 402) {
762
+ let quoted = '';
763
+ try {
764
+ const q = await response.clone().json();
765
+ const usd = Number(q?.accepts?.[0]?.extra?.billedUsd);
766
+ if (Number.isFinite(usd)) quoted = ` This call needs ≈$${usd.toFixed(4)}.`;
767
+ } catch { /* body was not the quote after all */ }
768
+ jsonErr(res, 402,
769
+ `openzoo wallet underfunded — payment did not settle.${quoted} `
770
+ + `Fund it and retry: send USDC (or TOKEN/LEOS for half price) to ${client.address} on Solana, `
771
+ + `or USDC to ${client.evmAddress} on Base. Check with: openzoo balance`);
772
+ return;
773
+ }
755
774
  await relay(res, response, meterStreamed);
756
775
  } catch (err) {
757
776
  if (err instanceof QuoteTooHighError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.50.8",
3
+ "version": "0.50.10",
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",