mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
docs: clarify setup and current contracts
Document one-click installation, consolidate manual deployment instructions, and describe current API and architecture contracts. Keep applicable configuration and upgrade guidance without recording implementation history. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -25,59 +25,48 @@
|
||||
以下命令适用于 Linux amd64/arm64,需要 Docker Engine、Docker Compose Plugin、curl 和 OpenSSL。已有部署请先看
|
||||
[升级说明](deploy/README.md#镜像升级与源码构建),不要覆盖原配置。
|
||||
|
||||
### 1. 下载部署文件并配置
|
||||
### 一键安装
|
||||
|
||||
请确保当前用户能访问 Docker,并可通过 `sudo` 或 root 设置目录权限。
|
||||
|
||||
```bash
|
||||
mkdir -p codex-proxy-rs/deploy && cd codex-proxy-rs
|
||||
|
||||
# 只解析一次最新正式版本,确保两个文件来自同一 Release。
|
||||
CPR_RELEASE_URL="$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/zyycn/codex-proxy-rs/releases/latest)"
|
||||
CPR_RELEASE_TAG="${CPR_RELEASE_URL##*/}"
|
||||
curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/compose.yaml" \
|
||||
-o deploy/compose.yaml
|
||||
curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/config.example.yaml" \
|
||||
-o deploy/config.example.yaml
|
||||
|
||||
install -d -m 0750 .runtime/postgres .runtime/redis
|
||||
sudo install -d -m 0770 -o "$(id -u)" -g 10001 .runtime/data .runtime/logs
|
||||
sudo install -m 0640 -o "$(id -u)" -g 10001 deploy/config.example.yaml deploy/config.yaml
|
||||
curl -fsSL https://raw.githubusercontent.com/zyycn/codex-proxy-rs/main/deploy/install.sh -o install.sh && bash install.sh
|
||||
```
|
||||
|
||||
也可将 `CPR_RELEASE_TAG` 设置为指定的发布标签。Release 附带的 `compose.yaml` 默认使用该版本镜像,
|
||||
配置模板和部署文件均包含在 `checksums.txt` 中;不要混用 `main` 分支模板与已发布镜像。
|
||||
[安装脚本](deploy/install.sh) 默认安装到当前目录下的 `codex-proxy-rs/`,下载同一正式 Release 的部署文件,
|
||||
自动生成密码、设置目录权限并启动服务。完成后会显示访问地址和管理员密码,请保存密码,再按下方步骤
|
||||
[添加账号与客户端密钥](#添加账号与客户端密钥)。
|
||||
|
||||
分别生成数据库和 Redis 密码:
|
||||
可在执行 `bash install.sh` 时传入环境变量:
|
||||
|
||||
| 变量 | 用途 | 默认值 |
|
||||
| --- | --- | --- |
|
||||
| `INSTALL_DIR` | 安装目录,建议使用绝对路径 | 当前目录下的 `codex-proxy-rs/` |
|
||||
| `CPR_RELEASE_TAG` | 指定发布标签 | 最新正式版本 |
|
||||
| `ADMIN_PASSWORD` | 管理员初始密码,至少 12 位,不能包含 `$`,不能使用常见弱口令 | 随机生成 |
|
||||
|
||||
例如,自定义安装目录:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 24
|
||||
openssl rand -hex 24
|
||||
INSTALL_DIR="$HOME/services/codex-proxy-rs" bash install.sh
|
||||
```
|
||||
|
||||
编辑 `deploy/config.yaml`,填好以下三项:
|
||||
重复运行时请使用同一安装目录。检测到 `deploy/config.yaml` 后,脚本保留现有配置和部署文件,
|
||||
忽略传入的管理员密码,也不执行版本升级。
|
||||
|
||||
| 配置项 | 填写内容 |
|
||||
| --- | --- |
|
||||
| `store.database.password` | 第一个生成的 48 位十六进制密码 |
|
||||
| `store.redis.password` | 第二个生成的 48 位十六进制密码 |
|
||||
| `admin.default_password` | 管理员初始密码,至少 12 位,不能包含 `$` |
|
||||
### 手动安装
|
||||
|
||||
### 2. 启动服务
|
||||
自行下载部署文件、配置密码和启动服务的完整步骤见 [部署文档](deploy/README.md#手动安装)。
|
||||
|
||||
```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 --wait
|
||||
curl -i http://127.0.0.1:8080/healthz
|
||||
```
|
||||
### 登录管理端
|
||||
|
||||
健康检查返回 `204 No Content` 后,打开 `http://127.0.0.1:8080`,
|
||||
使用 `admin@cpr.local` 和刚设置的管理员密码登录。
|
||||
部署完成后,打开 `http://127.0.0.1:8080`,使用 `admin@cpr.local` 和管理员密码登录。
|
||||
API Key 持有者可在同一登录页切换登录身份,进入 `/key-usage` 查看自己的用量、趋势、请求日志、额度与健康时间线;不能访问管理员页面。
|
||||
|
||||
默认地址只能在服务器本机访问。从其他设备使用时,需要配置
|
||||
[HTTPS 反向代理](deploy/README.md#公网访问)。
|
||||
|
||||
### 3. 添加账号与客户端密钥
|
||||
### 添加账号与客户端密钥
|
||||
|
||||
1. 在「账号」中添加账号,完成授权或导入。
|
||||
2. 按需建立账号分组,再创建客户端密钥并选择可用分组。**不选分组表示可使用全部账号**。
|
||||
|
||||
+39
-18
@@ -11,17 +11,36 @@
|
||||
|
||||
项目不使用 `.env` 配置文件。Compose 环境变量用于容器地址、镜像选择和构建发布;
|
||||
应用设置与凭据保存在 `config.yaml` 中。已有部署不要重新复制模板覆盖配置。
|
||||
配置加载会忽略未知或已移除的字段,并在启动控制台提示字段名;不输出对应值。缺少必填字段时会指出缺项并停止启动,
|
||||
已知字段的类型和取值仍需合法;可选字段省略时使用默认值。
|
||||
|
||||
## 准备
|
||||
## 手动安装
|
||||
|
||||
按快速开始下载部署文件后,从安装目录执行:
|
||||
本节适用于 Linux amd64/arm64,需准备 Docker Engine、Docker Compose Plugin、curl 和 OpenSSL,
|
||||
并确保当前用户能访问 Docker、可通过 `sudo` 或 root 设置目录权限。一键安装入口见
|
||||
[快速开始](../README.md#一键安装),脚本会自动完成本节准备和服务启动。
|
||||
|
||||
下载同一正式 Release 的部署文件并设置目录权限:
|
||||
|
||||
```bash
|
||||
mkdir -p codex-proxy-rs/deploy && cd codex-proxy-rs
|
||||
|
||||
# 只解析一次最新正式版本,确保两个文件来自同一 Release。
|
||||
CPR_RELEASE_URL="$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/zyycn/codex-proxy-rs/releases/latest)"
|
||||
CPR_RELEASE_TAG="${CPR_RELEASE_URL##*/}"
|
||||
curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/compose.yaml" \
|
||||
-o deploy/compose.yaml
|
||||
curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/config.example.yaml" \
|
||||
-o deploy/config.example.yaml
|
||||
|
||||
install -d -m 0750 .runtime/postgres .runtime/redis
|
||||
sudo install -d -m 0770 -o "$(id -u)" -g 10001 .runtime/data .runtime/logs
|
||||
sudo install -m 0640 -o "$(id -u)" -g 10001 deploy/config.example.yaml deploy/config.yaml
|
||||
```
|
||||
|
||||
也可将 `CPR_RELEASE_TAG` 设置为指定的发布标签。Release 附带的 `compose.yaml` 默认使用该版本镜像,
|
||||
配置模板和部署文件均包含在 `checksums.txt` 中;不要混用 `main` 分支模板与已发布镜像。
|
||||
|
||||
为 PostgreSQL 与 Redis 分别生成一个密码:
|
||||
|
||||
```bash
|
||||
@@ -56,8 +75,7 @@ Linux 上应用容器以 `10001:10001` 运行。上述命令将应用数据和
|
||||
该设置统一 OpenAI Responses 的 Web Search 位置与带来源标记的环境日期、时区,不修改 epoch 时间戳、
|
||||
真实出口 IP 或服务系统时区。字段约束见 [运行设置](../docs/api.md#8-运行设置)。
|
||||
|
||||
`config.yaml` 不再接受 `openai.wire_profile.location`。升级时将原有自定义值填写到管理端全局设置并开启开关,
|
||||
并从配置文件删除该项;数据库初始化不会从配置文件自动导入旧值。
|
||||
请求位置由管理端设置,数据库初始化不从 `config.yaml` 导入位置值。
|
||||
|
||||
## 启动
|
||||
|
||||
@@ -158,8 +176,8 @@ goals = true
|
||||
}
|
||||
```
|
||||
|
||||
这份文件可以保留,用于兼容已有客户端和 CCSwitch。新配置从 `experimental_bearer_token`
|
||||
读取代理密钥,不会因为仅含 API Key 的 `auth.json` 存在而关闭生图。
|
||||
使用 `auth.json` 读取密钥的客户端或 CCSwitch 可保留这份文件。上述 Provider 配置从
|
||||
`experimental_bearer_token` 读取代理密钥,可与仅含 API Key 的 `auth.json` 共存。
|
||||
真实 OpenAI OAuth 账号文件用于管理端账号导入,不要当作代理配置分发给客户端。
|
||||
|
||||
### 生图和 WebSocket
|
||||
@@ -169,14 +187,13 @@ goals = true
|
||||
需要支持该能力的客户端、支持图片输入的对话模型,以及有生图权限和额度的 OpenAI 账号。
|
||||
代理不会增加上游权限,xAI 账号不能承接这些 Images 请求。
|
||||
|
||||
本项目已用 Codex CLI 0.153.4 验证过原生生图,这不是最低支持版本声明。
|
||||
生图不要求开启 WebSocket。要启用客户端 WebSocket,把当前 Provider 的
|
||||
`supports_websockets` 改为 `true`,并检查反向代理是否允许 Upgrade。
|
||||
|
||||
客户端到代理、代理到上游是两段独立连接。客户端关闭 WebSocket 后,
|
||||
服务端仍可能用 WebSocket 访问上游;客户端开关不控制服务端连接池和 HTTP 回退策略。
|
||||
|
||||
### 旧版配置
|
||||
### 客户端配置兼容
|
||||
|
||||
仅含代理密钥的 `auth.json` 配合 `requires_openai_auth = true` 仍可用于已有请求,
|
||||
但 API Key 登录本身不会启用原生生图。需要生图时换用上述 Provider 配置。
|
||||
@@ -268,7 +285,7 @@ OpenAI 主动额度重置卡及其消费结果由上游持有,不写入 Postgr
|
||||
文件名统一为 `codex-proxy-rs-<类别>.YYYY-MM-DD[.N].log[.gz]`,类别分别为
|
||||
`application`、`oauth-recovery`、`request-dump`。专用 tracing target 为 `oauth_recovery` 和
|
||||
`request_dump`;普通日志保留各 Rust 模块的 target,便于按模块过滤。
|
||||
程序只管理上述规范名称的日志,旧命名文件由运维手动清理。
|
||||
程序只管理上述规范名称的日志,其他命名的文件由运维手动清理。
|
||||
普通日志未配置 `retention_days` 时默认使用 7 天,显式配置优先。
|
||||
|
||||
按 UTC 日期整组保留:例如 9 月 8 日配置 1 天,会保留 9 月 7 日全天及 9 月 8 日的所有分片,
|
||||
@@ -278,13 +295,12 @@ OpenAI 主动额度重置卡及其消费结果由上游持有,不写入 Postgr
|
||||
关闭的分片压缩为 `.log.gz`;成功压缩、同步并发布归档后才删除原文件,保留原修改时间。
|
||||
清理发生在启动和轮转时;空闲期间过期文件可能暂时多保留。检索时须同时读取 `.log` 与 `.log.gz`。
|
||||
|
||||
升级旧配置时删除 `host.logging.file.max_files`;该字段已移除,旧配置会校验失败而不会继续按数量删日志。
|
||||
报文开关仍为 `host.logging.request_dump`,默认关闭;开启时原始报文按块完整写入独立文件,
|
||||
报文开关为 `host.logging.request_dump`,默认关闭;开启时原始报文按块完整写入独立文件,
|
||||
数据库请求诊断仍是有界摘要,不能用摘要事件数代替全量报文完整性。
|
||||
|
||||
文件写入使用有界队列背压,正常退出会排空队列并同步文件。`file_logging` 健康探针在写入/同步失败后
|
||||
报告 `Unhealthy`,本次进程内恢复写入也不会清除已有缺口;压缩或清理失败报告 `Degraded`。
|
||||
这不是断电、强杀或磁盘故障下的零丢失承诺;已删除的历史文件也不能靠升级恢复。
|
||||
断电、强杀或磁盘故障可能造成日志丢失;需要恢复已删除文件时,应使用独立备份。
|
||||
容量不足时不会提前删除保留窗口内日志,必须根据完整日期的压缩后实际用量规划空间,并监控磁盘余量和
|
||||
健康探针。Docker stdout 的独立轮转不承担应用文件日志的完整保留承诺。
|
||||
|
||||
@@ -343,6 +359,14 @@ OpenAI 主动额度重置卡及其消费结果由上游持有,不写入 Postgr
|
||||
升级时先阅读目标版本说明,下载同一 Release 的部署附件,对比模板并合并必要配置,保留已有凭据
|
||||
和 Compose 自定义项。不要用模板覆盖 `config.yaml`,也不要从 `main` 下载模板搭配旧镜像。
|
||||
|
||||
按现有配置和接入方式检查以下升级条件:
|
||||
|
||||
| 适用条件 | 升级操作 |
|
||||
| --- | --- |
|
||||
| `config.yaml` 含 `openai.wire_profile.location` | 该字段会被忽略,可删除;如需继续覆盖请求位置,将值填入管理端全局请求位置并开启开关,数据库初始化不会自动导入 |
|
||||
| `config.yaml` 含 `host.logging.file.max_files` | 该字段会被忽略,可删除;日志按 `retention_days` 保留,`max_file_size_mb` 只控制分片大小 |
|
||||
| 使用旧管理员认证接口或 Cookie | 改用 `/api/auth/*` 并重新登录;会话合同见 [认证 API](../docs/api.md#4-浏览器认证) |
|
||||
|
||||
更新部署文件后,从安装目录拉取目标版本镜像并重建应用容器:
|
||||
|
||||
```bash
|
||||
@@ -357,12 +381,9 @@ docker compose -f deploy/compose.yaml build codex-proxy-rs
|
||||
docker compose -f deploy/compose.yaml up -d --no-build --wait
|
||||
```
|
||||
|
||||
源码提交、仓库发版和运行实例升级是三种独立状态:本地 commit 不等于 Release,Release/tag 和镜像
|
||||
已生成也不等于实例已升级。判断某项修复是否在线前,应先通过管理端版本接口或容器 image digest
|
||||
确认运行实例的实际 revision;实例只有在执行上面的 Compose pull/up,或成功完成管理端在线更新后
|
||||
才会改变。
|
||||
升级后通过管理端版本接口或容器 image digest 确认运行实例的版本和 revision。
|
||||
|
||||
构建元数据仍可作为一次性进程环境传入,不需要 `.env` 文件:
|
||||
构建元数据通过一次性进程环境传入:
|
||||
|
||||
```bash
|
||||
CPR_VERSION="$(ruby -ryaml -e 'puts YAML.load_file("release/version.yaml").fetch("version").delete_prefix("v")')" \
|
||||
@@ -373,7 +394,7 @@ docker compose -f deploy/compose.yaml build codex-proxy-rs
|
||||
|
||||
### 管理端在线更新
|
||||
|
||||
Compose 已显式装配正式发布构建所需的运行参数:
|
||||
Compose 提供以下在线更新运行参数:
|
||||
|
||||
- `CPR_UPDATE_REPOSITORY`:只接受 `owner/repository`;默认 `zyycn/codex-proxy-rs`。
|
||||
- `CPR_GITHUB_API_BASE`:正式环境必须为 `https://api.github.com/repos`。
|
||||
|
||||
+20
-23
@@ -157,7 +157,7 @@ Codex 的 review 等子代理请求仍使用 `/v1/responses`,并通过 `x-open
|
||||
`deflate`(zlib 封装)和 `zstd`,缺省、空值或 `identity` 直接使用原始正文。gzip 多成员与 zstd
|
||||
多帧连续解码,整体展开结果最多 64 MiB,超限在继续展开前返回 `400 request_too_large`;zstd
|
||||
回溯窗口同样最多 64 MiB,不能满足该限制的帧按解码失败处理。这个限制保护入站解压资源,不是
|
||||
模型上下文或 Token 上限,也不新增未压缩正文的长度限制。
|
||||
模型上下文或 Token 上限;未压缩正文不受此长度限制。
|
||||
不支持的编码、逗号分隔的叠加编码和重复 `Content-Encoding` 头返回
|
||||
`400 unsupported_content_encoding`;压缩正文损坏、截断或解压后不是合法 JSON 返回
|
||||
`400 invalid_json`。本地错误不包含原始正文或解压库细节。WebSocket 文本帧不经过这条解压路径。
|
||||
@@ -170,22 +170,21 @@ API Key 上游还会移除 Cookie、ChatGPT 账号身份、`x-codex-*`、`x-open
|
||||
`X-OpenAI-Actor-Authorization`,避免把 OAuth 或网关托管身份传给第三方 API。
|
||||
|
||||
Responses 也不透传 `x-stainless-*`、`Origin`、`Referer`、`sec-ch-ua*` 和 `sec-fetch-*`
|
||||
携带的下游 SDK/浏览器环境或页面来源。兼容基准是 Codex Core/Desktop 请求协议;
|
||||
OpenAI 官方 SDK 也会发送 `x-stainless-*`,浏览器字段也有标准定义,过滤不表示这些头非法。
|
||||
规则不依赖下游 User-Agent,也不改变原始入站请求供 CORS、鉴权和本地观测使用的字段。
|
||||
`session_id` 请求头仅作为入站会话别名,提取后不再原样透传,上游通过 `session-id` 表达;
|
||||
携带的下游 SDK/浏览器环境或页面来源。过滤规则适用于所有下游客户端,与 User-Agent 无关;
|
||||
原始入站头仍供 CORS、鉴权和本地观测使用。
|
||||
`session_id` 请求头仅作为入站会话别名,上游通过 `session-id` 表达;
|
||||
两者同时存在时仍优先使用 `session-id`。正文中的 `client_metadata.session_id`、
|
||||
`prompt_cache_key` 不受这条请求头规则影响。
|
||||
`thread-id`、turn metadata 等 Codex 协议字段及未知业务扩展继续按既有合同处理;
|
||||
`thread-id`、turn metadata 等 Codex 协议字段及未知业务扩展不受下游环境头过滤规则影响;
|
||||
`traceparent`、`tracestate` 不因属于追踪字段而被删除。
|
||||
|
||||
Responses 上游编码会移除 Codex 不接受的顶层 `temperature`、`max_output_tokens` 和
|
||||
`prompt_cache_retention`;这些参数可能来自 Pi 等客户端的普通 OpenAI Responses 适配。
|
||||
`prompt_cache_retention`。
|
||||
`prompt_cache_key`、`reasoning`、`include` 等 Codex 参数继续保留。过滤只作用于顶层,
|
||||
不删除工具参数 schema、输入内容或 `client_metadata` 内的同名业务字段;其他未知字段继续透传。
|
||||
|
||||
这不是客户端匿名化:系统提示词、工具定义、工具结果、工作目录及其他业务 metadata 仍可能
|
||||
透露客户端环境,网关不对正文做客户端品牌清洗。
|
||||
请求头过滤不提供客户端匿名化;系统提示词、工具定义、工具结果、工作目录及其他业务 metadata
|
||||
保持原有语义,可能包含客户端环境信息。
|
||||
|
||||
Responses WebSocket 仅接受文本 `response.create`,同一连接串行执行。当前响应期间收到的后续业务帧
|
||||
留在有界接收队列中,待当前响应完成终结和写出后再逐条校验、准入与执行,不因请求提前到达而断开。
|
||||
@@ -196,7 +195,7 @@ OAuth 账号在客户端使用 HTTP/SSE 时仍可能选择上游 WebSocket。API
|
||||
客户端配置的 `supports_websockets` 只控制第一段连接,不是服务端传输策略开关。
|
||||
上游在响应终态前发送 Close 1000 仍属于失败,不能按“正常关闭”计为成功。
|
||||
|
||||
已建立模型执行的 Responses、Images 和 Search HTTP 响应使用现有 ID:
|
||||
已建立模型执行的 Responses、Images 和 Search HTTP 响应按以下规则返回关联 ID:
|
||||
`x-gateway-request-id` 为模型执行 ID;`x-request-id` 保留有效上游值,只有上游
|
||||
`x-oai-request-id` 时复用其值,没有上游 ID 时使用模型执行 ID。`x-oai-request-id` 不是必需字段,
|
||||
也不要求客户端识别它;OpenAI 与 xAI 路由使用相同规则。失败响应的关联 ID 不采用会话 opening ID,
|
||||
@@ -253,12 +252,12 @@ Responses wire 之间的协议转换层,转换只在 xAI Provider 内完成。
|
||||
OpenAI 明确返回 `server_is_overloaded`、`slow_down` 或模型容量不足错误时,代理在允许安全重放且
|
||||
尚未交付输出的前提下,先做最多 3 次同账号指数退避,再通过现有调度换号。默认间隔从 500ms 开始,
|
||||
上游 `Retry-After` 参与退避计算,单次等待不超过 8 秒;重试同时受请求总尝试次数和截止时间约束。
|
||||
`server_is_overloaded`、`slow_down` 与既有可计分的结构化错误按已发送的失败尝试计入 Smart 账号
|
||||
健康分;容量分类不再豁免计分。失败率沿用账号级平滑与时间衰减,影响后续普通选路,已有可用账号的
|
||||
`server_is_overloaded`、`slow_down` 等可计分的结构化错误按已发送的失败尝试计入 Smart 账号
|
||||
健康分。失败率使用账号级平滑与时间衰减,影响后续普通选路,已有可用账号的
|
||||
会话亲和仍优先。容量不足不触发 Provider 全局熔断,也不作为账号额度耗尽;启用账号自动冻结时,
|
||||
达到容量失败阈值会另外写入临时冷却。
|
||||
最终交付的上游错误仍按上述透明边界保留原始状态码、错误码和正文。
|
||||
明确额度耗尽继续走现有账号隔离与安全换号流程,
|
||||
明确额度耗尽触发账号隔离与安全换号,
|
||||
包括 WebSocket 握手返回的 429;不会因其长 `Retry-After` 而转入同账号传输恢复等待。
|
||||
|
||||
## 4. 浏览器认证
|
||||
@@ -280,14 +279,12 @@ OpenAI 明确返回 `server_is_overloaded`、`slow_down` 或模型容量不足
|
||||
未登录时为 `{ authenticated: false, session: null }`。`role` 由服务端已验证身份推导,不接受客户端声明。
|
||||
不返回凭据或绑定 ID。
|
||||
|
||||
Redis 统一保存身份(管理员 ID 或 Client Key ID)和绝对有效期,不保存密码或原始 Key。
|
||||
使用 `auth:v1` 命名空间,Cookie 属性为 `Path=/; HttpOnly; SameSite=Lax`,`Max-Age` /
|
||||
会话由服务端保存,Cookie 属性为 `Path=/; HttpOnly; SameSite=Lax`,`Max-Age` /
|
||||
`Expires` 对齐固定有效期,`Secure` 沿用上述 Origin 规则。轮询不会续期。
|
||||
管理员有效期由 `admin.session_ttl_minutes` 控制;密钥有效期由 `client.session_ttl_minutes` 控制,默认 1440 分钟。
|
||||
|
||||
每次恢复密钥会话时重新确认 Key 存在且启用;停用或删除后会话失效,重新启用不会恢复已撤销会话。
|
||||
依赖不可用时返回 503,不返回已认证或假装未登录。预算耗尽不妨碍登录。
|
||||
原有管理员认证路由和 Cookie 不再接受,升级后需要重新登录。
|
||||
|
||||
密钥会话访问管理接口返回 403,不清除仍然有效的会话。
|
||||
浏览器会话不能替代 `/v1/*` 的 Bearer Key,数据面 Key 也不能替代浏览器会话。
|
||||
@@ -502,8 +499,8 @@ OAuth 等待回调期间不持有保护;提交仍拒绝已删除、连接配
|
||||
管理端通过后台任务导入账号,关闭页面不会取消执行。`submissionId` 为客户端生成的 UUID;同一管理员在任务记录
|
||||
保留期间使用相同标识和相同输入重新提交,会返回已有任务,内容改变则返回 409。修改输入须使用新标识。
|
||||
|
||||
每个任务接受 1–200 个 `items`,请求体上限为 4 MiB。每个条目沿用下节的 Provider 文档与设置合同,独立调用
|
||||
凭据准备、校验、事务提交与快照发布流程。批量 AT / RT 由前端按非空输入顺序拆成单账号条目,因此可逐条统计;
|
||||
每个任务接受 1–200 个 `items`,请求体上限为 4 MiB。每个条目遵循下节的 Provider 文档与设置合同,独立处理
|
||||
并返回结果。批量 AT / RT 按非空输入顺序拆成单账号条目,因此可逐条统计;
|
||||
JSON 文件按 Provider 文档分项,不拆解内部代理引用或改变 Provider 对文档的原子性与部分成功语义。
|
||||
一个文档可导入多个账号,条目成功数与入库账号数可能不同。
|
||||
|
||||
@@ -513,10 +510,10 @@ JSON 文件按 Provider 文档分项,不拆解内部代理引用或改变 Prov
|
||||
列表返回 `{ items: [摘要] }`。结果未知时保留 `unknown`,先核对账号目录再决定是否重新导入;服务端不自动重试凭据交换。
|
||||
停止请求可重复调用,已结束的任务保持原结果;未知、已过期或其他管理员的任务 ID 返回 404。
|
||||
|
||||
任务仅保存在单实例进程内,不新增数据库表,也不使用 Redis 保存任务。所有后台导入共享 3 个执行槽位;
|
||||
所有后台导入共享 3 个执行槽位;
|
||||
最多接受 8 个未结束任务、保留 100 个任务,达到上限返回 429。成功、失败或跳过后立即释放对应输入,
|
||||
终态结果保留 1 小时后自动清理。服务重启会丢失任务与未执行输入,已提交的账号不受影响;
|
||||
重新打开页面从服务端恢复当前管理员的任务列表,前端不持久化任务 ID 或凭据。
|
||||
任务记录仍在保留期内时,可通过列表接口查询当前管理员的任务及进度。
|
||||
|
||||
### 账号导入与 OAuth
|
||||
|
||||
@@ -1144,10 +1141,10 @@ OpenAI Responses 用量记录的 `serviceTier` 与本地费用估算统一采用
|
||||
计算,托管工具调用费不随 Token 档位倍增。
|
||||
Provider metadata 分别保留 `requestedServiceTier` 与 `upstreamServiceTier` 供诊断;发送给客户端的
|
||||
原始 `response.service_tier` 不变。用量中的 Fast 仅表示发送档位,不能证明上游实际加速,本地费用
|
||||
估算也不能代替官方账单。该口径仅作用于新记录,不回填历史档位或重算已存储费用。
|
||||
估算也不能代替官方账单。档位与费用在请求记录生成时确定;查询不会回填历史档位或重算已存储费用。
|
||||
|
||||
本地计价规则只保留尚在服务的型号;已过官方关闭日期的型号不再新增本地估价。清理计价规则不删除或
|
||||
重新计算已存储的历史费用;缺少当前计价规则时,历史总额仍保留,但无法再据此补充费用拆分。
|
||||
本地计价规则覆盖尚在服务的型号。已关闭型号或缺少计价规则时,不生成新的本地估价;已存储的历史费用
|
||||
保留原值,但缺少规则时无法补充费用拆分。
|
||||
|
||||
## 11. 版本、更新与重启
|
||||
|
||||
|
||||
+9
-11
@@ -116,18 +116,18 @@ flowchart LR
|
||||
|
||||
`event` 通过 `validation` / `upstream` 使用基础值,不依赖承载原始事件的执行错误;账号值对象和
|
||||
选择策略通过 `identity` / `account::scope` 使用身份与范围,不依赖路由计划。`routing` 和 `error` 的
|
||||
既有公开类型路径保留 re-export,定义与 Core 内部使用均归属上述 owner。架构测试约束这些叶子依赖。
|
||||
相关公开类型通过 re-export 引用上述定义,类型所有权和 Core 内部依赖归属定义模块。架构测试约束这些叶子依赖。
|
||||
|
||||
Provider 模型能力、目录代次与 `ProviderCatalogPort` 由 `routing::catalog` 定义。快照编译和对账只消费
|
||||
该只读合同,不反向依赖执行注册表;现有 `ProviderRegistry` 直接实现目录端口,仍只维护一份 Provider
|
||||
该只读合同,不反向依赖执行注册表;`ProviderRegistry` 实现目录端口,维护唯一的 Provider
|
||||
注册集合。已知空目录与查询失败的未知目录保持不同语义,目录替身无需实现请求执行。
|
||||
|
||||
客户端原生模型目录同样由 Provider 拥有,通过 `ExecutionService` 和现有 Registry 的只读调用传递。
|
||||
`routing::catalog` 的原生条目只包含模型 ID 与不透明协议正文,Core 负责冻结账号范围和整对象模型映射,
|
||||
不解析上游字段;API 负责协议输出,不直接依赖具体 Provider。原生目录失败不会退回通用画像,只有不提供
|
||||
该协议原生目录的 Provider(如 xAI 的 Codex 适配)才走画像转换。目录读取不创建计量请求或推理 attempt。
|
||||
OpenAI 的账号/凭据 revision/客户端版本隔离、并发合并、TTL、容量与失效均归属已有 credential catalog
|
||||
service;客户端原生对象只进有界进程缓存,不扩展套餐 Redis ID cache 或持久化模型字段副本。
|
||||
OpenAI 的账号/凭据 revision/客户端版本隔离、并发合并、TTL、容量与失效均归属 credential catalog
|
||||
service;客户端原生对象保存在有界进程缓存中,与套餐 Redis 模型 ID 缓存分开管理。
|
||||
|
||||
全局请求位置及开关由运行设置持久化;快照仅在开关开启时生成全局覆盖,并随
|
||||
`RuntimeSnapshot → RoutingPlan → AttemptContext` 冻结传递,关闭时保留客户端原有字段;
|
||||
@@ -196,15 +196,13 @@ OpenAI 的 OAuth 与 API Key 共用现有账号和事务。API Key 的 Base URL
|
||||
上游用户 ID 推断可用性;OAuth 未完成身份投影时由 Provider 保持 `unknown`。状态恢复和未补齐身份的凭据轮换保留 `unknown`。
|
||||
API Key 默认 HTTP/SSE,可选 WS 优先;选号先验证传输资格,WS pool 与 continuation 按凭据版本隔离。
|
||||
|
||||
|
||||
- OpenAI 是透明边界。Responses 请求保留未知字段和字段顺序;SSE、WebSocket、Images 与 standalone
|
||||
Search 的业务正文按原始字节转发。canonical facts 从同一数据旁路提取,只用于路由、观测和计费。
|
||||
- Responses 的业务扩展头保留原始多值字节。API 负责剥离鉴权、账号身份和 HTTP 传输字段,
|
||||
并提取会话语义;`gateway-protocol` 共享 HTTP 传输与网关链路字段分类。客户端兼容规则集中在
|
||||
`providers/openai/src/transport/downstream/`:`headers.rs` 管理下游环境头和已提取语义的头部别名,
|
||||
`body.rs` 管理不适用于 Codex Responses 的已知顶层参数;兼容基准为 Codex Core/Desktop 请求协议,
|
||||
不持有账号身份保护或会话规范化逻辑。OpenAI 官方 SDK 的
|
||||
`x-stainless-*` 也描述下游 SDK 环境;字段合法性与是否跨链路透传是不同判断。
|
||||
不持有账号身份保护或会话规范化逻辑。
|
||||
Provider 在 `transport/request.rs` 解码不透明头时组合兼容、身份与 HTTP 规则,
|
||||
同时调用正文兼容规则;HTTP/SSE 与 WebSocket 共用此边界。
|
||||
`transport/headers.rs` 负责上游身份保护和官方头组装。
|
||||
@@ -262,7 +260,7 @@ client,OIDC 的 JWKS 缓存与单飞归属对应出口状态。自动刷新提
|
||||
### Codex 原生生图与认证
|
||||
|
||||
管理端导出的 Codex 配置使用代理 Bearer 密钥,并声明服务端托管账号认证。
|
||||
客户端据此开放原生生图工具,图片生成和编辑仍进入现有 Images 路由,不新增独立的登录或图片代理服务。
|
||||
客户端据此开放原生生图工具,图片生成和编辑由 Images 路由处理。
|
||||
这只解决客户端能力识别;模型能力、客户端限制和上游账号的实际生图权限仍分别检查。
|
||||
|
||||
`X-OpenAI-Actor-Authorization` 是客户端能力标记,不是账号凭据。API 解码和 OpenAI Provider
|
||||
@@ -307,10 +305,10 @@ API 模块按 `url`、`method`、`data`(POST)或 `params: data`(GET)排
|
||||
一次有上下文的反馈;不得为普通失败重新维护一套消息或业务码映射。
|
||||
|
||||
管理员和密钥登录共用 `/api/auth/*`、AuthService、Redis 会话结构和 `cpr_session` Cookie。
|
||||
登录类型只选择凭据校验方式,权限来自服务端保存的身份。管理入口只接受管理员身份或原有部署级管理 API Key;
|
||||
登录类型只选择凭据校验方式,权限来自服务端保存的身份。管理入口只接受管理员身份或部署级管理 API Key;
|
||||
AuthService 每次恢复 Key 会话时重新检查 Key 是否存在且启用;Key 会话不能访问管理员页面和管理接口。
|
||||
前端只维护一份 Auth Store,不在每个 API 请求上标记身份;401 会话失效、403 权限不足和 503 依赖故障分别处理。
|
||||
成功登录替换旧会话,登出必须确认服务端撤销;旧管理员会话路径不保留兼容读取。
|
||||
成功登录替换旧会话,登出必须确认服务端撤销。
|
||||
KeyUsageService 从 AuthService 的服务端身份确定唯一查询范围,复用 ClientKeyStore 的额度账本投影和
|
||||
ObservabilityStore 的范围查询;API 只输出单页所需的字段白名单,不复用管理员的宽响应。
|
||||
前端 `/key-usage` 独立于管理布局,不挂载管理员菜单或请求管理接口。
|
||||
@@ -418,7 +416,7 @@ PostgreSQL 周期对账才是正确性基础。
|
||||
| admission、lease、cooldown、circuit、会话亲和、continuation、OAuth pending、目录 cache | Redis | 可重建、可过期的协调状态 |
|
||||
| 控制面统一登录会话与登录限流桶 | Redis | AuthService 唯一拥有;保存 Admin / Key 身份、绑定 ID、绝对有效期和计数,不保存原始凭据 |
|
||||
| 日志、OAuth 恢复记录、在线更新状态、备份暂存 | `.runtime/` | 部署节点本地运行文件 |
|
||||
| 重置卡库存与消费结果 | OpenAI upstream | 后端不建立本地卡库存;前端按账号保留当前浏览器会话的最近查询、未决消费幂等键与发送锁,展开行卸载不会清空 |
|
||||
| 重置卡库存与消费结果 | OpenAI upstream | 后端不建立本地卡库存;前端按账号在浏览器会话期间保留最近查询、未决消费幂等键与发送锁 |
|
||||
| Provider 公开模型与请求画像 | Provider/runtime cache | 由官方目录或发布源刷新,不写成第二份业务配置 |
|
||||
| Windows 安装包临时直链 | Host 进程内短缓存 | 按需解析、严格校验、到期前丢弃;不写 PostgreSQL/Redis,也不代理包字节 |
|
||||
|
||||
|
||||
+1
-2
@@ -248,8 +248,7 @@ createApp
|
||||
→ app.mount('#app')
|
||||
```
|
||||
|
||||
这样首个 Vue 组件渲染时已经具备正确主题,不需要在 `index.html` 增加 bootstrap 脚本,也不维护第二套本地存储
|
||||
解析逻辑。
|
||||
Theme Store 统一读取持久化配置并初始化主题,首个 Vue 组件渲染时即可使用主题变量。
|
||||
|
||||
### CSS Variables 提交
|
||||
|
||||
|
||||
Reference in New Issue
Block a user