Tools Layer
Package: src/tunacode/tools/
What
Every capability the agent can invoke during a conversation. Each tool is an async function decorated with @base_tool or @file_tool, then converted to a tinyagent AgentTool via to_tinyagent_tool().
Key Files
Tool Implementations
| File |
Tool Name |
Purpose |
bash.py |
bash |
Execute shell commands with timeout and output capture. |
glob.py |
glob |
Find files by glob pattern, respecting ignore rules. |
grep.py |
grep |
Regex search across files using ripgrep. |
read_file.py |
read_file |
Read file contents with hash-tagged line numbers for validation. |
write_file.py |
write_file |
Create or overwrite a file. |
hashline_edit.py |
hashline_edit |
Apply validated edits using content-hash line references. |
list_dir.py |
list_dir |
List directory contents with file metadata. |
web_fetch.py |
web_fetch |
Fetch and convert web pages with URL security validation. |
discover.py |
discover |
Find and map code related to concepts via natural language. |
Framework
| File |
Purpose |
decorators.py |
@base_tool -- wraps tools with consistent error handling (ToolRetryError passthrough, catch-all to ToolExecutionError). @file_tool -- adds path-specific error mapping (FileNotFoundError to ToolRetryError, PermissionError to FileOperationError). to_tinyagent_tool() -- converts a decorated async function to an AgentTool with auto-generated OpenAI-function JSON schema. |
xml_helper.py |
Loads tool descriptions from XML prompt files. If a tool has a matching XML file, its docstring is replaced with the XML content at decoration time. |
ignore.py |
Core ignore-pattern matching logic. |
ignore_manager.py |
Manages the full ignore stack (built-in + .gitignore + user overrides). |
Hashline Edit System
| File |
Purpose |
hashline.py |
Content-hash line tagging and validation. Provides HashedLine, format_hashline(), and parse_line_ref() for read/write validation. |
line_cache.py |
In-memory cache for edit validation. Stores {path: {line_number: HashedLine}} to detect stale references. |
Discover Engine (utils/)
| File |
Purpose |
discover_pipeline.py |
Core discovery pipeline logic. Implements term extraction, glob generation, candidate scoring, and clustering. |
discover_terms.py |
Lexical vocabularies for search heuristics. Defines SOURCE_EXTENSIONS, CONCEPT_EXPANSIONS, and noise filtering. |
discover_types.py |
Data structures for discovery reports. Provides DiscoveryReport, ConceptCluster, FileEntry, and Relevance enum. |
Grep Engine (grep_components/)
| File |
Purpose |
file_filter.py |
Decides which files to search based on ignore rules and include patterns. |
pattern_matcher.py |
Regex compilation and matching with timeout protection. |
result_formatter.py |
Formats grep results for the LLM (line numbers, context lines, truncation). |
search_result.py |
SearchResult dataclass for a single match. |
LSP (lsp/)
| File |
Purpose |
client.py |
LSP client for language-server communication. |
diagnostics.py |
Fetch and format diagnostics from the LSP server. |
servers.py |
Server configuration and lifecycle management. |
Utilities (utils/)
| File |
Purpose |
formatting.py |
Text formatting helpers (truncation, line numbering). |
ripgrep.py |
Ripgrep binary detection and invocation. |
Cache Accessors (cache_accessors/)
| File |
Purpose |
ignore_manager_cache.py |
Cached ignore-manager instance. |
ripgrep_cache.py |
Cached ripgrep binary path. |
xml_prompts_cache.py |
Cached XML prompt content. |
How
Tool registration flow:
agent_config.py::_build_tools() calls to_tinyagent_tool() on each decorated tool function.
to_tinyagent_tool() introspects the function signature to build an OpenAI-function JSON schema.
- The tool's docstring (possibly replaced by XML prompt content) becomes the tool description the model sees.
- At runtime, tinyagent calls
AgentTool.execute(tool_call_id, args, signal, on_update).
- The adapter binds
args to the function signature, checks for abort signal, calls the tool, and wraps the result in AgentToolResult.
Error contract:
ToolRetryError -- model should try again with corrected arguments (surfaces as tool error to model).
ToolExecutionError -- hard failure, reported to user.
FileOperationError -- file-specific hard failure.
UI Renderers
Each tool with visual output has a renderer in src/tunacode/ui/renderers/. The hashline_edit renderer displays diffs with syntax highlighting and line change indicators.
Why
The decorator pattern means tool authors only write the business logic. Error handling, schema generation, and abort-signal checking are handled uniformly. The XML prompt system lets tool descriptions be edited without touching Python code.
The hashline edit system replaces the previous fuzzy matching approach with cryptographic validation, preventing edits to stale file content. Each line read by read_file is tagged with a content hash; hashline_edit validates these hashes before applying any changes.
1---2name: tools-layer3description: Every capability the agent can invoke during a conversation. Each tool is an async function decorated with @basetool or @filetool, then converted to a tinyagent AgentTool via totinyagenttool().4---56# Tools Layer78**Package:** `src/tunacode/tools/`910## What1112Every capability the agent can invoke during a conversation. Each tool is an async function decorated with `@base_tool` or `@file_tool`, then converted to a tinyagent `AgentTool` via `to_tinyagent_tool()`.1314## Key Files1516### Tool Implementations1718| File | Tool Name | Purpose |19|------|-----------|---------|20| `bash.py` | `bash` | Execute shell commands with timeout and output capture. |21| `glob.py` | `glob` | Find files by glob pattern, respecting ignore rules. |22| `grep.py` | `grep` | Regex search across files using ripgrep. |23| `read_file.py` | `read_file` | Read file contents with hash-tagged line numbers for validation. |24| `write_file.py` | `write_file` | Create or overwrite a file. |25| `hashline_edit.py` | `hashline_edit` | Apply validated edits using content-hash line references. |26| `list_dir.py` | `list_dir` | List directory contents with file metadata. |27| `web_fetch.py` | `web_fetch` | Fetch and convert web pages with URL security validation. |28| `discover.py` | `discover` | Find and map code related to concepts via natural language. |2930### Framework3132| File | Purpose |33|------|---------|34| `decorators.py` | `@base_tool` -- wraps tools with consistent error handling (`ToolRetryError` passthrough, catch-all to `ToolExecutionError`). `@file_tool` -- adds path-specific error mapping (`FileNotFoundError` to `ToolRetryError`, `PermissionError` to `FileOperationError`). `to_tinyagent_tool()` -- converts a decorated async function to an `AgentTool` with auto-generated OpenAI-function JSON schema. |35| `xml_helper.py` | Loads tool descriptions from XML prompt files. If a tool has a matching XML file, its docstring is replaced with the XML content at decoration time. |36| `ignore.py` | Core ignore-pattern matching logic. |37| `ignore_manager.py` | Manages the full ignore stack (built-in + `.gitignore` + user overrides). |3839### Hashline Edit System4041| File | Purpose |42|------|---------|43| `hashline.py` | Content-hash line tagging and validation. Provides `HashedLine`, `format_hashline()`, and `parse_line_ref()` for read/write validation. |44| `line_cache.py` | In-memory cache for edit validation. Stores `{path: {line_number: HashedLine}}` to detect stale references. |4546### Discover Engine (`utils/`)4748| File | Purpose |49|------|---------|50| `discover_pipeline.py` | Core discovery pipeline logic. Implements term extraction, glob generation, candidate scoring, and clustering. |51| `discover_terms.py` | Lexical vocabularies for search heuristics. Defines `SOURCE_EXTENSIONS`, `CONCEPT_EXPANSIONS`, and noise filtering. |52| `discover_types.py` | Data structures for discovery reports. Provides `DiscoveryReport`, `ConceptCluster`, `FileEntry`, and `Relevance` enum. |5354### Grep Engine (`grep_components/`)5556| File | Purpose |57|------|---------|58| `file_filter.py` | Decides which files to search based on ignore rules and include patterns. |59| `pattern_matcher.py` | Regex compilation and matching with timeout protection. |60| `result_formatter.py` | Formats grep results for the LLM (line numbers, context lines, truncation). |61| `search_result.py` | `SearchResult` dataclass for a single match. |6263### LSP (`lsp/`)6465| File | Purpose |66|------|---------|67| `client.py` | LSP client for language-server communication. |68| `diagnostics.py` | Fetch and format diagnostics from the LSP server. |69| `servers.py` | Server configuration and lifecycle management. |7071### Utilities (`utils/`)7273| File | Purpose |74|------|---------|75| `formatting.py` | Text formatting helpers (truncation, line numbering). |76| `ripgrep.py` | Ripgrep binary detection and invocation. |7778### Cache Accessors (`cache_accessors/`)7980| File | Purpose |81|------|---------|82| `ignore_manager_cache.py` | Cached ignore-manager instance. |83| `ripgrep_cache.py` | Cached ripgrep binary path. |84| `xml_prompts_cache.py` | Cached XML prompt content. |8586## How8788Tool registration flow:891. `agent_config.py::_build_tools()` calls `to_tinyagent_tool()` on each decorated tool function.902. `to_tinyagent_tool()` introspects the function signature to build an OpenAI-function JSON schema.913. The tool's docstring (possibly replaced by XML prompt content) becomes the tool description the model sees.924. At runtime, tinyagent calls `AgentTool.execute(tool_call_id, args, signal, on_update)`.935. The adapter binds `args` to the function signature, checks for abort signal, calls the tool, and wraps the result in `AgentToolResult`.9495Error contract:96- `ToolRetryError` -- model should try again with corrected arguments (surfaces as tool error to model).97- `ToolExecutionError` -- hard failure, reported to user.98- `FileOperationError` -- file-specific hard failure.99100### UI Renderers101102Each tool with visual output has a renderer in `src/tunacode/ui/renderers/`. The `hashline_edit` renderer displays diffs with syntax highlighting and line change indicators.103104## Why105106The decorator pattern means tool authors only write the business logic. Error handling, schema generation, and abort-signal checking are handled uniformly. The XML prompt system lets tool descriptions be edited without touching Python code.107108The hashline edit system replaces the previous fuzzy matching approach with cryptographic validation, preventing edits to stale file content. Each line read by `read_file` is tagged with a content hash; `hashline_edit` validates these hashes before applying any changes.