Alloy.Tool behaviour (alloy v0.7.4)

Copy Markdown View Source

Behaviour for tools that agents can call.

Required Callbacks

Every tool must implement name/0, description/0, input_schema/0, and execute/2.

Optional Callbacks

Tools may optionally implement:

  • allowed_callers/0 — declares which callers may invoke this tool (:human, :code_execution). Defaults to [:human].
  • result_type/0 — declares whether the tool returns :text or :structured data. Defaults to :text.

Structured Results

Tools can return a 3-tuple {:ok, text, data} where text is the human-readable result and data is a map of structured data for programmatic consumption (e.g., by a code execution sandbox).

Path Security

Set :allowed_paths in the agent context to restrict file access:

Alloy.run("Read the config",
  context: %{allowed_paths: ["/home/user/project"]},
  tools: [Alloy.Tool.Core.Read]
)

When configured, resolve_path/2 returns {:error, reason} for paths outside the allowed directories.

Example

defmodule MyApp.Tools.Weather do
  @behaviour Alloy.Tool

  @impl true
  def name, do: "get_weather"

  @impl true
  def description, do: "Get current weather for a location"

  @impl true
  def input_schema do
    %{
      type: "object",
      properties: %{location: %{type: "string", description: "City name"}},
      required: ["location"]
    }
  end

  @impl true
  def execute(%{"location" => loc}, _context) do
    {:ok, "72°F, sunny in #{loc}", %{temp: 72, condition: "sunny", location: loc}}
  end

  @impl true
  def allowed_callers, do: [:human, :code_execution]

  @impl true
  def result_type, do: :structured
end

Summary

Callbacks

Declares which callers may invoke this tool.

Human-readable description of what the tool does.

Execute the tool with the given input.

JSON Schema defining the tool's input parameters.

Unique tool name (used in API calls).

Declares the tool's result type.

Functions

Resolve a file path against the working directory from context.

Callbacks

allowed_callers()

(optional)
@callback allowed_callers() :: [:human | :code_execution]

Declares which callers may invoke this tool.

  • :human — the tool can be called by the model during normal conversation
  • :code_execution — the tool can be called from a code execution sandbox

Defaults to [:human] when not implemented. Providers that support allowed_callers (e.g., Anthropic) include this in the tool definition sent to the API.

description()

@callback description() :: String.t()

Human-readable description of what the tool does.

execute(input, context)

@callback execute(input :: map(), context :: map()) ::
  {:ok, String.t()} | {:ok, String.t(), map()} | {:error, String.t()}

Execute the tool with the given input.

Context is a map that may contain:

  • :working_directory - base path for file operations
  • :config - agent config struct
  • :allowed_paths - list of allowed directory prefixes for file access
  • any custom keys added by middleware

Returns {:ok, string} or {:error, string} for text-only results. Optionally returns {:ok, string, map} to include structured data alongside the text (for programmatic consumption by code execution).

input_schema()

@callback input_schema() :: map()

JSON Schema defining the tool's input parameters.

name()

@callback name() :: String.t()

Unique tool name (used in API calls).

result_type()

(optional)
@callback result_type() :: :text | :structured

Declares the tool's result type.

  • :text — tool returns {:ok, String.t()} (the default)
  • :structured — tool returns {:ok, String.t(), map()}

Used by the executor and downstream consumers to know whether structured data is available in the tool result metadata.

Functions

resolve_path(file_path, context)

@spec resolve_path(String.t(), map()) :: {:ok, String.t()} | {:error, String.t()}

Resolve a file path against the working directory from context.

Absolute paths are returned as-is. Relative paths are joined with the :working_directory from context, or expanded from cwd if not set.

When :allowed_paths is set in context, validates the resolved path falls within one of the allowed directories. Returns {:error, reason} if the path is outside the allowed directories.