# `Dsxir.Primitives.Tool`

Value type describing a tool callable by `Dsxir.Predictor.ReAct`.

    %Dsxir.Primitives.Tool{
      name: "calculator",
      description: "Evaluate an arithmetic expression",
      parameters: Zoi.object(%{expression: Zoi.string()}),
      function: fn %{expression: expr} -> Code.eval_string(expr) |> elem(0) |> to_string() end
    }

`parameters` is a Zoi schema. Arguments are validated through it before the
function is invoked; a Zoi failure short-circuits without calling `:function`.

`function` is a 1-arity callable returning a string-coercible value. Any
exception raised inside the function is caught by `execute/2` and surfaced as
an `Dsxir.Errors.Invalid.Tool` value with `reason: :execution_error` so the
ReAct loop can route around it.

`to_sycophant_tool/1` returns a `%Sycophant.Tool{}` with `function: nil` so
Sycophant does not auto-execute the tool. dsxir owns the loop.

# `t`

```elixir
@type t() :: %Dsxir.Primitives.Tool{
  description: String.t(),
  function: (map() -&gt; any()),
  name: String.t(),
  parameters: Zoi.schema()
}
```

# `execute`

```elixir
@spec execute(t(), map()) ::
  {:ok, String.t()} | {:error, Dsxir.Errors.Invalid.Tool.t()}
```

Validate `args` against the tool's Zoi schema and dispatch the function.

Returns `{:ok, observation_string}` on success and `{:error, %Dsxir.Errors.Invalid.Tool{}}`
on validation failure or function exception.

# `new`

```elixir
@spec new(keyword()) :: t()
```

# `to_sycophant_tool`

```elixir
@spec to_sycophant_tool(t()) :: Sycophant.Tool.t()
```

Build a `%Sycophant.Tool{}` shape; `function: nil` keeps Sycophant out of the loop.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
