Tools
Copy MarkdownRun the setup in IEx first.
Capabilities
A capability is a module that returns an agent's tools:
defmodule MyApp.Orders do
@behaviour WardrikCore.Capability
@impl true
def tools(_context, orders) do
[
WardrikCore.Tool.new!(
name: "order_status",
description: "Say where an order is.",
schema: [order_id: [type: :string, required: true]],
run: fn %{order_id: id}, _context -> {:ok, Map.get(orders, id, "unknown")} end
)
]
end
end
{:ok, agent} =
WardrikCore.start_agent(
agent_id: "support",
model: "anthropic:claude-haiku-4-5",
capabilities: [{MyApp.Orders, %{"1001" => "shipped"}}]
)
:ok = WardrikCore.ask(agent, "Where is order 1001?")- The second element, here the orders, is passed to
tools/2as options. - Each call runs in its own process. A crash or timeout becomes an error the model sees.
Annotations
tool =
WardrikCore.Tool.new!(
name: "order_status",
description: "Say where an order is.",
schema: [order_id: [type: :string, required: true]],
run: fn %{order_id: _id}, _context -> {:ok, "shipped"} end,
annotations: [read_only: true, idempotent: true]
)
WardrikCore.Tool.annotation(tool, :idempotent)
#=> true- A
read_onlyoridempotentcall is retried on failure, and repeated after a crash. - Other packages read them too, such as a policy that allows every
read_onlytool. - See
WardrikCore.Toolfor the full list.
Reporting cost
Return the context with a measurement added:
WardrikCore.Tool.new!(
name: "enrich",
description: "Find a person's company from their email.",
schema: [email: [type: :string, required: true]],
run: fn %{email: email}, context ->
{:ok, %{email: email, company: "Acme"}, WardrikCore.Context.measure(context, :usd, 0.01)}
end
)The cost adds up on the tool call and the turn. See Tracing.