feat: wire swarm stop to runtime + add events SSE stream (#45/#46)
契约已冻结(agent_swarm#14 runtime-contract v1 / #15 event-schema v1),HM 侧据此 落地两项原本 deferred 的能力,叠在读侧适配(PR #59)之上: - stop(#45):HeicodeStopSwarm 真实调用运行时冻结路径 POST /api/agent/swarm/deployments/{deployment_id}/stop,复用 agent_runtime_client 的配置/URL/信封解析;Bearer SWARM_RUNTIME_SERVICE_TOKEN + X-Idempotency-Key 幂等。 仅 SWARM_RUNTIME_ENABLED=true 且配齐 base_url+token 时发起,否则 POLICY_REJECTED, 绝不伪造 accepted;终态不抢写,由 swarm.stopped 回调写回。 - events SSE(#46 读侧):GET /api/heicode/swarms/:id/events/stream?after=,与 events?after 同源(HM 持久化回调事件,按 user_id 收口 + payload 脱敏),命中终态 (swarm.completed/failed/stopped)/客户端断开/超时(30min)收流。不调运行时。 - docs:刷新 heicode-swarm-deferred.md(登记冻结契约、读侧/stop/SSE 已落地、唯一剩余 计费缺口 #60)与 heicode-desktop-client-api.md §5.2(SSE + stop 端点)。 影响面:Client(新增 SSE 端点 + stop 行为变化)、agent_swarm(按冻结契约调用其 stop)。 不涉及 Manager↔AM、密钥、计费扣费逻辑(计费缺口 #60 仍阻塞于 agent_swarm#16)。 测试:callSwarmRuntimeStop(httptest 校验路径/鉴权/幂等头/信封解析/错误路径/runtime id 回退)+ swarmEventIsTerminal;go build ./... 与 controller 测试全绿。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,17 +313,18 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
|
||||
---
|
||||
|
||||
## 5.2 Swarm 运行查询 🟡(#45 Phase1 · 只读预览)
|
||||
## 5.2 Swarm 运行查询 🟢(#45/#46 · 契约 v1 已冻结)
|
||||
|
||||
多 Agent 蜂群运行(`agent_swarm` / HeiCode Swarm)的**只读查询**。数据全部来自 HM 已持久化的运行时回调(Swarm → HM 带签名回调),**无需实时调 Swarm**,故不受 `agent_swarm#2` 契约冻结阻塞。
|
||||
多 Agent 蜂群运行(`agent_swarm` / HeiCode Swarm)的查询。读类接口数据全部来自 HM 已持久化的运行时回调(Swarm → HM 带签名回调),**无需实时调 Swarm**;契约已冻结为 `runtime-contract v1`/`event-schema v1`(`agent_swarm#14`/`#15`)。
|
||||
|
||||
| 方法 | 路径 | 说明 | 状态 |
|
||||
|---|---|---|---|
|
||||
| GET | `/api/heicode/swarms` | 列出我的 swarm 运行 | 🟢 本地数据 |
|
||||
| GET | `/api/heicode/swarms/:id` | 单个运行状态(:id = deployment_id / swarm_id / correlation_id 任一) | 🟢 |
|
||||
| GET | `/api/heicode/swarms/:id/events?after=&limit=` | 事件增量拉取(`after`=上次返回的 `next_after`,oldest-first) | 🟢 |
|
||||
| GET | `/api/heicode/swarms/:id/events/stream?after=` | **事件 SSE 实时流**(与 events 同源;进入即回放 `after` 之后历史) | 🟢 |
|
||||
| GET | `/api/heicode/swarms/:id/artifacts` | 从已存事件派生的产物 | 🟢(派生) |
|
||||
| POST | `/api/heicode/swarms/:id/stop` | 停止运行(**写**) | 🟡 待 `agent_swarm#2` 冻结 + `SWARM_RUNTIME_ENABLED=true` |
|
||||
| POST | `/api/heicode/swarms/:id/stop` | 停止运行(**写**,真实调运行时) | 🟢(开关:`SWARM_RUNTIME_ENABLED=true` + base_url + service token;否则 `POLICY_REJECTED`) |
|
||||
|
||||
```json
|
||||
// GET /api/heicode/swarms/:id
|
||||
@@ -350,6 +351,8 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
- **事件**:`sequence` = agent_swarm event-schema v1 的 **per-swarm 严格递增序号**(每 swarm 从 1、无空洞),客户端用它去重/排序;`id`/`next_after` 是 HM 不透明分页游标(单调,兼容 `sequence` 尚未全量上线)。事件 `payload` **已脱敏**(递归剔除 `secret_ref`/`credential_ref`/`signing_secret_ref`/credentials/大字段 + `RedactText` 兜底)。查询按**当前用户**作用域。
|
||||
- **新增事件类型**(已注册):`swarm.completed/failed/stopped`、`approval.approved/rejected`、`handoff.created`(event-schema v1)。
|
||||
- **artifact**:从 `artifact.created` 派生扁平 `{uri,checksum,task_id,size_bytes?,created_at}`(**无 secret_ref**;size 未知则省略,不伪造)。
|
||||
- **SSE 实时流**(`/events/stream`):`text/event-stream`,帧 `event: message` 的 `data` 即单条事件视图(同 `events` 的 item);命中终态(`swarm.completed/failed/stopped`)发 `event: done`(`{next_after,reason}`)后收流,客户端断开或超时(30min)亦收流。与轮询 `events?after` 等价,二选一;断线后用最后的 `next_after` 重新订阅即可续传。
|
||||
- **stop**:`SWARM_RUNTIME_ENABLED=true` 且配齐 base_url + service token 时真实调用运行时(`X-Idempotency-Key` 幂等),返回 `{accepted:true,runtime_status,...}`;**终态不在响应里**——由运行时异步回推 `swarm.stopped` 事件,客户端经 `events`/`stream` 收最终态。未启用则 `POLICY_REJECTED`(不伪造受理)。
|
||||
- `stop`(写):仍 gated,待 stop 真实接入 PR(复用运行时客户端 + `SWARM_RUNTIME_SERVICE_TOKEN`,契约 §3 已冻结)落地。
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user