Files
pikasTech-agentrun/docs/reference/spec-v01-backend-adapter.md
T
2026-05-29 19:02:28 +08:00

8.2 KiB
Raw Blame History

v0.1 Backend Adapter 规格

Backend adapter 是 runner 与具体 Code Agent 工具之间的适配层。它隐藏 Codex、OpenCode、Claude Code、host-native 或 Windows-native 的内部协议,把输入、事件、错误和 terminal status 归一化为 AgentRun 公共模型。

在系统中的职责划分

  • 根据 backendProfile 选择具体 backend profilev0.1 必须支持 codexdeepseek,两者共享同一个 codex-app-server-stdio backend kind。
  • 接收 manager 持久化后的 run、command 和 executionPolicy;不得自行扩大 workspace、network、approval 或 secret scope。
  • 调用具体 backend,并把 backend 输出归一化为 AgentRun events。
  • 负责 provider/auth/backend/protocol 错误到 failureKind 的映射。
  • 负责 backend 输出和错误中的 credential redaction。
  • 暴露 backend capability 给 manager,用于 GET /api/v1/backends

Adapter 合同

第一版可以把 adapter 实现为 runner 进程内 Bun/TypeScript 模块,不要求独立 Deployment。无论实现形态如何,对 runner 的逻辑合同必须稳定:

resolveProfile(profile) -> capability
prepare(run, command, secretProjection) -> executionContext
startTurn(executionContext) -> normalized event stream
interrupt(executionContext, command) -> backend interrupt attempt
finalize(executionContext) -> terminal status
redact(value) -> redacted value

Adapter 输入必须来自 manager 保存的 run/command 和 Kubernetes Secret projection;不得从 CLI 参数、临时环境变量或 Git 文件读取 provider credential 明文。resolveProfile(profile) 必须返回 profile、backendKind、protocol、transport、command、requiredSecretKeys 和 isolation policy;不得把 unknown profile 静默映射到默认 codex

v0.1 的第一真实 adapter 是 Codex stdio adapter。它必须走 Codex CLI app-server JSON-RPC over stdioadapter 合同把 Codex 的 thread、turn、notification、tool lifecycle 和 stderr/exit 信息归一化为 AgentRun 标准 events。codexdeepseek 只是该 adapter 的 profile/config/SecretRef 选择,不允许复制两套协议实现。

Backend Profile Registry

GET /api/v1/backends 和 adapter 内部 registry 至少报告以下 profile

profile backendKind protocol transport command v0.1 状态
codex codex-app-server-stdio codex-app-server-jsonrpc-stdio stdio codex app-server --listen stdio:// 已有主闭环,必须保持默认兼容。
deepseek codex-app-server-stdio codex-app-server-jsonrpc-stdio stdio codex app-server --listen stdio:// 已实现 profile;必须用独立 SecretRef 和 profile-scoped CODEX_HOME 完成真实联调。

Registry 只表达能力和选择边界,不读取 Secret 值。Manager 负责校验 backendProfile 是否在 allowlist 内,并校验 executionPolicy.secretScope.providerCredentials 是否存在匹配 profile 的 SecretRefrunner 只为当前 run 选择的 profile 准备 Secret projection 和 runtime home。

标准事件

Adapter 输出给 runner 的 event 类型至少包括:

  • backend_statusbackend 启动、模型/profile、能力和阶段状态,不包含 Secret 值。
  • assistant_message:模型回复的用户可见文本。
  • tool_call:工具调用摘要和 redacted 参数。
  • command_outputstdout/stderr 或命令输出摘要。
  • diff:代码变更摘要或 patch 片段;必须受长度限制。
  • error:结构化错误和 failureKind。
  • terminal_statuscompleted、failed、cancelled、blocked 等终态。

事件必须有上限和分页友好形态。大型日志、完整 stdout 或完整 trace 应进入 logPath 或后续 artifact,不得一次性塞入单个 event 造成输出爆炸。

Failure Mapping

Adapter 必须把 backend 错误映射为稳定 failureKind

failureKind 典型来源
secret-unavailable Secret projection 缺失、文件不存在、权限不可读。
provider-auth-failed provider credential 或 auth file 无效、上游返回 401/403。
provider-rate-limited 上游限流或 quota 错误。
provider-unavailable 上游 provider availability/transient 失败,包括 HTTP 5xx/503、Service UnavailableresponseStreamDisconnected 携带 5xx 状态码、明确 provider unavailabletemporary unavailable 文案。
backend-protocol-error backend 输出无法解析、协议字段缺失。
backend-json-parse-error backend stdout 不是合法 JSON-RPC 行。
backend-response-invalid backend JSON-RPC response/terminal notification 缺少必需字段。
backend-spawn-failed backend app-server 进程无法启动。
backend-failed backend 进程非零退出或 terminal error。
backend-timeout executionPolicy timeout 触发。
cancelled interrupt/cancel 生效。

Credential Boundary

  • Adapter 只能看到运行时投影出来的最小 Secret 文件或 env;不得枚举整个 namespace Secret。
  • Adapter 不得把 Secret 值写入 event、trace、日志、CLI 输出、health 或 Postgres。
  • Codex backend 的 auth.jsonconfig.toml 整体按敏感文件处理,即使其中包含非敏感配置,也不得输出原文。
  • Provider base URL、model 名称和 profile 名称可以输出,但 URL credential、Authorization header、token、api_key、password 必须 redacted。

测试规格

T1 Adapter 自测试

阅读本文,然后用 mock backend 做组件自测试,确认 adapter 能把 assistant/output/error/terminal 输出归一化为标准 events,并能对 token、Authorization header、URL credential 和 Secret 文件内容做 redaction。该测试属于自测试,不作为综合联调通过证据。

T2 Failure mapping 自测试

阅读本文,然后用 mock 错误覆盖 missing secret、provider auth failure、rate limit、provider availability/transient failure、protocol error、timeout 和 cancel。provider availability/transient 样例必须至少包含 HTTP 503 Service Unavailable 或携带 5xx 的 responseStreamDisconnected,并确认不会被归类为 backend-failed。确认每类错误都映射到稳定 failureKind,且输出为 JSON 或结构化 event。

T3 真实 backend 联调

阅读本文、spec-v01-backend-codex.mdspec-v01-validation.md,然后分别用 backendProfile=codexbackendProfile=deepseek 完成真实最短 turn。确认 adapter 输出真实 assistant/backend_status/terminal_status events,事件中包含 profile/backendKind/protocol 摘要,且没有 Secret 泄露。

T4 Profile isolation 自测试

阅读本文,然后用 fake Codex app-server 和两个不同的 profile Secret fixture 做自测试。确认 adapter 只选择 run 指定 profile 的 SecretRef 和 CODEX_HOMEdeepseek 缺失时失败为 secret-unavailable,不会 fallback 到 codex

规格的实现情况

规格项 状态 说明
Backend adapter 合同 已定义 本文为 v0.1 adapter 权威。
通用 adapter 模块 已实现 profile 形态 src/backend/adapter.ts 作为 runner 进程内 adapter 入口;codexdeepseek 均路由到同一 Codex stdio backend kind,不复制第二套协议实现。
event normalization 已实现主路径 Codex backend 已把 backend_status、assistant_message、tool_call、command_output、error 和 terminal_status 归一化为 manager events;复杂事件审计按人工验收抽查。
failure mapping 已实现主路径 Codex backend 已覆盖 missing secret、auth/rate/availability、protocol、JSON parse、invalid response、spawn、timeout 和 cancel 分类;真实负向场景按 spec-v01-validation.md T7 手动验收。
deepseek profile 已实现/已通过主闭环 已进入 registry、validation、runner Secret selection、backend_status metadata、CLI secret render 和 fake stdio 自测试;真实综合联调已按 spec-v01-validation.md T8 覆盖 codex -> deepseek -> codex 切换。
多 backend 路由 Deferred 跨 backend kind 的自动路由和 scheduler capacity selection 不进入 v0.1。