ExAgent.Tool (ExAgent v0.4.1)

Copy Markdown View Source

Normalized tool definition for LLM function-calling.

Represents a tool that an LLM can invoke, including its name, description, JSON Schema parameters, and the actual function to execute.

:parameters takes either a raw JSON Schema map or an Ecto embedded schema module. With a module, the JSON Schema is generated for you and the arguments are cast before your function runs, so it receives a struct:

defmodule OrderQuery do
  use Ecto.Schema

  @primary_key false
  embedded_schema do
    field :order_id, :string
  end
end

ExAgent.Tool.new(
  name: "order_status",
  description: "Look up the delivery status of an order",
  parameters: OrderQuery,
  function: fn %OrderQuery{order_id: id} -> Repo.get(Order, id) end
)

A typo in the function body is then a compile-time warning rather than a KeyError inside the agent's tool loop. Arguments the model gets wrong are fed back to it as a tool error, which is what lets it correct itself.

Summary

Functions

Casts a model's raw arguments for tool.

Creates a new tool with validated attributes.

Types

t()

@type t() :: %ExAgent.Tool{
  description: String.t(),
  function: (map() | struct() -> any()),
  name: String.t(),
  parameters: map(),
  schema: module() | nil
}

Functions

cast_args(tool, args)

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

Casts a model's raw arguments for tool.

A tool declared with a raw JSON Schema map gets the arguments unchanged. One declared with an Ecto schema gets a struct, or {:error, message} phrased for the model when the arguments do not fit.

new(attrs)

@spec new(keyword()) :: {:ok, t()} | {:error, String.t()}

Creates a new tool with validated attributes.

Examples

iex> {:ok, tool} = ExAgent.Tool.new(name: "search", description: "Search the web", parameters: %{}, function: fn _ -> :ok end)
iex> tool.name
"search"

iex> ExAgent.Tool.new(description: "Search", parameters: %{}, function: fn _ -> :ok end)
{:error, "name is required"}

iex> ExAgent.Tool.new(name: "search", parameters: %{}, function: fn _ -> :ok end)
{:error, "description is required"}