Skip to content

fix(cli): 支持关闭 Codex 系额度换模型提醒并兼容网关 - #1364

Open
xiongz-c wants to merge 4 commits into
masterfrom
codex/codex-model-nudge
Open

fix(cli): 支持关闭 Codex 系额度换模型提醒并兼容网关#1364
xiongz-c wants to merge 4 commits into
masterfrom
codex/codex-model-nudge

Conversation

@xiongz-c

@xiongz-c xiongz-c commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

背景 / 动机

Codex 在额度接近上限时会弹出换模型选择框,默认选项为切换到较低成本模型。Botmux 提交消息的 Enter 可能确认这个选择,造成用户未主动选择却改变会话模型。TraeX 及与其共用 traecli 的 CoCo 同样需要保护。

改动

  • Dashboard 新增「关闭 Codex 系额度换模型提醒」,保存到 dashboard.hideCodexRateLimitModelNudge,同步中英文说明。
  • worker 读取设置,开启时向 Codex / TraeX 传入 -c notice.hide_rate_limit_model_nudge=true,向 CoCo 传入长参数 --config notice.hide_rate_limit_model_nudge=true。关闭时不添加覆盖,遵循 CLI 自身配置。
  • 覆盖 Codex / TraeX 新建、resume、RPC viewer,以及 Codex fork、CoCo 新建和 resume;经 Codex 适配器启动的 SpineCodex 同样覆盖。
  • 网关兼容:cjadk 将注入的 -c 改为 --config;ttadk 保留透传,包括 CoCo 的长参数。Aiden 拒收该覆盖,沿用精确白名单剥离,保证启动兼容;设置明确注明「走 Aiden 网关启动的会话不受此保护」。

设置及保护范围说明

默认值 / 兼容性依据

默认开启,避免无人操作的托管终端误确认换模型。配置仅接受布尔值,缺省或非法值采用默认保护行为;显式 false 不覆盖 CLI 自身设置。

使用进程级配置,不写入用户配置,与审批及沙盒绕过设置独立。仅新启动的 CLI 进程生效;已有进程、adopt 及存活 pane 的重新挂接不改变启动参数。不会增加额度或恢复已经切换的模型。

已更新到最新主干,TraeX 的 shellSubprocessEnvhideRateLimitModelNudge 同时保留;触发人身份环境透传与本次保护共同生效。

测试覆盖

  • 默认开启、关闭、重新开启、持久化读回及非法值处理;worker 读取并传递实时配置。
  • 受保护 CLI 的新建、恢复和各自支持的 fork / RPC 路径,受限机器人、参数位置、模型参数保持及 SpineCodex 可执行文件路径覆盖。
  • CoCo 使用 --config,ttadk CoCo 新建 / 恢复透传;其余 28 个 CLI 的启动参数保持不变。
  • Aiden / cjadk / ttadk 包装真实适配器输出,用户提供的 notice.hide_rate_limit_model_nudge=false 参数保持原样。
  • TraeX 身份环境透传和提醒保护并存,RPC app-server / viewer 的 hook 边界不变。
  • 更新旧 RPC viewer 参数断言;配额回退进程测试等待全部配置观察记录,消除初始化竞态,未增加跳过或重试规则。
  • 设置页默认开启、关闭保存、刷新读回、重新开启,以及 CoCo / Aiden 范围说明。

验证

本次使用 Bun 1.4.2:

  • bun run test -- test/traex-native-subagent-hook-wiring.test.ts test/quota-fallback-process.integration.test.ts test/codex-model-nudge.test.ts test/cli-selection.test.ts test/cli-adapters.test.ts test/codex-hook-trust-worker-wiring.test.ts test/settings-write-applier.test.ts test/global-config.test.ts test/traex-shell-env.test.ts test/trigger-user-shell-env.test.ts:10 个文件、730 项通过。
  • Bun 在独立临时 HOME、每文件独立进程下执行 bun test <file> --timeout 180000:覆盖上述前 4 个文件及两个 shell-env 文件,143 项通过、3 项沿用既有直接 PTY 限制跳过、0 失败。
  • CoCo 补修前,新建、resume、ttadk 三项回归均失败;补修后通过。
  • bun run buildgit diff --check:通过。
  • 提交 f512319fd完整 CI 和 CodeQL 全部通过,包含三个 Node 分片、Bun 全量测试及各二进制构建检查。
  • 真实设置页配合隔离模拟 API、无登录浏览器:保存、刷新与范围说明验证通过,截图见上文。
  • 配置键验证改用实际启动解析,不以 --help 成功作为依据:远端 Linux 的 Codex 0.153.4、SpineCodex 0.2.2 对 --config notice.hide_rate_limit_model_nudge=notabool 明确报该字段应为 boolean,合法值通过配置解析。TraeX 0.201.5 在隔离 PTY 中得到同样结果;将同一二进制以临时 CoCo 别名启动,也能复现相同校验。所有探针均使用空的临时配置目录,未发送模型请求,未模拟真实额度耗尽。
  • bun run daemon:restart:本机缺少配置而退出,尚未部署或完成飞书端验收。

影响范围

涉及全局配置读写、Dashboard、worker 启动接口、Codex / TraeX / CoCo 适配器和网关兼容。PTY、tmux 及话题、群会话复用启动参数构造;RPC 覆盖 viewer,未改变 app-server 模型选择。未引入平台专有路径或进程逻辑。

CLI / 路径 处理结论
Codex / TraeX / CoCo 对共享额度换模型提示注入进程级保护。CoCo 已移出“不受影响”测试表。
SpineCodex 通过 Codex 适配器启动时覆盖。
Aiden 网关 仅保证启动兼容,会话不受此开关保护。
cjadk / ttadk 按网关参数规则改写或透传。
Gemini CLI / Claude Code 存在 CLI 原生回退行为,未发现相同误确认链路,不套用此配置。参见 Gemini CLI 官方说明Claude Code 模型配置
其余 CLI 已验证开关不改变适配器启动参数,未逐一完成真实会话验收。

@xiongz-c xiongz-c changed the title fix(codex): 支持关闭额度换模型提醒 fix(cli): 支持关闭 Codex 系额度换模型提醒并兼容网关 Sep 10, 2026
@xiongz-c
xiongz-c force-pushed the codex/codex-model-nudge branch from d3e9666 to 8bc172c Compare September 11, 2026 03:34
@xiongz-c
xiongz-c marked this pull request as ready for review September 11, 2026 03:42
@xiongz-c
xiongz-c requested a review from deepcoldy as a code owner September 11, 2026 03:42
@deepcoldy

Copy link
Copy Markdown
Owner

自动评审初步意见(最终以维护者审阅为准)

整体方向认可:开关默认开启、进程级 -c 覆盖不写用户配置、配置读写非法值 fail-closed、aiden/cjadk/ttadk 三个网关分别处理、RPC viewer 同步覆盖,测试也比较完整。本地基于最新主干合并后构建通过,相关测试全绿,反变异探针有效。有一个需要修改的问题和两个小建议:

1.(建议修改)coco 适配器漏装了同一保护,默认开启的开关对 coco 会话不生效

coco 与 traex/traecli 是同一个二进制(本机三者为同一 inode 的 symlink,均为 traecli 0.204.1;src/adapters/cli/coco.ts 注释也写明 "Coco runs the SAME traecli binary as traex"),换模型弹窗是共享 TUI 里的同一份实现:

  • coco --helptraex --help 输出 184 行零差异;
  • 两模式启动期都会解析并校验该配置键:传入 notice.hide_rate_limit_model_nudge=notabool 均报逐字相同的 Error loading config: invalid type: string "notabool", expected a boolean in notice.hide_rate_limit_model_nudge(用合法值启动则正常接受);
  • 二进制内换模型弹窗文案只有一份。

src/adapters/cli/coco.tsbuildArgs 只解构 { sessionId, resume, model, disableCliBypass },worker 对所有适配器都传入了 hideRateLimitModelNudge,coco 静默忽略——默认保护在 coco 会话上是 no-op,与「默认开启,避免无人操作的托管终端误确认换模型」的目标不一致。test/codex-model-nudge.test.ts 中「其余 29 个 CLI 不受影响」的参数不变性表也包含了 coco,等于把这个缺口固化进了断言。

建议的修法很小:

  • coco.tsbuildArgs 接收该字段,按 coco 现有的长参形态(与 model.name 一致)注入:...(hideRateLimitModelNudge ? ['--config', 'notice.hide_rate_limit_model_nudge=true'] : [])(ttadk 下 coco 路径本来就透传 --config;aiden 无内置 coco 网关);
  • src/adapters/cli/types.ts 该字段注释补上 coco;
  • 测试把 coco 从「不受影响」表移到受保护表(coco 没有 fork/RPC 路径,断言 --config 形态即可)。

2. 需要 rebase 到最新 master

当前分支与最新主干在 src/adapters/cli/traex.tsbuildArgs 签名行有冲突:#1329 新增了 shellSubprocessEnv、本 PR 新增了 hideRateLimitModelNudge。语义合并没有难度,两者并存即可;rebase 后麻烦重跑一下 CI。

3.(nit,不阻断) aiden 路径剥掉该参数后没有运行时兜底(启动更新弹窗有 dismissAidenCodexUpdateDialog 守底,换模型弹窗没有)。设置文案里已注明 Aiden 不支持,建议再直白一点,例如「走 aiden 网关启动的会话不受此保护」,让运营者一眼能判断自己的会话是否在保护范围内。

4.(nit,不阻断) 验证一个配置键是否被 CLI 真正接受,建议用「非法 bool 值启动」探针(会在配置加载期直接报错),--help 返回 0 不经过配置解析,无法证明键存在(本次的键我们已用非法值探针在 codex 0.153.4 / traecli 0.204.1 上独立确认存在且生效)。

以上为自动评审的初步意见,最终以维护者审阅为准,感谢贡献!

@xiongz-c
xiongz-c force-pushed the codex/codex-model-nudge branch from 8bc172c to f512319 Compare September 11, 2026 07:14
@xiongz-c

Copy link
Copy Markdown
Collaborator Author

已按这四点处理,新增提交 f512319fd

  1. 补齐 CoCo。 之前将 CoCo 放入“不受影响”表是遗漏,现已改为受保护对象。适配器用 --config notice.hide_rate_limit_model_nudge=true,覆盖新建和 resume,并验证 ttadk CoCo 的长参数透传;默认开启、关闭、受限机器人及原模型参数均有覆盖。补修前这三处回归失败,补修后通过。
  2. 更新主干。 已 rebase 到 ead85e5f5,解决 TraeX 签名冲突,保留 shellSubprocessEnvhideRateLimitModelNudge。新建、resume 和受限模式的测试同时断言身份环境透传与提醒保护,避免合并时遗漏其中一项。
  3. 明确 Aiden 边界。 中英文帮助已直接说明「走 Aiden 网关启动的会话不受此保护」,PR 截图同步更新。
  4. 纠正配置验证依据。 已撤掉 --help 成功作为键存在的证据。在空的临时配置目录中,Codex 0.153.4、SpineCodex 0.2.2 对非法值 notabool 明确报该字段应为 boolean,合法值通过配置解析。TraeX 0.201.5 需要 PTY 才进入配置加载;隔离 PTY 下同样校验该键,以同一二进制的临时 CoCo 别名启动也得到相同结果。未发送模型请求,未模拟真实额度耗尽。

验证:10 个文件、730 项 Node 测试通过;6 个文件、143 项 Bun 测试通过,3 项沿用既有直接 PTY 限制跳过;bun run buildgit diff --check 和设置页保存/刷新验证通过。本次提交的完整 CI 及 CodeQL 均通过。PR 描述已按原模板同步更新。

@deepcoldy

Copy link
Copy Markdown
Owner

自动评审复审(新 commit f512319)——coco 修复确认通过,还需 rebase + 同步主干测试(初步意见,以维护者审阅为准)

上轮 F1(coco 漏装)已正确修复coco.ts 按 CoCo 的 --config 长参形态门控注入、types/global-config 注释与中英文设置说明均补上 CoCo;coco 已移入受保护测试表并新增 ttadk coco 透传断言。我们在真实 traecli 0.204.1(coco 即该二进制的兼容模式)上独立验证:coco --config notice.hide_rate_limit_model_nudge=notabool 启动期报 Error loading config: invalid type: string "notabool", expected a boolean,合法值启动无配置错误;反变异(摘除注入行)对应 3 个用例转红。上轮 N1(Aiden 路径说明)也已按建议改成「走 Aiden 网关启动的会话不受此保护」。

合入前还需要做一件事:rebase 到最新 master 并更新主干上 #1367 留下的测试断言。

你这个分支之后,主干已合入 #1367(同一配置键的 codex-only 版本:codex 适配器无条件注入 -c notice.hide_rate_limit_model_nudge=true,CLI 与网关白名单已就位)。本 PR 的开关门控(默认 ON)是它的超集,语义合并没有冲突,但我们把本分支 rebase 到最新 master 后:

  • 代码冲突共 3 处(codex.ts 两处注入点、cli-selection.ts 白名单注释),解法都是「以本 PR 的开关门控取代无条件注入、保留主干注释」,均已本地验证;
  • 但有 11 个主干测试会变红test/cli-adapters.test.ts(5 个)和 test/write-input.test.ts(6 个)直接调用 codex buildArgs({...}) 且没有传 hideRateLimitModelNudge,用 toEqual 硬断言参数里无条件包含 nudge 两行。门控化后不传该字段即不注入,这 11 个断言需要补上 hideRateLimitModelNudge: true(它们要锁定的「默认受保护」意图不变;worker 真实链路始终传配置值、默认 ON,生产行为与 fix(codex): 进程级关闭低额度切 luna 的模型 nudge 弹窗 #1367 完全一致,相关 worker/PTY 测试我们本地已验证全绿)。

rebase 后我们本地的验证结果:bun run build 通过;本 PR 的 8 个测试文件 278 项全绿;唯一红的就是上述 11 个 #1367 直调断言(失败 diff 仅缺 nudge 两行,无其他差异)。

一个小 nit(不阻断):test/cli-selection.test.ts 新增的 ttadk coco 用例是文件顶层游离的 it(...)(在所有 describe 块之外),建议放进相邻的 describe('Codex model-nudge override through wrappers') 里。

以上为自动评审初步意见,最终以维护者审阅为准,感谢更新!

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.

2 participants