Skip to content

fix: preserve Luna Reserve quota routing - #457

Merged
qxcnm merged 5 commits into
qxcnm:mainfrom
MDX-Tom:codex/fix-luna-reserve-quota-routing
Sep 4, 2026
Merged

fix: preserve Luna Reserve quota routing#457
qxcnm merged 5 commits into
qxcnm:mainfrom
MDX-Tom:codex/fix-luna-reserve-quota-routing

Conversation

@MDX-Tom

@MDX-Tom MDX-Tom commented Sep 3, 2026

Copy link
Copy Markdown
Contributor
截屏2026-09-03 16 27 31

变更

  • 对齐 Codex 用量请求,非 FedRAMP 请求带上 Luna Reserve 请求头。
  • 当后续 usage payload 将 additional_rate_limits 返回为 null 时,保留旧快照中的 Reserve bucket;显式数组仍按上游结果作为权威值,并兼容旧的 additionalRateLimits 缓存格式。
  • 可用性判定优先识别仍可用的 Luna Reserve;新增“强制开启”账号操作,默认关闭,且保留禁用/封禁状态保护。
  • 账号池展示所有额外额度窗口;配额条、重置时间和倒计时保持在同一张卡片内。
  • 修复 Luna Reserve 标题/百分比重叠、长文本溢出、状态列截断和编辑按钮覆盖;标题统一为 Luna Reserve,额外额度子卡宽度提升约 10%。

验证

  • cargo fmt --all -- --check
  • cargo test -p codexmanager-core --test usage -- --nocapture(5 passed)
  • cargo test -p codexmanager-service usage_request_headers -- --nocapture(2 passed)
  • cargo test -p codexmanager-service legacy_usage_request_ignores_proxy_pool_when_account_proxy_is_disabled -- --nocapture(1 passed)
  • cargo test -p codexmanager-service followup_usage_without_extra_buckets_keeps_previous_luna_reserve -- --nocapture(1 passed)
  • pnpm -C apps run buildpnpm -C apps run test:runtime(199 passed)
  • macOS Tauri QA app build succeeded.

QA

使用独立 QA 实例和隔离数据库验证:点击首行“刷新用量”后,5h 与 Reserve 同时显示;仅首个 fixture account 生成新快照,其余账号快照保持不变。随后视觉复核确认 Luna Reserve 标题和加宽后的子卡无文字遮挡。官方实例端口保持不变。

@MDX-Tom
MDX-Tom marked this pull request as draft September 3, 2026 05:58
@MDX-Tom

MDX-Tom commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

补充修复已推送:b1eaf93f fix: route Luna Reserve usage by account identity

  • 用量请求的 ChatGPT-Account-ID 改为优先使用 token 派生的 ChatGPT account UUID,不再把 workspace ID 当作账号身份发送;额度重置读写链路同步修正。
  • 用量刷新加入 Cache-Control: no-cachePragma: no-cache,避免刷新继续复用旧 GET 响应。
  • 增加账号身份优先级、请求头、缓存头回归测试;service usage 142 项与前端 runtime 199 项通过。
  • formal arm64 App 已直接构建并通过签名校验,产物位于项目目录:target/codexmanager-formal-app-luna-fix/CodexManager.app

现网首个账号的只读验证结果:请求返回 200,已带 Luna Reserve opt-in 与正确的 ChatGPT account UUID,但 upstream 返回 additional_rate_limits: null。因此当前账号没有可供 UI 展示的 Reserve bucket;正式 App 之前不显示该窗口的直接原因是上游没有下发这段额度数据,而不是卡片渲染失败。第二个账号本次未执行刷新。

@MDX-Tom

MDX-Tom commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

继续修复(commit d6e4e90):

  • 修复旧版本把 additional_rate_limits: null 持久化为空数组后,后续刷新始终丢失 Luna Reserve 的问题。按账号隔离,从该账号最近仍含可用 Luna Reserve 的历史快照恢复;当前响应显式返回数组/对象(含空数组)时仍以服务器结果为准。
  • 独立 CodexManagerQARecovery.app 已通过本地 fixture 完成编译 app → RPC → usage refresh → usage list 链路验证:首个账号请求带 ChatGPT-Account-Idx-openai-codex-luna-reserve: 1Cache-Control: no-cachePragma: no-cache,只产生首个账号 usage 请求,返回 available_luna_reserve 与 1 个 gpt-reserve bucket。
  • 回归:core usage 50/50、service usage 213/213;当前 formal app 进程未停止。
  • 最终 formal app 将放在项目 target/ 目录,不写入 ~/.codex/

@MDX-Tom

MDX-Tom commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

最终验证补充(commit d6e4e90):

  • CodexManagerQARecovery.app 独立实例通过 UI 菜单“刷新用量”刷新首个账号,页面实际显示 Luna Reserve、80%、仅 Luna Reserve,并出现“账号用量已刷新”提示。
  • fixture 请求只出现首个账号的 /wham/usage,请求头包含 ChatGPT-Account-Idx-openai-codex-luna-reserve: 1Cache-Control: no-cachePragma: no-cache;第二个账号请求数为 0。
  • 最终 formal app 构建成功并通过 arm64、Info.plist 0.5.6、codesign 校验,产物保存在项目 target/codexmanager-formal-app-luna-recovery/CodexManager.app。当前运行中的旧 formal app PID 31159 全程保持运行。
  • 回归结果:core usage 50/50、service usage 213/213、frontend runtime 199/199。

@MDX-Tom

MDX-Tom commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author
截屏2026-09-04 08 33 29

经人工测试,目前较稳定使用

@qxcnm qxcnm left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

基础构建和测试是通过的,但这里还有 3 个需要在合并前修正的行为问题:

  1. Reserve 恢复没有失效边界。store_usage_snapshot 在上游持续返回 additional_rate_limits: null/缺失时,会把任意历史“曾可用”的 Reserve 反复复制到新快照;has_usable_luna_reserve 不校验原始快照时间、恢复次数或权益撤销。结果是套餐撤销、身份变化或 Reserve 下线后,旧额度仍可能永久显示为 available_luna_reserve 并参与候选路由。请加入有界恢复策略(例如来源时间/TTL 或一次性恢复)以及重复 null、过期/撤销的回归测试。另请用默认 retain=1 的真实写入序列覆盖“旧版空快照恢复”:当前测试直接 insert_usage_snapshot 绕过 prune,而默认配置下旧 Reserve 已经会被删掉。

  2. Reserve 的请求模型不能等同为普通 Luna。OpenAI Codex 把 gpt-reserve 定义为后端授权的临时请求别名;它只借用 normal_model_slug/Luna 的展示和 reasoning 元数据,最终请求仍应保持 gpt-reserve
    https://github.com/openai/codex/blob/1b53f6a44eff890b5169bde8d3bd5b12b8766946/codex-rs/tui/src/chatwidget/luna_reserve_model.rs#L1-L33
    当前 is_luna_reserve_model 把所有包含 luna 的模型视作 Reserve,候选测试也只用 gpt-5.6-luna,却没有验证最终上游 JSON 的 model。请收紧为明确的 gpt-reserve 别名;若产品要自动切换,则应显式改写当前请求并补最终请求体/额度扣减验证,不能只放宽候选池。

  3. apps/src/hooks/useAccounts.tslastKnownUsagesRef 不按 serviceStatus.addr 隔离,也不清理权威 usage/list 中已不存在的项。从实例 A 切到实例 B,若相同 accountId 在 B 暂无 usage,会继续展示 A 的旧 Reserve 配额与可用状态。请按服务地址分区/切换时清空,并在成功取得权威列表时完成对账,补服务切换与空列表测试。

已核对:head d6e4e909、3 项 CI 全绿、cargo fmt --all -- --check、Core 用量测试、Service 213 项 usage 测试、前端 runtime 199/199 与生产构建均通过;以上是通过测试仍未覆盖到的语义问题。force_enabled 的硬状态保护以及 ChatGPT account ID 优先级目前未发现问题。

@qxcnm
qxcnm merged commit 15f054a into qxcnm:main Sep 4, 2026
3 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.

2 participants