feat: add session subagent cli control

This commit is contained in:
Codex
2026-06-03 11:27:55 +08:00
parent a40fdf6ab1
commit b761ef6713
12 changed files with 833 additions and 34 deletions
+9
View File
@@ -43,9 +43,17 @@ POST /api/v1/runs/:runId/runner-jobs
GET /api/v1/runs/:runId/runner-jobs?commandId=<commandId>
GET /api/v1/runs/:runId/runner-jobs/:runnerJobId
POST /api/v1/commands/:commandId/cancel
GET /api/v1/sessions?state=default&readerId=cli&backendProfile=<profile>&cursor=<cursor>&limit=50
GET /api/v1/sessions/:sessionId?readerId=cli
GET /api/v1/sessions/:sessionId/trace?afterSeq=0&limit=100&runId=<runId>
GET /api/v1/sessions/:sessionId/output?afterSeq=0&limit=100&runId=<runId>
POST /api/v1/sessions/:sessionId/read
POST /api/v1/sessions/:sessionId/control
GET /api/v1/backends
```
Session API 是异步 subagent 的轻量控制面。`state=default` 必须只返回 running 和 unread session`state=all` 才返回历史 read session。command/run 进入 terminal 后,所属 session 的 projection 必须进入 `executionState=terminal` 并 bump version,使未读 reader 在 `ps/default` 中看到它;`POST /read` 写入 reader cursor 后,该 session 不再出现在该 reader 的默认列表中。`trace/output` 只分页读取所属 run 的 events,不代理 Queue summary`control action=cancel` 取消 active command 或 active run。
面向 HWLAB v0.2 canary 的手动调度 API 目标见 [spec-v01-hwlab-manual-dispatch.md](spec-v01-hwlab-manual-dispatch.md)。`runner-jobs` 只显式启动当前 run/command 的 runner Job,不扫描 pending queue,不等待完整模型 turn;自动 scheduler 仍是 deferred 能力。后续 durable cancel API 必须与同一 run/command 状态机衔接,不能让 HWLAB 直接删除 Kubernetes Job 作为正式取消语义。
Runner 私有 API 的 `v0.1` 范围:
@@ -163,6 +171,7 @@ Manager 只承接 HWLAB v0.2 Code Agent 的通用执行事实,不承接 HWLAB
| Manager REST API | 已实现/已通过主闭环 | 已有 run、command、event、backends、runner register、claim、lease heartbeat、poll、ack、status、runner Job 创建和 health/readiness 的 HTTP JSON API;真实 runtime 已通过 RESTful API 主闭环。 |
| 手动 runner Job API | 已实现 | `POST /api/v1/runs/:runId/runner-jobs` 已可创建 Kubernetes runner Job,并固化 idempotency、持久 runner job record、响应 schema 和 cancel 前置检查。 |
| runner Job 状态查询 | 已实现 | `GET /api/v1/runs/:runId/runner-jobs``GET /api/v1/runs/:runId/runner-jobs/:runnerJobId` 返回 attempt/job/log/phase/terminal 摘要,业务客户端无需直连 Kubernetes 做最小定位。 |
| Session 控制面 API | 已实现/Q3 | 已提供 `list/show/trace/output/read/control(cancel)`session projection 保存 running/terminal、active run/command、last event seq 和 read cursor,用于 CLI `ps/unread`。 |
| command/run terminal 分离 | 已实现最小闭环 | `PATCH /api/v1/commands/:commandId/status` 终结 command 并更新 SessionRef;普通 turn completed 不终结 runrun status 仅由 run cancel 或 runner 级不可恢复失败终结。 |
| Tenant policy boundary | 已实现最小边界 | v0.1 已做 schema、tenant/backend allowlist、executionPolicy 和 secretScope 结构校验;业务授权仍由 UniDesk/HWLAB 自己判定。 |
| `deepseek` backendProfile allowlist | 已实现/已通过主闭环 | Manager validation、backend capability 和 matching SecretRef 校验已支持 `deepseek`;真实 runtime 已经通过 CI/CD 发布并确认 Postgres migration `002_v01_backend_profiles` 应用。 |
+13 -6
View File
@@ -63,10 +63,14 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
./scripts/agentrun queue cancel <taskId> [--reason <text>]
./scripts/agentrun queue dispatch <taskId> [--json-file <dispatch.json>]
./scripts/agentrun queue refresh <taskId>
./scripts/agentrun sessions show <sessionId|sessionPath>
./scripts/agentrun sessions output <sessionId|sessionPath> [--cursor <cursor>] [--limit <limit>]
./scripts/agentrun sessions trace <sessionId|sessionPath> [--cursor <cursor>] [--limit <limit>]
./scripts/agentrun sessions control <sessionId|sessionPath> --json-file <control.json>
./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] [--runner-json-file <job.json>] [--no-runner-job]
./scripts/agentrun sessions steer <sessionId> --prompt-file <file>
./scripts/agentrun sessions cancel <sessionId> [--reason <text>]
./scripts/agentrun sessions trace <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>]
./scripts/agentrun sessions output <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>]
./scripts/agentrun sessions read <sessionId> [--reader-id <reader>]
```
具体参数可以在实现时按代码结构微调,但行为必须保持:
@@ -85,6 +89,9 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
- `queue dispatch` 是 Q2 的受控手动调度入口,只对单个 task 显式创建 attempt 和 Core run/command/runner job;不得伪装成自动 scheduler。
- `queue refresh` 只根据 Queue task 中保存的 Core run/command 引用回写 Queue attempt 状态,不读取 Core trace 反推 commander 或统计。
- `queue show` 必须返回 task/attempt summary、state、read cursor、stats 相关字段和 `sessionPath`;不得返回或代理完整 output/trace。
- `sessions ps` 默认只显示 running 和 unread session`--state all` 才显示历史 read session,避免旧 session 噪声淹没当前进度。
- `sessions turn` 是异步 subagent 的受控 CLI 入口:短返回 run、command、runnerJob 和后续 poll/read/steer/cancel 命令,不等待模型完成。`--profile M3``minimax-m3` 的 CLI aliasprofile 仍写入 canonical `backendProfile`,不得 fallback。
- `sessions steer` 对当前 active run 创建 `type=steer` command`sessions cancel` 通过 Session control 取消 active command 或 run`sessions read` 写入 reader cursor,使 terminal session 从默认 ps 中消失。
- `sessions output``sessions trace` 是输出和 trace 的唯一 CLI 查询入口;不得新增 `queue output``queue trace` 兼容命令。
## 配置与 Secret 边界
@@ -134,7 +141,7 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
| Queue CLI | 已实现/Q1 | 已提供 `queue submit/list/show/stats/commander/read/cancel`,通过 manager REST 访问 Queue task 和 stats,不直连 Postgres。 |
| Queue dispatch/refresh CLI | 已实现/Q2 | `queue dispatch` 受控创建 Core run/command/runner job`queue refresh` 从 Core run/command 终态回写 Queue task/latestAttempt。 |
| 本地 server 生命周期 CLI | 已实现/Q2 hardening | `server start` 默认后台短返回,`server status/stop` 提供 pid、port、logPath 和 readiness 可见性;`--foreground` 保留给容器/显式调试。 |
| Session CLI | 实现 | 规格见 [spec-v01-queue.md](spec-v01-queue.md);输出和 trace 进入 Session 命令,Queue 命令不得代理 output/trace。 |
| Session CLI | 实现/Q3 | 已提供 `sessions ps/show/turn/steer/cancel/trace/output/read`;默认 ps 只显示 running/unreadterminal 后自动 unreadread cursor 由 CLI 标记。 |
| CLI 测试规格 | 已定义/已验证主闭环 | 综合联调见 [spec-v01-validation.md](spec-v01-validation.md);每次发布仍按手动交互验收复跑。 |
| `deepseek` profile CLI | 已实现/已通过主闭环 | `secrets codex render --profile deepseek``backends list``runner start --backend``runner job` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调已通过 `codex -> deepseek -> codex` 切换主闭环。 |
| `minimax-m3` profile CLI | 已实现/待真实主闭环 | `secrets codex render --profile minimax-m3``backends list``runner start --backend``runner job` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调需要按 `codex -> deepseek -> minimax-m3 -> codex` 手动验收。 |
| `minimax-m3` profile CLI | 已实现/待真实主闭环 | `secrets codex render --profile minimax-m3``backends list``runner start --backend``runner job``sessions turn --profile minimax-m3|M3` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调需要按 `codex -> deepseek -> minimax-m3 -> codex` 手动验收。 |
+4 -3
View File
@@ -35,7 +35,8 @@ Secret 名称和 key 可以在实现时按 Kubernetes 命名限制微调,但
- `agentrun_events`:按 run 和 seq 索引的 append-only event records。
- `agentrun_runners`registered runner identity、placement、heartbeat 和 capability snapshot。
- `agentrun_runner_jobs`:手动 runner Job 的 idempotency key、payload hash、attempt/job identity 和创建响应。
- `agentrun_sessions`SessionRef 到 backend thread/cache identity 的最小映射,不保存 credential 文件或 Secret 值。
- `agentrun_sessions`SessionRef 到 backend thread/cache identity、execution projection、active run/command、terminal/unread 水位的映射,不保存 credential 文件或 Secret 值。
- `agentrun_session_read_cursors`:按 reader 记录 Session 已读 version,用于 CLI 默认只看 running/unread。
- `agentrun_queue_tasks`AgentRun Queue task identity、queue/lane、tenant/project、priority、state、backendProfile、workspace/resource 引用和 version。
- `agentrun_queue_attempts`task attempt identity、runId、commandId、runnerJobId、sessionId、state、failureKind、retry index 和 timestamps。
- `agentrun_task_summaries` / `agentrun_attempt_summaries`Queue 列表、详情和 commander 使用的轻量摘要;不能从 Core trace 反推 overview。
@@ -83,7 +84,7 @@ Secret 名称和 key 可以在实现时按 Kubernetes 命名限制微调,但
| --- | --- | --- |
| Postgres durable store 规格 | 已定义 | 本文为 v0.1 存储权威。 |
| StatefulSet/Service/PVC | 已实现/已通过主闭环 | `agentrun-v01-postgres` StatefulSet、Service 和 PVC 已由 GitOps runtime 提供,作为 `agentrun-v01` durable store。 |
| migration ledger | 已实现/已通过主闭环 | `agentrun-mgr` 启动 Postgres adapter 时幂等创建 `agentrun_schema_migrations` 并记录 migration id/checksum;当前最新 migration 为 `005_v01_minimax_m3_backend_profile`,用于在不改写既有 migration checksum 的前提下新增 `minimax-m3` backend profilereadiness 必须显示 migration ready。 |
| manager Postgres adapter | 已实现/已通过主闭环 | `agentrun-mgr` 通过 `DATABASE_URL` 启用 Postgres adapter,持久化 runs、commands、events、runners、runner_jobs、sessions、backends、leases、Queue task 和 read cursor;缺少 `DATABASE_URL` 时 live runtime fail fastmemory 只允许显式 self-test/dev。 |
| migration ledger | 已实现/已通过主闭环 | `agentrun-mgr` 启动 Postgres adapter 时幂等创建 `agentrun_schema_migrations` 并记录 migration id/checksum;当前最新 migration 为 `006_v01_session_control`,用于在不改写既有 migration checksum 的前提下新增 session projection/read cursorreadiness 必须显示 migration ready。 |
| manager Postgres adapter | 已实现/已通过主闭环 | `agentrun-mgr` 通过 `DATABASE_URL` 启用 Postgres adapter,持久化 runs、commands、events、runners、runner_jobs、sessions、session read cursors、backends、leases、Queue task 和 read cursor;缺少 `DATABASE_URL` 时 live runtime fail fastmemory 只允许显式 self-test/dev。 |
| health/readiness store 状态 | 已实现 | health/readiness 返回 adapter、reachable、migrationReady、migrationId、failureKind 和 redacted Secret 状态,不输出 DSN 明文。 |
| file/sqlite durable store | 不采用 | 只可用于临时本地测试,不作为 v0.1 runtime truth。 |
+13 -7
View File
@@ -44,8 +44,10 @@ Session 公共 API 承接输出、trace 和会话控制:
```http
GET /api/v1/sessions/:sessionId
GET /api/v1/sessions/:sessionId/output?cursor=<cursor>&limit=<limit>
GET /api/v1/sessions/:sessionId/trace?cursor=<cursor>&limit=<limit>
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
```
@@ -89,10 +91,14 @@ AgentRun CLI 必须提供 Queue 和 Session 两组命令。Queue 命令只操作
Session 命令负责输出、trace 和会话控制:
```bash
./scripts/agentrun sessions show <sessionId|sessionPath>
./scripts/agentrun sessions output <sessionId|sessionPath> [--cursor <cursor>] [--limit <limit>]
./scripts/agentrun sessions trace <sessionId|sessionPath> [--cursor <cursor>] [--limit <limit>]
./scripts/agentrun sessions control <sessionId|sessionPath> --json-file <control.json>
./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 show` 最多打印 `sessionPath` 和下一步 `sessions ...` 命令。
@@ -177,7 +183,7 @@ Queue Q2 的真实手动验收必须覆盖以下稳定边界:
| 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 | 实现 | Queue 只返回 `sessionPath`Session 层承接输出、trace 和控制。 |
| 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。 |