Behaviour that every provider model implements.
A "model" is any struct whose module @behaviours ExAgent.Model. The
struct carries the model's own state (base URL, API key, configured
options…). Callers never invoke a provider module directly — they go through
the dispatch functions in this module (request/4, request_stream/4, …),
which resolve the implementer from the struct's __struct__.
This uses Elixir behaviours plus struct dispatch so providers can stay small and explicit.
Summary
Callbacks
Declares this model's capabilities (optional; defaults are permissive).
Make a non-streaming request and return a full Message.Response.
Make a streaming request. Returns an enumerable of events. Implementations
may instead return {:error, _} if streaming is unsupported.
Functions
Resolve a model from a spec. A struct is returned as-is; a string like
"openai:gpt-4o" is resolved via the provider registry (only a few providers
are wired up for now).
Types
@type messages() :: [ExAgent.Message.t()]
@type model() :: struct()
Callbacks
@callback profile(model()) :: ExAgent.ModelProfile.t()
Declares this model's capabilities (optional; defaults are permissive).
@callback request( model :: model(), messages(), ExAgent.ModelSettings.t() | nil, ExAgent.ModelRequestParameters.t() ) :: {:ok, ExAgent.Message.Response.t(), model()} | {:error, term()}
Make a non-streaming request and return a full Message.Response.
Implementations return the (possibly updated) model struct alongside the
response. Real providers return the model unchanged; stateful models (e.g.
the script-driven Test) thread their internal state through the run this
way, avoiding globals.
@callback request_stream( model :: model(), messages(), ExAgent.ModelSettings.t() | nil, ExAgent.ModelRequestParameters.t() ) :: Enumerable.t() | {:error, term()}
Make a streaming request. Returns an enumerable of events. Implementations
may instead return {:error, _} if streaming is unsupported.
Functions
@spec profile(model()) :: ExAgent.ModelProfile.t()
@spec request( model(), messages(), ExAgent.ModelSettings.t() | nil, ExAgent.ModelRequestParameters.t() ) :: {:ok, ExAgent.Message.Response.t(), model()} | {:error, term()}
@spec request_stream( model(), messages(), ExAgent.ModelSettings.t() | nil, ExAgent.ModelRequestParameters.t() ) :: Enumerable.t()
Resolve a model from a spec. A struct is returned as-is; a string like
"openai:gpt-4o" is resolved via the provider registry (only a few providers
are wired up for now).