openzoo 0.43.4 → 0.43.6
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/grokui.mjs +41 -8
- package/lib/podagent.mjs +1 -1
- package/package.json +1 -1
package/lib/grokui.mjs
CHANGED
|
@@ -115,7 +115,13 @@ Via RUN you can also make YOUR OWN paid openzoo calls — POST to
|
|
|
115
115
|
http://localhost:8402/v1/chat/completions (or /v1/hrr/bind) with curl/python/etc. Auth is
|
|
116
116
|
"Authorization: Bearer sk-openzoo" — any string works, x402 pays per call, not the key. Do
|
|
117
117
|
NOT tell the user you "can't fire the paid calls" or need "their client's bearer key" —
|
|
118
|
-
that's wrong, you can make these calls yourself via RUN.
|
|
118
|
+
that's wrong, you can make these calls yourself via RUN. When you do, set max_tokens
|
|
119
|
+
generously (1000+, not 50) — a reasoning model can burn its ENTIRE budget on internal
|
|
120
|
+
reasoning before writing any visible answer, especially against a large bound corpus, and
|
|
121
|
+
comes back with content:null and finish_reason:"length" (confirmed live) if you starve it.
|
|
122
|
+
/v1/hrr/bind also caps around ~8MB per request after JSON-escaping — chunk large corpora
|
|
123
|
+
(e.g. 512KB raw per request) and pass the PREVIOUS chunk's context_id on each next request
|
|
124
|
+
to append to the same bound context, rather than one giant request that silently fails partway.
|
|
119
125
|
For normal questions just answer directly — do not use any of these unless the request
|
|
120
126
|
actually calls for delegation or file work.`;
|
|
121
127
|
|
|
@@ -230,17 +236,32 @@ function newGroupThread(names) {
|
|
|
230
236
|
// turn's brain()/brainStream() call picks up t.contextId once it lands, via
|
|
231
237
|
// the X-HRR-Context header, so retrieval is real and automatic, not a prompt
|
|
232
238
|
// claim about a mechanism that doesn't exist.
|
|
239
|
+
// Chunked, not one shot: a single request over ~8MB (post JSON-escaping)
|
|
240
|
+
// gets rejected, so a large/growing thread's bind would silently fail past
|
|
241
|
+
// whatever point it crossed that line — confirmed live by a bot's own RUN
|
|
242
|
+
// diagnostic ("Failed at chunk 2 — JSON escaping pushed a 3MB chunk over the
|
|
243
|
+
// ~8MB request limit"). 512KB raw per request leaves wide margin. Each
|
|
244
|
+
// chunk after the first carries the PREVIOUS chunk's context_id so the
|
|
245
|
+
// sidecar appends to the same bound context instead of starting fresh.
|
|
246
|
+
const BIND_CHUNK_BYTES = 512 * 1024;
|
|
233
247
|
async function bindThread(t) {
|
|
234
248
|
const corpus = t.history.map((h) => (h.who === 'user' ? 'you' : (h.name || t.name)) + ': ' + h.text).join('\n');
|
|
235
249
|
if (!corpus.trim()) return;
|
|
236
250
|
try {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
body:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
251
|
+
let ctx;
|
|
252
|
+
for (let i = 0; i < corpus.length; i += BIND_CHUNK_BYTES) {
|
|
253
|
+
const part = corpus.slice(i, i + BIND_CHUNK_BYTES);
|
|
254
|
+
const body = ctx ? { corpus: part, context_id: ctx } : { corpus: part };
|
|
255
|
+
const r = await fetch(`${PROXY}/hrr/bind`, {
|
|
256
|
+
method: 'POST',
|
|
257
|
+
headers: { 'content-type': 'application/json' },
|
|
258
|
+
body: JSON.stringify(body),
|
|
259
|
+
});
|
|
260
|
+
const j = await r.json().catch(() => ({}));
|
|
261
|
+
if (j?.context_id) ctx = j.context_id;
|
|
262
|
+
else break; // this chunk failed — stop, keep whatever bound so far rather than lose it all
|
|
263
|
+
}
|
|
264
|
+
if (ctx) { t.contextId = ctx; saveThreads(); }
|
|
244
265
|
} catch { /* leCore sidecar unreachable — thread still works, just not bound this round */ }
|
|
245
266
|
}
|
|
246
267
|
|
|
@@ -639,6 +660,7 @@ const APP_HTML = `<!doctype html>
|
|
|
639
660
|
<div class="hrow"><span>our cost (cogs)</span><span id="hYouCogs">—</span></div>
|
|
640
661
|
<div class="hrow"><span>margin</span><span id="hYouMargin" class="hlime">—</span></div>
|
|
641
662
|
<div class="hrow"><span>direct would be</span><span id="hYouDirect" class="hember">—</span></div>
|
|
663
|
+
<div class="hrow"><span>saved vs. naked calls</span><span id="hYouSaved" class="hlime">—</span></div>
|
|
642
664
|
<div class="hfoot" id="hFoot">loading…</div>
|
|
643
665
|
</div>
|
|
644
666
|
<div id="log"></div>
|
|
@@ -1034,6 +1056,17 @@ const APP_HTML = `<!doctype html>
|
|
|
1034
1056
|
document.getElementById('hYouCogs').textContent = usd(cogs);
|
|
1035
1057
|
document.getElementById('hYouMargin').textContent = margin;
|
|
1036
1058
|
document.getElementById('hYouDirect').textContent = usd(direct);
|
|
1059
|
+
const savedEl = document.getElementById('hYouSaved');
|
|
1060
|
+
if (spent > 0) {
|
|
1061
|
+
const mult = direct / spent;
|
|
1062
|
+
// honest either way: >=1x is a real saving vs a naked direct call,
|
|
1063
|
+
// <1x means you're currently paying MORE than direct would cost —
|
|
1064
|
+
// don't dress that up as green when it isn't one
|
|
1065
|
+
savedEl.textContent = mult.toFixed(2) + 'x';
|
|
1066
|
+
savedEl.className = mult >= 1 ? 'hlime' : 'hember';
|
|
1067
|
+
} else {
|
|
1068
|
+
savedEl.textContent = '—';
|
|
1069
|
+
}
|
|
1037
1070
|
document.getElementById('hFoot').textContent = (you.paidCalls || 0) + ' paid calls this session';
|
|
1038
1071
|
} catch (e) {
|
|
1039
1072
|
document.getElementById('hFoot').textContent = 'error: ' + e.message;
|
package/lib/podagent.mjs
CHANGED
|
@@ -192,7 +192,7 @@ function hasImages(messages) {
|
|
|
192
192
|
// grokui.mjs then renders as a generic "(no response)" — indistinguishable
|
|
193
193
|
// from a model that genuinely had nothing to say. Callers should know WHY.
|
|
194
194
|
function httpErrorNote(status) {
|
|
195
|
-
if (status === 402) return '(payment failed — the wallet\'s x402 retry gave up after HTTP 402.
|
|
195
|
+
if (status === 402) return '(payment failed — the wallet\'s x402 retry gave up after HTTP 402, likely out of funds. Open http://localhost:8402 for this wallet\'s funding addresses (Solana USDC/TOKEN, Base USDC, Robinhood Chain) and current balance, or run `npx openzoo` in a terminal to see the same info. Try again once it\'s funded.)';
|
|
196
196
|
if (status === 429) return '(rate limited — HTTP 429, try again in a moment)';
|
|
197
197
|
if (status >= 500) return `(upstream error — HTTP ${status}, try again)`;
|
|
198
198
|
return status ? `(request failed — HTTP ${status})` : '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.6",
|
|
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",
|