zames_pro 2.82.50 → 2.82.51
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/CHANGELOG.md +21 -0
- package/README.md +159 -26
- package/SECURITY.md +50 -0
- package/dist/agent-loop.js +24 -4
- package/dist/answer-parse.js +1 -1
- package/dist/attach-refs.js +22 -6
- package/dist/browser-chats.js +1 -1
- package/dist/browser-dom.js +1 -1
- package/dist/browser-pure.js +1 -1
- package/dist/browser.js +1 -1
- package/dist/changelog.js +1 -1
- package/dist/checkpoint.js +1 -1
- package/dist/cli-args.js +1 -1
- package/dist/config-command.js +1 -1
- package/dist/config-commands.js +1 -1
- package/dist/config.js +1 -1
- package/dist/context.js +19 -3
- package/dist/extraTools.js +7 -0
- package/dist/i18n/deepseek.js +3 -3
- package/dist/i18n.js +1 -1
- package/dist/index.js +3 -3
- package/dist/input/layout.js +1 -1
- package/dist/input/suggest.js +1 -1
- package/dist/input.js +1 -1
- package/dist/mcp.js +8 -2
- package/dist/path-token.js +1 -1
- package/dist/subagent.js +5 -12
- package/dist/tools.js +9 -0
- package/dist/tui/StatusBar.js +1 -1
- package/dist/web.js +16 -6
- package/llms-full.txt +679 -0
- package/llms.txt +102 -0
- package/package.json +84 -23
package/dist/i18n/deepseek.js
CHANGED
|
@@ -96,9 +96,9 @@ export const deepseekMessages = {
|
|
|
96
96
|
ru: '✖ {provider} перестал отвечать, лимит повторов исчерпан. Модель не дала ответа — проверь чат вручную.',
|
|
97
97
|
en: '✖ {provider} stopped responding, retry limit exhausted. The model gave no answer — check the chat manually.',
|
|
98
98
|
},
|
|
99
|
-
'ds.
|
|
100
|
-
ru: '⏳
|
|
101
|
-
en: '⏳ The
|
|
99
|
+
'ds.text_no_tool': {
|
|
100
|
+
ru: '⏳ Модель ответила текстом без вызова инструмента ({attempt}/{max}) — прошу вызвать инструмент...',
|
|
101
|
+
en: '⏳ The model answered with plain text and no tool call ({attempt}/{max}) — asking for a tool call...',
|
|
102
102
|
},
|
|
103
103
|
'ds.not_launched': {
|
|
104
104
|
ru: '✖ Браузер не запущен.',
|
package/dist/i18n.js
CHANGED
|
@@ -37,7 +37,7 @@ export function normalizeLocale(v) {
|
|
|
37
37
|
return DEFAULT_LOCALE;
|
|
38
38
|
}
|
|
39
39
|
// String catalog. Key -> { ru, en }. If a key is missing we return the key itself.
|
|
40
|
-
// Split into section files
|
|
40
|
+
// Split into section files; merged here so callers keep importing
|
|
41
41
|
// CATALOG from a single place.
|
|
42
42
|
export const CATALOG = {
|
|
43
43
|
...commonMessages,
|
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function authMarkerExists(provider = config.provider) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
// ---------- CLI parsing ----------
|
|
80
|
-
// The pure helpers live in src/cli-args.ts
|
|
80
|
+
// The pure helpers live in src/cli-args.ts and are bound to this process's
|
|
81
81
|
// argv ONCE here. Call sites keep using getArg/hasFlag/getPositional.
|
|
82
82
|
const { getArg, hasFlag, getPositional } = createCliArgs(process.argv.slice(2));
|
|
83
83
|
// /compact asks the OLD chat for a summary. If browser.ask() exhausts its own
|
|
@@ -1274,7 +1274,7 @@ async function main() {
|
|
|
1274
1274
|
// Write the checklist whenever the agent changes it, so a restart/resume
|
|
1275
1275
|
// brings the tasks back (they used to be in-memory only).
|
|
1276
1276
|
todoStore.onChange = () => persistTodos();
|
|
1277
|
-
// Subagents
|
|
1277
|
+
// Subagents: the `Task` tool delegates a self-contained
|
|
1278
1278
|
// sub-task to a nested agent loop in its OWN chat (context isolation — in
|
|
1279
1279
|
// zames "context" IS the chat), then restores this chat and returns only
|
|
1280
1280
|
// the report. Sequential by design (one browser, one send slot). On by
|
|
@@ -4109,7 +4109,7 @@ async function main() {
|
|
|
4109
4109
|
task: finalTaskText,
|
|
4110
4110
|
workdir: currentWorkdir,
|
|
4111
4111
|
});
|
|
4112
|
-
//
|
|
4112
|
+
// Snapshot the working tree BEFORE the task so /rewind can
|
|
4113
4113
|
// undo the whole task in one step. Best-effort: create() never throws, so
|
|
4114
4114
|
// a missing tar cannot abort the task it was meant to protect. Skipped
|
|
4115
4115
|
// while reviewing a snapshot (workdir is a throwaway copy).
|
package/dist/input/layout.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// LineEditor (src/input.ts). No terminal access, no state: given a prompt, a
|
|
3
3
|
// buffer, a cursor and a width these compute the visual rows, the cursor
|
|
4
4
|
// position, the visible width (wide chars count 2) and the status formatting.
|
|
5
|
-
// Split out
|
|
5
|
+
// Split out so the geometry can be unit-tested without driving the
|
|
6
6
|
// real editor, and so the editor class keeps only render/key handling.
|
|
7
7
|
// All control characters are assembled from codes so the file has no
|
|
8
8
|
// "raw" ESC/CR/LF in string literals (see AGENTS.md).
|
package/dist/input/suggest.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// of the LineEditor's «/» hint list (src/input.ts). No terminal access and no
|
|
3
3
|
// editor state: given the buffer text and the command list these decide which
|
|
4
4
|
// commands to show, the visible window, and the Tab completion. Split out
|
|
5
|
-
//
|
|
5
|
+
// so the fuzzy match can be unit-tested without driving the editor.
|
|
6
6
|
import { SUGGEST_PAGE, isSubsequence, visLen, } from './layout.js';
|
|
7
7
|
/**
|
|
8
8
|
* The commands matching the current buffer. Shown only when the line starts
|
package/dist/input.js
CHANGED
|
@@ -9,7 +9,7 @@ import { NL, CR, ESC, PASTE_START, PASTE_END, SUGGEST_PAGE, pasteReplacement, ex
|
|
|
9
9
|
// The pure layout/formatting helpers (visual rows, cursor position, visible
|
|
10
10
|
// width, paste markers, token formatting) live in ./input/layout.js. They are
|
|
11
11
|
// re-exported here so every existing import from './input.js' keeps working,
|
|
12
|
-
// and so tests can import them from either module
|
|
12
|
+
// and so tests can import them from either module.
|
|
13
13
|
export { PASTE_MIN_LINES, SUGGEST_PAGE, isSubsequence, countPasteLines, formatPasteMarker, pasteReplacement, expandPastes, visRows, visLen, charWidth, layoutInput, tokenStatusLevel, formatTokenStatus, formatCompactTokens, splitPasteTail, truncateToWidth, wrapToWidth, CONTEXT_LIMIT, CONTEXT_YELLOW_PCT, CONTEXT_RED_PCT, } from './input/layout.js';
|
|
14
14
|
// PURE slash-command suggestion logic (match / paging / completion), split out
|
|
15
15
|
// of the class so the fuzzy match is unit-tested without driving the editor.
|
package/dist/mcp.js
CHANGED
|
@@ -180,8 +180,14 @@ export function jsonSchemaToParams(schema) {
|
|
|
180
180
|
// descriptions and enums. The flat map alone cannot convey them, and MCP
|
|
181
181
|
// tools (browser_snapshot, browser_click, ...) rely on them heavily.
|
|
182
182
|
export function describeParamsExternally(description, schema) {
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
// A JSON Schema may spell the object type as a LIST (`type: ['object']`, a
|
|
184
|
+
// zod-derived or nullable wrapper). Rejecting anything but the exact string
|
|
185
|
+
// 'object' silently dropped the schema — field descriptions and enums — from
|
|
186
|
+
// the model-facing tool description while the flat param map still listed
|
|
187
|
+
// the fields.
|
|
188
|
+
const raw = schema?.type;
|
|
189
|
+
const isObject = raw === 'object' || (Array.isArray(raw) && raw.includes('object'));
|
|
190
|
+
if (!schema || !isObject)
|
|
185
191
|
return description;
|
|
186
192
|
try {
|
|
187
193
|
const json = JSON.stringify(schema);
|
package/dist/path-token.js
CHANGED
|
@@ -89,7 +89,7 @@ function stripRefPunct(tok) {
|
|
|
89
89
|
t = t.slice(0, -1);
|
|
90
90
|
return t;
|
|
91
91
|
}
|
|
92
|
-
// Find all `@path` references in a task text
|
|
92
|
+
// Find all `@path` references in a task text. Returns the unique paths in
|
|
93
93
|
// order of appearance. A reference is an '@' at a word boundary followed by a
|
|
94
94
|
// token that looks like a file name/path (a known extension). Implemented
|
|
95
95
|
// without regular expressions, like extractPathToken, to keep the source free
|
package/dist/subagent.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadHooks, runLifecycleHooks } from './hooks.js';
|
|
2
2
|
import { markInternalChat } from './sessions.js';
|
|
3
|
-
// Subagent runner
|
|
3
|
+
// Subagent runner. A `Task` tool call from the model is handled
|
|
4
4
|
// by the agent loop as a SEAM (like onAutoCompact): it calls back into the
|
|
5
5
|
// caller, which owns the whole lifecycle. This module builds that callback.
|
|
6
6
|
//
|
|
@@ -101,17 +101,10 @@ export function createSubagentRunner(opts) {
|
|
|
101
101
|
// parent chat id) returned BEFORE anything ran, and charging those
|
|
102
102
|
// attempts burned the whole budget on runs that never started.
|
|
103
103
|
used++;
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
transcript?.log('subagent_start', {
|
|
109
|
-
type: req.type,
|
|
110
|
-
description: req.description || '',
|
|
111
|
-
promptChars: String(req.prompt || '').length,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
catch { }
|
|
104
|
+
// NOTE: `subagent_start` is NOT logged here. agent-loop already writes it
|
|
105
|
+
// for the `Task` seam (with the description and the prompt), so logging it
|
|
106
|
+
// here too put a DUPLICATE event for the same run into the transcript —
|
|
107
|
+
// /export rendered every delegation twice. The seam owns the event.
|
|
115
108
|
const subTools = buildTools(req.type === 'explore');
|
|
116
109
|
const taskText = subagentPersona(req.type) + '\n\n--- SUB-TASK ---\n' + req.prompt;
|
|
117
110
|
// Save the parent's send hooks: the nested loop OVERWRITES them on
|
package/dist/tools.js
CHANGED
|
@@ -70,6 +70,15 @@ export function createTools(workdir, { undo, todos, readOnly = false, subagents
|
|
|
70
70
|
if (v === undefined || v === null) {
|
|
71
71
|
throw new Error(`Missing required argument: ${name}. Add "${name}" to the tool call arguments and retry.`);
|
|
72
72
|
}
|
|
73
|
+
// The contract says `path: string`/`command: string`; nothing used to
|
|
74
|
+
// enforce it, so an OBJECT became "[object Object]" and the file tools
|
|
75
|
+
// CREATED a file with that literal name (the same family as the old
|
|
76
|
+
// `undefined` file). A garbled tool call is exactly this shape.
|
|
77
|
+
if (typeof v === 'object' || typeof v === 'function') {
|
|
78
|
+
throw new Error(`Invalid required argument ${name}: expected a string, got ` +
|
|
79
|
+
JSON.stringify(v) +
|
|
80
|
+
'. Re-send the call with a plain string value.');
|
|
81
|
+
}
|
|
73
82
|
const s = String(v);
|
|
74
83
|
if (s === '' || s === 'undefined' || s === 'null') {
|
|
75
84
|
throw new Error(`Invalid required argument ${name}: ${JSON.stringify(v)}. Provide a non-empty value for "${name}" and retry.`);
|
package/dist/tui/StatusBar.js
CHANGED
|
@@ -27,7 +27,7 @@ function stateLabel(state, locale) {
|
|
|
27
27
|
* status). Measured with the shared `visLen` so wide chars (CJK/emoji) count
|
|
28
28
|
* as 2 and the emoji's text-presentation selector (\uFE0E) as 0 — a plain
|
|
29
29
|
* `.length` counted an emoji as 1 and a CJK badge was clipped on a narrow
|
|
30
|
-
* terminal
|
|
30
|
+
* terminal. Exported so the width arithmetic is unit-tested
|
|
31
31
|
* without rendering. */
|
|
32
32
|
export function badgeTextWidth(state) {
|
|
33
33
|
let w = 0;
|
package/dist/web.js
CHANGED
|
@@ -654,22 +654,32 @@ export function parseDuckDuckGoResults(body, limit) {
|
|
|
654
654
|
// single regex made the snippet group OPTIONAL with an unbounded gap, so a
|
|
655
655
|
// result without a snippet picked up the FOLLOWING result's snippet (wrong
|
|
656
656
|
// text under a URL). A row scan ties every snippet to its own result.
|
|
657
|
-
|
|
657
|
+
// A result anchor is `<a … class="… result__a|result__snippet …" …>`. The
|
|
658
|
+
// attribute VALUES may be single-quoted (HTML allows both, and a page served
|
|
659
|
+
// through a proxy does), so each quote style is accepted rather than only
|
|
660
|
+
// `class="…"`. Rejecting them made a valid page parse to zero results and
|
|
661
|
+
// WebSearch answer "the output format may have changed".
|
|
662
|
+
const anchorRe = /<a[^>]*class=(?:"([^"]*)"|'([^']*)')[^>]*>([\s\S]*?)<\/a>/gi;
|
|
658
663
|
const hrefOf = (tag) => {
|
|
659
|
-
const m = tag.match(/href="([^"]*)"/i);
|
|
660
|
-
return m ? m[1] : '';
|
|
664
|
+
const m = tag.match(/href=(?:"([^"]*)"|'([^']*)')/i);
|
|
665
|
+
return m ? (m[1] ?? m[2] ?? '') : '';
|
|
661
666
|
};
|
|
662
667
|
let cur = null;
|
|
663
668
|
let m;
|
|
664
669
|
while ((m = anchorRe.exec(body))) {
|
|
665
|
-
const
|
|
670
|
+
const classes = m[1] ?? m[2] ?? '';
|
|
671
|
+
const kindMatch = /result__(a|snippet)/i.exec(classes);
|
|
672
|
+
if (!kindMatch)
|
|
673
|
+
continue;
|
|
674
|
+
const kind = kindMatch[1].toLowerCase();
|
|
675
|
+
const text = m[3] || '';
|
|
666
676
|
if (kind === 'a') {
|
|
667
677
|
if (cur && cur.title && /^https?:\/\//i.test(cur.url)) {
|
|
668
678
|
results.push(cur);
|
|
669
679
|
if (results.length >= limit)
|
|
670
680
|
return results;
|
|
671
681
|
}
|
|
672
|
-
cur = { title: htmlToText(
|
|
682
|
+
cur = { title: htmlToText(text).trim(), url: '', snippet: '' };
|
|
673
683
|
// The href lives in the OPENING tag, which m[0] starts with.
|
|
674
684
|
let href = hrefOf(m[0].slice(0, m[0].indexOf('>') + 1));
|
|
675
685
|
const uddg = href.match(/[?&]uddg=([^&]+)/);
|
|
@@ -685,7 +695,7 @@ export function parseDuckDuckGoResults(body, limit) {
|
|
|
685
695
|
continue;
|
|
686
696
|
}
|
|
687
697
|
if (cur && !cur.snippet)
|
|
688
|
-
cur.snippet = htmlToText(
|
|
698
|
+
cur.snippet = htmlToText(text).trim();
|
|
689
699
|
}
|
|
690
700
|
if (cur && cur.title && /^https?:\/\//i.test(cur.url))
|
|
691
701
|
results.push(cur);
|