10 KiB
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 应构建为小型服务族:
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: 契约骨架
只定义最小资源模型和状态机:
RunCommandEventRunnerBackend
第一切片只要求 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 可以新增
agentrunCLI/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:
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:
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 应保持本地/私有且最小:
GET /health
GET /debug/status
不要依赖客户端调用短生命周期 runner Pod 地址。该方式在 Job、namespace、host-native backend 和重启场景下都会变脆。
Command 状态
Command 是 durable resource。turn、steer、interrupt 和 resume 不能实现为 client 到 runner 的同步进程调用。
初始 command 状态机:
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 类别:
systemassistant_messagetool_callcommand_outputdifferrorbackend_statusterminal_status
数据模型方向
v0.1 使用 Postgres 作为唯一 durable store;file、sqlite、JSONL 或 Pod 本地目录只能用于临时测试或日志,不作为运行面事实来源。第一版实现可以使用紧凑 schema,但不应把所有事实都隐藏在一个 JSON blob 中。稳定方向是:
agentrun_schema_migrations:migration id、checksum 和 applied timestamp;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。
Postgres DSN、provider API Key 和未来 tenant credential 的分发边界见 spec-v01-secret-distribution.md;source、GitOps、event、trace、日志和 CLI 输出都不得保存 Secret 明文。
部署方向
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。