108 lines
6.6 KiB
Markdown
108 lines
6.6 KiB
Markdown
# 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。
|
||
|
||
## 在系统中的职责划分
|
||
|
||
- 作为 Kubernetes Job 或受控 host process 启动;不作为普通业务客户端直接调用的长驻公共服务。
|
||
- 从 manager register、claim run、续租 lease、poll commands、ack command、append events、patch status。
|
||
- 根据 run 中的 `backendProfile` 和 `executionPolicy.secretScope` 调用 backend adapter。
|
||
- 将 backend stdout/stderr、assistant message、tool call、error 和 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。
|
||
|
||
Runner 自研代码优先使用 Bun + TypeScript。Kubernetes Job 和 CLI 启动的 host process 必须进入同一套 TS runner 模块,避免一套 Job 逻辑和一套本地调试逻辑分叉;容器镜像可以直接运行 TS 入口或运行由同一源码构建出的 JS artifact。
|
||
|
||
Runner 启动参数必须显式包含:
|
||
|
||
- manager API base URL。
|
||
- runId 和 attemptId。
|
||
- backendProfile。
|
||
- logPath 或 Kubernetes job/pod identity。
|
||
- source commit/build metadata。
|
||
|
||
Runner Secret 只能通过 Kubernetes Secret projection、ServiceAccount/RBAC 或受控 Secret API 读取获得。Codex 测试凭据投影规则见 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 和 [spec-v01-backend-codex.md](spec-v01-backend-codex.md)。
|
||
|
||
Kubernetes Job runner 必须把 credential source 与 runtime home 分开:Secret volume 只读挂在 `/var/run/agentrun/secrets/...`,`/home/agentrun` 由 `emptyDir` 提供可写空间,`CODEX_HOME` 指向 `/home/agentrun/.codex`,`AGENTRUN_CODEX_SECRET_HOME` 指向只读 projection。runner/backend 在启动 provider 前只复制授权文件,不打印内容。
|
||
|
||
## Runner 生命周期
|
||
|
||
标准状态方向:
|
||
|
||
```text
|
||
starting -> registered -> claimed -> running -> terminal
|
||
starting -> registered -> claim_failed
|
||
claimed -> running -> backend_failed
|
||
claimed -> running -> cancelled
|
||
claimed -> lease_lost
|
||
```
|
||
|
||
规则:
|
||
|
||
- runner 必须先 register,再 claim run;claim 失败不能继续调用 backend。
|
||
- lease heartbeat 必须可观察;过期或冲突时写入 failure event 或明确退出原因。
|
||
- command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。
|
||
- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 manager。
|
||
- terminal status 上报后 runner 可以退出;退出码与 terminal status 必须一致或在日志中可解释。
|
||
|
||
## Manager API 交互
|
||
|
||
Runner 只使用 manager 私有 API:
|
||
|
||
```http
|
||
POST /api/v1/runners/register
|
||
POST /api/v1/runs/:runId/claim
|
||
PATCH /api/v1/runs/:runId/lease
|
||
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
|
||
```
|
||
|
||
Runner inbound HTTP 不是业务 API。若实现本地诊断端点,只允许 `GET /health` 或 `GET /debug/status`,并且只能暴露在本地或 pod 内部调试面。
|
||
|
||
## Failure 与 Redaction
|
||
|
||
Runner 必须把以下失败归类为结构化 failureKind:
|
||
|
||
- `secret-unavailable`:SecretRef 缺失、RBAC 拒绝或 Secret projection 不完整。
|
||
- `provider-auth-failed`:上游 provider 鉴权失败。
|
||
- `backend-failed`:backend 进程退出、协议错误或返回 terminal error。
|
||
- `runner-lease-conflict`:claim/lease 被其他 runner 持有。
|
||
- `infra-failed`:Job 启动、网络、manager API 或文件系统基础设施失败。
|
||
- `cancelled`:收到 interrupt/cancel 且已停止执行。
|
||
|
||
Runner 日志必须实时 flush 到文件或 pod log,CLI 启动 runner 时必须返回 logPath 或 job/pod identity。日志、event、trace 和 CLI 输出不得出现 provider credential、`auth.json`、`config.toml` 内容、DSN password、token 或 URL credential。
|
||
|
||
## 测试规格
|
||
|
||
### T1 Runner 启动可见性
|
||
|
||
阅读 `AGENTS.md`、本文和 [spec-v01-cli.md](spec-v01-cli.md),然后用正式 AgentRun CLI 为一个真实 run 启动 runner。确认 CLI 立即返回 JSON,包含 runId、attemptId、job/process identity、logPath 和后续 poll command;不得等待完整模型 turn。
|
||
|
||
### T2 Claim 与 lease 冲突
|
||
|
||
阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 启动两个 runner。确认只有一个 runner claim 成功,失败方输出结构化 failureKind,并且 manager events 中能看到冲突或拒绝原因。
|
||
|
||
### T3 Backend event round-trip
|
||
|
||
阅读本文和 [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md),然后用真实 backend 执行一个最短 turn。确认 runner append assistant/output/error/backend_status/terminal_status 中的必要 events,event seq 单调,terminal status 可通过 manager 查询。
|
||
|
||
### T4 Missing Secret failure
|
||
|
||
阅读本文和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后用缺失 Codex SecretRef 的 run 启动 runner。确认 runner 不调用 provider,run 失败为 `secret-unavailable` 或等价 failureKind,日志和事件不泄露 Secret 值。
|
||
|
||
## 规格的实现情况
|
||
|
||
| 规格项 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| `agentrun-runner` 服务规格 | 已定义 | 本文为 v0.1 runner 权威。 |
|
||
| Kubernetes Job runner | 部分实现 | 已提供 `runner job --dry-run` Job manifest 渲染骨架;正式 `runner job` 通过 manager REST 创建 Kubernetes Job,固定使用 `agentrun-v01-runner` ServiceAccount、manager URL、runId/commandId/attemptId、executionPolicy、SecretRef 文件投影和 writable Codex runtime home;真实集群综合联调仍需验收。 |
|
||
| 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 status;durable store 仍待 Postgres adapter 接入。 |
|
||
| runner redaction | 已定义/未实现 | 需与 backend adapter 共同实现。 |
|