zames_pro 2.15.5 → 2.16.0
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/README.md +2 -0
- package/dist/browser.js +65 -3
- package/dist/config.js +4 -0
- package/dist/i18n.js +2 -0
- package/dist/index.js +10 -0
- package/dist/net-capture.js +32 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -206,6 +206,8 @@ Examples:
|
|
|
206
206
|
```
|
|
207
207
|
/config set maxIterations 20
|
|
208
208
|
/config set confirmation.bash false
|
|
209
|
+
/config set browser.deepThinking true # DeepSeek Deep thinking (slow; reasoning is hidden)
|
|
210
|
+
/config set browser.webSearch false # DeepSeek Smart web search
|
|
209
211
|
/config lang en
|
|
210
212
|
```
|
|
211
213
|
|
package/dist/browser.js
CHANGED
|
@@ -125,6 +125,11 @@ export class DeepSeekBrowser {
|
|
|
125
125
|
maxRateLimitRetries;
|
|
126
126
|
maxServerBusyRetries;
|
|
127
127
|
serverBusyWaitMs;
|
|
128
|
+
// Desired state of the DeepSeek chat toggles, applied before each send.
|
|
129
|
+
// deepThinking: the "Deep thinking" toggle (reasoning; the reasoning text
|
|
130
|
+
// is never read/shown). webSearch: the "Smart search" toggle.
|
|
131
|
+
deepThinking;
|
|
132
|
+
webSearch;
|
|
128
133
|
_lastSentAt;
|
|
129
134
|
_abort;
|
|
130
135
|
// The user pressed Esc/Ctrl+C — a "stop" for the WHOLE current batch of
|
|
@@ -144,7 +149,7 @@ export class DeepSeekBrowser {
|
|
|
144
149
|
// a generation really begins, not during the pre-send phase (chat open,
|
|
145
150
|
// throttle wait), which used to show a spinner with no work in flight.
|
|
146
151
|
onSendStart;
|
|
147
|
-
constructor({ headless = false, debug = false, channel = 'chrome', answerTimeoutMs = 180000, askRetries = 3, stabilityChecks = 2, stabilityDelayMs = 400, minSendIntervalMs = 15000, rateLimitWaitMs = 300000, maxRateLimitRetries = 6, maxServerBusyRetries = 5, serverBusyWaitMs = 3000, } = {}) {
|
|
152
|
+
constructor({ headless = false, debug = false, channel = 'chrome', answerTimeoutMs = 180000, askRetries = 3, stabilityChecks = 2, stabilityDelayMs = 400, minSendIntervalMs = 15000, rateLimitWaitMs = 300000, maxRateLimitRetries = 6, maxServerBusyRetries = 5, serverBusyWaitMs = 3000, deepThinking = false, webSearch = true, } = {}) {
|
|
148
153
|
this.headless = headless;
|
|
149
154
|
this.debug = debug;
|
|
150
155
|
this.channel = channel;
|
|
@@ -157,6 +162,8 @@ export class DeepSeekBrowser {
|
|
|
157
162
|
this.maxRateLimitRetries = maxRateLimitRetries;
|
|
158
163
|
this.maxServerBusyRetries = maxServerBusyRetries;
|
|
159
164
|
this.serverBusyWaitMs = serverBusyWaitMs;
|
|
165
|
+
this.deepThinking = deepThinking;
|
|
166
|
+
this.webSearch = webSearch;
|
|
160
167
|
this._lastSentAt = 0;
|
|
161
168
|
this._abort = false;
|
|
162
169
|
this._stopped = false;
|
|
@@ -329,11 +336,34 @@ export class DeepSeekBrowser {
|
|
|
329
336
|
return this._netCapture;
|
|
330
337
|
}
|
|
331
338
|
return await this.page.evaluate((sels) => {
|
|
339
|
+
// DeepSeek stores the model's reasoning in .ds-think-content blocks.
|
|
340
|
+
// They are NOT the answer and must never be picked up as the answer
|
|
341
|
+
// (otherwise the terminal would show the long reasoning). We also
|
|
342
|
+
// prefer the first (most specific) selector with a hit.
|
|
343
|
+
const inThink = (e) => {
|
|
344
|
+
let n = e;
|
|
345
|
+
while (n) {
|
|
346
|
+
const cls = (n.className || '').toString();
|
|
347
|
+
if (/ds-think-content|thinking-content/i.test(cls))
|
|
348
|
+
return true;
|
|
349
|
+
n = n.parentElement;
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
};
|
|
332
353
|
let el = null;
|
|
333
354
|
for (const s of sels) {
|
|
334
355
|
const list = document.querySelectorAll(s);
|
|
335
|
-
if (list.length)
|
|
336
|
-
|
|
356
|
+
if (!list.length)
|
|
357
|
+
continue;
|
|
358
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
359
|
+
const cand = list[i];
|
|
360
|
+
if (inThink(cand))
|
|
361
|
+
continue;
|
|
362
|
+
el = cand;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
if (el)
|
|
366
|
+
break;
|
|
337
367
|
}
|
|
338
368
|
if (!el)
|
|
339
369
|
return '';
|
|
@@ -411,6 +441,34 @@ export class DeepSeekBrowser {
|
|
|
411
441
|
async _isGenerating() {
|
|
412
442
|
return await this._stopButtonVisible();
|
|
413
443
|
}
|
|
444
|
+
// DeepSeek exposes two toggle buttons above the input: "Deep thinking"
|
|
445
|
+
// (reasoning) and "Smart search" (web search). Their labels are localized,
|
|
446
|
+
// so we match by a loose regex on the visible text and read the state from
|
|
447
|
+
// aria-pressed. We click ONLY when the state differs, so a send does not
|
|
448
|
+
// flip a toggle the operator set by hand.
|
|
449
|
+
async _setToggle(labelRe, want) {
|
|
450
|
+
try {
|
|
451
|
+
const btns = this.page.locator('.ds-toggle-button');
|
|
452
|
+
const count = await btns.count().catch(() => 0);
|
|
453
|
+
for (let i = 0; i < count; i++) {
|
|
454
|
+
const b = btns.nth(i);
|
|
455
|
+
const txt = ((await b.textContent().catch(() => '')) || '').trim();
|
|
456
|
+
if (!labelRe.test(txt))
|
|
457
|
+
continue;
|
|
458
|
+
const pressed = (await b.getAttribute('aria-pressed').catch(() => null)) === 'true';
|
|
459
|
+
if (pressed !== want) {
|
|
460
|
+
await b.click({ timeout: 2000 }).catch(() => { });
|
|
461
|
+
await this.page.waitForTimeout(150);
|
|
462
|
+
}
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
catch { }
|
|
467
|
+
}
|
|
468
|
+
async _applyToggles() {
|
|
469
|
+
await this._setToggle(/глубок|deep\s*think/i, this.deepThinking);
|
|
470
|
+
await this._setToggle(/поиск|search/i, this.webSearch);
|
|
471
|
+
}
|
|
414
472
|
async stopGeneration() {
|
|
415
473
|
this._abort = true;
|
|
416
474
|
this._stopped = true;
|
|
@@ -691,6 +749,10 @@ export class DeepSeekBrowser {
|
|
|
691
749
|
}
|
|
692
750
|
this._netCapture = '';
|
|
693
751
|
this._netCaptureAt = 0;
|
|
752
|
+
// Align the DeepSeek chat toggles (deep thinking / web search) with the
|
|
753
|
+
// configured state BEFORE typing. Doing it here (after the send-pause) it
|
|
754
|
+
// does not flip toggles for a generation that is not going to happen.
|
|
755
|
+
await this._applyToggles();
|
|
694
756
|
// Attach files/images FIRST (before the text): the DeepSeek upload widget
|
|
695
757
|
// shows them above the input, and only then the message can be sent.
|
|
696
758
|
if (attachments.length) {
|
package/dist/config.js
CHANGED
|
@@ -41,6 +41,8 @@ export const DEFAULTS = {
|
|
|
41
41
|
minSendIntervalMs: 15000,
|
|
42
42
|
rateLimitWaitMs: 300000,
|
|
43
43
|
maxRateLimitRetries: 6,
|
|
44
|
+
deepThinking: false,
|
|
45
|
+
webSearch: true,
|
|
44
46
|
},
|
|
45
47
|
ui: {
|
|
46
48
|
locale: DEFAULT_LOCALE,
|
|
@@ -94,6 +96,8 @@ export const CONFIG_SCHEMA = [
|
|
|
94
96
|
{ path: 'browser.minSendIntervalMs', type: 'number', min: 0, max: 600000, labelKey: 'cfg.f.browser_minSendIntervalMs', groupKey: 'cfg.group.browser' },
|
|
95
97
|
{ path: 'browser.rateLimitWaitMs', type: 'number', min: 0, max: 3600000, labelKey: 'cfg.f.browser_rateLimitWaitMs', groupKey: 'cfg.group.browser' },
|
|
96
98
|
{ path: 'browser.maxRateLimitRetries', type: 'number', min: 0, max: 100, labelKey: 'cfg.f.browser_maxRateLimitRetries', groupKey: 'cfg.group.browser' },
|
|
99
|
+
{ path: 'browser.deepThinking', type: 'boolean', labelKey: 'cfg.f.browser_deepThinking', groupKey: 'cfg.group.browser' },
|
|
100
|
+
{ path: 'browser.webSearch', type: 'boolean', labelKey: 'cfg.f.browser_webSearch', groupKey: 'cfg.group.browser' },
|
|
97
101
|
];
|
|
98
102
|
export function getConfigField(path) {
|
|
99
103
|
return CONFIG_SCHEMA.find((f) => f.path === path);
|
package/dist/i18n.js
CHANGED
|
@@ -293,6 +293,8 @@ const CATALOG = {
|
|
|
293
293
|
'cfg.f.browser_minSendIntervalMs': { ru: 'Мин. пауза между отправками, мс', en: 'Min pause between sends, ms' },
|
|
294
294
|
'cfg.f.browser_rateLimitWaitMs': { ru: 'Пауза при лимите частоты, мс', en: 'Wait on rate limit, ms' },
|
|
295
295
|
'cfg.f.browser_maxRateLimitRetries': { ru: 'Число повторов при лимите', en: 'Rate-limit retry count' },
|
|
296
|
+
'cfg.f.browser_deepThinking': { ru: 'Глубокое мышление (долго; размышления не выводятся)', en: 'Deep thinking (slow; reasoning is hidden)' },
|
|
297
|
+
'cfg.f.browser_webSearch': { ru: 'Умный поиск в интернете', en: 'Smart web search' },
|
|
296
298
|
'cfg.menu.title': { ru: '⚙ Настройки — выбери параметр', en: '⚙ Settings — choose a parameter' },
|
|
297
299
|
'cfg.menu.hint': { ru: '↑/↓ — выбор, Enter — изменить, q/Esc — выйти', en: '↑/↓ select, Enter edit, q/Esc quit' },
|
|
298
300
|
'cfg.menu.edit_hint': { ru: 'Введи значение и Enter (пусто — отмена)', en: 'Enter a value and press Enter (empty — cancel)' },
|
package/dist/index.js
CHANGED
|
@@ -1263,6 +1263,16 @@ async function main() {
|
|
|
1263
1263
|
editor.setPrompt(buildPrompt());
|
|
1264
1264
|
}
|
|
1265
1265
|
}
|
|
1266
|
+
// Reflect browser toggles on the LIVE browser object. The browser is
|
|
1267
|
+
// created once at startup, so without this a /config set browser.*
|
|
1268
|
+
// change would only apply after a restart.
|
|
1269
|
+
if (path === 'browser.deepThinking' || path === 'browser.webSearch') {
|
|
1270
|
+
const b = browser;
|
|
1271
|
+
if (path === 'browser.deepThinking')
|
|
1272
|
+
b.deepThinking = !!value;
|
|
1273
|
+
else
|
|
1274
|
+
b.webSearch = !!value;
|
|
1275
|
+
}
|
|
1266
1276
|
}
|
|
1267
1277
|
function configSetRaw(field, raw) {
|
|
1268
1278
|
const value = validateConfigValue(field, raw);
|
package/dist/net-capture.js
CHANGED
|
@@ -43,6 +43,12 @@ function parseDataLines(body) {
|
|
|
43
43
|
// incremental APPEND chunks response/fragments/-1/content.
|
|
44
44
|
export function extractFromSse(body) {
|
|
45
45
|
let out = '';
|
|
46
|
+
// Type of the CURRENT last fragment. When deep thinking is on, the
|
|
47
|
+
// stream first fills a THINK fragment (the reasoning) and only then a
|
|
48
|
+
// RESPONSE fragment (the answer), and BOTH use the same APPEND path
|
|
49
|
+
// response/fragments/-1/content. Without tracking this, the reasoning was
|
|
50
|
+
// concatenated into the answer and leaked to the terminal.
|
|
51
|
+
let lastType = '';
|
|
46
52
|
for (const obj of parseDataLines(body)) {
|
|
47
53
|
if (obj == null || typeof obj !== 'object')
|
|
48
54
|
continue;
|
|
@@ -58,21 +64,43 @@ export function extractFromSse(body) {
|
|
|
58
64
|
? v.response
|
|
59
65
|
: undefined;
|
|
60
66
|
if (resp && Array.isArray(resp.fragments)) {
|
|
61
|
-
|
|
67
|
+
const frags = resp.fragments;
|
|
68
|
+
for (const fr of frags) {
|
|
62
69
|
if (fr && fr.type === 'RESPONSE' && typeof fr.content === 'string') {
|
|
63
70
|
out += fr.content;
|
|
64
71
|
}
|
|
65
72
|
}
|
|
73
|
+
const lastFrag = frags[frags.length - 1];
|
|
74
|
+
if (lastFrag && typeof lastFrag.type === 'string')
|
|
75
|
+
lastType = lastFrag.type;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// A NEW fragment is appended to response/fragments[]. The LAST fragment
|
|
79
|
+
// decides what the following content chunks belong to (THINK vs
|
|
80
|
+
// RESPONSE).
|
|
81
|
+
if (o.p === 'response/fragments' && Array.isArray(o.v)) {
|
|
82
|
+
const frags = o.v;
|
|
83
|
+
for (const fr of frags) {
|
|
84
|
+
if (fr && fr.type === 'RESPONSE' && typeof fr.content === 'string') {
|
|
85
|
+
out += fr.content;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const lastFrag = frags[frags.length - 1];
|
|
89
|
+
if (lastFrag && typeof lastFrag.type === 'string')
|
|
90
|
+
lastType = lastFrag.type;
|
|
66
91
|
continue;
|
|
67
92
|
}
|
|
68
93
|
// Incremental APPEND: p='response/fragments/-1/content' -> v=string;
|
|
69
|
-
// subsequent chunks come with a single v field.
|
|
94
|
+
// subsequent chunks come with a single v field. Append ONLY when the
|
|
95
|
+
// current fragment is RESPONSE; a THINK fragment is the reasoning.
|
|
70
96
|
if (o.p === 'response/fragments/-1/content' && typeof o.v === 'string') {
|
|
71
|
-
|
|
97
|
+
if (lastType === '' || lastType === 'RESPONSE')
|
|
98
|
+
out += o.v;
|
|
72
99
|
continue;
|
|
73
100
|
}
|
|
74
101
|
if (o.p === undefined && typeof o.v === 'string') {
|
|
75
|
-
|
|
102
|
+
if (lastType === '' || lastType === 'RESPONSE')
|
|
103
|
+
out += o.v;
|
|
76
104
|
}
|
|
77
105
|
}
|
|
78
106
|
return out;
|