zames_pro 2.16.0 → 2.18.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 +40 -1
- package/dist/agent-loop.js +22 -6
- package/dist/browser.js +828 -29
- package/dist/commands.js +73 -0
- package/dist/config-menu.js +4 -0
- package/dist/config.js +11 -1
- package/dist/i18n.js +119 -1
- package/dist/index.js +111 -5
- package/dist/input.js +51 -9
- package/dist/spinner.js +39 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,42 @@ directory, reads and edits files, runs commands, and commits to git.
|
|
|
9
9
|
## Requirements
|
|
10
10
|
|
|
11
11
|
- Node.js >= 18
|
|
12
|
-
- A DeepSeek account
|
|
12
|
+
- A DeepSeek account. On first launch zames asks for your DeepSeek
|
|
13
|
+
login/password in the terminal (and stores them in `~/.zames/config.json`
|
|
14
|
+
after a successful sign-in, so a later logout is handled automatically
|
|
15
|
+
without asking you again). You can also sign in manually in the browser
|
|
16
|
+
window when the browser is headed.
|
|
17
|
+
|
|
18
|
+
## Signing in
|
|
19
|
+
|
|
20
|
+
The browser runs **headless by default**. When DeepSeek requires a sign-in,
|
|
21
|
+
zames:
|
|
22
|
+
|
|
23
|
+
1. reuses the session stored in the persistent profile (`~/.zames/profile`)
|
|
24
|
+
if it is still valid;
|
|
25
|
+
2. otherwise signs in automatically with the saved credentials
|
|
26
|
+
(`browser.auth.username` / `browser.auth.password`);
|
|
27
|
+
3. otherwise asks you for the login/password in the terminal (in a TTY) and,
|
|
28
|
+
after a successful sign-in, remembers them for next time;
|
|
29
|
+
4. otherwise falls back to a manual sign-in hint.
|
|
30
|
+
|
|
31
|
+
To sign in by hand (for example, if DeepSeek shows a captcha), run with a
|
|
32
|
+
visible window:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
zames --headed
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The `--headless` flag (the default) and `headless: true` in the config keep
|
|
39
|
+
the browser without a window; `--headed` / `headless: false` show it.
|
|
40
|
+
|
|
41
|
+
Headless works out of the box: a headless Chrome normally advertises a
|
|
42
|
+
`HeadlessChrome/...` User-Agent that DeepSeek's CDN blocks with a 403, so
|
|
43
|
+
zames strips that marker before loading the page (keeping the real engine
|
|
44
|
+
version). You do not need `--headed` just to log in.
|
|
45
|
+
|
|
46
|
+
Credentials and toggles can also be edited from `/config`
|
|
47
|
+
(`browser.auth.username`, `browser.auth.password`, `browser.auth.saveSession`).
|
|
13
48
|
|
|
14
49
|
## Installation
|
|
15
50
|
|
|
@@ -71,6 +106,7 @@ zames --new-chat
|
|
|
71
106
|
zames --resend-prompt
|
|
72
107
|
zames --dir <path>
|
|
73
108
|
zames --headless
|
|
109
|
+
zames --headed
|
|
74
110
|
zames --debug
|
|
75
111
|
zames --version
|
|
76
112
|
zames --help
|
|
@@ -111,6 +147,9 @@ Codex CLI:
|
|
|
111
147
|
alwaysConfirm regex list).
|
|
112
148
|
- /add-dir <path> — validate an extra directory (the sandbox is fixed at
|
|
113
149
|
startup; relaunch with --dir to write there).
|
|
150
|
+
- /resume <n> (after /chats) and /resume-id <id> — open a chat and PRINT its
|
|
151
|
+
dialogue into the terminal, so the restored context is visible. Only the
|
|
152
|
+
last 20 messages are shown (`RESTORED_HISTORY_LIMIT`).
|
|
114
153
|
- /review [focus] [--staged] — ask the agent to review uncommitted changes
|
|
115
154
|
and report findings (no code changes).
|
|
116
155
|
|
package/dist/agent-loop.js
CHANGED
|
@@ -4,7 +4,7 @@ import { getGitContext, formatGitContext } from './gitTools.js';
|
|
|
4
4
|
import { parseXmlToolCalls } from './xml-toolcall.js';
|
|
5
5
|
import { translate } from './i18n.js';
|
|
6
6
|
import { normText } from './browser.js';
|
|
7
|
-
export async function runAgentLoop({ browser, tools, task, workdir, maxIterations = 0, freshChat = false, sendSystemPrompt = false, transcript = null, attachments = [], onThinking = () => { }, onAssistantThought = () => { }, onToolCall = () => { }, onToolResult = () => { }, onAssistantMessage = () => { }, onChatReady = () => { }, onWarning = () => { }, debugLog = false, locale = 'ru', }) {
|
|
7
|
+
export async function runAgentLoop({ browser, tools, task, workdir, maxIterations = 0, freshChat = false, sendSystemPrompt = false, transcript = null, attachments = [], onThinking = () => { }, onSendPause = () => { }, onAssistantThought = () => { }, onToolCall = () => { }, onToolResult = () => { }, onAssistantMessage = () => { }, onChatReady = () => { }, onWarning = () => { }, debugLog = false, locale = 'ru', }) {
|
|
8
8
|
// UI callbacks must NEVER break the agent loop. A rendering error (a huge
|
|
9
9
|
// tool result, a broken markdown frame, a closed terminal) used to throw
|
|
10
10
|
// out of the loop right after a tool call — the session looked "stopped
|
|
@@ -26,6 +26,10 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
|
|
|
26
26
|
// Previously safeThinking() fired before browser.ask(), so the spinner ran
|
|
27
27
|
// through the whole throttle pause / chat-open phase with nothing in flight.
|
|
28
28
|
browser.onSendStart = safeThinking;
|
|
29
|
+
// Animate the send-interval pause too: the browser reports the remaining
|
|
30
|
+
// seconds, the UI shows an animated status instead of a frozen line.
|
|
31
|
+
const safeSendPause = safe(onSendPause);
|
|
32
|
+
browser.onSendPause = safeSendPause;
|
|
29
33
|
const safeAssistantThought = safe(onAssistantThought);
|
|
30
34
|
const safeToolCall = safe(onToolCall);
|
|
31
35
|
const safeToolResult = safe(onToolResult);
|
|
@@ -125,6 +129,9 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
|
|
|
125
129
|
let unparsedRetries = 0;
|
|
126
130
|
const MAX_UNPARSED_RETRIES = 4;
|
|
127
131
|
let finalRespondAsked = false;
|
|
132
|
+
// The operator is told ONCE that the agent is re-asking the model for a
|
|
133
|
+
// proper tool call (not on every retry — that would spam the terminal).
|
|
134
|
+
let toolRetryWarned = false;
|
|
128
135
|
// Guard against "the agent stalled": DeepSeek sometimes sends a final text
|
|
129
136
|
// that merely DESCRIBES the next tool call (or cuts the answer off
|
|
130
137
|
// mid-word), and the agent silently finishes the task even though the work
|
|
@@ -203,9 +210,9 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
|
|
|
203
210
|
attempt: afterToolRetries,
|
|
204
211
|
error: e.message,
|
|
205
212
|
});
|
|
206
|
-
safeWarning(
|
|
207
|
-
Math.round(askDeadlineMs / 1000)
|
|
208
|
-
|
|
213
|
+
safeWarning(translate(locale)('ds.answer_timeout', {
|
|
214
|
+
sec: Math.round(askDeadlineMs / 1000),
|
|
215
|
+
}));
|
|
209
216
|
if (afterToolRetries < MAX_AFTER_TOOL_RETRIES) {
|
|
210
217
|
afterToolRetries++;
|
|
211
218
|
await new Promise((r) => setTimeout(r, 1500));
|
|
@@ -214,8 +221,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
|
|
|
214
221
|
transcript?.log('ask_timeout_exhausted', {
|
|
215
222
|
message: 'ask() did not return an answer and the retry limit is exhausted',
|
|
216
223
|
});
|
|
217
|
-
safeWarning('
|
|
218
|
-
'stopping. No model answer — check the DeepSeek chat manually.');
|
|
224
|
+
safeWarning(translate(locale)('ds.answer_timeout_give_up'));
|
|
219
225
|
return 'ask() watchdog: no model answer received';
|
|
220
226
|
}
|
|
221
227
|
await reportChat();
|
|
@@ -398,6 +404,16 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
|
|
|
398
404
|
attempt: unparsedRetries,
|
|
399
405
|
response: rawResponse.slice(0, 500),
|
|
400
406
|
});
|
|
407
|
+
// Tell the operator WHY nothing is happening: the model wrote text
|
|
408
|
+
// instead of a tool call and the agent is asking it to continue. Only
|
|
409
|
+
// once per task, otherwise the retry budget spams the terminal.
|
|
410
|
+
if (!toolRetryWarned) {
|
|
411
|
+
toolRetryWarned = true;
|
|
412
|
+
safeWarning(translate(locale)('ds.tool_retry', {
|
|
413
|
+
attempt: unparsedRetries,
|
|
414
|
+
max: MAX_UNPARSED_RETRIES,
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
401
417
|
message =
|
|
402
418
|
(justRanTool
|
|
403
419
|
? 'You stopped after a tool call and wrote plain text. '
|