Commit Graph
8 Commits
Author SHA1 Message Date
chenchen b36dc3fe28 Merge remote-tracking branch 'origin/feat/swarm-io-proxy-46' into deploy/test-pr69-73 2026-06-11 19:19:35 +08:00
chenchenandClaude Opus 4.8 2c60af0216 feat(swarm): #46/#28 暴露 input/result 代理端点(I/O 闭环)
agent_swarm PR#41 已合并 main(契约冻结),HM 补齐客户端+swarm 双方点名需要的
两条透传端点(均设备签名,挂 /api/heicode/swarms/:id 下):

- POST /swarms/:id/input  → 代理 Swarm POST …/{deployment_id}/input(追加用户输入,
  注入 source=user_append;终态 run 自动 reopen,stopped 拒绝)。写路,需
  SWARM_RUNTIME_ENABLED+base+token,缺一即拒不伪造受理。**指令文本仅转发,绝不落
  HM 日志/审计/事件**(#40 原文不进事件流 + #46 勿落日志);审计只记发生过一次 append。
- GET  /swarms/:id/result → 代理 Swarm GET …/{deployment_id}/result,返回
  {summary, deliverable, artifacts[], termination_reason, status};产物按 uri 取非内联。
  读路,需 base+token(与派发开关解耦);透出前 stripSensitiveKeys 递归剔除 secret_ref 等兜底。

新增:callSwarmRuntimeJSON(通用 JSON 调用 + envelope 归一,错误信息不含请求体)、
agentRuntimeSwarm{Input,Result}Path(默认 create-path 基路径,SWARM_RUNTIME_{INPUT,RESULT}_PATH 可覆盖)。

测试:swarm_io_proxy_test.go 覆盖路径构造(默认/空回退/env 覆盖)、input 转发(方法/路径/鉴权/body)、
result 解析 + deliverable/artifacts 脱敏、运行时非 2xx 报错。go build ./... + controller/router 全绿。

影响面:Manager ✅(透传端点)/ agent_swarm ✅(消费 PR#41 契约)/ Client ✅(驾驶舱 I/O 闭环)/
Agent ❌ / CodeGW ❌ / 计费 ❌ / 密钥 ❌(不经手 secret)/ 审计 ✅(input_appended,不含原文)/ 发布链路 ❌

Refs #46 #28。Depends-on-contract: agent_swarm PR#41 (已合并 main)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 18:41:39 +08:00
chenchenandClaude Opus 4.8 a5419f9a15 feat(swarm): GET /swarms/:id 详情补 resource_grants/budget/audit_logs (#66 里程碑07/08)
HM 自有数据,不依赖 swarm 运行时,仅 detail 带、list 不带(免膨胀):
- resource_grants:plan_json 提取,脱敏(grant_id/resource_id/resource_type/binding_scope/
  target_role/permission_scope/status + has_secret);绝不下发 secret_ref 值。
- budget:max_tokens/max_cost_usd/max_duration_sec(plan.Budget 上限)。
- audit_logs:HM 控制面 deployment 级审计(脱敏 + 截断 100);run 级 trace 待 swarm /audit 代理(PR#41)。

usage/used_*/cost_by_phase 待 #60 + swarm metrics,本批不臆造。
测试:脱敏(secret_ref 值不外泄)/has_secret/budget 上限/空坏JSON。build+vet+controller 测试全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:24:09 +08:00
chenchenandClaude Opus 4.8 c3f51fe479 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>
2026-06-10 21:43:00 +08:00
chenchenandClaude Opus 4.8 292504735e feat(swarm): add goal_summary to swarm status view (#45/#28 consumer ask)
@Mem0ried 客户端 consumer 验收(#59)指出 GET /swarms/:id 缺 goal_summary —— Run 列表
只能显示 deployment_id/status,体验差。补:swarmDeploymentView 增加 goal_summary,从持久化
plan_json 顶层 objective 提取,折叠空白为单行 + 截断(200 rune)+ RedactText 兜底;取不到
(无 plan / 无 objective / 坏 JSON)返回空串,不臆造。list 与 detail 同走 swarmDeploymentView,
两处都带上。

文档 docs/integration/heicode-desktop-client-api.md §5.2 状态样例补 goal_summary 字段说明。
测试 TestSwarmGoalSummary 覆盖:空/坏 JSON/无 objective→空;多行多空格折叠;误入 sk- 被脱敏;
超长截断带省略号。go build ./... 与 controller 测试全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 21:17:32 +08:00
chenchenandClaude Opus 4.8 56a9b02a25 feat(swarm): adopt frozen agent_swarm contract v1 (read-side) (#45/#46)
按 agent_swarm#14/#15 冻结契约做 HM 读侧适配(客户端 #28 消费):
- 注册 6 类新事件(event-schema v1):swarm.completed/failed/stopped、approval.approved/rejected、
  handoff.created(categories + requiredFields 两表;必填先最小集,待 agent_swarm PR #28 §4 精校)。
- AgentCallbackEvent 增 Sequence(per-swarm 严格递增序号),回调入库透传 envelope.sequence;
  事件视图暴露 sequence 供客户端去重/排序。游标仍用稳定 id(next_after)避免 sequence 未全量
  上线时回归。
- 脱敏键补 credential_ref/signing_secret_ref(envelope 按设计透传 azkv:// 引用,客户端视图剔除)。
- artifact.created → 扁平视图 {uri,checksum,task_id,size_bytes?,created_at}(无 secret_ref;
  size 未知省略不伪造)。
- 状态展示映射 §4.1:display_status(blocked→degraded;不臆造 preparing/verifying)。

测试:状态映射、artifact 视图(脱敏 + size 省略)、6 类事件注册;controller+model 全回归通过,
go build/vet 干净。文档 §5.2 更新。

未含(下一 PR):stop 真实运行时接入(写路径,复用 agentRuntimeClientConfigForMode("swarm"))。

Affects: Manager only(只读查询契约适配)。AgentCallbackEvent 加列(AutoMigrate);无计费改动。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 18:01:32 +08:00
chenchenandClaude Opus 4.8 b9d9eddf7b fix(swarm): address #45 review — payload redaction, user-scoped events, no fake stop
回应 Fasthei 复审(PR #53 CHANGES_REQUESTED):
1. 事件 payload 脱敏:swarmEventView 经 sanitizeSwarmPayload —— 递归剔除
   secret_ref/credentials/token/api_key/private_key/access_key/password 及 plan/payload/
   permission_manifest/env 大字段,再跑 RedactText 兜底。绝不下发 azkv:// secret_ref 或
   sk-/Bearer(approval.requested 等 envelope 携带的凭据引用)。加 TestSanitizeSwarmPayload_*。
2. user 作用域:model.ListSwarmCallbackEventsAfter 增加 userID 参数 + WHERE user_id,
   controller 传入当前用户;防 runtime_swarm_id/deployment_id 碰撞或误写导致跨用户事件泄漏。
   测试补 user 隔离用例。
3. stop 不伪造成功:移除「开关打开返回 accepted:true」路径;未启用→POLICY_REJECTED,
   启用也→NOT_IMPLEMENTED(未转发运行时),直到 agent_swarm#2 冻结接上真实 stop。

文档 §5.2 同步(脱敏 / user 作用域 / stop 语义)。go build/vet 干净,controller+model 全回归通过。

Affects: Manager only(只读查询脱敏 + 写端点安全语义)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:23:58 +08:00
chenchenandClaude Opus 4.8 59b13ba824 feat(swarm): HM-side Swarm Run read-only query — Phase1 (#45)
#45 Phase1 的只读查询(list/status/events?after/artifacts),全部基于 HM 已持久化的
运行时回调数据(Swarm → HM 带签名回调,见 agent_callback.go),**无需实时调 Swarm**,
因此不被 agent_swarm#2 契约冻结阻塞、返工风险低:

- GET /api/heicode/swarms — 列出当前用户的 swarm 运行(AgentDeployment, sub_mode=swarm 或有 runtime_swarm_id)
- GET /api/heicode/swarms/:id — 状态(:id = deployment_id/swarm_id/correlation_id 任一)
- GET /api/heicode/swarms/:id/events?after=&limit= — 事件增量拉取(id 游标 next_after,oldest-first)
  新增 model.ListSwarmCallbackEventsAfter(按 deployment_id/swarm_id + id>after)
- GET /api/heicode/swarms/:id/artifacts — 从已存事件(event_type 含 artifact)派生
- POST /api/heicode/swarms/:id/stop — 唯一写操作;在 agent_swarm#2 冻结 + SWARM_RUNTIME_ENABLED=true
  前默认关闭并明确提示(不臆造未冻结写接口)

字段口径对齐 agent_swarm/docs/integration/runtime-contract.md(deployment_id↔swarm_id↔
manager_deployment_id;状态机 waiting_approval→running→…)。所有查询按 user 作用域,视图脱敏
(不含 plan/payload 大字段与凭据)。

测试:TestListSwarmCallbackEventsAfter(游标/过滤/空标识);TestMain 迁移 AgentDeployment +
AgentCallbackEvent。go build/vet 干净,controller+model 全套回归通过。文档 §5.2。

Affects: Manager only(新增只读查询端点 + 一个 gated 写端点)。无计费/审计 schema 改动;
不依赖未冻结契约。stop 真实接入随 agent_swarm#2 冻结落地。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 13:24:34 +08:00