ExAgent.Providers.OpenAIChat (ExAgent v0.1.0)

Copy Markdown View Source

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

The two directions every provider needs:

  • encode — our Message history → the messages array the API expects (roles system / user / assistant / tool), and our Tool list → the tools array.
  • decode — the API JSON response back into our Message.Response with TextPart / ToolCallPart parts and Usage.

Providers are thin structs carrying {:model, :api_key, :base_url, :extra_headers}; request/4 reads those fields generically, so the same code drives %OpenAI{} and %OpenRouter{}.

Summary

Functions

Encode a list of Tool into the OpenAI tools payload (or nil).

Perform a (non-streaming) chat-completions request.

Perform a streaming chat-completions request. Returns a lazy stream of

Functions

encode_tools(tools)

@spec encode_tools([ExAgent.Tool.t()]) :: [map()] | nil

Encode a list of Tool into the OpenAI tools payload (or nil).

parse_response(body, config)

@spec parse_response(
  map(),
  struct()
) :: ExAgent.Message.Response.t()

request(model, messages, settings, params)

Perform a (non-streaming) chat-completions request.

request_stream(model, messages, settings, params)

@spec request_stream(
  struct(),
  [ExAgent.Message.t()],
  ExAgent.ModelSettings.t() | nil,
  ExAgent.ModelRequestParameters.t()
) :: Enumerable.t() | {:error, term()}

Perform a streaming chat-completions request. Returns a lazy stream of:

  • {:text_delta, binary} — incremental text,
  • {:response, Response.t()} — the final assembled response,
  • {:error, reason} on failure.

to_openai_messages(messages)

@spec to_openai_messages([ExAgent.Message.t()]) :: [map()]