5.1 KiB
CLIProxyAPI 与 Codex 用量同步
外部依赖与凭据边界
Codex Helper 不再启动 codex app-server,也不保存 Codex OAuth token。所有 Codex 登录、凭据持久化和刷新均由外部 CLIProxyAPI(CPA)负责;本项目只通过环境变量读取:
CLIPROXY_API_BASE_URL:CPA Management API 根地址。CLIPROXY_API_MANAGEMENT_KEY:CPA management key,只进入服务端请求头,不写入 SQLite、日志或前端响应。
每条 accounts 记录保存一个唯一的非空 auth_index。添加或修改绑定时,后端先调用 CPA GET /v0/management/auth-files?auth_index=...,确认索引唯一匹配、provider/type 为 codex,且凭据未 disabled。CPA 的临时 unavailable/error 状态可能正是额度耗尽导致,不能据此拒绝读取,否则仪表盘无法显示 100% 用量和重置时间。账号邮箱、套餐和 ChatGPT account ID 来自该认证条目的安全元数据与 ID token claims;原始 token 不会进入 Codex Helper。
旧数据库迁移会为已有账号增加空 auth_index。这些账号会保持未连接,直到管理员在设置页绑定 CPA authIndex。新数据库不再自动创建无凭据的默认账号。
Management API 代请求
后端通过 CPA POST /v0/management/api-call 发起上游请求,请求体使用 auth_index 选择凭据,并在 Authorization 中传递 Bearer $TOKEN$ 占位符,由 CPA 注入和刷新真实 access token。关键上游请求是:
GET https://chatgpt.com/backend-api/wham/usage:套餐、普通限额、代码审查限额、additional_rate_limits和可用重置卡摘要。GET https://chatgpt.com/backend-api/wham/profiles/me:Token 活动摘要与每日 bucket。GET https://chatgpt.com/backend-api/wham/rate-limit-reset-credits:可选的重置卡详情及到期时间。
CPA HTTP 层和包装的上游状态分别校验。错误只包含安全的阶段、HTTP 状态和上游错误类型,不包含 management key、OAuth token、原始响应正文或 CPA 凭据内容。请求均有超时和响应体大小限制。
这些 /wham/* 路径属于 ChatGPT/Codex 内部接口,并非稳定公开 API;CLIProxyAPI 版本、当前解析代码和测试是本项目的实际兼容基线。
限额归一化
一次成功同步会把 /wham/usage 转换为现有 Dashboard.Limits:
- 顶层
rate_limit使用稳定limitId=codex。 code_review_rate_limit使用稳定limitId=code_review。additional_rate_limits[]优先使用metered_feature作为 limit ID,limit_name作为显示名称;例如 Spark 的codex_bengalfox。primary_window和secondary_window分别保留为windowType=primary|secondary,前端依据窗口时长识别小时和周额度,不假定字段顺序。limit_window_seconds向上取整转换为分钟。used_percent限制在 0–100,但保留小数。- 重置时间优先使用 Unix 秒
reset_at;缺失时以本次响应时间加reset_after_seconds推算。 plan_type未知时按原值保留,并由现有套餐分类逻辑安全显示为 unknown。
可用重置卡数量优先以详情接口的 available_count 为准,详情接口失败时可退回 /wham/usage 的 rate_limit_reset_credits.available_count。只有状态为 available 且能解析 RFC3339 expires_at 的记录才进入到期时间列表;详情失败不影响主同步。
Token 活动与当前周期
/wham/profiles/me 的 stats 提供 lifetime、单日峰值、最长任务、连续天数以及 daily_usage_buckets。每日 bucket 继续写入按 account_id 隔离的 daily_usage;optional、null、未来新增字段和暂缺 bucket 必须安全降级,不能合成调用次数、输入/输出 Token、价格或账单日期。
同步成功后,以当前仍有效的最长限额窗口作为当前重置周期,按每日 bucket 汇总周期起点至当前日期的 Token,写入 Dashboard.currentCycle。周期边界只有日期粒度,因此边界日按整日汇总。额度和 Profile Token 活动来自不同上游聚合链路,数据新鲜度可能不同。
调度、并发与失败
应用启动后异步同步全部已绑定账号,之后固定每五分钟同步;手动同步和 Telegram 立即刷新使用同一链路。每个账号的 syncing mutex 串行同步并保护内存 Dashboard,不同账号仍保持数据库、历史和提醒隔离。
auth_index 缺失、CPA 未配置、认证条目不可用或核心 /wham/usage 失败会使本次同步失败:已有 Dashboard 保留并标记 stale=true,内部错误仅对已登录管理员可见。/wham/profiles/me 的 Token 活动和重置卡详情都是可选数据;Profile 失败时同一进程内保留上次成功的摘要和每日历史,没有旧值时降级为空,重置卡详情失败时退回用量接口的可用数量。两者都不会隐藏已成功读取的额度窗口。成功同步会清除 stale/error、写入限额快照、检测百分比回落并更新账号元数据。
删除账号只删除 Codex Helper 中的绑定、数据库历史和内存 Dashboard,不调用 CPA 删除认证文件。CPA OAuth 凭据的删除和恢复必须在 CLIProxyAPI 中单独执行。