Files
ai-harness/docs/05-tools.md
T
darman 420f00494f M0: scaffold Cargo workspace, core types, event bus, permission engine, storage actor
Sets up the Cargo workspace (harness-core, harness-tools, harness-providers, harness-mcp, harness-lsp, harness-app, harness-tui) and the ten architecture docs under docs/. harness-core gets its foundational types (session/message/part/model ids), an in-process event bus, a table-driven permission evaluate function, and a SQLite-backed storage actor with schema and roundtrip coverage. Every crate compiles empty and a bin stub prints its version.
2026-07-10 16:19:27 +02:00

49 lines
3.5 KiB
Markdown

# 05 — Built-in Tools
`harness-tools`. All parameter structs derive `schemars::JsonSchema` (single source of truth for the schema sent to the model). Invalid-params errors are returned to the model as tool errors with the schema echoed (opencode's `invalid` pattern).
## Shared: output truncation
`truncate.rs`: cap output at 30,000 chars; keep head + tail with `... [N chars truncated; full output: <data_dir>/tool-output/<call_id>.txt] ...`; full output spilled to the session data dir.
## Tool table
| Tool | Params | Behavior | Permission key / pattern |
|---|---|---|---|
| `bash` | `{command, timeout_ms?, cwd?, description}` | `tokio::process::Command` `sh -c`, own process group (`setsid`); kill group on cancel/timeout (default 2 min, max 10); merge stdout+stderr; truncate | `bash` / command string; "always" pattern = `<first word> *` via `shell-words` |
| `read` | `{file_path, offset?, limit?}` | 2000-line default window, `cat -n` numbering, 2000-char line clamp, binary/image detection; reports context files to the JobBoard when in a child session | `read` / worktree-relative path (bundled default: allow) |
| `edit` | `{file_path, old_string, new_string, replace_all?}` | replacer chain (below); CRLF/BOM preservation; per-file `tokio::Mutex` lock map; unified diff via `similar` in permission metadata + part metadata; LSP diagnostics appended | `edit` / relative path; always-pattern `*` |
| `write` | `{file_path, content}` | mkdir -p; diff vs existing in metadata; LSP diagnostics | `edit` (same key as opencode) / relative path |
| `glob` | `{pattern, path?}` | `ignore::WalkBuilder` (respects .gitignore) + `globset`; sort mtime desc; cap 100 | none (read-only) |
| `grep` | `{pattern, path?, include?}` | `grep-regex` + `grep-searcher`, gitignore-aware; cap 100 matches, sorted by file mtime | none |
| `todowrite` / `todoread` | list of `{content, status: pending\|in_progress\|completed, priority}` | stored on the session row (JSON); part metadata drives a TUI checklist | none |
| `webfetch` | `{url, format: text\|markdown\|html, timeout?}` | reqwest GET (redirect cap 5), 5 MB cap, HTML→markdown via `htmd`, truncate | `webfetch` / URL |
| `task` | see [04-multiagent.md](04-multiagent.md) | spawn/reuse subagent sessions | `task` / agent name |
| `skill` | `{name}` | returns the SKILL.md body on demand | `skill` / name (default allow) |
MCP tools are registered alongside these, namespaced `{server}_{tool}` — see [09-integrations.md](09-integrations.md).
## Edit tool: replacer chain
**Port opencode's replacer chain verbatim** from `~/repos/opencode/packages/opencode/src/tool/edit.ts`, including its test table (`edit.test.ts`) — this is the highest-regression-risk code in the project:
1. Simple (exact match)
2. LineTrimmed
3. BlockAnchor (first/last line anchors, ≥0.65 similarity on middle lines, Levenshtein)
4. WhitespaceNormalized
5. IndentationFlexible
6. EscapeNormalized
7. TrimmedBoundary
8. ContextAware
9. MultiOccurrence (with `replace_all`)
Plus the disproportionate-match guard (reject matches that differ too much in size from `old_string`).
## Registry & agent filtering
`ToolRegistry::for_agent(agent)`:
1. Filter by the agent's `tools` wildcard map (`{ "write": false, "mcp_*": false }`).
2. Hard-remove tools denied for the session depth (e.g. `task`, `todowrite` at depth > 0 by default).
3. The `task` tool's description is generated dynamically, listing available subagents with their descriptions (so routing knowledge comes from agent frontmatter, not hardcoded text).