Skip to content

Tools

Tools let your agent interact with the outside world. NimbleAgents provides three ways to define tools.

The @tool Macro

The simplest way to create a tool:

julia
@tool function add(x::Int, y::Int)
    "Add two integers together."
    x + y
end

This creates:

  1. A Julia function add(x, y) you can call directly

  2. A NimbleTool object add_tool with auto-generated JSON schema

The first string literal in the function body becomes the tool's description for the LLM. Parameter types are automatically mapped to JSON schema types.

Optional Parameters

julia
@tool function search(query::String, limit::Int=10)
    "Search for documents matching the query."
    # ... implementation
end
  • query is required (no default)

  • limit is optional with default 10

Return Direct

When a tool has return_direct=true, its result becomes the agent's final output immediately — the LLM does not process it further:

julia
@tool return_direct=true function lookup_cache(key::String)
    "Look up a cached value. Returns immediately if found."
    cache[key]
end

Example: FAQ bot with return_direct

julia
# examples/tools/return_direct.jl
const FAQ = Dict(
    "refund"   => "Refunds are processed within 5–7 business days.",
    "shipping" => "Standard shipping takes 3–5 business days. Express is 1–2.",
    "password" => "Click 'Forgot password' on the login page to reset.",
)

@tool return_direct=true function lookup_faq(topic::String)
    "Look up a frequently asked question by topic keyword."
    get(FAQ, lowercase(topic), "No FAQ found for topic: $(topic)")
end

agent = Agent(
    name         = "SupportBot",
    instructions = "You are a customer support assistant. Use lookup_faq for support topics.",
    tools        = [lookup_faq_tool],
)

# The tool result is returned directly — no LLM call to rephrase it
run!(agent, "How long do refunds take?")
# → "Refunds are processed within 5–7 business days."

Run it with:

bash
julia --project examples/tools/return_direct.jl

Built-in Tools

NimbleAgents includes a library of built-in tools:

ToolDescription
read_file_toolRead file contents
write_file_toolWrite content to a file
edit_file_toolReplace a string in a file
list_dir_toolList directory contents
glob_toolFind files by glob pattern
delete_file_toolDelete a file
grep_toolSearch file contents with regex
find_files_toolFind files by name pattern
bash_toolExecute shell commands
http_get_toolHTTP GET request
http_post_toolHTTP POST request
eval_julia_toolEvaluate Julia code in a persistent sandbox
save_artifact_toolRegister a file as a session artifact
julia
agent = Agent(
    name = "Coder",
    instructions = "You help with coding tasks.",
    tools = [read_file_tool, write_file_tool, bash_tool, eval_julia_tool],
)

CLITool

Wrap shell commands as tools with typed arguments and placeholder substitution:

julia
grep_cli = CLITool(
    name        = "grep_cli",
    description = "Search for a pattern in files.",
    command     = ["grep", "-rn", "{pattern}", "{path}"],
    args        = [
        "pattern" => CLIArg(String, "Regex pattern to search for"),
        "path"    => CLIArg(String, "Directory to search in"),
    ],
    timeout     = 10.0,
)

The {placeholder} tokens in command are replaced with the LLM-provided argument values at runtime. The command is executed as a subprocess.

Example: Developer tools agent

julia
# examples/tools/cli_tools_demo.jl
grep_tool = CLITool(
    name        = "grep",
    description = "Search for a pattern in files or directories.",
    command     = ["grep", "-rn", "{pattern}", "{path}"],
    args        = [
        "pattern" => CLIArg(String, "Regex pattern to search for."),
        "path"    => CLIArg(String, "File or directory path to search in."),
    ],
)

git_log_tool = CLITool(
    name        = "git_log",
    description = "Show recent git commits as a compact one-line log.",
    command     = ["git", "log", "--oneline", "-{n}"],
    args        = ["n" => CLIArg(Int, "Number of recent commits to show.")],
)

agent = Agent(
    name         = "DevBot",
    instructions = "You are a developer assistant with access to shell tools.",
    tools        = [grep_tool, git_log_tool],
)

run!(agent, "Search for all uses of 'CLITool' in the src/ directory.")
run!(agent, "Show me the last 5 git commits.")

Run it with:

bash
julia --project examples/tools/cli_tools_demo.jl

CLITool Options

FieldTypeDefaultDescription
nameStringrequiredTool name
descriptionStringrequiredDescription for the LLM
commandVector{String}requiredCommand with {arg} placeholders
argsVector{Pair{String,CLIArg}}requiredArgument definitions
timeoutFloat6430.0Subprocess timeout in seconds
working_dirString or nothingnothingWorking directory
return_directBoolfalseShort-circuit agent loop
return_artifactBoolfalseRegister output as artifact

CLIArg

julia
CLIArg(type, description; required=true)
  • type: String, Int, Float64, or Bool

  • description: Description shown to the LLM

  • required: Whether the argument is mandatory (default: true)

Tool Dispatch

Under the hood, dispatch_tool routes LLM tool calls to the correct callable:

julia
julia> using NimbleAgents

julia> @tool function add_dispatch(x::Int, y::Int)
           "Add two integers."
           x + y
       end;

julia> tool_map = build_tool_map([add_dispatch_tool]);

julia> dispatch_tool(tool_map, "add_dispatch", Dict(:x => 10, :y => 32))
42

julia> tools_schema([add_dispatch_tool])[1]["function"]["name"]
"add_dispatch"

A Note on Provider-Native Tools

Some LLM providers offer built-in server-side tools — for example, Google Search in Gemini, web search in Claude, or code interpreter in OpenAI. These are not standard function-calling tools; they require provider-specific API parameters and return results in different formats.

NimbleAgents currently supports standard function-calling tools for its built-in OpenAI and Gemini providers. Provider-native tools are not yet supported.

In the meantime, NimbleAgents includes built-in tools that cover similar ground:

Provider-native toolNimbleAgents equivalent
Gemini Google Searchsearch_web (via Tavily API) + fetch_webpage
Claude web searchsearch_web + fetch_webpage
OpenAI code interpretereval_julia_tool (persistent Julia sandbox)

These work across all providers since they use standard function calling.