# `ExAthena.ToolCalls`
[🔗](https://github.com/udin-io/ex_athena/blob/v0.7.1/lib/ex_athena/tool_calls.ex#L1)

Extracts tool calls from a provider response.

Three parsers:

  * `ExAthena.ToolCalls.Native` — structured `tool_calls` array from the
    provider (OpenAI-style `function` + `arguments`, Claude `tool_use`
    blocks, Ollama's OpenAI-compatible payload).
  * `ExAthena.ToolCalls.TextTagged` — prompt-engineered
    `~~~tool_call <json> ~~~` blocks embedded in the assistant's text.
  * `ExAthena.ToolCalls.RawJson` — bare or `` ```json ``-fenced JSON objects
    emitted by weak open-weight models that ignore both native tool-call
    APIs and the `~~~tool_call` fence format.

## Auto-fallback

`extract/2` cascades through three tiers based on the response content and
`provider_capabilities.native_tool_calls`:

  1. Structured `tool_calls` present → `Native.parse/1`.
  2. Text contains `~~~tool_call` fences, or provider declared no native
     support → `TextTagged.parse/1`.
  3. Text looks like a raw JSON tool call (has both `"name"` and
     `"arguments"` substrings) → `RawJson.parse/1`.
  4. No match → `{:ok, []}`.

The agent loop uses `augment_system_prompt/2` to add text-tagged instructions
when a provider lacks native support.

# `provider_response`

```elixir
@type provider_response() :: %{
  optional(:text) =&gt; String.t() | nil,
  optional(:tool_calls) =&gt; list() | nil
}
```

# `augment_system_prompt`

```elixir
@spec augment_system_prompt(String.t() | nil, [map()], keyword()) :: String.t()
```

Append text-tagged tool-call instructions to a system prompt so
non-native-tool-call providers know how to respond.

The agent loop (Phase 2) calls this when the chosen provider lacks native
tool-call support, or when the user has forced TextTagged mode.

## Options

  * `:compact` — when `true`, emits a one-line-per-tool signature instead
    of the full JSON schema. Useful for weak open-weight models that degrade
    past ~4 KB system prompts. Default: `false`.

# `extract`

```elixir
@spec extract(provider_response(), ExAthena.Capabilities.t()) ::
  {:ok, [ExAthena.Messages.ToolCall.t()]} | {:error, term()}
```

Extract tool calls from a provider response.

Returns `{:ok, [ToolCall.t()]}` — always a list (possibly empty), never
`nil`. Pass capabilities so the parser can pick the right protocol.

---

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