Skip to content

feat(cliproxy): 集成 CLIProxyAPI,支持 CLI OAuth 上游 (#142)#166

Merged
g1331 merged 35 commits into
masterfrom
feat/cliproxy-integration
May 22, 2026
Merged

feat(cliproxy): 集成 CLIProxyAPI,支持 CLI OAuth 上游 (#142)#166
g1331 merged 35 commits into
masterfrom
feat/cliproxy-integration

Conversation

@g1331
Copy link
Copy Markdown
Owner

@g1331 g1331 commented May 22, 2026

@

概述

实现 issue #142:将 CLIProxyAPI 集成为 AutoRouter 的 CLI OAuth 上游提供方。CLIProxyAPI 作为 OAuth 协议适配器,使 AutoRouter 能够把 Codex、Gemini 等 CLI OAuth 账号纳入网关的多上游路由与计费体系。

Closes #142

变更构成

本 PR 由 5 个有序依赖的 OpenSpec 变更组成,已全部归档至 openspec/changes/archive/

顺序 变更 内容
1 cliproxy-instance-config CLIProxyAPI 实例数据模型(PostgreSQL + SQLite 双 schema)、Fernet 加密存储凭据、实例 CRUD Admin API、连通性检测
2 cliproxy-oauth-account-management OAuth 账号同步、账号启停与字段管理 Admin API
3 cliproxy-oauth-pool-upstream 池上游与单账号映射上游预设服务、转发层账号前缀注入
4 cliproxy-sidecar-deployment CPA sidecar 的 Docker Compose 叠加文件、配置模板与启动脚本、部署指南
5 cliproxy-admin-ui 前端管理界面:实例管理、OAuth 账号管理、OAuth 登录流程、上游创建入口

验证情况

本地预检验全部通过:

  • pnpm exec tsc --noEmit 无类型错误
  • pnpm lint 无告警
  • pnpm test:run 2476 通过 / 1 跳过(147 个测试文件)
  • 双方言迁移齐备(PostgreSQL drizzle/0034-0037、SQLite drizzle-sqlite/0012-0014),db:check:consistency 通过
  • pnpm build 生产构建成功

端到端验证:在本地 dev 环境完成实例创建、OAuth 账号同步、池上游创建,并通过 CLIProxyAPI 向 Codex 转发真实请求,返回 HTTP 200 且计费正确。

影响范围

仅涉及 CLIProxyAPI 集成相关代码与文档。openspec/changes/ 下的 traffic-recording-logs-integrationupstream-failure-controls 两个无关变更未受影响。
@

g1331 added 30 commits May 20, 2026 21:58
issue #142 集成 CLIProxyAPI 的第一个变更,交付 CLIProxyAPI 实例配置能力。
包含 proposal/design/specs/tasks 四件工件。
为 issue #142 集成 CLIProxyAPI 引入实例配置表,包含名称、运行模式、
代理与管理地址、加密凭据、启用状态等字段。PostgreSQL 与 SQLite
双 schema 同步落地,并生成对应迁移文件。

OpenSpec: cliproxy-instance-config 阶段 1
- cliproxy-instance-crud.ts:实例增删改查,凭据 Fernet 加密入库,
  更新时未提交密钥保留原值,地址校验按运行模式分流
- cliproxy-connection-tester.ts:调用管理 API 只读端点探活,
  区分成功、鉴权失败、地址不可达、服务异常四类结果
- 同步更新 migrate-sqlite 测试中的迁移数量与清单断言

OpenSpec: cliproxy-instance-config 阶段 2
新增 src/app/api/admin/cliproxy/instances 路由族:
- route.ts:GET 列表 / POST 创建
- [id]/route.ts:GET 详情 / PATCH 更新 / DELETE 删除
- [id]/test/route.ts:已保存实例连通性检测
- test/route.ts:未保存配置创建前预检测
路由复用 validateAdminAuth 鉴权与 Zod 入参校验,响应隐去凭据明文。

OpenSpec: cliproxy-instance-config 阶段 3
勾选 tasks.md 全部任务,格式、类型、测试、迁移一致性检查均通过。

OpenSpec: cliproxy-instance-config 阶段 4
- spec/design 将 external 模式表述明确为写入前同步地址安全校验,
  与既有上游写入路径防护粒度一致,DNS 重绑定防护归入后续请求时刻变更
- design 补充 CLIProxyAPI 管理 API 鉴权失败 IP 限流的开放问题
- getCliproxyInstanceRow 补充 @internal 说明,禁止原始记录进入 API 响应

OpenSpec: cliproxy-instance-config 评审修正
issue #142 集成 CLIProxyAPI 的第二个变更,交付 OAuth 账号管理与
登录流程能力。包含 proposal/design/specs/tasks 四件工件。

OpenSpec: cliproxy-oauth-account-management 提案
为 CLIProxyAPI OAuth 账号管理引入元数据缓存表,外键引用
cliproxy_instances(onDelete cascade),含 (实例, 账号文件名)
唯一约束。仅缓存非敏感字段,OAuth token 明文不入库。
PostgreSQL 与 SQLite 双 schema 同步并生成迁移。

OpenSpec: cliproxy-oauth-account-management 阶段 1
cliproxy-management-client.ts 集中封装管理 API 调用:列出 auth-files、
查询账号模型、更新账号状态与字段、获取 OAuth 授权地址、查询登录状态。
统一注入 Bearer 鉴权、超时控制与错误分类,OAuth 授权地址默认携带
is_webui=true。

OpenSpec: cliproxy-oauth-account-management 阶段 2
cliproxy-auth-account-service.ts 实现账号同步(拉取 auth-files、
白名单解析、模型数量查询、upsert、移除失效条目)与账号启停、
字段更新。单账号模型查询失败不中断整体同步。
deleteCliproxyInstance 补充缓存账号引用校验。

OpenSpec: cliproxy-oauth-account-management 阶段 3
cliproxy-oauth-login-service.ts 实现发起登录与登录状态查询。
发起登录校验服务商并获取授权地址;状态查询透传 CLIProxyAPI 状态,
成功时触发该实例账号同步。AutoRouter 不持久化登录会话。

OpenSpec: cliproxy-oauth-account-management 阶段 4
新增账号与 OAuth 登录相关路由:
- auth-accounts:列出账号、触发同步、启停、字段更新
- oauth-login:发起登录、轮询登录状态
新增账号 API 响应转换与 CLIProxyAPI 领域错误统一映射,
管理 API 调用失败映射为 502。

OpenSpec: cliproxy-oauth-account-management 阶段 5
勾选 tasks.md 全部任务,格式、类型、lint、2416 项测试、
迁移一致性检查均通过。

OpenSpec: cliproxy-oauth-account-management 阶段 6
评审发现 status 限定 varchar(32) 可能在 CLIProxyAPI 返回较长状态
文本时写入截断。provider 经归一化兜底也可能为长文本。两者改为 text
并生成迁移。补充含邮箱与点号的真实账号文件名路由测试,design 记录
登录轮询内联同步的耗时权衡。

OpenSpec: cliproxy-oauth-account-management 评审修正
issue #142 集成 CLIProxyAPI 的第三个变更,交付 OAuth 池上游与
单账号映射上游能力。包含 proposal/design/specs/tasks 四件工件。

OpenSpec: cliproxy-oauth-pool-upstream 提案
为 upstreams 表新增 cliproxyInstanceId(外键、onDelete set null)、
cliproxyAuthFileName、cliproxyProvider 三个可空字段。既有普通上游
字段为空、行为不变。PostgreSQL 与 SQLite 双 schema 同步并生成迁移。

OpenSpec: cliproxy-oauth-pool-upstream 阶段 1
新增 cliproxy-upstream-preset 服务,提供按服务商一键创建 OAuth 池上游与单账号映射上游的能力。池上游复用 createUpstream,按 codex/anthropic/gemini 预设代理路径后缀与路由能力;单账号上游在账号缺前缀时生成并经 CLIProxyAPI 写入前缀。落库后回填 upstreams 的 CLIProxyAPI 关联字段。

经核对 CLIProxyAPI 源码确认账号前缀在模型名中的拼接形式为前缀在前、正斜杠分隔,据此将单账号前缀注入方案从模型规则改为转发层注入,同步修订 design/spec/tasks 工件。导出 cliproxy-auth-account-service 的账号查询函数供预设服务复用。
为 CLIProxyAPI 单账号映射上游在转发前注入账号前缀,使 CLIProxyAPI
将请求固定路由到绑定账号。

forwardRequest 新增可选 modelOverride 入参:JSON 请求体改写 model 字段,
Gemini 原生请求改写 URL 路径中的模型段,非 JSON 请求体原样转发。

forwardWithFailover 选定上游后按 cliproxyAuthFileName 取账号前缀,
拼出携带前缀的模型名传入 forwardRequest;普通上游与池上游不带账号
文件名,跳过注入。failover 切换上游时在循环内按新选上游重新判定。

cliproxy-upstream-preset 新增 resolveCliproxyAccountPrefix 辅助函数,
账号缺失、无前缀或前缀非法时返回 null 跳过注入。
deleteCliproxyInstance 在校验缓存 OAuth 账号引用之外,新增对 upstreams
表 cliproxyInstanceId 引用的校验。存在关联池上游或单账号上游时抛出
CliproxyInstanceInUseError 拒绝删除,外键 set null 仅作兜底。
新增两个 Admin API 路由,复用 validateAdminAuth 鉴权与
handleCliproxyRouteError 错误映射。

POST /api/admin/cliproxy/instances/:id/pool-upstreams
按服务商一键创建 OAuth 池上游,provider 经 zod 枚举严格校验。

POST /api/admin/cliproxy/instances/:id/auth-accounts/:accountName/upstream
将单个 OAuth 账号固定映射为上游,账号文件名经 decodeURIComponent
还原以支持含邮箱与点号的真实文件名。

cliproxy-route-errors 新增 InvalidCliproxyPrefixError 到 400 的映射。
forwardRequest 新增 modelOverride 入参后,proxy route 测试中
forwardRequest 调用断言补充第六个参数 undefined。

format:check、test:run 全量 2447 项测试、db:check:consistency 与
openspec validate 均通过。
g1331 added 4 commits May 21, 2026 23:13
归档 issue #142 集成 CLIProxyAPI 的 5 个 OpenSpec 变更并同步主 specs:
- cliproxy-instance-config
- cliproxy-oauth-account-management
- cliproxy-oauth-pool-upstream
- cliproxy-sidecar-deployment
- cliproxy-admin-ui
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 67.83311% with 239 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.14%. Comparing base (339eb79) to head (d54f6af).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #166      +/-   ##
==========================================
- Coverage   79.19%   74.14%   -5.06%     
==========================================
  Files         125      145      +20     
  Lines       10739    11038     +299     
  Branches     3785     3819      +34     
==========================================
- Hits         8505     8184     -321     
- Misses       1444     1664     +220     
- Partials      790     1190     +400     
Flag Coverage Δ
typescript ?
verify 74.14% <67.83%> (-0.46%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

envsubst 不可用时原回退逻辑将原始环境变量取值插入 sed 替换文本,
取值中的 & \ | 会被 sed 解释,破坏生成的 config.yaml。
改为纯 POSIX shell 字面量替换,占位符与取值均按字面量处理,
不再经过 sed/awk,渲染结果与取值完全一致。
@g1331 g1331 merged commit 31afbf8 into master May 22, 2026
12 checks passed
@g1331 g1331 deleted the feat/cliproxy-integration branch May 24, 2026 04:34
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.

集成 CLIProxyAPI,支持 CLI OAuth 上游

1 participant