193 lines
15 KiB
Markdown
193 lines
15 KiB
Markdown
# v0.1 AgentRun Queue 规格
|
||
|
||
本文定义 AgentRun Queue 直接吸收 UniDesk Code Queue 的长期规格。AgentRun Queue 是 AgentRun 内部任务队列基础设施,不是 UniDesk Code Queue 的适配层、代理层或兼容层。
|
||
|
||
## 核心决策
|
||
|
||
- 直接吸收 UniDesk Code Queue 的队列产品能力,不做 adapter 过渡、不双写、不长期兼容旧 Code Queue API、CLI 或 UI。
|
||
- 新任务只写入 AgentRun Queue;旧 UniDesk Code Queue 停止接收新任务,历史数据不迁移到 AgentRun,只在 UniDesk 侧保留归档或只读查询。
|
||
- 第一版只做 RESTful API、CLI 和轻量轮询,不做 Event System、OA Event Flow、OA sink、GitHub sink、notification sink 或 integrations 表。
|
||
- Queue 和 Session 分层:Queue 查询返回 `sessionPath`;输出、trace、debug 和会话控制统一转到 Session API/CLI。
|
||
- Queue 列表、统计、已读状态和 commander 视图必须直接查询 Queue summary/stats/read 模型,不从 Core execution trace 或 Session trace 反推。
|
||
- 废弃旧 MiniMax/OpenCode 直连支持。第一版只保留 Codex/Codex-compatible backend profile,例如现有 `codex`、`deepseek` 与 `minimax-m3` profile。
|
||
- 不吸收 UniDesk 环境提示。执行上下文必须显式来自 workspace/resource/profile/tool/SecretRef 等 AgentRun 合同,不能继承旧 Code Queue 的隐式 env hint。
|
||
|
||
## 职责边界
|
||
|
||
| 层 | 负责 | 不负责 |
|
||
| --- | --- | --- |
|
||
| AgentRun Queue | task、queue/lane、attempt、priority、retry policy、judge、task summary、attempt summary、queue stats、read cursor、commander 聚合 | 输出、trace、session 详情、OA、notification、GitHub action、旧 Code Queue 兼容 |
|
||
| AgentRun Session | execution session、输出、trace、命令流、debug/audit 详情、会话控制 | queue 列表、queue 统计、read cursor、commander 聚合 |
|
||
| AgentRun Core | run、command、runner job、lease、terminal status、backend 执行事实 | 业务队列产品语义、queue overview、外部协作 sink |
|
||
| AgentRun Scheduler | pending task/attempt 扫描、capacity、runner assignment、backoff、stale lease recovery | 直接执行 backend、维护旧 UniDesk scheduler、决定 tenant 业务授权 |
|
||
| UniDesk Legacy Code Queue | 旧数据只读归档和停用期排障 | 新任务入口、长期兼容层、执行 authority |
|
||
|
||
Queue 可以保存 attempt 与 Core run/command/runner job 的引用,但 Queue 不直接暴露 Core trace。需要看输出或 trace 时,调用方必须从 Queue 返回的 `sessionPath` 进入 Session API。
|
||
|
||
## RESTful API
|
||
|
||
第一版 Queue 公共 API 只使用短 HTTP JSON 请求和轻量轮询:
|
||
|
||
```http
|
||
POST /api/v1/queue/tasks
|
||
GET /api/v1/queue/tasks?queue=<queue>&state=<state>&cursor=<cursor>&limit=<limit>&updatedAfter=<seq>
|
||
GET /api/v1/queue/tasks/:taskId
|
||
POST /api/v1/queue/tasks/:taskId/cancel
|
||
POST /api/v1/queue/tasks/:taskId/read
|
||
POST /api/v1/queue/tasks/:taskId/dispatch
|
||
POST /api/v1/queue/tasks/:taskId/refresh
|
||
GET /api/v1/queue/stats?queue=<queue>
|
||
GET /api/v1/queue/commander?queue=<queue>
|
||
```
|
||
|
||
Session 公共 API 承接输出、trace 和会话控制:
|
||
|
||
```http
|
||
GET /api/v1/sessions/:sessionId
|
||
GET /api/v1/sessions?state=default&readerId=<reader>&backendProfile=<profile>&cursor=<cursor>&limit=<limit>
|
||
GET /api/v1/sessions/:sessionId/output?afterSeq=<seq>&limit=<limit>
|
||
GET /api/v1/sessions/:sessionId/trace?afterSeq=<seq>&limit=<limit>
|
||
POST /api/v1/sessions/:sessionId/read
|
||
POST /api/v1/sessions/:sessionId/control
|
||
```
|
||
|
||
Queue task 详情必须返回 session 引用,而不是代理输出或 trace:
|
||
|
||
```json
|
||
{
|
||
"taskId": "qt_123",
|
||
"state": "running",
|
||
"summary": "正在修改队列规格",
|
||
"version": 42,
|
||
"latestAttempt": {
|
||
"attemptId": "qa_456",
|
||
"state": "running",
|
||
"runId": "run_789",
|
||
"commandId": "cmd_001",
|
||
"sessionId": "sess_abc",
|
||
"sessionPath": "/api/v1/sessions/sess_abc"
|
||
}
|
||
}
|
||
```
|
||
|
||
`version`、`changeSeq`、`updatedAt` 或 `cursor` 是 Queue 自身的轮询水位,不是 Event System。它只服务于 RESTful 增量查询和 CLI 轮询。
|
||
|
||
## CLI 命令族
|
||
|
||
AgentRun CLI 必须提供 Queue 和 Session 两组命令。Queue 命令只操作队列资源:
|
||
|
||
```bash
|
||
./scripts/agentrun queue submit --json-file <task.json> [--dry-run]
|
||
./scripts/agentrun queue list [--queue <queue>] [--state <state>] [--cursor <cursor>] [--limit <limit>] [--full|--raw]
|
||
./scripts/agentrun queue show <taskId> [--full|--raw]
|
||
./scripts/agentrun queue stats [--queue <queue>]
|
||
./scripts/agentrun queue commander [--queue <queue>] [--reader-id <reader>] [--limit <display-limit>] [--full|--raw]
|
||
./scripts/agentrun queue read <taskId> [--reader-id <reader>] [--dry-run] [--full|--raw]
|
||
./scripts/agentrun queue cancel <taskId> [--reason <text>] [--dry-run] [--full|--raw]
|
||
./scripts/agentrun queue dispatch <taskId> [--json-file <dispatch.json>] [--dry-run] [--full|--raw]
|
||
./scripts/agentrun queue refresh <taskId> [--dry-run] [--full|--raw]
|
||
```
|
||
|
||
Session 命令负责输出、trace 和会话控制:
|
||
|
||
```bash
|
||
./scripts/agentrun sessions ps [--state default|running|unread|terminal|idle|all] [--profile codex|deepseek|minimax-m3|M3] [--reader-id <reader>]
|
||
./scripts/agentrun sessions show <sessionId> [--reader-id <reader>]
|
||
./scripts/agentrun sessions turn [sessionId] --json-file <run-base.json> --prompt-file <file> [--profile codex|deepseek|minimax-m3|M3]
|
||
./scripts/agentrun sessions steer <sessionId> --prompt-file <file>
|
||
./scripts/agentrun sessions cancel <sessionId> [--reason <text>]
|
||
./scripts/agentrun sessions output <sessionId> [--after-seq <seq>] [--limit <limit>]
|
||
./scripts/agentrun sessions trace <sessionId> [--after-seq <seq>] [--limit <limit>]
|
||
./scripts/agentrun sessions read <sessionId> [--reader-id <reader>]
|
||
```
|
||
|
||
不得新增 `queue output`、`queue trace` 或 `queue session/*` 这类子路径代理。`queue list/show/commander` 默认输出低噪声 summary,最多打印 task/attempt/session ids、状态、统计、`sessionPath`、compact supervisor 和下一步 `sessions ...` 命令;supervisor 只允许披露 phase、last activity source seq/id、timeout budget 和恢复动作摘要,不得展开完整 payload、trace、tool command、stdout/stderr 或 runnerTrace。完整 payload/resource bundle/metadata 只能通过显式 `--full|--raw` 展开;trace/output 细节继续按 `sessionId` + `sourceSeq/eventId/itemId` 走 Session CLI 渐进披露。Queue mutation 命令带 `--dry-run` 时必须只返回 `mutation=false` 的计划,不得写 Queue、Core run/command 或 runner job。
|
||
|
||
Queue task 的 `resourceBundleRef` 在 dispatch 时原样进入 Core run。若其中声明 `requiredSkills`,Queue 只展示声明和终态摘要,不能自行判定可用;runner 必须在 gitbundle materialization 后、backend 启动前校验 `.agents/skills/<name>/SKILL.md`,缺失时以 `required-skill-unavailable` 写入 command/run result 和 events。
|
||
|
||
## 数据模型方向
|
||
|
||
Queue 首版新增或扩展的稳定表方向:
|
||
|
||
- `agentrun_queue_tasks`:任务 identity、tenant/project、queue/lane、title、priority、state、backendProfile、workspace/resource 引用、可选 `sessionRef`、创建者、version 和 timestamps。
|
||
- `agentrun_queue_attempts`:attempt identity、taskId、runId、commandId、runnerJobId、sessionId、state、failureKind、retry index 和 timestamps。
|
||
- `agentrun_task_summaries`:task 级摘要、当前状态、最新 attempt、最新 sessionPath、最后用户可见摘要和统计字段。
|
||
- `agentrun_attempt_summaries`:attempt 级摘要、terminalStatus、failureKind、runner identity、耗时和有界输出摘要引用。
|
||
- `agentrun_queue_stats`:按 queue/lane/state/backendProfile 聚合的轻量统计,可由 Queue 写入或按 Queue 表查询生成。
|
||
- `agentrun_queue_read_cursors`:按 user/agent/client 和 queue/task 记录已读水位。
|
||
- `agentrun_queue_judge_runs`:judge 请求、结果、failureKind、重试建议和与 attempt 的关联。
|
||
- `agentrun_task_references`:issue、PR、repo、commit、文档或外部上下文的显式引用,不保存 UniDesk 隐式环境提示。
|
||
|
||
第一版不得新增 `integrations`、`notification_deliveries`、`observability_exports`、`oa_events`、`oa_sinks` 或类似外部动作表。GitHub、notification、OA、外部审计和协作动作如果后续需要,必须作为独立 connector/sink 规格追加,不能混入 Queue 首版数据模型。
|
||
|
||
## Code Queue 吸收映射
|
||
|
||
| 旧 Code Queue 能力 | AgentRun 目标 | 吸收方式 | 不保留内容 |
|
||
| --- | --- | --- | --- |
|
||
| task 记录 | `agentrun_queue_tasks` | 直接建模为 Queue task;需要 trace/reuse 时必须携带 `sessionRef` 并在 dispatch 后暴露 `sessionPath` | 旧 API 字段兼容 |
|
||
| queueId、move、merge | queue/lane 字段和 Queue API | 保留队列归类与移动语义 | 旧 UI 操作合同 |
|
||
| attempt | `agentrun_queue_attempts` + Core run/command/runner job | attempt 引用真实执行资源 | 旧 attempt 输出结构 |
|
||
| `processQueue` / `runTask` | AgentRun Scheduler | 由 Scheduler 扫描 pending task/attempt 并创建 runner job | UniDesk Code Queue scheduler |
|
||
| `runCodexTurn` | Codex app-server stdio backend | 复用协议和 failure 分类经验 | 环境专用路径和明文凭据 |
|
||
| 旧 MiniMax/OpenCode 直连执行 | 无 | 废弃 | fallback、兼容配置、judge backend |
|
||
| activeRuns / active slot | Scheduler capacity 和 lease | 合并进 AgentRun 调度/lease 模型 | 旧内存状态 authority |
|
||
| judge | `agentrun_queue_judge_runs` | 使用 Codex-compatible judge profile 或规则 judge | MiniMax judge |
|
||
| prompt history / steer / resume / cancel | Queue audit + Session/Core control | Queue 记录任务级控制意图,执行细节走 Session/Core | 直接向旧 runner 写进程状态 |
|
||
| output / trace view | Session API | Queue 只返回 `sessionPath` 和 summary | Queue 代理输出或 trace |
|
||
| readAt | `agentrun_queue_read_cursors` | 保留已读水位 | 从 trace 推导已读 |
|
||
| commander | `agentrun_queue_stats` + `agentrun_task_summaries` | 直接从 Queue summary/stats 聚合 | 从 Core trace 反推 commander |
|
||
| task references | `agentrun_task_references` | 保留显式引用 | 隐式环境提示 |
|
||
| GitHub / notification / OA | deferred connector/sink | 首版不做 | 首版 integrations 表 |
|
||
| 旧 Postgres task 表 | UniDesk archive | 不迁移历史数据 | 作为 AgentRun source of truth |
|
||
| UniDesk Web UI | deferred client surface | 首版不做 | Web/Playwright 验收 |
|
||
|
||
## 实施顺序
|
||
|
||
| 阶段 | 目标 | 验收重点 |
|
||
| --- | --- | --- |
|
||
| Q0 | 固化 Queue SPEC 和 schema migration 计划 | 文档与旧 Code Queue 兼容口径不冲突。 |
|
||
| Q1 | Queue RESTful API 和 CLI 骨架 | submit/list/show/stats/read/cancel 全部短返回 JSON,不触发真实执行也能保存 task。 |
|
||
| Q2 | attempt 到 Core run/command/runner job 的真实闭环 | Queue submit 后通过受控 `queue dispatch` 产生 attempt,并创建真实 Core run/command/runner job;`queue refresh` 从 Core run/command 终态回写 Queue attempt;自动 Scheduler 仍 deferred。 |
|
||
| Q3 | Session 引用边界 | `queue show` 返回 `sessionPath`,输出和 trace 只能通过 `sessions ...` 查询。 |
|
||
| Q4 | summary/stats/read/commander | Queue overview、stats、read cursor、commander 全部直接查 Queue 模型。 |
|
||
| Q5 | retry/judge/cancel | retry/backoff、judge、cancel 与 attempt/session/core 状态一致。 |
|
||
| Q6 | 冻结旧 UniDesk Code Queue 新任务入口 | 新任务只进入 AgentRun Queue;旧系统只归档或只读。 |
|
||
|
||
## 验收规格
|
||
|
||
单元测试和组件自测试可以使用 mock、fake backend 或内存 store。最终 CLI 交互验收必须在真实 AgentRun runtime 上手动执行,不使用 mock,不写自动交互脚本,不做 Web 或 Playwright 验收。
|
||
|
||
Queue Q2 的真实手动验收必须覆盖以下稳定边界:
|
||
|
||
- `queue submit` 只创建 Queue task,不触发自动 scheduler。
|
||
- `queue dispatch` 是受控手动调度入口,必须创建 Core run、command 和 runner job,并把 attempt 引用写回 Queue task。
|
||
- `queue refresh` 只读取 Queue task 保存的 run/command 引用,将 Core 终态回写到 Queue task 和 latestAttempt;不得读取 Core trace、Session trace 或 events 来反推 Queue stats/commander。
|
||
- `queue submit/read/cancel/dispatch/refresh --dry-run` 必须只返回计划,不得改变 task state、read cursor、attempt、run、command 或 runner job。
|
||
- `queue show/list/stats/commander` 的统计口径必须来自 Queue 模型;默认输出必须有界,输出、trace 和会话控制继续由 Session API/CLI 承接。
|
||
- 综合联调里的 `workspaceRef` 必须是 runner 实际可访问且能启动 backend command 的工作区。`opaque` workspace 可用于不依赖 Git checkout 的最小 Queue dispatch 验收;`host-path` 只有在该 path 在 runner 容器/进程内可访问且不破坏 Codex command resolution 时才能作为通过证据。
|
||
- 因 workspace 形态导致的 backend command spawn 失败,应归类为 runtime workspace/command 一致性问题,不能误判为 Queue dispatch 或 Queue refresh 失败。
|
||
|
||
首版通过标准:
|
||
|
||
- `queue submit/list/show/stats/read/cancel` 均通过正式 CLI 和 RESTful API 返回非空 JSON。
|
||
- 至少一个真实 task 通过 Queue attempt 触发真实 Codex/Codex-compatible backend,并进入 terminal 状态。
|
||
- `queue show` 返回 `sessionPath`;输出、trace 和会话控制只能通过 Session API/CLI 完成。
|
||
- Queue overview、stats、read cursor 和 commander 视图来自 Queue summary/stats/read 表或等价 Queue 查询,不读取 Core trace 反推。
|
||
- 不存在 OA/Event/OA sink/GitHub/notification/integrations 首版表和首版必需流程。
|
||
- 旧 MiniMax/OpenCode 直连入口、配置、fallback 和 judge 路线不作为 AgentRun Queue 首版能力;MiniMax-M3 只能作为 Codex-compatible `minimax-m3` profile 使用。
|
||
- 旧 UniDesk Code Queue 不接收新任务;历史数据不迁移到 AgentRun。
|
||
- CLI、API、日志、summary、trace 和 Session 输出不泄露 Secret value、token、DSN password 或 URL credential。
|
||
|
||
## 规格的实现情况
|
||
|
||
| 规格项 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| AgentRun Queue 直接吸收规格 | 已定义 | 本文为 Queue 吸收 Code Queue 的首版权威规格。 |
|
||
| Queue RESTful API | 已实现/Q1 | 已通过 `agentrun-mgr` 暴露 `submit/list/show/stats/read/cancel/commander`,使用短请求和 Queue version/cursor 轻量轮询;Q2 再接入 attempt 与真实执行。 |
|
||
| Queue CLI | 已实现/Q1 | 已加入 `queue submit/list/show/stats/commander/read/cancel`;Queue 命令只返回 task summary、stats、read cursor 和 `sessionPath`。 |
|
||
| Queue dispatch/refresh | 已实现/Q2 | `queue dispatch` 受控创建 Core run/command/runner job;`queue refresh` 从 Core run/command 终态回写 Queue task/latestAttempt;自动 Scheduler 仍 deferred。 |
|
||
| Session API/CLI | 已实现/Q3 | Queue 只返回 `sessionPath`;Session 层已承接 `ps/show/turn/steer/cancel/output/trace/read`,默认列表只显示 running/unread。 |
|
||
| Scheduler 接入 | 待实现 | 旧 Code Queue scheduler 不保留;AgentRun Scheduler 是唯一调度方向。 |
|
||
| OA/Event/integrations | 不采用 | 首版不做,后续如需外部 connector/sink 必须单独立规格。 |
|
||
| 历史迁移 | 不采用 | 旧 Code Queue 历史数据不迁移到 AgentRun。 |
|