openzoo 0.38.6 → 0.38.8

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.
@@ -299,7 +299,10 @@ async function passthroughToRealAnthropic(req, res, body, host, full, log) {
299
299
  r.on('error', reject);
300
300
  });
301
301
  up.on('error', reject);
302
- up.setTimeout(20000, () => up.destroy(new Error('upstream timeout')));
302
+ // WatchSandBoxMigration is a LONG POLL — a 20s cap aborts it every time and
303
+ // the app never learns its sandbox is ready. Streams get no deadline.
304
+ const streaming = /Watch|Stream|Subscribe/i.test(full);
305
+ if (!streaming) up.setTimeout(20000, () => up.destroy(new Error('upstream timeout')));
303
306
  if (req.method !== 'GET' && req.method !== 'HEAD' && body && body.length) up.write(body);
304
307
  up.end();
305
308
  });
@@ -311,6 +314,17 @@ async function passthroughToRealAnthropic(req, res, body, host, full, log) {
311
314
  }
312
315
  res.writeHead(status, h);
313
316
  res.end(buf);
317
+ // DUMP THE INTERESTING ONES. EnsureSandBox's response is what names the
318
+ // sandbox, and the sandbox is the candidate inference path — you cannot
319
+ // read that from a byte count. Written raw for offline decoding.
320
+ if (process.env.OPENZOO_DUMP === '1' && buf.length) {
321
+ try {
322
+ const dir = '/tmp/openzoo-sniff';
323
+ fs.mkdirSync(dir, { recursive: true });
324
+ const safe = full.replace(/[^a-zA-Z0-9]+/g, '_').slice(0, 80);
325
+ fs.writeFileSync(`${dir}/${Date.now()}_${safe}.bin`, buf);
326
+ } catch { /* dumping must never break the proxy */ }
327
+ }
314
328
  log(`cursor-backend: ${req.method} ${full} -> REAL anthropic (${status}, ${buf.length}b)`);
315
329
  } catch (e) {
316
330
  res.writeHead(502, { 'content-type': 'application/json' });
@@ -461,6 +475,22 @@ export function startCursorBackend({ port = 8443, models, log = () => {} } = {})
461
475
  await handleStreamChat(req, res, body, log);
462
476
  return;
463
477
  }
478
+ // FULL PASSTHROUGH MODE — observe, do not stub.
479
+ //
480
+ // Stubbing unknown methods with empty protobufs BREAKS Grok Bot: it never
481
+ // gets a sandbox from GrokBotService/EnsureSandBox, so it re-polls
482
+ // WatchSandBoxMigration forever and never reaches the chat stage. That is
483
+ // why an intercepted run showed 40 methods and ZERO StreamChat — absence
484
+ // of evidence created by our own stub, not proof that chat lives
485
+ // elsewhere.
486
+ //
487
+ // In passthrough the app runs NORMALLY against the real backend while
488
+ // every method, size and status is logged here — which is what actually
489
+ // reveals where inference goes.
490
+ if (process.env.OPENZOO_PASSTHRU === '1') {
491
+ await passthroughToRealAnthropic(req, res, body, host, full, log);
492
+ return;
493
+ }
464
494
  try {
465
495
  respond(req, res, method, models);
466
496
  const populated = ['GetPlanInfo', 'GetMe', 'GetDefaultModel', 'IsOnNewPricing'];
package/lib/grokbot.js CHANGED
@@ -169,9 +169,17 @@ export async function setupGrokBot(argv = []) {
169
169
  const { startCursorBackend } = await import('./cursorbackend.js');
170
170
  const port = 443; // Node's DNS gives no port control — we must own :443
171
171
 
172
- process.env.OPENZOO_BYOK = '1';
172
+ // --sniff: intercept but PASS EVERYTHING THROUGH to the real backend, so
173
+ // the app works normally and every method/size/status is logged. This is
174
+ // the only way to see the chat path: stubbing breaks EnsureSandBox and the
175
+ // app never reaches inference at all.
176
+ if (argv.includes('--sniff')) { process.env.OPENZOO_PASSTHRU = '1'; process.env.OPENZOO_DUMP = '1'; }
177
+ else process.env.OPENZOO_BYOK = '1';
173
178
  process.env.OPENZOO_FORCE_BLOCK = '1'; // our own guard refuses otherwise
174
- console.error('openzoo: TAKEOVER — pinning api2.cursor.sh and serving it locally.');
179
+ console.error(argv.includes('--sniff')
180
+ ? 'openzoo: SNIFF — pinning api2.cursor.sh, proxying it to the REAL backend, logging everything.'
181
+ : 'openzoo: TAKEOVER — pinning api2.cursor.sh and serving it locally.');
182
+ if (argv.includes('--sniff')) console.error(' response bodies -> /tmp/openzoo-sniff/');
175
183
  console.error(' sudo will ask for your password (hosts file + :443).');
176
184
  if (!isBlocked()) blockBackend();
177
185
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.38.6",
3
+ "version": "0.38.8",
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",