Bug: Codex requires_openai_auth = false 会被 Codeg 重置为 true
问题描述
当 ~/.codex/config.toml 中存在以下配置时:
model_provider = "codeg"
[model_providers.codeg]
base_url = "https://example.com/v1"
name = "codeg"
wire_api = "responses"
requires_openai_auth = false
直接编辑并保存原始 config.toml 后,requires_openai_auth = false
通常能够暂时保留。但是在 Codeg 中进行某些 Codex 配置操作后,该字段会被自动改回:
requires_openai_auth = true
这不是 TOML 解析错误,也不是 Codex CLI 自己修改配置,而是 Codeg 前端和后端的
受管配置逻辑显式写入了 true。
兼容背景与实际影响
requires_openai_auth = true 最初用于兼容和保留旧版 Codex 配置。在旧版集成中,
API Key Mode 还承担客户端图片执行器的授权,图片生成通过 imagegen CLI 通道执行。
新版本 Codex 支持通过模型供应商 HTTP Header 授权本地图片扩展。例如:
model_provider = "codeg"
[model_providers.codeg]
base_url = "https://example.com/v1"
name = "codeg"
wire_api = "responses"
requires_openai_auth = false
[model_providers.codeg.http_headers]
x-openai-actor-authorization = "local-image-extension"
当配置了:
[model_providers.codeg.http_headers]
x-openai-actor-authorization = "local-image-extension"
时,requires_openai_auth 应为 false。这样 Codex 才能原生调用 imagegen;如果该字段
被 Codeg 重置为 true,Codex 就不会使用预期的原生 imagegen 调用路径,而会回退到
imagegen CLI 通道。
因此,true 并不是所有 codeg 模型供应商配置都适用的固定值。它只能作为兼容旧版
配置的默认值,不能覆盖新版本配置中显式设置的 false,尤其不能破坏
local-image-extension 的 HTTP Header 授权组合。
预期行为
- 如果
requires_openai_auth 不存在,Codeg 可以为新建的 codeg 供应商补充默认值。
- 如果用户已经显式设置
requires_openai_auth = false,后续更新其他字段时应保留该值。
- 当
[model_providers.codeg.http_headers] 中配置了
x-openai-actor-authorization = "local-image-extension" 时,
requires_openai_auth 应保持为 false,以使用原生 imagegen 调用路径。
- 修改 API URL、模型、API Key 或 WebSocket 设置,不应覆盖无关的认证配置。
实际行为
只要当前模型供应商名称是 codeg,部分配置路径会无条件执行:
requires_openai_auth = true
因此用户设置的 false 会丢失。
对于配置了 local-image-extension Header 的新版本 Codex,这还会改变图片生成执行路径:
原本应走原生 imagegen 调用,覆盖后会回退到 imagegen CLI 通道。
可复现路径一:Codex 设置面板的结构化控件
-
在 ~/.codex/config.toml 中设置:
[model_providers.codeg]
requires_openai_auth = false
-
打开 Codeg 的 Codex 设置页面。
-
执行以下任一操作:
- 将认证方式切换为 API Key 或模型供应商;
- 修改 API Base URL;
- 修改 WebSocket 支持开关;
- 绑定或重新选择 Codex 模型供应商。
-
保存设置。
-
再次检查 ~/.codex/config.toml。
结果:requires_openai_auth 被改为 true。
前端根因
src/components/settings/acp-agent-settings.tsx 中的
ensureCodexProviderDefaults() 会在供应商名称为 codeg 时,无条件覆盖该字段:
next = patchCodexProviderField(
next,
CODEX_DEFAULT_MODEL_PROVIDER,
"requires_openai_auth",
"requires_openai_auth = true"
)
位置:src/components/settings/acp-agent-settings.tsx:2529-2563
该函数名表达的是“确保默认值”,但 patchCodexProviderField() 对已存在字段采用替换语义,
所以显式的 false 也会被覆盖。
调用该函数的主要路径位于:
- 设置或切换
model_provider:src/components/settings/acp-agent-settings.tsx:2618-2627
- 修改 API Base URL:
src/components/settings/acp-agent-settings.tsx:2642-2660
- 修改 WebSocket 支持:
src/components/settings/acp-agent-settings.tsx:2662-2681
- 切换认证方式:
src/components/settings/acp-agent-settings.tsx:6701-6705
- API Base URL 控件:
src/components/settings/acp-agent-settings.tsx:6783-6789
- WebSocket 控件:
src/components/settings/acp-agent-settings.tsx:6832-6846
可复现路径二:更新已绑定的模型供应商
- 让 Codex 绑定一个 Codeg 模型供应商。
- 手动将
requires_openai_auth 设置为 false。
- 在“模型供应商”设置中修改该供应商的 API URL、API Key 或模型。
- 检查
~/.codex/config.toml。
结果:即使没有打开 Codex 原始配置编辑器,该字段也会被改回 true。
后端根因
模型供应商更新入口会在 URL、Key 或模型变化时触发级联:
if url_changed || key_changed || model_changed {
acp::cascade_update_model_provider(...).await?;
}
位置:src-tauri/src/commands/model_provider.rs:215-242
级联更新最终进入 Codex 分支。读取现有 TOML 后,只要当前供应商名称为 codeg,
就会无条件插入 true:
if provider_name == "codeg" {
provider_table.insert(
"requires_openai_auth".to_string(),
toml::Value::Boolean(true),
);
}
位置:src-tauri/src/commands/acp.rs:8023-8032
完整调用链:
update_model_provider_core
-> cascade_update_model_provider
-> cascade_update_agent_config(AgentType::Codex)
-> provider_table.insert("requires_openai_auth", true)
-> persist_codex_native_config_files
相关级联覆盖逻辑由提交 3a355bbd 引入。
其他同类覆盖点
通用 Codex 本地配置写入函数 persist_codex_local_config() 中也存在相同的无条件覆盖:
if provider_name == "codeg" {
provider_table.insert(
"requires_openai_auth".to_string(),
toml::Value::Boolean(true),
);
}
位置:src-tauri/src/commands/acp.rs:3154-3163
当前 Codex 原始 TOML 的主要保存路径通常不会经过该函数,但保留这段逻辑会让其他调用入口
或未来复用仍然产生同样的问题。
为什么只有“某些情况”会发生
Codex 原始 TOML 保存路径会把编辑器中的文本作为完整配置写入,后端不会主动修改
requires_openai_auth:
位置:src-tauri/src/commands/acp.rs:9609-9628
因此:
- 只在原始编辑器中设置
false 并直接保存:通常会保留。
- 随后使用结构化 Codex 控件:前端会先把草稿中的字段改成
true。
- 更新已绑定模型供应商:后端级联更新会把磁盘中的字段改成
true。
这种多写入路径的差异导致问题表现得不稳定。
建议修复
将“无条件覆盖”改为“字段缺失时补默认值”。默认值是否继续使用 true 可以单独讨论,
但至少应尊重用户显式设置的布尔值。
建议兼容规则如下:
- 旧版配置中没有
requires_openai_auth 时,可以补充兼容默认值 true。
- 用户显式配置
true 或 false 时,更新其他字段必须保留原值。
- 检测到
x-openai-actor-authorization = "local-image-extension" 时,不应写入或恢复
requires_openai_auth = true;该组合要求 requires_openai_auth = false 才能使用原生
imagegen。
前端
调整 ensureCodexProviderDefaults():
- 先检查
[model_providers.codeg] 中是否已经存在 requires_openai_auth;
- 仅在字段不存在时添加默认值;
- 已存在
true 或 false 时均保持不变。
Rust 后端
两处代码应使用 entry 的“仅缺失时插入”语义,例如:
provider_table
.entry("requires_openai_auth".to_string())
.or_insert(toml::Value::Boolean(true));
需要修改的位置:
src-tauri/src/commands/acp.rs:3154-3163
src-tauri/src/commands/acp.rs:8023-8032
建议测试
至少增加以下回归测试:
requires_openai_auth 缺失时,新建 codeg 供应商会补充默认值。
requires_openai_auth = false 时,修改 API Base URL 后仍为 false。
requires_openai_auth = false 时,切换 WebSocket 设置后仍为 false。
requires_openai_auth = false 时,更新已绑定模型供应商的 URL、Key 或模型后仍为 false。
requires_openai_auth = true 时,上述操作仍保留 true。
- 非
codeg 供应商不应被添加或修改该字段。
- 配置
x-openai-actor-authorization = "local-image-extension" 且
requires_openai_auth = false 时,所有结构化设置操作都应保留该组合。
- 更新已绑定模型供应商的 URL、Key 或模型后,
local-image-extension Header 及
requires_openai_auth = false 都应保持不变。
- 验证上述新版本配置使用原生 imagegen 调用路径,不会回退到 imagegen CLI 通道。
Bug: Codex
requires_openai_auth = false会被 Codeg 重置为true问题描述
当
~/.codex/config.toml中存在以下配置时:直接编辑并保存原始
config.toml后,requires_openai_auth = false通常能够暂时保留。但是在 Codeg 中进行某些 Codex 配置操作后,该字段会被自动改回:
这不是 TOML 解析错误,也不是 Codex CLI 自己修改配置,而是 Codeg 前端和后端的
受管配置逻辑显式写入了
true。兼容背景与实际影响
requires_openai_auth = true最初用于兼容和保留旧版 Codex 配置。在旧版集成中,API Key Mode 还承担客户端图片执行器的授权,图片生成通过 imagegen CLI 通道执行。
新版本 Codex 支持通过模型供应商 HTTP Header 授权本地图片扩展。例如:
当配置了:
时,
requires_openai_auth应为false。这样 Codex 才能原生调用 imagegen;如果该字段被 Codeg 重置为
true,Codex 就不会使用预期的原生 imagegen 调用路径,而会回退到imagegen CLI 通道。
因此,
true并不是所有codeg模型供应商配置都适用的固定值。它只能作为兼容旧版配置的默认值,不能覆盖新版本配置中显式设置的
false,尤其不能破坏local-image-extension的 HTTP Header 授权组合。预期行为
requires_openai_auth不存在,Codeg 可以为新建的codeg供应商补充默认值。requires_openai_auth = false,后续更新其他字段时应保留该值。[model_providers.codeg.http_headers]中配置了x-openai-actor-authorization = "local-image-extension"时,requires_openai_auth应保持为false,以使用原生 imagegen 调用路径。实际行为
只要当前模型供应商名称是
codeg,部分配置路径会无条件执行:因此用户设置的
false会丢失。对于配置了
local-image-extensionHeader 的新版本 Codex,这还会改变图片生成执行路径:原本应走原生 imagegen 调用,覆盖后会回退到 imagegen CLI 通道。
可复现路径一:Codex 设置面板的结构化控件
在
~/.codex/config.toml中设置:打开 Codeg 的 Codex 设置页面。
执行以下任一操作:
保存设置。
再次检查
~/.codex/config.toml。结果:
requires_openai_auth被改为true。前端根因
src/components/settings/acp-agent-settings.tsx中的ensureCodexProviderDefaults()会在供应商名称为codeg时,无条件覆盖该字段:位置:
src/components/settings/acp-agent-settings.tsx:2529-2563该函数名表达的是“确保默认值”,但
patchCodexProviderField()对已存在字段采用替换语义,所以显式的
false也会被覆盖。调用该函数的主要路径位于:
model_provider:src/components/settings/acp-agent-settings.tsx:2618-2627src/components/settings/acp-agent-settings.tsx:2642-2660src/components/settings/acp-agent-settings.tsx:2662-2681src/components/settings/acp-agent-settings.tsx:6701-6705src/components/settings/acp-agent-settings.tsx:6783-6789src/components/settings/acp-agent-settings.tsx:6832-6846可复现路径二:更新已绑定的模型供应商
requires_openai_auth设置为false。~/.codex/config.toml。结果:即使没有打开 Codex 原始配置编辑器,该字段也会被改回
true。后端根因
模型供应商更新入口会在 URL、Key 或模型变化时触发级联:
位置:
src-tauri/src/commands/model_provider.rs:215-242级联更新最终进入 Codex 分支。读取现有 TOML 后,只要当前供应商名称为
codeg,就会无条件插入
true:位置:
src-tauri/src/commands/acp.rs:8023-8032完整调用链:
相关级联覆盖逻辑由提交
3a355bbd引入。其他同类覆盖点
通用 Codex 本地配置写入函数
persist_codex_local_config()中也存在相同的无条件覆盖:位置:
src-tauri/src/commands/acp.rs:3154-3163当前 Codex 原始 TOML 的主要保存路径通常不会经过该函数,但保留这段逻辑会让其他调用入口
或未来复用仍然产生同样的问题。
为什么只有“某些情况”会发生
Codex 原始 TOML 保存路径会把编辑器中的文本作为完整配置写入,后端不会主动修改
requires_openai_auth:位置:
src-tauri/src/commands/acp.rs:9609-9628因此:
false并直接保存:通常会保留。true。true。这种多写入路径的差异导致问题表现得不稳定。
建议修复
将“无条件覆盖”改为“字段缺失时补默认值”。默认值是否继续使用
true可以单独讨论,但至少应尊重用户显式设置的布尔值。
建议兼容规则如下:
requires_openai_auth时,可以补充兼容默认值true。true或false时,更新其他字段必须保留原值。x-openai-actor-authorization = "local-image-extension"时,不应写入或恢复requires_openai_auth = true;该组合要求requires_openai_auth = false才能使用原生imagegen。
前端
调整
ensureCodexProviderDefaults():[model_providers.codeg]中是否已经存在requires_openai_auth;true或false时均保持不变。Rust 后端
两处代码应使用 entry 的“仅缺失时插入”语义,例如:
provider_table .entry("requires_openai_auth".to_string()) .or_insert(toml::Value::Boolean(true));需要修改的位置:
src-tauri/src/commands/acp.rs:3154-3163src-tauri/src/commands/acp.rs:8023-8032建议测试
至少增加以下回归测试:
requires_openai_auth缺失时,新建codeg供应商会补充默认值。requires_openai_auth = false时,修改 API Base URL 后仍为false。requires_openai_auth = false时,切换 WebSocket 设置后仍为false。requires_openai_auth = false时,更新已绑定模型供应商的 URL、Key 或模型后仍为false。requires_openai_auth = true时,上述操作仍保留true。codeg供应商不应被添加或修改该字段。x-openai-actor-authorization = "local-image-extension"且requires_openai_auth = false时,所有结构化设置操作都应保留该组合。local-image-extensionHeader 及requires_openai_auth = false都应保持不变。