zames_pro 2.10.1 → 2.10.2

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/dist/agent-loop.js +32 -11
  2. package/package.json +1 -1
@@ -3,6 +3,27 @@ import { getGitContext, formatGitContext } from './gitTools.js';
3
3
  import { parseXmlToolCalls } from './xml-toolcall.js';
4
4
  import { translate } from './i18n.js';
5
5
  export async function runAgentLoop({ browser, tools, task, workdir, maxIterations = 40, freshChat = false, sendSystemPrompt = false, transcript = null, attachments = [], onThinking = () => { }, onAssistantThought = () => { }, onToolCall = () => { }, onToolResult = () => { }, onAssistantMessage = () => { }, onChatReady = () => { }, onWarning = () => { }, debugLog = false, locale = 'ru', }) {
6
+ // UI callbacks must NEVER break the agent loop. A rendering error (a huge
7
+ // tool result, a broken markdown frame, a closed terminal) used to throw
8
+ // out of the loop right after a tool call — the session looked "stopped
9
+ // after a tool call", with a tool_call but no tool_result in the log. We
10
+ // wrap every callback so a UI failure is swallowed and the loop continues.
11
+ const safe = (fn) => {
12
+ return (...a) => {
13
+ try {
14
+ fn(...a);
15
+ }
16
+ catch {
17
+ // Intentionally ignored: the loop must survive UI failures.
18
+ }
19
+ };
20
+ };
21
+ const safeThinking = safe(onThinking);
22
+ const safeAssistantThought = safe(onAssistantThought);
23
+ const safeToolCall = safe(onToolCall);
24
+ const safeToolResult = safe(onToolResult);
25
+ const safeAssistantMessage = safe(onAssistantMessage);
26
+ const safeWarning = safe(onWarning);
6
27
  if (freshChat) {
7
28
  await browser.newChat();
8
29
  transcript?.log('new_chat');
@@ -42,7 +63,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
42
63
  length: systemPrompt.length,
43
64
  gitContext: gitText,
44
65
  });
45
- onThinking();
66
+ safeThinking();
46
67
  // system-prompt is an agent send: throttled (agent: true).
47
68
  await browser.ask(systemPrompt, { timeout: 60_000, agent: true });
48
69
  await reportChat();
@@ -104,7 +125,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
104
125
  let afterToolRetries = 0;
105
126
  const MAX_AFTER_TOOL_RETRIES = 6;
106
127
  for (let i = 0; i < maxIterations; i++) {
107
- onThinking();
128
+ safeThinking();
108
129
  // The first message (task) is user input: no throttle.
109
130
  // Subsequent ones (tool-result and resend requests) are agent sends:
110
131
  // throttled so we don't hit the rate limit.
@@ -139,7 +160,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
139
160
  attempt: afterToolRetries,
140
161
  error: e.message,
141
162
  });
142
- onWarning('browser.ask() не вернул ответ за ' +
163
+ safeWarning('browser.ask() не вернул ответ за ' +
143
164
  Math.round(askDeadlineMs / 1000) +
144
165
  'с — повторяю запрос.');
145
166
  if (afterToolRetries < MAX_AFTER_TOOL_RETRIES) {
@@ -150,7 +171,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
150
171
  transcript?.log('ask_timeout_exhausted', {
151
172
  message: 'ask() не вернул ответ и лимит повторов исчерпан',
152
173
  });
153
- onWarning('browser.ask() перестал отвечать; лимит повторов исчерпан, ' +
174
+ safeWarning('browser.ask() перестал отвечать; лимит повторов исчерпан, ' +
154
175
  'останавливаюсь. Ответа модели нет — проверьте чат DeepSeek вручную.');
155
176
  return 'ask() watchdog: ответ модели не получен';
156
177
  }
@@ -205,7 +226,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
205
226
  if (parsed) {
206
227
  const thought = extractPreToolText(rawResponse);
207
228
  if (thought)
208
- onAssistantThought(thought);
229
+ safeAssistantThought(thought);
209
230
  }
210
231
  const parsedCalls = Array.isArray(parsed) ? parsed : parsed ? [parsed] : [];
211
232
  if (parsedCalls.some((p) => p && p._permissive)) {
@@ -341,7 +362,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
341
362
  // not be turned into a tool call even after all retries: warn the
342
363
  // operator instead of silently printing e.g. "Stale. Let me verify".
343
364
  transcript?.log('suspicious_final', { response: rawResponse });
344
- onWarning(translate(locale)('msg.suspicious_stop'));
365
+ safeWarning(translate(locale)('msg.suspicious_stop'));
345
366
  }
346
367
  // A meaningful plain-text answer (e.g. a final report the model forgot to
347
368
  // wrap in respond) is surfaced as-is WITHOUT a warning: after the bounded
@@ -393,11 +414,11 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
393
414
  // the task normally.
394
415
  if (!isMeaningfulRespond(msg)) {
395
416
  transcript?.log('empty_respond_exhausted', { response: rawResponse });
396
- onWarning('Модель вызвала respond без текста, и лимит повторов исчерпан. ' +
417
+ safeWarning('Модель вызвала respond без текста, и лимит повторов исчерпан. ' +
397
418
  'Проверьте чат DeepSeek вручную.');
398
419
  return 'Модель не сформировала итоговое сообщение (пустой respond).';
399
420
  }
400
- onAssistantMessage(msg);
421
+ safeAssistantMessage(msg);
401
422
  transcript?.log('assistant_final', { message: msg });
402
423
  return msg;
403
424
  }
@@ -410,12 +431,12 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
410
431
  const tool = tools.find((t) => t.name === call.tool);
411
432
  if (!tool) {
412
433
  const err = `Неизвестный инструмент: ${call.tool}`;
413
- onToolResult(err);
434
+ safeToolResult(err);
414
435
  transcript?.log('tool_error', { tool: call.tool, error: err });
415
436
  results.push({ tool: call.tool, result: err });
416
437
  continue;
417
438
  }
418
- onToolCall(call.tool, call.args);
439
+ safeToolCall(call.tool, call.args);
419
440
  transcript?.log('tool_call', { tool: call.tool, args: call.args });
420
441
  let result;
421
442
  try {
@@ -424,7 +445,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
424
445
  catch (e) {
425
446
  result = `Ошибка: ${e.message}`;
426
447
  }
427
- onToolResult(result);
448
+ safeToolResult(result);
428
449
  transcript?.log('tool_result', {
429
450
  tool: call.tool,
430
451
  result: String(result),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.10.1",
3
+ "version": "2.10.2",
4
4
  "description": "Terminal coding agent over chat.deepseek.com via Playwright",
5
5
  "type": "module",
6
6
  "bin": {