Merge branch 'main' into feat/agent-launcher-k8s-backend

This commit is contained in:
Fasthei
2026-06-11 23:05:02 +08:00
committed by GitHub
7 changed files with 298 additions and 8 deletions
+3
View File
@@ -93,9 +93,12 @@
| `handoff.requested` | `task_id`, `from_role`, `to_role` | swarm_task_flow | ✅ |
| `timeline.updated` | `title` | timeline | ✅(emit 时回填 `title`=`summary`) |
| `budget.alert` | `threshold_pct` | budget | ✅(emit 时回填 `threshold_pct`) |
| `swarm.pool_terminated` | `user_id`, `secret_ref` | lifecycle | ✅(HM #60 模型 key 吊销握手;**非**客户端事件,见下) |
| `phase.changed` / `agent.*` / `sk_tool.*` | — | ordinary_sub / sk | ❌(本运行时不产生) |
> 说明:评审/重做循环复用 `task.retried` + `timeline.updated`(`Review cycle N`)表达,无单独 review 事件类型;蜂群内部遥测(提案/竞价/交叉评审/收敛/health)**不经回调外发**(见各协议文档「事件不进 Manager 流」),故不在本表。`swarm.completed/failed/stopped` 与 `approval.approved/rejected`、`handoff.created` 为本次冻结**新增**,HM 注册表需据此登记(agent_swarm#15.2)。
>
> **`swarm.pool_terminated`(HM #60 模型 key 吊销握手)**:HM 控制面生命周期事件,**非**客户端 cockpit 事件、**不**入 `FROZEN_CLIENT_EVENT_TYPES`、不渲染到驾驶舱。当某用户**所有 swarm run 均被 stop**(completed/failed 可经 `…/input` 重开故仍保 key)时,运行时发恰好一次,载 `user_id` + `secret_ref`(`azkv://` 引用,非明文 key)。HM 需在 `subscribed_events` + `agent_callback` 登记,收到即吊销该用户 per-user `sk-` + 清 KV。口径见 [runtime-contract §3.3.1](./runtime-contract.md)。
## 5. HM 响应
+16 -1
View File
@@ -87,9 +87,24 @@ Swarm 拉起每个专家 agent 时注入以下进程环境变量(`agent/main.p
**约束**:
- 模型 key 由 **Swarm 服务端从 `billing_context.secret_ref`(`azkv://`)解析**(`resolve_model_key`:override → azkv(部署 SecretResolver / dev `HEICODE_SECRET_<name>`)→ 编排器 `OPENAI_API_KEY` 兜底)后注入被拉起 agent 的 env。key **不入** create 请求体 / 回调 / 日志 / argv(满足 §3.1);解析不到则 agent keyless 启动并明确报错(不伪造)。`billing_context` 的 `newapi_user_ref`/`quota_ref` 仍仅为归因元数据。见 [usage-billing-schema.md §2](./usage-billing-schema.md)。
- 同一用户的专家 agent 注入**同一把** `sk-` + `OPENAI_API_BASE=HM/v1`,计费归一到发起用户;`task_executor` 随模型请求带 `X-Agent-*` 归因头供 HM/NewAPI 关联。token 由 HM 按 agent 生命周期吊销(stop/delete)。
- 同一用户的专家 agent 注入**同一把** `sk-` + `OPENAI_API_BASE=HM/v1`,计费归一到发起用户;`task_executor` 随模型请求带 `X-Agent-*` 归因头供 HM/NewAPI 关联。token 吊销走 §3.3.1 A.5 的 `swarm.pool_terminated` 握手(per-user,全部 run stop 后吊销)。
- **运行时事件前置**:只有 (i) HM 真把 create 派发到编排器(`SWARM_RUNTIME_ENABLED=true`,非 manager-local 适配器)且 (ii) Swarm 已按上表拉起 agent 并连入,编排器才回推 `task.*`/`swarm.*` 运行时事件(否则 events feed 仅有 HM 控制面 `deployment.status_changed`,见 #39)。
#### 3.3.1 模型 key 注入对接参数(HM #60,Swarm 侧已定死)
HM 实现 #60(计费 key 注入)前需 Swarm 定死的参数,逐条口径如下(实现:`agent_launcher.resolve_model_key` / `_resolve_secret_ref`,`swarm_runtime` 吊销握手;测试 `scripts/test-key-injection-contract.py`):
| # | 参数 | Swarm 口径(已定) |
|---|---|---|
| A.1 | `sk-` 粒度 + mint 时机 | **每用户一把**(首次蜂群开通 mint、跨该用户所有 run 复用);同一用户的专家 agent 注入同一把 `sk-`、计费归一到发起用户。 |
| A.1 | KV secret 命名约定 | `swarm-model-key-<user_id>`(Swarm 只取 `secret_ref` 末段做名,不强约束路径;命名供 HM 定位)。 |
| A.2 | KV secret **value 格式** | **JSON `{"openai_api_key":"sk-..."}`**(对齐 callback 签名密钥的 `{"callback_signing_secret":"..."}` 约定,可扩展)。Swarm 解析字段名 = `openai_api_key`;裸 `sk-` 字符串亦兼容(`_extract_model_key`);解析不到/字段缺失 → 不伪造、agent keyless 明确报错。 |
| A.3 | Swarm 读 KV 身份 / RBAC | **⚠ 联调阻塞前置(分两步)**:① **Swarm 侧先 provision Pod 的 Workload Identity**(建 UAMI → federate 到 `orchestrator-sa` SA → 用 `client-id` 注解 SA)——当前**尚未建**(仓内无 `azure.workload.identity/client-id` 注解、无 IaC);② **HM/运维** 在其库 `heicode-kv`(`https://heicode-kv.vault.azure.net`)给该身份授 `Key Vault Secrets User`(只读、限 `swarm-model-key-*`)。`heicode-kv` 是 HM 侧库,故授权由 HM/运维做;Swarm 只提供 Pod 身份 id + 收窄作用域。不通则 `secret_ref` 解不出。生产 KV 适配器(`SECRET_RESOLVER`)在仓外经部署接线;dev/CI 用 `HEICODE_SECRET_<name>` 环境映射。 |
| A.4 | `OPENAI_API_BASE` | **Swarm 部署常量**(`AGENT_OPENAI_API_BASE`/`OPENAI_API_BASE`,设为 HM 网关 `https://code.xinghanlab.com/v1`),**不**经 create 的 `billing_context` 下发。 |
| A.5 | 吊销信号 | **事件驱动(方案 A)**:`sk-` per-user 长存;`stop` 是唯一**终态**(`completed`/`failed` 可经 `POST …/input` 重开,故仍保留 key)。当某用户**所有 run 均被 stop**(retained 集清空)时,运行时发**恰好一次** `swarm.pool_terminated{user_id, secret_ref}`,HM 收到即吊销 `sk-` + 清 KV。单 run 的 `swarm.stopped` **不**触发吊销(key per-user 复用);账户停用 / HM 主动 delete 走同一 stop 路径。 |
> `swarm.pool_terminated` 是 **HM 控制面生命周期事件**(非客户端 cockpit 事件,**不**入 `FROZEN_CLIENT_EVENT_TYPES`);HM 需在 `subscribed_events` + `agent_callback` 登记以收吊销信号。payload `secret_ref` 为 `azkv://` 引用(非明文 key)。
## 4. 状态机
部署状态:`waiting_approval` → `running` →(`blocked` ⇄ `running`)→ 终态 `completed` / `failed` / `stopped`。