ExAgent.Model behaviour (ExAgent v0.1.0)

Copy Markdown View Source

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

messages()

@type messages() :: [ExAgent.Message.t()]

model()

@type model() :: struct()

Callbacks

model_name(model)

@callback model_name(model()) :: String.t()

profile(model)

(optional)
@callback profile(model()) :: ExAgent.ModelProfile.t()

Declares this model's capabilities (optional; defaults are permissive).

request(model, messages, arg3, t)

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

request_stream(model, messages, arg3, t)

(optional)
@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.

system(model)

@callback system(model()) :: String.t()

Functions

model_name(model)

@spec model_name(model()) :: String.t()

profile(model)

@spec profile(model()) :: ExAgent.ModelProfile.t()

request(model, messages, settings, params)

@spec request(
  model(),
  messages(),
  ExAgent.ModelSettings.t() | nil,
  ExAgent.ModelRequestParameters.t()
) ::
  {:ok, ExAgent.Message.Response.t(), model()} | {:error, term()}

request_stream(model, messages, settings, params)

resolve(model)

@spec resolve(model() | String.t()) :: {:ok, model()} | {:error, term()}

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

system(model)

@spec system(model()) :: String.t()