# `ReqLLM.Providers.OpenAI`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/providers/openai.ex#L1)

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

## Architecture

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

- **ChatAPI** (`ReqLLM.Providers.OpenAI.ChatAPI`) - Handles `/v1/chat/completions` endpoint
  for models like GPT-4, GPT-3.5, and other chat-based models.

- **ResponsesAPI** (`ReqLLM.Providers.OpenAI.ResponsesAPI`) - Handles `/v1/responses` endpoint
  for models such as GPT-4.1, GPT-4o, o-series, and GPT-5.

- **DecisionsAPI** (`ReqLLM.Providers.OpenAI.DecisionsAPI`) - Handles `/v1/decisions` for
  provider-neutral evaluation calls.

- **ImagesAPI** (`ReqLLM.Providers.OpenAI.ImagesAPI`) - Handles `/v1/images/generations` endpoint
  for image generation models (DALL-E 2, DALL-E 3, gpt-image-*). A thin adapter over
  `ReqLLM.Images.OpenAICompatible`, the codec shared with every provider that speaks the
  same wire format.

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 o-series and GPT-5 models
- Reasoning effort control (minimal, low, medium, high)
- Reasoning summary control (`:auto`, `:concise`, `:detailed`)
- Streaming with reasoning token tracking
- Tool calling with responses-specific format
- Enhanced usage metrics including `:reasoning_tokens`

### Images API (ImagesAPI)
- Image generation and edit with gpt-image-* models
- Multiple output formats: PNG, JPEG, WebP (gpt-image-* only)
- Size and aspect ratio control
- gpt-image quality tiers (`:auto`, `:low`, `:medium`, `:high`), `:background`
  (`:transparent` needs PNG or WebP output), `:moderation`, `:output_compression`
  (JPEG/WebP), and `:input_fidelity` on edits
- Quality and style options (DALL-E 3); `response_format: :url` is DALL-E only
- Returns images as `ReqLLM.Message.ContentPart` with `:image` or `:image_url` type
- Streaming generation via `ReqLLM.stream_image/3` (gpt-image-* only): preview
  frames with `:partial_images`, then the final image; edits do not stream

## Explicit Prompt Caching

GPT-5.6 and later models support explicit cache breakpoints. Add
`prompt_cache_breakpoint` to content-part metadata and configure the request-wide
policy through provider options:

    cached_part =
      ReqLLM.Message.ContentPart.text("Stable instructions", %{
        prompt_cache_breakpoint: %{mode: "explicit"}
      })

    ReqLLM.generate_text(model, ReqLLM.Context.user([cached_part]),
      provider_options: [
        prompt_cache_key: "tenant:acme:instructions-v1",
        prompt_cache_options: %{mode: "explicit", ttl: "30m"}
      ]
    )

Both the Chat Completions API and Responses API support these options.

## 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 (loaded from .env under Mix)
    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
    )

# `attach`

Default implementation of attach/3.

Sets up Bearer token authentication and standard pipeline steps.

# `attach_stream`

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

# `attach_websocket_stream`

# `base_url`

# `build_body`

Default implementation of build_body/1.

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

# `decode_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`

Custom decode_stream_event to route based on model API type.

# `default_base_url`

# `default_env_key`

# `encode_body`

Custom body encoding that delegates to the selected API module.

# `extract_usage`

Default implementation of extract_usage/2.

Extracts usage data from standard `usage` field in response body.

# `prepare_request`

Custom prepare_request to route requests to appropriate API endpoints.

- :image operations route to `/v1/images/generations` or `/v1/images/edits` 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`

# `start_responses_session`

# `supported_provider_options`

# `translate_options`

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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
