Skip to content

Bug: Codex requires_openai_auth = false 会被 Codeg 无条件重置为 true #406

Description

@AwangYes

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 设置面板的结构化控件

  1. ~/.codex/config.toml 中设置:

    [model_providers.codeg]
    requires_openai_auth = false
  2. 打开 Codeg 的 Codex 设置页面。

  3. 执行以下任一操作:

    • 将认证方式切换为 API Key 或模型供应商;
    • 修改 API Base URL;
    • 修改 WebSocket 支持开关;
    • 绑定或重新选择 Codex 模型供应商。
  4. 保存设置。

  5. 再次检查 ~/.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_providersrc/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

可复现路径二:更新已绑定的模型供应商

  1. 让 Codex 绑定一个 Codeg 模型供应商。
  2. 手动将 requires_openai_auth 设置为 false
  3. 在“模型供应商”设置中修改该供应商的 API URL、API Key 或模型。
  4. 检查 ~/.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
  • 用户显式配置 truefalse 时,更新其他字段必须保留原值。
  • 检测到 x-openai-actor-authorization = "local-image-extension" 时,不应写入或恢复
    requires_openai_auth = true;该组合要求 requires_openai_auth = false 才能使用原生
    imagegen。

前端

调整 ensureCodexProviderDefaults()

  • 先检查 [model_providers.codeg] 中是否已经存在 requires_openai_auth
  • 仅在字段不存在时添加默认值;
  • 已存在 truefalse 时均保持不变。

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

建议测试

至少增加以下回归测试:

  1. requires_openai_auth 缺失时,新建 codeg 供应商会补充默认值。
  2. requires_openai_auth = false 时,修改 API Base URL 后仍为 false
  3. requires_openai_auth = false 时,切换 WebSocket 设置后仍为 false
  4. requires_openai_auth = false 时,更新已绑定模型供应商的 URL、Key 或模型后仍为 false
  5. requires_openai_auth = true 时,上述操作仍保留 true
  6. codeg 供应商不应被添加或修改该字段。
  7. 配置 x-openai-actor-authorization = "local-image-extension"
    requires_openai_auth = false 时,所有结构化设置操作都应保留该组合。
  8. 更新已绑定模型供应商的 URL、Key 或模型后,local-image-extension Header 及
    requires_openai_auth = false 都应保持不变。
  9. 验证上述新版本配置使用原生 imagegen 调用路径,不会回退到 imagegen CLI 通道。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions