Skip to content

Codex 支持 agents.toml config_overrides(exec -c 透传) - #35

Merged
Fei2411 merged 2 commits into
mainfrom
feat/codex-config-overrides
Oct 7, 2026
Merged

Fei2411 merged 2 commits into
mainfrom
feat/codex-config-overrides

Conversation

@Fei2411

@Fei2411 Fei2411 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • [agents.codex] 新增 config_overrides = ["key=value", ...],每项作为 codex exec -c <item> 传入,位于 -C cwd 之后、任务级 -m / effort 之前。
  • 用于 --ignore-user-config 跳过的设置,例如自定义 model provider。不校验键名、不过滤,也不读取用户 config.toml。
  • 修正 SETUP.md:项目 .codex/config.toml 与项目 hooks/rules 通常不会加载(Codex 从被跳过的用户配置读取项目信任);AGENTS.md 与 $CODEX_HOME/rules 仍生效。
  • 文档写明密钥只能通过 env_key 引用环境变量。

Closes #28

Test plan

  • argv 顺序测试;空列表时 argv 不变;配置能传到 adapter 生成的 argv
  • 真实 Codex(Desktop 二进制):config_overrides = ['model="bridge-override-probe"'],API 错误中原样出现该模型名,说明 override 生效
  • pytest 669 passed;ruff、mypy 通过

Note

Medium Risk
Changes Codex worker invocation and routing via raw CLI overrides; misconfiguration can point tasks at the wrong provider, though quota lookup is intentionally disabled in that case.

Overview
Adds [agents.codex] config_overrides: each string is passed through as codex exec -c <item>, placed after -C cwd and before task model / effort so per-dispatch values still win. This lets Bridge supply settings that --ignore-user-config would otherwise skip (e.g. custom model_provider / gateway URLs) without reading the user config.toml.

SETUP.md documents the TOML example, env_key + MCP env_vars for secrets, and clarifies that project .codex/config.toml / project hooks usually do not load under --ignore-user-config, while AGENTS.md and $CODEX_HOME/rules still apply.

Quota lookup now fails closed when config_overrides is non-empty (same rationale as CLI -c overrides). Tests cover argv ordering, adapter wiring, and quota blocking.

Reviewed by Cursor Bugbot for commit 46a4e7e. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor

cursor Bot commented Oct 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: b06b68f3-f5ec-4fef-b37b-7efca6057761)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T16:13:26.575038Z 1e16dc2 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e16dc2681

ℹ️ 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".

Comment on lines +129 to +132
# Codex only: each item is passed as `codex exec -c <item>` (raw TOML
# key=value). No key validation, no filtering, user config.toml is
# never read.
config_overrides: list[str] = Field(default_factory=list)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Disable Codex quota lookup for config overrides

When config_overrides selects a custom model provider, the worker uses that provider, but quota_block_reason() in src/agent_bridge/quota_endpoints.py only detects -c overrides embedded in cfg.command. Because this new field is stored separately, list_agents can query and report the official Codex account quota for a worker actually using a custom gateway, violating the quota guard's fail-closed behavior. Treat any nonempty config_overrides as unsupported for quota lookup, or parse it with equivalent endpoint checks.

Useful? React with 👍 / 👎.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Devin Review

Comment thread src/agent_bridge/config.py
Comment thread src/agent_bridge/adapters/codex.py
effort=task.effort or session.effort,
resume_id=session.native_session_id,
yolo=yolo_requested(self.agent.session_meta),
config_overrides=self.agent.config_overrides,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Configured Codex model absent from result

With config_overrides = ['model="custom-model"'] and no dispatch model, get_result.observed_model stays null. run_turn reads only task and session models, losing the configured selection.

Learn more

A Codex override can set a model even when neither dispatch_task.model nor the session model is set. The worker then runs with that explicit configured model, but run_turn computes observed_model only from those two fields. The registry passes that value directly to the result, so callers cannot see the applied override.

Example: Configure config_overrides = ['model="bridge-override-probe"'] and dispatch without model. Codex receives the model in its argv, but get_result.observed_model is null rather than bridge-override-probe.

Recommended fix: Derive the effective model from overrides when no task or session model was selected, or obtain the selected model from Codex's turn events if available. Keep task and session model precedence when present.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@cursor

cursor Bot commented Oct 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: a960c576-8670-40fb-aa4e-f32c35caf5da)

@Fei2411

Fei2411 commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

自动审查结论处理(46a4e7e):

  • 自定义 provider 仍报官方配额(Codex P2 / Devin):已修。config_overrides 非空时,配额查询和 command 里带 -c 时一样直接判为不支持,不解析 override 内容。
  • env_key 变量在 Codex 宿主下被清掉(Devin):Bridge 已有 [env.inherit] 机制,这里只补文档,写明变量名要加进宿主的 env_vars / [env.inherit]。不改代码。
  • override 设置的 model 没体现在 observed_model(Devin):不改。observed_model 只反映 Bridge 自己设置的值;这个场景不常见,不为它解析 override。

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

argv 顺序和 adapter 透传没有问题。有一处高置信缺陷:config_overrides 不会经过现有的 Codex quota fail-closed 检查,自定义 provider 伝然会报官方 ChatGPT 账号的 quota。

Open in Web View Automation 

Sent by Cursor Automation: GitHub PR 自动审核

Comment on lines +129 to +132
# Codex only: each item is passed as `codex exec -c <item>` (raw TOML
# key=value). No key validation, no filtering, user config.toml is
# never read.
config_overrides: list[str] = Field(default_factory=list)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

严重程度:高

问题: config_overrides 会被 build_codex_exec_argv 逐条加成真实的 codex exec -c <item>,但 _codex() / quota_block_reason() 只扫 cfg.command 里的 -c / --config。这个新字段不在 command 里,quota 守卫完全看不到。

触发条件: [agents.codex] config_overrides 非空,尤其是 SETUP.md 示例里的 model_provider="my-gateway"。Worker 走自定义网关,但 command 仍是 bundled codex,不含 -c。

影响: list_agents 会把官方 ChatGPT 账号的缓存 quota,或 codex app-server 的 account/rateLimits/read,挂到实际上在用另一个 provider 的 worker。这违反 quota_endpoints.py 的 fail-closed 约定(自定义服务不能复用官方账号的 token 或之前的成功读数)。现有测试 test_fallback_endpoint_overrides_cannot_reuse_official_cache 已覆盖 command = [..., "-c", 'model_provider="custom"'],却盖不到这个新字段。协调端可能按错误的官方配额路由或放过这个 worker。

建议改法: 在 _codex() 里,若 cfg.config_overrides 非空,直接返回与 command 内 -c 相同的拒绝理由(quota lookup is unsupported with Codex CLI configuration overrides)。fetch_quota 已经在读 cache 之前调 quota_block_reason,改 _codex 即可同时挡住 cache 与直接查询。补覆盖:非空 overrides 时缓存的官方 quota 必须被 forget,返回 unknown。

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

argv 顺序和 adapter 透传没有问题。有一处高置信缺陷:config_overrides 不会经过现有的 Codex quota fail-closed 检查,自定义 provider 仍然会报官方 ChatGPT 账号的 quota。

Open in Web View Automation 

Sent by Cursor Automation: GitHub PR 自动审核

Comment on lines +129 to +132
# Codex only: each item is passed as `codex exec -c <item>` (raw TOML
# key=value). No key validation, no filtering, user config.toml is
# never read.
config_overrides: list[str] = Field(default_factory=list)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

严重程度:高

问题: config_overrides 会被 build_codex_exec_argv 逐条加成真实的 codex exec -c <item>,但 _codex() / quota_block_reason() 只扫 cfg.command 里的 -c / --config。这个新字段不在 command 里,quota 守卫完全看不到。

触发条件: [agents.codex] config_overrides 非空,尤其是 SETUP.md 示例里的 model_provider="my-gateway"。Worker 走自定义网关,但 command 仍是 bundled codex,不含 -c。

影响: list_agents 会把官方 ChatGPT 账号的缓存 quota,或 codex app-server 的 account/rateLimits/read,挂到实际上在用另一个 provider 的 worker。这违反 quota_endpoints.py 的 fail-closed 约定(自定义服务不能复用官方账号的 token 或之前的成功读数)。现有测试 test_fallback_endpoint_overrides_cannot_reuse_official_cache 已覆盖 command = [..., "-c", 'model_provider="custom"'],却盖不到这个新字段。协调端可能按错误的官方配额路由或放过这个 worker。

建议改法: 在 _codex() 里,若 cfg.config_overrides 非空,直接返回与 command 内 -c 相同的拒绝理由(quota lookup is unsupported with Codex CLI configuration overrides)。fetch_quota 已经在读 cache 之前调 quota_block_reason,改 _codex 即可同时挡住 cache 与直接查询。补覆盖:非空 overrides 时缓存的官方 quota 必须被 forget,返回 unknown。

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

未发现高置信问题。

Open in Web View Automation 

Sent by Cursor Automation: GitHub PR 自动审核

@Fei2411
Fei2411 merged commit 5560e06 into main Oct 7, 2026
7 checks passed
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.

[feature] Codex worker 支持自定义 model provider(目前 --ignore-user-config 让 config.toml 中的 provider 失效)

1 participant