news 2026/10/7 15:09:11

如何精准检测Codex订阅状态:codex-console多源解析与Rate Limit窗口识别原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何精准检测Codex订阅状态:codex-console多源解析与Rate Limit窗口识别原理

如何精准检测Codex订阅状态:codex-console多源解析与Rate Limit窗口识别原理

【免费下载链接】codex-consolecodex-console 是一个集成化控制台项目,支持任务管理、批量处理、数据导出、自动上传、日志查看与打包支持。项目地址: https://gitcode.com/gh_mirrors/co/codex-console

codex-console 是一个面向 Codex 账号的集成化控制台,它通过多源解析 + Rate Limit 窗口识别双引擎,精准检测 Codex 订阅状态(Plus / Team / Basic)与 5 小时、周配额额度,还能在代理异常、接口抖动时自动降级,避免误判。本文将拆解它的订阅状态检测原理。

一、为什么单接口检测不够可靠?

OpenAI 的订阅与配额信息分散在多个后端接口中,且字段会随版本变化。只依赖某一个接口,容易出现"昨天能跑、今天翻车"的问题:

  • 某个接口返回 403 / 404 时,直接判为"无订阅"会造成误判降级;
  • 配额字段名不统一(used_percent可能是 0~1 比例,也可能是 0~100 百分比);
  • 5 小时窗口和周窗口的字段可能互换位置。

codex-console 的解法是:并发抓多个来源、按优先级交叉验证、失败时静默降级,核心逻辑在 src/core/openai/overview.py。

二、多端点并发抓取:3 个数据源各司其职

检测入口是fetch_codex_overview(),它同时请求 3 个后端接口:

数据源接口角色失败策略
me/backend-api/me计划类型核心来源(必选)重试 2 次,计入错误
wham_usage/backend-api/wham/usage配额 + 计划核心来源(必选)重试 2 次,计入错误
codex_usage/backend-api/codex/usage兜底补充(可选)401/403/404 时静默降级

端点定义见 overview.py#L26-L32。三个请求通过ThreadPoolExecutor并发执行,主入口见 overview.py#L788-L843。

两个关键的容错设计:

  1. 代理回退直连:请求优先走当前代理,代理异常时自动回退直连重试一次(_request_json_with_proxy_fallback);
  2. 可重试错误识别:只对 408、429、5xx 和超时类错误重试,401/403/404 不重试,避免无效等待。

三、多源解析:如何判断是 Plus / Team / Basic?

计划类型识别是订阅检测的重头戏。_detect_plan()采用六级优先链,逐级降级,确保任何一级拿到信号就能定论(源码见 overview.py#L727-L785):

  1. me 接口的 plan 字段:扫描plan_type、subscription_plan、tier等 10 余个候选字段,并归一化——enterprise/team → Team、plus → Plus、pro → Pro、free/basic → Basic;
  2. org / workspace 信息:me.orgs里的workspace_plan_type为 team/enterprise 时直接判为 Team;
  3. 订阅布尔信号:has_paid_subscription、is_subscribed等为true时按 Plus 处理;
  4. wham/usage 与 codex/usage 的 plan_type:这是与官方工具同款的核心信号;
  5. JWT 声明兜底:解码id_token/access_token的 payload,读取chatgpt_plan_type声明,不依赖任何网络刷新;
  6. 数据库已有订阅字段,仍无信号则默认为 Basic。

每一级检测都会记录plan_source(如me.plan、id_token.chatgpt_plan_type),让你可以追溯结论来自哪个来源,排查误判时一目了然。

四、Rate Limit 窗口识别:区分 5 小时配额与周配额

这是 codex-console 最有特色的部分。wham/usage返回的rate_limit包含primary_window和secondary_window两个窗口,但窗口位置并不总是一成不变——接口改版后,7 天窗口可能出现在 primary 位置。

基于窗口时长的置信推断

_infer_rate_limit_window_type()用两条阈值线判定窗口类型(overview.py#L437-L448):

  • 窗口时长limit_window_seconds≥5 天→ 判定为weekly(周窗口),高置信;
  • 窗口时长 ≤12 小时→ 判定为hourly(5 小时窗口),高置信;
  • 无时长信息时,退化到 key 语义:primary_window倾向 hourly,secondary_window倾向 weekly,但置信度标记为低。

三级选择策略

_select_rate_limit_window()(overview.py#L451-L478)按置信度三级筛选:

  1. 优先高置信匹配:基于窗口时长推断且类型命中,避免把 7 天窗口误判成 5 小时窗口;
  2. 普通语义匹配:无时长信息时按 key 语义兜底;
  3. 历史 key 兜底:单窗口账号场景下,按primary=5h / secondary=周的历史约定取值,避免页面上出现--空值。

配额数值归一化

窗口内部的字段同样被做了防御式解析(_extract_quota_from_rate_limit_window):

  • used_percent在 0~1 与 0~100 之间自动换算;
  • total / used / remaining三者互相推算,任一缺失可由另外两个补出;
  • resets_at与resets_in_seconds互推,最终渲染成"1小时23分"这类人类可读的剩余时间;
  • 时间戳兼容秒 / 毫秒两种 epoch 格式。

最终每个账号输出hourly_quota(5 小时窗口)、weekly_quota(周窗口)、code_review_quota(Code Review 专属配额)三组数据,且每个窗口都标注了source溯源路径。

五、缓存与信任源:让检测又快又稳

服务层 accounts.py#L585-L679 的_get_account_overview_data()在抓取之外还做了几件重要的事:

  • 缓存优先:结果缓存在账号extra_data.codex_overview中,TTL 内直接读缓存,首屏卡片列表默认不发网络请求,避免被远端接口阻塞;
  • 过期缓存标记 stale:刷新失败时返回旧数据并打上stale标记,而不是显示空白;
  • 信任源同步:只有来自me.、wham_usage.、codex_usage.、id_token.等高置信来源的计划类型,才会回写数据库subscription_type字段;
  • 防降级保护:本地已确认的 Plus / Team 账号,不会被远端偶发的 free/basic 响应覆盖降级,只记录日志跳过;
  • 停用识别:请求过程中抛出AccountDeactivatedError时,账号直接标记为 BANNED 并记录停用时间。

六、批量刷新体验

Web UI 的批量刷新走 accounts.py#L1235 的/api/accounts/overview/refresh接口:

  • 默认只刷新"卡片可见的付费账号"(plus / team),无关账号不会拖慢整体进度;
  • 支持按状态、邮箱服务、关键词筛选刷新范围;
  • 每个账号优先使用其绑定的代理(account.proxy_used),无绑定代理时才用全局代理;
  • 结果明细里带上plan_type与各窗口percentage,日志中还记录每个配额的数据来源,方便逐账号核对。

七、核心文件速查

文件职责
src/core/openai/overview.py订阅状态与配额抓取解析核心:多端点并发、计划六级解析链、窗口识别
src/web/routes/accounts.py缓存策略、信任源回写、批量刷新 API
static/js/accounts_overview.js总览卡片前端交互
tests/覆盖注册、上传、安全等链路的自动化测试

小结

codex-console 的订阅状态检测可以概括为一句话:"多点并发取数、按置信度定级、失败静默降级"。多源交叉验证消除了单点接口波动带来的误判,Rate Limit 窗口识别则让 5 小时 / 周配额在不同接口布局下都能被准确归类——这正是它在 v1.1 版本修复"无法检查订阅状态"问题后的核心能力。

【免费下载链接】codex-consolecodex-console 是一个集成化控制台项目,支持任务管理、批量处理、数据导出、自动上传、日志查看与打包支持。项目地址: https://gitcode.com/gh_mirrors/co/codex-console

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 15:08:33

AnyPS5与PS5模拟器的本质区别:原生移植路线的7个关键技术差异

AnyPS5与PS5模拟器的本质区别:原生移植路线的7个关键技术差异 【免费下载链接】AnyPS5 Tool for automatic PS5 executables porting to Linux and Windows 项目地址: https://gitcode.com/GitHub_Trending/an/AnyPS5 想搞清楚 AnyPS5 和 PS5 模拟器到底有什…

作者头像 李华
网站建设 2026/10/7 15:08:22

一条命令背后,五层各司其职

一、一个简单的问题:date 是谁在执行你在终端里输入 date,按一下回车,时间就出来了。看起来一步完成,其实背后有六个角色接力。执行 date 时发生了什么"流程图分六步:1 终端输入(date)&…

作者头像 李华
网站建设 2026/10/7 15:06:38

前端通信与React核心:HTTP、WebSocket与状态更新全解

如果你写过前端代码,就一定躲不开“前端通信”这四个字。页面要拉数据,表单要提交,日志要上报,服务端还要实时推消息,甚至两个浏览器标签页之间也得互相递个话。而在 React 项目里,这些问题往往还会跟上组件…

作者头像 李华
网站建设 2026/10/7 15:06:19

功能盘点|AI论文写作工具推荐,论文写作与修改之选

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 15:06:16

pstack原则09类型系统纪律:如何让非法状态不可表示

pstack原则09类型系统纪律:如何让非法状态不可表示 【免费下载链接】pstack-claude Claude Code, Codex, Copilot, Pi, OpenCode, Gemini, and Prime Agent versions of Potetos pstack. Rigorous agent workflows with Cursor primitives translated for other har…

作者头像 李华