openzoo 0.48.16 → 0.48.18

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/grokui.mjs +22 -5
  2. package/package.json +1 -1
package/lib/grokui.mjs CHANGED
@@ -359,7 +359,16 @@ function newGroupThread(names) {
359
359
  // sidecar appends to the same bound context instead of starting fresh.
360
360
  const BIND_CHUNK_BYTES = 512 * 1024;
361
361
  // Chained auto-run commands per user message. Each hop is a paid call.
362
- const AUTO_MAX_STEPS = Number(process.env.OZ_AUTO_MAX_STEPS || 8);
362
+ // 8 was far too tight. A real task — install a toolchain, read a tree, wire a
363
+ // service — is dozens of directives, so auto kept halting mid-job and telling
364
+ // the user to type "continue", which is the exact thing auto exists to avoid.
365
+ // Still bounded, because every hop is a paid call, but bounded at a number
366
+ // that lets a job finish.
367
+ const AUTO_MAX_STEPS = Number(process.env.OZ_AUTO_MAX_STEPS || 60);
368
+ // An empty completion is a provider hiccup, not an answer. In auto we retry it
369
+ // silently rather than parking the thread behind a "say continue" note the
370
+ // user then has to answer — that turned a transient blip into a manual step.
371
+ const AUTO_EMPTY_RETRIES = Number(process.env.OZ_AUTO_EMPTY_RETRIES || 3);
363
372
  // Ceiling on subagents per thread. Spawning is fire-and-forget and each child
364
373
  // can spawn too, so without a count it is unbounded — MEASURED as 15+ threads
365
374
  // all named tetris-contract, every one of them a live agent making paid calls.
@@ -1308,8 +1317,16 @@ async function runTurn(threadId, userText, onEvent, images) {
1308
1317
  // user a turn and told them nothing. Retry once before giving up, and if
1309
1318
  // it is still empty, say what actually happened instead of "(no
1310
1319
  // response)", which reads like the harness broke.
1311
- if (!reply) reply = await ask();
1312
- if (!reply) reply = '(the model returned an empty completion — usually a transient provider hiccup or a stop-sequence firing early. Say "continue" to retry.)';
1320
+ // Retry in place rather than parking the thread behind a note the user has
1321
+ // to answer. In auto especially: a transient blip must not become a manual
1322
+ // step, which is the whole point of auto.
1323
+ for (let i = 0; !reply && i < AUTO_EMPTY_RETRIES; i++) {
1324
+ await new Promise((r) => setTimeout(r, 400 * (i + 1)));
1325
+ reply = await ask();
1326
+ }
1327
+ if (!reply) {
1328
+ reply = `(the model returned nothing ${AUTO_EMPTY_RETRIES + 1} times — that is a provider problem, not your input. Try /model to switch, or send anything to retry.)`;
1329
+ }
1313
1330
  } catch (e) {
1314
1331
  reply = `error: ${e.message}`;
1315
1332
  }
@@ -1343,7 +1360,7 @@ async function runTurn(threadId, userText, onEvent, images) {
1343
1360
  bindThread(t).catch(() => {});
1344
1361
  runTurn(threadId, condense('(command output)', output), onEvent).catch(() => {});
1345
1362
  } else {
1346
- const note = `(auto-run stopped after ${AUTO_MAX_STEPS} chained commands — say "continue" to keep going)`;
1363
+ const note = `(auto-run paused after ${AUTO_MAX_STEPS} chained commands — that is the spend ceiling, not the end of the job. Send anything to carry on, or raise OZ_AUTO_MAX_STEPS.)`;
1347
1364
  t.history.push({ who: 'bot', text: note });
1348
1365
  onEvent?.({ type: 'final', name: t.name, color: t.color, text: note });
1349
1366
  saveThreads();
@@ -1388,7 +1405,7 @@ async function runTurn(threadId, userText, onEvent, images) {
1388
1405
  runTurn(threadId, condense('(directive result)', ack), onEvent).catch(() => {});
1389
1406
  return;
1390
1407
  }
1391
- const note = `(auto stopped after ${AUTO_MAX_STEPS} steps — say "continue" to keep going)`;
1408
+ const note = `(auto paused after ${AUTO_MAX_STEPS} steps — that is the spend ceiling, not the end of the job. Send anything to carry on, or raise OZ_AUTO_MAX_STEPS.)`;
1392
1409
  t.history.push({ who: 'bot', text: note });
1393
1410
  onEvent?.({ type: 'final', name: t.name, color: t.color, text: note });
1394
1411
  saveThreads();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.48.16",
3
+ "version": "0.48.18",
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",