Responses API to Chat Completions bridge for Codex CLI
Project description
codex-bridge-python
A lightweight Python proxy that translates the OpenAI Responses API used by Codex into the standard Chat Completions API, so Codex can work with OpenAI-compatible providers such as DashScope (Qwen), DeepSeek, Kimi, OpenRouter, Groq, xAI, and others.
Why
Codex speaks the OpenAI Responses API. Many non-OpenAI providers expose only
the Chat Completions API. codex-bridge-python sits between Codex and your upstream
provider, translating requests and responses on the fly so you can keep using
Codex normally.
What It Does
- Accepts Codex
POST /v1/responsesrequests locally - Translates them into upstream
POST /v1/chat/completions - Converts blocking and streaming Chat Completions responses back into Responses API format
- Preserves session history for
previous_response_id - Proxies
/v1/modelsand normalizes the response shape for Codex clients - Generates a Codex config snippet plus model catalog JSON via
--print-config
Install
Install from PyPI:
python3 -m pip install codex-bridge-python
After installation, the codex-bridge-python command is available on your PATH.
Quick Start
The simplest launch form is:
codex-bridge-python base_url api_key model
For example:
codex-bridge-python https://dashscope.aliyuncs.com/compatible-mode/v1 sk-xxxx deepseek-v4-flash
You can also pass a fourth positional argument, context_size:
codex-bridge-python base_url api_key model context_size
For example:
codex-bridge-python https://dashscope.aliyuncs.com/compatible-mode/v1 sk-xxxx deepseek-v4-flash 262144
After the first successful launch, you can run it again without arguments if
~/.codex-bridge-python/config.toml and ~/.codex-bridge-python/auth.json
already exist:
codex-bridge-python
If any required value cannot be restored from the saved config, codex-bridge-python
prints exactly which values are missing.
What this mode does
- starts
codex-bridge-pythonon127.0.0.1:5057 - stores bridge state and Codex config in
~/.codex-bridge-python - writes a minimal
config.tomlthat points Codex at the local bridge - saves your second argument into
~/.codex-bridge-python/auth.jsonand exports it asOPENAI_API_KEY - uses your third argument as the model written into Codex config and the bridge's forced upstream model
- uses your optional fourth argument as the Codex context window size
- writes
model_context_window,model_auto_compact_token_limit, and enables request compression for Codex - starts the
codexCLI as a child process in the current directory, unless you launch from~, in which case it switches the workdir to~/.codex-bridge-pythonto avoid config conflicts with~/.codex - accumulates model metadata in
~/.codex-bridge-python/model-catalog.local.jsonand only adds or refreshes the currently selected model entry while keeping existing entries
If you omit the context-window argument, codex-bridge-python first tries any saved
value for the same model, otherwise falls back to a model-name-based estimate,
and finally defaults to 128000.
Development Install
Install from source:
python3 -m pip install .
Build a wheel locally and install it:
python3 -m build --wheel
python3 -m pip install dist/codex_bridge_python-<version>-py3-none-any.whl
Or download a prebuilt wheel from GitHub Releases and install it directly:
python3 -m pip install /path/to/codex_bridge_python-<version>-py3-none-any.whl
For editable local development:
python3 -m pip install -e ".[dev]"
Advanced Usage
The simplified launcher is the recommended path, but the original flag-based bridge mode is still available and works with the current version.
The two modes use different port behavior:
- Simplified launcher: always uses
127.0.0.1:5057 - Advanced standalone bridge mode:
--portis configurable and still defaults to4444
Start the bridge manually
You can still run codex-bridge-python as a standalone local bridge:
codex-bridge-python --upstream https://dashscope.aliyuncs.com/compatible-mode/v1 --api-key sk-xxxx --port 4448
Generate a Codex config snippet
The --print-config mode is still available:
codex-bridge-python --print-config --upstream https://dashscope.aliyuncs.com/compatible-mode/v1 --api-key sk-xxxx --port 4448
CLI Reference
| Flag | Env var | Default | Description |
|---|---|---|---|
--port |
CODEX_BRIDGE_PORT |
4444 |
Local listen port |
--upstream |
CODEX_BRIDGE_UPSTREAM |
https://openrouter.ai/api/v1 |
Upstream Chat Completions base URL |
--api-key |
CODEX_BRIDGE_API_KEY |
(empty) | API key forwarded to upstream |
--print-config |
(none) | — | Print a Codex config snippet and exit |
--force-default-model |
CODEX_BRIDGE_FORCE_DEFAULT_MODEL |
false |
Ignore the incoming request model and always forward the default model |
--default-model |
CODEX_BRIDGE_DEFAULT_MODEL |
deepseek-v4-flash |
Target model used when forced default model routing is enabled |
--max-sessions |
CODEX_BRIDGE_MAX_SESSIONS |
256 |
Maximum retained completed sessions |
--max-session-memory-mb |
CODEX_BRIDGE_MAX_SESSION_MEMORY_MB |
512 |
Approximate memory budget for retained session and reasoning state |
--session-ttl-hours |
CODEX_BRIDGE_SESSION_TTL_HOURS |
168 |
Idle session retention window in hours |
--history-store |
CODEX_BRIDGE_HISTORY_STORE |
memory |
Session backend: memory or disk |
--history-dir |
CODEX_BRIDGE_HISTORY_DIR |
.codex-bridge-python-history |
Disk history directory when history-store=disk |
Extra Environment Variables
These are supported by the implementation even though they are not exposed as CLI flags:
| Variable | Default | Description |
|---|---|---|
CODEX_BRIDGE_MODEL_MAP |
(empty) | Comma-separated model remaps such as gpt-5.4:qwen-plus |
CODEX_BRIDGE_TOOL_DENYLIST |
(empty) | Comma-separated tool names to drop before forwarding upstream |
CODEX_BRIDGE_LOG |
codex_bridge=info |
Logging level hint, for example debug, info, warning, error |
If CODEX_BRIDGE_FORCE_DEFAULT_MODEL=true, every incoming request model is
rewritten to CODEX_BRIDGE_DEFAULT_MODEL. When
CODEX_BRIDGE_DEFAULT_MODEL is unset, it defaults to deepseek-v4-flash.
Features
- Blocking responses: Converts standard Chat Completions responses into
Responses API
outputitems - Streaming: Emits Responses-style SSE events such as
response.created,response.output_text.delta,response.function_call_arguments.delta, andresponse.completed - Tool calls: Flattens Responses-style tools into Chat Completions tool schemas and round-trips returned function calls
- Namespace tools: Expands
namespacetool groups into individually callable upstream tools while preserving reversible naming - Parallel tool calls: Consecutive function calls are grouped into a single assistant turn for upstream compatibility
- Reasoning content retention: Retains provider reasoning content across tool-call turns where possible
- Session continuation: Stores translated history for
previous_response_id - Spawned child isolation: Prevents spawned subagent prompts from accidentally replaying parent history
- Model catalog proxying: Normalizes
/v1/modelsso Codex clients can consume upstream model lists consistently - Forced default model routing: Can rewrite every incoming request model to a single configured upstream model
- Config generation: Prints Codex-ready
model_catalog_jsonconfig plus a matching model catalog JSON payload from real upstream models
Session Storage
By default, codex-bridge-python keeps retained session and reasoning state in
memory.
To use disk-backed retention:
CODEX_BRIDGE_HISTORY_STORE=disk \
CODEX_BRIDGE_HISTORY_DIR=.codex-bridge-python-history \
codex-bridge-python
The disk backend writes JSON files under:
.codex-bridge-python-history/
sessions/
reasoning/
turns/
Treat this directory as sensitive. It can contain prompts, tool outputs, and other conversation data.
Python API
You can also launch the bridge from Python:
from codex_bridge import start
proc = start(
port=4448,
upstream="https://dashscope.aliyuncs.com/compatible-mode/v1",
api_key="sk-...",
)
# ... use Codex ...
proc.terminate()
Testing
Run the local test suite:
python3 -m pytest -q
The current tests cover:
- translation of Responses input into Chat Completions messages
- namespace tool flattening
- reasoning item handling
- image input reshaping
- streaming event sequencing
- tool-call streaming round-trip
- spawned child request isolation
Debugging
For more verbose bridge logs:
CODEX_BRIDGE_LOG=debug codex-bridge-python
Useful things to look for in logs:
- upstream model discovery
- forwarded tool names
- returned function call names
- upstream HTTP failures or parse failures
Known Scope
codex-bridge-python is focused on Codex's Responses workflow and currently proxies:
POST /v1/responsesGET /v1/models
It is not trying to be a full generic OpenAI-compatible reverse proxy for every endpoint.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codex_bridge_python-0.1.1.tar.gz.
File metadata
- Download URL: codex_bridge_python-0.1.1.tar.gz
- Upload date:
- Size: 36.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e665ecc4de64e2c5296883a52503815917aa5f768a173ead896652e4a3f92920
|
|
| MD5 |
bcfccc493097955632fb0457fffcd187
|
|
| BLAKE2b-256 |
375121949968722ca386fc23d1e793b2975d780eecab4600cf0da1905466d38d
|
File details
Details for the file codex_bridge_python-0.1.1-py3-none-any.whl.
File metadata
- Download URL: codex_bridge_python-0.1.1-py3-none-any.whl
- Upload date:
- Size: 31.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
127e519f8c390e76b9d854f8ad0a2927e052a4adb93a58de9b1939dd802fdc49
|
|
| MD5 |
5bbbe09356931f4286b43cb21fa7259a
|
|
| BLAKE2b-256 |
62446e1fde2df924049f2bbc37d7fd93d2465ff17dccc2ee828ac7ab717b3613
|