Skip to content
 
 

Repository files navigation

Codex Mixin

Codex Mixin icon

CI Latest release macOS and Linux License Rust

Bring custom model providers into official Codex without giving up ChatGPT account features.

中文 · English · Download · Issues

Codex model picker with custom models

中文

Codex Mixin 是一个 Rust 本地网关、CLI 和 macOS 菜单栏 App。它把 OpenRouter、DeepSeek、Baidu OneAPI 或其他 OpenAI Chat Completions / Anthropic Messages 兼容模型接入官方 Codex,同时保留官方 ChatGPT/OpenAI 账号路径、官方 GPT 模型、远程控制和 Codex 原生体验。

它不是 Codex 的二次发行版,也不重新打包官方 Codex App。Codex 仍然是主入口,Codex Mixin 只负责模型接入、协议转换、模型目录生成、配置托管、服务常驻和额度展示。

目录

为什么需要它

很多团队和个人已经有自己的模型入口,例如内部 OneAPI、OpenRouter、DeepSeek 或自建兼容网关。但 Codex 的真实使用场景不只是发一次 API 请求,用户还希望保留这些能力:

  • 继续使用 ChatGPT 账号登录后的官方 Codex 能力。
  • 官方 GPT 模型和自定义模型能在同一个模型选择器里出现。
  • 新会话可以用自定义模型,旧会话不会因为 provider 被改掉而看起来消失。
  • Codex model catalog 字段完整,不缺 context window、instructions template 等必需字段。
  • 本地网关能长期运行,不依赖一个不能关闭的终端窗口。
  • 普通用户不需要理解 /v1/messages/v1/chat/completions/anthropic 等路径差异。
  • API 额度能在菜单栏里用可读方式展示,而不是显示一整段原始 JSON。

Codex Mixin 的解法是:Codex 连到本机自动分配的 loopback 端口,本地网关再按 provider 把请求转成上游需要的协议,并把流式响应转回 Codex 能理解的 Responses 形态。端口会持久化;若已被占用,网关会自动选择空闲端口并同步 Codex 配置。

功能特性

  • 保留官方路径:官方 GPT 模型继续走 Codex 官方认证、官方后端和远程控制路径。
  • 接入自定义模型:自定义模型进入 Codex 模型选择器,和官方模型一起使用。
  • 避免模型冲突:上游返回的 gpt-* 与官方模型重名时会附加 provider 后缀(例如 gpt-...-baidu-oneapi),不顶掉官方 GPT;旧的 -custom 别名仍兼容。
  • 保护历史会话:安装时按官方/自定义模式注册托管 provider,并把现有会话统一迁移到该 provider。
  • 可回滚配置:安装前备份 ~/.codex/config.toml;卸载时恢复配置和原 provider,并删除托管模型目录。
  • 供应商预设:内置 custombaidu-oneapiopenrouterdeepseek
  • 协议转换:支持 Anthropic Messages 和 OpenAI Chat Completions 上游。
  • 极致 prompt 缓存:用逐字节的前缀契约驱动上游自动缓存命中,并在每一轮报告缓存是否失效、失效在哪里;工具截图只在首次进入上下文的那一轮内联,之后回放为固定占位符,历史不会永久携带图片字节。
  • 图片能力:官方 GPT 保留 Codex 原生生图;自定义模型可调用上游 OpenAI-compatible 生图接口。
  • 模型 metadata 补齐:结合 LiteLLM metadata 和内置正则规则补齐上下文窗口、能力和 instruction 字段。
  • 模型选择与测速:独立窗口统一完成模型搜索、勾选和保存,并对已选模型测试 TTFT、TPS、实际 usage tokens、总耗时和本次额度花费;结果可按列升降序排列并持续保存。
  • Fusion 多模型编排:多个 Panel 并行分析,经 Judge 汇总后由 Final 模型流式回答;中间结果可使用 Codex 原生交互式 Fusion · Review 展示。
  • 菜单栏产品化:启动、暂停、重启、配置密钥、安装到 Codex、恢复、查看额度、Token/缓存使用和日志都在菜单栏完成。
  • App 启动即用:打开菜单栏 App 后自动启动后台网关,并在菜单顶部显示实际 endpoint。
  • 自动端口管理:优先复用上次端口,冲突时由系统分配空闲端口,并同步受管 Codex 配置。
  • 常驻服务:后台 daemon 在退出菜单栏 App 后仍可运行;启用登录自启时会切换为 launchd 托管,异常退出后由 launchd 节流重启。
  • 可诊断日志:网关日志包含带时间戳的启动、监听、刷新、错误和停止记录,达到 5 MiB 后保留一个 .1 备份。
  • 自动更新检查:菜单栏 App 每次启动都会静默检查 GitHub Release;发现新版本时提示下载当前架构对应的 DMG。

快速安装

GitHub Releases 下载当前 Mac 架构对应的 DMG:

Mac 架构 下载文件
Apple Silicon codex-mixin-<version>-aarch64-apple-darwin.dmg
Intel codex-mixin-<version>-x86_64-apple-darwin.dmg

菜单栏 App 支持 macOS 13.1 Ventura 及以上版本。打开 DMG,把 Codex Mixin.app 拖到 Applications,然后启动菜单栏 App。

发布包带有有效的 ad-hoc bundle 签名,但尚未使用 Apple Developer ID 签名,也未 notarize。如果 Gatekeeper 拦截,执行下面命令后再打开:

xattr -dr com.apple.quarantine "/Applications/Codex Mixin.app"

打开后按菜单栏提示完成配置。远端开发机或 Linux 用户可以从 Release 页面下载 CLI 包自行使用。

CLI 下载文件名
  • macOS Apple Silicon: codex-mixin-cli-<version>-aarch64-apple-darwin.tar.gz
  • macOS Intel: codex-mixin-cli-<version>-x86_64-apple-darwin.tar.gz
  • Linux x86_64: codex-mixin-cli-<version>-x86_64-unknown-linux-musl.tar.gzcodex-mixin-<version>-x86_64-unknown-linux-musl.deb
  • Linux ARM64: codex-mixin-cli-<version>-aarch64-unknown-linux-musl.tar.gzcodex-mixin-<version>-aarch64-unknown-linux-musl.deb

快速使用

本地 Codex App 用户

  1. 打开 Codex Mixin.app
  2. 点击菜单栏图标,选择 供应商设置...
  3. 选择 provider,填入 API Key。上游地址只填根地址,不要填 /v1/messages/v1/chat/completions
  4. 点击 启动本地网关
  5. 点击 安装到 Codex...,明确选择“官方账号模式”或“仅自定义模型模式”。
  6. 重启 Codex App。
  7. 在 Codex 模型选择器里选择可用模型。

Menu bar status

远端 Codex CLI 用户

codex-mixin setup
codex-mixin info

setup 是 CLI 的首次配置入口:交互终端可直接运行并选择 preset,隐藏输入 API Key、添加或更新 provider、刷新模型、启动或按需重启网关, 然后询问 Codex 集成方式,选择保留官方账号能力、仅使用自定义模型或暂时跳过。选择后可以直接完成 Codex 安装,不需要再单独执行 connect codex;跳过时可以用 connect codex 以后再装。

Baidu OneAPI 还会询问额度查询用户名,自动下载并登录托管认证核心。当前默认使用 DUCC, 也可以选择 DUCX;两者都作为 header 产生器使用,不转发 warmup 请求到 OneAPI:

codex-mixin setup --preset baidu-oneapi

脚本和 CI 用 --key--quota-username--codex-mode official|custom|skip 跳过交互,或设置 CODEX_MIXIN_API_KEYCODEX_MIXIN_QUOTA_USERNAME

codex-mixin setup --preset openrouter --key <key> --codex-mode custom
codex-mixin setup --preset baidu-oneapi --key <key> --quota-username <username> --codex-mode skip

只写配置、不启动网关时增加 --no-start。日常入口按任务收敛:setup 负责首次配置,update 负责从 GitHub Release 更新 CLI 并重启网关,provider 管理供应商,service 管理本地网关,connect 管理 Codex/Claude 集成,info 查看运行状态,doctor 负责诊断和修复。

然后重新打开 Codex CLI 会话,在模型选择器里选择接入后的模型。遇到问题时再运行 codex-mixin doctor --quick;它会给出具体修复命令。

常用检查命令:

codex-mixin info
codex-mixin info --json
codex-mixin provider list --json
codex-mixin service logs -n 200

供应商预设

Provider 上游协议 上游根地址 对话接口 生图接口 模型接口 额度接口
custom OpenAI Responses 默认 用户填写 /v1/responses 可选,用户填写 /v1/models 自动探测常见只读端点
baidu-oneapi Anthropic Messages https://oneapi-comate.baidu-int.com /v1/messages /v1/images/generations POST /openapi/v2/available_models /openapi/v3/user/quota
openrouter OpenAI Chat Completions https://openrouter.ai/api /v1/chat/completions 可选,用户填写 /v1/models /v1/credits
deepseek OpenAI Chat Completions https://api.deepseek.com /chat/completions 可选,用户填写 /models 无默认值
opencode-go OpenAI Responses https://opencode.ai/zen/go /v1/responses /v1/models dashboard /workspace/{id}/go + /billing

设置窗口里的上游地址只填根地址。路径由 provider preset 补齐。 Baidu OneAPI 的额度接口必须同时填写额度用户名;CLI 和 App 都会在保存时校验。 OpenCode Go 的额度显示需要额外填写工作区 ID 和 opencode.aiauth cookie; 这两个值可以在浏览器控制台里从 OpenCode Go dashboard 页面取得,cookie 过期后需要重新填写。 新增或更新 custom 供应商时,会按 /v1/responses/v1/messages → Chat Completions 顺序探测上游接口,并把第一个可用协议写入配置。Baidu OneAPI 不参与该探测,使用预设协议。 预设供应商的协议在离线验证后写死,例如 OpenCode Go 使用 /v1/responses。 启用 Baidu OneAPI 时可以选择「DUCC 核心」或「DUCX 核心」。两者都是 header 产生器: 网关启动后在后台预热一次,运行一个短命认证回合,从该回合发出的 OneAPI 请求中抓取 comate_custom_headerAuthorization 等原生 Header,然后缓存复用;抓取后立即终止 warmup 回合,不会把它转发到真实 OneAPI,也不会消耗推理额度。DUCC 使用 --bare --print 短命进程,DUCX 使用 --disable hooks/plugins exec 短命进程,两者都不 维护长驻的 350 MiB worker。

真实模型请求始终由调用方决定,Header 由所选认证核心产生并注入到 Mixin 自己的上游请求。 Fusion、Web Search、画图和 Auto Review 产生的子请求走同一个统一执行层,不会绕过用户 选择的核心。上报 hook 与认证核心解耦:配置里单独保存 data-report 二进制路径,运行时 不再读取 DUCC/DUCX 的认证路径。

选择 DUCC 核心时,macOS App 会先确认,再按百度 baidu-cc/install.sh 的版本和包规则把 独立副本下载到 ~/.codex-mixin/ducc/home/;选择 DUCX 核心时下载到 ~/.codex-mixin/ducx/home/。两者都不会直接执行官方安装脚本;下载完成后, 独立 Terminal 会显示进度并执行托管副本的登录,扫码成功后自动关闭并继续保存。 Provider 可通过 --header-env NAME=ENV_VAR 转发用户自行提供的自定义请求头。配置文件 只保存 Header 名和环境变量名,不保存值;网关启动时读取一次,缺失或空值会阻止启动, 更新值后需重启网关。authorizationx-api-keycomate_custom_header 和传输层 Header 不允许覆盖;comate_custom_header 只允许由当前认证核心产生。Codex Mixin 不生成、校验或授权任何凭据,用户须自行确认对相关账号、凭据和服务有使用权。DUCC/DUCX 会把托管登录得到的 Authorization: Bearer ...、DUCC 生成的 x-api-key 以及 comate_custom_header 注入到 Mixin 的上游请求,不删除也不替换。data-report 会继续执行 managed settings 中的 SessionStart、UserPromptSubmit、Stop、SessionEnd data-report hooks,把这些使用次数标记为百度 OneAPI Token 流量。 新增或刷新 custom Provider 时会并发尝试 New API、Sub2API、OpenRouter 等常见只读额度端点;只有返回可识别额度数据的端点才会保存,不会发起付费推理。

示例:

  • OpenRouter 填 https://openrouter.ai/api,不要填 /v1/chat/completions
  • DeepSeek 填 https://api.deepseek.com,不要填 /chat/completions
  • Anthropic Messages 兼容网关通常填网关根地址,custom 会默认使用 /v1/messages/v1/models

Provider select

Provider config

安装到 Claude Code

Codex Mixin 也提供一个 Anthropic Messages 兼容端点 /v1/messages,所以 Claude Code 可以直接把本地网关当作上游使用。菜单栏 App 选择「安装到 Claude Code...」后,会:

  1. 备份并保留 ~/.claude/settings.json 中已有的 env 配置。
  2. env 中写入 ANTHROPIC_BASE_URL=http://127.0.0.1:<端口>
  3. 自动选择一个已配置的 Claude/Anthropic Messages 模型,写入 ANTHROPIC_MODELANTHROPIC_DEFAULT_SONNET_MODELANTHROPIC_DEFAULT_OPUS_MODELANTHROPIC_DEFAULT_HAIKU_MODEL
  4. 写入 codex_mixin_managed 标记,卸载时恢复之前的值。

CLI 等价命令:

codex-mixin connect claude --model "Claude Sonnet 5"
codex-mixin connect remove claude
codex-mixin connect status

注意:Claude Code 默认模型名可能不是本地 provider 的 catalog 名称;安装后建议使用 --model 显式选择,或先执行 codex-mixin info 查看网关和 provider 状态。

安装到 Codex 的行为

安装面板和 CLI 都提供两种互斥模式:

模式 CLI 命令 models_cache.json 安装结果
官方账号模式 codex-mixin connect codex --codex-oauth-proxy 必须存在;请先登录并打开一次 Codex 合并官方 GPT 与自定义模型,保留官方 OAuth、插件、云任务和账户能力
仅自定义模型模式 codex-mixin connect codex --custom-only 不依赖、不要求存在 备份并临时替换 Codex 登录,用本地登录占位开启模型选择器;官方插件、云任务和账户功能不可用

CLI 不会根据 auth.jsonmodels_cache.json 猜测模式,也不允许省略模式参数。即使你有官方账号,也可以明确选择仅自定义模型模式;如果想使用官方能力,请先取消安装,在 Codex 中登录并打开一次,然后选择官方账号模式。

安装会做这些事:

  1. 读取上游 models 接口,生成 Codex 可用的模型目录。
  2. 写入独立模型目录文件 ~/.codex/model-catalogs/mixin-models.json
  3. 备份当前 ~/.codex/config.toml
  4. 官方账号模式注册独立的 codex-mixin provider;仅自定义模式复用 Codex 内置 amazon-bedrock provider,并只把它的 base_url 指向本地网关。两种模式都不覆盖内置 openai provider。
  5. 将顶层 model_provider 设置为当前模式对应的托管 provider。
  6. 将现有 JSONL 和 SQLite 历史索引迁移到当前托管 provider,并保留迁移前备份。
  7. 官方账号模式写入 requires_openai_auth = truesupports_websockets = true。仅自定义模式使用本地 Bedrock-shaped 登录占位;Codex Desktop 对该账户类型不应用官方模型白名单,因此完整自定义目录会出现在模型选择器。
  8. 仅自定义模型模式会把原 ~/.codex/auth.json 备份到 auth.json.codex-mixin.backup;原文件不存在时写入 auth.json.codex-mixin.absent 标记,然后安装由 codex-mixin 管理的本地登录占位。

有账号模式的关键配置形态:

model_catalog_json = "/Users/you/.codex/model-catalogs/mixin-models.json"
model_provider = "codex-mixin"

[model_providers.codex-mixin]
name = "Codex Mixin"
base_url = "http://127.0.0.1:<自动分配端口>/v1"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = true

仅自定义模型模式只覆盖内置 amazon-bedrock provider 允许覆盖的 base_url,并会把一个上游模型写成默认模型:

model = "DeepSeek-V4-Flash"
model_catalog_json = "/Users/you/.codex/model-catalogs/mixin-models.json"
model_provider = "amazon-bedrock"

[model_providers.amazon-bedrock]
base_url = "http://127.0.0.1:<自动分配端口>/v1"

最新版 Codex 禁止覆盖内置 openai provider,并严格限制内置 provider 可修改的字段。Codex Mixin 的官方账号模式使用独立的 codex-mixin provider;仅自定义模式只修改 amazon-bedrock.base_url,其余 Bedrock provider 字段保持 Codex 默认值。即使首次配置里没有 model_providermodel_providers,安装器也会补齐所需配置。有账号模式下,官方 GPT 请求由网关转发到官方 Codex backend;两种模式下的自定义模型请求都会转发到已配置的上游。

有账号模式安装后,可以在同一个 Codex 会话中从官方 GPT 切换到自定义模型,也可以再切回官方模型。Codex Mixin 会按每个 Responses WebSocket 请求重新分流,并在自定义模型连续调用时重建增量上下文。

默认不会改顶层 model。如果确实要顺手设置默认模型,可以显式传入:

codex-mixin connect codex --codex-oauth-proxy --model deepseek-chat --set-default

卸载并恢复安装前配置:

codex-mixin connect remove codex

卸载会从备份配置读取原 provider;原配置没有显式 provider 时使用 Codex 默认的 openai。当前托管 provider 的历史会同步迁回该 provider,避免恢复配置后会话消失。仅自定义模型模式创建的本地登录占位会被删除,并恢复安装前的 auth.json;如果用户安装后自行改过登录,卸载会保留当前登录且不会用旧备份覆盖它。

从仅自定义模型模式切到官方账号模式时,先执行卸载,登录 Codex 并打开一次以生成模型缓存,再用 --codex-oauth-proxy 重新安装。切回仅自定义模型模式时,直接用 --custom-only 重新安装即可,当前官方登录会被备份。

安装或卸载后需要重启 Codex App。Codex CLI 需要开启新会话。

菜单栏 App

菜单栏 App 提供这些动作:

  • 启动本地网关:启动后台网关,不改变登录自启设置。
  • 暂停本地网关:停止当前后台网关。
  • 重启本地网关:按当前登录自启设置重启服务。
  • 登录时启动并开启服务:登录后同时打开菜单栏 App 和网关;开启时将当前 daemon 切换为 launchd 服务,关闭时将仍在运行的服务切回后台 daemon。
  • 刷新状态与额度:刷新服务状态和额度进度条。
  • 供应商设置...:新增、删除和启停 provider,填写 API Key、上游根地址和额度信息,并刷新上游模型缓存。
  • 模型选择与测速...:搜索、筛选和勾选要加入 Codex 的模型;未保存的选择会在测速前自动保存。下方结果表按模型显示 TTFT、TPS、usage、总耗时和状态,可点击表头切换升降序。关闭窗口或退出 App 不会停止后台测速,重开 App 会从 ~/.codex-mixin/model-benchmarks.json 恢复上次结果。
  • Fusion 设置...:选择 1–8 个 Panel 模型以及 Judge、Final 模型,并控制是否在回答中展示中间结果。
  • 安装到 Codex...:选择有账号或仅自定义模型模式;先确保网关已启动,再按实际动态端口生成模型目录并写入托管 Codex 配置。未检测到 models_cache.json 时默认选择仅自定义模型。
  • 从 Codex 恢复...:恢复安装前备份并删除托管模型目录。
  • 关于 Codex Mixin...:显示当前 App 版本、Build 号和 GitHub 仓库链接,可一键复制版本信息;还可以打开只在本机生成的互动 Mixin 卡片并保存或分享 PNG。每次打开关于页时会随机选择一张与上次不同的当月 NASA 背景,窗口打开期间保持不变;老用户的天数会从 ~/.codex-mixin 最早的创建时间回迁,全新安装则从第一次记录开始。
  • 检查更新...:查询 GitHub 最新 release,下载并打开当前架构对应的 DMG。
  • 复制本地接口地址:复制当前实际监听的本地接口地址。
  • 打开运行日志:打开当前日志 ~/.codex-mixin/gateway.log;轮转前的日志保存在 gateway.log.1
  • 打开配置目录:打开 ~/.codex-mixin

打开 App 会自动启动本地网关。关闭终端或退出菜单栏 App 后,后台网关仍可以继续运行;只有打开 登录时启动并开启服务 时才会安装菜单 App 和网关各自的 launchd agent。daemon 与 launchd 切换前会先等待旧进程退出,避免同时启动两个动态端口。未配置有效上游 API 时不会安装登录自启任务。需要临时停服务时使用菜单里的暂停动作。

Fusion 多模型编排

Fusion 虚拟模型使用 Panel → Judge → Final 三段式管线。打开菜单栏的 Fusion 设置...,选择 1–8 个并行 Panel 模型、一个 Judge 模型和一个 Final 模型;保存并重启网关后,mixin/fusion/<profile-id> 会出现在 Codex 模型选择器中。

Fusion 只在 Plan 模式的新用户轮次运行 Panel 和 Judge。切换到 Default 模式执行计划后,所有后续用户轮次与工具结果续跑都直接交给该 profile 的 Final 模型,避免在编码阶段重复分析。

Codex 中的交互式 Fusion Review

高级选项 在回答中显示 Panel / Judge 中间结果 默认开启,对应 stored config 中的 show_intermediate_results: true。开启后,Codex Mixin 会直接使用 Codex 原生 inline visualization:

  1. Panel 输出按配置顺序排成并列小卡片;卡片先显示短预览,点击即可展开完整报告。
  2. Judge 固定生成三个可点选的编号要点:共识与证据、分歧与缺口、建议的具体做法;标题和正文跟随当前用户请求的语言。
  3. Final 回答继续使用 Codex 原生流式消息,不插入额外的 Final 标题或模型说明。

可视化文件只写入当前 Codex task 的 visualization 目录,不访问网络。若当前客户端未提供该目录,网关会自动回退到可折叠的 Markdown Panel 表格和 Judge 汇总。

关闭该选项时,Panel 和 Judge 仍会正常参与生成,但回答区只保留 Final 内容;执行进度仍通过 reasoning summary 显示,避免长时间无反馈。

CLI

# 首次配置:交互终端可直接运行并选择 preset / API Key / Codex 集成方式
codex-mixin setup

# 脚本或 CI:显式传参,跳过所有交互
codex-mixin setup --preset openrouter --key <key> --codex-mode custom
codex-mixin setup --preset baidu-oneapi --key <key> --quota-username <username> --codex-mode skip
codex-mixin setup --preset <preset> --no-start

# 从 GitHub Release 更新 CLI 并重启网关
codex-mixin update

# Provider 管理
codex-mixin provider list
codex-mixin provider add --preset <preset> --key <key>
codex-mixin provider update <id> --key <key>
codex-mixin provider discover <id>
codex-mixin provider test <id>
codex-mixin provider select <id> --model <model>...

# 本地网关;service start 在配置或参数变化时会自动重启
codex-mixin service start
codex-mixin service status
codex-mixin service restart
codex-mixin service logs -n 200
codex-mixin service start --foreground

# Codex / Claude 集成
codex-mixin connect codex --codex-oauth-proxy
codex-mixin connect codex --custom-only
codex-mixin connect claude --model "Claude Sonnet 5"
codex-mixin connect remove codex
codex-mixin connect status

# 状态与诊断
codex-mixin info
codex-mixin info --json
codex-mixin doctor
codex-mixin doctor --quick
codex-mixin doctor --fix               # 自动修复权限、失效状态、网关启动、base_url、模型目录
codex-mixin doctor --fix --restart-apps # 额外允许重启 ChatGPT/Codex App(会中断进行中的会话)

新用户从 setup 开始,日常只需要 updateproviderserviceconnectinfodoctorfusionbenchmark、catalog 刷新和历史迁移仍可用,但属于高级维护命令。

模型目录和 metadata

很多上游 /models 只返回模型 ID。Codex Mixin 生成 catalog 时会按以下顺序补齐上下文窗口和能力字段:

  1. CODEX_GATEWAY_MODEL_METADATA 指向的本地 metadata 文件。
  2. ~/.codex-mixin/model_metadata_litellm.json,由 refresh-metadata 或安装时自动拉取 LiteLLM metadata 生成。
  3. 内置模型族正则规则,例如 Claude、DeepSeek、GPT、Kimi、GLM、MiniMax 等常见命名。

生成的 catalog 会包含 context_windowmax_context_windowinput_modalitiesbase_instructionsmodel_messages.instructions_template,避免 Codex 解析模型目录时报缺字段。

图片生成

  • 官方 GPT:Codex 原生 image_gen extension 请求本地 /v1/images/generations/v1/images/edits 后,Codex Mixin 使用 Codex OAuth 和 chatgpt-account-id 转发到官方图片后端。请求不会携带自定义 provider 的 API Key。
  • 自定义模型:当设置中配置了上游生图路径,Codex Mixin 会识别 image_gen.imagegen 工具调用;图片仍由 Codex 原生 extension 执行和保存,本地图片 route 会把纯生图请求精确转到该 provider 的 OpenAI-compatible 接口。Anthropic Messages 和 OpenAI Chat Completions 上游都支持。
  • Baidu OneAPI:baidu-oneapi preset 自动使用 /v1/images/generations,请求模型为 gpt-image-2
  • 其他 provider:在设置窗口填写相对上游根地址的生图路径,例如 /v1/images/generations。接口需要接受 gpt-image-2 请求,并返回 data[0].b64_json
  • 未配置上游生图路径:保留原 image_gen.imagegen 工具调用,由 Codex 原生 extension 继续走官方图片路径。

当前自定义上游只代理纯文本生图。包含非空 referenced_image_paths 或正数 num_last_images_to_include 的图片编辑请求会明确失败,不会静默切换到其他后端。清空设置里的生图路径即可禁用自定义上游生图。

Thinking 与 Web Search

自定义模型默认在 Codex picker 中暴露 Off / low / medium / high / xhigh / max / ultra,并启用 multi-agent v2。 其中 Off 的 Codex wire value 是 none。Provider 的 per-model capability 明确报告 supports_thinking = false 时只保留 Off / ultra:Ultra 仍由 Codex 客户端主动派生 subagent,但不会向不支持思考的远端发送 reasoning。其他模型的 Ultra 在远端映射为 最高合法档位 max,不会把客户端专用的字面值 ultra 传给上游。

Anthropic 风格上游支持 Codex reasoning effort 到 thinking 的映射:

Codex effort Anthropic thinking
minimal / low low
medium medium
high high
xhigh / max max

未知 effort 会返回 400,而不是静默降级到错误档位。

Web search 转发使用保存的 Provider 配置和内置默认策略。网关运行行为不再读取 CODEX_GATEWAY_* 环境变量进行覆盖;监听地址、网关密钥和 Provider 信息必须通过 App 或 CLI 显式保存,临时监听地址使用 service start --bind,前台调试使用 service start --foreground

Prompt 缓存优化

上游 provider 的自动 prompt 缓存只在一个条件下命中:上一轮的 prompt 前缀逐字节不变,新内容 只追加在尾部。网关把这一点当作可验证的契约来执行,而不是碰运气。

每次发往 provider 的请求都会按真正发出的上游字节推导缓存形状 —— system prompt、工具定义与 tool_choice、reasoning 配置,以及逐条消息的摘要。同一 session 的下一轮请求与上一轮比对后 给出明确结论:

状态 含义
cold_start 该 session 还没有可比对的历史请求
append_only 旧内容逐字节不变,新内容只追加在尾部,缓存完全命中
tail_rewritten 只有上一轮的最后一条消息被改写,它之前的前缀仍然命中
system_changed / tools_changed / config_changed instructions、工具或 reasoning 配置发生漂移,整个前缀失效
turn_rewritten 历史中间某条消息被改写,provider 需要从该条开始重算
history_truncated 历史变短,通常是 compaction

缓存失效以 WARN 记录,并附带 reused_turnsreused_bytes,可以直接定位原因。每一轮的 完整轨迹需要 debug 级别:

RUST_LOG=codex_mixin=debug codex-mixin service start --foreground

网关还会把 provider 返回的缓存计数与自己保住的前缀对账。如果本轮前缀逐字节不变、稳定前缀又 足够大,而 provider 仍然重算了它,日志会明确写成上游行为,而不是让它看起来像网关的 bug:

WARN provider recomputed a prompt prefix this gateway kept byte-identical
     prefix_state="append_only" prompt_tokens=99200 cache_read_tokens=3456 uncached_input_tokens=95744

这条区分很重要:prefix_state 不是 append_only 说明问题在请求形状,可以修;是 append_onlycache_read_tokens 仍然很低,说明是上游缓存池驱逐或后端实例路由,本地无法修复,只能据此 和 provider 对话。实测中 Baidu OneAPI 会周期性出现后者,并且忽略 Anthropic 的 cache_control 断点 —— 加与不加,计费和 usage 完全一致。

判定只用 provider 自己返回的 token 计数,不用字节换算:同一份 prompt 里 ASCII 代码和中文正文的 每 token 字节数能差三倍以上,足以把 98% 的命中误判成未命中。provider 完全不返回缓存计数时 (Baidu OneAPI 的 Opus 路由就是这样)不做判定,因为无法归因。

图片走同一条契约。工具返回的截图只在模型尚未看过的那一轮内联,并压缩到最长边 1568px;之后 每一轮都回放为固定占位符。所以截图和视觉工具继续可用,而历史不会永久携带图片字节,代价只是 上一轮的最后一条消息被改写一次。HTTP 和 WebSocket 解压后的 JSON 请求上限为 256 MiB; HTTP 请求会先落盘再解析, 上游返回 413 时,网关会把内嵌图片压缩到最长边 768px、JPEG quality 65,并且只重试一次。

OpenAI Chat Completions 兼容上游不接受 tool 消息内嵌图片,网关会把图片改放到紧随该批工具 结果之后的一条 user 消息,同时让 assistant 的 tool_calls 与对应的 tool 结果保持相邻。

scripts/e2e_prompt_cache.sh 在真实网关上逐字校验以上全部行为,CI 每次提交都会运行。

数据位置

内容 路径
Codex Mixin 配置 ~/.codex-mixin/config.json
本地网关日志 ~/.codex-mixin/gateway.log,轮转备份为 gateway.log.1
登录自启任务 ~/Library/LaunchAgents/local.codex-mixin.{menu-launch,service}.plist
LiteLLM metadata 缓存 ~/.codex-mixin/model_metadata_litellm.json
模型测速结果 ~/.codex-mixin/model-benchmarks.json
Codex 配置 ~/.codex/config.toml
Codex 配置备份 ~/.codex/config.toml.codex-mixin.backup
Codex 登录 ~/.codex/auth.json
仅自定义模式登录备份 ~/.codex/auth.json.codex-mixin.backup
安装前无登录文件标记 ~/.codex/auth.json.codex-mixin.absent
Codex 模型目录 ~/.codex/model-catalogs/mixin-models.json

做 Codex 配置实验时不要直接碰真实配置,可以使用隔离目录:

CODEX_HOME=/tmp/codex-mixin-home codex-mixin connect codex --codex-oauth-proxy

开发与发布

本地检查:

cargo fmt --all -- --check
cargo test --locked
./macos/build_app.sh

Release workflow 在推送 v* tag 或手动运行时生成:

平台 架构 CLI 包 安装包
Linux x86_64 .tar.gz .deb
Linux aarch64 .tar.gz .deb
macOS x86_64 .tar.gz .dmg
macOS aarch64 .tar.gz .dmg

macOS DMG 内包含 Codex Mixin.appbin/codex-mixinREADME.mdApplications 快捷入口,并带有 Finder 窗口布局和背景图。Linux .deb 会把 CLI 安装到 /usr/local/bin/codex-mixin

许可证

Codex Mixin 使用 PolyForm Noncommercial License 1.0.0

这意味着你可以为非商业目的使用、复制、修改和分发源码及其修改版本;不能把它用于商业目的。这个许可证是 source-available / non-commercial license,不是 OSI open source license。

分发副本或修改版本时,请同时保留 LICENSENOTICE

常见问题

为什么 macOS 14 Sonoma 提示 App 无法打开?

旧版发布包的 Swift 菜单栏程序可能被编译为最低要求 macOS 15。这个要求写在 Mach-O 可执行文件中,修改 Info.plist 或执行 xattr 都不能降低它。请安装 Release 页面中的修复版本;当前菜单栏程序和 Info.plist 都以 macOS 13.1 为最低版本。若系统仅提示无法验证开发者,再执行快速安装中的 xattr 命令。

安装后为什么要重启 Codex App?

Codex App 读取配置有自己的生命周期。安装或恢复 Codex 配置后,需要重启 Codex App 才能看到最新模型目录。Codex CLI 需要重新开启新会话。

官方 GPT 会走本地网关吗?

推荐的 --codex-oauth-proxy 模式会保留官方 OAuth provider 能力。官方 GPT 模型继续走官方 Codex/OpenAI 路径;自定义模型通过本地网关转发到你的 provider。

为什么不直接做一个新的 Codex App?

官方 Codex App 的交互、插件、权限模型和工具运行时更新很快。二次开发 App 容易变成长期追版本。Codex Mixin 选择增强官方 App,而不是替代官方 App。

菜单栏额度显示支持哪些 provider?

baidu-oneapiopenrouter 有默认额度接口。其他 provider 可以在设置窗口里填自定义额度接口。Codex Mixin 会从常见 JSON 字段中提取 used / limit / remaining 并显示进度条;无法识别时会显示明确的查询结果或错误。

API Key 存在哪里?

默认保存在 ~/.codex-mixin/config.json。这是本机用户目录下的配置文件。不要把它提交到 Git。

反馈问题时应该带什么?

请在 GitHub Issues 新建 issue,选择 Bug report 或 Question 模板;Bug report 模板会要求版本、平台、复现步骤和诊断信息。手动反馈时请提供:

  • Codex Mixin 版本。
  • Codex App / Codex CLI 版本。
  • 使用菜单栏 App 还是 CLI。
  • provider 类型。
  • 问题截图。
  • codex-mixin doctor 输出。
  • codex-mixin service logs -n 200 输出。

English

Codex Mixin is a local Rust gateway, CLI, and macOS menu bar app for connecting custom model providers to official Codex while keeping ChatGPT/OpenAI account features, official GPT models, remote control, and the native Codex experience.

It is not a fork or repackaged Codex Desktop. Codex remains the main UI. Codex Mixin only handles provider setup, protocol translation, model catalog generation, managed config updates, daemon lifecycle, quota display, and rollback.

Why

Many users already have model access through internal OneAPI gateways, OpenRouter, DeepSeek, or self-hosted OpenAI / Anthropic compatible APIs. A simple base_url patch is not enough for Codex because real usage needs:

  • Official ChatGPT account features to keep working.
  • Official GPT models and custom models in the same model picker.
  • Existing sessions to stay visible instead of disappearing after a provider switch.
  • A valid Codex model catalog with context window and instruction fields.
  • A local service that survives terminal exits.
  • Provider presets so users do not need to know every endpoint path.
  • Human-readable quota status instead of raw JSON in the menu bar.

Codex Mixin exposes a Responses-compatible endpoint on an automatically selected loopback port, translates requests to Anthropic Messages or OpenAI Chat Completions upstreams, then translates streaming responses back for Codex. It reuses the last successful port and updates the managed Codex config if that port becomes unavailable.

Features

  • Keeps official Codex/OpenAI account path for official GPT models.
  • Adds custom upstream models to the Codex model picker.
  • Avoids GPT name collisions by suffixing upstream gpt-* models with their provider (for example, gpt-...-baidu-oneapi); legacy -custom aliases remain compatible.
  • Registers the managed provider for the selected mode and migrates existing sessions to it during installation.
  • Backs up ~/.codex/config.toml before managed changes and restores both the config and original history provider on uninstall.
  • Includes provider presets for custom, baidu-oneapi, openrouter, and deepseek.
  • Supports Anthropic Messages and OpenAI Chat Completions upstreams.
  • Drives upstream automatic prompt caching with a byte-level prefix contract, reports per turn whether the cache survived and where it broke, and inlines a tool screenshot only on the turn it first enters the context so history never carries image bytes forever.
  • Keeps native Codex image generation for official GPT models and can route custom-model image calls to an OpenAI-compatible upstream image endpoint.
  • Completes model metadata using LiteLLM metadata plus built-in model-family rules.
  • Provides one model-selection and benchmark window for searching, enabling, and saving models, then recording sortable TTFT, TPS, actual usage tokens, total latency, timeout results, and estimated quota cost.
  • Orchestrates multiple Panel models in parallel, compares them with a Judge model, and streams a Final answer, with an optional native interactive Fusion · Review surface in Codex.
  • Provides a macOS menu bar control surface for service lifecycle, provider setup, Codex install, rollback, quota, token/cache usage, logs, and updates.
  • Exposes an Anthropic Messages-compatible /v1/messages endpoint so Claude Code and Anthropic SDKs can reuse the same local gateway.
  • Provides one-click install/uninstall for Claude Code through ~/.claude/settings.json env overrides.
  • Starts the background gateway when the menu bar app opens and prominently shows the active endpoint.
  • Reuses a persisted loopback port, automatically selects a free port on conflict, and synchronizes the managed Codex endpoint.
  • Opens both the menu bar app and gateway at login, while keeping their launchd jobs independent.
  • Keeps the background daemon running after the app exits and migrates gateway ownership between the daemon and launchd without running both at once.
  • Uses launchd to restart unexpected failures with throttling, while graceful stops remain stopped.
  • Writes timestamped lifecycle and error logs, rotating at 5 MiB with one .1 backup.
  • Silently checks GitHub Releases on every app launch and prompts only when a newer version is available.

Install

Download the DMG for your Mac from GitHub Releases:

Mac File
Apple Silicon codex-mixin-<version>-aarch64-apple-darwin.dmg
Intel codex-mixin-<version>-x86_64-apple-darwin.dmg

The menu bar app supports macOS 13.1 Ventura and later. Open the DMG, drag Codex Mixin.app to Applications, then launch it.

Release bundles have a valid ad-hoc signature, but are not signed with an Apple Developer ID or notarized. If Gatekeeper blocks the app, run:

xattr -dr com.apple.quarantine "/Applications/Codex Mixin.app"

After launch, follow the menu bar actions to configure a provider and install it into Codex. Remote Linux or Codex CLI users can download the CLI archives from the same Release page.

CLI asset names
  • macOS Apple Silicon: codex-mixin-cli-<version>-aarch64-apple-darwin.tar.gz
  • macOS Intel: codex-mixin-cli-<version>-x86_64-apple-darwin.tar.gz
  • Linux x86_64: codex-mixin-cli-<version>-x86_64-unknown-linux-musl.tar.gz or codex-mixin-<version>-x86_64-unknown-linux-musl.deb
  • Linux ARM64: codex-mixin-cli-<version>-aarch64-unknown-linux-musl.tar.gz or codex-mixin-<version>-aarch64-unknown-linux-musl.deb

Usage

For Codex Desktop on macOS

  1. Open Codex Mixin.app.
  2. Open Set Provider and Key... from the menu bar.
  3. Choose a provider and enter your API key. Only enter the upstream root URL, not /v1/messages or /v1/chat/completions.
  4. Click Start Local Gateway.
  5. Click Install to Codex..., then explicitly choose Official Account Mode or Custom Models Only.
  6. Restart Codex Desktop.
  7. Pick an available model in Codex.

For Codex CLI

codex-mixin setup
codex-mixin info

setup is the first-run entry point: in a TTY it can prompt for the provider preset and API key, adds or updates the provider, refreshes models, starts or restarts the gateway as needed, then asks whether to keep official Codex account features, use custom models only, or skip Codex installation. When you choose an installation mode, setup finishes the Codex install itself. Scripts and CI can pass --key, --quota-username, and --codex-mode official|custom|skip to skip all prompts.

For later management, use provider for providers, service for the gateway, connect for Codex/Claude integration, update to update the CLI from the latest GitHub Release, info for state, and doctor for diagnosis. Then start a new Codex CLI session.

Provider Presets

Provider Upstream protocol Base URL Chat path Image path Models path Quota path
custom OpenAI Responses by default User provided /v1/responses Optional, user provided /v1/models Auto-detected from common read-only endpoints
baidu-oneapi Anthropic Messages https://oneapi-comate.baidu-int.com /v1/messages /v1/images/generations POST /openapi/v2/available_models /openapi/v3/user/quota
openrouter OpenAI Chat Completions https://openrouter.ai/api /v1/chat/completions Optional, user provided /v1/models /v1/credits
deepseek OpenAI Chat Completions https://api.deepseek.com /chat/completions Optional, user provided /models None
opencode-go OpenAI Responses https://opencode.ai/zen/go /v1/responses None /v1/models Dashboard /workspace/{id}/go + /billing

Only enter the upstream root URL in the settings window. Codex Mixin adds provider-specific paths. The Baidu OneAPI quota endpoint also requires a quota username; both the CLI and app validate it before saving. OpenCode Go quota display also requires a workspace ID and the opencode.ai auth cookie. Take both values from the OpenCode Go dashboard in a signed-in browser; refresh the cookie when it expires. When a custom provider is added or updated, Codex Mixin probes /v1/responses, then /v1/messages, then Chat Completions, and stores the first working protocol. Baidu OneAPI is excluded and keeps its curated protocol. Curated presets keep offline-verified protocols, for example OpenCode Go uses /v1/responses. For Baidu OneAPI, users can select either the “DUCC core” or “DUCX core”. Both are header generators: the gateway prewarms one short auth turn in the background, captures the native comate_custom_header, Authorization, and related headers, then caches them. The warmup turn is stopped before it reaches the real OneAPI, so it does not consume inference quota. DUCC runs as a short-lived --bare --print process; DUCX runs as a short-lived --disable hooks/plugins exec process. Neither maintains a persistent 350 MiB worker.

The caller request always determines the real model and body. The selected auth core only produces native headers, which Mixin injects into its own upstream request. Responses subrequests created by Fusion, Web Search, image generation, and Auto Review use the same executor and cannot bypass the selected core. The reporting hook is decoupled from the auth core: the provider config stores a dedicated data-report executable path, and the hook no longer reads the DUCC/DUCX auth path.

For the DUCC core, the macOS App asks for confirmation, follows the package rules from Baidu's baidu-cc/install.sh, and downloads an isolated copy under ~/.codex-mixin/ducc/home/ without executing the installer. For the DUCX core, the managed copy lives under ~/.codex-mixin/ducx/home/. A dedicated Terminal displays download progress and runs the managed copy's login; it closes after QR-code login succeeds. Providers can forward user-supplied custom request headers with --header-env NAME=ENV_VAR. The configuration stores only the header and environment-variable names, never the value. The gateway reads values once at startup and fails closed when a value is missing or empty; restart it after changing a value. Primary authentication and transport headers cannot be overridden, and comate_custom_header is reserved for the selected auth core. Codex Mixin does not generate, validate, or authorize credentials; users must confirm that they are entitled to use the relevant account, credential, and service. Managed DUCC/DUCX data-report continues to run the SessionStart, UserPromptSubmit, Stop, and SessionEnd hooks from its managed settings, attributing usage to Baidu OneAPI token traffic. When a custom provider is added or refreshed, Codex Mixin concurrently probes common read-only quota endpoints used by New API, Sub2API, OpenRouter, and similar gateways. It stores an endpoint only after receiving recognizable quota data and never runs paid inference. Separately, adding or updating a custom base URL without an explicit protocol or API path probes conversation endpoints in the order Responses, Messages, then Chat Completions.

Codex Install Behavior

The install panel and CLI expose two mutually exclusive modes:

Mode CLI command models_cache.json Result
Official account mode codex-mixin connect codex --codex-oauth-proxy Required; sign in and open Codex once first Merges official GPT and custom models while preserving official OAuth, plugins, cloud tasks, and account features
Custom models only codex-mixin connect codex --custom-only Never read or required Backs up and temporarily replaces Codex auth, then uses a local login placeholder to enable the model picker; official plugins, cloud tasks, and account features are unavailable

The CLI never guesses a mode from auth.json or models_cache.json, and the mode flag is required. Even if you have an official account, you may explicitly choose custom-only mode. To use official features, cancel installation, sign in to Codex and open it once, then select official account mode.

Installation needs a local codex binary to validate the managed config with codex doctor and codex debug models. Codex Mixin first uses CODEX_CLI_PATH, the bundled CLI inside /Applications/ChatGPT.app or /Applications/Codex.app, then ~/.local/bin/codex, then PATH. If none is found, it runs the official Codex installer in non-interactive mode and installs the standalone CLI under ~/.local/bin.

Installation:

  1. Fetches upstream models.
  2. Generates ~/.codex/model-catalogs/mixin-models.json.
  3. Backs up ~/.codex/config.toml.
  4. Official account mode registers a separate codex-mixin provider. Custom-only mode reuses Codex's built-in amazon-bedrock provider and only points its base_url at the local gateway. Neither mode overrides the built-in openai provider.
  5. Sets model_provider to the managed provider for the selected mode.
  6. Migrates existing JSONL and SQLite history indexes to that managed provider while keeping backups.
  7. Official account mode writes requires_openai_auth = true and supports_websockets = true. Custom-only mode uses a local Bedrock-shaped login placeholder, which makes Codex Desktop skip its official-model allowlist and expose the complete custom catalog.
  8. In custom-only mode, backs up ~/.codex/auth.json as auth.json.codex-mixin.backup; if no auth file existed, it creates an auth.json.codex-mixin.absent marker, then installs a codex-mixin-managed local login placeholder.

Account-mode managed shape:

model_catalog_json = "/Users/you/.codex/model-catalogs/mixin-models.json"
model_provider = "codex-mixin"

[model_providers.codex-mixin]
name = "Codex Mixin"
base_url = "http://127.0.0.1:<auto-selected-port>/v1"
wire_api = "responses"
requires_openai_auth = true
supports_websockets = true

Custom-only mode only overrides the built-in amazon-bedrock provider's supported base_url field and writes an upstream model as the default:

model = "DeepSeek-V4-Flash"
model_catalog_json = "/Users/you/.codex/model-catalogs/mixin-models.json"
model_provider = "amazon-bedrock"

[model_providers.amazon-bedrock]
base_url = "http://127.0.0.1:<auto-selected-port>/v1"

In account mode, you can switch from an official GPT model to a custom model and back within the same Codex task. Codex Mixin routes each Responses WebSocket request independently and rebuilds incremental custom-model context across turns.

Rollback:

codex-mixin connect remove codex

Uninstall reads the original provider from the config backup, or uses Codex's default openai provider when none was configured. Sessions using the managed provider are migrated back so they remain visible after rollback. It also removes the custom-only login placeholder and restores the pre-install auth.json. If the user changed auth after installation, uninstall preserves the current login instead of overwriting it with the old backup.

To move from custom-only to official account mode, uninstall first, sign in to Codex and open it once to generate the model cache, then reinstall with --codex-oauth-proxy. To move back to custom-only mode, reinstall with --custom-only; the current official login is backed up.

Restart Codex Desktop after install or uninstall. Start a new session for Codex CLI.

Model Fusion

Fusion virtual models run a Panel → Judge → Final pipeline. Open Fusion Settings... from the menu bar, select 1–8 Panel models plus one Judge and one Final model, then save and restart the gateway. The virtual model appears in Codex as mixin/fusion/<profile-id>.

Fusion runs Panel and Judge only for new user turns in Plan mode. After switching to Default mode to execute the plan, all later user turns and tool-result continuations go directly to the profile's Final model, avoiding repeated analysis during implementation.

Interactive Fusion Review in Codex

Show Panel / Judge intermediate results is enabled by default and maps to show_intermediate_results: true in stored config. When enabled, Codex Mixin uses Codex's native inline visualization surface:

  1. Panel reports appear as compact side-by-side cards in configured order, with a short preview and click-to-expand full output.
  2. Judge returns exactly three selectable numbered points covering consensus and evidence, tensions and gaps, and a concrete recommendation. Titles and bodies follow the language of the current user request.
  3. The Final answer streams as a normal Codex message, without an extra Final heading or model label.

Visualization files stay inside the current Codex task's visualization directory and make no network requests. If that directory is unavailable, the gateway falls back to a collapsible Markdown Panel table followed by the Judge synthesis.

When disabled, Panel and Judge still run, but only the Final answer is added to the conversation. Progress remains visible through reasoning-summary events.

Image Generation

  • Official GPT models keep the native Codex image_gen extension. Requests to local /v1/images/generations and /v1/images/edits routes are forwarded to the official image backend with Codex OAuth and chatgpt-account-id, never with the custom provider key.
  • When an upstream image path is configured, custom-model image_gen.imagegen calls still run through the native Codex extension so Codex saves and displays the image. Codex Mixin routes the text-to-image request to that provider. Both Anthropic Messages and OpenAI Chat Completions upstreams are supported.
  • The baidu-oneapi preset configures /v1/images/generations automatically and sends gpt-image-2.
  • Other providers must expose an OpenAI-compatible endpoint that accepts gpt-image-2 and returns data[0].b64_json. Enter its path relative to the provider base URL, for example /v1/images/generations.
  • Without an upstream image path, Codex Mixin preserves the tool call so the native Codex extension can use the official image backend.

Custom upstreams currently support text-to-image generation only. Non-empty referenced_image_paths or a positive num_last_images_to_include fails explicitly instead of silently changing backends. Clear the image path in settings to disable custom upstream image generation.

Prompt Caching

Upstream automatic prompt caching hits under one condition: the previous prompt prefix is byte-identical and new content is appended only at the tail. Codex Mixin enforces that as a verifiable contract instead of hoping for it.

Every provider request derives its cache shape from the bytes actually sent upstream: the system prompt, the tool definitions and tool_choice, the reasoning configuration, and a digest of each message. The next turn in the same session is compared against the previous one and classified:

State Meaning
cold_start No earlier request recorded for this session
append_only Earlier content is byte-identical and new turns were appended, so the cache fully survives
tail_rewritten Only the previous last message changed; everything before it still caches
system_changed / tools_changed / config_changed Instructions, tools, or reasoning configuration drifted, invalidating the whole prefix
turn_rewritten An earlier message was rewritten, so the provider recomputes from there
history_truncated History shrank, which is what compaction looks like from upstream

Cache loss is logged at WARN with reused_turns and reused_bytes, so a miss has a concrete cause. The full per-turn trail needs debug level:

RUST_LOG=codex_mixin=debug codex-mixin service start --foreground

Images follow the same contract. A tool screenshot is inlined only on the turn the model has not answered yet, compressed to a 1568 px longest side, and replayed as a stable marker on every later turn. Screenshots and vision tools keep working while history stops carrying image bytes forever, and the only cost is rewriting what was previously the last message. Decompressed JSON requests over HTTP and WebSocket are limited to 256 MiB. HTTP requests are spooled before parsing, and an upstream 413 triggers one retry with embedded images reduced to a 768 px longest side at JPEG quality 65.

OpenAI Chat Completions upstreams reject images inside tool messages, so those images move into a user message placed right after the tool run, keeping assistant tool_calls adjacent to the tool results they pair with.

scripts/e2e_prompt_cache.sh checks all of this against the real upstream bytes through a live gateway, and CI runs it on every commit.

CLI Reference

# First-run setup; prompts for the preset, API key, and Codex mode
codex-mixin setup

# Scripts and CI: pass everything explicitly
codex-mixin setup --preset openrouter --key <key> --codex-mode custom
codex-mixin setup --preset baidu-oneapi --key <key> --quota-username <username> --codex-mode skip
codex-mixin setup --preset <preset> --no-start

# Update the CLI from the latest GitHub Release and restart the gateway
codex-mixin update

# Provider management
codex-mixin provider list
codex-mixin provider add --preset <preset> --key <key>
codex-mixin provider update <id> --key <key>
codex-mixin provider discover <id>
codex-mixin provider test <id>
codex-mixin provider select <id> --model <model>...

# Local gateway; service start restarts it when config or arguments change
codex-mixin service start
codex-mixin service status
codex-mixin service restart
codex-mixin service logs -n 200
codex-mixin service start --foreground

# Codex / Claude integration
codex-mixin connect codex --codex-oauth-proxy
codex-mixin connect codex --custom-only
codex-mixin connect claude --model "Claude Sonnet 5"
codex-mixin connect remove codex
codex-mixin connect status

# State and diagnosis
codex-mixin info
codex-mixin info --json
codex-mixin doctor
codex-mixin doctor --quick
codex-mixin doctor --fix               # auto-repair permissions, stale state, gateway startup, base_url, model catalog
codex-mixin doctor --fix --restart-apps # additionally allow restarting the ChatGPT/Codex app (interrupts active sessions)

Files

Purpose Path
Codex Mixin config ~/.codex-mixin/config.json
Gateway log ~/.codex-mixin/gateway.log, with gateway.log.1 as the rotated backup
Login launch agents ~/Library/LaunchAgents/local.codex-mixin.{menu-launch,service}.plist
LiteLLM metadata cache ~/.codex-mixin/model_metadata_litellm.json
Codex config ~/.codex/config.toml
Codex config backup ~/.codex/config.toml.codex-mixin.backup
Codex auth ~/.codex/auth.json
Custom-only auth backup ~/.codex/auth.json.codex-mixin.backup
Pre-install auth-absent marker ~/.codex/auth.json.codex-mixin.absent
Codex model catalog ~/.codex/model-catalogs/mixin-models.json

Use an isolated Codex home for experiments:

CODEX_HOME=/tmp/codex-mixin-home codex-mixin connect codex --codex-oauth-proxy

Development

git clone https://github.com/Edward-lyz/codex-mixin.git
cd codex-mixin
cargo fmt --all -- --check
cargo test --locked
./macos/build_app.sh

Release builds are produced by GitHub Actions for Linux and macOS, x86_64 and aarch64, including CLI archives plus .deb or .dmg installers.

License

Codex Mixin is licensed under the PolyForm Noncommercial License 1.0.0.

You may use, copy, modify, and distribute the source code and modified versions for noncommercial purposes. Commercial use is not permitted. This is a source-available / non-commercial license, not an OSI open source license.

Keep both LICENSE and NOTICE when distributing copies or modified versions.

Support

Open a new issue at GitHub Issues and use the Bug report or Question template; the Bug report template asks for version, platform, reproduction steps, and diagnostics. Manually include:

  • Codex Mixin version.
  • Codex Desktop / Codex CLI version.
  • Whether you use the menu bar app or CLI.
  • Provider type.
  • Screenshot if applicable.
  • codex-mixin doctor.
  • codex-mixin service logs -n 200.

About

Codex menu bar app and local gateway for mixing custom model providers with the official Codex account path

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages