# `PhoenixKitAgent.Turns.Tools`
[🔗](https://github.com/BeamLabEU/phoenix_kit_agent/blob/v0.1.0/lib/phoenix_kit_agent/turns/tools.ex#L1)

How the tools of a round are shown to the model, and how what it sends back
is taken (spec §6.1 b, f; §6.2, §6.4).

  * The tools are those core lists for the session
    (`PhoenixKit.API.Executor.visible_for/3` with `allow: :all`): the module
    adds no filter of its own and opens nothing beyond them. Whether a
    session sees the write tools of a module is core's setting
    `api_session_write_modules` (the "Agent may act" box of Settings → API),
    and a write never runs on the call: core holds it for the user's
    confirmation (`PhoenixKitAgent.Confirmations`).
  * Names: the model sees `PhoenixKit.API.MCP.Names.to_mcp/1` of the registry
    name (`catalogue.list_products` → `catalogue_list_products`); a name that
    is not 1-64 characters of `[a-zA-Z0-9_-]` (what model APIs accept) is
    left out, and of two tools with one MCP name the first wins
    (`Names.dedupe/1`). `for_model/1` returns the map back from that name to
    the tool, and only a name in it is ever executed.
  * Schemas: `PhoenixKit.API.Executor.input_schema/1` without the control
    fields (`PhoenixKit.API.ControlFields`: `dry_run`, `confirm_token`,
    `idempotency_key`) — the model neither sees nor sets them; they are cut
    from its arguments too (`arguments/1`).
  * Results: the JSON of a result longer than `agent_tool_result_chars` is
    replaced by `%{"truncated" => true, "partial" => <its beginning>, "hint"
    => …}` whose own JSON fits the limit (`fit/2`). The same value is kept in
    the database.

# `arguments`

```elixir
@spec arguments(term()) :: {:ok, map()} | :error
```

The arguments of a tool call as the executor's input: the JSON object the
model sent, without control fields. `:error` for anything that is not a
JSON object.

# `fit`

```elixir
@spec fit(map(), pos_integer()) :: map()
```

`result` as it is kept and sent to the model: itself when its JSON is at
most `limit` characters, else the truncated form (see the moduledoc).

# `for_model`

```elixir
@spec for_model([PhoenixKit.API.Tool.t()]) ::
  {[map()], %{required(String.t()) =&gt; PhoenixKit.API.Tool.t()}}
```

The tool definitions for the model (OpenAI function tools) and the map from
each model name to its tool.

# `held`

```elixir
@spec held(term()) :: {:ok, String.t()} | :error
```

The uuid of the confirmation a write's answer says it waits for — core's
prompt for a live session (`"executed": false`, `"status":
"confirmation_required"`, `"confirmation_id"`) — else `:error`.

# `held_result`

```elixir
@spec held_result(String.t()) :: map()
```

What is kept of a write that waits for confirmation `uuid`, and sent back to
the model: the status and the uuid, never a code, the preview or the
arguments.

---

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