openzoo 0.50.28 → 0.50.30

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.
@@ -1136,6 +1136,48 @@ function gatewayEntry(e) {
1136
1136
  const { seq, pulledRemote, ...rest } = e;
1137
1137
  return rest;
1138
1138
  }
1139
+
1140
+ function stripSpendFooter(s) {
1141
+ return String(s || '').replace(/\n{2,}this call \$[\d.]+[\s\S]*$/i, '').trimEnd();
1142
+ }
1143
+
1144
+ /** Prior turns for zooComplete. sendPrompt used to POST only the latest user
1145
+ * line, so the model said each thread starts blank while the UI still showed
1146
+ * the canvas. Skip the last user echo of `currentPrompt` (already appended). */
1147
+ function historyMessages(agentId, currentPrompt) {
1148
+ const entries = agentTranscript(agentId).entries || [];
1149
+ const cur = String(currentPrompt || '').trim();
1150
+ const out = [];
1151
+ for (const e of entries) {
1152
+ if (!e || typeof e !== 'object') continue;
1153
+ let role = null;
1154
+ let text = '';
1155
+ if (e.kind === 'send-message' || e.role === 'assistant') {
1156
+ const m = e.message;
1157
+ text = typeof m === 'string' ? m : String(m?.content || m?.text || '');
1158
+ role = 'assistant';
1159
+ text = stripSpendFooter(text);
1160
+ } else if (e.kind === 'message' || e.role === 'user') {
1161
+ text = String(e.content || e.message?.content || e.message?.text || '');
1162
+ role = 'user';
1163
+ }
1164
+ text = String(text || '').trim();
1165
+ if (!role || !text) continue;
1166
+ out.push({ role, content: text });
1167
+ }
1168
+ while (out.length && out[out.length - 1].role === 'user' && String(out[out.length - 1].content).trim() === cur) {
1169
+ out.pop();
1170
+ }
1171
+ let chars = 0;
1172
+ const kept = [];
1173
+ for (let i = out.length - 1; i >= 0; i--) {
1174
+ chars += String(out[i].content).length;
1175
+ if (chars > 80_000 && kept.length) break;
1176
+ kept.push(out[i]);
1177
+ }
1178
+ kept.reverse();
1179
+ return kept;
1180
+ }
1139
1181
  async function podJson(path0, bodyObj, log) {
1140
1182
  if (!realPod?.agent) return null;
1141
1183
  let agent;
@@ -1520,9 +1562,11 @@ async function zooComplete(prompt, log, agentId, parsed = {}) {
1520
1562
  'Never claim you lack filesystem access or local-exec. If a tool errors, report the error.',
1521
1563
  'After using tools you MUST still write a normal chat reply: what you did, file paths written, and what to open. Empty content is a bug.',
1522
1564
  'A spend footer is appended after your reply by the host — ignore it.',
1565
+ 'Prior turns of THIS Grok Bot chat are in the messages below. Do not claim the thread starts blank or that earlier questions did not arrive.',
1523
1566
  ].join(' '),
1524
1567
  },
1525
1568
  ];
1569
+ for (const m of historyMessages(agentId, prompt)) messages.push(m);
1526
1570
  if (textFiles.length) {
1527
1571
  const bits = textFiles.map((a) => (
1528
1572
  a.error
package/lib/grokcli.js CHANGED
@@ -177,7 +177,9 @@ export async function runBot(argv = []) {
177
177
  console.error(' EnsureSandBox HIJACKED here; StreamUnifiedChat -> :8402 (x402)');
178
178
  }
179
179
 
180
- if (!argv.includes('--no-quit') && process.env.OZ_NO_QUIT !== '1') {
180
+ // Default: do not quit Grok Bot. Restarting the hijack used to osascript-quit
181
+ // the app and drop the session; pass --quit to get the old bounce.
182
+ if (argv.includes('--quit') || process.env.OZ_NO_QUIT === '0') {
181
183
  try { execSync('osascript -e \'tell application "Grok Bot" to quit\'', { stdio: 'ignore' }); } catch { /* ok */ }
182
184
  await new Promise((r) => setTimeout(r, 1500));
183
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.50.28",
3
+ "version": "0.50.30",
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",