zames_pro 2.29.1 → 2.29.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.
- package/dist/browser.js +69 -2
- package/dist/input.js +80 -28
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -1063,6 +1063,35 @@ export class DeepSeekBrowser {
|
|
|
1063
1063
|
async _isGenerating() {
|
|
1064
1064
|
return await this._stopButtonVisible();
|
|
1065
1065
|
}
|
|
1066
|
+
// Is DeepSeek's "Continue" button currently visible? Used to BLOCK the
|
|
1067
|
+
// "answer settled" early-return in the finish loop: while Continue is on
|
|
1068
|
+
// screen the generation is PAUSED, not finished, so returning the partial
|
|
1069
|
+
// text there is exactly the "agent stopped with a Continue button" bug.
|
|
1070
|
+
async _continueButtonVisible() {
|
|
1071
|
+
try {
|
|
1072
|
+
return await this.page.evaluate(() => {
|
|
1073
|
+
const labelOf = (b) => ((b.textContent || '') + ' ' + (b.getAttribute('aria-label') || ''))
|
|
1074
|
+
.replace(/\s+/g, ' ')
|
|
1075
|
+
.trim();
|
|
1076
|
+
const isExact = (t) => /^(continue|продолжить|продолжение)\s*[.!…]?$/i.test(t);
|
|
1077
|
+
const cands = Array.from(document.querySelectorAll('div[role="button"], button'));
|
|
1078
|
+
for (const e of cands) {
|
|
1079
|
+
if (!isExact(labelOf(e)))
|
|
1080
|
+
continue;
|
|
1081
|
+
const st = getComputedStyle(e);
|
|
1082
|
+
if (st.display === 'none' || st.visibility === 'hidden')
|
|
1083
|
+
continue;
|
|
1084
|
+
if (!e.offsetParent && st.position !== 'fixed')
|
|
1085
|
+
continue;
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
return false;
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
catch {
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1066
1095
|
// Click the DeepSeek "Continue" button when it is visible (reasoning/answer
|
|
1067
1096
|
// paused by the server). Returns true when a click happened.
|
|
1068
1097
|
//
|
|
@@ -1091,6 +1120,27 @@ export class DeepSeekBrowser {
|
|
|
1091
1120
|
continue;
|
|
1092
1121
|
if (!e.offsetParent && st.position !== 'fixed')
|
|
1093
1122
|
continue;
|
|
1123
|
+
// DeepSeek's button is a React component listening for POINTER/mouse
|
|
1124
|
+
// events, not just a bare click(). A plain e.click() sometimes does
|
|
1125
|
+
// nothing; dispatching the full sequence is what a real press does.
|
|
1126
|
+
const rect = e.getBoundingClientRect();
|
|
1127
|
+
const cx = rect.left + rect.width / 2;
|
|
1128
|
+
const cy = rect.top + rect.height / 2;
|
|
1129
|
+
const opts = {
|
|
1130
|
+
bubbles: true,
|
|
1131
|
+
cancelable: true,
|
|
1132
|
+
composed: true,
|
|
1133
|
+
clientX: cx,
|
|
1134
|
+
clientY: cy,
|
|
1135
|
+
button: 0,
|
|
1136
|
+
};
|
|
1137
|
+
try {
|
|
1138
|
+
e.dispatchEvent(new PointerEvent('pointerdown', opts));
|
|
1139
|
+
e.dispatchEvent(new MouseEvent('mousedown', opts));
|
|
1140
|
+
e.dispatchEvent(new PointerEvent('pointerup', opts));
|
|
1141
|
+
e.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
1142
|
+
}
|
|
1143
|
+
catch { }
|
|
1094
1144
|
e.click();
|
|
1095
1145
|
return true;
|
|
1096
1146
|
}
|
|
@@ -1688,7 +1738,10 @@ export class DeepSeekBrowser {
|
|
|
1688
1738
|
// capture proves a new answer exists. If it stays equal, keep waiting.
|
|
1689
1739
|
const notGenerating = !(await this._isGenerating());
|
|
1690
1740
|
const differs = !!cur && normText(cur) !== normText(beforeText);
|
|
1691
|
-
|
|
1741
|
+
// Do NOT accept a "settled" answer while Continue is on screen — that
|
|
1742
|
+
// is a paused generation, not a finished one.
|
|
1743
|
+
const paused = this.autoContinue && (await this._continueButtonVisible());
|
|
1744
|
+
if (differs && cur === lastStartCur && notGenerating && !paused) {
|
|
1692
1745
|
settledTicks++;
|
|
1693
1746
|
if (settledTicks >= 2) {
|
|
1694
1747
|
this._askDebug('SETTLED-differs return len=' + cur.length);
|
|
@@ -1829,7 +1882,17 @@ export class DeepSeekBrowser {
|
|
|
1829
1882
|
// so the FIN-loop always cost ~1.6s per answer. Defaults are now
|
|
1830
1883
|
// 2 checks x 400ms (~0.8s saved per turn) and the values are honored.
|
|
1831
1884
|
if (stable >= Math.max(1, this.stabilityChecks - 1)) {
|
|
1832
|
-
|
|
1885
|
+
// A PAUSED generation also looks "stable" (the text stops changing
|
|
1886
|
+
// while Continue is on screen), so the old check returned the
|
|
1887
|
+
// partial answer here — the "agent stopped with a Continue button"
|
|
1888
|
+
// symptom. Click Continue and keep waiting instead.
|
|
1889
|
+
if (this.autoContinue && (await this._continueButtonVisible())) {
|
|
1890
|
+
if (await this._clickContinueIfVisible()) {
|
|
1891
|
+
this._askDebug('CLICKED Continue (before early return)');
|
|
1892
|
+
}
|
|
1893
|
+
stable = 0;
|
|
1894
|
+
}
|
|
1895
|
+
else if (isNew || !(await this._isGenerating())) {
|
|
1833
1896
|
this._askDebug('RETURN stable curLen=' + cur.length);
|
|
1834
1897
|
return cur;
|
|
1835
1898
|
}
|
|
@@ -1855,6 +1918,10 @@ export class DeepSeekBrowser {
|
|
|
1855
1918
|
await this.page.waitForTimeout(Math.max(0, this.stabilityDelayMs));
|
|
1856
1919
|
}
|
|
1857
1920
|
if (last && (normText(last) !== normText(beforeText) || this._netCapture)) {
|
|
1921
|
+
// If Continue is STILL on screen, the turn is paused, not finished:
|
|
1922
|
+
// click once more and report what we have rather than silently stopping.
|
|
1923
|
+
if (this.autoContinue)
|
|
1924
|
+
await this._clickContinueIfVisible();
|
|
1858
1925
|
this._askDebug('RETURN last len=' + last.length);
|
|
1859
1926
|
return last;
|
|
1860
1927
|
}
|
package/dist/input.js
CHANGED
|
@@ -233,6 +233,10 @@ export class LineEditor {
|
|
|
233
233
|
pendingText;
|
|
234
234
|
rendered;
|
|
235
235
|
cursorRowFromTop;
|
|
236
|
+
// Number of rows occupied by the status/spinner block above the input line,
|
|
237
|
+
// as computed by the last _writeBlock(). _renderInputOnly() uses it to keep
|
|
238
|
+
// cursorRowFromTop correct without repainting the status.
|
|
239
|
+
_statusTop;
|
|
236
240
|
busy;
|
|
237
241
|
onSubmit;
|
|
238
242
|
onEscape;
|
|
@@ -309,6 +313,7 @@ export class LineEditor {
|
|
|
309
313
|
this.pendingText = null;
|
|
310
314
|
this.rendered = false;
|
|
311
315
|
this.cursorRowFromTop = 0;
|
|
316
|
+
this._statusTop = 0;
|
|
312
317
|
this.busy = false;
|
|
313
318
|
this.onSubmit = null;
|
|
314
319
|
this.onEscape = null;
|
|
@@ -642,6 +647,7 @@ export class LineEditor {
|
|
|
642
647
|
// re-printing the whole block on every keystroke is what made the display
|
|
643
648
|
// flicker on terminals like Tabby. `top` is recovered from the cache so the
|
|
644
649
|
// cursor math stays correct.
|
|
650
|
+
this._statusTop = top;
|
|
645
651
|
const statusBlock = statusOut;
|
|
646
652
|
const statusUnchanged = this.rendered && statusBlock === this._lastStatusBlock;
|
|
647
653
|
if (statusUnchanged) {
|
|
@@ -729,6 +735,52 @@ export class LineEditor {
|
|
|
729
735
|
this._eraseBlock();
|
|
730
736
|
this._writeBlock();
|
|
731
737
|
}
|
|
738
|
+
// Repaint ONLY the input rows, leaving the status/spinner block untouched.
|
|
739
|
+
// Used for buffer/cursor changes (typing, arrows, backspace, …): the status
|
|
740
|
+
// line has its OWN animation timer, and repainting it on every keystroke
|
|
741
|
+
// made the whole block blink on terminals like Tabby. When nothing is drawn
|
|
742
|
+
// yet (rendered === false) fall back to a full render so the very first
|
|
743
|
+
// paint is correct.
|
|
744
|
+
_renderInputOnly() {
|
|
745
|
+
if (!this.rendered) {
|
|
746
|
+
this._render();
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const cols = process.stdout.columns || 80;
|
|
750
|
+
const lay = layoutInput(this.promptStr, this.buf, this.cursor, cols);
|
|
751
|
+
const inputRows = lay.rows.length;
|
|
752
|
+
const sugg = this._suggestions();
|
|
753
|
+
const shown = sugg.slice(0, 8);
|
|
754
|
+
this._suggestCount = shown.length;
|
|
755
|
+
const linesBelow = shown.length
|
|
756
|
+
? shown.length + (sugg.length > shown.length ? 1 : 0)
|
|
757
|
+
: 0;
|
|
758
|
+
this._eraseInputOnly(inputRows + linesBelow);
|
|
759
|
+
let out = lay.rows.map((r) => r.prefix + r.text).join(NL);
|
|
760
|
+
if (shown.length) {
|
|
761
|
+
const maxName = Math.max(...shown.map((c) => c.name.length));
|
|
762
|
+
const lines = shown.map((c) => {
|
|
763
|
+
const name = theme.prompt(c.name.padEnd(maxName));
|
|
764
|
+
const desc = theme.dim(' ' + c.description);
|
|
765
|
+
return ' ' + name + desc;
|
|
766
|
+
});
|
|
767
|
+
out += NL + lines.join(NL);
|
|
768
|
+
const hidden = sugg.length - shown.length;
|
|
769
|
+
if (hidden > 0)
|
|
770
|
+
out +=
|
|
771
|
+
NL +
|
|
772
|
+
theme.dim(' ' + translate(this.locale)('editor.more', { n: hidden }));
|
|
773
|
+
}
|
|
774
|
+
process.stdout.write(out);
|
|
775
|
+
const up = lay.rows.length - 1 - lay.cursorRow + linesBelow;
|
|
776
|
+
if (up > 0)
|
|
777
|
+
process.stdout.write(ESC + '[' + up + 'A');
|
|
778
|
+
process.stdout.write(CR);
|
|
779
|
+
if (lay.cursorCol > 0)
|
|
780
|
+
process.stdout.write(ESC + '[' + lay.cursorCol + 'C');
|
|
781
|
+
this.rendered = true;
|
|
782
|
+
this.cursorRowFromTop = this._statusTop + lay.cursorRow;
|
|
783
|
+
}
|
|
732
784
|
// Print a block ABOVE the input line and put the input line back.
|
|
733
785
|
printAbove(text) {
|
|
734
786
|
this._stopDots();
|
|
@@ -1185,7 +1237,7 @@ export class LineEditor {
|
|
|
1185
1237
|
}
|
|
1186
1238
|
this._pasteBuf = '';
|
|
1187
1239
|
}
|
|
1188
|
-
this.
|
|
1240
|
+
this._renderInputOnly();
|
|
1189
1241
|
continue;
|
|
1190
1242
|
}
|
|
1191
1243
|
const pasteAt = s.indexOf(PASTE_START);
|
|
@@ -1196,7 +1248,7 @@ export class LineEditor {
|
|
|
1196
1248
|
this._pasteBuf = '';
|
|
1197
1249
|
if (before) {
|
|
1198
1250
|
this._insert(before);
|
|
1199
|
-
this.
|
|
1251
|
+
this._renderInputOnly();
|
|
1200
1252
|
}
|
|
1201
1253
|
continue;
|
|
1202
1254
|
}
|
|
@@ -1205,31 +1257,31 @@ export class LineEditor {
|
|
|
1205
1257
|
if (s.startsWith(ESC + '[13;2u')) {
|
|
1206
1258
|
this._insertNewline();
|
|
1207
1259
|
s = s.slice(7);
|
|
1208
|
-
this.
|
|
1260
|
+
this._renderInputOnly();
|
|
1209
1261
|
continue;
|
|
1210
1262
|
}
|
|
1211
1263
|
if (s.startsWith(ESC + '[13;5u')) {
|
|
1212
1264
|
this._insertNewline();
|
|
1213
1265
|
s = s.slice(7);
|
|
1214
|
-
this.
|
|
1266
|
+
this._renderInputOnly();
|
|
1215
1267
|
continue;
|
|
1216
1268
|
}
|
|
1217
1269
|
if (s.startsWith(ESC + '[27;2;13~')) {
|
|
1218
1270
|
this._insertNewline();
|
|
1219
1271
|
s = s.slice(10);
|
|
1220
|
-
this.
|
|
1272
|
+
this._renderInputOnly();
|
|
1221
1273
|
continue;
|
|
1222
1274
|
}
|
|
1223
1275
|
if (s.startsWith(ESC + '[27;5;13~')) {
|
|
1224
1276
|
this._insertNewline();
|
|
1225
1277
|
s = s.slice(10);
|
|
1226
|
-
this.
|
|
1278
|
+
this._renderInputOnly();
|
|
1227
1279
|
continue;
|
|
1228
1280
|
}
|
|
1229
1281
|
if (s.startsWith(ESC + NL)) {
|
|
1230
1282
|
this._insertNewline();
|
|
1231
1283
|
s = s.slice(2);
|
|
1232
|
-
this.
|
|
1284
|
+
this._renderInputOnly();
|
|
1233
1285
|
continue;
|
|
1234
1286
|
}
|
|
1235
1287
|
const ch = s[0];
|
|
@@ -1243,7 +1295,7 @@ export class LineEditor {
|
|
|
1243
1295
|
const before = this.cursor > 0 ? Array.from(this.buf)[this.cursor - 1] : '';
|
|
1244
1296
|
if (before === '\\') {
|
|
1245
1297
|
this._insertNewline();
|
|
1246
|
-
this.
|
|
1298
|
+
this._renderInputOnly();
|
|
1247
1299
|
continue;
|
|
1248
1300
|
}
|
|
1249
1301
|
this._submit();
|
|
@@ -1251,7 +1303,7 @@ export class LineEditor {
|
|
|
1251
1303
|
}
|
|
1252
1304
|
if (code === 10) {
|
|
1253
1305
|
this._insertNewline();
|
|
1254
|
-
this.
|
|
1306
|
+
this._renderInputOnly();
|
|
1255
1307
|
continue;
|
|
1256
1308
|
}
|
|
1257
1309
|
if (code === 3) {
|
|
@@ -1266,24 +1318,24 @@ export class LineEditor {
|
|
|
1266
1318
|
}
|
|
1267
1319
|
if (code === 1) {
|
|
1268
1320
|
this._home();
|
|
1269
|
-
this.
|
|
1321
|
+
this._renderInputOnly();
|
|
1270
1322
|
continue;
|
|
1271
1323
|
}
|
|
1272
1324
|
if (code === 5) {
|
|
1273
1325
|
this._end();
|
|
1274
|
-
this.
|
|
1326
|
+
this._renderInputOnly();
|
|
1275
1327
|
continue;
|
|
1276
1328
|
}
|
|
1277
1329
|
if (code === 9) {
|
|
1278
1330
|
this._completeCommand();
|
|
1279
|
-
this.
|
|
1331
|
+
this._renderInputOnly();
|
|
1280
1332
|
continue;
|
|
1281
1333
|
}
|
|
1282
1334
|
if (code === 21) {
|
|
1283
1335
|
this.buf = '';
|
|
1284
1336
|
this.cursor = 0;
|
|
1285
1337
|
this.pastes = [];
|
|
1286
|
-
this.
|
|
1338
|
+
this._renderInputOnly();
|
|
1287
1339
|
continue;
|
|
1288
1340
|
}
|
|
1289
1341
|
if (code === 22) {
|
|
@@ -1295,7 +1347,7 @@ export class LineEditor {
|
|
|
1295
1347
|
}
|
|
1296
1348
|
if (code === 23) {
|
|
1297
1349
|
this._deleteWordLeft();
|
|
1298
|
-
this.
|
|
1350
|
+
this._renderInputOnly();
|
|
1299
1351
|
continue;
|
|
1300
1352
|
}
|
|
1301
1353
|
if (code === 11) {
|
|
@@ -1306,12 +1358,12 @@ export class LineEditor {
|
|
|
1306
1358
|
e++;
|
|
1307
1359
|
arr.splice(this.cursor, e - this.cursor);
|
|
1308
1360
|
this.buf = arr.join('');
|
|
1309
|
-
this.
|
|
1361
|
+
this._renderInputOnly();
|
|
1310
1362
|
continue;
|
|
1311
1363
|
}
|
|
1312
1364
|
if (code === 127 || code === 8) {
|
|
1313
1365
|
this._backspace();
|
|
1314
|
-
this.
|
|
1366
|
+
this._renderInputOnly();
|
|
1315
1367
|
continue;
|
|
1316
1368
|
}
|
|
1317
1369
|
if (code === 27) {
|
|
@@ -1320,25 +1372,25 @@ export class LineEditor {
|
|
|
1320
1372
|
if (s.startsWith('[1;5D') || s.startsWith('[5D')) {
|
|
1321
1373
|
this._wordLeft();
|
|
1322
1374
|
s = s.slice(s.startsWith('[1;5D') ? 5 : 3);
|
|
1323
|
-
this.
|
|
1375
|
+
this._renderInputOnly();
|
|
1324
1376
|
continue;
|
|
1325
1377
|
}
|
|
1326
1378
|
if (s.startsWith('[1;5C') || s.startsWith('[5C')) {
|
|
1327
1379
|
this._wordRight();
|
|
1328
1380
|
s = s.slice(s.startsWith('[1;5C') ? 5 : 3);
|
|
1329
|
-
this.
|
|
1381
|
+
this._renderInputOnly();
|
|
1330
1382
|
continue;
|
|
1331
1383
|
}
|
|
1332
1384
|
if (s.startsWith('[D')) {
|
|
1333
1385
|
this._left();
|
|
1334
1386
|
s = s.slice(2);
|
|
1335
|
-
this.
|
|
1387
|
+
this._renderInputOnly();
|
|
1336
1388
|
continue;
|
|
1337
1389
|
}
|
|
1338
1390
|
if (s.startsWith('[C')) {
|
|
1339
1391
|
this._right();
|
|
1340
1392
|
s = s.slice(2);
|
|
1341
|
-
this.
|
|
1393
|
+
this._renderInputOnly();
|
|
1342
1394
|
continue;
|
|
1343
1395
|
}
|
|
1344
1396
|
if (s.startsWith('[A')) {
|
|
@@ -1348,7 +1400,7 @@ export class LineEditor {
|
|
|
1348
1400
|
else
|
|
1349
1401
|
this._up();
|
|
1350
1402
|
s = s.slice(2);
|
|
1351
|
-
this.
|
|
1403
|
+
this._renderInputOnly();
|
|
1352
1404
|
continue;
|
|
1353
1405
|
}
|
|
1354
1406
|
if (s.startsWith('[B')) {
|
|
@@ -1357,38 +1409,38 @@ export class LineEditor {
|
|
|
1357
1409
|
else
|
|
1358
1410
|
this._down();
|
|
1359
1411
|
s = s.slice(2);
|
|
1360
|
-
this.
|
|
1412
|
+
this._renderInputOnly();
|
|
1361
1413
|
continue;
|
|
1362
1414
|
}
|
|
1363
1415
|
if (s.startsWith('[H') || s.startsWith('[1~')) {
|
|
1364
1416
|
this._home();
|
|
1365
1417
|
s = s.slice(s.startsWith('[1~') ? 3 : 2);
|
|
1366
|
-
this.
|
|
1418
|
+
this._renderInputOnly();
|
|
1367
1419
|
continue;
|
|
1368
1420
|
}
|
|
1369
1421
|
if (s.startsWith('[F') || s.startsWith('[4~')) {
|
|
1370
1422
|
this._end();
|
|
1371
1423
|
s = s.slice(s.startsWith('[4~') ? 3 : 2);
|
|
1372
|
-
this.
|
|
1424
|
+
this._renderInputOnly();
|
|
1373
1425
|
continue;
|
|
1374
1426
|
}
|
|
1375
1427
|
if (s.startsWith('[3~')) {
|
|
1376
1428
|
this._delete();
|
|
1377
1429
|
s = s.slice(3);
|
|
1378
|
-
this.
|
|
1430
|
+
this._renderInputOnly();
|
|
1379
1431
|
continue;
|
|
1380
1432
|
}
|
|
1381
1433
|
// Alt+B / Alt+F — word movement.
|
|
1382
1434
|
if (s.startsWith('b') || s.startsWith('B')) {
|
|
1383
1435
|
this._wordLeft();
|
|
1384
1436
|
s = s.slice(1);
|
|
1385
|
-
this.
|
|
1437
|
+
this._renderInputOnly();
|
|
1386
1438
|
continue;
|
|
1387
1439
|
}
|
|
1388
1440
|
if (s.startsWith('f') || s.startsWith('F')) {
|
|
1389
1441
|
this._wordRight();
|
|
1390
1442
|
s = s.slice(1);
|
|
1391
|
-
this.
|
|
1443
|
+
this._renderInputOnly();
|
|
1392
1444
|
continue;
|
|
1393
1445
|
}
|
|
1394
1446
|
let j = 0;
|
|
@@ -1400,7 +1452,7 @@ export class LineEditor {
|
|
|
1400
1452
|
if (code < 32)
|
|
1401
1453
|
continue;
|
|
1402
1454
|
this._insert(ch);
|
|
1403
|
-
this.
|
|
1455
|
+
this._renderInputOnly();
|
|
1404
1456
|
}
|
|
1405
1457
|
}
|
|
1406
1458
|
}
|