Behaviour for LLM providers.
Each provider translates between its native wire format and Alloy's
normalized Alloy.Message structs. The agent loop only sees normalized
messages - adding a new provider means implementing this behaviour.
Completion Response
Providers return a map with:
:stop_reason-:tool_use(continue looping) or:end_turn(done):messages- list ofAlloy.Messagestructs from the response:usage- map with:input_tokensand:output_tokens:provider_state- optional opaque map Alloy feeds back to the same provider on subsequent turns (for example, stored response IDs):response_metadata- optional provider response metadata exposed to the app layer (for example, citations or server-side tool usage)
Summary
Callbacks
Send messages to the provider and get a completion response.
Stream a completion, calling on_chunk for each text delta.
Functions
Decode a JSON binary response body, passing through maps unchanged.
Recursively convert atom keys to strings in maps.
Types
@type completion_response() :: %{ :stop_reason => stop_reason(), :messages => [Alloy.Message.t()], :usage => map(), optional(:provider_state) => map(), optional(:response_metadata) => map() }
@type stop_reason() :: :tool_use | :end_turn
Callbacks
@callback complete( messages :: [Alloy.Message.t()], tool_defs :: [tool_def()], config :: map() ) :: {:ok, completion_response()} | {:error, term()}
Send messages to the provider and get a completion response.
Parameters
messages- Conversation history as normalizedAlloy.Messagestructstool_defs- Tool definitions (JSON Schema format)config- Provider-specific configuration (API keys, model, etc.)
Returns
{:ok, completion_response()}on success{:error, term()}on failure
@callback stream( messages :: [Alloy.Message.t()], tool_defs :: [tool_def()], config :: map(), on_chunk :: (String.t() -> :ok) ) :: {:ok, completion_response()} | {:error, term()}
Stream a completion, calling on_chunk for each text delta.
Returns the same {:ok, completion_response()} as complete/3 once
the stream finishes -- the full accumulated response.
Functions
Decode a JSON binary response body, passing through maps unchanged.
Returns {:ok, decoded_map} or {:error, reason}.
Recursively convert atom keys to strings in maps.
Used by providers to prepare JSON-compatible request bodies.