52 lines
8.9 KiB
Markdown
52 lines
8.9 KiB
Markdown
# AgentRun Code Agent Dispatch
|
||
|
||
本文定义 HWLAB Code Agent 通过 AgentRun `v0.1` 手动调度 API 执行时的装配边界。它只描述稳定的 payload、SecretRef 和 credential 归属,不替代当前 G14 DEV `/v1/agent/chat` 的真实 completed 判定。
|
||
|
||
## 装配入口
|
||
|
||
- 源码入口是 `internal/agent/agentrun-dispatch.mjs`。
|
||
- `createHwlabAgentRunDispatchAssembly()` 生成 AgentRun `POST /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`。
|
||
|
||
## 会话和执行边界
|
||
|
||
- HWLAB `conversationId` / `sessionId` / `threadId` 是用户可见业务会话 authority;AgentRun `runId` / `commandId` / `runnerJobId` 是执行尝试 identity;AgentRun `SessionRef` 和 per-session PVC 承载 backend/profile 的续接状态。不要把新建 AgentRun run/job 等同于新建 HWLAB session,也不要把复用 workspace selection 当作 session state。
|
||
- HWLAB adapter 调 AgentRun 时必须固定使用 AgentRun policy 边界字段:`tenantId=hwlab`、`projectId=pikasTech/HWLAB`、`providerId=G14`。HWLAB Workbench 的 project/workspace 标识只能作为 `metadata.hwlabProjectId`、`metadata.hwlabWorkspaceId` 或 `workspaceRef` 子字段保存,不能写入 AgentRun `projectId`。如果运行面出现 `tenant-policy-denied`、project mismatch 或 workspace project 污染,临时处理是修 adapter 的字段归一化并重放最小真实请求,不放宽 AgentRun tenant policy。
|
||
- `providerProfile` 由显式 HWLAB session 负责。`client agent session create --provider-profile <profile>` 建立 session 的 provider profile,并映射为 AgentRun `backendProfile`;后续 `client agent send --session-id <sessionId>` 在未显式传 `--provider-profile` 时必须继承该 session 的 `providerProfile`。账号 workspace 的 provider profile 只在 workspace 当前 selected session 与本次目标 session 完全一致时作为 fallback;旧 workspace 状态不得覆盖显式 session。
|
||
- 同一 HWLAB session 的 resume 判定看同一个 `sessionId`、`threadId`、`providerProfile/backendProfile`、AgentRun `SessionRef` 和 PVC,而不是只看是否复用了同一个 AgentRun `runId` 或 runner Job。runner pod 被删、Job 被重建或 lease 失效后的临时恢复可以创建 replacement run/job,但只有在复用同一 `SessionRef`/PVC/thread、没有拼接历史 prompt 且 assistant 能看到前序上下文时,才算 session 持久化恢复证据;它不替代 runner reuse window 内复用同一 run/runner 的长期目标。
|
||
|
||
## 架构混乱处理
|
||
|
||
- 临时处理:排查 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、fake `thread/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 引用,默认随 `backendProfile` 选择 `agentrun-v01-provider-deepseek`、`agentrun-v01-provider-codex` 或 `agentrun-v01-provider-minimax-m3`。
|
||
- Provider API Key 的 Web 配置面归属 HWLAB `v0.2` 管理页,HWLAB Cloud API 通过已鉴权的管理接口委托 AgentRun 后端更新 profile Secret/配置;dispatch 路径只消费 AgentRun 返回的 SecretRef,不接收浏览器提交的 API Key 原文。完整管理规格见 [spec-v02-provider-management.md](spec-v02-provider-management.md)。
|
||
- GitHub PR/issue 能力通过 `toolCredentials[].tool=github` 注入,默认 SecretRef 是 `agentrun-v01-tool-github-pr` key `GH_TOKEN`。
|
||
- UniDesk SSH passthrough 通过 `toolCredentials[].tool=unidesk-ssh` 注入,默认 SecretRef 是 `agentrun-v01-tool-unidesk-ssh` key `UNIDESK_SSH_CLIENT_TOKEN`。
|
||
- `UNIDESK_SSH_CLIENT_TOKEN` 只授予 UniDesk frontend `/ws/ssh` scoped client 能力;route allowlist 由 UniDesk frontend 配置控制。HWLAB 不持有 provider token、主 server SSH key 或完整 frontend 登录态。
|
||
- `runnerJob.transientEnv` 只能承接本次 runner job 需要的短期执行上下文,例如 owner-scoped `HWLAB_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 device-pod 能力在 runner 内只通过 `hwpod -> HWLAB_RUNTIME_API_URL -> hwlab-cloud-api` 进入。`HWLAB_RUNTIME_API_URL` 指向当前 namespace 的 `hwlab-cloud-api` Service;`HWLAB_RUNTIME_WEB_URL` 仅供需要浏览器同源语义的工具查看 Cloud Web。AgentRun 不以 Cloud Web 代理替代设备 API。
|
||
|
||
## ResourceBundle
|
||
|
||
- AgentRun run 必须使用 Git-only `resourceBundleRef`,默认 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` 为准。
|
||
- 默认 `toolAliases` 会把 `tools/device-pod-cli.mjs` 暴露为 `hwpod`,并把 `tools/unidesk-ssh.mjs` 暴露为 runner shell 内的 `unidesk-ssh` 命令。Device Pod、D601-F103-V2、Keil build/download、job status/output 和 UART/debug-probe 操作必须优先走 `hwpod`;`unidesk-ssh` 只用于 UniDesk passthrough 任务,不能替代 Device Pod 正式路径。
|
||
- Device Pod lease 不是独立 runner 控制命令;标准 `hwpod` surface 只提交命名 Device Pod job。需要 lease 时,token 只能作为 `--lease-token` 跟随实际 mutating job 请求转发给 cloud-api。Agent 不得调用 `hwpod lease ...`,也不得新增 gateway shell 或其他 fallback 来绕过 job authority。
|
||
- 默认 `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。
|
||
- 默认 `skillRefs` 指向 `skills/device-pod-cli/SKILL.md` 和 `skills/hwlab-agent-runtime/SKILL.md`,都为 `required=true`,由 AgentRun 聚合到当前 workspace `.agents/skills/<name>/SKILL.md`。HWLAB 不再依赖 `/app/skills`、hostPath、默认 Codex skill registry、ConfigMap 或用户长 prompt 作为 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 能力都通过 AgentRun `toolCredentials` SecretRef 装配,且 runner resource bundle 默认暴露 `hwpod`、`unidesk-ssh`、`promptRefs` 和 `skillRefs`。
|
||
- 真实 CLI 验收默认使用短 prompt 走 `backendProfile=deepseek`:首轮 prompt “不调用工具的情况下,你可见的 skill 有哪些?”应能回答 HWLAB bundle skill;同一会话 continuation 应显示 AgentRun 原生 resume 语义且不重复注入 initial prompt;“编译 D601-F103-V2”应触发 `hwpod` Device Pod 路径,若失败则报告正式 blocker,不切换 fallback。
|
||
- 如果 DeepSeek profile 的 trace 明确失败为 AgentRun `provider-auth-failed`,且上游错误码或消息是 `INSUFFICIENT_BALANCE` / account balance 不足,则该次 CLI 验收改用 `--provider-profile minimax-m3` 继续执行同一短 prompt 组。这个规则只替换 provider profile,不替换 AgentRun 装配标准:仍必须使用同一个 `ResourceBundleRef`、`promptRefs`、`skillRefs`、`toolAliases`、Codex stdio `thread/start` / `thread/resume`,不得拼接历史上下文,不得切回旧 HWLAB prompt/skill 注入方式,也不得用 codex-api、generic shell、gateway shell 或诊断镜像作为替代验收。
|