Files
codex-helper/docs/backend/codex-integration-and-usage.md
wuxu 8997886eef
Frontend / quality (push) Canceled after 0s
feat: migrate account usage to CLIProxyAPI
2026-09-08 09:56:08 +08:00

54 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 中单独执行。