mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
docs: streamline project guidance
Keep the public README terse and operational, and align the repository skills with the current lifecycle, transport, validation, and release boundaries. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -1,41 +1,33 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="frontend/public/favicon.svg" alt="Codex Proxy RS" width="88" height="88" />
|
||||
<img src="frontend/public/favicon.svg" alt="Codex Proxy RS" width="80" height="80" />
|
||||
|
||||
# Codex Proxy RS
|
||||
|
||||
**基于 Rust 的高性能 Codex 多账号网关代理**
|
||||
OpenAI Responses 多账号网关。
|
||||
|
||||
[](https://github.com/zyycn/codex-proxy-rs/actions/workflows/ci.yml)
|
||||
[](https://github.com/zyycn/codex-proxy-rs/releases)
|
||||
[](https://www.rust-lang.org/)
|
||||
[](https://vuejs.org/)
|
||||
[](https://vite.dev/)
|
||||
[](https://github.com/zyycn/codex-proxy-rs/pkgs/container/codex-proxy-rs)
|
||||
[](#开源许可)
|
||||
[](#许可)
|
||||
|
||||
[快速开始](#快速开始) · [首次使用](#首次使用) · [客户端接入](#客户端接入) · [常见问题](#常见问题) · [部署文档](deploy/README.md)
|
||||
[部署](deploy/README.md) · [架构](docs/architecture.md) · [发布](https://github.com/zyycn/codex-proxy-rs/releases)
|
||||
|
||||
</div>
|
||||
|
||||
> [!NOTE]
|
||||
> 当前兼容 OpenAI Responses API,不提供 `/v1/chat/completions`。
|
||||
## 边界
|
||||
|
||||
## 功能
|
||||
- OpenAI Responses:HTTP、SSE、官方 WebSocket。
|
||||
- 多账号调度、故障切换、额度与身份隔离。
|
||||
- 会话级 WebSocket 池与共享 HTTP/2 后备。
|
||||
- PostgreSQL 持久化,Redis 运行态协调。
|
||||
- Vue 管理端:账号、客户端 Key、用量、费用、延迟与错误。
|
||||
|
||||
- 支持 Responses HTTP、SSE 和官方 WebSocket 请求。
|
||||
- 提供智能调度、额度重置优先、轮询和粘滞四种账号策略。
|
||||
- 某个账号遇到额度、认证、模型或传输错误时,继续尝试其他账号。
|
||||
- 在网页中管理账号、客户端 Key、模型别名和运行参数。
|
||||
- 按请求、模型、账号或客户端 Key 查看 Token、费用、缓存、TTFT、延迟和错误。
|
||||
- 支持账号 OAuth、Token 导入以及 CPR、Sub2API、CLIProxyAPI JSON 导入。
|
||||
- 可直接生成 Codex CLI 配置,或通过 deeplink 导入 CCSwitch。
|
||||
不提供 `/v1/chat/completions`。
|
||||
|
||||
## 快速开始
|
||||
## 部署
|
||||
|
||||
Docker Compose 是最简单的启动方式。开始前请安装 Docker Engine 和 Docker Compose Plugin。
|
||||
|
||||
### 1. 准备配置
|
||||
要求 Docker Engine 与 Docker Compose Plugin。
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zyycn/codex-proxy-rs.git
|
||||
@@ -48,74 +40,62 @@ sudo chown "$(id -u):10001" deploy/config.yaml
|
||||
chmod 0640 deploy/config.yaml
|
||||
```
|
||||
|
||||
分别执行三次以下命令生成密码:
|
||||
分别生成 PostgreSQL、Redis 和管理员密码:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 24
|
||||
```
|
||||
|
||||
把结果填入 `deploy/config.yaml` 的 `database.password`、`redis.password` 和
|
||||
`admin.default_password`。PostgreSQL 与 Redis 密码必须是 48 位十六进制字符;管理员密码
|
||||
至少 12 位且不能包含 `$`。
|
||||
写入 `deploy/config.yaml`:
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 应用容器以非 root 用户 `10001:10001` 运行。Linux Bind Mount 会保留宿主机权限,因此需要允许容器用户组读取配置并写入数据和日志目录:
|
||||
>
|
||||
> ```bash
|
||||
> sudo chown -R "$(id -u):10001" .runtime/data .runtime/logs
|
||||
> chmod 0770 .runtime/data .runtime/logs
|
||||
> ```
|
||||
>
|
||||
> 配置文件通过 Compose `configs` 只读挂载;普通 Compose 会保留宿主机权限,因此由
|
||||
> 当前用户持有、仅向容器组开放读取权限。
|
||||
> macOS 和 Windows 的 Docker Desktop 通常也不需要调整数据目录权限。
|
||||
- `x-cpr.database.password`
|
||||
- `x-cpr.redis.password`
|
||||
- `x-cpr.admin.default_password`
|
||||
|
||||
### 2. 启动服务
|
||||
前两个值必须是 48 位十六进制字符。管理员密码至少 12 位,且不能包含 `$`。
|
||||
|
||||
Linux 需要开放容器组写权限:
|
||||
|
||||
```bash
|
||||
sudo chown -R "$(id -u):10001" .runtime/data .runtime/logs
|
||||
chmod 0770 .runtime/data .runtime/logs
|
||||
```
|
||||
|
||||
启动:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose.yaml config --quiet
|
||||
docker compose -f deploy/compose.yaml pull
|
||||
docker compose -f deploy/compose.yaml up -d --no-build
|
||||
```
|
||||
|
||||
启动后检查:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose.yaml ps
|
||||
curl -i http://127.0.0.1:8080/healthz
|
||||
```
|
||||
|
||||
`/healthz` 返回 `204 No Content` 即表示服务正常。管理端地址为 <http://127.0.0.1:8080>。
|
||||
`204 No Content` 表示应用、PostgreSQL 与 Redis 均可用。管理端位于
|
||||
`http://127.0.0.1:8080`。
|
||||
|
||||
## 首次使用
|
||||
完整部署与密码轮换规则见 [deploy/README.md](deploy/README.md)。
|
||||
|
||||
1. 使用 `admin@cpr.local` 和 `x-cpr.admin.default_password` 中设置的密码登录。
|
||||
2. 打开“账号”,用 OAuth、Access/Refresh Token 或 JSON 文件添加账号。
|
||||
3. 点一次连接测试,能看到模型和额度即可。
|
||||
4. 打开“API 密钥”,创建一个 `sk_...` 客户端 Key。
|
||||
5. 点击“使用密钥”复制 Codex CLI 配置,或一键导入 CCSwitch。
|
||||
## 初始化
|
||||
|
||||
> [!TIP]
|
||||
> `admin.default_password` 只用于首次创建管理员。已有管理员后修改该字段不会重置登录密码。
|
||||
1. 使用 `admin@cpr.local` 与配置中的初始密码登录。
|
||||
2. 添加 Codex 账号并执行连接测试。
|
||||
3. 创建 `sk_...` 客户端 Key。
|
||||
4. 复制 Codex CLI 配置,或导入 CCSwitch。
|
||||
|
||||
## 客户端接入
|
||||
`admin.default_password` 只在首次创建管理员时生效。
|
||||
|
||||
## 客户端
|
||||
|
||||
| 配置 | 值 |
|
||||
| -------- | ---------------------------------------- |
|
||||
| Base URL | `http://127.0.0.1:8080/v1` |
|
||||
| API Key | 管理端创建的 `sk_...` 客户端 Key |
|
||||
| API Key | 管理端创建的 `sk_...` |
|
||||
| 鉴权 | `Authorization: Bearer <client-api-key>` |
|
||||
|
||||
先查询当前可用模型:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8080/v1/models \
|
||||
-H 'Authorization: Bearer <client-api-key>'
|
||||
```
|
||||
|
||||
发送一个非流式 Responses 请求:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8080/v1/responses \
|
||||
-H 'Authorization: Bearer <client-api-key>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
@@ -126,90 +106,36 @@ curl http://127.0.0.1:8080/v1/responses \
|
||||
}'
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>查看全部客户端 API 路由</summary>
|
||||
|
||||
| 路由 | 说明 |
|
||||
| -------------------------------- | ------------------------------- |
|
||||
| `POST /v1/responses` | Responses 非流式或 SSE 流式请求 |
|
||||
| `GET /v1/responses` | 官方 Responses WebSocket |
|
||||
| `POST /v1/responses/review` | Review 请求 |
|
||||
| `GET /v1/models` | OpenAI 格式的模型列表 |
|
||||
| `GET /v1/models/catalog` | 完整模型目录 |
|
||||
| `GET /v1/models/{model_id}` | 模型详情 |
|
||||
| `GET /v1/models/{model_id}/info` | 模型运行信息 |
|
||||
| 路由 | 用途 |
|
||||
| --------------------------- | ------------------- |
|
||||
| `POST /v1/responses` | JSON 或 SSE |
|
||||
| `GET /v1/responses` | Responses WebSocket |
|
||||
| `POST /v1/responses/review` | Review |
|
||||
| `GET /v1/models` | 模型列表 |
|
||||
| `GET /v1/models/catalog` | 模型目录 |
|
||||
|
||||
所有 `/v1/*` 路由都需要客户端 API Key。
|
||||
|
||||
</details>
|
||||
|
||||
## 管理端
|
||||
|
||||
| 页面 | 内容 |
|
||||
| -------- | ---------------------------------------------------------------------- |
|
||||
| 概览 | 查看服务状态、请求趋势、Token、账号池容量、请求健康和最近调用 |
|
||||
| 账号 | 添加、导入、导出、测试、启停账号,以及刷新 Token 和额度 |
|
||||
| API 密钥 | 创建、复制、启停或删除 Key,生成 Codex CLI 配置并导入 CCSwitch |
|
||||
| 使用统计 | 按时间、模型、账号和客户端 Key 查看用量、费用、缓存、延迟和错误 |
|
||||
| 系统设置 | 配置模型别名、调度策略、单账号并发、请求间隔、刷新参数和管理员 API Key |
|
||||
| 系统更新 | 查看版本和发布说明;Release 版本可以在线更新并重启 |
|
||||
|
||||
## 常用操作
|
||||
|
||||
### 升级
|
||||
## 运维
|
||||
|
||||
```bash
|
||||
# 升级
|
||||
docker compose -f deploy/compose.yaml pull codex-proxy-rs
|
||||
docker compose -f deploy/compose.yaml up -d --no-build
|
||||
```
|
||||
|
||||
### 查看日志
|
||||
|
||||
```bash
|
||||
# 日志
|
||||
docker compose -f deploy/compose.yaml logs -f codex-proxy-rs
|
||||
```
|
||||
|
||||
### 从当前源码构建
|
||||
|
||||
```bash
|
||||
# 从源码构建
|
||||
docker compose -f deploy/compose.yaml build codex-proxy-rs
|
||||
docker compose -f deploy/compose.yaml up -d
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> PostgreSQL、Redis、应用数据和文件日志都保存在仓库根目录 `.runtime/`。普通
|
||||
> `docker compose down` 不会删除这些绑定目录;删除 `.runtime/` 才会清除数据。升级前请备份
|
||||
> 整个目录,数据库备份中包含客户端凭据,应按敏感数据保管。
|
||||
运行状态保存在 `.runtime/`。删除该目录会清除数据库、Redis、身份密钥和日志。
|
||||
|
||||
## 常见问题
|
||||
Compose 默认只绑定 `127.0.0.1`。公网接入应使用 HTTPS 反向代理,并转发 WebSocket
|
||||
upgrade 与真实客户端 IP;不要暴露 PostgreSQL 或 Redis。
|
||||
|
||||
### `/healthz` 返回 `503`
|
||||
## 许可
|
||||
|
||||
检查 PostgreSQL 和 Redis 容器是否健康:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose.yaml ps
|
||||
docker compose -f deploy/compose.yaml logs postgres redis
|
||||
```
|
||||
|
||||
### 容器反复重启
|
||||
|
||||
检查 `deploy/config.yaml` 的三个密码是否填写完整,以及 `.runtime/data`、`.runtime/logs`
|
||||
的权限是否正确。
|
||||
|
||||
### 需要从其他设备访问
|
||||
|
||||
Compose 默认仅绑定 `127.0.0.1`。请在服务前配置 HTTPS 反向代理,并正确转发 WebSocket 升级和真实客户端 IP 请求头。不要直接暴露 PostgreSQL 或 Redis。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [发布版本](https://github.com/zyycn/codex-proxy-rs/releases)
|
||||
- [容器镜像](https://github.com/zyycn/codex-proxy-rs/pkgs/container/codex-proxy-rs)
|
||||
- [详细部署说明](deploy/README.md)
|
||||
- [架构说明](docs/architecture.md)
|
||||
|
||||
Docker 镜像支持 Linux amd64/arm64。Release 压缩包另有 macOS arm64 和 Windows amd64 版本。
|
||||
|
||||
## 开源许可
|
||||
|
||||
Codex Proxy RS 基于 [MIT License](https://opensource.org/license/mit) 开源。
|
||||
[MIT](LICENSE)
|
||||
|
||||
@@ -1,51 +1,58 @@
|
||||
---
|
||||
name: codex-proxy-rs
|
||||
description: Codex Proxy RS 仓库开发指南。Use when working on its Rust/Axum backend, Vue frontend, PostgreSQL/Redis storage, account-pool scheduling, Responses proxy and recovery, telemetry, Docker deployment, CI/release, configuration, debugging, or documentation.
|
||||
description: Codex Proxy RS 仓库开发指南。Use when changing or auditing its Rust backend, Vue frontend, PostgreSQL/Redis state, account scheduling, Responses transport and recovery, telemetry, Docker deployment, CI, release, configuration, or project documentation.
|
||||
---
|
||||
|
||||
# Codex Proxy RS
|
||||
|
||||
使用此 skill 处理 Codex Proxy RS 的开发、审计、验证和发布工作。
|
||||
## 事实来源
|
||||
|
||||
## 开始前
|
||||
1. 以当前源码、配置和测试为准。
|
||||
2. 非简单改动读取 `references/repo-guide.md`。
|
||||
3. 涉及目录、生命周期、存储或后台任务时读取 `docs/architecture.md`。
|
||||
4. skill 或文档与实现冲突时,在同一改动中修正。
|
||||
|
||||
1. 确认当前仓库根目录是 `codex-proxy-rs`。
|
||||
2. 存在 `.codegraph/` 时,优先用 CodeGraph 定位调用链,再回到源码和测试验证。
|
||||
3. 非简单改动先阅读 `references/repo-guide.md`。
|
||||
4. 涉及目录边界、请求链路、存储归属或后台任务时,同时阅读 `docs/architecture.md`。
|
||||
5. 始终以当前源码、配置和测试为准;发现 skill 与代码不一致时,在同一改动中修正 skill。
|
||||
6. 保持改动紧贴用户请求,不擅自改变目录、部署或发布契约。
|
||||
存在 `.codegraph/` 时可先定位调用链;结论必须回到源码和测试验证。
|
||||
|
||||
## 任务分流
|
||||
## 边界
|
||||
|
||||
- 后端:遵循 `backend/src` 当前领域边界;测试统一放在 `backend/tests`,禁止写入 `backend/src`。
|
||||
- 存储:PostgreSQL 是权威持久化,Redis 保存运行态数据,本地数据目录保存身份密钥和更新状态。
|
||||
- 前端:使用 Vue 3 `<script setup>`、TypeScript、Tailwind v4、已有组件和主题 token。
|
||||
- Docker / 发布:保留非 root runtime、YAML 凭据桥接、`.runtime` 绑定目录、GitHub Release、GHCR 和在线更新契约。
|
||||
- 文档:README 面向部署者和使用者;`docs/architecture.md` 面向开发者。不要新增过程型审计或迁移文档。
|
||||
- `v1/*` 使用 Request → Attempt → Stream 生命周期。功能规则只能留在唯一 owner 内。
|
||||
- `api` 解析和编码;`dispatch` 编排;`fleet` 管账号;`upstream` 管协议与传输;`telemetry` 保存确定事实。
|
||||
- transport 不选择账号,不解释账号状态,不在 payload 发送后重放。
|
||||
- PostgreSQL 是持久化权威;Redis 保存会话、租约、模型快照和短期状态。
|
||||
- 测试只放 `backend/tests/`。禁止在 `backend/src/` 写 test-only 代码。
|
||||
- Vue 使用 `<script setup lang="ts">`、现有基础组件和主题 token。
|
||||
- README 面向使用者,保持简短;长期架构只写入 `docs/architecture.md`。
|
||||
- 不添加兼容 shim、重复状态机、第二套配置或补丁式旁路。
|
||||
|
||||
## 工作流
|
||||
|
||||
1. 检查工作树,区分用户改动与当前任务。
|
||||
2. 追踪入口、owner、状态变化和输出,再决定修改点。
|
||||
3. 在最小所有权边界内实现;行为变化用外置集成测试固定。
|
||||
4. 同步受影响的架构、配置或 skill。
|
||||
5. 按风险运行验证,最后检查 staged 与 unstaged 范围。
|
||||
|
||||
## 验证
|
||||
|
||||
按改动范围选择足以证明行为的命令。跨领域改动执行完整门禁:
|
||||
从仓库根目录执行:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cargo fmt --check
|
||||
cargo clippy --all-targets --all-features --locked
|
||||
cargo test --test main --locked
|
||||
cargo +1.97.0 fmt --manifest-path backend/Cargo.toml -- --check
|
||||
cargo +1.97.0 clippy --manifest-path backend/Cargo.toml --all-targets --all-features --locked -- -D warnings
|
||||
cargo +1.97.0 test --manifest-path backend/Cargo.toml --locked
|
||||
pnpm --dir frontend format:check
|
||||
pnpm --dir frontend build
|
||||
docker compose -f deploy/compose.yaml config --quiet
|
||||
```
|
||||
|
||||
后端集成测试需要可用的 PostgreSQL 和 Redis;通过 `CPR_TEST_DATABASE_URL`、`CPR_TEST_REDIS_URL` 指定测试连接。使用部署 Compose 时,连接密码必须与 `deploy/config.yaml` 一致。
|
||||
后端完整测试需要 PostgreSQL、Redis,以及与 `deploy/config.yaml` 一致的
|
||||
`CPR_TEST_DATABASE_URL`、`CPR_TEST_REDIS_URL`。
|
||||
|
||||
涉及在线更新时,至少运行 `api::admin::system_routes` 相关测试。涉及发布或镜像时,按 `references/repo-guide.md` 核对版本元数据、Release asset 和镜像 tag。
|
||||
## Git 与发布
|
||||
|
||||
## Git
|
||||
|
||||
沿用仓库历史:使用简短的 Conventional Commit subject,并带署名:
|
||||
|
||||
```text
|
||||
Co-authored-by: Codex <noreply@openai.com>
|
||||
```
|
||||
- 使用简短 Conventional Commit subject。
|
||||
- 提交前检查 `git status --short`、cached/unstaged diff 和 `git diff --check`。
|
||||
- 提交带 `Co-authored-by: Codex <noreply@openai.com>`。
|
||||
- 发布以 `release/version.yaml` 和带注释的 `vX.Y.Z` tag 为准。
|
||||
- 发布完成后核对远端 `main`、tag、Actions、Release asset 与 GHCR。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
interface:
|
||||
display_name: "Codex Proxy RS"
|
||||
short_description: "按当前架构开发和维护 Rust/Vue/PostgreSQL/Redis 代理服务"
|
||||
default_prompt: "使用 $codex-proxy-rs 按当前源码和架构开发、验证或维护 Codex Proxy RS。"
|
||||
short_description: "按当前架构维护 Rust/Vue 多账号 Responses 网关"
|
||||
default_prompt: "使用 $codex-proxy-rs 按当前源码与架构完成开发、验证或发布。"
|
||||
|
||||
@@ -1,232 +1,118 @@
|
||||
# Codex Proxy RS 项目指南
|
||||
|
||||
## 目录
|
||||
## 权威来源
|
||||
|
||||
- [Codex Proxy RS 项目指南](#codex-proxy-rs-项目指南)
|
||||
- [目录](#目录)
|
||||
- [事实来源](#事实来源)
|
||||
- [仓库结构](#仓库结构)
|
||||
- [后端边界](#后端边界)
|
||||
- [存储边界](#存储边界)
|
||||
- [前端规范](#前端规范)
|
||||
- [Docker 和运行时](#docker-和运行时)
|
||||
- [发布和在线更新](#发布和在线更新)
|
||||
- [文档边界](#文档边界)
|
||||
- [验证矩阵](#验证矩阵)
|
||||
- [项目约束](#项目约束)
|
||||
- 行为:当前源码、配置和测试。
|
||||
- 架构:`docs/architecture.md`。
|
||||
- 部署:`deploy/config.example.yaml`、`deploy/compose.yaml`、`deploy/README.md`。
|
||||
- 发布:`release/version.yaml`、`release/platforms.yaml`、`.github/workflows/release.yml`。
|
||||
|
||||
## 事实来源
|
||||
本文件只记录高频开发入口,不复制完整架构。
|
||||
|
||||
1. 当前源码、配置和测试是行为事实。
|
||||
2. `docs/architecture.md` 是目录、依赖方向、请求链路和存储归属的权威说明。
|
||||
3. 本文件记录开发流程和高频约束,不复制完整架构。
|
||||
4. 文档与代码冲突时先核对实现,再在同一提交中修正文档。
|
||||
## 结构
|
||||
|
||||
## 仓库结构
|
||||
| 路径 | 责任 |
|
||||
| ----------------------------- | --------------------------------------------- |
|
||||
| `backend/src/api` | HTTP/WebSocket 契约、鉴权、响应编码、静态资源 |
|
||||
| `backend/src/dispatch` | `v1/*` Request → Attempt → Stream 编排 |
|
||||
| `backend/src/fleet` | 账号、调度、quota、token、Cookie、管理操作 |
|
||||
| `backend/src/upstream/openai` | Codex 协议、HTTP/2、WebSocket、指纹 |
|
||||
| `backend/src/telemetry` | usage、错误事实、聚合和查询 |
|
||||
| `backend/src/infra` | PostgreSQL、Redis、日志、路径、身份 |
|
||||
| `backend/src/bootstrap` | 配置、装配、后台任务、关闭 |
|
||||
| `backend/tests` | 集成、契约、fixture;生产源码内禁止测试 |
|
||||
| `frontend` | Vue 管理端 |
|
||||
| `deploy` | 唯一 Compose 与配置模板 |
|
||||
| `docs/architecture.md` | 唯一长期架构文档 |
|
||||
| `release` | 版本与平台元数据 |
|
||||
|
||||
- `backend/src/`:Rust 1.97 / Axum 后端生产代码。
|
||||
- `backend/tests/`:后端集成测试和 fixtures。测试代码禁止放进 `backend/src/`。
|
||||
- `backend/build.rs`:把版本、Git SHA、构建时间和构建类型写入编译期环境变量。
|
||||
- `frontend/`:Vue 3、Vite 8、Tailwind v4、Pinia、Vue Router、Axios、Lucide 和 ECharts 管理端。
|
||||
- `deploy/`:Dockerfile、唯一的 `compose.yaml` 和 `config.example.yaml`。
|
||||
- `docs/architecture.md`:唯一长期架构文档。
|
||||
- `release/`:版本、目标平台和发布脚本。
|
||||
- `skills/`:项目本地 Codex skills。
|
||||
仓库根目录没有 Cargo manifest。后端命令使用
|
||||
`--manifest-path backend/Cargo.toml`,或先进入 `backend/`。
|
||||
|
||||
仓库根目录没有 Cargo workspace manifest。Rust 命令必须显式使用 `backend/Cargo.toml`。
|
||||
## 后端所有权
|
||||
|
||||
## 后端边界
|
||||
- `api` 只做入站/出站适配,不写业务规则。
|
||||
- `dispatch/lifecycle` 只编排顺序、retry、commit 和 finalize。
|
||||
- `dispatch/controllers` 中每个功能只能有一个 owner,controller 不互调。
|
||||
- `fleet/account_failure.rs` 统一解释跨入口账号失败和状态 effect。
|
||||
- `upstream/openai/failure.rs` 只生成 typed failure facts。
|
||||
- `upstream/openai/transport` 只建立连接、收发协议和产出 transport metrics。
|
||||
- `telemetry` 保存已经确定的事实,不参与调度。
|
||||
- `bootstrap` 是 composition root,不解释业务错误。
|
||||
|
||||
项目没有 `application` 层。`bootstrap` 是装配根,业务规则留在各领域模块。
|
||||
提交边界后不得自动换 transport、账号或重放 payload。账号身份按 attempt 重建;客户端
|
||||
session/thread/turn 等拓扑字段原样透传。
|
||||
|
||||
| 目录 | 职责 |
|
||||
| --- | --- |
|
||||
| `backend/src/api` | 入站 HTTP、鉴权提取、响应映射和静态资源 |
|
||||
| `backend/src/bootstrap` | 配置加载、服务装配、启动关闭和后台任务 |
|
||||
| `backend/src/dispatch` | Responses 编排、账号失败处理、流生命周期和会话恢复 |
|
||||
| `backend/src/fleet` | 账号、账号池、调度、quota、刷新、Cookie 和管理操作 |
|
||||
| `backend/src/upstream/openai` | OpenAI/Codex 协议、HTTP/WebSocket 传输、token 和指纹 |
|
||||
| `backend/src/telemetry` | 成功/失败事实、聚合桶、账号用量和 Dashboard 查询 |
|
||||
| `backend/src/keys` | 客户端 API Key |
|
||||
| `backend/src/auth` | 管理员用户和登录会话 |
|
||||
| `backend/src/settings` | PostgreSQL 运行时设置和 watch 广播 |
|
||||
| `backend/src/models` | 模型目录和 Redis 快照 |
|
||||
| `backend/src/update` | Release 查询、下载、替换、回滚和更新状态 |
|
||||
| `backend/src/infra` | PostgreSQL、Redis、日志、身份和通用工具 |
|
||||
## Responses 传输
|
||||
|
||||
关键入口:
|
||||
- 热 WS 立即复用。
|
||||
- 冷 WS 前台预算为 800ms;超时后当前请求使用同账号 HTTP/2。
|
||||
- 未完成的 WS 只在后台继续握手,不发送原 payload;成功后进入 Idle。
|
||||
- `Connecting` 按 key 单飞并沿用原绝对 deadline。
|
||||
- 账号驱逐和 shutdown 取消 opening;迟到连接不能重新入池。
|
||||
- warmup 与 connection-local continuation 必须使用精确 WS。
|
||||
- breaker 按 origin/TLS profile 统计退化 opening,同一次 opening 只计一次。
|
||||
|
||||
- 总路由:`backend/src/api/router.rs`
|
||||
- 客户端路由:`backend/src/api/client/router.rs`
|
||||
- 管理端路由:`backend/src/api/admin/router.rs`
|
||||
- 服务装配:`backend/src/bootstrap/services.rs`
|
||||
- 非流式调度:`backend/src/dispatch/service.rs`
|
||||
- 流式调度:`backend/src/dispatch/stream/lifecycle.rs`
|
||||
- 账号调度:`backend/src/fleet/scheduler/mod.rs`
|
||||
完整 typestate、pool、breaker 和指标契约见 `docs/architecture.md`。
|
||||
|
||||
对应测试:
|
||||
## 存储
|
||||
|
||||
- 系统更新:`backend/tests/api/admin/system_routes/mod.rs`
|
||||
- 代理调度:`backend/tests/dispatch/service.rs` 及其子目录
|
||||
- 静态资源和健康检查:`backend/tests/api/assets.rs`
|
||||
| 位置 | 数据 |
|
||||
| --------------- | ------------------------------------------------------ |
|
||||
| PostgreSQL | 管理员、Key、账号、quota、设置、Cookie、指纹、遥测事实 |
|
||||
| Redis | 管理会话、刷新租约、模型快照、响应归属、短期会话状态 |
|
||||
| `.runtime/data` | 身份 HMAC secret、更新状态和锁 |
|
||||
| `.runtime/logs` | 结构化轮转日志 |
|
||||
|
||||
启动服务:
|
||||
规则:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cargo run -- serve
|
||||
```
|
||||
- migration 只能新增;禁止修改已应用 SQL。
|
||||
- Redis 业务键使用 `cpr:` 前缀和明确 TTL。
|
||||
- `identity_hmac_secret` 必须随部署保留。
|
||||
- 遥测或 affinity 写入失败不能改变已取得的代理响应。
|
||||
- 账号明确失效先更新内存并驱逐 WS,再异步持久化。
|
||||
|
||||
`main.rs` 还提供内部维护命令 `rebuild-buckets`,用于从保留期内的请求事实重建聚合桶。
|
||||
## 前端
|
||||
|
||||
## 存储边界
|
||||
- Vue 3 Composition API、`<script setup lang="ts">`。
|
||||
- API:`frontend/src/api/modules`。
|
||||
- 基础组件:`frontend/src/components/base`。
|
||||
- 页面状态和副作用:对应 `views/*/composables`。
|
||||
- 使用现有主题 token、Tailwind utilities 和 Lucide。
|
||||
- 独立功能使用独立 loading;旧请求不得覆盖较新响应。
|
||||
- 保持紧凑、低噪声的运维界面。
|
||||
|
||||
| 存储 | 数据 |
|
||||
| --- | --- |
|
||||
| PostgreSQL | 管理员、客户端 Key、运行时设置、账号、quota、累计用量、请求事实、错误事实、聚合桶、Cookie 和指纹 |
|
||||
| Redis | 管理会话、token 刷新租约、模型计划快照、会话亲和与 replay |
|
||||
| 本地数据目录 | `identity_hmac_secret`、更新状态、锁和临时文件 |
|
||||
| 文件日志目录 | 轮转后的结构化日志 |
|
||||
## 运行与部署
|
||||
|
||||
约束:
|
||||
- 配置入口只有 `deploy/config.yaml`;项目不使用 `.env`。
|
||||
- Compose 运行 PostgreSQL、Redis 和非 root 应用容器 `10001:10001`。
|
||||
- 持久状态全部位于 `.runtime/`。
|
||||
- 应用默认绑定 `127.0.0.1:8080`;公网使用 HTTPS 反向代理。
|
||||
- Docker runtime 只包含后端二进制、前端产物和运行依赖。
|
||||
|
||||
- PostgreSQL migration 必须新增版本,禁止修改已应用 SQL;启动会校验版本顺序、名称和 checksum。
|
||||
- Redis 业务键统一使用 `cpr:` 前缀;会话、租约和 affinity 依赖 TTL。
|
||||
- `identity_hmac_secret` 决定账号作用域身份和 installation ID,换镜像时必须保留。
|
||||
- 模型别名、调度策略、并发、请求间隔和刷新参数保存到 PostgreSQL,不放回 YAML。
|
||||
- 遥测和 affinity 写入失败不能改变已经取得的代理响应语义。
|
||||
不要输出 `docker compose config`、`docker inspect` 或真实连接 URL 中的密码。
|
||||
|
||||
## 前端规范
|
||||
|
||||
- 使用 Vue 3 Composition API 和 `<script setup lang="ts">`。
|
||||
- API 客户端位于 `frontend/src/api/modules`。
|
||||
- 基础 UI 位于 `frontend/src/components/base`。
|
||||
- 页面私有组件和 composables 放在对应 `frontend/src/views/*` 下。
|
||||
- 优先使用 Tailwind v4 utilities;需要 CSS 时复用 `frontend/src/styles/tokens.css`。
|
||||
- 保持亮色和暗色主题一致,有 token 时不硬编码一次性颜色。
|
||||
- 按钮和紧凑操作优先使用 Lucide 图标。
|
||||
- 弹窗工作流沿用现有 modal/component 模式,不为一次性操作增加路由。
|
||||
|
||||
## Docker 和运行时
|
||||
|
||||
- Runtime 基于 `debian:bookworm-slim`,只安装 `ca-certificates` 和健康检查所需的 `curl`。
|
||||
- 镜像包含单个后端二进制和 `web/dist`,以非 root 用户 `10001:10001` 运行。
|
||||
- Builder 使用 Node 24 和 Rust 1.97,构建工具不得进入 runtime。
|
||||
- 默认应用镜像是 `ghcr.io/zyycn/codex-proxy-rs:latest`。
|
||||
|
||||
`deploy/config.example.yaml` 是完整启动配置模板。真实配置复制为被 Git 忽略的
|
||||
`deploy/config.yaml`,其中同时保存应用行为、管理员初始化密码、PostgreSQL 密码和 Redis 密码。
|
||||
服务密码通过 YAML anchor 与 Compose `extends` 传给内置服务,不使用 `.env` 配置文件。
|
||||
|
||||
首次部署:
|
||||
|
||||
```bash
|
||||
mkdir -p .runtime/data .runtime/logs
|
||||
install -d -m 0750 .runtime/postgres .runtime/redis
|
||||
cp deploy/config.example.yaml deploy/config.yaml
|
||||
sudo chown "$(id -u):10001" deploy/config.yaml
|
||||
chmod 0640 deploy/config.yaml
|
||||
# 设置 deploy/config.yaml 中的三个密码后执行
|
||||
docker compose -f deploy/compose.yaml config --quiet
|
||||
docker compose -f deploy/compose.yaml up -d
|
||||
```
|
||||
|
||||
挂载和卷:
|
||||
|
||||
- `deploy/config.yaml` -> `/app/deploy/config.yaml`,Compose config、只读(宿主 mode `0640`)
|
||||
- `.runtime/data` -> `/app/.runtime/data`
|
||||
- `.runtime/logs` -> `/app/.runtime/logs`
|
||||
- `.runtime/postgres` -> PostgreSQL 权威数据
|
||||
- `.runtime/redis` -> Redis AOF
|
||||
|
||||
普通 `docker compose down` 不删除绑定目录;删除 `.runtime` 才会清除本地状态。
|
||||
|
||||
## 发布和在线更新
|
||||
|
||||
发布契约:
|
||||
|
||||
- 发布入口:`release/publish <version>`
|
||||
- 产品版本:`release/version.yaml`
|
||||
- 目标平台:`release/platforms.yaml`
|
||||
- Release workflow:`.github/workflows/release.yml`
|
||||
- `v*` tag 触发 Release
|
||||
- Docker 平台:`linux/amd64`、`linux/arm64`
|
||||
|
||||
Release asset:
|
||||
|
||||
```text
|
||||
codex-proxy-rs_<version>_linux_amd64.tar.gz
|
||||
codex-proxy-rs_<version>_linux_arm64.tar.gz
|
||||
codex-proxy-rs_<version>_darwin_arm64.tar.gz
|
||||
codex-proxy-rs_<version>_windows_amd64.zip
|
||||
checksums.txt
|
||||
```
|
||||
|
||||
GHCR 发布 `<version>` 和 `sha-<git-sha>` tag;只有稳定版本更新 `latest`,预发布版本不得覆盖 `latest`。
|
||||
|
||||
在线更新接口位于 `/api/admin/system/*`,前端入口是
|
||||
`frontend/src/layout/components/SystemUpdateModal.vue`。Docker 环境使用:
|
||||
|
||||
- `CPR_DEPLOYMENT_MODE=docker`
|
||||
- `CPR_UPDATE_REPOSITORY=zyycn/codex-proxy-rs`
|
||||
- `CPR_UPDATE_CHANNEL=stable`
|
||||
- `CPR_UPDATE_TEMP_DIR=/app/.runtime/data/update-tmp`
|
||||
- `CPR_UPDATE_STATE_FILE=/app/.runtime/data/update-state.json`
|
||||
- `CPR_UPDATE_LOCK_FILE=/app/.runtime/data/update.lock`
|
||||
- `CPR_WEB_DIST_DIR=/app/web/dist`
|
||||
- `CPR_ENABLE_SELF_RESTART=true`
|
||||
|
||||
更新会校验 checksum,替换二进制和 `web/dist`,再触发进程重启。文件替换必须保留跨文件系统的 copy-and-remove fallback。
|
||||
|
||||
## 文档边界
|
||||
|
||||
- 根 `README.md` 面向部署者和 API 使用者,只写当前产品能力、部署、配置、持久化、升级和排障。
|
||||
- README 不写内部发布脚本、CI 门禁、审计过程或内测迁移流程。
|
||||
- `docs/` 只保留 `architecture.md`,用于说明当前目录、依赖、请求链路、调度恢复、存储和后台任务。
|
||||
- 维护者专用流程写入本 skill,不新增过程型 Markdown 文档。
|
||||
|
||||
## 验证矩阵
|
||||
|
||||
Rust:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
cargo fmt --check
|
||||
cargo clippy --all-targets --all-features --locked
|
||||
cargo test --test main --locked
|
||||
```
|
||||
|
||||
完整测试需要 PostgreSQL 和 Redis。通过以下变量提供连接:
|
||||
|
||||
```text
|
||||
CPR_TEST_DATABASE_URL
|
||||
CPR_TEST_REDIS_URL
|
||||
```
|
||||
|
||||
使用部署 Compose 时,测试 URL 的密码必须与 `deploy/config.yaml` 一致并正确进行 URL 编码。不要在日志或提交中输出真实密码。
|
||||
|
||||
前端:
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
cargo +1.97.0 fmt --manifest-path backend/Cargo.toml -- --check
|
||||
cargo +1.97.0 clippy --manifest-path backend/Cargo.toml --all-targets --all-features --locked -- -D warnings
|
||||
cargo +1.97.0 test --manifest-path backend/Cargo.toml --locked
|
||||
pnpm --dir frontend format:check
|
||||
pnpm --dir frontend build
|
||||
```
|
||||
|
||||
Compose:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose.yaml config --quiet
|
||||
```
|
||||
|
||||
聚焦测试应使用现有集成测试模块过滤;只有跨模块契约、存储或用户流程变化时才扩大到完整门禁。发布与镜像改动还需核对 `.github/workflows/_quality.yml`、`.github/workflows/_container.yml` 和 `.github/workflows/release.yml`。
|
||||
聚焦改动先运行对应模块。跨领域、存储、生命周期或发布改动执行完整门禁。
|
||||
|
||||
## 项目约束
|
||||
## 发布
|
||||
|
||||
- 新代码和重构不保留兼容别名、临时 shim、重复旧 API 或补丁式旁路。
|
||||
- 不把测试写入 `backend/src`。
|
||||
- 不为 Cargo `target` 添加仓库级重定向;运行时数据和日志放在 `.runtime`。
|
||||
- 已确认且属于当前范围的问题应先修复,再继续后续测试。
|
||||
- README、架构、skill、workflow、Dockerfile 和真实命令必须一致。
|
||||
- UI 保持安静、紧凑的运维控制台风格,避免营销式布局、卡片套卡片和重复说明。
|
||||
- 不创建冗余 Docker 配置、第二套版本源或重复存储路径。
|
||||
- CodeGraph 用于定位;只有后续判断依赖已修改的索引且工具需要手动刷新时才同步索引。
|
||||
1. 更新 `release/version.yaml`。
|
||||
2. 提交版本变更。
|
||||
3. 创建同版本带注释 `vX.Y.Z` tag。
|
||||
4. 原子推送 `main` 与 tag。
|
||||
5. 等待 Release workflow 完成。
|
||||
6. 核对远端 `main`、tag target、GitHub Release、assets 和 GHCR tags。
|
||||
|
||||
Release 包含 Linux amd64/arm64、macOS arm64、Windows amd64;稳定版本更新 GHCR
|
||||
`latest`。在线更新必须验证 checksum,并保留跨文件系统 copy-and-remove fallback。
|
||||
|
||||
@@ -1,108 +1,59 @@
|
||||
---
|
||||
name: engineering-standards
|
||||
description: 面向长期维护的工程规范工作流。当用户要求代码审计、问题修复、重构、实现方案、生产问题追溯,或强调代码质量、干净架构、拒绝垃圾代码、禁止兼容写法、先审计再改代码、参考项目对比时使用。
|
||||
description: 证据优先的长期维护工作流。用于代码审计、问题修复、重构、生产故障、参考项目对比,以及用户强调干净架构、禁止兼容写法、先审计再实现或拒绝代码异味的任务。
|
||||
---
|
||||
|
||||
# 工程规范
|
||||
|
||||
先证明当前系统的真实行为,再决定是否改代码。证据来自当前源码、配置、测试和运行结果。
|
||||
## 证据顺序
|
||||
|
||||
## 证据门禁
|
||||
1. 当前运行结果与可复现输入。
|
||||
2. 当前源码、配置、数据库和日志。
|
||||
3. 当前测试与公开契约。
|
||||
4. 架构文档。
|
||||
5. 记忆和参考项目。
|
||||
|
||||
对非简单行为变更,动代码前在内部确认:
|
||||
后两项只能辅助定位,不能覆盖当前事实。
|
||||
|
||||
1. 现有机制:入口、调用链、数据变化、持久化、读取和展示路径。
|
||||
2. 缺口证据:已经证明的断点及对应源码位置。
|
||||
3. 改动边界:在现有所有权模型中负责修复该问题的最小边界。
|
||||
## 工作流
|
||||
|
||||
不强制向用户输出固定模板。根据任务复杂度,用简短进度或审计结论说明关键证据。简单文案、格式或明确的机械修改只需检查受影响文件并直接完成。
|
||||
1. 追踪入口、调用链、状态变化、持久化、读取和输出。
|
||||
2. 区分展示、接口、领域规则、存储、异步任务和外部依赖。
|
||||
3. 找到现有 owner,证明断点位于该边界。
|
||||
4. 在 owner 内直接修复;必要重构必须减少分支或重复职责。
|
||||
5. 通过公开接口或外置集成测试固定行为。
|
||||
6. 运行项目既定格式、lint 和相关测试,再检查最终 diff。
|
||||
|
||||
在现有链路被追完并证明不足之前,不引入新的机制、分支或旁路绕开问题。
|
||||
简单文案和机械修改直接完成,不套审计模板。结论先行,只报告影响判断的证据。
|
||||
|
||||
## 审计流程
|
||||
## 实现约束
|
||||
|
||||
以当前仓库的实时源码为唯一事实来源。当前链路清楚后,才使用记忆或参考项目补充判断。
|
||||
|
||||
1. 确认用户讨论的数据或行为。
|
||||
2. 追踪它在哪里产生、转换、持久化、加载和展示。
|
||||
3. 同时检查主动链路和被动链路。运行时行为分别确认触发条件、执行路径、持久化、读取和展示。
|
||||
4. 分类问题所在边界:
|
||||
- 展示层
|
||||
- 接口契约
|
||||
- 持久化层
|
||||
- 运行时行为
|
||||
- 外部依赖
|
||||
- 异步或周期任务
|
||||
5. 说明支持分类的证据,以及仍未证明的部分。
|
||||
6. 排查中发现旁支问题时先记录证据。确认属于当前范围的,修复后再继续测试;与任务无关的只在结尾报告,不擅自扩大改动。只有无法从用户目标判断范围时才询问。
|
||||
|
||||
存在 CodeGraph 时可先用它定位,再回到源码和测试验证。不要把索引摘要、记忆或参考项目当成强于当前源码的证据。
|
||||
- 不添加兼容 shim、重复 API、双状态机或临时旁路。
|
||||
- 不用大范围重构掩盖尚未理解的问题。
|
||||
- 不为局部问题修改无关模块。
|
||||
- 不在没有复用或所有权收益时增加抽象。
|
||||
- 用户只要求审计、文档或方案时,不扩大到实现。
|
||||
- 已确认且属于当前范围的问题,先修复再继续测试。
|
||||
- 测试遵守仓库目录边界,不混入生产源码。
|
||||
- 行为语义变化应在修改前明确说明。
|
||||
|
||||
## 参考项目
|
||||
|
||||
参考项目只用于理解可能的模式。除非同时满足以下条件,否则不把参考实现搬进当前项目:
|
||||
只有同时满足以下条件才采用参考实现:
|
||||
|
||||
1. 当前项目确实缺少所需行为。
|
||||
2. 当前架构存在匹配的所有权边界。
|
||||
3. 新设计不会绕开或复制现有链路。
|
||||
4. 当前任务范围允许实现。
|
||||
1. 当前项目已证明缺少该行为。
|
||||
2. 当前架构存在匹配 owner。
|
||||
3. 不会复制现有链路。
|
||||
4. 用户授权的范围包含实现。
|
||||
|
||||
参考项目与当前源码冲突时,以当前源码为准。
|
||||
|
||||
## 干净实现
|
||||
|
||||
优先在现有所有权边界内完成直接修复。
|
||||
|
||||
- 除非用户明确要求,不添加兼容代码。
|
||||
- 不用补丁式分支、重复机制或外层绕路掩盖边界问题。
|
||||
- 不用大范围重构掩盖不确定性。
|
||||
- 不为局部问题修改无关模块。
|
||||
- 只有确实降低复杂度或符合现有模式时才添加抽象。
|
||||
- 必要重构必须收敛职责、减少分支并让主链路更清楚。
|
||||
- 未证明现有设计不足时,不引入第二条执行路径。
|
||||
|
||||
方案改变行为语义时,动代码前明确说明影响。
|
||||
|
||||
## 范围纪律
|
||||
|
||||
- 简单问题先给结论。
|
||||
- 审计给出具体源码证据。
|
||||
- 不做推测性断言,不虚构事实、数据来源或系统行为。
|
||||
- 新项目和新链路不保留无意义兼容路径。
|
||||
- 仓库约定测试目录时,不把测试写入源码模块。
|
||||
- 用户限定为审计、文档、评审或方案时,只交付对应产物。
|
||||
- 用户要求直接修复且范围清楚时,不用重复确认阻断执行。
|
||||
|
||||
## 动代码前
|
||||
|
||||
非简单行为变更应满足:
|
||||
|
||||
1. 当前链路已经端到端追完。
|
||||
2. 问题已按证据分类。
|
||||
3. 已证明现有机制不能满足需求,而不是尚未找到。
|
||||
4. 改动落在最小的干净所有权边界。
|
||||
5. 测试通过公开接口或集成测试面覆盖行为。
|
||||
|
||||
缺少任一项时继续调查。简单机械修改不需要套用完整审计流程,但仍要检查目标文件、相邻约束和最终差异。
|
||||
参考代码用于验证机制,不用于替代当前项目证据。
|
||||
|
||||
## 收尾
|
||||
|
||||
结束前确认:
|
||||
交付只包含:
|
||||
|
||||
1. 运行格式化和相关测试。
|
||||
2. 运行项目既定 lint。
|
||||
3. 没有把测试加入错误目录。
|
||||
4. 没有用参考项目取代当前项目证据。
|
||||
5. 没有未经批准引入额外分支、旁路或兼容实现。
|
||||
6. 只有后续判断依赖已改动索引且工具要求手动刷新时,才同步 CodeGraph。
|
||||
7. 汇报改动、验证结果和明确未做的事项。
|
||||
- 已改变的行为与边界。
|
||||
- 能证明结果的验证。
|
||||
- 明确未做或仍受外部状态阻塞的事项。
|
||||
|
||||
## 禁止的做法
|
||||
|
||||
1. 只看局部触发点就断言完整系统行为。
|
||||
2. 没追完已有链路就新增另一套机制。
|
||||
3. 没证明现有机制失败就设计旁路。
|
||||
4. 直接照搬参考项目,跳过当前源码证据。
|
||||
5. 用兼容 shim、重复 API 或生命周期补丁掩盖所有权问题。
|
||||
|
||||
正确顺序是:追清现有链路,证明断点,选择所有权边界,完成干净修复,再用真实测试验证。
|
||||
禁止把排查时间线、空洞原则或未证实猜测包装成深度。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
interface:
|
||||
display_name: "工程规范"
|
||||
short_description: "长期维护的工程规范:证据优先、范围纪律、干净实现与审计工作流。"
|
||||
default_prompt: "使用 $engineering-standards 按工程规范先审计当前代码链路,再提出或实现干净修复。"
|
||||
short_description: "证据优先、边界清晰、拒绝兼容旁路的长期工程维护工作流"
|
||||
default_prompt: "使用 $engineering-standards 追清当前链路,并在唯一所有权边界内完成干净修复。"
|
||||
|
||||
Reference in New Issue
Block a user