From 5fb008f5cf7784250761814f2521de72fceb8562 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 1 Jun 2026 22:32:40 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=9B=BA=E5=8C=96=20runner=20=E5=A4=9A?= =?UTF-8?q?=E8=BD=AE=E6=89=A7=E8=A1=8C=E8=A7=84=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/spec-v01-agentrun-mgr.md | 13 ++++++++-- docs/reference/spec-v01-agentrun-runner.md | 24 ++++++++++++------- .../spec-v01-hwlab-manual-dispatch.md | 15 +++++++++--- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/docs/reference/spec-v01-agentrun-mgr.md b/docs/reference/spec-v01-agentrun-mgr.md index 540b421..783f68e 100644 --- a/docs/reference/spec-v01-agentrun-mgr.md +++ b/docs/reference/spec-v01-agentrun-mgr.md @@ -11,6 +11,7 @@ - 执行最小 tenant policy boundary:只做 schema、allowlist、idempotency、secret scope 和 executionPolicy 范围检查;不内建 UniDesk/HWLAB 的业务授权。 - 使用 Postgres 保存 runs、commands、events、runners、backends、leases 和 migration ledger。 - 输出结构化 health/readiness、failureKind、redacted SecretRef 和 trace correlation。 +- 可观测性只能定位和验证状态,不能替代缺失能力实现;如果 HWLAB canary 需要的 final reply、command result、runner 多 turn、SessionRef 或 cancel 能力缺失,manager 必须补 durable API/状态机,而不是只补 trace 文案。 ## 内部架构 @@ -57,6 +58,7 @@ 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 ``` 所有 API 成功和失败响应都必须是 JSON。失败响应至少包含 `failureKind`、`message` 和 trace correlation;不得出现空 stdout/空 response 被误判为成功的情况。 @@ -103,7 +105,7 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB ## 最小 Observability 合同 - events append-only,单 run 内 `seq` 单调递增。 -- 每个 run 必须最终出现唯一 authoritative `terminal_status`,或保持明确 non-terminal status 并可查询 lease/heartbeat;assistant partial、stdout、transport close 或 idle timeout 不能替代 terminal completed。 +- command terminal 与 run terminal 必须分离。普通 turn completed 只终结对应 command,run 可以保持 `claimed/running` 以继续接收后续 command;每个 command result 必须能从 command record 与 command-scoped events 得到 authoritative terminal。run 级 `terminal_status` 只用于 run cancel、runner 级不可恢复失败或明确 run terminal;assistant partial、stdout、transport close 或 idle timeout 不能替代 terminal completed。 - failureKind 至少能区分 `schema-invalid`、`tenant-policy-denied`、`secret-unavailable`、`runner-lease-conflict`、`backend-failed`、`provider-auth-failed`、`provider-unavailable`、`infra-failed`、`cancelled`。 - health/readiness 必须返回 Postgres reachable、schema migration ready、SecretRef redacted 状态和 build/source metadata。 - 日志、event、trace、health 和 diagnostics 不得输出 provider credential、Codex auth/config 内容、DSN password、token 或 URL credential。 @@ -125,6 +127,8 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB `assistant_message` partial、`command_output` 存在、stdout 非空、backend transport close 或 idle timeout 都不能单独让 result 进入 `completed`。 +当 `commandId` 已指定,result envelope 必须只聚合该 command 的 assistant/output/error/terminal 事件;同一 run 的其他 command reply 不能串入当前 command result。未指定 `commandId` 时可默认选择最新 command。 + ## 测试规格 ### T1 Manager health/readiness @@ -147,6 +151,10 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB 阅读本文和 [spec-v01-hwlab-manual-dispatch.md](spec-v01-hwlab-manual-dispatch.md),然后用 RESTful API 创建 `tenantId=hwlab` 的 run、提交 command、调用 `POST /api/v1/runs/:runId/runner-jobs`。确认响应短返回 JSON,包含 `runId`、`commandId`、`attemptId`、`jobName`、namespace、log/pod identity 和后续 poll 入口;重复 idempotency key 不创建重复 job。 +### T6 command/run terminal 分离 + +阅读本文和 [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md),然后在同一 run 内让两个 command 依次 completed。确认第一条 command completed 不会把 run 标为 terminal,`GET /commands/:id/result` 只返回对应 command 的 reply/terminal,run cancel 才会把 run 和未完成 command 一起收敛到 cancelled。 + ## 规格的实现情况 | 规格项 | 状态 | 说明 | @@ -155,8 +163,9 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB | Manager REST API | 已实现/已通过主闭环 | 已有 run、command、event、backends、runner register、claim、lease heartbeat、poll、ack、status、runner Job 创建和 health/readiness 的 HTTP JSON API;真实 runtime 已通过 RESTful API 主闭环。 | | 手动 runner Job API | 已实现 | `POST /api/v1/runs/:runId/runner-jobs` 已可创建 Kubernetes runner Job,并固化 idempotency、持久 runner job record、响应 schema 和 cancel 前置检查。 | | runner Job 状态查询 | 已实现 | `GET /api/v1/runs/:runId/runner-jobs` 和 `GET /api/v1/runs/:runId/runner-jobs/:runnerJobId` 返回 attempt/job/log/phase/terminal 摘要,业务客户端无需直连 Kubernetes 做最小定位。 | +| command/run terminal 分离 | 已实现最小闭环 | `PATCH /api/v1/commands/:commandId/status` 终结 command 并更新 SessionRef;普通 turn completed 不终结 run,run status 仅由 run cancel 或 runner 级不可恢复失败终结。 | | Tenant policy boundary | 已实现最小边界 | v0.1 已做 schema、tenant/backend allowlist、executionPolicy 和 secretScope 结构校验;业务授权仍由 UniDesk/HWLAB 自己判定。 | | `deepseek` backendProfile allowlist | 已实现/已通过主闭环 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `deepseek`;真实 runtime 已经通过 CI/CD 发布并确认 Postgres migration `002_v01_backend_profiles` 应用。 | | Postgres durable adapter | 已实现/已通过主闭环 | live runtime 通过 `DATABASE_URL` 使用 Postgres durable store;memory store 仅用于显式 self-test/dev。见 [spec-v01-postgres.md](spec-v01-postgres.md)。 | -| Observability 最小合同 | 已实现主路径 | events append-only、terminal status、failureKind、health/readiness store 状态、runner claim/lease/backend events 和 Secret/DSN redaction 已进入 manager;集中 trace 和部署级观测仍属后续工作。 | +| Observability 最小合同 | 已实现主路径 | events append-only、command-scoped terminal status、failureKind、health/readiness store 状态、runner claim/lease/backend events 和 Secret/DSN redaction 已进入 manager;集中 trace 和部署级观测仍属后续工作。 | | durable cancel API | 已实现最小闭环 | 已提供 run/command cancel API;pending command cancel 阻止新 runner Job,running runner 轮询 cancel 并中止 Codex stdio backend,终态使用 `cancelled`。 | diff --git a/docs/reference/spec-v01-agentrun-runner.md b/docs/reference/spec-v01-agentrun-runner.md index bb8253d..00eaa90 100644 --- a/docs/reference/spec-v01-agentrun-runner.md +++ b/docs/reference/spec-v01-agentrun-runner.md @@ -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--`。MVP 允许 CLI 启动受控本地 process,但该 process 仍必须通过 manager API claim/report。 +`v0.1` 默认 runner 形态是 `agentrun-v01` namespace 中的短生命周期 Job,Job 名称建议使用 `agentrun-v01-runner--`。短生命周期指 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 到 manager;backend_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-terminal,runner 在 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 status;live 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 status;live 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 只终结 command,run 保持可继续接后续 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` 切换联调。 | diff --git a/docs/reference/spec-v01-hwlab-manual-dispatch.md b/docs/reference/spec-v01-hwlab-manual-dispatch.md index 4709df7..88e0df2 100644 --- a/docs/reference/spec-v01-hwlab-manual-dispatch.md +++ b/docs/reference/spec-v01-hwlab-manual-dispatch.md @@ -6,7 +6,7 @@ - HWLAB `hwlab-cloud-api` 是业务 dispatcher:继续负责用户登录、session owner、device-pod 授权、Workbench `/v1/agent/chat` 合同、result/trace/cancel 对外接口和业务权限判断。 - AgentRun `agentrun-mgr` 是执行事实 authority:负责 run、command、event、runner job、backend profile、SecretRef、terminal status 和手动调度 API。 -- `agentrun-runner` 是短生命周期执行者:从 manager claim run、poll command、调用 backend adapter、append events、ack command、上报 terminal status。 +- `agentrun-runner` 是手动启动的执行者:从 manager claim run、poll command、调用 backend adapter、append events、ack command、上报 command terminal,并在同一 runner Job 生命周期内继续等待同 run 的后续 command;run terminal 只由显式 run cancel 或 runner 级不可恢复失败产生。 - HWLAB 不直接写 AgentRun Postgres、不读取 AgentRun Secret、不直接创建 Kubernetes Job;所有跨服务操作只走 AgentRun RESTful API。 - AgentRun 不内建 HWLAB device-pod/gateway 业务授权;涉及硬件、用户授权或 device lease 的判断仍由 HWLAB 自己完成。 @@ -17,6 +17,7 @@ - 不使用 SSE、WebSocket、long-polling 或长同步 `turn` 请求替代 durable resource 模型。 - 不把 HWLAB 的 provider Secret、device token、gateway route 或 kubeconfig 复制给业务客户端。 - 不把 mock、fixture、source-only smoke 或 dry-run 结果当作 HWLAB canary 通过证据。 +- 不把 trace、日志、诊断文案、降级原因或“已观测到缺口”当作功能完成。若 HWLAB v0.2 原有 Code Agent 需要的能力在 AgentRun v0.1 中缺失,必须补齐 AgentRun 自身能力;若实现未修复,必须修复实现本身,观测只作为定位和验收证据。 ## 目标调用链 @@ -28,6 +29,7 @@ HWLAB Workbench -> AgentRun POST /api/v1/runs/:runId/commands -> AgentRun POST /api/v1/runs/:runId/runner-jobs -> agentrun-runner claim/poll/report +-> 同一 run 后续 turn 复用已 claim 的 runner Job 继续 poll command -> AgentRun events/command status/terminal_status -> hwlab-cloud-api 映射为 HWLAB result/trace ``` @@ -44,7 +46,7 @@ AgentRun `v0.1` 承接 HWLAB v0.2 时,只吸收原有 Code Agent 的通用执 | 只有真实 terminal completed + 非空 reply 才算通过 | `docs/reference/code-agent-chat-readiness.md`、`internal/cloud/code-agent-chat.ts` | result envelope 和 terminal status 规则;partial、stdout、transport close 不升级为 completed | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | | runnerTrace 可见,能展示请求、工具、输出、错误和终态 | `internal/cloud/code-agent-trace-store.ts`、`web/hwlab-cloud-web/app-trace.ts` | 标准 event schema、单 run 内 seq 单调、bounded payload、Secret redaction | [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | | 取消正在执行的 turn | `internal/cloud/server-code-agent-http.ts`、`internal/cloud/codex-stdio-session.ts` | durable run/command cancel、pending 阻止启动、running interrupt、terminal 幂等返回 | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | -| conversation/session/thread 复用 | `internal/cloud/codex-stdio-session.ts`、`internal/cloud/code-agent-session-registry.ts` | `SessionRef` 保存 session/thread 摘要,runner 有 thread 则 resume,无 thread 则 start | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md) | +| conversation/session/thread 复用 | `internal/cloud/codex-stdio-session.ts`、`internal/cloud/code-agent-session-registry.ts` | `SessionRef` 保存 session/thread 摘要;同一 run/runner Job 处理后续 command,不重新 materialize bundle;runner 内每 turn 有 thread 则 resume,无 thread 则 start | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | | 固定 repo workspace 执行 | `internal/cloud/code-agent-contract.ts`、`docs/reference/code-agent-chat-readiness.md` | `ResourceBundleRef` 使用 Git-only `repoUrl + full commitId` checkout 到隔离 workspace | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md)、[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md) | | provider profile 隔离和 Secret 不泄露 | `internal/cloud/code-agent-contract.ts`、`docs/reference/code-agent-chat-readiness.md` | `ProfileRef/SecretRef` profile-scoped 投影、缺失为 `secret-unavailable`、禁止 fallback 和泄露值 | [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md)、[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) | | device-pod 短期会话 env 注入 | `internal/cloud/server-code-agent-http.ts` 的 `codeAgentDevicePodAuthEnv()` | `runner-jobs.transientEnv` 只在本次 Kubernetes Job env 中生效;只记录 name/count,不保存或输出 value | [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)、[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) | @@ -102,6 +104,8 @@ AgentRun 标准 events 必须稳定到足以被 HWLAB 转换: 面向 HWLAB 的 result envelope 至少应能回答:`status`、`terminalStatus`、`reply`、`failureKind`、`blocker`、`lastSeq`、`eventCount`、`artifactSummary`、`runId`、`commandId` 和 `attemptId`。partial assistant 文本、transport close、idle timeout 或 stdout 存在都不能单独升级为 `completed`。 +command terminal 与 run terminal 必须分离。普通 turn completed 只终结对应 command,并更新 SessionRef/thread 摘要;同一 run 保持可继续接收 command,已启动 runner Job 在 idle timeout 内继续 poll。只有显式 run cancel、runner 级不可恢复失败或未来 scheduler/retention 策略要求时,run 才进入 terminal。 + ### P0 cancel AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs/:runId/cancel` 或 `POST /api/v1/commands/:commandId/cancel`。cancel 必须幂等;已 terminal 的对象返回当前终态。pending command 被 cancel 后不得再创建 runner Job。running runner 必须通过 poll、lease 或 heartbeat 观察 cancel,并传播到 backend interrupt;backend 不支持 interrupt 时终止受控进程组。cancel 最终必须写入 event、command state 和 run status,`failureKind` 使用 `cancelled`。 @@ -122,7 +126,7 @@ AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs | 2 | trace/result 元语 | 标准 event 子集、terminal result envelope、bounded output metadata | HWLAB 可由 events 稳定生成 result/trace;partial 不误报 completed。 | | 3 | cancel 闭环 | durable cancel API、runner cancel poll、backend interrupt/process group stop | pending/running/terminal 后 cancel 均幂等且可见。 | | 4 | ResourceBundleRef materialization | Git-only checkout、workspace 前缀、commit/tree 摘要、failureKind | 使用 full commit;不接受 branch/tag/HEAD;不覆盖 Secret/session/runtime home。 | -| 5 | SessionRef 持久化 | session record/store、thread resume、TTL/GC、profile 隔离 | 同一 conversation 连续两轮可复用;不同 profile 不污染。 | +| 5 | SessionRef 持久化与 runner 多 turn | session record/store、thread resume、runner command loop、TTL/GC、profile 隔离 | 同一 conversation 连续两轮复用同一 run/runner Job;第二轮不重新 materialize bundle;不同 profile 不污染。 | | 6 | HWLAB v0.2 canary | HWLAB dispatcher adapter、traceId 映射、result/trace 转换 | 普通自然语言最短 turn 真实 completed 且 reply 非空;device-pod 仍由 HWLAB 授权。 | ## 测试规格 @@ -147,6 +151,10 @@ AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs 阅读本文和 [spec-v01-runtime-assembly.md](spec-v01-runtime-assembly.md),然后验证一次带 SessionRef 和 Git-only ResourceBundleRef 的 runner Job。确认 session 不含 credential 文件,bundle 使用 full commit checkout 到允许 workspace,event/result 能回答 session id、repo、commit 和 checkout 摘要。 +### T6 同 run/runner 后续 turn + +阅读本文和 [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md),然后在同一 run 中先提交第一条 turn command 并启动一次 runner Job;第一条 command completed 后,在同一 run 中提交第二条 turn command。确认第二条由同一 runner Job 在 idle timeout 内处理,run 未因第一条 completed 而 terminal,events 中 `resource-bundle-materialized` 只出现一次,两个 command result 分别可查且 reply 不互相串联。 + ## 实现状态 | 能力 | v0.1 状态 | 说明 | @@ -156,4 +164,5 @@ AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs | cancel | 已实现最小闭环 | 已提供 run/command cancel API;pending cancel 会阻止新 runner Job,running runner 通过轮询触发 backend abort,终态写入 event、command state 和 run status。 | | SessionRef | 已实现最小持久化 | run 可携带 `sessionRef`,manager 保存 session/thread,runner 会按 threadId resume,result envelope 暴露脱敏 session 摘要;TTL/GC 仍按后续运维策略细化。 | | ResourceBundleRef | 已实现 Git-only materialization | run 可携带 `repoUrl + full commitId`,runner checkout 到 `AGENTRUN_WORKSPACE_ROOT` 下的隔离目录并记录 commit/tree/workspace 摘要;上传文件和对象存储仍不进入 v0.1。 | +| 同 run/runner 多 turn | 已实现最小闭环 | runner Job 在 idle timeout 内持续 poll 同一 run 的后续 command;普通 turn completed 不终结 run,bundle 只 materialize 一次,command result 按 commandId 独立聚合。 | | HWLAB v0.2 canary | 待实现 | 需要 HWLAB dispatcher adapter 调 AgentRun 手动调度 API,并转换 result/trace。 |