ReqLLM.Providers.OpenAI (ReqLLM v1.4.0)

View Source

OpenAI provider implementation with multi-driver architecture for Chat, Responses, and Images APIs.

Architecture

This provider uses a metadata-driven routing system to dispatch requests to specialized API drivers:

The provider automatically routes requests based on the operation type and model metadata:

  • :image operations → uses ImagesAPI driver
  • :chat operations with "api": "responses" → uses ResponsesAPI driver
  • :chat operations (default) → uses ChatAPI driver

Capabilities

Chat Completions API (ChatAPI)

  • Text generation with GPT models
  • Streaming responses with usage tracking
  • Tool calling (function calling)
  • Multi-modal inputs (text and images)
  • Embeddings generation
  • Full OpenAI Chat API compatibility

Responses API (ResponsesAPI)

  • Extended reasoning for o1/o3/o4/GPT-4.1/GPT-5 models
  • Reasoning effort control (minimal, low, medium, high)
  • Streaming with reasoning token tracking
  • Tool calling with responses-specific format
  • Enhanced usage metrics including :reasoning_tokens

Images API (ImagesAPI)

  • Image generation with DALL-E and gpt-image-* models
  • Multiple output formats: PNG, JPEG, WebP (gpt-image-* only)
  • Size and aspect ratio control
  • Quality and style options (DALL-E 3)
  • Returns images as ReqLLM.Message.ContentPart with :image or :image_url type
  • Streaming not supported

Usage Normalization

Chat and Responses drivers normalize usage metrics to provide consistent field names:

  • :reasoning_tokens - Primary field for reasoning token count (ResponsesAPI)
  • :reasoning - Backward-compatibility alias (deprecated, use :reasoning_tokens)

Deprecation Notice: The :reasoning usage key is deprecated in favor of :reasoning_tokens and will be removed in a future version.

Configuration

Set your OpenAI API key via environment variable or application config:

# Option 1: Environment variable (automatically loaded from .env via dotenvy)
OPENAI_API_KEY=sk-...

# Option 2: Store in application config
ReqLLM.put_key(:openai_api_key, "sk-...")

Examples

# Simple text generation (ChatAPI)
model = ReqLLM.model("openai:gpt-4")
{:ok, response} = ReqLLM.generate_text(model, "Hello!")

# Reasoning model (ResponsesAPI)
model = ReqLLM.model("openai:o1")
{:ok, response} = ReqLLM.generate_text(model, "Solve this problem...")
response.usage.reasoning_tokens  # Reasoning tokens used

# Streaming with reasoning
{:ok, stream} = ReqLLM.stream_text(model, "Complex question", stream: true)

# Tool calling (both APIs)
tools = [%ReqLLM.Tool{name: "get_weather", ...}]
{:ok, response} = ReqLLM.generate_text(model, "What's the weather?", tools: tools)

# Embeddings (ChatAPI)
{:ok, embedding} = ReqLLM.generate_embedding("openai:text-embedding-3-small", "Hello world")

# Reasoning effort (ResponsesAPI)
{:ok, response} = ReqLLM.generate_text(
  "openai:gpt-5",
  "Hard problem",
  reasoning_effort: :high
)

# Image generation (ImagesAPI)
{:ok, response} = ReqLLM.generate_image("openai:gpt-image-1", "A futuristic city at sunset")

# DALL-E with options
{:ok, response} = ReqLLM.generate_image(
  "openai:dall-e-3",
  "A watercolor painting of a forest",
  size: {1792, 1024},
  quality: :hd,
  style: :natural
)

Summary

Functions

Default implementation of attach/3.

Custom attach_stream to route reasoning models to /v1/responses endpoint for streaming.

Default implementation of build_body/1.

Custom decode_response to delegate to the selected API module.

Custom decode_stream_event to route based on model API type.

Custom body encoding that delegates to the selected API module.

Default implementation of extract_usage/2.

Custom prepare_request to route requests to appropriate API endpoints.

Translates provider-specific options for different model types.

Functions

attach(request, model_input, user_opts)

Default implementation of attach/3.

Sets up Bearer token authentication and standard pipeline steps.

attach_stream(model, context, opts, finch_name)

Custom attach_stream to route reasoning models to /v1/responses endpoint for streaming.

base_url()

build_body(request)

Default implementation of build_body/1.

Builds request body using OpenAI-compatible format for chat and embedding operations.

decode_response(request_response)

Custom decode_response to delegate to the selected API module.

Auto-detects the API type from the response body if not already set. This is important for fixture replay where api_mod isn't set during prepare_request.

decode_stream_event(event, model)

Custom decode_stream_event to route based on model API type.

default_base_url()

default_env_key()

Callback implementation for ReqLLM.Provider.default_env_key/0.

encode_body(request)

Custom body encoding that delegates to the selected API module.

extract_usage(body, model)

Default implementation of extract_usage/2.

Extracts usage data from standard usage field in response body.

prepare_request(operation, model_spec, input, opts)

Custom prepare_request to route requests to appropriate API endpoints.

  • :image operations route to /v1/images/generations via ImagesAPI
  • :chat operations detect model type and route to ChatAPI or ResponsesAPI
  • :object operations maintain OpenAI-specific token handling

provider_extended_generation_schema()

provider_id()

provider_schema()

supported_provider_options()

translate_options(operation, model, opts)

Translates provider-specific options for different model types.

Uses a profile-based system to apply model-specific parameter transformations. Profiles are resolved from model metadata and capabilities, making it easy to add new model-specific rules without modifying this function.

Reasoning Models

Models with reasoning capabilities (o1, o3, o4, gpt-5, etc.) have special parameter requirements:

  • max_tokens is renamed to max_completion_tokens
  • temperature may be unsupported or restricted depending on the specific model

Returns

{translated_opts, warnings} where warnings is a list of transformation messages.