docs: 固化 runner 多轮执行规格

This commit is contained in:
Codex
2026-06-01 22:32:40 +08:00
parent 237b10c4da
commit 5fb008f5cf
3 changed files with 39 additions and 13 deletions
+16 -8
View File
@@ -1,20 +1,20 @@
# v0.1 agentrun-runner 服务规格
`agentrun-runner` 是 AgentRun `v0.1`短生命周期执行入口。它以 per-run 或 per-attempt 方式运行,必须从 `agentrun-mgr` claim run,调用一个 backend adapter,并把 events、heartbeat、command ack 和 terminal status 写回 manager。
`agentrun-runner` 是 AgentRun `v0.1`手动启动执行入口。它以 per-run runner Job 方式运行,必须从 `agentrun-mgr` claim run,调用 backend adapter,并把 events、heartbeat、command ack 和 command terminal status 写回 manager。同一 runner Job 在 idle timeout 内必须继续 poll 同一 run 的后续 command,不得把每个 turn 都变成重新 bundle 和新 runner Job。
## 在系统中的职责划分
- 作为 Kubernetes Job 或受控 host process 启动;不作为普通业务客户端直接调用的长驻公共服务。
- 从 manager register、claim run、续租 lease、poll commands、ack command、append events、patch status。
- 从 manager register、claim run、续租 lease、poll commands、ack command、append events、patch command status;只有 runner 级不可恢复失败或显式 run terminal 时才 patch run status。
- 根据 run 中的 `backendProfile``executionPolicy.secretScope` 调用 backend adapter。
- 根据 manager 解析出的 RuntimeAssembly materialize backend image、profile Secret、session 和初始资源;四要素字段权威见 [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md),本文只规定 runner 消费边界。
- 将 backend stdout/stderr、assistant message、tool call、error 和 terminal status 归一化为 manager event。
- 将 backend stdout/stderr、assistant message、tool call、error 和 command terminal status 归一化为 manager event。
- 提供可定位的 job/process identity、logPath、attempt id 和 failureKind。
- 不直连 Postgres,不扩大 workspace、network、approval 或 secret scope。
## 内部架构
`v0.1` 默认 runner 形态是 `agentrun-v01` namespace 中的短生命周期 Job,Job 名称建议使用 `agentrun-v01-runner-<runId>-<attempt>`。MVP 允许 CLI 启动受控本地 process,但该 process 仍必须通过 manager API claim/report。
`v0.1` 默认 runner 形态是 `agentrun-v01` namespace 中的短生命周期 Job,Job 名称建议使用 `agentrun-v01-runner-<runId>-<attempt>`短生命周期指 Job 不作为公共长驻服务;Job 内部必须支持同一 run 的多 command loop,直到 run 被 cancel/terminal、lease 冲突或 idle timeout。MVP 允许 CLI 启动受控本地 process,但该 process 仍必须通过 manager API claim/report。
Runner 自研代码优先使用 Bun + TypeScript。Kubernetes Job 和 CLI 启动的 host process 必须进入同一套 TS runner 模块,避免一套 Job 逻辑和一套本地调试逻辑分叉;容器镜像可以直接运行 TS 入口或运行由同一源码构建出的 JS artifact。
@@ -65,7 +65,7 @@ claimed -> lease_lost
- lease heartbeat 必须可观察;过期或冲突时写入 failure event 或明确退出原因。
- command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。
- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 managerbackend_status 至少包含 redacted profile/backendKind/protocol 摘要。
- terminal status 上报后 runner 可以退出;退出码与 terminal status 必须一致或在日志中可解释。
- 单个 command terminal 上报后 runner 不应立即退出,而应继续 poll 同一 run 的 pending command,直到 idle timeout、lease 冲突或 run terminal。退出码与 runner loop 终态必须一致或在日志中可解释。
## Manager API 交互
@@ -79,8 +79,11 @@ GET /api/v1/runs/:runId/commands?afterSeq=0&limit=20
POST /api/v1/runs/:runId/events
PATCH /api/v1/runs/:runId/status
POST /api/v1/commands/:commandId/ack
PATCH /api/v1/commands/:commandId/status
```
`PATCH /api/v1/commands/:commandId/status` 是普通 turn 完成的权威上报入口;它只能终结 command,并可更新 run 的 SessionRef/thread 摘要。`PATCH /api/v1/runs/:runId/status` 只用于 runner 级不可恢复失败或显式 run terminal,不得在每个成功 turn 后调用。
Runner inbound HTTP 不是业务 API。若实现本地诊断端点,只允许 `GET /health``GET /debug/status`,并且只能暴露在本地或 pod 内部调试面。
## Failure 与 Redaction
@@ -134,15 +137,20 @@ HWLAB v0.2 原有 Code Agent 在 cloud-api 进程内执行,失败时依赖本
阅读本文和 [spec-v01-backend-codex.md](spec-v01-backend-codex.md),然后按 `codex -> deepseek -> codex` 顺序启动三个真实 runner Job。确认每个 Job 只挂载和复制当前 profile 的 SecretRef`CODEX_HOME` 互相隔离,且前后两个 `codex` run 不受 `deepseek` run 的 config/model/upstream 影响。
### T6 Same-run runner command loop
阅读本文和 [spec-v01-hwlab-manual-dispatch.md](spec-v01-hwlab-manual-dispatch.md),然后在同一 run 中提交两条 `turn` command,只启动一次 runner Job。确认第一条 completed 后 run 仍为 non-terminalrunner 在 idle timeout 内处理第二条 command`resource-bundle-materialized` 只记录一次,两个 command result 按 commandId 独立返回 reply/terminal。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| `agentrun-runner` 服务规格 | 已定义 | 本文为 v0.1 runner 权威。 |
| Kubernetes Job runner | 已实现/已通过主闭环 | `runner job` 通过 manager REST 创建 Kubernetes Job,固定使用 `agentrun-v01-runner` ServiceAccount、manager URL、runId/commandId/attemptId、executionPolicy、SecretRef 文件投影、writable Codex runtime home 和有限 TTL;真实 `agentrun-v01` runner Job 已完成 Codex turn。 |
| host process runner | 已实现 | `runner start``src/runner/main.ts` 进入同一套 `runOnce`,可通过 manager register/claim/poll/report 执行自测试。 |
| claim/lease/report client | 已实现 | 已拆出 runner manager API client,覆盖 register、claim、lease heartbeat、poll command、ack、append event 和 terminal statuslive runtime 通过 manager 写入 Postgres durable store。 |
| Kubernetes Job runner | 已实现/已通过主闭环 | `runner job` 通过 manager REST 创建 Kubernetes Job,固定使用 `agentrun-v01-runner` ServiceAccount、manager URL、runId/commandId/attemptId、executionPolicy、SecretRef 文件投影、writable Codex runtime home、idle timeout 和有限 TTL;真实 `agentrun-v01` runner Job 已完成 Codex turn。 |
| host process runner | 已实现 | `runner start``src/runner/main.ts` 进入同一套 `runOnce`,可通过 manager register/claim/poll/report 执行自测试,并支持 `--one-shot` 或 idle timeout 控制。 |
| claim/lease/report client | 已实现 | 已拆出 runner manager API client,覆盖 register、claim、lease heartbeat、poll command、ack、append event、command status 和必要 run statuslive runtime 通过 manager 写入 Postgres durable store。 |
| cancel observation | 已实现最小闭环 | runner 在 backend 执行期间轮询 run/command cancel,触发 AbortController 中止 Codex stdio backend,并按 `cancelled` 上报 command/run 终态。 |
| SessionRef/ResourceBundleRef 消费 | 已实现最小闭环 | runner 会使用 run 中的 SessionRef threadId 执行 resume,并 materialize Git-only ResourceBundleRef 到隔离 workspace 后再启动 backend。 |
| 同 run/runner 多 turn | 已实现最小闭环 | runner 在同一 Job 中 materialize bundle 一次后循环 poll command;普通 turn completed 只终结 commandrun 保持可继续接后续 turn,直到 idle timeout 或 run terminal。 |
| runner redaction | 已实现主路径 | runner/backend event 和 Job 输出使用 redaction;复杂审计仍按 [spec-v01-validation.md](spec-v01-validation.md) 的人工验收抽查。 |
| `deepseek` profile runner selection | 已实现/已通过主闭环 | Runner Job 和 host runner 已按 run `backendProfile` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata;真实 Kubernetes Job 已完成 `codex -> deepseek -> codex` 切换联调。 |