zames_pro 2.4.2 → 2.4.4

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.
@@ -64,6 +64,12 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
64
64
  const rawResponse = await browser.ask(message);
65
65
  await reportChat();
66
66
  transcript?.log('assistant_raw', { response: rawResponse });
67
+ // Пользователь прервал генерацию (Esc/Ctrl+C): не считаем это ответом
68
+ // модели и не запускаем инструменты — корректно завершаем задачу.
69
+ if (/^\s*\(прервано пользователем\)\s*$/.test(rawResponse)) {
70
+ transcript?.log('user_aborted');
71
+ return rawResponse;
72
+ }
67
73
  const parsed = parseToolCall(rawResponse);
68
74
  if (parsed) {
69
75
  const thought = extractPreToolText(rawResponse);
package/dist/browser.js CHANGED
@@ -101,6 +101,10 @@ export class DeepSeekBrowser {
101
101
  maxRateLimitRetries;
102
102
  _lastSentAt;
103
103
  _abort;
104
+ // Пользователь нажал Esc/Ctrl+C — «стоп» для ВСЕЙ текущей пачки задач
105
+ // (включая очередь). В отличие от _abort (сбрасывается на каждую
106
+ // отправку), этот флаг живёт до явного запуска новой задачи с промпта.
107
+ _stopped;
104
108
  context;
105
109
  page;
106
110
  _netCapture;
@@ -109,7 +113,7 @@ export class DeepSeekBrowser {
109
113
  _netSniff;
110
114
  _netSniffLimit;
111
115
  _netHookInstalled;
112
- constructor({ headless = false, debug = false, channel = 'chrome', answerTimeoutMs = 180000, askRetries = 3, stabilityChecks = 3, stabilityDelayMs = 1000, minSendIntervalMs = 15000, rateLimitWaitMs = 300000, maxRateLimitRetries = 6, } = {}) {
116
+ constructor({ headless = false, debug = false, channel = 'chrome', answerTimeoutMs = 180000, askRetries = 3, stabilityChecks = 3, stabilityDelayMs = 1000, minSendIntervalMs = 2000, rateLimitWaitMs = 300000, maxRateLimitRetries = 6, } = {}) {
113
117
  this.headless = headless;
114
118
  this.debug = debug;
115
119
  this.channel = channel;
@@ -122,6 +126,7 @@ export class DeepSeekBrowser {
122
126
  this.maxRateLimitRetries = maxRateLimitRetries;
123
127
  this._lastSentAt = 0;
124
128
  this._abort = false;
129
+ this._stopped = false;
125
130
  this._netCapture = '';
126
131
  this._netCaptureAt = 0;
127
132
  this._netChatId = null;
@@ -354,6 +359,7 @@ export class DeepSeekBrowser {
354
359
  }
355
360
  async stopGeneration() {
356
361
  this._abort = true;
362
+ this._stopped = true;
357
363
  // 1) Пробуем явные селекторы Stop.
358
364
  const btn = await this._findVisible(STOP_SELECTORS, 500);
359
365
  if (btn) {
@@ -395,8 +401,6 @@ export class DeepSeekBrowser {
395
401
  let attempt = 0;
396
402
  let rateLimitRetries = 0;
397
403
  while (attempt < this.askRetries) {
398
- if (this._abort)
399
- return '(прервано пользователем)';
400
404
  attempt++;
401
405
  try {
402
406
  return await this._askOnce(prompt, { timeout });
@@ -480,13 +484,17 @@ export class DeepSeekBrowser {
480
484
  await this.page.keyboard.insertText(text);
481
485
  }
482
486
  }
487
+ // Небольшая пауза между отправками, чтобы случайно не отправить два
488
+ // сообщения подряд. Основная защита от лимита частоты — обработка
489
+ // RateLimitError в ask() (ждём rateLimitWaitMs и повторяем), поэтому
490
+ // здесь интервал маленький и не мешает живому вводу.
483
491
  async _waitForSendSlot() {
484
492
  if (!this._lastSentAt)
485
493
  return;
486
494
  const gap = this.minSendIntervalMs - (Date.now() - this._lastSentAt);
487
495
  if (gap <= 0)
488
496
  return;
489
- console.error(theme.warn(`⏳ пауза ${Math.ceil(gap / 1000)}с перед отправкой (лимит частоты DeepSeek)...`));
497
+ console.error(theme.warn(`⏳ пауза ${Math.ceil(gap / 1000)}с перед отправкой...`));
490
498
  await this.page.waitForTimeout(gap);
491
499
  }
492
500
  async _askOnce(prompt, { timeout }) {
package/dist/config.js CHANGED
@@ -37,7 +37,7 @@ export const DEFAULTS = {
37
37
  askRetries: 3,
38
38
  stabilityChecks: 3,
39
39
  stabilityDelayMs: 1000,
40
- minSendIntervalMs: 15000,
40
+ minSendIntervalMs: 2000,
41
41
  rateLimitWaitMs: 300000,
42
42
  maxRateLimitRetries: 6,
43
43
  },
package/dist/index.js CHANGED
@@ -626,6 +626,9 @@ async function runTask(browser, tools, taskText, workdir, opts) {
626
626
  // В TTY-режиме UI — это LineEditor: он владеет вводом (очередь, Esc,
627
627
  // Ctrl+C) и рисует статус НАД постоянной строкой ввода. В не-TTY режиме
628
628
  // (пайпы) — обычный спиннер + watchInput.
629
+ // Новая задача с промпта — сбрасываем «стоп» от прошлого прерывания.
630
+ browser._stopped = false;
631
+ browser._abort = false;
629
632
  const ui = editor || mod.createSpinner();
630
633
  const stopWatching = editor
631
634
  ? () => { }
@@ -667,6 +670,12 @@ async function runTask(browser, tools, taskText, workdir, opts) {
667
670
  onChatReady,
668
671
  debugLog: debug,
669
672
  });
673
+ // Прервали (Esc/Ctrl+C) — не запускаем следующие задачи из очереди
674
+ // и очищаем её, чтобы «стоп» действительно останавливал всё.
675
+ if (browser._stopped) {
676
+ queue.length = 0;
677
+ break;
678
+ }
670
679
  if (!queue.length)
671
680
  break;
672
681
  const queued = queue.shift() ?? '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "Terminal coding agent over chat.deepseek.com via Playwright",
5
5
  "type": "module",
6
6
  "bin": {