# AgentRun 架构参考 AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行面。它不是 UniDesk Code Queue 的改名,也不能默认替换现有 Code Queue 行为。Code Queue 仍是当前 UniDesk 任务队列;AgentRun 是新的基础设施线,重点是 Agent run 生命周期、runner 隔离和可插拔执行 backend。 ## 产品边界 AgentRun 负责通用执行基础设施: - 创建和跟踪 run; - 接收 `turn`、`steer`、`interrupt`、`resume` 等 durable command; - 将 run 分配给短生命周期 runner; - 归一化 backend event、stdout/stderr、assistant message、tool call 和 terminal status; - 管理 lease、heartbeat、基础设施恢复导致的 retry 语义和 run 可观测性; - 注册 backend capability,并定义 credential 注入边界。 UniDesk 与 HWLAB 是 tenant/client。UniDesk 负责平台入口、provider 清单、CLI/frontend 集成和现有 Code Queue 兼容。HWLAB 负责实验室任务 policy、设备/硬件语义、operation/audit/evidence 模型和 HWLAB workspace 规则。AgentRun 不判断某个 HWLAB live device mutation 是否被授权,也不判断某个 UniDesk production deployment 是否允许执行;它只执行 tenant policy 已授权的 run。 每个 run 都必须显式携带隔离字段: - `tenantId`,例如 `unidesk` 或 `hwlab`; - `projectId`,例如 `pikasTech/unidesk` 或 `pikasTech/HWLAB`; - `workspaceRef`,用于定位 source/worktree/workspace; - `providerId`,例如 `G14` 或 `D601`; - `backendProfile`,例如 `codex`、`opencode`、`claudecode`、`host-native` 或 `windows-native`; - `executionPolicy`,包含 sandbox、approval、timeout、network 和 secret scope; - `traceSink`,说明标准化 event 镜像到哪里。 ## 服务形态 AgentRun 应构建为小型服务族: ```text agentrun-mgr 公共 RESTful API、durable facts、tenant/policy/idempotency 检查 agentrun-runner 短生命周期 per-run 或 per-attempt executor;claim 一个 run,连接一个 backend,写回 events/status agentrun-backend-* Codex、Claude Code、OpenCode、host-native 或 Windows-native 执行适配器 agentrun-scheduler 后续自动 dispatcher;扫描 pending runs,选择 backend/profile/capacity,创建 runner Jobs ``` Manager 是稳定 API 和审计点。Runner 是执行者,不应成为业务客户端直接调用的公共 API。MVP 阶段 operator 可以人工启动 runner 进程或 Kubernetes Job,但 runner 仍必须从 `agentrun-mgr` claim run,并把所有事实写回 manager。 Backend adapter 隐藏具体工具协议。Codex stdio JSON-RPC、OpenCode JSON events、Claude Code、host-native process 和 Windows-native execution 可以使用不同内部协议,但 AgentRun 公共 API 必须保持稳定且与 backend 无关。 ## MVP 顺序 AgentRun 必须按纵向切片推进,不要一开始大规模并行开发。 ### M0: 契约骨架 只定义最小资源模型和状态机: - `Run` - `Command` - `Event` - `Runner` - `Backend` 第一切片只要求 `turn`、`interrupt`、`status` 和分页 `events`。不要一开始就做 `steer`、`resume`、judge/retry、UI、多 backend 路由或自动调度。 ### M1: 最小 Runner 加一个 Backend 第一份可执行证明不依赖 manager 或 scheduler。Runner 读取本地 run spec,调用一个 backend,并输出标准化 events。 验收标准: - 一个 `turn` 能通过 backend 执行; - assistant/output/error events 被归一化; - terminal status 被写出; - interrupt 至少有 durable cancellation 路径,backend 支持时再传播到真实进程中断。 第一个 backend 应选择能证明真实 Agent 原语的最窄实现。如果 Codex 摩擦过大,可以短暂用 controlled process backend 证明 contract shape,但 MVP 必须尽快回到一个真实 Agent backend,否则不能认为上层已验证。 ### M2: Manager 加 Runner Claim 加入 `agentrun-mgr` 作为 durable fact store 和公共 API。Client 创建 run;operator 或 CLI 用 run id 人工启动 runner;runner claim、poll commands、append events、heartbeat 并退出。 验收标准: - run create/query 是 durable 的; - runner claim 幂等,并拒绝双 owner; - events 是 append-only,并按 seq 分页; - command ack state 可见; - heartbeat expiration 可观察。 ### M3: 手动 Dispatch CLI 增加 CLI,为指定 run 启动本地 runner process 或 Kubernetes Job。这是 manual dispatch,不是 manager 侧同步编排。Manager 仍拥有事实,runner 仍拥有执行。 验收标准: - CLI 快速返回 JSON; - job/process identity 和 log path 可见; - run status 可从 manager 轮询; - runner 启动失败被报告为基础设施失败,不能静默写成任务成功。 ### M4: 自动 Scheduler 只有 M1-M3 稳定后才加入 `agentrun-scheduler`。Scheduler 扫描 pending runs,应用 policy/capacity/backend selection,创建 runner Jobs,并处理 stale lease recovery。Scheduler 不直接执行 backend。 验收标准: - pending run 自动变为 running; - scheduler restart 不影响已经运行的 runner; - stale lease recovery 留下显式 audit event; - scheduler rollout 不等同于 active run failure。 ### M5: Tenant Canary 集成 核心生命周期证明后,再接入 UniDesk 和 HWLAB canary: - UniDesk 可以新增 `agentrun` CLI/API route,同时保持现有 Code Queue 不变。 - HWLAB 可以把一个窄范围 Code Agent canary 路由到 AgentRun。 - 每个 run 都必须显式带 tenant policy、workspace、secret scope 和 trace sink。 ## RESTful MVP 契约 MVP 只使用短 RESTful HTTP/JSON 请求。长时间 Agent 工作用 durable command resource、run status 和分页 event polling 表示。不要让一个 HTTP 请求等待完整模型 turn。 Manager 公共 API: ```http POST /api/v1/runs GET /api/v1/runs/:runId GET /api/v1/runs/:runId/events?afterSeq=0&limit=100 POST /api/v1/runs/:runId/commands GET /api/v1/runs/:runId/commands/:commandId GET /api/v1/backends ``` 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 API 应保持本地/私有且最小: ```http GET /health GET /debug/status ``` 不要依赖客户端调用短生命周期 runner Pod 地址。该方式在 Job、namespace、host-native backend 和重启场景下都会变脆。 ## Command 状态 Command 是 durable resource。`turn`、`steer`、`interrupt` 和 `resume` 不能实现为 client 到 runner 的同步进程调用。 初始 command 状态机: ```text accepted -> delivered -> confirmed accepted -> delivered -> failed accepted -> expired ``` 所有 command 写入都应支持 idempotency key。相同 idempotency key 且 payload hash 相同的重复请求返回既有 command;相同 key 但 payload hash 不同必须显式失败。 ## Event 模型 Event 是 append-only,并按 seq 分页: - `seq` 在单个 run 内单调递增。 - `eventId` 或 `(runId, seq)` 支持幂等去重。 - `GET /events?afterSeq=N&limit=M` 是第一阶段观察 API。 - 后续 SSE 可以流式传输相同 event resource,但不能替代 REST polling contract。 最小 event 类别: - `system` - `assistant_message` - `tool_call` - `command_output` - `diff` - `error` - `backend_status` - `terminal_status` ## 数据模型方向 第一版实现可以使用紧凑 schema,但不应把所有事实都隐藏在一个 JSON blob 中。稳定方向是: - `agentrun_runs`:run identity、tenant/project/workspace/backend policy、status 和 timestamps; - `agentrun_commands`:command type、idempotency key、payload hash、state 和 ack timestamps; - `agentrun_events`:按 run 和 seq 索引的 append-only event records; - `agentrun_runners`:registered runner identity、placement 和 heartbeat; - `agentrun_backends`:backend profile、capabilities、capacity 和 health; - `agentrun_leases`:当前 ownership 和 expiry。 ## 部署方向 AgentRun 从 `v0.1` 开始按版本 lane 滚动,废弃 `dev/prod` 管理口径。`v0.1` 的固定 source workspace 是 `G14:/root/agentrun-v01`,固定 source branch 是 `v0.1`,固定运行目标是 G14 原生 k3s namespace `agentrun-v01`。后续 `v0.2`、`v0.3` 必须拥有自己的 branch、workspace、namespace、GitOps branch、runtime path 和发布验收。 Control-plane service 应是长驻服务;runner 应是短生命周期 Job 或受控 host-native process。Backend adapter 可以作为 pod 或 host-native service 运行,但必须通过 AgentRun 注册 capability 和 health,不能通过临时地址被 ad hoc 调用。 广泛 tenant 使用前,需要先设计 namespace isolation、RBAC、Secret scope、NetworkPolicy 和 ResourceQuota。独立 cluster 是后续成熟选项;第一版应优先在 `agentrun-v01` namespace 内证明服务,除非出现明确隔离 blocker。`agentrun_dev` 和 `agentrun_prod` 不再作为当前架构规格或验收目标。 ## MVP 非目标 第一版 MVP 不包含: - 迁移 UniDesk Code Queue; - 全局替换 HWLAB Code Agent; - 多 backend 路由; - 最小诊断之外的 UI; - judge/retry 自动化; - 自动扩缩容; - 跨集群调度; - SSE/WebSocket 流式输出; - 完整权限系统; - production rollout 自动化。 第一目标是稳定跑通一条纵向 run 生命周期:create run、人工启动 runner、执行一个 backend turn、append events、观察 final status,并能发出可见的 interrupt/cancel command。