ReqLLM.Provider.Defaults (ReqLLM v1.0.0)
View SourceDefault implementations for common provider behavior patterns.
This module extracts shared logic between OpenAI-compatible providers (OpenAI, Groq, etc.)
into reusable runtime functions and a __using__ macro that provides default callback
implementations.
Usage
defmodule MyProvider do
@behaviour ReqLLM.Provider
use ReqLLM.Provider.DSL, [...]
use ReqLLM.Provider.Defaults
# All default implementations are available and overridable
# Override only what you need to customize
endDesign Principles
- Runtime functions are pure and testable
- Provider module is passed as first argument to access attributes
- All defaults are
defoverridablefor selective customization - Providers can override individual methods or use helper functions directly
Default Implementations
The following methods get default implementations:
prepare_request/4- Standard chat/object/embedding request preparationattach/3- OAuth Bearer authentication and standard pipeline stepsencode_body/1- OpenAI-compatible request body encodingdecode_response/1- Standard response decoding with error handlingextract_usage/2- Usage extraction from standardusagefieldtranslate_options/3- No-op translation (pass-through)decode_stream_event/2- OpenAI-compatible SSE event decodingattach_stream/4- OpenAI-compatible streaming request buildingdisplay_name/0- Human-readable provider name from provider_id
Runtime Functions
All default implementations delegate to pure runtime functions that can be called independently:
prepare_chat_request/4prepare_object_request/4prepare_embedding_request/4default_attach/3default_encode_body/1default_decode_response/1default_extract_usage/2default_translate_options/3default_decode_stream_event/2default_attach_stream/5default_display_name/1
Customization Examples
# Override just the body encoding while keeping everything else
def encode_body(request) do
request
|> ReqLLM.Provider.Defaults.default_encode_body()
|> add_custom_headers()
end
# Use runtime functions directly for testing
test "encoding produces correct format" do
request = build_test_request()
encoded = ReqLLM.Provider.Defaults.default_encode_body(request)
assert encoded.body =~ ~s("model":")
end
Summary
Functions
Provides default implementations for common provider patterns.
Build a complete OpenAI-style chat body from a Req request.
Decodes OpenAI-format response body to ReqLLM.Response.
Default attachment implementation with Bearer token auth and standard pipeline steps.
Default implementation of attach_stream/4.
Default response decoding with success/error handling.
Default SSE event decoding for OpenAI-compatible providers.
Default display name implementation.
Default body encoding for OpenAI-compatible APIs.
Default usage extraction from standard usage field.
Default options translation (pass-through).
Encodes ReqLLM.Context to OpenAI-compatible format.
Prepares a chat completion request.
Prepares an embedding generation request.
Prepares an object generation request using tool calling.
Runtime implementation of prepare_request/4.
Functions
Provides default implementations for common provider patterns.
All methods are defoverridable, so providers can selectively override
only the methods they need to customize.
Build a complete OpenAI-style chat body from a Req request.
This helper function encodes context, adds common options (temperature, max_tokens, etc.), converts tools to OpenAI schema, and handles stream flags. Providers can use this as a starting point and add provider-specific fields.
Example
def encode_body(req) do
body = Defaults.build_openai_chat_body(req)
|> Map.put(:my_provider_field, req.options[:my_provider_field])
req
|> Req.Request.put_header("content-type", "application/json")
|> Map.put(:body, Jason.encode!(body))
end
@spec decode_response_body_openai_format(map(), ReqLLM.Model.t()) :: {:ok, ReqLLM.Response.t()} | {:error, term()}
Decodes OpenAI-format response body to ReqLLM.Response.
This function moves the logic from ReqLLM.Response.Codec.Map directly into Provider.Defaults for the protocol removal refactoring.
@spec default_attach(module(), Req.Request.t(), term(), keyword()) :: Req.Request.t()
Default attachment implementation with Bearer token auth and standard pipeline steps.
@spec default_attach_stream( module(), ReqLLM.Model.t(), ReqLLM.Context.t(), keyword(), atom() ) :: {:ok, Finch.Request.t()} | {:error, Exception.t()}
Default implementation of attach_stream/4.
Builds complete streaming requests using OpenAI-compatible format and returns a complete Finch.Request.t() ready for streaming execution.
@spec default_decode_response({Req.Request.t(), Req.Response.t()}) :: {Req.Request.t(), Req.Response.t() | Exception.t()}
Default response decoding with success/error handling.
@spec default_decode_stream_event(map(), ReqLLM.Model.t()) :: [ReqLLM.StreamChunk.t()]
Default SSE event decoding for OpenAI-compatible providers.
This function moves the logic from ReqLLM.Response.Codec.Map directly into Provider.Defaults for the protocol removal refactoring.
Default display name implementation.
Returns a human-readable display name based on the provider_id from DSL, or falls back to capitalizing the module name.
@spec default_encode_body(Req.Request.t()) :: Req.Request.t()
Default body encoding for OpenAI-compatible APIs.
@spec default_extract_usage(term(), ReqLLM.Model.t() | nil) :: {:ok, map()} | {:error, term()}
Default usage extraction from standard usage field.
@spec default_translate_options(atom(), ReqLLM.Model.t(), keyword()) :: {keyword(), [String.t()]}
Default options translation (pass-through).
@spec encode_context_to_openai_format(ReqLLM.Context.t(), String.t()) :: map()
Encodes ReqLLM.Context to OpenAI-compatible format.
This function moves the logic from ReqLLM.Context.Codec.Map directly into Provider.Defaults for the protocol removal refactoring.
@spec prepare_chat_request(module(), term(), term(), keyword()) :: {:ok, Req.Request.t()} | {:error, Exception.t()}
Prepares a chat completion request.
@spec prepare_embedding_request(module(), term(), term(), keyword()) :: {:ok, Req.Request.t()} | {:error, Exception.t()}
Prepares an embedding generation request.
@spec prepare_object_request(module(), term(), term(), keyword()) :: {:ok, Req.Request.t()} | {:error, Exception.t()}
Prepares an object generation request using tool calling.
@spec prepare_request(module(), atom(), term(), term(), keyword()) :: {:ok, Req.Request.t()} | {:error, Exception.t()}
Runtime implementation of prepare_request/4.
Delegates to operation-specific preparation functions.