12 KiB
AgentRun Code Agent Dispatch
本文定义 HWLAB Code Agent 通过 AgentRun v0.1 调度 API 执行时的装配边界,也是 nested/child Code Agent provider profile 继承语义的唯一权威出处。它只描述稳定的 payload、SecretRef、credential、session/profile 归属和验收判定;CLI/Web 的用户入口只交叉引用本文,不重复定义继承规则。
装配入口
- 源码入口是
internal/agent/agentrun-dispatch.mjs。 createHwlabAgentRunDispatchAssembly()生成 AgentRunPOST /api/v1/runs、POST /api/v1/runs/:runId/commands和POST /api/v1/runs/:runId/runner-jobs三段 payload。dispatchHwlabAgentRun()使用同一 assembly 顺序调用 AgentRun manager;调用方可以注入fetchImpl做合同测试或接入真实 manager。- 默认 manager URL 是
http://agentrun-mgr.agentrun-v01.svc.cluster.local:8080,默认 namespace 是agentrun-v01,默认 providerId 是G14,默认 workspace branch 是v0.2。 - 人工和 agent 触发 HWLAB Code Agent 任务时,优先使用已成型的
hwlab-cli client agent session create/send/result/trace、Workbench 同路径 API 或 CaseRun 封装入口;只有在修 adapter/dispatcher/合同测试时才手写 AgentRun payload。排查 provider、API key、session 或 trace 问题时,先用这些 CLI 原入口确认 runtime config、SecretRef、session、trace 和 result,再定位具体组件,不把问题绕成 generic provider API、runner shell、直连 Cloud API 或临时脚本路径。
会话和执行边界
- HWLAB
conversationId/sessionId/threadId是用户可见业务会话 authority;AgentRunrunId/commandId/runnerJobId是执行尝试 identity;AgentRunSessionRef和 per-session PVC 承载 backend/profile 的续接状态。不要把新建 AgentRun run/job 等同于新建 HWLAB session,也不要把复用 workspace selection 当作 session state。 - AgentRun
type=steercommand 是作用在既有 target trace/target command 上的控制命令,不创建新的 HWLAB session,也不改变业务conversationId/sessionId/threadId。HWLAB closeout 和 UI 展示必须同时保留 target command identity 与steerCommandId,并从原 target trace 观察agentrun:steer:accepted/agentrun:steer:command-created。steer command 创建成功只证明短连接控制动作已被 AgentRun 接收;目标 turn 后续 terminal 状态按原 command/result 判定。 - HWLAB adapter 调 AgentRun 时必须固定使用 AgentRun policy 边界字段:
tenantId=hwlab、projectId=pikasTech/HWLAB、providerId=G14。HWLAB Workbench 的 project/workspace 标识只能作为metadata.hwlabProjectId、metadata.hwlabWorkspaceId或workspaceRef子字段保存,不能写入 AgentRunprojectId。如果运行面出现tenant-policy-denied、project mismatch 或 workspace project 污染,临时处理是修 adapter 的字段归一化并重放最小真实请求,不放宽 AgentRun tenant policy。 - 显式 HWLAB session 是用户可见 provider profile authority。
client agent session create --provider-profile <profile>建立 session 的providerProfile,Cloud API 在 dispatch 时映射为 AgentRunbackendProfile;后续client agent send --session-id <sessionId>在未显式传--provider-profile时继承该 session 的providerProfile。workspace 只记录当前已选 session 和展示 seed,不能作为 child agent profile 继承来源,也不得用旧 workspace 状态覆盖显式 session。 - 同一 HWLAB session 的 resume 判定看同一个
sessionId、threadId、providerProfile/backendProfile、AgentRunSessionRef和 PVC,而不是只看是否复用了同一个 AgentRunrunId或 runner Job。runner pod 被删、Job 被重建或 lease 失效后的临时恢复可以创建 replacement run/job,但只有在复用同一SessionRef/PVC/thread、没有拼接历史 prompt 且 assistant 能看到前序上下文时,才算 session 持久化恢复证据;它不替代 runner reuse window 内复用同一 run/runner 的长期目标。
Provider Profile 与 Child Agent 继承
Nested/child hwlab-code-agent spawn 的 provider profile 继承只走环境变量通道。有效来源和优先级固定为:
- 显式
spawn --profile <profile>。 - runner 环境变量
HWLAB_CODE_AGENT_PROVIDER_PROFILE。
未提供这两项时,spawn 必须 fail fast 返回 provider_profile_required。不得从 skills/hwlab-code-agent/config.json、账号 workspace、Cloud API 默认值、runner 默认 deepseek、历史 session、模型名或 profile 静态 allowlist 推断 child profile;也不得用 silent fallback 掩盖缺失配置。
Parent -> child 传播链固定如下:外层 HWLAB request/session 解析出 providerProfile -> Cloud API/AgentRun adapter 解析当前 AgentRun backendProfile -> runner job transientEnv 注入 HWLAB_CODE_AGENT_PROVIDER_PROFILE=<backendProfile> 和 HWLAB_CODE_AGENT_PARENT_TRACE_ID=<traceId> -> runner 内的 hwlab-code-agent spawn 在没有显式 --profile 时读取该环境变量。HWLAB_CODE_AGENT_PARENT_TRACE_ID 只用于 trace/diagnostic 关联,不参与 profile 选择。
可见性必须跟随同一链路:spawn JSON 输出暴露 resolvedProviderProfile、profileSource 和 parentTraceId;child trace/result 必须暴露真实 providerProfile/backendProfile、AgentRun infrastructure backend、provider 和 model。CaseRun d601-f103-v2-leader-review 使用 dsflash-go 时,Leader -> Coder/Reviewer child traces 应落到 trc_dsflash-go_*,child result backend 为 agentrun-v01/dsflash-go,model 为 deepseek-v4-flash,并由 compile check 与 reviewer verdict 形成业务通过证据。
Provider profile slug 与配置是 AgentRun profile 管理数据,不是 Cloud API/Web 每次新增 slug 都要修改代码的枚举。HWLAB 已鉴权 CLI/Web/API 通过 spec-v02-provider-management.md 委托 AgentRun 管理 profile config/credential/validate;只有共享运行面、bridge、SecretRef 约定或镜像变化才进入 GitOps/CI/CD。
架构混乱处理
- 临时处理:排查 CLI/Web/Cloud API/AgentRun 对 session、project、provider 或 run/job 的口径不一致时,先收集 HWLAB session status、workspace selection、trace/result、AgentRun run/job env、
SessionRef、PVC phase 和 command events;以单变量热补丁证明最小链路,再回到源码 PR/CI/CD/原入口复测。不得通过长 prompt、历史 messages、fakethread/resume:completed、放宽 tenant policy 或手工改 DB lease 来掩盖缺口。 - 长期建议:跨仓库 schema 必须把
hwlabProjectId/agentRunProjectId、providerProfile/backendProfile、hwlabSessionId/agentRunSessionId、runId/sessionId分成不同字段;Web 和 CLI 应同时展示业务 session/thread/provider 与执行 run/job/command,避免 operator 把执行尝试误判为业务会话迁移。
Credential 边界
- Provider credential 只通过
executionPolicy.secretScope.providerCredentials[]的 AgentRun provider SecretRef 引用。默认 SecretRef 随backendProfile解析为agentrun-v01-provider-<backendProfile>;历史 alias 只允许表达已有 Secret 命名事实,例如codex-api -> codex。动态 profile(如dsflash-go)不得要求 HWLAB service 代码新增 allowlist 后才能 dispatch。 - Provider API Key 的 Web 配置面归属 HWLAB
v0.2管理页,HWLAB Cloud API 通过已鉴权的管理接口委托 AgentRun 后端更新 profile Secret/配置;dispatch 路径只消费 AgentRun 返回的 SecretRef,不接收浏览器提交的 API Key 原文。完整管理规格见 spec-v02-provider-management.md。 - GitHub PR/issue 能力通过
toolCredentials[].tool=github注入,默认 SecretRef 是agentrun-v01-tool-github-prkeyGH_TOKEN。 - UniDesk SSH passthrough 通过
toolCredentials[].tool=unidesk-ssh注入,默认 SecretRef 是agentrun-v01-tool-unidesk-sshkeyUNIDESK_SSH_CLIENT_TOKEN。 UNIDESK_SSH_CLIENT_TOKEN只授予 UniDesk frontend/ws/sshscoped client 能力;route allowlist 由 UniDesk frontend 配置控制。HWLAB 不持有 provider token、主 server SSH key 或完整 frontend 登录态。runnerJob.transientEnv只能承接本次 runner job 需要的短期执行上下文,例如 owner-scopedHWLAB_API_KEY、HWLAB_RUNTIME_API_URL和UNIDESK_MAIN_SERVER_IP;敏感项必须标记 sensitive,不得承载 GitHub token、UniDesk SSH client token、provider key、长期 SSH key 或 registry token。- HWLAB v0.2 HWPOD 能力在 runner 内只通过
hwpod -> hwpod-compiler-cli -> HWLAB_RUNTIME_API_URL -> hwlab-cloud-api /v1/hwpod-node-ops进入。HWLAB_RUNTIME_API_URL指向当前 namespace 的hwlab-cloud-apiService;HWLAB_RUNTIME_WEB_URL仅供需要浏览器同源语义的工具查看 Cloud Web。AgentRun 不以 Cloud Web 代理替代 HWPOD API。
ResourceBundle
- AgentRun run 必须使用
ResourceBundleRef.kind="gitbundle",默认 repo 是http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git。 commitId必须是完整 40 字符小写 SHA,不接受 branch、tag、HEAD或短 SHA;workspaceRef只描述目标 repo/branch,默认 branch 是v0.2,实际 checkout 身份以resourceBundleRef.repoUrl + commitId为准。- 默认
bundles[]只有两项:{ name: "hwlab-tools", subpath: "tools", target_path: "tools" }和{ name: "hwlab-agent-skills", subpath: "skills", target_path: ".agents/skills" }。不得再发送toolAliases、skillRefs、workspaceFiles、subdir或sparsePaths。 - repo 自身必须提供 extensionless 工具入口,例如
tools/hwpod、tools/hwpod-ctl、tools/hwpod-compiler、tools/unidesk-ssh和tools/hwlab-code-agent;AgentRun 只把 materializedtools/加入 PATH,不再生成 alias wrapper。 - HWPOD 快速阶段没有独立 lease 控制命令;标准
hwpodsurface 只提交 HWPOD intent,经 compiler 生成 node-ops。Agent 不得新增 gateway shell 或其他 fallback 来绕过hwpod -> hwpod-compiler -> /v1/hwpod-node-ops -> hwpod-node。 - 默认
promptRefs指向internal/agent/prompts/hwlab-v02-runtime.md,inject=thread-start且required=true。该 prompt 只在 AgentRun/Codex stdio 新 thread 首轮注入;后续 turn 必须依赖原生thread/resume,不得在 command payload 中拼接历史、旧 skill 列表或长业务 prompt。 - skills 由
skills/subtree 作为整体复制到.agents/skills。HWLAB 不再依赖/app/skills、hostPath、默认 Codex skill registry、ConfigMap、workspace seed files、workspaceFiles或用户长 prompt 作为 AgentRun runner 的 skill 注入 fallback。 - AgentRun runtime image 已预装
gh,结合tool=github注入的GH_TOKEN即可访问 HWLAB/UniDesk PR 与 issue;不得把 GitHub token 放入 prompt 或transientEnv。
验收
- 源码合同测试:
node --test internal/agent/agentrun-dispatch.test.mjs。 - 语法检查:
node --check internal/agent/agentrun-dispatch.mjs && node --check internal/agent/agentrun-dispatch.test.mjs。 - 合同必须证明
UNIDESK_SSH_CLIENT_TOKEN不出现在transientEnv,GitHub/UniDesk SSH 能力都通过 AgentRuntoolCredentialsSecretRef 装配,且 runner resource bundle 默认使用kind="gitbundle",trace 暴露bundles、tools、promptRefs和skillDirs。 - 真实 CLI 验收必须使用目标 profile 显式创建 session,例如
--provider-profile dsflash-go,再发送至少一个不传--provider-profile的 turn,证明 send 继承 session profile;不得因为某个 provider 失败自动切换 profile 并把结果记为原 profile 通过。 - Nested profile 继承验收必须覆盖 runner env:父 AgentRun result/trace 显示目标
backendProfile,childspawn输出resolvedProviderProfile=<profile>、profileSource=env、parentTraceId=<outerTraceId>,child trace/result 使用同一个 profile/model/backend。缺少任意字段时先修可见性,不新增旧 fallback、旧门禁或兼容分支。