openzoo 0.48.2 → 0.48.3

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 -2
  2. package/package.json +1 -1
package/lib/grokui.mjs CHANGED
@@ -378,8 +378,16 @@ function parseRun(reply) {
378
378
  // use U+FF5C FULLWIDTH VERTICAL LINE (|) — matching only `|` parsed the
379
379
  // pretty-printed form in tests while missing what the model actually emits,
380
380
  // which is exactly how this survived one round of "fixed".
381
+ // The PARAMETER NAME is not fixed either. Models emit name="command",
382
+ // name="cmd", name="shell_command" and name="script" for the same thing —
383
+ // MEASURED live emitting `name="cmd"` inside an invoke named exec_command,
384
+ // against a parser that demanded name="command". One attribute apart, and
385
+ // the whole envelope was dropped in silence: the bot then explained what it
386
+ // was "about to run" forever, never running anything. Match the shape of the
387
+ // envelope, not one vendor's spelling of it.
381
388
  const SEP = '[||\\s]*';
382
- const dsml = new RegExp(`<${SEP}DSML[^>]*\\bparameter\\b[^>]*name="command"[^>]*>([\\s\\S]*?)<\\/${SEP}DSML`, 'i').exec(reply);
389
+ const NAME = '(?:command|cmd|shell_command|script)';
390
+ const dsml = new RegExp(`<${SEP}DSML[^>]*\\bparameter\\b[^>]*\\bname="${NAME}"[^>]*>([\\s\\S]*?)<\\/${SEP}DSML`, 'i').exec(reply);
383
391
  if (dsml) return sanitizeRunCommand(dsml[1]);
384
392
 
385
393
  const m = /^[ \t>*-]*RUN:[ \t]*([\s\S]+)/m.exec(reply);
@@ -391,9 +399,21 @@ function parseRun(reply) {
391
399
  return sanitizeRunCommand(cmd);
392
400
  }
393
401
 
402
+ // RUN through BASH, not /bin/sh. node's exec() defaults to /bin/sh, which on
403
+ // Debian is dash — so every bash-ism a model writes (`for … do`, `[[ ]]`,
404
+ // arrays, process substitution) dies as
405
+ // /bin/sh: 40: Syntax error: "do" unexpected
406
+ // which reads as the model writing bad code when it wrote perfectly good bash.
407
+ // Models overwhelmingly emit bash; give them bash. Windows is left alone so
408
+ // node picks cmd.exe, and a box without /bin/bash falls back to the default.
409
+ const RUN_SHELL = process.platform !== 'win32' && existsSync('/bin/bash') ? '/bin/bash' : undefined;
410
+ // Installing a toolchain (apt-get, pip, cargo) routinely outruns two minutes,
411
+ // and a killed install leaves a half-configured box that fails confusingly.
412
+ const RUN_TIMEOUT_MS = Number(process.env.OZ_RUN_TIMEOUT_MS || 600000);
413
+
394
414
  function execCommand(command, cwd) {
395
415
  return new Promise((resolve) => {
396
- exec(command, { cwd, timeout: 120000, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
416
+ exec(command, { cwd, shell: RUN_SHELL, timeout: RUN_TIMEOUT_MS, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
397
417
  let out = (stdout || '') + (stderr ? '\n' + stderr : '');
398
418
  if (err) out += `\n(exit ${err.code ?? 1})`;
399
419
  resolve(out.slice(0, 6000) || '(no output)');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.48.2",
3
+ "version": "0.48.3",
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",