返回 DeepSeek-TUI-2026
TOOL_SURFACE.md
根目录 / docs / TOOL_SURFACE.md
1 # Tool surface
2
3 Why these specific tools, in this groupings, and how each one is meant to be
4 chosen over the available shell equivalent. Companion to `crates/tui/src/prompts/agent.txt`.
5
6 ## Design stance
7
8 - **Dedicated tools over `exec_shell` whenever the dedicated tool returns
9 structured output.** Bash escaping is error-prone and platform behavior
10 varies (GNU vs BSD `grep`, `rg` is not always installed). Structured
11 output also frees the model from re-parsing free-form text.
12 - **`exec_shell` for everything else.** Build, test, format, lint, ad-hoc
13 commands, anything platform-specific. We don't try to wrap the long tail.
14 - **Drop tools that don't beat their shell equivalent.** Two-tool aliases
15 for the same backing operation are a model trap — the LLM will alternate
16 between them and the cache hit rate suffers.
17
18 ## Current surface (v0.7.5)
19
20 ### File operations
21
22 | Tool | Niche |
23 |---|---|
24 | `read_file` | Read a UTF-8 file. PDFs auto-extracted via `pdftotext` (poppler) when available; `pages: "1-5"` slices large docs. |
25 | `list_dir` | Structured, gitignore-aware listing. Preferred over `exec_shell("ls")`. |
26 | `write_file` | Create or overwrite a file. |
27 | `edit_file` | Search-and-replace inside a single file. Cheaper than a full rewrite. |
28 | `apply_patch` | Apply a unified diff. The right tool for multi-hunk edits. |
29
30 ### Search
31
32 | Tool | Niche |
33 |---|---|
34 | `grep_files` | Regex search file contents within the workspace; structured matches + context lines. Pure-Rust (`regex` crate), no `rg`/`grep` shell-out. |
35 | `file_search` | Fuzzy-match filenames (not contents). Use when you know roughly the name. |
36 | `web_search` | DuckDuckGo (with Bing fallback); ranked snippets + `ref_id` for citation. |
37 | `fetch_url` | Direct HTTP GET on a known URL. Faster than `web_search` when the link is already known. HTML stripped to text by default. |
38
39 ### Shell
40
41 | Tool | Niche |
42 |---|---|
43 | `exec_shell` | Run a shell command. Foreground runs are cancellable, but use them only for bounded commands; timeout kills the process and returns a background-rerun hint. |
44 | `exec_shell_wait` | Poll a background task for incremental output. Canceling the turn stops waiting without killing the task. |
45 | `exec_shell_interact` | Send stdin to a running background task and read incremental output. |
46 | `exec_shell_cancel` | Cancel one running background shell task by id, or all running background shell tasks when explicitly requested. |
47 | `task_shell_start` | Start a long-running command in the background and return immediately. Preferred over foreground shell for diagnostics, tests, searches, and servers that may run for minutes. |
48 | `task_shell_wait` | Poll a background command. If `gate` is supplied after completion, record structured gate evidence on the active durable task. |
49
50 When a foreground shell command times out, the process is not continued
51 silently. The tool result tells the model to rerun long work with
52 `task_shell_start` or `exec_shell` with `background = true`, then poll with
53 `task_shell_wait` or `exec_shell_wait`.
54
55 Interactive shell jobs are also visible through `/jobs`. The TUI job center is
56 fed by the same shell manager as `exec_shell`/`task_shell_start`, and shows the
57 command, cwd, elapsed time, status, output tail, process-local shell id, and
58 linked durable task id when available. `/jobs show`, `/jobs poll`, `/jobs wait`,
59 `/jobs stdin`, and `/jobs cancel` provide inspect, polling, stdin, and cancel
60 controls for live jobs. Jobs are process-local; after restart, live process
61 state is not reattached, and any remembered detached entries must be marked
62 stale rather than presented as live processes.
63
64 ### MCP manager and palette discovery
65
66 MCP server configuration is surfaced in the TUI through `/mcp` and the
67 `mcp_config_path` row in `/config`. `/mcp` shows the resolved config path,
68 server enabled/disabled state, transport, command or URL, timeouts, connection
69 errors, and discovered tools/resources/prompts. It supports narrow manager
70 actions for init, add, enable, disable, remove, validate, and reload/reconnect.
71 Config edits are written immediately, but the model-visible MCP tool pool is
72 restart-required after edits.
73
74 The command palette includes MCP entries grouped by server. Disabled and failed
75 servers stay visible, and discovered tools/prompts use the runtime names shown
76 to the model, such as `mcp_<server>_<tool>`.
77
78 ### Git / diagnostics / testing
79
80 | Tool | Niche |
81 |---|---|
82 | `git_status` | Inspect repo status without running shell. |
83 | `git_diff` | Inspect working-tree or staged diffs. |
84 | `diagnostics` | Workspace, git, sandbox, and toolchain info in one call. |
85 | `run_tests` | `cargo test` with optional args. |
86
87 ### Task management and durable work
88
89 | Tool | Niche |
90 |---|---|
91 | `update_plan` | Structured checklist for complex multi-step work. |
92 | `task_create` | Create/enqueue a durable background task through `TaskManager`. This is the real executable work object for long-running agent work. |
93 | `task_list` | List durable tasks with status and linked runtime ids. |
94 | `task_read` | Read durable task detail: thread/turn linkage, timeline, checklist, gates, artifacts, PR attempts, GitHub events. |
95 | `task_cancel` | Cancel a queued or running durable task. Approval-required. |
96 | `checklist_write` | Granular progress under the active thread/task. Checklist state is subordinate to the durable task. |
97 | `checklist_add` / `checklist_update` / `checklist_list` | Single-item checklist operations. |
98 | `todo_write` / `todo_add` / `todo_update` / `todo_list` | Compatibility aliases for the checklist tools. Existing sessions keep working, but new prompts should use `checklist_*`. |
99 | `note` | One-off important fact for later. |
100
101 ### Verification gates and artifacts
102
103 | Tool | Niche |
104 |---|---|
105 | `task_gate_run` | Run an approved verification command and attach structured evidence to the active durable task: command, cwd, exit code, duration, classification, summary, and log artifact. |
106
107 Large logs and command outputs should be artifacts with compact summaries in the transcript. `task_gate_run` handles this automatically for active durable tasks.
108
109 ### GitHub context and guarded writes
110
111 | Tool | Niche |
112 |---|---|
113 | `github_issue_context` | Read-only issue context via `gh issue view`; large bodies become task artifacts when possible. |
114 | `github_pr_context` | Read-only PR context via `gh pr view`; optional diff capture via `gh pr diff --patch`; large bodies/diffs become task artifacts when possible. |
115 | `github_comment` | Approval-required issue/PR comment with structured evidence. |
116 | `github_close_issue` | Approval-required issue closure. Requires non-empty acceptance criteria and evidence; refuses dirty worktrees unless explicitly allowed. Never close an issue merely because an agent is stopping. |
117
118 ### PR attempts
119
120 | Tool | Niche |
121 |---|---|
122 | `pr_attempt_record` | Capture the current git diff as attempt metadata plus a patch artifact on a durable task. |
123 | `pr_attempt_list` | List attempts recorded on a task. |
124 | `pr_attempt_read` | Inspect one recorded attempt and its artifact reference. |
125 | `pr_attempt_preflight` | Run `git apply --check` against an attempt patch. No worktree mutation. |
126
127 ### Automations
128
129 | Tool | Niche |
130 |---|---|
131 | `automation_create` | Create a scheduled automation. Approval-required. |
132 | `automation_list` / `automation_read` | Inspect durable automations and recent runs. |
133 | `automation_update` | Update prompt, schedule, cwds, or status. Approval-required. |
134 | `automation_pause` / `automation_resume` / `automation_delete` | Lifecycle controls. Approval-required. |
135 | `automation_run` | Run an automation now; the run enqueues a normal durable task. Approval-required. |
136
137 ### Sub-agents
138
139 `agent_spawn` plus the supporting tools (`agent_result` / `wait` / `send_input` /
140 `agent_assign` / `agent_cancel` / `resume_agent` / `agent_list`).
141 See `agent.txt` for the delegation protocol and
142 [`SUBAGENTS.md`](SUBAGENTS.md) for the role taxonomy
143 (`general` / `explore` / `plan` / `review` / `implementer` /
144 `verifier` / `custom`).
145
146 ### Parallel fan-out: cost-class caps
147
148 Two tools offer parallel fan-out with different concurrency limits that
149 reflect very different cost classes:
150
151 | Tool | What each child does | Wall-clock | Token cost | Cap |
152 |---|---|---|---|---|
153 | `agent_spawn` | Full sub-agent loop (planning, tool calls, multi-turn streaming, can spawn children) | minutes | thousands of tokens | 10 in flight by default (`[subagents].max_concurrent`, hard ceiling 20) |
154 | `rlm` helper `llm_query_batched` | One-shot non-streaming Chat Completions calls pinned to `deepseek-v4-flash` | seconds | ~hundreds of tokens | 16 per call |
155
156 The caps appear in each tool's description and error messages so the model
157 (and the user) can choose the right tool for the job. If one sub-agent is
158 enough but you need parallel lookups, prefer `rlm` with `llm_query_batched`; if each task needs
159 its own tool-carrying agent loop, use `agent_spawn` (and cancel completed
160 ones to free slots).
161
162 ## Recently consolidated (v0.5.1)
163
164 Removed from the prompt as duplicates of equivalent tools (the underlying
165 dispatchers still resolve them, so existing sessions don't break — they just
166 no longer pollute the model's tool list):
167
168 - `spawn_agent` → use `agent_spawn`.
169 - `close_agent` → use `agent_cancel`.
170 - `assign_agent` → use `agent_assign`.
171
172 ## Deprecation schedule (v0.6.2 → v0.8.0)
173
174 The alias tools below still execute successfully but now attach a
175 `_deprecation` block to every result they return. Models should migrate to
176 the canonical name before v0.8.0, when the aliases will be removed.
177
178 | Deprecated alias | Canonical name | Warning since | Removal |
179 |---|---|---|---|
180 | `spawn_agent` | `agent_spawn` | v0.6.2 | v0.8.0 |
181 | `delegate_to_agent` | `agent_spawn` | v0.6.2 | v0.8.0 |
182 | `close_agent` | `agent_cancel` | v0.6.2 | v0.8.0 |
183 | `send_input` | `agent_send_input` | v0.6.2 | v0.8.0 |
184
185 The `_deprecation` block shape:
186
187 ```json
188 {
189 "_deprecation": {
190 "this_tool": "spawn_agent",
191 "use_instead": "agent_spawn",
192 "removed_in": "0.8.0",
193 "message": "Tool 'spawn_agent' is deprecated; switch to 'agent_spawn' before v0.8.0."
194 }
195 }
196 ```
197
198 This block is merged into the tool result's `metadata` object alongside any
199 other metadata keys (e.g. `status`, `timed_out`) so it does not displace
200 existing metadata. A one-line deprecation warning is also emitted to the
201 audit log at `tracing::warn` level every time an alias is invoked.
202
203 ## Why we don't ship a single `bash` tool
204
205 Single-`bash` agents (Claude Code's design) are powerful but hand the model
206 all the foot-guns of shell scripting: quoting, platform divergence,
207 side-effects from misread cwd, `cd` not persisting between calls, etc. Our
208 file tools are also significantly cheaper to render in the transcript
209 (structured JSON-shaped output collapses better than `ls -la` walls of text).
210
211 The model can always fall back to `exec_shell` when something is missing.
212 The dedicated tools just take the common 80% off the shell escape-hatch.
213
213 lines MARKDOWN