Codex and ChatGPT desktop
Use Logits in ChatGPT desktop / Codex. Connect Codex directly to Logits with DeepSeek Flash or Kimi K3.1 Pro.
macOS / Python 3 · desktop engine 0.162.0-alpha.2 · October 20, 2026 · experimental pilot
Native coding profile validation
Native DeepSeek and Kimi coding profiles are enabled in production. Before deployment, the desktop-bundled engine and Logits handler passed low-effort reasoning, native apply_patch, images, manual compaction and restart/resume for both models. Fourteen model calls matched fourteen settled receipts in that pre-deployment check. Use the published setup helper below to create an isolated profile; it stops if the deployed catalog does not support the selected model.
Direct coding connection
Logits translates Responses in its server and reuses its existing model dispatch, admission and billing. Each generation has one usage record. This setup covers local Codex coding tasks and the desktop coding engine; regular ChatGPT chats and MCP apps use separate integration paths.
Codex → https://api.logits.com/v1/responses
→ Logits router → DeepSeek V4.1 Flash / Kimi K3.1 Pro1. Save your Logits API key
Sign in to the console, check your balance, and create a dedicated key on the API keys page. Allow the selected model if the key has a model restriction. Reuse your existing private key file if you already have one.
mkdir -p ~/.config/logits-codex
chmod 700 ~/.config/logits-codex
read -rs 'logits_key?Paste your Logits API key: '
printf '\n'
printf '%s' "$logits_key" > ~/.config/logits-codex/api-key
chmod 600 ~/.config/logits-codex/api-key
unset logits_key2. Create an isolated Codex profile
Download and inspect the setup helper. It reads the installed engine's complete bundled instructions in a fresh temporary Codex home and fetches the real Logits Codex catalog with X-Gateway-Client: codex. It creates a separate configuration directory; your regular desktop configuration is untouched. Python 3 is required. No inference is sent by setup.
curl --fail --output /tmp/logits-codex-setup.py \
https://logits.com/guides/logits-codex/setup.py
python3 /tmp/logits-codex-setup.py \
--codex-binary "/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex" \
--api-key-file "$HOME/.config/logits-codex/api-key" \
--model deepseek/deepseek-v4.1-flash --reasoning-effort low \
--output-dir "$HOME/.config/logits-codex/deepseek-native"The generated config points model_instructions_file at the complete extracted instructions and model_catalog_json at the endpoint's unmodified catalog snapshot. Both are required: the server does not supply replacement coding instructions, and a shared model cache can otherwise select fallback tool metadata. The helper records version and content hashes in setup.json, protects profile files, and refuses incomplete catalogs or empty instructions. It references your private key file without copying its contents.
CODEX_HOME="$HOME/.config/logits-codex/deepseek-native" \
"/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex"Confirm the engine version and use /status to check provider logits and the intended model. The profile uses HTTP SSE, 32,000 context and a 24,000-token compaction threshold. Apps, plugins and multi-agent are disabled only inside this isolated profile; their namespace tools remain outside the supported contract.
Kimi K3.1 Pro
python3 /tmp/logits-codex-setup.py \
--model moonshotai/kimi-k3.1-pro --reasoning-effort low \
--output-dir "$HOME/.config/logits-codex/kimi-pro-native"Launch with CODEX_HOME pointing to kimi-pro-native. Start with reasoning low; high is also accepted. The catalog lists model-specific efforts. none turns reasoning off on both models. On Kimi K3.1 Pro, minimal runs as low and xhigh runs as max. Low is only the profile Codex suggests: an API request that names no effort runs at max. Do not assume the same effort represents the same compute budget across models. The retired kimi-k3 ID is not accepted; use moonshotai/kimi-k3.1-pro.
Desktop setup
To use a generated profile in the normal desktop, back up ~/.codex/config.toml and merge its root settings and provider tables without duplicate keys, preserving absolute paths to instructions and catalog. This is an explicit manual change. Fully restart and create a new coding task; project settings can override user settings. A Dock-launched app does not inherit a terminal-only CODEX_HOME assignment. GUI provider switching and the complete connected desktop toolset remain separate checks.
3. Verify your first task
These model requests consume Logits usage. Use a scratch project:
- Text: Reply with exactly: logits-ok
- Tools: Run pwd and list the files in this scratch project.
- Native patch: Use the native apply_patch tool to create hello.py printing logits-ok; run it and report the output.
- Follow up: Use apply_patch to accept a name argument while preserving the prefix. Run hello.py dogfood and report the actual output.
- Image: Attach your own small synthetic image and ask the model to identify its shapes, colors and positions.
Confirm a native patch/file-change event, inspect the actual file, and check command output and independent tests. A shell edit or text claim alone does not establish native apply_patch. Then try manual compaction, continue the task, and restart/resume the thread. Check request logs and usage for the intended model and one settled receipt per generation. Never execute incomplete tool calls.
Supported scope and limits
The native bridge accepts text, ordinary JSON function tools, custom text tools and the captured Codex apply_patch Lark grammar, full plaintext reasoning replay, and ordered user input_image parts. Tool loops send complete ordered history and matching call IDs with store=false. Full reasoning_text is continuation state; a short summary cannot replace it. No encrypted state is fabricated.
Images use HTTPS or data URLs with detail auto, low, high or original and the existing Chat image validation, SSRF protections and budgets. Source inputs fit within the 12 MiB Responses request body or remote-source limit, and each prepared data URL must be under 5 MB. Detail is an advisory compatibility hint normalized to auto before dispatch. Larger sources and images above the model's image_input.max_pixels resize target are downscaled and re-encoded to fit, not rejected. Query the ordinary /v1/models image_input for current model-specific counts and formats. Existing model text limits still apply.
Namespace/server tools, hosted search, file_id images, images in assistant/system/tool-result messages, structured Responses output, store=true, previous_response_id and non-null opaque encrypted_content are unsupported. The full connected plugin set, automatic threshold compaction and full 1M operational context remain unqualified. This is a bounded coding profile.
Troubleshooting
A setup catalog error means the endpoint has not enabled this native profile yet, or the requested model is missing. Do not bypass the check with synthetic metadata or delete the instruction override. Refresh by generating a new profile directory and switching CODEX_HOME; re-run setup after updating Codex or changing the catalog.
For 401/403 check the key and model allowlist; for 402 check balance; for 429 follow retry guidance. For 400 preserve the redacted shape, tool name and request ID. On failed or interrupted SSE, inspect the receipt before retrying: delivery failure can follow settlement.
Rollback
Exit the isolated process to return to your usual setup. If you manually merged desktop settings, restore the backup, restart and create a new task. Stop the separate local adapter when testing the direct route. Retiring a profile does not revoke its API key; revoke a dedicated key separately when needed.
Reference: Router's Codex guide. Logits now defines its own explicit Codex catalog header contract. The dated local adapter fallback below covers basic DeepSeek text and function tools; it does not qualify these expanded capabilities.
Local adapter fallback
Qualified October 19, 2026. Use this separate path only when deliberately testing the fallback. It needs Python 3 and uv.
mkdir -p ~/.config/logits-codex
chmod 700 ~/.config/logits-codex
read -rs 'logits_key?Paste your Logits API key: '
printf '\n'
printf '%s' "$logits_key" > ~/.config/logits-codex/api-key
chmod 600 ~/.config/logits-codex/api-key
unset logits_key
python3 - <<'PY'
import os
from pathlib import Path
from secrets import token_urlsafe
path = Path.home() / ".config/logits-codex/bridge-key"
if not path.exists():
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(fd, "w") as f:
f.write("sk-local-" + token_urlsafe(32))
path.chmod(0o600)
PY# Root settings: place before the first TOML table.
model = "deepseek/deepseek-v4.1-flash"
model_provider = "logits-local"
model_reasoning_effort = "none"
model_context_window = 32000
model_auto_compact_token_limit = 24000
web_search = "disabled"
[model_providers.logits-local]
name = "Logits (local adapter)"
base_url = "http://127.0.0.1:4000/v1"
wire_api = "responses"
supports_websockets = false
request_max_retries = 0
stream_max_retries = 0
[model_providers.logits-local.auth]
command = "/bin/cat"
args = ["/Users/YOUR_NAME/.config/logits-codex/bridge-key"]
timeout_ms = 5000Add these settings to the config.toml in your Codex home: ~/.codex/config.toml by default, or config.toml in the directory that CODEX_HOME points to. Back up the file first, then merge the root settings and provider tables without duplicate keys. An existing ~/.codex/config.toml probably already sets model and model_provider; TOML rejects a key that is set twice, so replace those lines instead of adding new ones. TOML does not expand ~, so replace /Users/YOUR_NAME in args with your home directory.
Save the LiteLLM configuration below as ~/.config/logits-codex/litellm.yaml, or download the YAML file. Also save the required text compatibility hook as ~/.config/logits-codex/logits_adapter.py in the same directory. LiteLLM loads it through the YAML callback setting.
model_list:
- model_name: deepseek/deepseek-v4.1-flash
litellm_params:
model: openai/deepseek/deepseek-v4.1-flash
api_base: https://api.logits.com/v1
api_key: os.environ/LOGITS_API_KEY
use_chat_completions_api: true
additional_drop_params: [prompt_cache_key]
reasoning_effort: none
max_tokens: 8192
num_retries: 0
model_info:
mode: chat
litellm_settings:
num_retries: 0
callbacks: [logits_adapter.handler]
general_settings:
master_key: os.environ/LOGITS_CODEX_BRIDGE_KEYKeep use_chat_completions_api: true: it forces Responses requests through the Chat Completions adapter. The explicit additional_drop_params entry removes the client's unsupported prompt_cache_key hint before the Logits request. The hook converts the client's text content blocks into plain strings accepted by Logits, preserving tool calls and results; it rejects non-text blocks. Keep reasoning_effort: none for this pilot: LiteLLM 1.106.0 can omit text deltas when an upstream chunk contains both reasoning and text. The example uses one model, an 8,192-token default output budget, and no adapter retries.
export LOGITS_API_KEY="$(cat ~/.config/logits-codex/api-key)"
export LOGITS_CODEX_BRIDGE_KEY="$(cat ~/.config/logits-codex/bridge-key)"
uvx --from 'litellm[proxy]==1.106.0' litellm \
--config ~/.config/logits-codex/litellm.yaml \
--host 127.0.0.1 --port 4000Keep this terminal running. The first launch downloads dependencies. In a second terminal, send a streaming test request:
export LOGITS_CODEX_BRIDGE_KEY="$(cat ~/.config/logits-codex/bridge-key)"
curl --fail-with-body --no-buffer http://127.0.0.1:4000/v1/responses \
-H "Authorization: Bearer $LOGITS_CODEX_BRIDGE_KEY" \
-H 'Content-Type: application/json' \
-d '{"model":"deepseek/deepseek-v4.1-flash","input":"Reply with exactly: logits-ok","stream":true,"store":false,"max_output_tokens":256}'Expect text deltas containing logits-ok and a terminal response.completed event. Resolve errors before editing the desktop configuration. This request consumes Logits usage.