Files
pikasTech-agentrun/docs/reference/spec-v01-hwlab-manual-dispatch.md
T
2026-06-02 15:40:48 +08:00

19 KiB
Raw Blame History

v0.1 HWLAB 手动调度接入规格

本文定义 AgentRun v0.1 面向 HWLAB v0.2 的下一阶段服务目标:不以前置自动 scheduler 为条件,而是通过 agentrun-mgr 的手动调度 API 为 HWLAB 提供 canary Code Agent 执行服务。实施跟踪见 pikasTech/agentrun#31

在系统中的职责划分

  • 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、上报 command terminal,并在同一 runner Job 生命周期内继续等待同 run 的后续 commandrun terminal 只由显式 run cancel 或 runner 级不可恢复失败产生。
  • HWLAB 不直接写 AgentRun Postgres、不读取 AgentRun Secret、不直接创建 Kubernetes Job;所有跨服务操作只走 AgentRun RESTful API。
  • AgentRun 不内建 HWLAB device-pod/gateway 业务授权;涉及硬件、用户授权或 device lease 的判断仍由 HWLAB 自己完成。

非目标

  • 本阶段不要求自动 scheduler、pending scan、capacity selection 或长驻调度器。
  • 不改变 HWLAB 对外 /v1/agent/chat/result/trace/cancel 用户合同。
  • 不使用 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 自身能力;若实现未修复,必须修复实现本身,观测只作为定位和验收证据。

目标调用链

HWLAB Workbench
-> hwlab-cloud-api /v1/agent/chat
-> HWLAB 用户/session/device 权限判断
-> AgentRun POST /api/v1/runs
-> 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

HWLAB 应保存 traceId -> runId/commandId/attemptId/jobName 映射。用户轮询 HWLAB result/trace 时,HWLAB 从 AgentRun command status 与 run events 读取进展,再转换为 HWLAB 自己的前端 schema;浏览器不直接理解 AgentRun 内部 event schema。

HWLAB v0.2 Code Agent 能力吸收基线

AgentRun v0.1 承接 HWLAB v0.2 时,只吸收原有 Code Agent 的通用执行能力,不吸收 HWLAB 的用户鉴权、device-pod 授权、Workbench UI 或业务 trace schema。下表是后续实现时的代码追溯入口,目的是复用 HWLAB 已验证的边界和判定标准,而不是重新发明一套 Agent 行为。

HWLAB v0.2 原有能力 HWLAB 代码/文档追溯入口 AgentRun 自身承接点 SPEC 归属
短连接 submit + result/trace 轮询 internal/cloud/server-code-agent-http.tsdocs/reference/spec-v02-hwlab-cloud-api.md run + command + runner-job 三段式手动调度,所有写操作短返回 JSON spec-v01-agentrun-mgr.md
只有真实 terminal completed + 非空 reply 才算通过 docs/reference/code-agent-chat-readiness.mdinternal/cloud/code-agent-chat.ts result envelope 和 terminal status 规则;partial、stdout、transport close 不升级为 completed spec-v01-agentrun-mgr.mdspec-v01-backend-adapter.md
runnerTrace 可见,能展示请求、工具、输出、错误和终态 internal/cloud/code-agent-trace-store.tsweb/hwlab-cloud-web/app-trace.ts 标准 event schema、单 run 内 seq 单调、bounded payload、Secret redaction spec-v01-backend-adapter.mdspec-v01-agentrun-runner.md
取消正在执行的 turn internal/cloud/server-code-agent-http.tsinternal/cloud/codex-stdio-session.ts durable run/command cancel、pending 阻止启动、running interrupt、terminal 幂等返回 spec-v01-agentrun-mgr.mdspec-v01-agentrun-runner.md
conversation/session/thread 复用 internal/cloud/codex-stdio-session.tsinternal/cloud/code-agent-session-registry.ts SessionRef 保存 session/thread 摘要;同一 run/runner Job 处理后续 command,不重新 materialize bundlerunner 内每 turn 有 thread 则 resume,无 thread 则 start spec-v01-runtime-assembly.mdspec-v01-agentrun-runner.md
固定 repo workspace 执行 internal/cloud/code-agent-contract.tsdocs/reference/code-agent-chat-readiness.md ResourceBundleRef 使用 Git-only repoUrl + full commitId checkout 到隔离 workspace spec-v01-runtime-assembly.mdspec-v01-agentrun-runner.md
provider profile 隔离和 Secret 不泄露 internal/cloud/code-agent-contract.tsdocs/reference/code-agent-chat-readiness.md ProfileRef/SecretRef profile-scoped 投影、缺失为 secret-unavailable、禁止 fallback 和泄露值 spec-v01-runtime-assembly.mdspec-v01-backend-adapter.md
device-pod 短期会话 env 注入 internal/cloud/server-code-agent-http.tscodeAgentDevicePodAuthEnv() runner-jobs.transientEnv 只在本次 Kubernetes Job env 中生效;只记录 name/count,不保存或输出 value spec-v01-agentrun-mgr.mdspec-v01-secret-distribution.md
UniDesk SSH passthrough HWLAB Code Agent 通过 tran 访问 G14/D601/HWLAB/GitHub 维护面 toolCredentials[].tool=unidesk-ssh 注入 UNIDESK_SSH_CLIENT_TOKENtransientEnv 只注入非敏感 UNIDESK_MAIN_SERVER_IPUniDesk frontend 负责 route allowlist spec-v01-runtime-assembly.mdspec-v01-secret-distribution.md
provider/backend/cancel 等失败可区分 scripts/src/code-agent-response-contract.mjsinternal/cloud/code-agent-chat.ts failureKind 最小矩阵和 JSON 错误响应 spec-v01-agentrun-mgr.mdspec-v01-backend-adapter.md
stdout/stderr/tool 输出必须有界 docs/reference/code-agent-chat-readiness.mdinternal/cloud/code-agent-trace-store.ts command_output/tool_call 记录摘要、字节数、截断标记和必要引用 spec-v01-backend-adapter.md
runner/job 失败需要定位证据 internal/cloud/server-code-agent-http.ts 的 trace/result 可见性 runner job identity、attempt、jobName、pod/log identity 和最小 phase/exit 摘要 spec-v01-agentrun-runner.mdspec-v01-agentrun-mgr.md

手动调度 API

POST /api/v1/runs/:runId/runner-jobs 是 HWLAB canary 的正式手动调度入口。它只负责为一个已存在 run 和 command 显式创建 runner Job,不负责扫描 pending queue。

请求最小字段:

字段 规则
commandId 必填,必须属于 runId
attemptId 可选;未提供时由 manager 生成,返回值必须可持久查询。
idempotencyKey HWLAB 必须用 traceIdmessageId 或等价稳定 key;相同 key 和相同 payload 返回既有 job/attempt。
image / backendImageRef 只能来自 manager allowlist、GitOps/catalog 或受控默认值;客户端不能传任意镜像扩大执行面。
retention / ttlSecondsAfterFinished 可选;默认遵循 runner Job TTL 规格。
transientEnv 可选,只用于本次 runner Job 的 Kubernetes env 渲染;不得写入 run/command/result/event 明文。用于承接 HWLAB 原 Code Agent 的短期 device-pod session token 和 API URL。

响应必须短返回 JSON,不等待完整模型 turn,至少包含:runIdcommandIdattemptIdjobNamenamespacerunnerIdlogPathpodIdentity、后续 commands showevents 轮询入口。重复提交若 payload 不同,必须结构化失败,不能创建第二个同名业务 attempt。

transientEnv 是 runner-job 层的临时执行上下文,不是 AgentRun run 的 durable fact。manager 不对条目数量设固定上限,只校验数组形态、env name 合法且唯一、value 非空和单值长度;payload hash 只保存 value hashresponse、event、dry-run manifest 和错误详情不得输出明文 value。业务授权仍由 HWLAB 自己负责,AgentRun 只把调度方明确提供的短期 env 交给本次 runner。UniDesk SSH passthrough 的长期 token 不得放入 transientEnvHWLAB dispatcher 只能把 UNIDESK_MAIN_SERVER_IP 这类非敏感定位信息放入 transientEnv,并通过 run executionPolicy.secretScope.toolCredentials[] 请求 tool=unidesk-ssh

Run / Command 映射

HWLAB canary 创建 run 时应使用以下字段口径:

字段 HWLAB canary 口径
tenantId hwlab
projectId pikasTech/HWLAB
providerId G14,只表示目标 provider,不授予 HWLAB 业务权限。
backendProfile deepseekcodexminimax-m3,由 HWLAB 或调度方显式选择;缺少 matching SecretRef 必须失败,不 fallback。
workspaceRef 必须引用 ResourceBundleRef 中的 Git-only full commit;不得由 runner 猜 host path。
executionPolicy sandbox、network、timeout、secretScope 必须显式,不得由 HWLAB 扩大 AgentRun Secret 范围。
executionPolicy.secretScope.toolCredentials[] 需要 UniDesk SSH passthrough 时必须声明 tool=unidesk-sshpurpose=ssh-passthrough、SecretRef agentrun-v01-tool-unidesk-ssh、projection env UNIDESK_SSH_CLIENT_TOKEN;不得把 token 放入 command payload 或 runner-job transientEnv。
traceSink 可指向 HWLAB trace adapter;为 null 时 HWLAB 仍可通过 AgentRun events 轮询。

Command 第一阶段要求 type=turntype=steerturn 保存用户原始 prompt、conversation metadata、profile 选择和 HWLAB trace correlationsteer 保存运行中引导文本,并由 runner 在同 run active turn 期间转发到 backend。业务 cancel 仍走 run/command cancel API,不用 steer 伪装。不得把 cookie、session token、provider credential、device internal token 或 Secret value 写入 payload。

需要补齐的能力

P0 trace/result 元语

AgentRun 标准 events 必须稳定到足以被 HWLAB 转换:

  • backend_statusprofile、backendKind、protocol、attempt、resource/session 摘要,不包含 Secret 值。
  • assistant_message:用户可见 assistant 文本,允许分片但必须能聚合为最终 reply。
  • tool_call:工具名、状态、bounded 参数摘要和 redacted correlation。
  • command_outputstdout/stderr/diff 的 bounded summary、原始字节数、截断标记和 artifact/log 引用。
  • errorfailureKind、message、retryable、provider/infra/backend 分类和 redacted details。
  • terminal_statuscompletedfailedblockedcancelled,是 completed 的唯一终态来源。

面向 HWLAB 的 result envelope 至少应能回答:statusterminalStatusreplyfailureKindblockerlastSeqeventCountartifactSummaryrunIdcommandIdattemptId。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/cancelPOST /api/v1/commands/:commandId/cancel。cancel 必须幂等;已 terminal 的对象返回当前终态。pending command 被 cancel 后不得再创建 runner Job。running runner 必须通过 poll、lease 或 heartbeat 观察 cancel,并传播到 backend interruptbackend 不支持 interrupt 时终止受控进程组。cancel 最终必须写入 event、command state 和 run statusfailureKind 使用 cancelled

P1 SessionRef 持久化

SessionRef 需要从 null/deferred 升级为可选持久会话引用,支持 HWLAB conversationId/sessionId/threadId 到 AgentRun session identity 的映射。session 只能保存 backend thread/session/cache,不保存 API KEY、auth.jsonconfig.toml 或完整 CODEX_HOME。session store 必须与 Secret projection、writable runtime home、Git workspace 分离。runner 启动时,只按 command payload.threadIdSessionRef.threadId 执行 thread/resume,没有标准 threadId 则执行 thread/startevents、result 和 session record 都以 threadId 为唯一 thread identityprofile 隔离、TTL、GC 和跨 profile 污染防护必须可见。

P1 ResourceBundleRef / bundle materialization

ResourceBundleRef 必须按 Git-only 模型落地:repoUrl + full commitId 是唯一内容身份。runner 只能 checkout 到允许 workspace 前缀,不能覆盖 /app、Secret projection、profile runtime home 或 session 目录。第一阶段支持 subdirsparsePathssubmodules=falselfs=falsecredentialRef 的最小字段即可。HWLAB canary 只需要 pikasTech/HWLAB 固定 full commit 的普通 checkout;用户上传文件和对象存储 artifact 不进入 v0.1

分阶段增强计划

阶段 目标 主要交付 验收重点
1 手动调度 API 固化 runner-jobs request/response schema、idempotency、job identity、CLI 调同一 REST API 重复 key 不重复创建;短返回;manager 重启后可查。
2 trace/result 元语 标准 event 子集、terminal result envelope、bounded output metadata HWLAB 可由 events 稳定生成 result/tracepartial 不误报 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 持久化与 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 授权。

测试规格

T1 手动调度 API

阅读本文和 spec-v01-agentrun-mgr.md,然后在真实 agentrun-v01 runtime 中用 RESTful API 创建 tenantId=hwlab 的 run、提交 turn command、调用 POST /api/v1/runs/:runId/runner-jobs。确认每个 API 返回 JSON、60 秒内返回、不等待完整 turn,并返回 job identity 与后续 poll 入口。

T2 幂等和重复提交

阅读本文,然后用相同 idempotencyKey 重复调用 runner job API。相同 payload 必须返回同一 attempt/job;不同 payload 必须结构化失败,且不能创建第二个 runner Job。

T3 trace/result 映射

阅读本文和 spec-v01-backend-adapter.md,然后执行真实 Codex stdio turn,确认 events 中存在可转换为 HWLAB result/trace 的 backend_status、assistant 或 error、terminal_status,且 bounded output metadata 足够判断截断和 artifact 引用。

T4 cancel

阅读本文,然后分别验证 pending cancel、running cancel、重复 cancel 和 terminal 后 cancel。确认 command/run 终态、events 和 failureKind 均为 cancelled 或当前既有 terminal 状态,日志不泄露 Secret。

T5 SessionRef 与 ResourceBundleRef

阅读本文和 spec-v01-runtime-assembly.md,然后验证一次带 SessionRef 和 Git-only ResourceBundleRef 的 runner Job。确认 session 不含 credential 文件,bundle 使用 full commit checkout 到允许 workspaceevent/result 能回答 session id、repo、commit 和 checkout 摘要。

T6 同 run/runner 后续 turn

阅读本文和 spec-v01-agentrun-runner.md,然后在同一 run 中先提交第一条 turn command 并启动一次 runner Job;第一条 command completed 后,在同一 run 中提交第二条 turn command。确认第二条由同一 runner Job 在 idle timeout 内处理,run 未因第一条 completed 而 terminalevents 中 resource-bundle-materialized 只出现一次,两个 command result 分别可查且 reply 不互相串联。

实现状态

能力 v0.1 状态 说明
手动 runner Job API 已实现 runner job 通过 manager REST 创建 Kubernetes Job,支持 idempotencyKey、持久 runner job record、job identity、attempt/runner/jobName 返回和重复 payload 冲突保护。
trace/result 元语 已实现最小合同 新增 run/command result envelope,聚合 terminal status、reply、failureKind、event cursor、artifact summary、attempt、SessionRef 和 ResourceBundleRef 摘要。
cancel 已实现最小闭环 已提供 run/command cancel APIpending cancel 会阻止新 runner Jobrunning runner 通过轮询触发 backend abort,终态写入 event、command state 和 run status。
SessionRef 已实现最小持久化 run 可携带 sessionRefmanager 保存 session/threadrunner 会按 threadId resumeresult envelope 暴露脱敏 session 摘要;TTL/GC 仍按后续运维策略细化。
ResourceBundleRef 已实现 Git-only materialization run 可携带 repoUrl + full commitIdrunner checkout 到 AGENTRUN_WORKSPACE_ROOT 下的隔离目录并记录 commit/tree/workspace 摘要;上传文件和对象存储仍不进入 v0.1。
同 run/runner 多 turn 已实现最小闭环 runner Job 在 idle timeout 内持续 poll 同一 run 的后续 command;普通 turn completed 不终结 runbundle 只 materialize 一次,command result 按 commandId 独立聚合。
HWLAB v0.2 canary 待实现 需要 HWLAB dispatcher adapter 调 AgentRun 手动调度 API,并转换 result/trace。