ExAthena.ToolCalls (ExAthena v0.4.2)

Copy Markdown View Source

Extracts tool calls from a provider response.

Two protocols, two 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.

Auto-fallback

extract/2 picks the protocol based on provider_capabilities.native_tool_calls. If native is claimed but the parser finds no tool calls AND the assistant text contains ~~~tool_call fences, it falls back to TextTagged. Conversely, if native returns tool calls, TextTagged is skipped. The agent loop (Phase 2) uses augment_system_prompt/2 to add text-tagged instructions when a provider lacks native support.

Summary

Functions

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

Extract tool calls from a provider response.

Types

provider_response()

@type provider_response() :: %{
  optional(:text) => String.t() | nil,
  optional(:tool_calls) => list() | nil
}

Functions

augment_system_prompt(existing, tools)

@spec augment_system_prompt(String.t() | nil, [map()]) :: 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.

extract(response, capabilities \\ %{})

@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.