docs: 同步 v0.1 backend profile 规格

This commit is contained in:
Codex
2026-05-29 18:05:05 +08:00
parent e955eace58
commit 526faff3f2
12 changed files with 161 additions and 62 deletions
+40 -12
View File
@@ -1,18 +1,18 @@
# v0.1 Codex Backend 规格
# v0.1 Codex Stdio Backend/Profile 规格
Codex backend 是 AgentRun `v0.1` 的第一真实 Code Agent backend 候选。它用于证明 runner、backend adapter、Kubernetes Secret projection、真实 provider 调用、event normalization 和 terminal status 的完整闭环。
Codex stdio backend 是 AgentRun `v0.1` 的第一真实 Code Agent backend kind。它用于证明 runner、backend adapter、Kubernetes Secret projection、真实 provider 调用、event normalization 和 terminal status 的完整闭环。`v0.1` 在同一个 backend kind 下支持 `codex``deepseek` 两个 profile;两者共享 Codex CLI app-server stdio 协议,只通过 profile/config/SecretRef 隔离上游和模型。
## 在系统中的职责划分
- 作为 `backendProfile=codex` 具体实现。
- 作为 `backendProfile=codex` `backendProfile=deepseek` 的共同具体实现。
- 使用真实 Codex/Codex-compatible 配置执行最短 turn,不使用 fake provider 作为综合联调通过证据。
- 消费 Kubernetes Secret projection 提供的 Codex 凭据文件
- 消费 Kubernetes Secret projection 提供的 profile 专属 Codex `auth.json``config.toml`
- 把 Codex 输出归一化为 AgentRun 标准 events 和 terminal status。
- 将 provider/auth/protocol/timeout/cancel 错误映射为 [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) 定义的 failureKind。
## 协议选型与实现参考
`v0.1` Codex backend 的协议固定为 Codex CLI app-server JSON-RPC over stdio。Backend adapter 必须启动受控子进程:
`v0.1` Codex stdio backend 的协议固定为 Codex CLI app-server JSON-RPC over stdio。Backend adapter 必须启动受控子进程:
```bash
codex app-server --listen stdio://
@@ -20,7 +20,7 @@ codex app-server --listen stdio://
Adapter 通过 stdin 写入换行分隔 JSON-RPC 请求,通过 stdout 逐行读取 JSON-RPC response 和 notificationstderr 只作为有界诊断日志。最小请求序列是 `initialize``thread/start``thread/resume``turn/start`response 中必须提取 thread/turn identitynotification 和后续输出必须归一化为 `backend_status``assistant_message``tool_call``command_output``error``terminal_status` events。
不得把以下路径作为 `v0.1` Codex backend 的正式实现或综合联调通过证据:直接 Responses HTTP 代理、OpenAI SDK wrapper、`codex exec` 一次性命令输出、fake provider、固定文本回复、只读 shortcut 或本地 shell 模拟。裸 HTTP 或 `codex exec --json` 可以作为 provider/upstream 诊断,但最终通过必须来自 app-server stdio turn。
不得把以下路径作为 `v0.1` Codex stdio backend 的正式实现或综合联调通过证据:直接 Responses HTTP 代理、OpenAI SDK wrapper、`codex exec` 一次性命令输出、fake provider、固定文本回复、只读 shortcut 或本地 shell 模拟。裸 HTTP 或 `codex exec --json` 可以作为 provider/upstream 诊断,但最终通过必须来自 app-server stdio turn。
实现必须参考成熟代码:
@@ -30,30 +30,49 @@ Adapter 通过 stdin 写入换行分隔 JSON-RPC 请求,通过 stdout 逐行
| UniDesk `src/components/microservices/code-queue/src/code-agent/common.ts` | backend port/capability、model/profile 边界、文本 input shape、Git/proxy env 处理和 provider 端口归一化。 |
| HWLAB `internal/cloud/codex-stdio-session.mjs` | long-lived stdio session readiness、Codex home/workspace/protocol gate、child env redaction、trace recorder、cancel/timeout/failure kind。 |
| HWLAB `scripts/code-agent-chat-smoke.mjs` | fake app-server 自测试方式、`thread/start` + `turn/start` 调用顺序、session reuse、tool trace 和 Secret 不泄露断言。 |
| HWLAB `docs/reference/spec-v02-deepseek-proxy.md` | DeepSeek profile 通过稳定 bridge/Responses-compatible 入口接入,而不是把 DeepSeek 做成绕过 Codex stdio 的直接 HTTP backend。 |
| HWLAB `docs/reference/code-agent-chat-readiness.md` | provider/profile 切换时按 profile overlay、认证、网络、模型、Codex CLI/app-server 分层验证,并防止一个 profile 的成功掩盖另一个 profile 的退化。 |
这些参考用于协议和质量标准,不复制 UniDesk/HWLAB 的业务 prompt、硬件路径、tenant policy、hostPath Secret 做法或任何明文密钥。
## v0.1 Profile 定义
| backendProfile | SecretRef | 配置来源 | 规则 |
| --- | --- | --- | --- |
| `codex` | `agentrun-v01-provider-codex` | operator 当前 Codex `auth.json`/`config.toml` | 现有默认 profile;实现 DeepSeek 时不得改变其默认模型、config authority 或真实联调路径。 |
| `deepseek` | `agentrun-v01-provider-deepseek` | operator 准备的 DeepSeek-compatible Codex `auth.json`/`config.toml` | 使用同一 `codex app-server --listen stdio://` 协议,通过 `config.toml` 或等价 profile overlay 指向 DeepSeek-compatible upstream/model。 |
`deepseek` 的上游形态借鉴 HWLAB v0.2DeepSeek 是 provider profile,通过 Responses-compatible bridge、Moon Bridge 或等价稳定服务暴露给 Codex CLIAgentRun 不在 backend adapter 里手写 DeepSeek HTTP 转换器,也不把 DeepSeek 作为绕过 Codex app-server 的独立 backend kind。上游 base URL、模型和 provider 名称可以作为 redacted metadata 输出;API Key 和 `auth.json`/`config.toml` 原文不得输出。
Profile 切换规则:
- `backendProfile` 是 run 的显式字段,manager 不得静默改写。
- runner/backend 只读取与 `backendProfile` 同名的 provider credential;缺失则 `secret-unavailable`
- 每次 run 必须使用 profile-scoped writable `CODEX_HOME`。Kubernetes Job 可以把选中 profile 的 Secret projection 复制到该 Job 独占的 `/home/agentrun/.codex`host process 或复用进程必须使用 run/profile 独占目录,避免 `codex``deepseek` 互相污染。
- `deepseek` 不得 fallback 到 `codex` Secret、模型或 upstream`codex` 也不得读取 `deepseek` Secret。
- command payload 中显式提供 model 时可以透传给 Codex turn;未显式提供时以 profile `config.toml` 为 authority,不在 adapter 中写死默认模型。
## 测试凭据来源
`v0.1` 综合联调用的 Codex 测试凭据源固定为 operator 环境中的以下两个文件:
`v0.1` 综合联调用的 Codex stdio profile 测试凭据源固定为 operator 环境中的以下两个文件形态
```text
~/.codex/auth.json
~/.codex/config.toml
```
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源,不能通过 hostPath 挂载进 Pod,不能复制进镜像,不能提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源,不能通过 hostPath 挂载进 Pod,不能复制进镜像,不能提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。`codex``deepseek` 可以来自不同 operator profile 目录或显式文件参数,但进入 Kubernetes 后必须是不同 SecretRef,除非后续规格明确批准某个共享 SecretRef 场景。
`v0.1` 默认 Kubernetes Secret
| 对象 | v0.1 规格 |
| --- | --- |
| Namespace | `agentrun-v01` |
| Secret name | `agentrun-v01-provider-codex` |
| Secret name | `agentrun-v01-provider-codex``agentrun-v01-provider-deepseek` |
| Secret key | `auth.json`,来自 `~/.codex/auth.json` |
| Secret key | `config.toml`,来自 `~/.codex/config.toml` |
| Consumer | runner 或 backend adapter Pod |
| Projection target | 容器用户的 `~/.codex/auth.json``~/.codex/config.toml` |
| Projection target | 只读 projection,再复制到当前 run/profile 的 writable `CODEX_HOME/auth.json``CODEX_HOME/config.toml` |
| File mode | 只读,建议 `0400` 或等价最小权限 |
Kubernetes Secret 的创建、轮换和权限控制属于集群密钥管理流程;source branch 只声明 SecretRef 名称、key 和 mount intent。`deploy/deploy.json` 和 rendered GitOps manifest 不得包含 Secret data。
@@ -70,7 +89,7 @@ Kubernetes Secret 的创建、轮换和权限控制属于集群密钥管理流
[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 是 SecretRef、Kubernetes projection、redaction 和 missing secret failure 的权威。本文件只定义 Codex backend 对测试凭据文件的消费方式。
Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex``auth.json``config.toml`,而不是携带 provider credential 或文件内容。
Run 的 `executionPolicy.secretScope` 应引用 `backendProfile` 匹配的 provider SecretRef`auth.json``config.toml`,而不是携带 provider credential 或文件内容。
## 测试规格
@@ -82,6 +101,10 @@ Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex`
阅读本文和 [spec-v01-validation.md](spec-v01-validation.md),然后用 `backendProfile=codex` 创建真实 run 并提交一个最短 `turn` command。确认 runner 调用真实 Codex providermanager 可查询 backend_status、assistant 或 error event、terminal_status,且 Secret value 未泄露。
### T2b 真实 DeepSeek profile 最短 turn
阅读本文、HWLAB v0.2 DeepSeek profile 参考和 [spec-v01-validation.md](spec-v01-validation.md),然后用 `backendProfile=deepseek` 创建真实 run 并提交一个最短 `turn` command。确认 runner 仍调用 `codex app-server --listen stdio://`,但使用 `agentrun-v01-provider-deepseek` 的 profile SecretRef 和独立 `CODEX_HOME`manager 可查询 profile 为 `deepseek` 的 backend_status、assistant 或 error event、terminal_status,且 Secret value 未泄露。
### T3 Missing auth/config failure
阅读本文,然后分别移除或改名 Secret 中的 `auth.json``config.toml` key,启动真实 run。确认 adapter 在调用 provider 前失败为 `secret-unavailable`failure response 为 JSON,日志不包含 Secret value。
@@ -94,13 +117,18 @@ Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex`
阅读本文,然后用 mock/fake Codex app-server 自测试 HTTP 503 `Service Unavailable`、携带 5xx 的 `responseStreamDisconnected``method=error` retry notification 中 `willRetry=true` 且嵌套 `codexErrorInfo.responseStreamDisconnected.httpStatusCode=503` 的结构,或明确 temporary/provider unavailable 文案。确认 Codex adapter 返回 `provider-unavailable`,不会落到 `backend-failed`;综合联调若真实 provider 返回同类错误,应记录为外部 provider blocker,而不是本地 runner/backend 执行面 blocker。
### T6 Profile switching isolation
阅读本文,然后在真实 `agentrun-v01` 运行面按顺序执行 `backendProfile=codex``backendProfile=deepseek``backendProfile=codex` 三个最短 turn。确认第二个 run 使用 DeepSeek profile,前后两个 `codex` run 仍使用原 Codex profile;三者的 event、log、backend_status、model/upstream metadata 和 failureKind 不互相污染,且任何一个 profile SecretRef 缺失都不会 fallback 到另一个 profile。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| Codex backend 规格 | 已定义 | 本文为 v0.1 第一真实 backend 权威。 |
| Codex stdio backend/profile 规格 | 已定义 | 本文为 v0.1 Codex app-server stdio backend kind 和 profile 权威。 |
| Codex Secret projection | 已实现/已通过主闭环 | runner Job 使用只读 Secret projection 和 writable `CODEX_HOME`Codex 测试凭据来自 `agentrun-v01-provider-codex``auth.json`/`config.toml`。 |
| Codex adapter | 已实现/已通过主闭环 | 当前代码已实现受控 `codex app-server --listen stdio://``initialize`/`thread/start`/`thread/resume`/`turn/start` response 校验、stderr 有界诊断、spawn/JSON parse/response invalid/timeout/provider 5xx availability failureKind,以及包含 retry error notification 的 fake app-server 自测试。 |
| 错误可观测与脱敏 | 已实现主路径 | child env、cwd、workspace 和 Codex home 只输出摘要;stderr tail 有界且标记截断;事件和 failure 统一走 redaction。 |
| 真实 provider turn | 已通过主闭环 | 真实 Codex provider turn 已经通过 RESTful API 和 CLI 综合联调;每次发布仍按 [spec-v01-validation.md](spec-v01-validation.md) 手动复验。 |
| `deepseek` profile | 已定义/待实现 | 需要作为同一 Codex stdio backend kind 的 profile 实现,使用 `agentrun-v01-provider-deepseek` 和独立 `CODEX_HOME` 完成真实联调。 |
| hostPath `~/.codex` | 不采用 | 只能通过 Kubernetes Secret projection 注入。 |