zames_pro 2.10.4 → 2.10.7
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 +89 -21
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -520,9 +520,23 @@ export class DeepSeekBrowser {
|
|
|
520
520
|
.replace(/\r\n/g, '\n')
|
|
521
521
|
.replace(/\u00a0/g, ' ')
|
|
522
522
|
.trim();
|
|
523
|
-
|
|
523
|
+
// Verify the WHOLE text landed in the input, not just that it is non-empty.
|
|
524
|
+
// A partial paste (DeepSeek input limits, lost chars) used to pass the
|
|
525
|
+
// old "not empty" check, so a TRUNCATED message was sent, the model
|
|
526
|
+
// replied to the wrong thing (or nothing), and the loop looked stalled.
|
|
527
|
+
if (norm(got) !== norm(text)) {
|
|
524
528
|
await input.click();
|
|
529
|
+
await this.page.keyboard.press("Control+A");
|
|
530
|
+
await this.page.keyboard.press("Delete");
|
|
525
531
|
await this.page.keyboard.insertText(text);
|
|
532
|
+
const got2 = await input.evaluate((el) => {
|
|
533
|
+
if (el.tagName.toLowerCase() === "textarea" || el.tagName.toLowerCase() === "input")
|
|
534
|
+
return el.value;
|
|
535
|
+
return el.innerText || el.textContent || "";
|
|
536
|
+
});
|
|
537
|
+
if (norm(got2) !== norm(text)) {
|
|
538
|
+
throw new Error("Не удалось вставить текст в поле ввода DeepSeek целиком (вставлено " + norm(got2).length + " из " + norm(text).length + " символов). Сообщение не отправлено, чтобы не отправить обрезанный текст.");
|
|
539
|
+
}
|
|
526
540
|
}
|
|
527
541
|
}
|
|
528
542
|
// Attach files/images to the chat via the hidden <input type=file> of the
|
|
@@ -602,6 +616,18 @@ export class DeepSeekBrowser {
|
|
|
602
616
|
console.error(theme.warn(`⏳ пауза ${Math.ceil(gap / 1000)}с перед отправкой`));
|
|
603
617
|
await this.page.waitForTimeout(gap);
|
|
604
618
|
}
|
|
619
|
+
// DEBUG: append ask() phases to ~/.zames/ask-debug.log so a stall can be
|
|
620
|
+
// diagnosed from the field (what the DOM/network looked like at each step).
|
|
621
|
+
_askDebug(msg) {
|
|
622
|
+
if (!process.env.ZAMES_ASK_DEBUG)
|
|
623
|
+
return;
|
|
624
|
+
try {
|
|
625
|
+
const line = new Date().toISOString() + ' ' + msg + String.fromCharCode(10);
|
|
626
|
+
const dir = path.join(os.homedir(), '.zames');
|
|
627
|
+
void fs.appendFile(path.join(dir, 'ask-debug.log'), line).catch(() => { });
|
|
628
|
+
}
|
|
629
|
+
catch { }
|
|
630
|
+
}
|
|
605
631
|
async _askOnce(prompt, { timeout, agent, attachments = [], }) {
|
|
606
632
|
// We reset the abort flag ONLY at the very start of the send.
|
|
607
633
|
this._abort = false;
|
|
@@ -610,6 +636,7 @@ export class DeepSeekBrowser {
|
|
|
610
636
|
throw new Error('Не найдено поле ввода. Запустите /debug-dom и поправьте INPUT_SELECTORS.');
|
|
611
637
|
}
|
|
612
638
|
const beforeText = await this._readLastAnswerTextClean().catch(() => '');
|
|
639
|
+
this._askDebug('SEND agent=' + agent + ' len=' + prompt.length + ' beforeLen=' + beforeText.length + ' beforeHead=' + JSON.stringify(beforeText.slice(0, 60)));
|
|
613
640
|
await this._waitForSendSlot(agent);
|
|
614
641
|
this._netCapture = '';
|
|
615
642
|
this._netCaptureAt = 0;
|
|
@@ -638,10 +665,11 @@ export class DeepSeekBrowser {
|
|
|
638
665
|
await this.page.keyboard.press('Enter');
|
|
639
666
|
}
|
|
640
667
|
this._lastSentAt = Date.now();
|
|
668
|
+
this._askDebug('SENT at=' + this._lastSentAt);
|
|
641
669
|
// Wait for the start: either Stop appeared, or the answer text changed,
|
|
642
670
|
// or the total amount of text on the page grew. In parallel we catch
|
|
643
671
|
// the rate-limit toast (only toasts, not the whole body).
|
|
644
|
-
const startDeadline = Date.now() +
|
|
672
|
+
const startDeadline = Date.now() + 30_000;
|
|
645
673
|
const startBodyLen = await this.page
|
|
646
674
|
.evaluate(() => document.body.innerText.length)
|
|
647
675
|
.catch(() => 0);
|
|
@@ -684,16 +712,20 @@ export class DeepSeekBrowser {
|
|
|
684
712
|
const netStarted = !!this._netCapture && this._netCaptureAt >= this._lastSentAt;
|
|
685
713
|
if (changed || netStarted || bodyLen > startBodyLen) {
|
|
686
714
|
started = true;
|
|
715
|
+
this._askDebug('STARTED changed=' + changed + ' netStarted=' + netStarted + ' bodyGrew=' + (bodyLen > startBodyLen));
|
|
687
716
|
break;
|
|
688
717
|
}
|
|
689
|
-
// Fallback for an echo
|
|
690
|
-
//
|
|
691
|
-
//
|
|
692
|
-
//
|
|
718
|
+
// Fallback for an echo: the text equals beforeText, so it is the OLD
|
|
719
|
+
// answer still on screen, NOT a new one. We must NOT return it (that
|
|
720
|
+
// made the loop re-run the previous tool call). We only return when the
|
|
721
|
+
// text DIFFERS from beforeText and has settled, or when a fresh network
|
|
722
|
+
// capture proves a new answer exists. If it stays equal, keep waiting.
|
|
693
723
|
const notGenerating = !(await this._isGenerating());
|
|
694
|
-
|
|
724
|
+
const differs = !!cur && normText(cur) !== normText(beforeText);
|
|
725
|
+
if (differs && cur === lastStartCur && notGenerating) {
|
|
695
726
|
settledTicks++;
|
|
696
727
|
if (settledTicks >= 2) {
|
|
728
|
+
this._askDebug('SETTLED-differs return len=' + cur.length);
|
|
697
729
|
return cur;
|
|
698
730
|
}
|
|
699
731
|
}
|
|
@@ -701,19 +733,52 @@ export class DeepSeekBrowser {
|
|
|
701
733
|
settledTicks = 0;
|
|
702
734
|
}
|
|
703
735
|
lastStartCur = cur;
|
|
736
|
+
this._askDebug('START-loop curLen=' + cur.length + ' changed=' + changed + ' netStarted=' + netStarted + ' bodyLen=' + bodyLen + ' settled=' + settledTicks + ' generating=' + notGenerating);
|
|
704
737
|
await this.page.waitForTimeout(300);
|
|
705
738
|
}
|
|
706
739
|
if (!started) {
|
|
707
|
-
// Last chance: the
|
|
708
|
-
//
|
|
740
|
+
// Last chance: accept the text only when it DIFFERS from beforeText
|
|
741
|
+
// (otherwise it is the old answer on screen) or a fresh network capture
|
|
742
|
+
// proves a new answer. Returning an equal text made the loop re-run the
|
|
743
|
+
// previous tool call.
|
|
709
744
|
const cur = await this._readLastAnswerTextClean().catch(() => '');
|
|
710
|
-
|
|
745
|
+
const fresh = !!this._netCapture && this._netCaptureAt >= this._lastSentAt;
|
|
746
|
+
if (cur && cur.trim() && normText(cur) !== normText(beforeText) && !(await this._isGenerating())) {
|
|
711
747
|
return cur;
|
|
712
748
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
749
|
+
if (fresh) {
|
|
750
|
+
return this._netCapture;
|
|
751
|
+
}
|
|
752
|
+
// The send did not start generation within 15s. The most common cause is
|
|
753
|
+
// that the message did not actually go out (Enter lost, button not
|
|
754
|
+
// clicked). Instead of throwing (which made ask() retry for minutes and
|
|
755
|
+
// looked like a stall), press Enter once more and give it another
|
|
756
|
+
// window. Only if that also fails do we throw.
|
|
757
|
+
this._askDebug('START-failed, resending');
|
|
758
|
+
await this.page.keyboard.press('Enter');
|
|
759
|
+
this._lastSentAt = Date.now();
|
|
760
|
+
const retryDeadline = Date.now() + 20_000;
|
|
761
|
+
while (Date.now() < retryDeadline) {
|
|
762
|
+
if (this._abort)
|
|
763
|
+
return '(прервано пользователем)';
|
|
764
|
+
const cur2 = await this._readLastAnswerTextClean().catch(() => '');
|
|
765
|
+
const net2 = !!this._netCapture && this._netCaptureAt >= this._lastSentAt;
|
|
766
|
+
const grew2 = (await this.page
|
|
767
|
+
.evaluate(() => document.body.innerText.length)
|
|
768
|
+
.catch(() => 0)) > startBodyLen;
|
|
769
|
+
if (net2 ||
|
|
770
|
+
grew2 ||
|
|
771
|
+
(!!cur2 && normText(cur2) !== normText(beforeText))) {
|
|
772
|
+
started = true;
|
|
773
|
+
this._askDebug('STARTED-after-resend');
|
|
774
|
+
break;
|
|
775
|
+
}
|
|
776
|
+
await this.page.waitForTimeout(300);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (!started) {
|
|
780
|
+
throw new Error('Ответ не начал генерироваться за 35с даже после повторной отправки. ' +
|
|
781
|
+
'Проверьте чат DeepSeek вручную.');
|
|
717
782
|
}
|
|
718
783
|
// Wait until the answer stops changing. We check the "not generating"
|
|
719
784
|
// condition via text growth, NOT via _isGenerating().
|
|
@@ -752,30 +817,33 @@ export class DeepSeekBrowser {
|
|
|
752
817
|
// tool call" hang. If generation has clearly ENDED (no Stop button) and
|
|
753
818
|
// the text is stable, accept it (even when it repeats the previous one).
|
|
754
819
|
const sameAsBefore = !!cur && !isNew && normText(cur) === normText(beforeText);
|
|
755
|
-
if (
|
|
820
|
+
if (isNew && cur === last) {
|
|
756
821
|
stable++;
|
|
757
822
|
if (stable >= 2) {
|
|
758
|
-
if (isNew || !(await this._isGenerating()))
|
|
823
|
+
if (isNew || !(await this._isGenerating())) {
|
|
824
|
+
this._askDebug('RETURN stable curLen=' + cur.length);
|
|
759
825
|
return cur;
|
|
826
|
+
}
|
|
760
827
|
}
|
|
761
828
|
}
|
|
762
829
|
else {
|
|
763
830
|
stable = 0;
|
|
764
831
|
}
|
|
765
|
-
if (isNew
|
|
832
|
+
if (isNew)
|
|
766
833
|
last = cur;
|
|
834
|
+
this._askDebug('FIN-loop isNew=' + isNew + ' sameAsBefore=' + sameAsBefore + ' stable=' + stable + ' curLen=' + cur.length + ' lastLen=' + last.length + ' netFresh=' + netFresh);
|
|
767
835
|
await this.page.waitForTimeout(800);
|
|
768
836
|
}
|
|
769
837
|
if (last && (normText(last) !== normText(beforeText) || this._netCapture)) {
|
|
838
|
+
this._askDebug('RETURN last len=' + last.length);
|
|
770
839
|
return last;
|
|
771
840
|
}
|
|
772
|
-
//
|
|
773
|
-
|
|
774
|
-
return last;
|
|
775
|
-
}
|
|
841
|
+
// No fallback on a text equal to beforeText: returning it would re-run
|
|
842
|
+
// the previous tool call. Only a fresh network capture is accepted below.
|
|
776
843
|
if (this._netCapture && this._netCaptureAt >= this._lastSentAt) {
|
|
777
844
|
return this._netCapture;
|
|
778
845
|
}
|
|
846
|
+
this._askDebug('THROW no-new-answer lastLen=' + last.length + ' beforeLen=' + beforeText.length);
|
|
779
847
|
throw new Error('Новый ответ не получен (на странице остался прежний текст). ' +
|
|
780
848
|
'Возможно, сообщение не отправилось.');
|
|
781
849
|
}
|