zames_pro 1.1.1 → 1.2.1
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 +5 -0
- package/package.json +1 -1
- package/src/agent-loop.js +99 -12
- package/src/browser.js +22 -0
- package/src/config.js +1 -0
- package/src/index.js +403 -109
- package/src/input.js +447 -0
- package/src/sessions.js +110 -0
- package/src/spinner.js +60 -2
- package/src/system-prompt.js +39 -5
- package/src/theme.js +1 -0
- package/src/xml-toolcall.js +69 -0
package/src/system-prompt.js
CHANGED
|
@@ -14,6 +14,34 @@ export function buildSystemPrompt({ workdir, tools, gitContext = null }) {
|
|
|
14
14
|
|
|
15
15
|
You work in the directory: ${workdir}
|
|
16
16
|
|
|
17
|
+
## SILENT OPERATION (most important rule)
|
|
18
|
+
|
|
19
|
+
Work silently. While you are still solving the task you must output ONLY
|
|
20
|
+
tool calls — nothing else. Do NOT narrate what you are about to do, do NOT
|
|
21
|
+
summarize what you just did, do NOT think out loud, do NOT print progress
|
|
22
|
+
like "Now I will read the file...". Every extra sentence pollutes the chat
|
|
23
|
+
and the context, so keep it to zero.
|
|
24
|
+
|
|
25
|
+
The operator does NOT read free text in the chat. Anything written outside a
|
|
26
|
+
tool call is lost: the operator only sees tool calls and their results. In
|
|
27
|
+
particular, the operator reads EXACTLY ONE thing from you — the message of the
|
|
28
|
+
LAST respond tool call before you stop. Everything else is ignored.
|
|
29
|
+
|
|
30
|
+
Therefore the only way to talk to the operator is the respond tool, and it
|
|
31
|
+
must be your LAST action. Call respond in exactly two situations:
|
|
32
|
+
1. The task is done — report the result.
|
|
33
|
+
2. You cannot continue and must ask the operator a question or a decision.
|
|
34
|
+
|
|
35
|
+
Never call respond in the middle, and never split a report across several
|
|
36
|
+
messages: put the complete operator-facing text into that single final
|
|
37
|
+
respond. Do NOT end a turn with plain text, and do NOT rely on plain text to
|
|
38
|
+
ask or answer anything — if you have something to say, say it via respond and
|
|
39
|
+
stop. If you are still working, emit a tool call instead.
|
|
40
|
+
|
|
41
|
+
So the pattern is: tool call, tool call, tool call, ..., then a single final
|
|
42
|
+
respond. A bare text message without a tool call ends the task and the
|
|
43
|
+
operator will not read it, so never use plain text.\n\nNO PROSE AROUND TOOL CALLS. Each turn must contain ONLY the JSON of the tool\ncall(s) — not a single word before or after, not even a short lead-in like\n"Let me check..." or "Now I'll fix it.". The JSON must be the entire response.\n\nWRONG: "Let me read the file first." then a Read call.\nWRONG: a Read call then "I'll analyze the result next."\nRIGHT: only the JSON of the tool call, nothing else.\n\nIf you feel the urge to explain, do not: put it in the final respond when the\ntask is done (or when you must ask the operator), not between tool calls.
|
|
44
|
+
|
|
17
45
|
You have access to the following tools:
|
|
18
46
|
|
|
19
47
|
${toolDescriptions}
|
|
@@ -28,7 +56,9 @@ To call MULTIPLE tools at once (only if they are independent — e.g. reading se
|
|
|
28
56
|
|
|
29
57
|
[{"tool": "Read", "args": {"path": "a.js"}}, {"tool": "Read", "args": {"path": "b.js"}}]
|
|
30
58
|
|
|
31
|
-
After the tool result(s) come back, decide the next action
|
|
59
|
+
After the tool result(s) come back, decide the next action and immediately
|
|
60
|
+
emit the next tool call as bare JSON. Do NOT write a sentence about what
|
|
61
|
+
you learned or what you will do next — no commentary between tool calls.
|
|
32
62
|
|
|
33
63
|
To give a final answer to the user, respond with:
|
|
34
64
|
|
|
@@ -68,9 +98,9 @@ Inside that string:
|
|
|
68
98
|
- Do NOT write any text before or after the JSON. No explanations, no greetings, no plans.
|
|
69
99
|
- Do NOT wrap JSON in markdown fences.
|
|
70
100
|
- Do NOT use XML-like tags such as tool_calls, invoke, parameter, or their DSML variants.
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
for newlines.
|
|
101
|
+
- The ONLY way to reach the operator is the respond tool, as your LAST action.
|
|
102
|
+
Any other text is not read by the operator.
|
|
103
|
+
- If JSON parsing fails, the tool call will NOT run and the user will see raw text. Keep JSON valid: escape every double quote inside strings, escape backslashes, use \n for newlines.
|
|
74
104
|
|
|
75
105
|
## Rules
|
|
76
106
|
|
|
@@ -82,7 +112,11 @@ Inside that string:
|
|
|
82
112
|
- Never output anything except JSON when you want to call a tool.
|
|
83
113
|
- Your ENTIRE response must be exactly one JSON object (or array of objects).
|
|
84
114
|
|
|
85
|
-
REMINDER:
|
|
115
|
+
REMINDER: every intermediate response is exactly one JSON object or array —
|
|
116
|
+
no text, no markdown, no explanations, no progress narration. Keep working
|
|
117
|
+
with tool calls only. Talk to the operator with a single final respond call:
|
|
118
|
+
when the task is done, or when you are blocked and must ask the operator.
|
|
119
|
+
Anything you write outside that one respond is not read by the operator.
|
|
86
120
|
## Web access
|
|
87
121
|
|
|
88
122
|
- You have WebSearch and WebFetch. Use them when the answer requires current information (versions, changelogs, recent bugs, docs).
|
package/src/theme.js
CHANGED
|
@@ -28,6 +28,7 @@ export const theme = {
|
|
|
28
28
|
warn: chalk.hex('#c9a86a'), // спокойный охра
|
|
29
29
|
error: chalk.hex('#c98a80'), // приглушённый терракот
|
|
30
30
|
success: chalk.hex('#a9c08c'), // мягкий шалфейный
|
|
31
|
+
brown: chalk.hex('#a1723f'), // коричневый (статус/спиннер)
|
|
31
32
|
bold: chalk.bold,
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
function unescapeXml(s) {
|
|
2
|
+
const A = String.fromCharCode(38) // ampersand
|
|
3
|
+
return String(s)
|
|
4
|
+
.split(A + "lt;").join(String.fromCharCode(60))
|
|
5
|
+
.split(A + "gt;").join(String.fromCharCode(62))
|
|
6
|
+
.split(A + "quot;").join(String.fromCharCode(34))
|
|
7
|
+
.split(A + "apos;").join(String.fromCharCode(39))
|
|
8
|
+
.split(A + "amp;").join(A)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function readAttr(attrs, name) {
|
|
12
|
+
const Q = String.fromCharCode(34)
|
|
13
|
+
const re = new RegExp(name + "[ ]*=[ ]*([" + Q + "]([^" + Q + "]*)[" + Q + "])")
|
|
14
|
+
const m = attrs.match(re)
|
|
15
|
+
return m ? m[2] : null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function parseXmlToolCalls(text) {
|
|
19
|
+
if (!text || typeof text !== "string") return null
|
|
20
|
+
if (!/<[^>]*invoke/i.test(text)) return null
|
|
21
|
+
|
|
22
|
+
const invokeRe = /<[^>]*?invoke([^>]*)>/gi
|
|
23
|
+
const calls = []
|
|
24
|
+
let m
|
|
25
|
+
while ((m = invokeRe.exec(text)) !== null) {
|
|
26
|
+
const attrs = m[1] || ""
|
|
27
|
+
const name = readAttr(attrs, "name")
|
|
28
|
+
if (!name) continue
|
|
29
|
+
|
|
30
|
+
const rest = text.slice(invokeRe.lastIndex)
|
|
31
|
+
const closeRe = /<\/[^>]*?invoke[^>]*>/i
|
|
32
|
+
const closeMatch = closeRe.exec(rest)
|
|
33
|
+
const body = closeMatch ? rest.slice(0, closeMatch.index) : rest
|
|
34
|
+
|
|
35
|
+
const args = {}
|
|
36
|
+
const paramRe = /<[^>]*?parameter([^>]*)>([\s\S]*?)<\/[^>]*?parameter[^>]*>/gi
|
|
37
|
+
let p
|
|
38
|
+
while ((p = paramRe.exec(body)) !== null) {
|
|
39
|
+
const pname = readAttr(p[1] || "", "name")
|
|
40
|
+
if (!pname) continue
|
|
41
|
+
const isString = /string[ ]*=[ ]*"?true"?/i.test(p[1] || "")
|
|
42
|
+
let value = unescapeXml(p[2])
|
|
43
|
+
if (!isString) {
|
|
44
|
+
try { value = JSON.parse(value) } catch (e) {}
|
|
45
|
+
}
|
|
46
|
+
args[pname] = value
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Некоторые модели кладут весь JSON-объект аргументов в один
|
|
50
|
+
// parameter с именем args. Разворачиваем, чтобы не было
|
|
51
|
+
// {args: {args: {...}}}.
|
|
52
|
+
let finalArgs = args
|
|
53
|
+
const keys = Object.keys(args)
|
|
54
|
+
if (
|
|
55
|
+
keys.length === 1 &&
|
|
56
|
+
keys[0] === 'args' &&
|
|
57
|
+
args.args &&
|
|
58
|
+
typeof args.args === 'object' &&
|
|
59
|
+
!Array.isArray(args.args)
|
|
60
|
+
) {
|
|
61
|
+
finalArgs = args.args
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
calls.push({ tool: name, args: finalArgs })
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!calls.length) return null
|
|
68
|
+
return calls.length === 1 ? calls[0] : calls
|
|
69
|
+
}
|