Modules
An agent: model + instructions + tools + output spec, runnable as a loop that alternates between calling the model and executing tools until a final result is produced.
Composable middleware that observes/transforms an agent run at well-defined
points. This is ExAgent's "capabilities" spine, modelled the Elixir way: a
behaviour whose callbacks default to no-ops via use ExAgent.Capability, so
a capability overrides only the hooks it cares about.
Message and part types exchanged between the agent and a model.
Request & response part structs.
A retry prompt: validation errors (list of maps) or a plain message, sent back to the model so it can correct itself.
A system / instruction prompt part.
A plain text chunk returned by the model.
A reasoning / chain-of-thought part (provider-dependent).
The model asking the agent to run a tool.
The return value of a tool call, fed back to the model.
A user prompt part (text or multimodal content list).
A message sent to the model.
A message returned by the model.
Token accounting for a single model response.
Behaviour that every provider model implements.
Advisory declaration of what a given model/provider supports, so callers and future capabilities can negotiate gracefully per model — e.g. whether the provider can do native JSON-schema output, forced tool calls, or extended thinking.
The per-request contract handed to a model. It bundles the tools the agent has prepared (function tools + output tools), the negotiated output mode, and the structured-output schema (if any).
A tool or output validator can return/raise this to ask the model to try
again. In Elixir we mostly use {:error, reason} tuples, but this exception
exists for the rescue-based escape hatch.
Per-request knobs sent to the model. Provider-specific options that are not
first-class fields can be carried in the immutable :extra map.
Anthropic Messages API provider, or any endpoint that speaks the same format
(e.g. Z.AI's /api/anthropic, which serves GLM models natively in Anthropic
form).
OpenAI Chat Completions provider. Talks the real API over Req.
OpenRouter provider.
A deterministic, in-process model for development and tests.
Structured output via Ecto schemas and changesets.
Implementation for providers that speak the Anthropic Messages API:
POST {base_url}/v1/messages.
Shared implementation for any provider that speaks the OpenAI Chat
Completions wire format (/v1/chat/completions). This covers OpenAI itself
and OpenRouter (and DeepSeek, Groq, Together, etc.).
Turn a Req asynchronous response into a lazy Stream of Server-Sent-Events.
Structured error returned by providers for transport/API failures.
The context object threaded through dynamic instructions, tool calls and output validators during a single run.
Convert Elixir type expressions (as written in :: annotations / typespecs)
into JSON Schema fragments — the foundation for deftool and structured
output.
Telemetry event helpers.
A tool the model may call.
Define tools as plain Elixir functions, with their JSON Schema derived from
:: type annotations and @doc strings — no hand-written schemas.
Raised/returned when the model behaves in a way the loop cannot recover from (retries exhausted, no progress, usage limits hit).
Run-level safety net: caps on requests and token usage, enforced before each model request.