openzoo 0.43.3 → 0.43.4

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/podagent.mjs +14 -2
  2. package/package.json +1 -1
package/lib/podagent.mjs CHANGED
@@ -188,6 +188,16 @@ function hasImages(messages) {
188
188
  return messages.some((m) => Array.isArray(m.content) && m.content.some((c) => c?.type === 'image_url'));
189
189
  }
190
190
 
191
+ // A non-ok response with no usable content used to silently become '', which
192
+ // grokui.mjs then renders as a generic "(no response)" — indistinguishable
193
+ // from a model that genuinely had nothing to say. Callers should know WHY.
194
+ function httpErrorNote(status) {
195
+ if (status === 402) return '(payment failed — the wallet\'s x402 retry gave up after HTTP 402. Try again; if it keeps happening, check the wallet balance/RPC.)';
196
+ if (status === 429) return '(rate limited — HTTP 429, try again in a moment)';
197
+ if (status >= 500) return `(upstream error — HTTP ${status}, try again)`;
198
+ return status ? `(request failed — HTTP ${status})` : '';
199
+ }
200
+
191
201
  /** One openzoo chat turn. Paid per call by the box's own wallet via the local
192
202
  * proxy — no key, no account. */
193
203
  export async function brain(messages, contextId) {
@@ -208,7 +218,8 @@ export async function brain(messages, contextId) {
208
218
  body: JSON.stringify({ model: hasImages(messages) ? VISION_MODEL : MODEL, max_tokens: 4096, messages, plugins: [{ id: 'web' }] }),
209
219
  });
210
220
  const j = await r.json().catch(() => ({}));
211
- return j?.choices?.[0]?.message?.content ?? '';
221
+ const content = j?.choices?.[0]?.message?.content;
222
+ return content || (r.ok ? '' : httpErrorNote(r.status));
212
223
  }
213
224
 
214
225
  /** Same call, but streamed — invokes onDelta(text) as tokens arrive (for a
@@ -225,7 +236,8 @@ export async function brainStream(messages, onDelta, contextId) {
225
236
  });
226
237
  if (!r.ok || !r.body) {
227
238
  // fall back to the non-streaming path rather than fail outright
228
- const text = await r.json().then((j) => j?.choices?.[0]?.message?.content ?? '').catch(() => '');
239
+ const content = await r.json().then((j) => j?.choices?.[0]?.message?.content).catch(() => undefined);
240
+ const text = content || (r.ok ? '' : httpErrorNote(r.status));
229
241
  if (text) onDelta(text);
230
242
  return text;
231
243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.43.3",
3
+ "version": "0.43.4",
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",