Providers
Purpose
codex_ai.providers contains concrete SDK adapters, not a broad interchangeable provider framework. Gemini is the product focus; OpenAI is a separate modern Responses API adapter.
Gemini is the primary target and exposes direct methods for text, JSON, and image generation:
await gemini.generate_text(...)
await gemini.generate_json(...)
await gemini.generate_image_bytes(...)
await gemini.generate_imagen_bytes(...)
OpenAI exposes direct text, structured JSON, and typed streaming helpers:
await openai.generate_text(...)
await openai.generate_json(..., schema=MyModel)
async for chunk in openai.stream_text(...):
...
Architecture
PromptResult/String
│
├── GeminiProvider.generate_text(...) -> str
├── GeminiProvider.generate_json(...) -> dict | BaseModel
├── GeminiProvider.generate_image_bytes(...) -> tuple[bytes, str]
├── GeminiProvider.generate_imagen_bytes(...) -> tuple[bytes, str]
├── OpenAIProvider.generate_text(...) -> str
├── OpenAIProvider.generate_json(...) -> dict | BaseModel
└── OpenAIProvider.stream_text(...) -> AsyncIterator[str]
The legacy router pipeline remains available:
LLMRouter builder -> PromptResult -> LLMDispatcher.process() -> provider.answer() -> str
answer() is a compatibility wrapper for text generation.
Key Components
| Component | Class | SDK | Default Model |
|---|---|---|---|
gemini.py |
GeminiProvider |
google-genai |
gemini-2.5-flash-lite |
openai.py |
OpenAIProvider |
openai 2.x |
gpt-5.6-luna |
Key Design Decisions
- Gemini-specific capabilities are represented directly instead of being hidden behind a broad universal abstraction.
- JSON generation uses provider-native JSON configuration and still validates locally with
json.loadsand optional Pydantic models. - OpenAI uses the Responses API exclusively; the old Chat Completions path is not retained.
- OpenAI requests default to
store=Falseandreasoning={"effort": "none"}. - OpenAI Pydantic schemas use the SDK's native
responses.parse()structured-output path. - The OpenAI SDK client is injectable behind a small Responses API port for deterministic tests and custom transports.
- Gemini image generation and Imagen generation are separate explicit methods because they use different SDK calls.
generate_image_bytes()uses Geminigenerate_contentwith image modality. Itsresponse_mime_typeis only a preferred/fallback MIME type, and Gemini image controls are passed throughimage_config.generate_image_bytes()can also acceptinput_images=[ImageInput(...)]for image reference/edit workflows; withoutinput_images, the prompt-only path is unchanged.generate_image_bytes()retries a rejectedimage_config={"image_size": "4K"}request once as2K.generate_imagen_bytes()uses Imagengenerate_imagesand passes the requested MIME asoutput_mime_type.- Anthropic, OpenRouter, and multi-provider failover are not active APIs in this line.