docs: align guides and workflows with current behavior

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Zyy
2026-10-28 21:50:51 +08:00
co-authored by Codex
parent 736eca6593
commit 0f214c3e25
10 changed files with 50 additions and 29 deletions
+2 -2
View File
@@ -20,7 +20,7 @@ description: Codex Proxy RS 开发、修复、排障、代码审查和文档修
| 模块或调用链变更 | [Workspace 边界](../../../docs/architecture.md#3-workspace-边界)及所属模块章节,不通读整份架构 |
| 新增、调整、清理或审查测试 | 下方[测试维护](#测试维护),按当前行为、职责归属与已有覆盖判断保留、合并或删除 |
| 修改部署行为、`deploy/` 配置或数据库迁移 | 按范围读取[部署](../../../deploy/README.md)、[迁移](../../../backend/migrations/README.md)对应章节 |
| 修改或审查文档 | [文档检查](references/documentation.md)及目标章节,不默认读取代码开发、页面验收或发布流程 |
| 修改或审查文档;实现或审查用法、公开合同、职责、约束或运维操作的变化 | [文档检查](references/documentation.md)及相关章节,尚无文档差异时也检查是否漏更;纯文档任务不默认读取代码开发、页面验收或发布流程 |
| 代码审查,包括 PR 审查 | [审查标准](../../../CONTRIBUTING.md#审查标准),叠加被审查行为所属领域的规范;审查默认只读 |
| PR / Issue / 发版 | 按当前意图选 [PR](../cpr-github-pr/SKILL.md)、[Issue](../cpr-github-issue/SKILL.md)或[发版](../cpr-release/SKILL.md),普通提交不创建 PR |
@@ -36,7 +36,7 @@ description: Codex Proxy RS 开发、修复、排障、代码审查和文档修
1. 遵守已提供的 [AGENTS.md](../../../AGENTS.md),按其 CodeGraph 约定定位代码;确认工作区、任务范围与已有改动,找到事实归属、同类实现和调用链,补齐上表命中规范及[项目约定](../../../CONTRIBUTING.md#项目约定)对应条目后再修改
2. 以最终差异重新匹配上表,补齐新增领域的规范并检查实际实现,再处理本次引入的职责越界、重复规则、冗余状态与无依据分支;删除或替换功能时一并清理失效的配置、类型、调用、测试与文档,已部署数据和公开合同仍遵守所属迁移及兼容规则;仅审查时报告,不自行修复
3. 常规文档只写当前状态;有文档差异时执行[文档检查](references/documentation.md),没有时只确认现有说明是否失真,普通开发不自动修改 `release/notes.md`
3. 按最终行为执行[文档检查](references/documentation.md),核对所属正文及相关概述、示例和引用,在本任务内完成必要同步;不以尚无文档差异跳过检查。内部重构等未改变文档所述事实时无需改文档;常规文档只写当前状态,普通开发不自动修改 `release/notes.md`
4. 按变更范围执行[验证](../../../CONTRIBUTING.md#验证)及其停止条件,后端命令见[验证命令](../../../docs/architecture.md#验证命令);沿用本轮有效证据与用户已确定的验收分工,区分通过、失败、跳过与未执行;提交时补读[提交约定](../../../CONTRIBUTING.md#项目约定)
5. 交付实际结果与验证缺口;前端按[前端流程](references/frontend.md)核对最终差异和运行证据,后端按上表检查生命周期,不把构建通过当作行为验收
@@ -1,14 +1,22 @@
# 文档检查
修改或审查文档时完整读取本流程,并读取 [文档职责与更新条件](../../../../CONTRIBUTING.md#文档职责与更新条件)的完整章节,覆盖内容归属与层次行文
修改或审查文档,以及实现或审查涉及文档更新条件的行为变化时,完整读取本流程和 [文档职责与更新条件](../../../../CONTRIBUTING.md#文档职责与更新条件),覆盖内容归属与层次行文
## 核实与同步范围
- 以当前目标分支及任务内工作区的实现、配置和有效运行证据核实行为;提交记录用于发现待核实的主题,不能直接当作现行事实或按提交顺序组织正文。按 [CodeGraph 约定](../../../../AGENTS.md#codegraph)同步索引后定位,证据不足时报告缺口,不把计划或推测写成已支持能力
- 开发任务按最终行为检查哪些用法、合同、职责、约束或运维操作需要同步,即使尚无 Markdown 差异也要检查;独立文档更新按用户范围核对现行说明,不等到发版时再补普通开发所需的文档
- 沿同一事实查找所属正文及相关概述、示例和引用,重点核对“支持/不支持”等能力声明、默认值、配置模板和命令。概述保留必要摘要并链接详细合同;不能只更新详细章节,留下 README 或示例中的矛盾说明,也不扩展为无关全仓改写
## 写之前
先确定读者、必须说明的当前事实与所属章节,再决定是否需要修改及详略;文档职责与更新条件按上节核对。涉及合同或职责说明时,补读所属架构、API 或 SDK 的对应条款,核实事实;不因文档提及实现而执行无关的开发与构建流程
在所属章节就地替换失效说明,先组织读者现在需要的操作、结果和限制,不从变更摘要改写正文。仅介绍被替代实现、修复动机或修改经过的段落直接删除;删掉“新增”“此前”“不再”等词后仍在回答变更经过的内容,也不保留
## 逐段验收
检查工作区和暂存区中本任务的最终文档差异,按内容用途处理,不只搜索关键词:
检查工作区和暂存区中本任务的最终文档差异,并连同受影响章节及相关概述、示例通读,按内容用途处理,不只搜索关键词:
| 段落回答的问题 | 处理 |
| --- | --- |
@@ -26,6 +34,6 @@
- 完成上述逐段验收及[行文检查](../../../../CONTRIBUTING.md#层次与行文),发现问题先处理,未完成内容审查不能称文档已检查
- 检查相对链接、章节锚点、表格与命令示例,`git diff --check` 或构建通过不能代替内容审查
- 报告实际覆盖和缺口即可,不把检查记录写进常规文档
- 交付时简述已同步的文档范围;涉及更新条件却未改文档时,说明现有内容为何仍准确或还有什么缺口。仅报告实际核对范围,不把链接检查通过称为事实核实,也不把检查记录写进常规文档
只有明确的发布说明任务才进入 `cpr-release`;发布说明与常规文档的边界按[内容归属](../../../../CONTRIBUTING.md#内容归属)执行
+1
View File
@@ -28,6 +28,7 @@ Issue 和 PR 回复统一按 [GitHub 回复口吻](CONTRIBUTING.md#github-回复
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
- **Index freshness**: Run `codegraph sync` from the repository root before the first code query in a task. After pulling updates, switching branches, or changing code, run it again before the next query so symbols and call paths match the working tree. If synchronization fails, report the failure and verify against current source rather than treating the index as current.
- **MCP tools** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them. `codegraph_node` returns one symbol's source + callers, or reads a whole file with line numbers. If the tools are listed but deferred, load them by name via tool search.
- **Shell** (always works): `codegraph explore "<symbol names or question>"` and `codegraph node <symbol-or-file>` print the same output.
+2 -2
View File
@@ -17,7 +17,7 @@
</div>
> [!NOTE]
> 本项目提供 Responses API,不支持 `/v1/chat/completions`,接入前请确认客户端支持 Responses 协议
> 本项目提供 Responses API 和 Chat Completions API;Chat Completions 请求通过 Responses 链路执行,支持范围见 [API 参考](docs/api.md#chat-completions-请求)
## 快速预览
@@ -97,7 +97,7 @@ API Key 持有者可在登录页切换身份,查看自己的用量与额度,
完整步骤、生图配置与排障见[客户端配置](deploy/README.md#客户端配置)
**其他 Responses API 客户端**:填写以下信息:
**其他 Responses / Chat Completions API 客户端**:填写以下信息:
| 配置 | 值 |
| --- | --- |
+2 -4
View File
@@ -180,10 +180,8 @@ RPC v7 的调度控制消息没有载荷:`Suspend { id, epoch }` 归还执行
结果接收本身不恢复父任务、不释放驻留额度;父调用终结统一回收剩余回调。
取消、恢复授权和结果可能交错,终结后的消息不得重新打开调用
宿主只接受 RPC v7,不提供旧协议兼容或降级。使用旧 SDK 的插件须更新 SDK、重新构建并由 CLI 生成安装包后安装,
只修改清单中的版本号不能满足任务挂起、恢复和回调回收合同
插件须校验 `Hello` 的协议版本。一次 `Call` 的结果、错误和流帧按 ID 关联;实例、代次、阶段、账号或资源 ID 用于关联调用和管理资源生命周期
宿主只接受 RPC v7,插件须校验 `Hello` 的协议版本并遵守上述挂起、恢复和回调回收合同。
一次 `Call` 的结果、错误和流帧按 ID 关联;实例、代次、阶段、账号或资源 ID 用于关联调用和管理资源生命周期
## 本地验证
@@ -542,7 +542,8 @@ restore_and_validate_response(response).await
### 模型目录
`model_catalog` 仅支持 v2,在 registration 阶段通过 `model_catalog.register` 一次提交
`ModelCatalogRegistrationV2 { aliases, models }`,不需要请求级 binding。
`ModelCatalogRegistrationV2 { aliases, models }`,不接受请求级 binding。
返回值必须同时包含 `aliases` 和 `models`,没有对应条目时使用空数组。
`aliases` 的每条 `ModelAlias { id, provider, model }` 定义公开 ID、Provider 及直接上游目标,条目正确性由插件负责。
别名条目重复、目标不存在或 Provider 未注册不阻止宿主快照发布。
请求按发布顺序取首个匹配条目,插件别名优先于静态映射,目标直接用于上游选路,不递归展开别名或目标上的静态映射
@@ -575,7 +576,6 @@ let plugin = PluginBuilder::from_json(include_bytes!("../plugin.json"))?
清单须显式声明 `model_catalog.version = 2`,可使用上述 `.model_catalog(...)` 固定目录,
或通过 `PluginBuilder::on(methods::MODEL_CATALOG_REGISTER_V2, handler)` 返回 `TypedReply<ModelCatalogRegistrationV2>`。
使用 v1 的插件需将原 `models` 别名列表移入 `aliases`,补充 `models: []`,更新能力声明并重新构建、打包;仅修改清单版本号不能迁移旧结构
原生 Codex 目录成功返回后,宿主保留其中的完整对象,只追加可见且尚未出现的适配模型画像;原生读取错误仍向调用方返回错误。
适配模型的 wire 模型名、协议编解码及摘要由插件负责,宿主只使用公开 ID、能力和账号范围参与现有选号,不生成请求正文或转换历史
@@ -17,8 +17,8 @@
| `package` | CLI 生成的协议版本、单一目标平台与文件摘要,不需作者手写 |
作者清单不能包含 `package`。使用 `Manifest::from_author_slice()` 校验并规范化;直接反序列化的 `Manifest`
不会执行作者清单的 ID 与固定阶段推导,声明的可选字段仍使用其默认值。打包后,`main` 和所有资源都必须进入 `package.files`;宿主用
`package_for(host, os, architecture)` 检查版本与平台。运行模式为 `trustedProcess`,信任边界见[完整信任](#完整信任)
不会执行作者清单的 ID 与固定阶段推导,声明的可选字段仍使用其默认值。打包后,`main` 和所有资源都必须进入 `package.files`,
宿主校验包结构、目标平台与文件完整性,宿主范围和能力版本另行进行兼容检查。运行模式为 `trustedProcess`,信任边界见[完整信任](#完整信任)
宿主实际开放的合同由 [plugin-host-compatibility.json](../../runtime/plugin-host-compatibility.json)
声明,SDK 的 `Capability::contract_versions()` 只表示 SDK 能描述的行为版本,不能代替宿主支持检查
+4
View File
@@ -358,6 +358,7 @@ experimental_realtime_ws_base_url = "http://127.0.0.1:8080/v1"
[model_providers.OpenAI]
name = "OpenAI"
base_url = "http://127.0.0.1:8080/v1"
model_catalog_url = "http://127.0.0.1:8080/v1/models"
wire_api = "responses"
supports_websockets = false
requires_openai_auth = false
@@ -381,6 +382,9 @@ goals = true
不要重复添加 `[features]` 或 Provider 表。更换模型时也要检查其支持的推理强度。
密钥以明文保存,文件仅供本人读取,不要提交到 Git。接入代理不需要扩大命令沙箱的联网或文件权限
`model_catalog_url` 指向同一网关的 `/v1/models`;更换网关地址时与 `base_url` 一起修改。
该接口返回当前密钥可见的模型目录,具体格式见 [模型目录](../docs/api.md#模型目录)
V2 远程压缩通过 Responses 接口发送 `compaction_trigger`,网关和上游需支持该协议。
若 Provider ID 改为 `custom`,相应能力配置也要改到 `[model_providers.custom.capabilities]`
+14 -8
View File
@@ -207,7 +207,7 @@ Dashboard 的 `lastUsedRelative` 和账号额度的 `refreshedAtRelative` 由后
## 3. OpenAI 数据面与模型目录
除下述入站解压保护外,Responses、Chat Completions、Images 和 standalone Search HTTP body、
WebSocket message 和 frame 不设置网关私有长度上限;协议可接受性由上游决定
WebSocket message 和 frame 不设置网关私有长度上限;请求字段与协议限制见各入口说明
| 方法 | 路由 | 说明 |
| --- | --- | --- |
@@ -290,13 +290,19 @@ print(completion.choices[0].message.content)
#### 响应与共用规则
非流式响应包含一个 `choices` 项,支持文本、拒绝和 function 工具调用。
流式响应交付对应的 Chat delta;`stream_options` 仅在 `stream: true` 时可提供,
非流式响应包含一个 `choices` 项,支持文本、拒绝和 function 工具调用;流式响应交付对应的 Chat delta。
两种响应的 `id` 均由网关生成,`model` 保留客户端请求的模型 ID;流内各块使用同一身份。
正常完成的 `finish_reason` 为 `stop`,包含工具调用时为 `tool_calls`;上游明确因输出长度或内容过滤而未完成时,
分别为 `length` 或 `content_filter`
`stream_options` 仅在 `stream: true` 时可提供,
`include_usage: true` 在完整上游用量可用时于结束前追加 `choices: []` 的用量块,其余块的 `usage` 为 `null`。
未提供完整用量时不补造 Token 数;缺省不启用流长度混淆,`include_obfuscation: true` 不受支持,`false` 可接受
响应对象新增普通属性、非必要事件不影响已有内容映射;无法表达的业务输出、缺少必要终态或终态冲突会失败,
不以丢弃内容或补造成功结束掩盖错误。OpenAI 是此入口的兼容目标,混合分组仍沿用现有选路与 fallback 规则,
响应对象的额外普通属性、非必要事件不影响已有内容映射;无法表达的业务输出、缺少必要终态或终态冲突会失败,
不补造成功终态。SSE 已开始后通过 `data: {"error": ...}` 交付错误,再以 `[DONE]` 结束,
因此 `[DONE]` 仅表示流结束,不能单独作为成功依据。
OpenAI 是此入口的兼容目标,混合分组沿用账号范围内的选路与 fallback 规则,
不能据此推导所有 Provider 都具备相同的 Chat 能力
Responses 的 reasoning 项(包括摘要与 `encrypted_content`)不投影到 Chat 消息,
@@ -306,8 +312,8 @@ Chat 沿用 [Client Key 鉴权](#openai-数据面客户端接口)、[请求期
[请求头与身份](#请求头与身份)及[隐私策略](#隐私策略)。隐私策略的 `request_body` 面向转换后的 Responses 正文,
例如 `$.input`,不需要另外维护一套针对 `messages` 的规则
转换后的请求仍执行统一[正文兼容](#正文兼容):顶层 `temperature`、`max_output_tokens` 和
`prompt_cache_retention` 会被移除。因此接受相应 Chat 参数不表示采样、输出长度或缓存保留设置必然生效,
转换后的请求按选中 Provider 的正文规则处理。OpenAI 的[正文兼容](#正文兼容)会移除顶层 `temperature`、
`max_output_tokens` 和 `prompt_cache_retention`。因此接受相应 Chat 参数不表示采样、输出长度或缓存保留设置必然生效,
不会通过本地截断模拟长度控制;`top_p` 等其他参数继续由上游判断
### Images 请求
@@ -419,7 +425,7 @@ Images 的 `x-codex-image-turn-id` 和 Desktop 自动 Git 上下文的 `clientUs
#### 正文兼容
Responses 上游编码会移除 Codex 不接受的顶层 `temperature`、`max_output_tokens` 和
OpenAI Provider 的 Responses 上游编码会移除 Codex 不接受的顶层 `temperature`、`max_output_tokens` 和
`prompt_cache_retention`。缺少顶层 `store` 时补齐 `false`,与官方 Codex 客户端一致;
显式提供的值保持原样。顶层 `input` 为字符串时按公开 Responses API 的语义展开为一条
`user` 文本消息条目(`{"type": "message", "role": "user", "content": [{"type": "input_text", ...}]}`),
+10 -6
View File
@@ -15,15 +15,15 @@
Codex Proxy RS 是单进程、单副本运行的多 Provider AI 网关,同时提供:
- 面向客户端的 OpenAI Responses、Images、standalone Search 和模型目录协议
- 面向客户端的 OpenAI Responses、Chat Completions、Images、standalone Search 和模型目录协议
- 面向管理员的 `/api/admin/*` 控制面和 Vue 管理端
- 面向 Key 持有者的 `/api/key-usage/*` 用量与客户端配置接口、独立 `/key-usage` 页面,以及复用数据面认证的 `/v1/usage` 额度查询
- 固定的 OpenAI 与 xAI 两个编译期 Provider,以及插件提供的认证、中间件和管理扩展
- PostgreSQL 持久化、Redis 协调状态以及 S3/R2 数据库备份
系统不提供 `/v1/chat/completions`,不存在 Provider Instance 层,也不支持通过复制应用容器进行多副本
扩容。Client Key 限定账号分组,而不是绑定某个 Provider;一次请求的 Provider 候选由账号范围、模型
能力和运行时健康共同决定
Chat Completions 通过 API 协议转换复用 Responses 执行链。系统不存在 Provider Instance 层,也不支持
通过复制应用容器进行多副本扩容。Client Key 限定账号分组,而不是绑定某个 Provider;一次请求的
Provider 候选由账号范围、模型能力和运行时健康共同决定
## 2. 运行拓扑
@@ -948,8 +948,8 @@ credential 与 quota 是两组独立事实:credential refresh 不等于 quota
- 账号导入和 OAuth complete(包括重新授权)在 credential 提交、Provider 事实失效及快照发布后,
由 Admin 共用流程后台读取一次额度;不等待观测完成才返回管理请求,失败记录告警但不回滚账号事务。
手工和后台 credential refresh 仍不隐式刷新 quota
- quota refresh、正常推理返回的 rate-limit headers 和后台健康任务汇入同一额度事实;套餐只用于展示与
目录 cache 隔离,不创建套餐专属状态机。
- quota refresh、正常推理返回的 rate-limit headers 和后台健康任务汇入同一额度事实;Provider 使用套餐
事实进行展示、目录 cache 隔离和请求资格检查,不创建套餐专属状态机。
OpenAI Provider 将其中明确的套餐变更与额度原子提交,共用凭据版本和观察时间保护;
空值及 `unknown` 不覆盖套餐,同族泛化值保留具体子类型。Token 刷新保留提交时的账号资料
@@ -994,6 +994,10 @@ Store 从请求源事实维护窄事实及十五分钟、小时统计状态,
统计 Worker 跨周期保留消费批量上限,整轮无进展超时或存储操作超时后缩小批量,满批快速完成时恢复吞吐;
维护锁竞争造成的空轮不重置批量,未提交事务与未确认队列项由后续周期重试。
用量洞察的请求并发由 Store 在同一读取快照中按请求开始、完成时间聚合,运行中请求计至查询范围末尾。
每个时间桶返回按持续时间加权的平均并发和峰值,Admin 按各桶的有效时长合并全区间平均值,并取全区间峰值。
该趋势使用请求记录,不读取 Redis 准入租约,也不参与容量裁决;筛选与统计口径见[用量统计](api.md#记录范围与统计口径)
### 额度预测
账号容量预测属于 Admin 的只读派生规则,不参与 quota 权威状态、调度或金额结算。Store 通过专用采样端口