Skip to content

Tools

Tools are structured functions that an LLM can call. Every agent ships with a set of built-in tools, and you can extend them with custom tools using the @tool decorator, Tool.from_callable(), or Toolset classes.

Every agent gets a default set of tools automatically via default_tools(). These are always available unless explicitly filtered by agent tool rules. Additional tools from capabilities are additive on top.

ToolSignaturePurpose
readread(file_path, offset?, limit?)Read a file or directory listing. Returns line-numbered content. Supports images and PDFs (base64). Output capped at 50 KB.
writewrite(file_path, content)Write content to a file, creating parent directories as needed.
globglob(pattern, path?)Find files matching a glob pattern, sorted by modification time. Uses ripgrep when available. Capped at 100 results.
grepgrep(pattern, path?, include?)Search file contents using a regex pattern. Uses ripgrep when available. Supports include glob filter. Capped at 100 matches.
lsls(path?, ignore?)Tree-style directory listing. Auto-ignores common directories (node_modules, __pycache__, .git, etc.). Capped at 100 entries.
ToolSignaturePurpose
edit_fileedit_file(path, old_string, new_string, replace_all?)Surgical text replacement with 7-tier fuzzy matching. Fails on ambiguous matches unless replace_all=True.
multieditmultiedit(path, edits)Apply multiple edits to a single file atomically. All-or-nothing — all must succeed or none are applied.
insert_linesinsert_lines(path, line_number, content)Insert content before a specific line number (1-indexed).
delete_linesdelete_lines(path, start_line, end_line)Delete a range of lines (1-indexed, inclusive).
apply_patchapply_patch(patch_text)Apply a multi-file patch using a structured LLM-friendly format. Supports Add File, Delete File, and Update File operations with 4-pass fuzzy matching.
ToolSignaturePurpose
bashbash(cmd, timeout?, env?, input?)Execute a bash command in a subprocess. Default 120s timeout. Process-group isolation with SIGTERM/SIGKILL escalation.
pythonpython(code, timeout?, env?)Execute Python code in a subprocess. Code is piped to stdin — output must be printed to stdout to be captured.
ToolSignaturePurpose
fetchfetch(url, format?, timeout?, headers?)Fetch content from a URL. HTML is converted to markdown by default. 5 MB response limit, 50K char output limit.
web_searchweb_search(query, num_results?, search_engine?)Search the web. DuckDuckGo by default (no API key). Set search_engine="google" with GOOGLE_API_KEY + GOOGLE_CSE_ID for Google. Max 10 results.
ToolSignaturePurpose
thinkthink(thought)Record a thought or reflection. No side effects — purely for chain-of-thought reasoning.
todotodo(todos)Manage a structured task list. Each TodoItem has id, content, status (pending/in_progress/completed/cancelled), and priority (high/medium/low).

These tools enable human-in-the-loop workflows where the agent can ask the user for input.

ToolSignaturePurpose
ask_userask_user(question, options?, kind?, details?, allow_free_text?, default_option?, severity?)Ask the user a question and wait for their response. Supports three kinds: "input" (free-form text), "choice" (selection from options), "approval".
confirmconfirm(action, default_yes?)Ask the user to confirm an action. Returns a boolean. Wraps ask_user() with “Yes”/“No” options.

Options can be plain strings or structured HumanPromptOption(label, description) objects. The handler chain tries a structured handler first (used by the TUI), then a legacy callback, then falls back to stdin input.

The Memory toolset provides a stateful key-value store for the agent’s lifetime.

ToolSignaturePurpose
save_memorysave_memory(key, value)Save or overwrite a value by key.
retrieve_memoryretrieve_memory(key)Retrieve a value by key. Raises an error if the key does not exist.
list_memory_keyslist_memory_keys()List all stored keys.
clear_memoryclear_memory(key?)Clear a specific key, or all keys if no key is provided.

from dreadnode.agents import tool
@tool
def calculator(operation: str, a: float, b: float) -> float:
"""Perform basic math operations."""
if operation == "add":
return a + b
if operation == "subtract":
return a - b
if operation == "multiply":
return a * b
if operation == "divide":
return a / b
raise ValueError("Unsupported operation")

Use @tool(catch=True) to automatically catch exceptions and return the error message as the tool output instead of raising.

Tool.from_callable() builds a tool from any callable with type annotations.

from dreadnode.agents import Tool
def greet(name: str) -> str:
"""Say hello."""
return f"Hello, {name}!"
tool = Tool.from_callable(greet, name="greet")
definition = tool.definition.function # FunctionDefinition

When a tool returns more than 30,000 characters, the SDK writes the full output to {working_dir}/.dreadnode/tool-output/<tool_call_id>.txt and replaces the in-context result with a middle-out summary that points to the file. Set tool.offload = False to disable this behavior for a specific tool.

Toolset classes keep state and expose methods decorated with @tool_method.

from dreadnode.agents import Toolset, tool_method
class MathTools(Toolset):
factor: int = 2
@tool_method
def multiply(self, value: int) -> int:
"""Multiply by the configured factor."""
return value * self.factor
tools = MathTools().get_tools()

discover_tools_on_obj() scans objects for @tool_method descriptors.

from dreadnode.agents import discover_tools_on_obj
toolset = MathTools(factor=3)
tools = discover_tools_on_obj(toolset)

ToolMode controls how tool calls are parsed:

  • auto (choose API or JSON/XML automatically)
  • api (provider function calling)
  • xml, json, json-in-xml, json-with-tag, pythonic

Tools use ToolCall to represent an invocation and ToolResponse to format results for XML tool mode. FunctionDefinition describes each tool’s schema.