# Heicode Manager 新模型重构说明:模板 Agent + 客户端直连(v1) > 更新时间:2026-06-03 > 范围:**HM 端**(后端 + 网页控制台)在「模板 agent + 客户端直连」新模型下的改造清单。 > 关联文档:客户端对接见 `heicode-desktop-client-api.md`;旧代码清理见 `heicode-hm-legacy-teardown.md`。(旧的「sub 任务编排」设计文档 heicode-sub-mode-flow-spec.md / heicode-desktop-unified-api.md 等已删除。) --- ## 0. 新模型一句话 用户在 **HM 网页台**绑定资源、选「资源 + 模板」**部署一个常驻 agent**;HM 把密钥从 Key Vault 解出、拼成 env 交给 **AM** 启动,AM 返回**唯一子域名 + 访问 token**;**桌面客户端从 HM 读 agent 列表后,直连子域名 SSE 使用**,HM 不在对话回路里。**模型调用两端都仍走 HM `/v1/*` 计费。** **砍掉**旧的 sub 任务编排:task/workflow/`display_status` 裁决/git_ref 交付/产物下载/部署租约/revision —— 客户端直连 agent 后这些都不需要。 --- ## 1. 三端角色与边界 | 端 | 职责 | |---|---| | **HM 网页台(UI)** | 绑资源、选资源+模板部署 agent、停/删 agent、看 agent 列表 | | **HM 后端** | KV 存/解密钥、从 AM 拉模板、转发启动、**存 agent 记录(含 token)**、查询 API、**`/v1/*` 模型网关计费**。**不在 agent 对话回路** | | **AM** | 启动并**常驻** agent、注入 `.env`、发访问 token + 校验、**保证 agent 不泄密**、生命周期(部署后不自停,HM 调才停) | | **桌面客户端** | 从 HM 读 agent 列表(地址+token+资源) → **直连 agent SSE 使用**;模型走 HM `/v1/*`。**不参与部署** | --- ## 2. 端到端流程 **阶段 0 — 资源绑定(HM 网页台)** 1. 用户在 UI 绑 git / vm / database / blob。 2. 每条 = 非密配置(明文 metadata) + 密钥(进 KV,库里只留 `secret_ref`) → 得 `resource_binding_id`。 **阶段 1 — 部署 agent(HM 网页台)** 1. UI 展示从 AM 拉来的模板列表。 2. 用户选 1 个模板 + 勾选要挂的资源绑定 → 点「部署」。 3. HM 后端:所选 binding 的密钥**从 KV 解出** → 拼 env(非密配置 + 密钥) → 调 AM「用模板 X + 这份 env 启动」。 4. AM:启动 agent → 注入 `.env` → 分配唯一子域名 + 生成访问 token → 常驻 → 返回 `{子域名, token}`。 5. HM:存「agent ↔ 用户 ↔ 资源 ↔ 子域名 ↔ token ↔ 状态」;UI 显示已部署。HM 日志不落明文密钥。 **阶段 2 — 客户端使用(直连,HM 退出回路)** 1. 客户端 `GET /api/heicode/agents` → 拿 `agent_id/子域名/token/资源/状态`。 2. 客户端直连子域名 SSE、带 token → agent 校验 token(防裸奔)。 3. 对话/干活全在客户端↔agent;HM 不参与。 4. agent 用 `.env` 配置干活;用模型打 HM `/v1/*` 计费;客户端本地用模型也走 `/v1/*`。 5. 同一 agent 可跨模式复用。 **阶段 3 — 管理 + 查询** - 管理(HM UI):停止 / 删除 agent → HM 转 AM。**不自动停。** - 查询(API):`GET /api/heicode/agents`、`GET /api/heicode/resources`。 - 换密钥:**不支持改密钥**;要换就用新绑定**重新部署新 agent**,旧的停掉。 --- ## 3. 一、保留(接口 / 功能,原样用) | 项 | 落点 | 说明 | |---|---|---| | 资源绑定 CRUD | `/api/resources/*`(会话鉴权)、`resource.go` | 网页台绑 git/vm/db/blob,写 KV | | Key Vault 集成 | `secret_store.go` | 存/解密钥,`GetSecretStoreStatus` | | 网页台资源绑定页 | `web/default/src/features/resources/resources-page.tsx` | 已建,沿用 | | **`/v1/*` 模型网关** | `relay/*` | 客户端与 agent 两端模型都走这里,鉴权+计费 | | 账户/余额 | `GET /api/user/self` | 余额/用量,UI 概览用 | | V2 设备加密/签名 | `middleware/*`(`UserOrV2DeviceAuth` 等) | 客户端↔HM 鉴权 | | 能力发现(models 部分) | `GET /api/heicode/capabilities` | 保留 `models[]` 供模型选择;`modes` 见§5 修改 | | Runtime 健康探测 | `AgentRuntimeHealth`(`/api/agent/runtime/health`) | 探 AM 是否接通 | | 概述看板 / 资源页菜单 | web/default | 已建,沿用 | --- ## 4. 二、新增(接口 / 功能 / 数据) **后端接口(heicode 组,客户端走 `UserOrV2DeviceAuth`,UI 走会话)** | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/heicode/agent-templates` | 从 AM 拉模板列表(给 UI 选)。代理 AM 模板接口 | | POST | `/api/heicode/agents` | **部署**:body `{template_id, binding_ids[]}` → HM 解 KV 拼 env → 调 AM 启动 → 存记录 → 返回 `{agent_id, subdomain, token, status}` | | GET | `/api/heicode/agents` | 列出当前用户的 agent(`agent_id/subdomain/token/绑定资源/status`) | | GET | `/api/heicode/agents/{id}` | 单个 agent 详情(含绑了哪些资源) | | POST | `/api/heicode/agents/{id}/stop` | 停止(HM 转 AM) | | DELETE | `/api/heicode/agents/{id}` | 删除(HM 转 AM + 清记录) | **AM 客户端封装(`agent_runtime_client.go` 新增方法)** - `ListTemplates()` → 拉模板 - `StartAgent(templateID, env)` → 启动,返回 `{subdomain, token, agent_runtime_id}` - `StopAgent(id)` / `DeleteAgent(id)` **env 组装(新增,落点可在 `agent_task_bridge.go` 改造或新文件)** - 输入:选中的 `binding_ids[]` + 模板声明需要的 env 名(见§7 AM 契约)。 - 处理:每条 binding → 非密字段直接取值;密钥从 KV 解出 → 按 env 名填值 → 组成 env map 给 AM。 - 约束:**仅注入该 agent 选中的 binding**;HM 全程不落明文日志。 **网页台(web/default 新增页/组件)** - 模板选择 + 资源勾选 + 「部署」按钮。 - agent 列表页:状态、子域名、绑定资源、停止/删除操作。 **数据模型(建议复用现有 `AgentDeployment` 表扩字段,而非新建——见 teardown 文档 §0.0)** - 复用 `agent_deployments`(`agent_deployment.go`),**扩字段**:`template_id / subdomain / access_token / binding_ids(JSON)`;已有 `DeploymentID/UserID/RuntimeDeploymentID/Status` 等正好可当 agent 记录。 - 旧任务态字段(`SubMode/Phase/PlanJSON/AgentInstancesJSON/PayloadJSON` 等)停写、留列。 - `access_token` HM **存一份**(换设备登录后客户端重新拉列表即可拿回)。 - 跨 SQLite/MySQL/PG,GORM `AutoMigrate` 加列,TEXT 存 JSON。 --- ## 5. 三、修改 | 项 | 落点 | 改动 | |---|---|---| | 能力发现 | `HeicodeCapabilities` | `modes` 改为"基于已部署 agent / 模板"语义(或简化只留 `models`);去掉旧 sub/swarm 任务模式描述 | | 凭据注入 | `agent_task_bridge.go`(`resolveResourceBindingIntoGrant`/`normalizeTaskDraftResourceGrants`) | 从"给任务注入 grant(secret_ref)"改为"**给 agent 启动拼 env(非密+解密后的密钥)**" | | Runtime 回调 | `AgentReceiveRuntimeEventCallback`(`agent_callback.go`) | 收缩为**只收 agent 生命周期/状态**(started/stopped/unhealthy);**删掉 work 事件流**(客户端直连 agent,不再经 HM 转发) | | 资源模型 | `resource.go` + resource model | 明确非密 `metadata` 与 `secret_ref` 两段;可加 `env_map`(binding 字段 → env 名,配合§7) | | 网页台任务总览 | `web/default/src/features/agent-console/*` | 「任务总览」改/并入「**agent 列表与管理**」页 | --- ## 6. 四、删除 / 废弃(新模型不再需要) > 客户端直连 agent 后,HM 不再做任务编排与状态裁决。以下整块移除(删路由 + handler + 模型)。**删除前确认无其它依赖(尤其计费/审计不依赖 task 记录——计费走 `/v1/*` 已独立)。** | 项 | 落点 | |---|---| | 客户端统一任务接口整套 | `registerHeicodeTaskRoutes`(`api-router.go` 530-559):`/tasks`(create/list/detail/messages/execute/stop/workflow/logs/events/metrics/diagnostics/...) sub-agile 与 swarm 两组 | | 工作流投影 | `HeicodeTaskWorkflow`(`heicode_client_routes.go`) | | `display_status` 裁决 | `withDisplayStatus` 裁决逻辑(`agent_runtime_client.go`) | | 产物下载/项目文件夹 | `HeicodeListTaskArtifacts`/`HeicodeArtifactManifest`/`Archive`/`File`/`Revisions`(`heicode_project_artifacts.go`) | | 本地修改回传/revision | `HeicodeArtifactLocalEdit`、`consumeActiveRevision`(`heicode_task_create.go`)、`LatestAcceptedRevisionForDeployment`(`model/agent_artifact_revision.go`) | | 旧代部署控制面 | `HeicodeCreateDeployment`/`HeicodeListDeployments`、`HeicodeDeploymentTargets`(`/api/heicode/deployment-targets`) | | 审批接口(确认) | `/tasks/{id}/approvals*`、`HeicodeListTaskApprovals` —— 新模型审批由 agent 与客户端直接处理,HM 侧建议删,**待确认** | | 相关错误码 | `ARTIFACT_*`、`FILE_*`、`*_REVISION_*`、`LEASE_*`、`BUDGET_*` | | 相关数据表 | `artifact_revision` 等任务态表(保留历史可只停写) | --- ## 7. AM 契约(要和 AM 团队对齐的接口点) - **模板列表**:AM 提供"列模板"接口;每个模板声明 `template_id / name / 需要的资源类型(required_resource_types) / 期望的 env 名(env_schema)`。 - **启动 agent**:HM 调 AM「启动模板 X + env map」→ AM 返回 `{agent_runtime_id, subdomain, access_token, status}`。 - **token 校验**:agent 子域名对外 SSE,**自行校验 access_token**(HM 只转发 token 给客户端)。 - **生命周期**:AM 提供 stop/delete;部署后不自动停。 - **防泄密**:agent 不得把 `.env`/密钥回显到对话/日志/git —— **AM 保证**。 - **模型调用**:agent 用模型仍打 HM `/v1/*`(带用户身份计费)。 --- ## 8. 鉴权与密钥要点 - **鉴权三线**:客户端↔HM = V2 设备签名;客户端↔agent = AM 的 access_token;模型 = HM `/v1/*`。 - **密钥生命周期**:KV 静止 → HM 部署瞬间解出注入 env → 运行期只在 agent `.env`;**不进 HM 日志、不回客户端、不进 git**;agent 不回显(AM 保证)。 - **scope 隔离**:一条 binding 只该用户的 agent 可挂。 - **换密钥**:不支持改;重新部署新 agent。 --- ## 9. 决策记录(已拍板) 1. 凭据模型 = **方案 A**:HM 解 KV → 注入 agent `.env`,agent 不碰 KV。 2. git 凭据 = **scoped PAT 存 KV**(不做 GitHub App)。 3. vm/db/blob 生产密钥**只注入 agent env**,不走别的通道;agent 只写入 `.env`。 4. 客户端**直连 agent 子域名 SSE**,HM 不在回路。 5. agent 子域名**需 access token 才能访问**(AM 发+校验)。 6. agent **部署后常驻**,手动停/删在 HM UI。 7. **token HM 存一份**。 8. **不支持改密钥**;换 = 重新部署。 9. 两端模型都走 HM `/v1/*` 计费。 10. **砍掉**旧 sub 任务编排全套(task/workflow/display_status/git_ref/产物/租约/revision)。 --- ## 10. 落地顺序 1. 数据模型 `heicode_agent` + 资源模型非密/密钥分段(+ env_map)。 2. AM 客户端封装:ListTemplates / StartAgent / StopAgent。 3. 新增接口:agent-templates / agents(部署/列/详情/停/删) + env 组装(解 KV)。 4. 网页台:模板选择 + 资源勾选 + 部署 + agent 管理页。 5. 删除旧 sub 任务编排整套(§6)。 6. 修改:capabilities、回调收缩、任务总览→agent 管理页。 ## 11. 待确认 - §6 审批接口是否一并删(新模型审批在 agent↔客户端,HM 不掺和)。 - §7 模板 env_schema 的具体字段名约定(HM↔AM 对齐)。 - swarm 模式在新模型下是否也走"模板 agent"这条路(统一),还是另有形态。