Tools
Tools follow a handler pattern where each tool defines a name, description, JSON-schema parameters, and a handle() implementation. Tool availability is controlled by the active permission profile.
File inspection tools¶
These tools are always available regardless of profile.
read¶
Read file contents with optional line ranges.
| Parameter | Type | Description |
|---|---|---|
path |
string | File path (required) |
start_line |
integer | First line to read |
end_line |
integer | Last line to read |
Returns line-numbered content. Blocks binary files. Defaults to 500 lines max, truncating lines longer than 500 characters.
grep¶
Search file contents using ripgrep.
| Parameter | Type | Description |
|---|---|---|
pattern |
string | Search pattern (required) |
path |
string | File or directory to search |
glob |
string | File glob filter |
ignore_case |
boolean | Case-insensitive matching |
context_lines |
integer | Lines of context around matches |
max_matches |
integer | Maximum results (default: 100) |
Automatically skips .git, node_modules, __pycache__, and .venv directories.
glob¶
Find files by glob pattern.
| Parameter | Type | Description |
|---|---|---|
pattern |
string | Glob pattern (required) |
path |
string | Base directory |
max_results |
integer | Maximum results (default: 100) |
list¶
List directory contents as a flat listing or recursive tree.
| Parameter | Type | Description |
|---|---|---|
path |
string | Directory path (required) |
show_hidden |
boolean | Include hidden files |
recursive |
boolean | Recursive tree view |
max_depth |
integer | Maximum tree depth |
Flat mode shows permissions, size, mtime, and name. Recursive mode shows a tree structure. Defaults to 200 entries max.
read_excel¶
Read and inspect Excel files (.xlsx, .xls).
| Parameter | Type | Description |
|---|---|---|
path |
string | Excel file path (required) |
action |
string | list_sheets, read_sheet, or get_info |
sheet |
string | Sheet name or index |
start_row |
integer | First row to read |
end_row |
integer | Last row to read |
show_hidden |
boolean | Include hidden rows/columns |
Returns tab-delimited data or sheet metadata. Defaults to 500 rows max.
Shell tool¶
bash¶
Execute shell commands. Behavior depends on the profile's shell mode.
| Parameter | Type | Description |
|---|---|---|
command |
string | Shell command to execute (required) |
working_dir |
string | Working directory override |
timeout |
integer | Timeout in seconds |
Restricted mode (readonly profile): Only allowlisted commands are permitted. The allowlist includes read-only commands like cat, grep, find, ls, head, tail, wc, jq, git log, git diff, git show, ps, df, du, env, curl, and similar inspection tools. Redirects (>, >>) and destructive commands (rm, mv, chmod, kill, sudo) are blocked.
Unrestricted mode (developer and eval profiles): Any command is allowed.
Returns JSON with output, exit_code, and duration_seconds.
File edit tools¶
Available when the profile's file_write mode is create-only or full.
write¶
Create or overwrite files.
| Parameter | Type | Description |
|---|---|---|
path |
string | File path (required) |
content |
string | File content (required) |
Create-only mode: Can only create new files. Blocks overwrites and writes to sensitive paths (.bashrc, .ssh/, .aws/, /etc/, /usr/).
Full mode: Unrestricted write access.
edit¶
Surgical file edits via search-and-replace.
| Parameter | Type | Description |
|---|---|---|
path |
string | File path (required) |
old_string |
string | Text to find (required) |
new_string |
string | Replacement text (required) |
Requires a unique match to prevent accidental changes. Uses a three-stage matching strategy:
- Exact match — literal string comparison
- Whitespace-normalized — matches ignoring whitespace differences
- Indentation-flexible — matches with different indentation while preserving relative indentation in the replacement
Database tools¶
Database tools share a common interface. All support query, list_tables, describe, and export_query operations. By default, only SELECT queries are allowed. Mutation queries (INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, TRUNCATE) require the eval profile.
| Parameter | Type | Description |
|---|---|---|
database |
string | Database alias (for multi-database configs) |
operation |
string | query, list_tables, describe, or export_query |
sql |
string | SQL query (for query and export_query) |
table_pattern |
string | Filter pattern for list_tables |
table_name |
string | Table name for describe |
output_path |
string | CSV output path for export_query |
Query results are formatted as ASCII tables with a default limit of 100 rows.
Configuration¶
CLI users¶
The CLI reads database configuration from ~/.config/rho-agent/databases.yaml (or the path in RHO_AGENT_DB_CONFIG). Any databases defined there are available to all CLI sessions automatically.
# ~/.config/rho-agent/databases.yaml
databases:
sales:
type: sqlite
path: /data/sales.db
analytics:
type: postgres
host: localhost
database: analytics
user: reader
password: ${ANALYTICS_PASSWORD}
Python SDK users¶
Set databases on AgentConfig directly — either in YAML agent config files or inline in code. No global config file is consulted; you get exactly the databases you configure.
Agent config YAML:
# agents/data-analyst.yaml
system_prompt: You are a data analyst.
profile: readonly
databases:
sales:
type: sqlite
path: /data/sales.db
analytics:
type: postgres
host: localhost
database: analytics
user: reader
password: ${ANALYTICS_PASSWORD}
Inline in Python:
config = AgentConfig(
system_prompt="You are a data analyst.",
profile="readonly",
databases={
"sales": {"type": "sqlite", "path": "/data/sales.db"},
"analytics": {
"type": "postgres",
"host": "localhost",
"database": "analytics",
"user": "reader",
"password": "${ANALYTICS_PASSWORD}",
},
},
)
Environment variable interpolation¶
String values support ${ENV_VAR} interpolation so secrets stay out of config files.
Supported databases¶
| Type | Required fields | Optional fields | Install extra |
|---|---|---|---|
sqlite |
path |
— | — |
postgres |
database |
host, port, user, password |
uv pip install '.[db]' |
mysql |
database |
host, port, user, password |
uv pip install '.[db]' |
oracle |
dsn |
user, password |
uv pip install '.[db]' |
vertica |
database |
host, port, user, password |
uv pip install '.[db]' |
Daytona remote sandbox tools¶
When the Daytona backend is active (--backend daytona), all file and shell tools (bash, read, write, edit, glob, grep, list) execute in a remote cloud sandbox. The tool names and parameter schemas are identical — the model sees the same interface. Database tools always run locally.
See the Daytona guide for setup, configuration, and file upload/download.
Sub-agent tools¶
rho-agent supports two patterns for spawning child agents. Both create independent sessions and disable further delegation to prevent unbounded recursion.
delegate (ad-hoc delegation)¶
Spawn a child agent to execute a focused subtask. The LLM decides at runtime when to delegate. See Architecture for details on multi-agent coordination.
| Parameter | Type | Description |
|---|---|---|
instruction |
string | Task description for the child agent (required) |
full_context |
boolean | Copy parent conversation history to child |
The child agent inherits the parent's profile, model, and working directory. Delegation is single-level — child agents cannot delegate further. Parent cancellation propagates to children automatically.
Agent-as-tool (pre-configured specialists)¶
Wrap a pre-configured agent as a named tool with typed parameters. Unlike delegate, the child has its own system prompt, profile, and model — configured at setup time, not derived from the parent.
from rho_agent.tools.handlers import AgentToolHandler
from rho_agent.core.config import AgentConfig
sql_agent = AgentToolHandler(
tool_name="generate_sql",
tool_description="Generate SQL from a natural language question.",
system_prompt="You are an expert SQL developer. ...",
config=AgentConfig(model="gpt-5-mini", profile="readonly"),
input_schema={
"type": "object",
"properties": {
"question": {"type": "string", "description": "Natural language question"},
"dialect": {"type": "string", "enum": ["sqlite", "postgres", "mysql"]},
},
"required": ["question"],
},
)
# Register on an existing agent's registry
agent.registry.register(sql_agent)
The parent LLM sees generate_sql(question, dialect) as a first-class tool. Each invocation spawns an independent session — no conversation history is shared.
| Constructor parameter | Type | Description |
|---|---|---|
tool_name |
string | Tool name the LLM sees (required) |
tool_description |
string | Description for the LLM (required) |
system_prompt |
string | Child agent's system prompt (required) |
config |
AgentConfig | Child's model, profile, etc. |
input_schema |
dict | JSON Schema for typed parameters |
input_formatter |
callable | Custom (args) -> instruction mapper |
requires_approval |
bool | Whether parent needs approval before calling |