fix(codex): ensure [model_providers.<id>] TOML section exists in config.toml#3719
fix(codex): ensure [model_providers.<id>] TOML section exists in config.toml#3719Kakueeen wants to merge 4 commits into
Conversation
… config.toml Codex CLI requires the `[model_providers.<id>]` section to route requests to a custom (non-reserved) provider. Without it, Codex falls back to `model_provider: openai` and all API calls go directly to api.openai.com. The section can be lost when: - Codex Desktop App rewrites config.toml, stripping unknown tables - CC-Switch imports a pre-existing flat-format config - A backup/restore cycle drops the section Add a defensive normalization step (`ensure_codex_model_provider_section`) that creates an empty `[model_providers.<id>]` table whenever `model_provider` is set to a custom provider ID but the corresponding table is missing. This runs in both `write_codex_live_for_provider` and `prepare_codex_provider_live_config`, covering all code paths that write config.toml to disk. Fixes farion1231#3449 Signed-off-by: Liu Zhangjian <liuzhangjian@uniontech.com>
set_implicit(true) on the synthesized table prevented toml_edit from emitting the [model_providers.<id>] section header, causing the empty table to be invisible to subsequent DocumentMut parsing. This made set_codex_experimental_bearer_token fall through to the top-level fallback instead of scoping the token inside the provider table. Also update two test assertions to check the bearer token at its scoped location inside [model_providers.<id>] rather than the top level.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1761570241
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ovider table Address AI review P2 feedback: when ensure_codex_model_provider_section() creates a new [model_providers.<id>] table, it now copies/migrates the legacy top-level base_url and wire_api fields into the synthesized table and removes the top-level copies. This ensures that configs in the flat layout (model_provider + top-level endpoint fields) that Codex Desktop App or CC-Switch import can leave behind are normalized so that Codex CLI finds all required routing fields inside [model_providers.<id>]. Also fixes cargo fmt issues that caused CI to fail. Closes farion1231#3719
|
@codex review |
|
To use Codex here, create a Codex account and connect to github. |
farion1231
left a comment
There was a problem hiding this comment.
感谢您的贡献。请查看一下是否有以下问题:
P1:Clippy 阻塞
cargo clippy --lib -- -D warnings 失败,位置在 src-tauri/src/codex_config.rs:1136:
.map(|t| ensure_codex_model_provider_section(t)) 应改成 .map(ensure_codex_model_provider_section)。
P1/P2:可能没覆盖 #3449 的字面复现
#3449 贴出的坏配置没有 model_provider,但 PR 的 ensure_codex_model_provider_section() 在缺少 model_provider 时直接原样返回。也就是说,它只修了“有 model_provider、缺 [model_providers.] 表”的场景,可能没修“顶层 base_url/wire_api + 没有 model_provider”这个 issue 报告格式。需要作者确认真实现场格式,或补一条针对该 flat config 的 normalization。
P2:合成 provider 表时仍可能不完整
PR 会在没有任何 endpoint 字段时合成只有 experimental_bearer_token 的 [model_providers.] 表,这是对旧测试 does_not_create_incomplete_provider_table 的反转。没有 base_url 的表对 Codex 路由帮助有限。另外,如果 provider 表已存在但缺 base_url/wire_api,而顶层有旧字段,当前代码会 early-return,不会补齐缺失字段。建议只在有可迁移 endpoint 时合成,或至少回填缺失字段并明确 name / requires_openai_auth 的策略。
P1 (Clippy): Use method reference instead of closure. P1/P2: Handle flat config without model_provider (issue farion1231#3449 format). When top-level base_url exists but model_provider is absent, synthesize model_provider = "custom" + [model_providers.custom] table with migrated endpoint fields. P2: Fill incomplete existing provider tables. When [model_providers.<id>] exists but is missing base_url/wire_api while top-level copies remain, fill the gap so Codex CLI can route. Refactored ensure_codex_model_provider_section() with clearer documentation covering all three normalization scenarios. Closes farion1231#3719
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8d1bedd2a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (field, _) in &fields_to_insert { | ||
| doc.remove(field); |
There was a problem hiding this comment.
Preserve endpoints when provider entries are inline
When a valid TOML config represents the active provider as an inline entry, e.g. [model_providers] followed by vendor = { name = "Vendor" }, mp.contains_key(&provider_id) is true but as_table_mut() returns None. In that case the code above does not copy base_url/wire_api into the provider entry, yet these lines still remove the top-level endpoint fields, leaving the active custom provider without the base_url Codex needs for routing. Only remove the flat fields after a successful insert, or handle inline tables as provider tables.
Useful? React with 👍 / 👎.
Summary / 概述
Fix Codex CLI ignoring the
model_provider = "custom"setting by ensuring the[model_providers.<id>]TOML section always exists in the writtenconfig.toml.Codex CLI requires the
[model_providers.<id>]section to route requests to a custom provider. When this section is missing — which can happen when Codex Desktop App rewritesconfig.toml, when CC-Switch imports a pre-existing flat-format config, or after a backup/restore cycle — Codex falls back tomodel_provider: openaiand all API calls go directly toapi.openai.com.Changes / 变更内容
src-tauri/src/codex_config.rsensure_codex_model_provider_section()that defensively creates[model_providers.<id>]table whenmodel_provideris set but the table is missing. Integrate intowrite_codex_live_for_providerandprepare_codex_provider_live_config. Add 6 unit tests covering normalization edge cases.Fix details (commits 2-3)
toml_edit::Table::new()creates implicit tables (no[section]header in output). Changed toset_implicit(false)so the synthesized[model_providers.<id>]header is emitted correctly.experimental_bearer_tokenat its scoped location[model_providers.<id>]rather than the top level — the function intentionally scopes bearer tokens inside the provider table for custom providers.Root Cause / 根因
The
[model_providers.<provider>]TOML table could be lost during the config lifecycle (Codex.app rewrites, import, backup restore). Without this table, Codex CLI ignores themodel_providertop-level key and defaults toopenai, routing all traffic to the official OpenAI endpoint instead of the configured custom provider.Test Plan / 测试计划
pnpm typecheck)cargo test --lib codex_config— 43 passed, 0 failedensure_codex_model_provider_sectioncargo fmt --check/cargo clippy(requires Rust 1.95)[model_providers.<id>]section persists in~/.codex/config.tomlRelated Issue / 关联 Issue
Fixes #3449