Commit 15dc49eb authored by 方海彤's avatar 方海彤 👶🏻

feat: migrate local proxy from codex_proxy to CLIProxyAPI

- Updates the default `API_URL` and port from `8088` to `8317` in `ai_review/config.py` and documentation to align with CLIProxyAPI defaults.
- Replaces the custom `proxy/codex_proxy.py` and launchd plist with a new configuration example for `CLIProxyAPI` (`proxy/cliproxyapi.config.example.yaml`).
- Updates `README.md` with instructions for installing and configuring `CLIProxyAPI` via Homebrew, including OAuth login and API key setup.
- Adjusts environment variable documentation to reflect that `AI_REVIEW_API_KEY` is now required by the new proxy configuration.
parent 7450df55
...@@ -51,11 +51,11 @@ ai-code-review: ...@@ -51,11 +51,11 @@ ai-code-review:
| 变量 | 说明 | | 变量 | 说明 |
|------|------| |------|------|
| `AI_REVIEW_API_URL` | 代理地址,例 `http://<MacIP>:8088/v1`;缺省 `http://localhost:8088/v1/chat/completions`(本机调试用) | | `AI_REVIEW_API_URL` | 代理地址,例 `http://<MacIP>:8317/v1`;缺省 `http://localhost:8317/v1/chat/completions`(本机调试用) |
| `AI_REVIEW_API_KEY` | 代理 Bearer token(开放模式可不设) | | `AI_REVIEW_API_KEY` | 代理 Bearer token(必填,配在 cliproxyapi 的 `api-keys` 列表里) |
| `FEISHU_WEBHOOK_URL` | 飞书机器人 Webhook(建议项目级配置,每项目独立的群) | | `FEISHU_WEBHOOK_URL` | 飞书机器人 Webhook(建议项目级配置,每项目独立的群) |
> 详细的 codex 代理部署见下方 [本地 Codex 代理](#本地-codex-代理可选)。 > 详细的代理部署见下方 [本地 CLIProxyAPI](#本地-cliproxyapi可选)。
## 环境变量 ## 环境变量
...@@ -63,8 +63,8 @@ ai-code-review: ...@@ -63,8 +63,8 @@ ai-code-review:
| 变量 | 默认值 | 说明 | | 变量 | 默认值 | 说明 |
|------|--------|------| |------|--------|------|
| `AI_REVIEW_API_URL` | `http://localhost:8088/v1/chat/completions` | 代理 / OpenAI 兼容网关地址 | | `AI_REVIEW_API_URL` | `http://localhost:8317/v1/chat/completions` | 代理 / OpenAI 兼容网关地址 |
| `AI_REVIEW_API_KEY` | - | Bearer token(代理开放模式可空) | | `AI_REVIEW_API_KEY` | - | Bearer token(cliproxyapi 的 `api-keys` 之一) |
| `AI_REVIEW_MODEL` | `gpt-5.5` | 深度审查模型 | | `AI_REVIEW_MODEL` | `gpt-5.5` | 深度审查模型 |
| `AI_REVIEW_TRIAGE_MODEL` | `gpt-5.4-mini` | 分流判定 & 标准审查模型 | | `AI_REVIEW_TRIAGE_MODEL` | `gpt-5.4-mini` | 分流判定 & 标准审查模型 |
| `AI_REVIEW_PLATFORM` | - | 平台预设:`android` / `ios` / `frontend` | | `AI_REVIEW_PLATFORM` | - | 平台预设:`android` / `ios` / `frontend` |
...@@ -102,32 +102,37 @@ git diff → 文件过滤 → LLM 分流判定 → 审查 → 飞书通知 ...@@ -102,32 +102,37 @@ git diff → 文件过滤 → LLM 分流判定 → 审查 → 飞书通知
• 命中安全关键词 → 升级为 deep • 命中安全关键词 → 升级为 deep
``` ```
## 本地 Codex 代理(可选) ## 本地 CLIProxyAPI(可选)
如果你不想买 LLM API key,但有:① 一台**常开**的 Mac、② **ChatGPT 订阅**(已 `codex login`)、③ CI runner 在内网可访问该 Mac,可以用 `proxy/codex_proxy.py` 把本机 codex CLI 包成 OpenAI 兼容 HTTP 接口。 如果你不想买 LLM API key,但有:① 一台**常开**的 Mac、② **ChatGPT 订阅**、③ CI runner 在内网可访问该 Mac,可以在 Mac 上跑 [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)(router-for.me),把本机 ChatGPT 订阅登录态通过 OAuth 接入,对外暴露 OpenAI 兼容 HTTP 接口。
业务项目侧 **`.gitlab-ci.yml` 完全不动**,只是 GitLab Variables 里的 `AI_REVIEW_API_URL` / `AI_REVIEW_API_KEY` 指向代理而已。 业务项目侧 **`.gitlab-ci.yml` 完全不动**,只是 GitLab Variables 里的 `AI_REVIEW_API_URL` / `AI_REVIEW_API_KEY` 指向代理而已。
### 部署(Mac 侧,一次性) ### 部署(Mac 侧,一次性)
1. 确认 codex 已登录:`codex login status` 应显示 `Logged in using ChatGPT` 1. 安装并启动:
2. 生成一个 token(任意 32 位随机串),启动代理:
```bash ```bash
export CODEX_PROXY_TOKEN=<你的token> brew install cliproxyapi
python3 proxy/codex_proxy.py brew services start cliproxyapi
# 默认监听 0.0.0.0:8088 # 默认监听 0.0.0.0:8317
``` ```
3. 找内网 IP:`ipconfig getifaddr en0` 2. 登录 Codex(OAuth 复用 ChatGPT 订阅):参考官方文档 <https://help.router-for.me/cn/>,登录态会写入 `~/.cli-proxy-api/`
4. 防睡眠:`caffeinate -di -w $(pgrep -f codex_proxy.py)` 或 系统设置 → 电池/电源 → 防止自动休眠 3. 配置 api-keys:复制本仓库示例
5. 验证(在另一个终端):
```bash ```bash
curl -X POST http://127.0.0.1:8088/v1/chat/completions \ cp proxy/cliproxyapi.config.example.yaml ~/.cli-proxy-api/config.yaml
-H "Authorization: Bearer $CODEX_PROXY_TOKEN" \ # 编辑文件,把 api-keys 里的占位串换成你自己的随机 token
brew services restart cliproxyapi
```
4. 找内网 IP:`ipconfig getifaddr en0`
5. 防睡眠:系统设置 → 电池/电源 → 防止自动休眠
6. 验证(在另一个终端):
```bash
curl -X POST http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer <你 config 里写的 api-key>" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"回复:ok"}]}' -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"回复:ok"}]}'
``` ```
6. 开机自启(可选):编辑 `proxy/com.codex-proxy.plist` 把里面的 `__PROXY_PATH__` / `__SET_YOUR_TOKEN_HERE__` / `__HOME__` 替换好,拷到 `~/Library/LaunchAgents/`,然后 `launchctl load ~/Library/LaunchAgents/com.codex-proxy.plist` 7. macOS 防火墙若开启,第一次访问会弹出"是否允许 cliproxyapi 接受连接",选允许
7. macOS 防火墙若开启,第一次访问会弹出"是否允许 python3 接受连接",选允许;或在 系统设置 → 网络 → 防火墙 里手动加 python3 例外
### GitLab 配置(一次性) ### GitLab 配置(一次性)
...@@ -135,39 +140,20 @@ git diff → 文件过滤 → LLM 分流判定 → 审查 → 飞书通知 ...@@ -135,39 +140,20 @@ git diff → 文件过滤 → LLM 分流判定 → 审查 → 飞书通知
| 变量 | 值 | 说明 | | 变量 | 值 | 说明 |
|------|------|------| |------|------|------|
| `AI_REVIEW_API_URL` | `http://<你Mac内网IP>:8088/v1` | 必填 | | `AI_REVIEW_API_URL` | `http://<你Mac内网IP>:8317/v1` | 必填 |
| `AI_REVIEW_API_KEY` | 上面的 `CODEX_PROXY_TOKEN` | 代理开放模式可不设 | | `AI_REVIEW_API_KEY` | cliproxyapi config 里的某个 api-key | 必填 |
| `AI_REVIEW_MODEL` | 例如 `gpt-5.5` | 可选;deep 审查用 | | `AI_REVIEW_MODEL` | 例如 `gpt-5.5` | 可选;deep 审查用 |
| `AI_REVIEW_TRIAGE_MODEL` | 例如 `gpt-5.4-mini` | 可选;triage / standard 审查用 | | `AI_REVIEW_TRIAGE_MODEL` | 例如 `gpt-5.4-mini` | 可选;triage / standard 审查用 |
**模型解析规则(代理侧)** **模型路由**:cliproxyapi 会按 config.yaml 里的 `models` / `alias` 把请求路由到对应上游(Codex OAuth 或外部 OpenAI 兼容上游);下游传什么 model 名,飞书通知就显示上游真实返回的 model 名。
- 请求里 model 像 codex 模型名(`gpt-*` / `o*` / `codex-*`)→ 转给 `codex exec -m <model>`,飞书显示该名
- 请求里 model 是别的(比如非 `gpt-*` 命名)→ 用代理兜底 `CODEX_PROXY_DEFAULT_MODEL`(默认 `gpt-5.5`),飞书显示兜底名
- 想换兜底:Mac 启动代理时设 `CODEX_PROXY_DEFAULT_MODEL=gpt-5.4 python3 proxy/codex_proxy.py`
**你可用的 codex 模型**(在 Mac 上跑 `cat ~/.codex/models_cache.json | grep -oE '"gpt-[0-9.-]+"' | sort -u` 查实时列表):
- `gpt-5.5`(最新,质量最好)
- `gpt-5.4`
- `gpt-5.4-mini`(快、便宜,适合 triage)
- `gpt-5.3-codex`(代码场景)
- `gpt-5.2`
> 已有项目检查项目级 Variables 里有没有 `AI_REVIEW_API_KEY` —— 项目级会覆盖 group 级,要么删掉让它继承,要么改成新 token。 > 已有项目检查项目级 Variables 里有没有 `AI_REVIEW_API_KEY` —— 项目级会覆盖 group 级,要么删掉让它继承,要么改成新 token。
### 简化版:完全信任内网,关掉鉴权
如果 CI runner 与代理在同一可信内网、不担心被无意调用,可以省掉 Bearer token:
- **Mac 侧**:启动代理时**不设** `CODEX_PROXY_TOKEN`,代理进入开放模式(启动会打 WARNING)
- **GitLab 侧**`AI_REVIEW_API_KEY` 不需要配置(留空或不设都可以),代理不校验
### 注意事项 ### 注意事项
- **TOS**:把个人 ChatGPT 订阅暴露成内部服务在 OpenAI 条款里属灰色地带,仅限自用、不要对外 - **TOS**:把个人 ChatGPT 订阅暴露成内部服务在 OpenAI 条款里属灰色地带,仅限自用、不要对外
- **并发**:代理强制串行(一次只跑一个 codex),多 CI 并发会排队,必要时调高 `STANDARD_TIMEOUT` / `DEEP_TIMEOUT` - **可用性**:Mac 一旦睡眠/重启 / cliproxyapi 的 OAuth 登录态失效,所有项目 CI 会挂 —— 关键时刻请用真 API key 兜底
- **可用性**:Mac 一旦睡眠/重启/codex 登录失效,所有项目 CI 会挂 —— 关键时刻请用真 API key 兜底 - **并发**:cliproxyapi 不再像旧版自研代理那样强制串行;如果触发 ChatGPT 上游限流,按需调高客户端 `AI_REVIEW_STANDARD_TIMEOUT` / `AI_REVIEW_DEEP_TIMEOUT`
## 项目结构 ## 项目结构
...@@ -183,8 +169,7 @@ ai_review/ ...@@ -183,8 +169,7 @@ ai_review/
└── main.py # 主流程编排 └── main.py # 主流程编排
ci_review.py # 薄包装入口(兼容现有 CI 调用) ci_review.py # 薄包装入口(兼容现有 CI 调用)
proxy/ proxy/
├── codex_proxy.py # 本地 Codex CLI -> OpenAI 兼容 HTTP 代理 └── cliproxyapi.config.example.yaml # CLIProxyAPI 示例配置(brew services 起)
└── com.codex-proxy.plist # macOS launchd 自启模板
templates/ templates/
└── ai-review.yml # GitLab CI 模板 └── ai-review.yml # GitLab CI 模板
``` ```
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
import os import os
# ─── 配置(全部从环境变量读取) ────────────────────────────── # ─── 配置(全部从环境变量读取) ──────────────────────────────
# 默认指向本机 codex 代理;CI 走内网时通过 GitLab Variables 覆盖为代理 IP # 默认指向本机 CLIProxyAPI(router-for.me);CI 走内网时通过 GitLab Variables 覆盖为代理 IP
API_URL = os.environ.get("AI_REVIEW_API_URL", "http://localhost:8088/v1/chat/completions") API_URL = os.environ.get("AI_REVIEW_API_URL", "http://localhost:8317/v1/chat/completions")
API_KEY = os.environ.get("AI_REVIEW_API_KEY", "") API_KEY = os.environ.get("AI_REVIEW_API_KEY", "")
MODEL = os.environ.get("AI_REVIEW_MODEL", "gpt-5.5") MODEL = os.environ.get("AI_REVIEW_MODEL", "gpt-5.5")
TRIAGE_MODEL = os.environ.get("AI_REVIEW_TRIAGE_MODEL", "gpt-5.4-mini") TRIAGE_MODEL = os.environ.get("AI_REVIEW_TRIAGE_MODEL", "gpt-5.4-mini")
......
# CLIProxyAPI 示例配置
# 上游项目: https://github.com/router-for-me/CLIProxyAPI
# 文档: https://help.router-for.me/cn/
#
# 用法:
# 1. cp proxy/cliproxyapi.config.example.yaml ~/.cli-proxy-api/config.yaml
# 2. 按下方 TODO 注释填值
# 3. 按官方文档跑一次 OAuth 登录,把 ChatGPT 订阅登录态写入 auth-dir
# 4. brew services restart cliproxyapi
# ─── 服务监听 ────────────────────────────────────────────────
host: "0.0.0.0" # 内网暴露;仅在受信任内网这么写,公网请改 127.0.0.1 + 反代
port: 8317
# ─── 鉴权 ────────────────────────────────────────────────────
# 客户端调用 /v1/chat/completions 时携带 `Authorization: Bearer <这里某一个>`
# TODO: 至少配一个 32+ 位随机串,CI 端把同一个值填进 GitLab Variables 的 AI_REVIEW_API_KEY
api-keys:
- "TODO-replace-with-32-char-random-string"
# Codex / Claude 等 OAuth 登录态目录;登录命令见官方文档
auth-dir: "~/.cli-proxy-api"
# ─── 调试 ────────────────────────────────────────────────────
debug: false
logging-to-file: true
# ─── 路由 / 重试(按需调) ───────────────────────────────────
request-retry: 3
routing:
strategy: "round-robin"
# ─── 可选:其它 OpenAI 兼容上游做 fallback ───────────────────
# 如果只想跑 Codex OAuth,下面这段保持注释即可。
#
# openai-compatibility:
# - name: "openrouter"
# base-url: "https://openrouter.ai/api/v1"
# api-key-entries:
# - api-key: "sk-or-v1-..."
# models:
# - name: "moonshotai/kimi-k2:free"
# alias: "gpt-5.5" # 下游传 gpt-5.5 时也能命中此上游
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment