API Reference
Built-in Tools
Complete reference for the BuiltinTools registry and every built-in tool: its name, description, JSON schema parameters, and behavior.
BuiltinTools
pub struct BuiltinTools { /* fields omitted */ }
Registry of built-in tools. Provides methods to access tool configurations and executors for registration with the tool system.
Constructors
all()
pub fn all() -> Self
Creates a registry containing all built-in tools. Returns 9 tools.
select()
pub fn select(tools: &[&str]) -> Result<Self, ToolError>
Creates a registry containing only the specified tools by name. Returns an error if an unknown tool name is provided.
let tools = BuiltinTools::select(&["read_file", "write_file", "glob"])?;
Query methods
available()
pub fn available() -> Vec<&'static str>
Lists all available built-in tool names (9 total).
get_config()
pub fn get_config(&self, name: &str) -> Option<&ToolConfig>
Returns the configuration for a specific tool.
get_executor()
pub fn get_executor(&self, name: &str) -> Option<Arc<BoxedToolExecutor>>
Returns the executor for a specific tool.
configs()
pub fn configs(&self) -> impl Iterator<Item = (&String, &ToolConfig)>
Returns an iterator over all registered tool configurations.
executors()
pub fn executors(&self) -> impl Iterator<Item = (&String, &Arc<BoxedToolExecutor>)>
Returns an iterator over all registered tool executors.
len()
pub fn len(&self) -> usize
Returns the number of registered tools.
is_empty()
pub fn is_empty(&self) -> bool
Returns true if no tools are registered.
Enabling built-in tools
There are several ways to make built-in tools available to the LLM.
On the builder (recommended)
// All builtins, auto-enabled on every prompt
ActonAI::builder()
.with_builtins()
.launch().await?;
// Specific builtins, auto-enabled
ActonAI::builder()
.with_builtin_tools(&["read_file", "glob", "grep", "bash"])
.launch().await?;
// All builtins, but require manual opt-in per prompt
ActonAI::builder()
.with_builtins()
.manual_builtins()
.launch().await?;
On the prompt
When manual_builtins() is set, you must enable them on each prompt:
runtime.prompt("List files")
.use_builtins()
.collect()
.await?;
See ActonAIBuilder and PromptBuilder for full details.
Tool reference
Each tool below lists its name (used by the LLM), description, JSON schema parameters, and behavior notes.
read_file
Reads file contents with line numbers.
Parameters:
{
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Absolute path to the file to read"
},
"offset": {
"type": "integer",
"description": "Line number to start from (1-indexed, default: 1)",
"minimum": 1
},
"limit": {
"type": "integer",
"description": "Maximum number of lines to read (default: 2000)",
"minimum": 1
}
},
"required": ["path"]
}
Returns: { content, total_lines, start_line, end_line, truncated }
Behavior:
- Path must be absolute. Relative paths are rejected.
- Content is returned with line numbers in
cat -nstyle format. - Lines longer than 2000 characters are truncated.
- Binary files are detected and rejected.
- Path is validated by
PathValidatorfor security (prevents path traversal).
write_file
Writes content to a file, creating parent directories if needed.
Parameters:
{
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Absolute path to the file to write"
},
"content": {
"type": "string",
"description": "Content to write to the file"
}
},
"required": ["path", "content"]
}
Returns: { success, path, bytes_written }
Behavior:
- Path must be absolute.
- Parent directories are created automatically if they do not exist.
- Overwrites existing files.
- Marked as requiring sandbox (
sandboxed: true).
edit_file
Makes targeted string replacements in a file.
Parameters:
{
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Absolute path to the file to edit"
},
"old_string": {
"type": "string",
"description": "Exact string to find and replace"
},
"new_string": {
"type": "string",
"description": "Replacement string"
},
"replace_all": {
"type": "boolean",
"description": "Replace all occurrences (default: false, which requires exactly one match)"
}
},
"required": ["path", "old_string", "new_string"]
}
Returns: { success, path, replacements, diff }
Behavior:
- Path must be absolute.
- When
replace_allisfalse(default), theold_stringmust appear exactly once in the file. If it appears multiple times, the tool returns an error suggesting to usereplace_all: trueor provide more context. old_stringandnew_stringmust be different.- Returns a simple diff-style output showing what changed.
- Marked as requiring sandbox (
sandboxed: true).
list_directory
Lists directory contents with metadata (type, size, modified time).
Parameters:
{
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Directory path to list"
}
},
"required": ["path"]
}
Returns: { path, entries: [{ name, entry_type, size, modified }], count }
Behavior:
- Path must be absolute.
- Each entry includes its type (
"file","dir", or"symlink"), size (for files), and last modified time in ISO 8601 format. - Results are sorted alphabetically by name.
glob
Finds files matching a glob pattern.
Parameters:
{
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Glob pattern to match (e.g., '**/*.rs', 'src/**/*.ts')"
},
"path": {
"type": "string",
"description": "Base directory to search in (default: current working directory)"
}
},
"required": ["pattern"]
}
Returns: { matches: [string], count, truncated, pattern, base_path }
Behavior:
- Supports recursive patterns with
**. - Returns up to 1000 matching paths.
- Results are sorted alphabetically.
- If
pathis provided, it must be absolute.
grep
Searches file contents using regex patterns.
Parameters:
{
"type": "object",
"properties": {
"pattern": {
"type": "string",
"description": "Regex pattern to search for"
},
"path": {
"type": "string",
"description": "File or directory to search in (default: current directory)"
},
"glob": {
"type": "string",
"description": "File pattern to filter files (e.g., '*.rs', '*.{ts,tsx}')"
},
"context_lines": {
"type": "integer",
"description": "Number of context lines before and after each match",
"minimum": 0,
"maximum": 10
},
"ignore_case": {
"type": "boolean",
"description": "Case insensitive search (default: false)"
}
},
"required": ["pattern"]
}
Returns: { matches: [{ file, line, content, before, after }], count, files_searched, truncated, pattern }
Behavior:
- Uses Rust's
regexcrate for pattern matching. - Returns up to 500 matches.
- Skips hidden files (starting with
.), binary files, and files larger than 10MB. - When searching a directory, walks the tree recursively.
- Context lines (before/after) are included when
context_lines > 0. - If
pathis provided, it must be absolute.
bash
Executes shell commands and captures output.
Parameters:
{
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The shell command to execute"
},
"timeout": {
"type": "integer",
"description": "Timeout in seconds (default: 120, max: 600)",
"minimum": 1,
"maximum": 600
},
"cwd": {
"type": "string",
"description": "Absolute path to working directory. Only specify if you need a different directory than the current one."
}
},
"required": ["command"]
}
Returns: { exit_code, stdout, stderr, success, truncated }
Behavior:
- Runs the command via
bash -c. - stdin is connected to
/dev/null(no interactive input). - Output is captured and truncated at 1MB per stream (stdout/stderr).
- If
cwdis provided, it must be an absolute path to an existing directory. - Rejects obviously dangerous commands (
rm -rf /, fork bombs,mkfs,ddto devices). - Marked as requiring sandbox (
sandboxed: true). - Killed after the timeout expires.
Security
The bash tool executes arbitrary shell commands. In production, enable the Process Sandbox via with_process_sandbox() so each command runs in a subprocess with rlimits, a timeout, and (on Linux) best-effort landlock + seccomp filters.
calculate
Evaluates mathematical expressions using the fasteval crate.
Parameters:
{
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Mathematical expression to evaluate (e.g., '2 + 2', 'abs(-5)', 'sin(pi()/2)')"
},
"variables": {
"type": "object",
"description": "Optional variable bindings (e.g., {\"x\": 5, \"y\": 10})",
"additionalProperties": {
"type": "number"
}
}
},
"required": ["expression"]
}
Returns: { result, formatted, expression, is_special }
Behavior:
- Supports arithmetic operators:
+,-,*,/,^,%. - Built-in functions:
sin,cos,tan,log,abs,min,max,floor,ceil,round,sqrt, and more. - Constants via functions:
pi(),e(). - User-defined variables can be passed via the
variablesfield. - Results are formatted nicely: integer results show as integers, floats as floats.
- Special values (NaN, Infinity) are detected and flagged.
- Expression length is capped at 1000 characters.
- This is a safe math parser -- it does not execute arbitrary code.
web_fetch
Fetches content from a URL. Supports GET and POST methods with custom headers.
Parameters:
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "URL to fetch (must be http or https)"
},
"method": {
"type": "string",
"enum": ["GET", "POST"],
"description": "HTTP method (default: GET)"
},
"headers": {
"type": "object",
"description": "Optional HTTP headers",
"additionalProperties": {
"type": "string"
}
},
"body": {
"type": "string",
"description": "Optional request body (for POST requests)"
},
"timeout": {
"type": "integer",
"description": "Timeout in seconds (default: 30, max: 120)",
"minimum": 1,
"maximum": 120
}
},
"required": ["url"]
}
Returns: { status_code, success, content_type, body, body_length, truncated, headers }
Behavior:
- Only
httpandhttpsschemes are allowed. - Blocks requests to localhost,
127.0.0.1,::1, and private IP ranges (192.168.*,10.*,172.16-31.*) for security. - Response body is truncated at 5MB.
- Default timeout is 30 seconds.
- User agent is set to
acton-ai/0.1.
update_plan
Maintains the model's structured plan for the current task. The only built-in that runs no code: it validates what the model sent, records it as the turn's plan, echoes back the normalized version, and broadcasts it. The tool's description teaches the model to skip planning for trivial tasks, never send a single-step plan, and update the plan right after completing each step.
Parameters:
{
"type": "object",
"properties": {
"steps": {
"type": "array",
"description": "The complete ordered list of steps, resent in full on every call",
"minItems": 2,
"maxItems": 32,
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "What this step does, in a few words"
},
"status": {
"type": "string",
"enum": ["pending", "in_progress", "completed"]
}
},
"required": ["title", "status"]
}
},
"note": {
"type": "string",
"description": "Optional one-line note about the plan or why it changed"
}
},
"required": ["steps"]
}
Returns: { status: "recorded", plan, completed, total }
Behavior:
- The model sends the whole plan every time, not a diff.
- A plan must have 2--32 steps; each step's title is trimmed, non-empty, at most 200 characters, and distinct from every other step. A single-step plan is refused with a corrective message: split the work, or skip planning.
- At most one step may be
in_progress. A step with nostatusispending. - A
noteis optional, at most 1000 characters; blank counts as absent. - A plan that breaks any of those rules is refused, and the reason goes back to the model as that call's tool result so it can correct itself. Nothing is broadcast for a refused plan, and the plan already recorded stands.
- The prompt round loop owns the turn's current plan: it carries across every round of the tool loop, and the turn's final plan is returned on
CollectedResponse::plan. - Every accepted plan is broadcast on the broker as a
PlanUpdatedmessage (defined inacton_ai::messages, alongside the other stream and lifecycle events) carrying the turn ID, the round's correlation ID, the tool call ID, and the validatedPlan. Theacton-ai chatREPL renders each update as an inline checklist. Subscribe an actor to render progress yourself:
// On the builder, before start() -- a later subscription is ignored.
builder.handle().subscribe::<PlanUpdated>().await;
builder.mutate_on::<PlanUpdated>(|actor, envelope| {
let plan = &envelope.message().plan;
println!("{}/{} steps done", plan.completed_count(), plan.step_count());
Reply::ready()
});
Agent skill tools
These tools are auto-registered on every prompt when skills are loaded via ActonAIBuilder::with_skill_paths or a [skills] TOML section (or the --skill-dir CLI flag). If no skill paths are supplied, the tools are absent.
list_skills
Lists available agent skills with their descriptions.
Parameters:
{
"type": "object",
"properties": {
"filter": {
"type": "string",
"description": "Optional filter pattern for skill names (case-insensitive substring match)"
}
}
}
Returns: { skills: [{ name, description, tags }], count }
Behavior:
- Returns all registered skills, optionally filtered by name.
- Use this to discover available skills before activating one.
activate_skill
Activates a skill and receives its full instructions.
Parameters:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the skill to activate"
}
},
"required": ["name"]
}
Returns: { name, description, instructions, path, tags }
Behavior:
- Loads the full instructions for the named skill.
- Call
list_skillsfirst to see what is available. - The
instructionsfield contains the complete skill content that guides the agent.
Enabling skill tools
use acton_ai::tools::builtins::{spawn_skill_tool_actors, skill_tool_names};
use acton_ai::skills::SkillRegistry;
use std::sync::Arc;
let registry = Arc::new(SkillRegistry::new());
let skill_tools = spawn_skill_tool_actors(&mut runtime, registry).await;
// skill_tool_names() returns ["list_skills", "activate_skill"]
Tool summary table
| Tool | Sandboxed | Category | Description |
|---|---|---|---|
read_file | No | Filesystem | Read file contents with line numbers |
write_file | Yes | Filesystem | Write content to files |
edit_file | Yes | Filesystem | Targeted string replacements |
list_directory | No | Filesystem | List directory contents with metadata |
glob | No | Filesystem | Find files matching glob patterns |
grep | No | Filesystem | Search file contents with regex |
bash | Yes | Execution | Execute shell commands |
calculate | No | Computation | Evaluate math expressions |
web_fetch | No | Web | Fetch content from URLs |
update_plan | No | Coordination | Record the task plan and its progress |
list_skills | No | Skills | List available agent skills |
activate_skill | No | Skills | Activate a skill for the agent |
Sandboxed tools
Tools marked as sandboxed (write_file, edit_file, bash) run inside a ProcessSandbox child process when sandbox mode is enabled via with_process_sandbox(). Without sandbox mode, they still execute but directly in the parent process.