diff --git a/Heicode-Manager-生产配置与账号交接清单.md b/Heicode-Manager-生产配置与账号交接清单.md index 214605f..1a5a0fe 100644 --- a/Heicode-Manager-生产配置与账号交接清单.md +++ b/Heicode-Manager-生产配置与账号交接清单.md @@ -180,6 +180,8 @@ Key Vault 最低权限: ## 7. 蜂群 Runtime 配置 +> ⚠️ **2026-06-10 勘误(模型已更新)**:本节描述的「普通 sub + 蜂群两套模式 + `SWARM_RUNTIME_*` + `/api/swarms`」是**旧的「HM 主导编排」模型,已作废**。当前权威模型:HM **不实现 swarm runtime**;单 Agent 走「模板 Agent + AM」(见 `docs/integration/heicode-am-contract.md`),多 Agent 蜂群归 **`agent_swarm`**(产品名 HeiCode Swarm)仓,其编排为 Master-Agent(分解→派发→评审→汇总),契约见 `agent_swarm/docs/integration/runtime-contract.md`(待冻结,`agent_swarm#2`)。详见 `docs/integration/heicode-swarm-deferred.md`。下表 `SWARM_RUNTIME_*` 仅为**仍存在于 env 但当前关闭(`SWARM_RUNTIME_ENABLED=false`)**的历史开关,保留作记录,不代表当前接入形态。 + 蜂群模式和普通 sub 模式是两套部署、两套语义。Manager 当前环境里蜂群 Runtime 开关是关闭状态。 | 环境变量 | 当前状态 | 当前值 / 位置 | 说明 | @@ -196,7 +198,7 @@ Key Vault 最低权限: | 项目 | 地址 | 说明 | |------|------|------| -| HeiCode-Swarm Orchestrator | `http://52.139.240.116:8000` | 蜂群项目独立 Runtime / Orchestrator | +| `agent_swarm`(HeiCode Swarm)Orchestrator | `http://52.139.240.116:8000` | 蜂群项目独立 Runtime / Orchestrator(HM 侧 deferred,未在 Manager 生产 env 启用) | ## 8. NewAPI / 模型网关配置 diff --git a/docs/deployment/Heicode-Manager-更换部署服务配置清单.md b/docs/deployment/Heicode-Manager-更换部署服务配置清单.md index 5299c81..6bbc087 100644 --- a/docs/deployment/Heicode-Manager-更换部署服务配置清单.md +++ b/docs/deployment/Heicode-Manager-更换部署服务配置清单.md @@ -42,6 +42,8 @@ HEICODE_PUBLIC_BASE_URL=https://code.xinghanlab.com ### 2.2 Agent Manager / 普通 sub / 蜂群联调配置 +> ⚠️ **2026-06-10 勘误**:下列「普通 sub / 蜂群 + `/api/swarms` + `SWARM_RUNTIME_*`」属**旧「HM 主导编排」模型,已作废**。当前权威模型:单 Agent 走「模板 Agent + AM」(`heicode-am-contract.md`);多 Agent 蜂群归 **`agent_swarm`**(HeiCode Swarm)仓(Master-Agent 编排),HM 侧 deferred,契约待 `agent_swarm#2` 冻结。见 `docs/integration/heicode-swarm-deferred.md`。本节 env 仅为历史记录(蜂群开关当前 `SWARM_RUNTIME_ENABLED=false`)。 + ```env AGENT_RUNTIME_ENABLED=true AGENT_RUNTIME_BASE_URL=http://20.212.121.126 diff --git a/docs/integration/heicode-desktop-client-api.md b/docs/integration/heicode-desktop-client-api.md index 6362e39..579bf9b 100644 --- a/docs/integration/heicode-desktop-client-api.md +++ b/docs/integration/heicode-desktop-client-api.md @@ -120,6 +120,29 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) ) > 客户端只需 `models`(当前可用 `gpt-5.4`);`modes` 是旧任务模式,新模型已无意义。 +> ⚠️ **能力发现 vs 登录用户模型列表**:`/api/heicode/capabilities` 是**免登录**的总目录(渲染模型选择用)。**登录后客户端展示的「我能用哪些模型」必须走 §3.1 `/api/heicode/available-models`**——它按当前用户的分组/订阅服务端收口,且**只有** HM 这一个来源:客户端不得使用本地 preset,也不得从 CodeGW 渠道后台读取模型。 + +--- + +## 3.1 登录用户可用模型 🟢(模型列表收口) + +| 方法 | 路径 | 鉴权 | 说明 | +|---|---|---|---| +| GET | `/api/heicode/available-models` | `UserOrV2DeviceAuth`(会话/JWT 或设备签名) | 当前登录用户**实际可用**的模型列表;服务端按用户可用分组 → 分组启用模型解析 | + +```json +{ "success": true, "data": { + "available_models": [ + { "model_id": "gpt-5.4", "display_name": "gpt-5.4", "default": true } + ] +}} +``` + +- 字段仅 `model_id` / `display_name` / `default`(默认模型)。 +- **禁止暴露字段**:`channel_id`、`base_url`、`api_key`、供应商类型、价格/倍率等一律不返回。 +- **唯一模型来源**:客户端登录后模型列表完全来自此接口,不使用本地 preset / 不读 CodeGW 渠道后台。 +- 鉴权要求登录用户上下文(`id>0`);未登录返回 `authentication required`。 + --- ## 4. Agent 模板列表 🟢 @@ -258,6 +281,33 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) ) --- +## 5.1 Agent 模型用量 🟢(按部署 Agent 聚合) + +| 方法 | 路径 | 鉴权 | 说明 | +|---|---|---|---| +| GET | `/api/heicode/agents/{deployment_id}/usage` | `UserOrV2DeviceAuth`,且只能查**自己**的 agent | 按该 agent 的隐藏模型 token(name=`agent:`)在计费 logs 中聚合用量 | + +查询参数(可选):`start` / `end` = unix 秒时间窗(缺省=全窗口)。 + +```json +{ "success": true, "data": { + "agent_id": "dep_4bb07dc1e376", + "quota": 12345, // 消耗的额度(配额单位) + "prompt_tokens": 8000, + "completion_tokens": 4000, + "call_count": 12, + "quota_per_unit": 500000, // 额度→货币换算分母(quota/quota_per_unit=美元额度) + "budget_remaining": 1234567 // ★ 用户钱包剩余额度(预算剩余;-1=读取失败,不阻断展示) +}} +``` + +- **空数据语义**:无调用记录时各计数为 `0`(仍返回 `success:true`,不是 404)。 +- **`budget_remaining`(#9)**:用户剩余可用额度(同 `quota_per_unit` 口径换算)。Agent 模型调用经隐藏 token 计费到 `user.Quota`,故"本任务预算剩余"= 用户钱包剩余额度。 +- **与 billing logs 的关系**:用量来自统一计费 logs(`SumAgentUsage`),按 token name `agent:` 过滤聚合 —— 即 agent 走 HM `/v1/*` 的真实消耗,与用户钱包/订阅扣费同源。 +- **计费归集语义(#30)**:每个部署的 agent,HM 为其 mint 一个**隐藏、不展示在用户 token 列表**的模型 token(`UnlimitedQuota:true`)。`UnlimitedQuota` 的含义是「**不对该 token 自身设单独的剩余额度上限**」——它**不**绕过用户额度:agent 经此 token 调 `/v1/*` 时,HM 仍先校验 `user.Quota`,并在结算时从 `user.Quota`(钱包)或订阅项扣费、写计费 log,完全经过计费表达式。停止/删除 agent 后该 token 被撤销,旧 token 无法再调 `/v1/*`。该 token 对普通用户隐藏,但审计/管理员可追踪。 + +--- + ## 6. 直连 Agent(客户端 ↔ agent,A2A 协议) > 客户端**直接连 agent 子域名**(§5 的 `subdomain`),不经过 HM。agent 是 AM 的 `coding_a2a_agent`,走 **A2A 协议**。 @@ -302,6 +352,59 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) ) --- +## 7.1 客户端运行时配置 🟢 + +| 方法 | 路径 | 鉴权 | 说明 | +|---|---|---|---| +| GET | `/api/heicode/config` | 无(公开,非敏感全局配置) | 客户端 runtime config / telemetry 开关;客户端轮询以便会话内即时生效(无需重登) | + +```json +{ "success": true, "data": { + "telemetry": { + "enabled": false, // 默认关闭(kill switch) + "endpoint": "/api/heicode/telemetry/events", + "max_batch": 20, + "flush_interval_sec": 30, + "retention_days": 30 // 服务端保留期:超期遥测被清理(#32) + } +}} +``` + +- 客户端必须以 `telemetry.enabled` 为准:为 `false` 时**停止上送**(摄入端点也会回 410)。 + +--- + +## 7.2 客户端错误遥测上送 🟡(默认关闭) + +| 方法 | 路径 | 鉴权 | 说明 | +|---|---|---|---| +| POST | `/api/heicode/telemetry/events` | `UserOrV2DeviceAuth` + **V2 设备签名**(需配对设备) | 上送客户端错误遥测;**诊断流量,绝不计费、不进 consume log** | + +- **默认关闭**:`HEICODE_TELEMETRY_ENABLED=false` 时返回 **410**(kill switch),客户端应停止上送。 +- **鉴权**:需登录用户 + 已配对设备;请求头带 `X-Heicode-Device-Id`。会话-only(无设备)调用被拒(403)。 +- **Body = 顶层 JSON 数组**(不是包裹对象),**1–20 条/批**,**≤256KB**。超限 413,非数组 400。 +- **每条事件**字段(诊断用,无用户内容):`client_id`(须等于配对设备 id)、`schema_version`、`app_version`、`platform`、`os_version`、`arch`、`locale`、`error_category`、`error_code`、`error_message_hash`、`stack_hash`、`stack_top`(数组)、`context`(对象)、`timestamp`、`session_seq`。 +- **服务端脱敏**:`stack_top` / `context` 即使客户端已脱敏,服务端仍二次 redaction(剥离 `sk-`/`Bearer`/URL token/JSON 密钥字段)。 +- **context 字段白名单(#32)**:`context` 仅保留 `route` / `retryable` / `phase` / `exit_code` / `duration_ms` / `attempt`;其余键(含 email、完整文件路径、prompt、IP 原文等可识别信息)**一律丢弃**。`stack_top`/`context` 单字段脱敏后截断到 8KiB。 +- **重试语义**:4xx(校验失败/超限/kill switch 410)**丢弃不重试**;5xx(持久化失败)可重试。 +- **保留期(#32)**:服务端按 `HEICODE_TELEMETRY_RETENTION_DAYS`(默认 30)定期清理超期遥测。 + +> ⚠️ **上线前置门槛(#32)**:`device_id`/`client_id` 可关联账号,属隐私敏感。生产开启 `HEICODE_TELEMETRY_ENABLED=true` 前必须:隐私文档已如实披露「设备 ID 可关联账号的错误遥测」、产品/法务已确认、kill switch 已验证。隐私文档同步见 heicodeDocs(#34)。 + +```json +// 请求体(顶层数组,示意一条) +[ + { "client_id":"", "app_version":"0.5.0", "platform":"win32", + "error_category":"ui_crash", "error_code":"RENDERER_ERROR", + "error_message_hash":"9f2a7c1b4e8d", "stack_hash":"a1b2c3d4e5f6", + "stack_top":["at MessageList (MessageList.tsx:212:9)"], + "context":{"route":"chat"}, "timestamp":"2026-06-09T07:21:33.123Z", "session_seq":1 } +] +// 成功:{ "success": true, "accepted": 1 } +``` + +--- + ## 8. 响应 envelope 与错误码 **成功**:`{ "success": true, "data": {…} }` @@ -347,11 +450,15 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) ) | 接口 | 鉴权 | 状态 | |---|---|---| | `GET /api/heicode/capabilities` | 无(公开) | 🟢 | +| `GET /api/heicode/available-models` | 会话/设备 | 🟢(登录用户模型列表收口,唯一来源) | +| `GET /api/heicode/config` | 无(公开) | 🟢(runtime config / telemetry 开关) | | `GET /api/user/self`、`/self/models` | **UserAuth(会话/JWT)** | 🟢 | | `GET /api/heicode/agent-templates` | 会话/设备 | 🟢(生产已验证 19 中文模板) | | `GET /api/heicode/agents` `/{id}` `/{id}/status` | 会话/设备 | 🟢 | | `POST /api/heicode/agents` | 会话/设备 | 🟢(调 AM,AM 接口 🔴) | | `POST /api/heicode/agents/{id}/stop`、`DELETE /{id}` | 会话/设备 | 🟢(调 AM 🔴) | +| `GET /api/heicode/agents/{id}/usage` | 会话/设备(仅自己的 agent) | 🟢(按 `agent:` token 聚合计费 logs) | +| `POST /api/heicode/telemetry/events` | 会话/设备 + V2 设备签名 | 🟡 默认关闭(410 kill switch);不计费 | | 模型 `/v1/*` | 同模型调用 | 🟢 | | `POST /api/heicode/agent-access/verify` | 公开(令牌即凭据) | 🟢(可选兜底;接入用 ① 本地比对,默认不用此端点) | | 直连 agent SSE(subdomain + X-Agent-Access-Token) | agent 本地比对令牌 | 🟢 直连已通 / ⚠️ 令牌校验待 AM 开启 | diff --git a/docs/integration/heicode-swarm-deferred.md b/docs/integration/heicode-swarm-deferred.md index 40ff24a..299a71e 100644 --- a/docs/integration/heicode-swarm-deferred.md +++ b/docs/integration/heicode-swarm-deferred.md @@ -1,8 +1,10 @@ # Heicode 蜂群(Swarm)—— 现状裁定与后续跟踪入口(HM 侧) -> 起草:2026-06-05 · 状态:跟踪占位(HM 侧不实现,归口 AM / Swarm) +> 起草:2026-06-05 · 更新:2026-06-10(同步 `agent_swarm` 当前状态)· 状态:跟踪占位(HM 侧不实现,归口 AM / Swarm) > > 本文是 PR #15「文档大同步」删除全部旧 sub/蜂群文档后留下的**追踪入口**,回答三件事:① 旧文档为什么作废、② 蜂群能力现在归谁、③ 未来对接/待定项在哪里跟踪。删除旧文档≠放弃蜂群能力,**上下文迁移到本文**。 +> +> **2026-06-10 勘误**:蜂群仓库名是 **`agent_swarm`**(GitHub `xmindlab-heicode/agent_swarm`;产品名 **HeiCode Swarm**),不是 `HeiCode-Swarm`。该仓已从「仅 `/tasks`」演进为完整的 Master-Agent 编排运行时并起草了正式契约 `runtime-contract.md`——本文下文已据实更新。 --- @@ -10,7 +12,8 @@ - **HM(Heicode Manager)当前不实现 swarm runtime。** HM 的职责边界是:模型网关(`/v1/*`)+ 资源/权限/计费/审计 + **模板 Agent 部署编排**(经 AM 启动常驻 agent、客户端直连)。多 agent 蜂群编排**不在 HM 端**。 - **旧的「HM 内部 sub/蜂群任务编排」模型已作废。** 那套(sub 任务、display_status、HM 侧蜂群 runtime 对接草案)随产品转向「模板 Agent + 客户端直连」一并下线,相关代码删除清单见 [`heicode-hm-legacy-teardown.md`](./heicode-hm-legacy-teardown.md),当前模型见 [`heicode-hm-template-agent-model.md`](./heicode-hm-template-agent-model.md)。 -- **新版蜂群能力仍在开发中,但在 AM / Swarm 侧,不在本仓。** 旧文档描述的是「HM 主导编排蜂群」的废弃设计;新蜂群若落地,HM 侧最多提供资源/计费/鉴权支撑面,runtime 与编排由 Swarm 承载。 +- **新版蜂群能力在 `agent_swarm`(HeiCode Swarm)仓,不在本仓。** 当前模型:主控 Agent(Master Agent,`orchestrator/master_agent.py`)把需求**分解**为子任务 → **派发**给不同领域的专家 Agent **并行执行** → 重叠领域**协作/移交** → 主控**评审/重做**循环(受 `MAX_REVIEW_CYCLES` 约束)→ **汇总交付**;Orchestrator(FastAPI) + Redis 权威状态 + WebSocket Agent 协议 + Prometheus 指标。旧文档描述的「HM 主导编排蜂群 / 仅 `/tasks`」已作废。HM 侧最多提供资源/计费/鉴权支撑面,runtime 与编排由 Swarm 承载。 +- **该仓尚未作为 Heicode 主链路正式 Runtime Backend 接入。** 按 `agent_swarm` README 与 `agent_swarm#2`:编排器已可运行(仓内),但 Manager↔Runtime 生命周期契约、HMAC 签名回调 envelope、稳定 `deployment_id`/`workflow_id`/`trace_id`、统一 usage/审计接入等仍为 🟡 待接入,需各 Team 评审冻结后联调。 --- @@ -18,11 +21,11 @@ | 项 | 归属仓 / 负责人 | 说明 | |---|---|---| -| Swarm runtime / 多 agent 编排 | **`agent_swarm` / `HeiCode-Swarm`**(@Songhaoz666) | 执行面、回调、Swarm Runtime | -| Manager ↔ Swarm 契约(若未来需要) | 待 Swarm 侧给出正式 `/api/agent/swarm/*` 接口后,在本目录 `docs/integration/` 另立契约文档跟踪 | 当前 Swarm 仅暴露 `/tasks`、缺 `deployment_id ↔ swarm_id` 映射(见 `agent_swarm#1`) | +| Swarm runtime / 多 agent 编排 | **`agent_swarm`**(产品名 HeiCode Swarm,@Songhaoz666) | 执行面、Master-Agent 编排、回调、Swarm Runtime | +| Manager ↔ Swarm 契约 | Swarm 侧**已起草正式契约** `agent_swarm/docs/integration/runtime-contract.md`(沿用 `heicode-am-contract` 的鉴权/回调/env/路径覆盖约定),**待 Manager Runtime Team 评审冻结**;冻结后在本目录 `docs/integration/` 另立 HM 侧对接契约 | Swarm 已实现生命周期接口 create/status/tasks/logs/events/metrics/workflow/diagnostics/stop/approvals(均带 `deployment_id`,三组路径别名 `/api/swarms`、`/api/agent/swarm/deployments`、`/api/agnet/deployments`);契约冻结与主链路接入跟踪在 **`agent_swarm#2`**(`#1` 执行面缺口已关闭) | | Agent 运行时(单 agent,已落地) | **`agent_management`(AM)**(@azgy) | 模板 Agent 启动/状态/停止/删除,契约见 [`heicode-am-contract.md`](./heicode-am-contract.md) | -> **HM 侧后续若要支撑蜂群**:不恢复旧文档,按当时 Swarm 的正式契约在 `docs/integration/` 新立文档;本文作为「蜂群在 HM 侧当前为 deferred」的唯一锚点。 +> **HM 侧后续若要支撑蜂群**:不恢复旧文档,按 Swarm 的 `runtime-contract.md` 冻结版在 `docs/integration/` 新立 HM 对接契约;本文作为「蜂群在 HM 侧当前为 deferred」的唯一锚点。HM 侧对接前置依赖见 issue #45(Phase1 只读查询,阻塞于 `agent_swarm#2` 契约冻结)/ #46(Phase2 SSE)。 --- @@ -53,4 +56,4 @@ ## 4. 给后续开发者的一句话 -要找「蜂群在 HM 侧怎么对接」——**当前答案是「HM 不实现,等 Swarm 侧正式契约」**;旧设计已废,别从 git 历史里捞旧文档当依据,按本文与 Swarm 仓的最新结论走。 +要找「蜂群在 HM 侧怎么对接」——**当前答案是「HM 不实现 swarm runtime;Swarm 侧已起草 `agent_swarm/docs/integration/runtime-contract.md`,待 Manager Runtime Team 评审冻结(`agent_swarm#2`)后,HM 再据冻结版做只读查询接入(#45/#46)」**;旧设计(HM 主导编排 / 仅 `/tasks` / `HeiCode-Swarm` 仓名)已废,别从 git 历史里捞旧文档当依据,按本文与 `agent_swarm` 仓的最新结论走。 diff --git a/heicode/docker-compose.azure-vm.yml b/heicode/docker-compose.azure-vm.yml index b87bc57..ddf8c3d 100644 --- a/heicode/docker-compose.azure-vm.yml +++ b/heicode/docker-compose.azure-vm.yml @@ -61,7 +61,10 @@ services: - AGENT_RUNTIME_STOP_PATH=${AGENT_RUNTIME_STOP_PATH:-/api/agent/deployments/{deployment_id}/stop} - AGENT_RUNTIME_SERVICE_TOKEN=${AGENT_RUNTIME_SERVICE_TOKEN:-} - AGENT_RUNTIME_CALLBACK_SIGNING_SECRET_REF=${AGENT_RUNTIME_CALLBACK_SIGNING_SECRET_REF:-} - # HeiCode-Swarm Runtime is separate from ordinary sub Agent Runtime. + # agent_swarm (product: HeiCode Swarm) Runtime — separate from the single + # template-agent Runtime (AM). Currently DEFERRED/disabled (SWARM_RUNTIME_ENABLED=false): + # HM does not orchestrate swarm; pending agent_swarm runtime-contract.md freeze (agent_swarm#2). + # See docs/integration/heicode-swarm-deferred.md. - SWARM_RUNTIME_ENABLED=${SWARM_RUNTIME_ENABLED:-false} - SWARM_RUNTIME_BASE_URL=${SWARM_RUNTIME_BASE_URL:-} - SWARM_RUNTIME_CREATE_PATH=${SWARM_RUNTIME_CREATE_PATH:-/api/swarms}