Files
codewhale/docs/TOOL_SURFACE.md
T
Hunter Bown c58d10ded1 feat(tools): mark alias tools with deprecation metadata
Add `wrap_with_deprecation_notice` helper in the subagent module that
merges a `_deprecation` block into a ToolResult's metadata. Applied
exclusively on alias invocations:

- `spawn_agent` → use `agent_spawn` (removed in v0.8.0)
- `delegate_to_agent` → use `agent_spawn` (removed in v0.8.0)
- `close_agent` → use `agent_cancel` (removed in v0.8.0)
- `send_input` → use `agent_send_input` (removed in v0.8.0)

Canonical names are unaffected. Each alias invocation also emits a
`tracing::warn` so the deprecation appears in audit logs. Documents
the deprecation schedule in `docs/TOOL_SURFACE.md`. Four unit tests
verify the notice shape and that canonical tools stay clean.

Refs #72

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 12:32:26 -05:00

4.9 KiB

Tool surface

Why these specific tools, in this groupings, and how each one is meant to be chosen over the available shell equivalent. Companion to crates/tui/src/prompts/agent.txt.

Design stance

  • Dedicated tools over exec_shell whenever the dedicated tool returns structured output. Bash escaping is error-prone and platform behavior varies (GNU vs BSD grep, rg is not always installed). Structured output also frees the model from re-parsing free-form text.
  • exec_shell for everything else. Build, test, format, lint, ad-hoc commands, anything platform-specific. We don't try to wrap the long tail.
  • Drop tools that don't beat their shell equivalent. Two-tool aliases for the same backing operation are a model trap — the LLM will alternate between them and the cache hit rate suffers.

Final surface (v0.5.1)

File operations

Tool Niche
read_file Read a UTF-8 file. PDFs auto-extracted via pdftotext (poppler) when available; pages: "1-5" slices large docs.
list_dir Structured, gitignore-aware listing. Preferred over exec_shell("ls").
write_file Create or overwrite a file.
edit_file Search-and-replace inside a single file. Cheaper than a full rewrite.
apply_patch Apply a unified diff. The right tool for multi-hunk edits.
Tool Niche
grep_files Regex search file contents within the workspace; structured matches + context lines. Pure-Rust (regex crate), no rg/grep shell-out.
file_search Fuzzy-match filenames (not contents). Use when you know roughly the name.
web_search DuckDuckGo (with Bing fallback); ranked snippets + ref_id for citation.
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.

Shell

Tool Niche
exec_shell Run a shell command. Foreground or background (background: true returns a task_id).
exec_shell_wait Poll a background task for incremental output.
exec_shell_interact Send stdin to a running background task and read incremental output.

Git / diagnostics / testing

Tool Niche
git_status Inspect repo status without running shell.
git_diff Inspect working-tree or staged diffs.
diagnostics Workspace, git, sandbox, and toolchain info in one call.
run_tests cargo test with optional args.

Task management

Tool Niche
todo_write Granular per-item progress.
update_plan Structured checklist for complex multi-step work.
note One-off important fact for later.

Sub-agents

agent_spawn, agent_swarm, spawn_agents_on_csv, plus the supporting tools (agent_result / swarm_result / wait / send_input / agent_assign / agent_cancel / resume_agent / agent_list / report_agent_job_result / swarm_status). See agent.txt for the delegation protocol.

Recently consolidated (v0.5.1)

Removed from the prompt as duplicates of equivalent tools (the underlying dispatchers still resolve them, so existing sessions don't break — they just no longer pollute the model's tool list):

  • spawn_agent → use agent_spawn.
  • close_agent → use agent_cancel.
  • assign_agent → use agent_assign.

Deprecation schedule (v0.6.2 → v0.8.0)

The alias tools below still execute successfully but now attach a _deprecation block to every result they return. Models should migrate to the canonical name before v0.8.0, when the aliases will be removed.

Deprecated alias Canonical name Warning since Removal
spawn_agent agent_spawn v0.6.2 v0.8.0
delegate_to_agent agent_spawn v0.6.2 v0.8.0
close_agent agent_cancel v0.6.2 v0.8.0
send_input agent_send_input v0.6.2 v0.8.0

The _deprecation block shape:

{
  "_deprecation": {
    "this_tool": "spawn_agent",
    "use_instead": "agent_spawn",
    "removed_in": "0.8.0",
    "message": "Tool 'spawn_agent' is deprecated; switch to 'agent_spawn' before v0.8.0."
  }
}

This block is merged into the tool result's metadata object alongside any other metadata keys (e.g. status, timed_out) so it does not displace existing metadata. A one-line deprecation warning is also emitted to the audit log at tracing::warn level every time an alias is invoked.

Why we don't ship a single bash tool

Single-bash agents (Claude Code's design) are powerful but hand the model all the foot-guns of shell scripting: quoting, platform divergence, side-effects from misread cwd, cd not persisting between calls, etc. Our file tools are also significantly cheaper to render in the transcript (structured JSON-shaped output collapses better than ls -la walls of text).

The model can always fall back to exec_shell when something is missing. The dedicated tools just take the common 80% off the shell escape-hatch.