Skip to content

feat(codex): configure shared and per-model approval models - #246

Open
mkit777 wants to merge 2 commits into
router-for-me:mainfrom
mkit777:feat/codex-auto-review-model
Open

mkit777 wants to merge 2 commits into
router-for-me:mainfrom
mkit777:feat/codex-auto-review-model

Conversation

@mkit777

@mkit777 mkit777 commented Sep 9, 2026

Copy link
Copy Markdown

feat(codex): configure shared and per-model approval models

Problem

Selecting a primary model in EasyCLIProxyAPI does not select the model used by Codex's automatic approval reviewer. With custom providers or model aliases, the reviewer can choose an unintended or unavailable model even when the primary model works normally.

In Codex rust-v0.153.2, the reviewer reads auto_review_model_override from the primary model's catalog entry. When present, that model ID is used. Otherwise, it looks for the provider's preferred review model (commonly codex-auto-review) in the available catalog and falls back to the primary model if the preferred model is absent. This is automatic approval, not the code-review model setting. The override changes the model ID, not the provider; catalog membership alone does not guarantee upstream availability.

UI and save behavior

  • Add Approval model to the main Codex configuration page: Codex default plus all available model IDs. Save with the existing apply/update configuration action; no new save entry point.
  • Place the per-model Approval model beside Display name in the model catalog editor: Inherit global configuration, Codex default, plus all model IDs. Save with the editor's existing Save button.
  • Extract and reuse the existing searchable AgentModelPicker, retaining the project's styling. Special choices are separate from actual model IDs, including IDs that happen to match a special choice's internal name.
  • Include hidden models. Preserve and warn about saved IDs that are no longer listed instead of silently changing the selection.
  • Keep the existing Chinese, English, Japanese, and traditional-Chinese translation conventions.

Precedence and persistence

Per-model selection Global selection Generated auto_review_model_override
Inherit A model ID Global model ID
Inherit Codex default Omitted
Codex default Any Omitted
A model ID Any Per-model model ID

Codex default removes the field, including any override carried by the source template. It does not preserve the template override or write a null/object value to the generated catalog.

The existing customization file stores the global default_auto_review_model separately. A per-model null/absent selection inherits; {"mode":"codex_default"} explicitly bypasses the global setting; a string selects a model. The object is an editor-storage marker only.

  • Inheritance is resolved during generation, not materialized in per-model settings; newly discovered models inherit the global choice.
  • The editor saves only revision + models, preserving the global choice.
  • The main configuration action validates the revision, prepares the candidate catalog, applies the Codex configuration, and then persists the global choice. A failed configuration apply does not persist that choice.
  • Reuse existing storage, validation, revision checks, and catalog synchronization. Older customization files remain readable.

Approval policy and permissions are unchanged. The selected model must be callable through the configured proxy.

Validation

  • cargo test --locked --offline --manifest-path src-tauri/Cargo.toml codex_catalog:: --no-fail-fast: 33 passed. Includes the precedence matrix with/without template overrides, persistence/reload, new-model inheritance, stale revisions, and failed configuration applies.
  • bun test tests/agentModelPicker.test.ts tests/codexModelCatalog.test.ts: 33 passed.
  • npm run check: passed.
  • Local macOS debug app build: passed.
  • Native UI acceptance in a separate, isolated local copy: used the existing buttons and read the actual Rust-generated files to verify global inheritance, explicit Codex default omission, and explicit per-model overrides. The isolated fixture/proxy and local preview entry point are not included in this PR.
  • git diff --check: passed.

No real upstream automatic-approval request was exercised. The native check validates interaction and configuration generation, not upstream model availability.


中文翻译

问题背景

在 EasyCLIProxyAPI 中选择主模型,并不等于指定 Codex 自动审批使用的模型。使用自定义 provider 或模型别名时,即使主模型调用正常,自动审批仍可能选中非预期或不可用的模型。

Codex rust-v0.153.2 源码中,审批器读取主模型目录条目auto_review_model_override。存在该字段时使用指定模型 ID;否则在可用目录中查找 provider 首选审批模型(通常为 codex-auto-review),不存在时回退主模型。这是自动审批模型,不是代码审查模型配置。该覆盖项只改变模型 ID,不切换 provider;模型出现在目录里也不保证上游可以调用。

界面与保存入口

  • 在 Codex 主配置页面增加“审批模型”:选项为“Codex 默认”及全部可用模型 ID,使用现有应用/更新配置入口,不新增保存入口。
  • 模型目录编辑器中,“审批模型”与“显示名称”并排:选项为“继承全局配置”“Codex 默认”及全部模型 ID,使用现有“保存”按钮。
  • 提取并复用既有可搜索的 AgentModelPicker,沿用项目样式。特殊选项与真实模型 ID 分开,不会与同名模型发生冲突。
  • 包含隐藏模型;已保存但不再列出的 ID 保留并提示,不会静默更换。
  • 沿用中文、英文、日文及繁体中文的既有翻译机制。

优先级与持久化

单模型选择 全局选择 最终生成的 auto_review_model_override
继承全局配置 指定模型 全局指定的模型 ID
继承全局配置 Codex 默认 不写入字段
Codex 默认 任意 不写入字段
指定模型 任意 单模型指定的模型 ID

“Codex 默认”会移除覆盖字段,包括源模板自带的覆盖;不是保留模板值,也不是向最终目录写入 null 或对象。

既有自定义配置文件分别保存全局 default_auto_review_model 与单模型选择。单模型 null/缺省表示继承;{"mode":"codex_default"} 表示明确绕过全局;字符串表示指定模型。对象仅为编辑器保存选择的标记。

  • 生成目录时才解析继承,不把全局值固化到单模型配置;新增模型自动继承全局。
  • 模型编辑器只提交 revision + models,不覆盖全局选择。
  • 主配置入口检查修订版本,生成候选目录,应用 Codex 配置后再保存全局选择;应用失败时不保存该选择。
  • 复用既有存储、校验、修订版本检查和目录同步逻辑,旧配置文件仍可读取。

本改动不改变审批策略或权限。所选模型必须能够通过当前代理调用。

验证结果与边界

  • Rust 模型目录定向测试:33 项通过,覆盖有/无模板覆盖的优先级矩阵、持久化与重载、新模型继承、过期版本及配置应用失败。
  • 前端模型选择和配置逻辑测试:33 项通过
  • npm run check:通过。
  • macOS 本地 debug 应用编译:通过。
  • 独立本地副本的原生 UI 验收:通过现有入口保存,并读取 Rust 实际生成文件,验证继承全局、Codex 默认移除字段、单模型显式覆盖。隔离测试代理、配置和本地预览入口不包含在本 PR 中。
  • git diff --check:通过。

未向真实上游发起自动审批请求。原生验收覆盖交互和配置生成,不代表真实上游模型可用性已验证。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant