@semalt-ai/code 1.8.1 → 1.8.4
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/.claude/settings.local.json +14 -1
- package/CLAUDE.md +2 -1
- package/index.js +29 -8
- package/lib/agent.js +725 -133
- package/lib/api.js +193 -59
- package/lib/commands.js +263 -201
- package/lib/config.js +33 -4
- package/lib/constants.js +52 -2
- package/lib/metrics.js +16 -3
- package/lib/permissions.js +73 -73
- package/lib/prompts.js +90 -86
- package/lib/tool_specs.js +499 -0
- package/lib/tools.js +418 -198
- package/lib/ui/ansi.js +13 -1
- package/lib/ui/chat-history.js +212 -61
- package/lib/ui/create-ui.js +145 -377
- package/lib/ui/diff.js +91 -78
- package/lib/ui/format.js +247 -0
- package/lib/ui/input-field.js +200 -107
- package/lib/ui/layout.js +0 -2
- package/lib/ui/messages.js +44 -0
- package/lib/ui/select.js +114 -0
- package/lib/ui/status-bar.js +179 -42
- package/lib/ui/stream.js +8 -12
- package/lib/ui/terminal.js +60 -0
- package/lib/ui/theme.js +99 -0
- package/lib/ui/utils.js +135 -6
- package/lib/ui/writer.js +603 -0
- package/lib/ui.js +11 -6
- package/package.json +1 -1
- package/lib/ui/legacy.js +0 -130
package/lib/prompts.js
CHANGED
|
@@ -1,112 +1,116 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<replace_in_file path="/path/to/file" search="old pattern" replace="new text"></replace_in_file>
|
|
48
|
-
|
|
49
|
-
To replace a specific line in a file:
|
|
50
|
-
<edit_file path="/path/to/file" line="42">replacement line content</edit_file>
|
|
51
|
-
|
|
52
|
-
To fetch a URL over HTTP or HTTPS (HTML pages are auto-converted to plain text):
|
|
53
|
-
<http_get url="https://example.com/api/data"></http_get>
|
|
54
|
-
|
|
55
|
-
To fetch raw HTML when you need to parse markup, extract links, or inspect structure:
|
|
56
|
-
<http_get url="https://example.com/" raw="true"></http_get>
|
|
57
|
-
|
|
58
|
-
If the response is large it will be delivered in numbered parts. To retrieve the next part:
|
|
59
|
-
<http_get_next key="https://example.com/api/data"/>
|
|
60
|
-
|
|
61
|
-
To download a file from a URL (saved to current directory):
|
|
62
|
-
<download>https://example.com/file.zip</download>
|
|
63
|
-
|
|
64
|
-
To write base64-encoded content to a file:
|
|
65
|
-
<upload path="/path/to/file">base64encodedcontent</upload>
|
|
66
|
-
|
|
67
|
-
To ask the user a question and receive their typed answer:
|
|
68
|
-
<ask_user question="Which directory should I use?"></ask_user>
|
|
3
|
+
const { TAG_REGISTRY } = require('./constants');
|
|
4
|
+
|
|
5
|
+
const WRAPPER_NAMES = new Set([
|
|
6
|
+
'minimax:tool_call',
|
|
7
|
+
'qwen:tool_call',
|
|
8
|
+
'invoke',
|
|
9
|
+
'parameter',
|
|
10
|
+
'tool_call',
|
|
11
|
+
'function_call',
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
// For each tool tag: required attributes and a one-line purpose.
|
|
15
|
+
// Required attributes are derived from the matchers in `extractToolCalls`
|
|
16
|
+
// (lib/tools.js). Where a tag accepts either an attribute or inline content,
|
|
17
|
+
// the attribute is marked optional.
|
|
18
|
+
const TOOL_TAG_SPECS = {
|
|
19
|
+
exec: { attrs: [], purpose: 'Run a shell command (inline content).' },
|
|
20
|
+
shell: { attrs: [], purpose: 'Run a shell command (inline content).' },
|
|
21
|
+
read_file: { attrs: ['path?'], purpose: 'Read a file (path attr or inline content).' },
|
|
22
|
+
write_file: { attrs: ['path'], purpose: 'Write file with inline content (overwrites).' },
|
|
23
|
+
create_file: { attrs: ['path'], purpose: 'Create file with inline content.' },
|
|
24
|
+
append_file: { attrs: ['path'], purpose: 'Append inline content to file.' },
|
|
25
|
+
delete_file: { attrs: [], purpose: 'Delete a file (inline content = path).' },
|
|
26
|
+
list_dir: { attrs: [], purpose: 'List directory contents (inline content = path).' },
|
|
27
|
+
make_dir: { attrs: [], purpose: 'Create directory recursively (inline content = path).' },
|
|
28
|
+
remove_dir: { attrs: [], purpose: 'Remove directory recursively (inline content = path).' },
|
|
29
|
+
move_file: { attrs: ['src', 'dst'], purpose: 'Move or rename a file.' },
|
|
30
|
+
copy_file: { attrs: ['src', 'dst'], purpose: 'Copy a file.' },
|
|
31
|
+
file_stat: { attrs: [], purpose: 'Stat a file (inline content = path).' },
|
|
32
|
+
edit_file: { attrs: ['path', 'line'], purpose: 'Replace a single line in a file (inline content = new line).' },
|
|
33
|
+
search_files: { attrs: ['pattern?', 'dir?'], purpose: 'Find files by glob pattern.' },
|
|
34
|
+
search_in_file: { attrs: ['path'], purpose: 'Regex search inside a file (inline content = pattern).' },
|
|
35
|
+
replace_in_file: { attrs: ['path', 'search', 'replace'], purpose: 'Regex replace inside a file.' },
|
|
36
|
+
get_env: { attrs: [], purpose: 'Read an env var (inline content = name).' },
|
|
37
|
+
set_env: { attrs: ['name', 'value'], purpose: 'Set an env var for this process.' },
|
|
38
|
+
download: { attrs: [], purpose: 'HTTP download to the CWD (inline content = URL).' },
|
|
39
|
+
upload: { attrs: ['path'], purpose: 'Write base64-encoded content to file.' },
|
|
40
|
+
http_get: { attrs: ['url'], purpose: 'HTTP GET; returns the response body (truncated to a byte cap with an explicit notice when oversized).' },
|
|
41
|
+
ask_user: { attrs: ['question'], purpose: 'Ask the user a question and receive an answer.' },
|
|
42
|
+
store_memory: { attrs: ['key'], purpose: 'Persist a key/value to local memory (inline content = value).' },
|
|
43
|
+
recall_memory: { attrs: ['key'], purpose: 'Read a key from local memory.' },
|
|
44
|
+
list_memories: { attrs: [], purpose: 'List memory keys.' },
|
|
45
|
+
system_info: { attrs: [], purpose: 'Return platform, arch, host, memory, node version, cwd.' },
|
|
46
|
+
};
|
|
69
47
|
|
|
70
|
-
|
|
71
|
-
|
|
48
|
+
function buildTagInventory() {
|
|
49
|
+
const lines = [];
|
|
50
|
+
for (const tag of Object.keys(TAG_REGISTRY)) {
|
|
51
|
+
const entry = TAG_REGISTRY[tag];
|
|
52
|
+
if (entry.type !== 'tool') continue;
|
|
53
|
+
if (WRAPPER_NAMES.has(tag)) continue;
|
|
54
|
+
const spec = TOOL_TAG_SPECS[tag] || { attrs: [], purpose: '' };
|
|
55
|
+
const attrPart = spec.attrs.length
|
|
56
|
+
? ` [attrs: ${spec.attrs.join(', ')}]`
|
|
57
|
+
: '';
|
|
58
|
+
lines.push(`- <${tag}>${attrPart} — ${spec.purpose}`);
|
|
59
|
+
}
|
|
60
|
+
return lines.join('\n');
|
|
61
|
+
}
|
|
72
62
|
|
|
73
|
-
|
|
74
|
-
<recall_memory key="project_name"></recall_memory>
|
|
63
|
+
const TAG_INVENTORY = buildTagInventory();
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
<list_memories></list_memories>
|
|
65
|
+
const SYSTEM_PROMPT_TEMPLATE = `You are Semalt.AI, an expert AI coding assistant running in the user's terminal. You have the ability to execute shell commands and file operations.
|
|
78
66
|
|
|
79
|
-
|
|
80
|
-
<system_info></system_info>
|
|
67
|
+
## Available tool tags:
|
|
81
68
|
|
|
82
|
-
|
|
83
|
-
<get_env>VARIABLE_NAME</get_env>
|
|
69
|
+
${TAG_INVENTORY}
|
|
84
70
|
|
|
85
|
-
|
|
86
|
-
<set_env name="VARIABLE_NAME" value="value"/>
|
|
71
|
+
## Tool call syntax — use EXACTLY these forms:
|
|
87
72
|
|
|
88
|
-
|
|
89
|
-
|
|
73
|
+
- Single-value inline-content tags: put the value directly between the tags as plain text. **Do NOT nest pseudo-tags like \`<path>\`, \`<command>\`, \`<url>\`, \`<key>\`, \`<name>\`, \`<pattern>\`, or \`<question>\` inside the body** — the parser treats the body as the literal value.
|
|
74
|
+
- Correct: \`<list_dir>/tmp/foo</list_dir>\`, \`<shell>ls -la</shell>\`, \`<read_file>/etc/hosts</read_file>\`, \`<download>https://x.com/f.zip</download>\`
|
|
75
|
+
- Wrong: \`<list_dir><path>/tmp/foo</path></list_dir>\`, \`<shell><command>ls</command></shell>\`
|
|
76
|
+
- Attribute tags: parameters go as quoted attributes on the opening tag; the body is either empty (self-closed) or real payload content (e.g. file bytes for \`write_file\`).
|
|
77
|
+
- Correct: \`<write_file path="/tmp/a.txt">actual file contents here</write_file>\`, \`<http_get url="https://example.com"/>\`, \`<move_file src="/a" dst="/b"/>\`
|
|
78
|
+
- Wrong: \`<write_file><path>/tmp/a.txt</path><content>...</content></write_file>\`
|
|
90
79
|
|
|
91
80
|
## Reasoning vs planning — IMPORTANT:
|
|
92
81
|
|
|
93
82
|
- Your internal chain-of-thought reasoning uses your native \`<think>...</think>\` block. Use it normally for deliberation. Do NOT treat \`<think>\` as a user-facing tool and do NOT try to emit \`<think>\` as an action — it is reserved for your own reasoning and is handled by the runtime.
|
|
94
83
|
- When you need to explicitly record a short plan that the agent framework can see (for logging or hand-off between steps), use \`<plan>...</plan>\` instead. \`<plan>\` is a tool tag; \`<think>\` is not.
|
|
95
|
-
- Never emit \`<think>\` as
|
|
84
|
+
- Never emit \`<think>\` as an action. The valid action tags are the ones listed above.
|
|
96
85
|
|
|
97
86
|
## STRICT RULES — follow exactly:
|
|
98
87
|
|
|
99
|
-
1.
|
|
88
|
+
1. Emit tool tags as needed. If a step depends on a prior tool's result, wait for the result before the next call. Independent tool calls may be batched in a single response.
|
|
100
89
|
2. **Always end your response with exactly one action tag** whenever the task is not yet complete. Do NOT end a response with only prose like "Let me create the files…" — that prose must be immediately followed by the actual tool tag in the same response. Preamble without a tool tag is a bug.
|
|
101
90
|
3. Only use the exact tag names listed above. Unknown tag names will not be executed.
|
|
102
91
|
4. When the user asks you to do something on their system, USE the tools — do NOT just print instructions.
|
|
103
92
|
5. Each action will be shown to the user for approval before execution.
|
|
104
93
|
6. After execution you will receive the result and can proceed with the next action in a new response.
|
|
105
94
|
7. Be concise. Provide working solutions. Use markdown for code blocks in explanations.
|
|
106
|
-
8.
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
8. Current working directory: __CWD__
|
|
96
|
+
|
|
97
|
+
Response contract:
|
|
98
|
+
- If the task requires an action, emit the appropriate tool tag(s) — do not narrate intended actions in prose without the tag.
|
|
99
|
+
- If the task is complete or the user's question can be answered directly without running a tool, reply in plain prose. No special wrapper is needed.`;
|
|
100
|
+
|
|
101
|
+
const NATIVE_SYSTEM_PROMPT_TEMPLATE = `You are Semalt.AI, an expert AI coding assistant running in the user's terminal. Use the provided tools to execute shell commands and file operations; do not just print instructions. Each call is approved by the user before execution, and the result is returned to you for the next step.
|
|
102
|
+
|
|
103
|
+
Use \`<think>...</think>\` for internal reasoning (runtime-handled; never emit as an action). Use \`<plan>...</plan>\` to record a short plan for the agent framework.
|
|
104
|
+
|
|
105
|
+
Be concise. Use markdown for code blocks in explanations. Current working directory: __CWD__
|
|
106
|
+
|
|
107
|
+
Response contract: if the task requires an action, emit one or more tool calls — do not narrate intended actions in prose without the tool call. Otherwise, answer in plain prose; no special wrapper is needed.`;
|
|
108
|
+
|
|
109
|
+
function getSystemPrompt(nativeTools = false) {
|
|
110
|
+
const template = nativeTools ? NATIVE_SYSTEM_PROMPT_TEMPLATE : SYSTEM_PROMPT_TEMPLATE;
|
|
111
|
+
return template.replace('__CWD__', process.cwd());
|
|
112
|
+
}
|
|
109
113
|
|
|
110
114
|
module.exports = {
|
|
111
|
-
|
|
115
|
+
getSystemPrompt,
|
|
112
116
|
};
|