forked from xiaohei/taiji-AI-PAD
== Heicode integration (~41 endpoints across 5 modules) ==
- §2 ResourceBinding (5 endpoints) — resources.py / resource_grants.py
- §4 NewAPI metadata proxy (4 endpoints) — heicode_proxy.py + heicode_client.py
- §5 Agnet platform stub (12 endpoints, in-memory mock) — agnet_stub.py
- §6 Task orchestration (5 endpoints + 3 extension endpoints) — heicode_tasks.py
6.1-6.5: intent / list / get / answer / messages
6.6-6.8: execution / delivery / audit?tab=... (Slice 8/9/10)
- §7 SSE single channel + approvals (4 endpoints + 5 event types) —
heicode_events.py + event_bus.py
- §7.8.1 internal billing-provider PUT endpoint — auth.py (routes)
== Schema changes ==
- migrations/026 heicode_tasks (orchestration state)
- migrations/027 users.billing_provider (litellm | newapi switch)
- migrations/028 heicode_approvals (high-risk approval queue)
== Register transaction hardening (P0 + P1 + P2) ==
routes/auth.py register():
- Pre-existing P0: failed register returned IntegrityError str verbatim
(leaking SQL params + ~50 plaintext LiteLLM keys per attempt).
Now logs exc_info, returns {code: REGISTER_FAILED, message: ...}.
- Pre-existing P0: model dedupe — two ModelProvider rows with overlapping
supported_models (e.g. taiji/gpt-4o-mini in both taiji and azure providers)
collide on uq_tenant_model. seen_models set deduplicates within the loop.
- New P1: track created_litellm_keys; on any failure call delete_key() for
each — prevents remote orphan keys when DB rollback fires.
- New P1: replace verify_code with peek_verification_code at the start;
only call verify_code (which consumes) after commit succeeds. Failed
registrations no longer burn the user's one-shot code.
- New P2: narrow inner `except (LiteLLMClientError, Exception)` to just
LiteLLMClientError so SQLAlchemy errors bubble to the outer rollback
instead of being silently swallowed into a half-allocated 200 response.
- New P2: same narrowing on outer `except (AgentManagerError, Exception)`.
== Auth middleware ==
- app/auth.py: allow /api/auth/internal/billing-provider and
/api/auth/internal/approvals to bypass user JWT (service-token auth
via HEICODE_INTERNAL_SERVICE_TOKEN, validated in-route).
== Docs ==
- Heicode-接口契约文档.md v2.2 (41 endpoints + SSE schema + 6.6-6.8)
- Heicode-对接进度与待办.md (through §7.14 SSE + 7.8.2 delivery回执)
- Heicode-完整调用流程图.md (sequence + routing diagrams)
- Agent-Manager-Heicode对接需求文档.md
- HEICODE_API_INTEGRATION.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1333 lines
81 KiB
Markdown
1333 lines
81 KiB
Markdown
# Heicode ↔ mcp-server (Heicode Manager) 对接进度与待办
|
||
|
||
**版本**: v2.0
|
||
**生效日期**: 2026-05-08
|
||
**对应 Heicode 主线**: `heicode.md` / `plan.md` / `heicode-runtime-auth-newapi-secret-design.md` / `integration/agnet-platform-request-contract.md`
|
||
**当前生产镜像**: `taiji.azurecr.io/mcp-server:heicode-tasks-20260508`(arm64)
|
||
|
||
**v2.0 重要变化**(vs v1.0):
|
||
- ✅ **P4 NewAPI 元数据透传 4 端点已上线**(待 B-1 admin token 配置即真跑)
|
||
- ✅ **P5 本地 stub 12 端点已上线**(mock 数据,cc-haha 可立即联调)
|
||
- ✅ **任务编排 5 端点已上线**(cc-haha 任务驾驶舱 / 工作台 直接切真)
|
||
- 当前已上线 mcp-server 端 **34 个 Heicode 相关接口**
|
||
- 全部端到端测试通过:登录 9/9 + P1 14/14 + P4 8/8 + P5 stub 20/20 + 任务编排 25/25
|
||
|
||
> 本文档汇总 mcp-server 侧已交付内容、未交付内容与原因,并明确每个待办项需要 Heicode 这边提供什么信息或决策。用于双方对齐进度、解锁阻塞。
|
||
|
||
> 📍 **整体调用关系**见 [`Heicode-完整调用流程图.md`](./Heicode-完整调用流程图.md)。
|
||
|
||
## 0. Heicode 项目真实组成(核实于 2026-05-05)
|
||
|
||
| 组件 | 物理形态 | 角色 | 与 mcp-server 关系 |
|
||
|---|---|---|---|
|
||
| `heicode/cc-haha/` | Tauri 桌面应用 + Bun CLI | "Heicode 客户端"(用户编程入口) | **当前不直接调** mcp-server |
|
||
| `heicode/heicode/web/default/` | React + Rsbuild SPA | NewAPI 自带管理 UI(用户进的那个) | ✅ 直接跨域调 mcp-server `/login` `/me` `/refresh` `/logout` |
|
||
| `heicode/heicode/` (Go 后端) | Gin + GORM | **NewAPI** —— 模型网关 + 计费 + 用户/Token/Group | ✅ 调 mcp-server `/me` `/refresh`(验证前端给的 token) |
|
||
| `heicode/website/` | Next.js | 极简市场页 | 与登录无关 |
|
||
|
||
**结论**:mcp-server **是事实上的主认证源**。heicode 前后端都依赖 mcp-server 的 4 个登录接口;字段形态绝不能 breaking change。
|
||
|
||
|
||
---
|
||
|
||
## 1. 已交付(生产可用 ✅)
|
||
|
||
### 1.1 登录认证(4 接口)
|
||
|
||
| 接口 | 路径 | 状态 |
|
||
|---|---|---|
|
||
| 登录 | `POST /api/auth/login` | ✅ 上线,Heicode 可直接调 |
|
||
| 当前用户 | `GET /api/auth/me` | ✅ 上线 |
|
||
| 续期 | `POST /api/auth/refresh` | ✅ 上线 |
|
||
| 登出 | `POST /api/auth/logout` | ✅ 上线 |
|
||
|
||
**对接文档**: 已发给 Heicode 团队(见 `integration/Heicode-登录接口对接文档.md`,Heicode 仓库已收录)。
|
||
|
||
**已通过的端到端测试**: 9/9。包括限流(每 IP 5/min)、refresh token 类型校验、登出黑名单、审计日志。
|
||
|
||
---
|
||
|
||
### 1.2 P1 资源模型(9 接口)
|
||
|
||
依据:`heicode.md §五`、`plan.md §P1`。
|
||
|
||
| 接口 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| 创建资源绑定 | `POST /api/resources` | 用户绑定 Git/SK/项目文档/云账号/云资源 |
|
||
| 列表 | `GET /api/resources` | 当前用户的所有绑定 |
|
||
| 详情 | `GET /api/resources/{id}` | 单个绑定 |
|
||
| 更新 | `PUT /api/resources/{id}` | 改 metadata/scope/secret_ref/status |
|
||
| 软删除 | `DELETE /api/resources/{id}` | status=revoked |
|
||
| 创建授权 | `POST /api/resource-grants` | 把 binding 授给 role/agent |
|
||
| 列表 | `GET /api/resource-grants` | 当前用户的所有 grant |
|
||
| 详情 | `GET /api/resource-grants/{id}` | 单个 grant |
|
||
| 撤销 | `DELETE /api/resource-grants/{id}` | status=revoked + revoked_at |
|
||
|
||
**安全约束(已实现)**:
|
||
- 写入前递归扫描 `metadata` / `constraints` / `permission_scope` / `allowed_actions`,任何 key 包含 `password|token|secret|private_key|access_key|credential` 均返回 **422 `RESOURCE_GRANT_SECRET_REJECTED`**
|
||
- 例外:key 名为 `secret_ref` 视为引用允许通过
|
||
- Grant 的 `allowed_actions` 必须是对应 binding `permission_scope` 的子集;否则 **400 `RESOURCE_GRANT_INVALID`**
|
||
- 跨用户访问别人的 binding/grant → **403 `FORBIDDEN_SCOPE`**
|
||
|
||
**已通过的端到端测试**: 14/14。含敏感字段拒绝、子集校验、跨用户隔离、现有业务回归。
|
||
|
||
**联调说明**:Heicode 前端的"绑定资源 → 分配角色 → 部署"主流程,前两步现在就能调通。
|
||
|
||
---
|
||
|
||
## 2. 未交付项(按需点单)
|
||
|
||
每一项都列:**是什么 / 为什么没做 / 需要 Heicode 提供什么 / 推荐 owner / 工作量预估**。
|
||
|
||
---
|
||
|
||
### 2.1 P2 Secret Broker / Secret Store
|
||
|
||
**是什么**: 用户绑定 Git/云资源时,真实凭据(GitHub PAT、Azure key 等)由 Manager 后端的 Secret Broker 写入 Vault/OpenBao;Manager DB 只保存 `secret_ref`。
|
||
|
||
**当前替代**: P1 的 `secret_ref` 字段是普通字符串,前端写啥就存啥(推荐写 `vault://...` 占位)。**没有真实 Vault 写入**。
|
||
|
||
**为什么没做**:
|
||
1. **AKS 集群里还没部署 Vault/OpenBao**
|
||
2. **选型未拍板**:Heicode 文档列了三个候选(HashiCorp Vault / Infisical / Azure Key Vault),各有取舍:
|
||
- Vault: 能力最全(Kubernetes Auth、动态密钥、TTL、Policy)
|
||
- Infisical: 体验好,多租户隔离待验证
|
||
- Azure Key Vault: Azure 优先时最易部署,但语义偏 KV 而非 Secret 治理
|
||
3. **缺凭据获取流程**:OAuth/GitHub App callback 流程没设计
|
||
|
||
**需要 Heicode 提供 / 决策**:
|
||
- ❓ **Secret Provider 选型**:Vault / Infisical / Azure Key Vault 三选一
|
||
- ❓ **部署位置**:AKS 内 namespace `secret-store`?独立 VM?Azure managed?
|
||
- ❓ **凭据来源**:用户在前端填表 vs OAuth 第三方授权 vs GitHub App
|
||
- ❓ **路径规范**:`vault://secret/users/{user_id}/bindings/{binding_id}/resources/{resource_id}` 这种约定 OK 吗?
|
||
- ❓ **轮换策略**:是否支持 TTL / 自动轮换?由谁触发?
|
||
|
||
**推荐 owner**: mcp-server(Secret Broker 代码) + 基础设施团队(Vault 部署 + K8s Auth)
|
||
|
||
**工作量预估**:
|
||
- Vault 部署 + K8s Auth 配置:~3 天(基础设施)
|
||
- mcp-server Secret Broker 实现:~5 天(写入/读取/轮换/撤销 + 审计)
|
||
|
||
---
|
||
|
||
### 2.2 P3 Agnet AKS 身份接入
|
||
|
||
**是什么**: 子 Agent Pod 通过 K8s ServiceAccount + Workload Identity 拿身份;运行时只能访问被授权的 secret;不接收长期密钥。
|
||
|
||
**为什么没做**:
|
||
- **主要不在 mcp-server 范围**:
|
||
- 涉及改 AKS 集群配置(Workload Identity)
|
||
- 涉及改 agent-manager 的 Pod spec 模板
|
||
- 涉及改子 Agent 容器的 entrypoint(启动后从 Vault 自取短期凭证)
|
||
- **依赖 P2**:Vault 没就位前 Workload Identity → Vault 的桥接没法做
|
||
|
||
**需要 Heicode 提供 / 决策**:
|
||
- ❓ **AKS Workload Identity 是否启用?** 需要先在集群上配置 OIDC issuer + Federated Identity
|
||
- ❓ **子 Agent 镜像的 entrypoint 改造负责人?** mcp-server 不出 Agent 镜像
|
||
- ❓ **资源授权 → K8s ServiceAccount 的命名约定**?
|
||
- ❓ **是否区分 dev/staging/prod 三套集群?**
|
||
|
||
**推荐 owner**: agent-manager 团队 + AKS 基础设施团队
|
||
|
||
**工作量预估**: ~1-2 周(含基础设施)
|
||
|
||
---
|
||
|
||
### 2.3 P4 NewAPI 解耦(Manager 拉取 NewAPI 元数据)
|
||
|
||
**Heicode 团队 2026-05-07 修订(C 方案 — 两平台并存,详见完整调用流程图 §2.5)**:
|
||
|
||
模型调用实际有**四条独立路径**:
|
||
|
||
| # | 调用方 | 触发场景 | 走哪 |
|
||
|---|---|---|---|
|
||
| 1 | Heicode 客户端(桌面)+ heicode web 前端 | 用户实时交互式 chat / 写代码 | **Heicode NewAPI**(`code.xinghanlab.com`) |
|
||
| 2 | 子 Agent Pod(**Heicode 用户部署的**) | 任务执行时调模型,`billing_context.provider="newapi"` | **Heicode NewAPI** |
|
||
| 3 | 子 Agent Pod(**原生 taijiagent 用户部署的**) | 任务执行时调模型,`billing_context.provider` 默认或 `"litellm"` | **taijiagent LiteLLM** |
|
||
| 4 | mcp-server 进程内(embedding / 内部分类) | mcp-server 自身功能 | **LiteLLM** |
|
||
|
||
**核心结论**:
|
||
- LiteLLM 同时是 ① taijiagent 平台对其用户的**产品级**模型网关 + ② mcp-server 自己内部工具
|
||
- NewAPI 同时是 ① Heicode 平台对 Heicode 客户端用户的**产品级**网关 + ② Heicode 部署的 agent 计费网关
|
||
- 子 Agent 走哪条网关由 mcp-server 在 `POST /api/agnet/deployments` 的 `billing_context.provider` 字段决定
|
||
- **LiteLLM 与 NewAPI 不冲突,不需要替代/迁移**
|
||
|
||
---
|
||
|
||
**P4 真实任务**:mcp-server 在控制台聚合费用展示时,把"路径 1+2 的 NewAPI 数据"和"路径 3 的 LiteLLM 数据"合并展示给用户。属于**只读元数据查询 + 前端聚合**。
|
||
|
||
具体要拿的元数据(heicode NewAPI 已就绪的接口):
|
||
|
||
| heicode 接口 | 用途 |
|
||
|---|---|
|
||
| `GET /api/user/self` | 用户基础信息 + 余额 |
|
||
| `GET /api/user/self/models` | 当前用户可用模型 |
|
||
| `GET /api/user/self/groups` | 用户分组 |
|
||
| `GET /api/log/self/stat` | 调用统计 |
|
||
| `GET /api/log/self` | 调用日志 |
|
||
| `GET /api/data/self` | 按日用量 |
|
||
| `GET /api/usage/token/` | token 维度用量(用 access token 调) |
|
||
|
||
**当前状态**: mcp-server 还**没**调 NewAPI 拿元数据。元数据展示这块的 Manager UI 也还没建。
|
||
|
||
---
|
||
|
||
### 2.3.1 Heicode 团队对 4 个 ❓ 的答复(2026-05-07)
|
||
|
||
> 决策已定,可直接开工,无需再往返。
|
||
|
||
| # | 问题 | **答复** | 理由 |
|
||
|---|---|---|---|
|
||
| ① | **服务凭据方案**(A pass-through / B service-token / C OAuth client) | **B:mcp-server 持有 NewAPI service token,按 user_id 维度筛选** | mcp-server 是后端服务(不是用户代理);service token 性能好、不依赖每用户凭据;A 路径在长会话场景下 token 续期复杂;C 路径需要 NewAPI 实装 OAuth provider,工作量太大且短期不需要。**Heicode 这边会用一个超级管理员 NewAPI access token 给 mcp-server 用**,token 通过 OpenBao/Vault 注入 mcp-server pod 环境变量。token 命名建议:`HEICODE_NEWAPI_SERVICE_TOKEN`。 |
|
||
| ② | **NewAPI base URL** | **`https://code.xinghanlab.com`**(生产 / 唯一对外入口) | 该域名走 Cloudflare → Azure VM → heicode 容器,已上线生产。mcp-server 出站走公网即可(Azure→Cloudflare→Azure 同 region);如未来需要内网,再加 Azure Private Endpoint。 |
|
||
| ③ | **Manager UI 范围**(哪些元数据要展示) | **第一版只展示 4 项**:① 余额(`GET /api/user/self` 的 quota 字段)② 当前可用模型清单(`/api/user/self/models`)③ 30 天用量汇总图(`/api/data/self`)④ 最近 50 条调用日志(`/api/log/self?limit=50`)。**详细统计、token 维度用量、分组管理留到 v2**。 | 与 heicode web 现有"用户中心"页对齐;mcp-server UI 不重复 NewAPI 自家功能,只做"聚合视图"差异化。 |
|
||
| ④ | **透传 vs 直连** | **透传**(mcp-server 包一层 `/api/user/heicode/*`) | 三个理由:① 前端只对接一个域(mcp-server),不引入 `code.xinghanlab.com` 第三方域 → 简化 CORS;② 鉴权审计统一在 mcp-server;③ 未来如果 NewAPI 切换内网地址,前端零改动。 |
|
||
|
||
**配套约定**(Heicode 端落实):
|
||
- Heicode 这边创建一个专用的 `mcp-server-service` 用户(role = admin),生成一个永久 access token
|
||
- 该 token 走 OpenBao 注入 mcp-server pod 的 `HEICODE_NEWAPI_SERVICE_TOKEN` env
|
||
- mcp-server 调 NewAPI 时,在 user-context 路由(如 `/api/user/self`)上需要按 `New-Api-User: <真实用户 id>` 头切换身份;需要 mcp-server 提前拿到本地 `users.id`(即 from-agnet 流程里 syncLocalUserFromAgnet 返回的 id)
|
||
|
||
**推荐 owner**: mcp-server(透传层 + heicode_client.py) + 基础设施(OpenBao token 注入)
|
||
|
||
**工作量预估**(按 ① + ② + ③ + ④ 答复):
|
||
- mcp-server 加 `HEICODE_NEWAPI_SERVICE_TOKEN` env 读取 + heicode_client.py:~1 天
|
||
- mcp-server 透出 4 个 `/api/user/heicode/*` 端点(balance / models / usage-30d / logs-recent-50):~1.5 天
|
||
- Manager UI 一页"用量与费用" 接入:~1 天(前端)
|
||
- **总计 ~3.5 天**(比原 5 天压缩,因为 UI 只做 v1 范围)
|
||
|
||
---
|
||
|
||
### 2.3.2 还需 Heicode 进一步澄清的 2 个细节(不阻塞主开工)
|
||
|
||
Heicode 团队 2026-05-07 决策很完整,但落实到具体调用时还有 2 个二级问题没明示。**P4 主路径可以先开工**,这 2 个细节边做边对齐:
|
||
|
||
#### 细节 ① mcp-server 怎么知道 heicode 那边的本地 `users.id`?
|
||
|
||
Heicode 决策 ① 说:"mcp-server 调 NewAPI 时按 `New-Api-User: <真实用户 id>` 头切换身份"。
|
||
|
||
但 from-agnet 流程是 **heicode 后端调用 mcp-server**,mcp-server 从未收到 heicode 那边给该用户分配的本地 id。候选方案:
|
||
|
||
| 方案 | 实现 | 取舍 |
|
||
|---|---|---|
|
||
| (a) heicode 在 from-agnet 后**回调** mcp-server 一个新接口 `POST /api/auth/heicode-link {mcp_user_id, heicode_user_id}` | 要双方都加接口 + 同步表 | 最干净,但工作量大 |
|
||
| (b) **mcp-server 用自己的 user_id(UUID)当 `New-Api-User`**,NewAPI 那边把这个 UUID 当外部身份键,反查本地用户 | NewAPI 这边 user 表加 `external_id` 字段;mcp-server 不需要知道 heicode local id | 最简单,但 NewAPI 数据模型要小改 |
|
||
| (c) mcp-server 调 NewAPI 时用 email 反查 heicode local id(多一次往返) | NewAPI 已有 `GET /api/user/?email=xxx` 即可(admin token) | 性能差,每次调 NewAPI 多一次查询 |
|
||
|
||
**mcp-server 推荐 (b)**,因为:
|
||
- 已经在 from-agnet 流程里把 `mcp-server.user.id` 作为 `id` 字段返给 heicode 了(`/api/auth/me` 响应的 `data.id`)
|
||
- heicode 后端只需要在 `syncLocalUserFromAgnet` 里把它存到 `users.external_id`
|
||
- 之后 mcp-server 调 NewAPI 时,`New-Api-User: <mcp_user_id_uuid>` 就能让 NewAPI 反查到正确用户
|
||
|
||
❓ **请 Heicode 团队答复**:(a) / (b) / (c) 哪个?
|
||
|
||
#### 细节 ② 子 Agent 部署时 mcp-server 怎么决定 `billing_context.provider`?
|
||
|
||
Heicode 决策里隐含:"Heicode 用户" → `provider="newapi"`,"taijiagent 用户" → `provider="litellm"`。但 mcp-server 内的 User 表当前没有"哪个平台来的"标识。候选方案:
|
||
|
||
| 方案 | 实现 |
|
||
|---|---|
|
||
| (a) User 表加 `billing_provider` 字段(`newapi`/`litellm`,默认 `litellm`),from-agnet 流程同步时设为 `newapi` | mcp-server 加字段 + from-agnet 时回填 |
|
||
| (b) 看 user 是否从 `syncLocalUserFromAgnet` 路径来 → 推断 newapi。但 mcp-server 这边不知道 heicode 是否调过自己 | 不可行,信息缺失 |
|
||
| (c) Channel 表加 `default_billing_provider`,channel-level 决策;user 沿用所属 channel 的默认 | 适合"按渠道分平台"的场景 |
|
||
| (d) 统一一个新字段 `User.platform` ∈ {`taijiagent`, `heicode`},billing provider 由 platform 派生 | 概念更清晰,但加字段 |
|
||
|
||
**mcp-server 推荐 (a) 或 (d)**,最简单。
|
||
|
||
❓ **请 Heicode 团队答复**:(a) / (c) / (d) 哪个?或者 mcp-server 自己拍板?
|
||
|
||
> 这两个细节即使没立刻答复也**不阻塞 P4 元数据查询主开工**。可以先用占位方案(mcp-server 用自己 user_id 当 `New-Api-User`,子 Agent 默认走 LiteLLM),跑通主流程后再按 Heicode 答复回填。
|
||
|
||
---
|
||
|
||
### 2.4 P5 — Manager 侧 Agnet 出站客户端
|
||
|
||
**是什么**: mcp-server 实现 12 个出站调用,把 `orchestration_plan` 发给真实的 Agnet 平台。
|
||
|
||
**对应 Heicode 文档**: `integration/agnet-platform-request-contract.md` §2-§7。
|
||
|
||
**为什么没做**:
|
||
- **没有调用目标**:Agnet 平台(agent-manager)**还没实现** 12 个新接口
|
||
- 调一个不存在的端点会全 404
|
||
- Heicode 文档自己说:"当前仓库提供 Manager 侧最小验证端点,**生产 Agnet 平台部署尚未完成**"
|
||
|
||
**需要 Heicode 提供**:
|
||
- ❓ **agent-manager 端 12 接口实现的时间表**(见 §2.6)
|
||
- ❓ **Agnet 平台 base URL** 和 **Manager 服务令牌的 secret_ref**(先用占位,等部署确定)
|
||
- ❓ **联调环境**(staging)地址 vs 生产地址
|
||
|
||
**推荐 owner**: mcp-server(client 实现) — 等 agent-manager 接口落地后
|
||
|
||
**工作量预估**: ~3-5 天(client 类、错误码处理、重试、幂等键)
|
||
|
||
---
|
||
|
||
### 2.5 P5 — Manager 侧本地 stub 端点(✅ **2026-05-08 已上线**)
|
||
|
||
**是什么**: 在 mcp-server 内挂载 12 个 `/api/agnet/*` 路由,返回 mock 数据,**用于前端联调**。
|
||
|
||
**完成情况**:
|
||
- 12 端点全部上线,字段形态严格按 `agnet-platform-request-contract.md`
|
||
- **20/20 端到端测试 PASS**(含 happy path + 5 错误码场景 + 幂等 + 跨用户隔离 + 业务回归)
|
||
- 镜像:`mcp-server:heicode-p5-stub-v2-20260508`
|
||
- 见 [接口契约 §5](./Heicode-接口契约文档.md)
|
||
|
||
**实施过程发现的 1 个 bug 已修**:原 `reject_sensitive_keys` 子串匹配会把 `max_tokens` 误判为敏感字段(包含 "token")。已改为按契约 §8.3 仅扫 `metadata` / `constraints` / `audit` 三个字段。
|
||
|
||
**前端可立即用**:cc-haha 任务执行联调 / heicode web 展示部署状态都能基于真实路径 + 字段形态对接。
|
||
|
||
---
|
||
|
||
### 2.7 任务编排 5 端点(✅ **2026-05-08 已上线**)
|
||
|
||
**是什么**:cc-haha 任务驾驶舱(切片 7)+ 工作台 UI 配套。用户输入想法 → Heicode 追问 → 全部答完 → 生成任务卡。
|
||
|
||
**端点**:
|
||
- `POST /api/user/tasks/intent`
|
||
- `GET /api/user/tasks`
|
||
- `GET /api/user/tasks/{id}`
|
||
- `POST /api/user/tasks/{id}/answer`
|
||
- `POST /api/user/tasks/{id}/messages`
|
||
|
||
**完成情况**:
|
||
- 5 端点全部上线,字段形态严格对齐 `cc-haha/desktop/src/stores/heicodeTaskStore.ts`
|
||
- DB 表 `heicode_tasks` 已建(migration 026)
|
||
- **25/25 端到端测试 PASS**(含状态机、跨用户隔离、错误码 INVALID_OPTION/QUESTION_NOT_FOUND/NOT_FOUND/FORBIDDEN_SCOPE)
|
||
- 镜像:`mcp-server:heicode-tasks-20260508`
|
||
- 见 [接口契约 §6](./Heicode-接口契约文档.md)
|
||
|
||
**MVP 编排器为确定性模板**(不依赖 LLM):
|
||
- 初始 followups:scope(mvp/polish/prod-高风险)+ tech(modern_web/py_backend/let_heicode)
|
||
- 全答完 → 用 answers 填模板生成 TaskCard
|
||
- 后续可加 LLM 增强(用 LiteLLM 生成更智能 followups),**前端 0 影响**
|
||
|
||
**cc-haha 可立即从 mock 切真**:把 `heicodeTaskStore.ts` 里的 seeded 数据替换成 5 个端点调用即可。
|
||
|
||
---
|
||
|
||
### 2.6 P5 — agent-manager 12 接口实现(不在 mcp-server)
|
||
|
||
**是什么**: 真正在 Agnet 平台(agent-manager 服务)实现:
|
||
|
||
| 接口 | 必要性 |
|
||
|---|---|
|
||
| `POST /api/agnet/deployments` 创建子 Agent 部署 | 必需 |
|
||
| `GET /api/agnet/deployments[/{id}]` 部署列表/详情 | 必需 |
|
||
| `POST /api/agnet/deployments/{id}/stop` 停止 | 必需 |
|
||
| `GET /api/agnet/deployments/{id}/logs` 日志(脱敏) | 必需 |
|
||
| `GET /api/agnet/deployments/{id}/logs/stream` 实时 SSE | 可选 |
|
||
| `GET /api/agnet/projects/{binding_scope}/dashboard-snapshot` 监控 | 必需 |
|
||
| `GET /api/agnet/deployments/{id}/metrics` 指标 | 建议 |
|
||
| `GET /api/agnet/deployments/{id}/events` 事件 | 必需 |
|
||
| `GET /api/agnet/audit-logs` 审计 | 必需 |
|
||
| `POST /api/agnet/sk-snapshots/resolve` SK 解析 | 必需 |
|
||
| `GET /api/agnet/deployments/{id}/sk-snapshots` SK 查询 | 必需 |
|
||
|
||
**为什么没做**: **不在 mcp-server 代码库**。这是 agent-manager 团队的工作。
|
||
|
||
**需要 Heicode 提供**:
|
||
- ❓ **agent-manager 团队的对接负责人**
|
||
- ❓ **预计开发周期**
|
||
- ❓ **联调环境地址**
|
||
|
||
**推荐 owner**: agent-manager 团队
|
||
|
||
**工作量预估**: ~1-2 周(含 K8s API 集成、日志聚合、SSE 推送、metric 管道)
|
||
|
||
---
|
||
|
||
## 3. 已知小尾巴(透明化,不是 P1 引入)
|
||
|
||
### 3.1 Channel 登录的审计日志写入失败
|
||
|
||
**现象**: Channel 角色登录(如 `66@66.com`)成功后,`audit_logs` 表插入因 FK 约束失败:
|
||
```
|
||
ForeignKeyViolationError: Key (user_id)=(channel_uuid) is not present in table "users".
|
||
```
|
||
|
||
**当前行为**: 失败被 `try/except` 兜住,记 warning 日志。**登录 200 正常返回,业务零影响**。
|
||
|
||
**根因**: 上一轮 heicode-auth-fix2 加审计日志时,channel 登录的 `result_user_id` 用了 `Channel.id`,但 `audit_logs.user_id` 外键指向 `users.id`。
|
||
|
||
**修复方案**(小,待排): channel 登录时 `result_user_id=None`,或扩展 audit_logs 支持 `subject_type` 区分 user/channel。
|
||
|
||
**影响**: channel 登录的审计日志暂时不入库,只在 mcp-server 应用日志里有 warning。User 角色(即 Heicode 客户端登录)正常入库。
|
||
|
||
---
|
||
|
||
### 3.2 Heicode 文档与现有代码的边界差
|
||
|
||
Heicode 主线文档(2026-05-04)明确:
|
||
- 不再以 `tenant`/`project` 作为产品/认证/扣费主轴
|
||
- 用 `user_id` + `channel_id` + `binding_scope` + `resource_grants` 表达边界
|
||
|
||
mcp-server 现有代码层面仍存在:
|
||
- `tenant_id` 字段(在 `external_toolkits.tenant_id` 等地方,**当前业务仍在使用**)
|
||
- `Channel` 表(保留,作为分销渠道实体)
|
||
|
||
**对齐做法(已落地)**:
|
||
- 新接口(P1 资源模型)**不引入** tenant_id
|
||
- `agnet-platform-request-contract` 中的 `metadata.tenant_id`/`metadata.project_id` 标记为 **legacy 兼容字段**,新功能不依赖
|
||
- `User.channel_id` 继续作为身份载体,对外**作为** `user_context.channel_id` 透传
|
||
|
||
**Heicode 不需要做什么**:现有 mcp-server 业务(渠道后台、超管、用户中心)继续维护 channel/tenant 概念,不影响 Heicode 客户端。
|
||
|
||
---
|
||
|
||
## 4. 联调建议(按可执行顺序)
|
||
|
||
| 步骤 | 行动 | 阻塞解除条件 |
|
||
|---|---|---|
|
||
| 1 | Heicode 客户端实装 4 个登录接口 | 无(**现在就能做**) |
|
||
| 2 | Heicode 客户端实装资源绑定 UI | 无(**现在就能做**,调 9 个 P1 接口) |
|
||
| 3 | mcp-server 实现 P5 本地 stub | 等 Heicode 确认(**1-2 天能交付**) |
|
||
| 4 | Heicode 客户端基于 stub 联调"绑定 → 角色 → 部署"完整流程 | 步骤 3 完成后 |
|
||
| 5 | 产品决策:NewAPI 还是 LiteLLM 等价 | 决策后排工程 |
|
||
| 6 | 基础设施:Vault 部署 + 选型 | 决策后部署 |
|
||
| 7 | mcp-server P2 Secret Broker | 步骤 6 完成后 |
|
||
| 8 | agent-manager 团队实现 12 接口 | 排期 |
|
||
| 9 | mcp-server P5 出站 client | 步骤 8 完成后 |
|
||
| 10 | P3 AKS Workload Identity + Pod 改造 | 步骤 6+8 完成后 |
|
||
|
||
**最快产生价值的路径**:1 → 2 → 3 → 4。前四步**完全不依赖** Heicode 之外的任何方,**两周内可联调全主流程**(基于 stub)。
|
||
|
||
---
|
||
|
||
## 5. 联调环境
|
||
|
||
**生产 mcp-server 入口**: `https://apimtaiji.azure-api.net/api/mcp/api/...`(经 Azure APIM 网关)
|
||
|
||
**测试账号**(仅联调用):
|
||
|
||
| 角色 | 邮箱 | 密码 |
|
||
|---|---|---|
|
||
| 普通用户 | `55@55.com` | `By@123456.` |
|
||
| 渠道管理员(不给 Heicode 用,留给现有业务) | `66@66.com` | `66` |
|
||
| 超级管理员(同上) | `superadmin@taiji-ai.com` | `Admin@123456` |
|
||
|
||
**Heicode 客户端固定使用** `role="user"` 登录。
|
||
|
||
---
|
||
|
||
## 6. 联系与反馈
|
||
|
||
如对接过程发现接口行为与文档不一致:
|
||
|
||
- 请附 `X-Request-Id` 头值(如未传,附完整 URL + Body + 响应 + 时间戳)
|
||
- mcp-server 后端可按 `X-Request-Id` 反查日志和审计
|
||
|
||
如需 Heicode 这边对未实现项做决策(见 §2 各项末尾的 ❓),请直接答复或在 Heicode 仓库新建 issue。
|
||
|
||
---
|
||
|
||
## 7. Heicode 团队答复(2026-05-07)
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧
|
||
> 范围:本文档 §2 列出的 18 项 ❓ 决策点 + §2.4 P4 NewAPI vs LiteLLM 表述澄清
|
||
> 状态:本节是答复,**不是规范**;规范以 Heicode 仓库 `docs/` 下原始设计为准
|
||
|
||
### 7.1 立即可定的(10 条)
|
||
|
||
| # | 原问题位置 | 答复 |
|
||
|---|---|---|
|
||
| 1 | §2.1 Secret Provider 选型 | **HashiCorp Vault**。理由:Heicode 上游 `heicode.md §六` 把它列在第一位,K8s Auth/TTL/Policy 能力最全,与 §五的"密钥不能进入客户端,由 Manager 统一托管"路径最契合 |
|
||
| 2 | §2.1 部署位置 | **AKS 内独立 namespace `secret-store`**。与 Agnet 同集群、内网通路;不暴露公网(参见 `deployment/azure-production-deploy-guardrails.md`) |
|
||
| 3 | §2.1 凭据来源 | **优先 OAuth / GitHub App,前端表单作为兜底**。GitHub App 路径符合 §1.2 P1 `secret_ref` 不接收明文的安全红线 |
|
||
| 4 | §2.1 secret_ref 路径规范 | **OK**。`vault://secret/users/{user_id}/bindings/{binding_id}/resources/{resource_id}` 与 `agnet-platform-request-contract` 中 `permission_manifest.resource_grants[].secret_ref` 示例完全一致 |
|
||
| 5 | §2.1 轮换策略 | **Vault 原生 TTL + Pod 启动时 K8s Auth 自动续期**。无需 Manager 显式触发轮换 |
|
||
| 6 | §2.2 K8s ServiceAccount 命名 | **`sa-{role}-{user_id_short_hash}`**(与 `Agent-Manager-Heicode对接需求文档.md §4.1` 一致)。短哈希取 user_id sha1 前 8 位 |
|
||
| 7 | §2.4 NewAPI vs LiteLLM | **两个并行平台各有网关,不替代不冲突**。LiteLLM 是 taijiagent 平台对其用户的产品级模型网关;NewAPI 是 Heicode 平台对其用户的产品级模型网关;两边共用 mcp-server 账号。详见 §7.3 |
|
||
| 8 | §2.5 是否做 P5 本地 stub | **立即做**。这是 Heicode 客户端联调任务驾驶舱主流程的前置;本文档自己也建议优先(详见 §7.5 第 2 项已升级为阻塞)|
|
||
| 9 | Agent-Manager 文档 §2.1 服务令牌方案 | **(A) Pre-shared bearer 起步,后期升 (C) Workload Identity**。与 mcp-server 自己的建议一致 |
|
||
| 10 | §2.2 子 Agent 镜像 entrypoint 改造负责人 | **agent-manager 团队**。Heicode 不出 Agent 镜像;Pod 启动逻辑、Vault 拉取流程均归 agent-manager |
|
||
|
||
### 7.2 需团队/基础设施侧讨论后再定(8 条,先记账)
|
||
|
||
| # | 原问题位置 | 当前判断 | 等谁 |
|
||
|---|---|---|---|
|
||
| 11 | §2.2 AKS Workload Identity 启用 | 必须启用(Heicode 安全设计依赖) | 基础设施团队排期 |
|
||
| 12 | §2.2 dev/staging/prod 集群分隔 | **至少 staging + prod**;dev 复用 staging | 基础设施团队 |
|
||
| 13 | §2.4 如选 NewAPI 实体如何部署 | 见 §7.3 —— 当前不强制迁移 | — |
|
||
| 14 | §2.5/§2.6 agent-manager 12 接口时间表 | 参考其文档 §7,预计 3-4 周闭环 | agent-manager 团队回复 |
|
||
| 15 | §2.5 Agnet 平台 base URL + 服务令牌 secret_ref | 待 staging 部署落地 | agent-manager 团队 |
|
||
| 16 | §2.6 联调环境地址 | 建议 `staging-agnet.xinghanlab.com` / `agnet.xinghanlab.com` | agent-manager 团队 |
|
||
| 17 | §2.6 agent-manager 团队对接负责人 | — | 项目管理 |
|
||
| 18 | §2.6 agent-manager 开发节奏 | 按其 §7 phase | agent-manager 团队 |
|
||
|
||
### 7.3 §2.4 P4 表述澄清:C 方案 — 两个并行平台 + 子 Agent 网关由 billing_context 决定
|
||
|
||
> ⚠️ Heicode 团队 2026-05-07 三次修订(最终版)。本节经历的版本:
|
||
> - v1(已撤回):"LiteLLM 是 mcp-server 进程内细节" — 否定了 LiteLLM 的产品级地位
|
||
> - v2(已撤回):mcp-server 团队 §2.3 改写为 "子 Agent 全部走 NewAPI" — 忽略了原生 taijiagent 用户场景
|
||
> - v3(已撤回):Heicode 反向修订为 "子 Agent 全部走 LiteLLM" — 忽略了 Heicode 用户部署 agent 的场景
|
||
> - **v4(本版,最终)**:C 方案 — 子 Agent 网关由 `billing_context.provider` 字段决定,两条路径并存。**已被 mcp-server 团队最新 §2.3 采用。**
|
||
|
||
**架构(C 方案)**:
|
||
|
||
| 平台 | 组成 | 自家产品级模型网关 |
|
||
|---|---|---|
|
||
| **taijiagent** | mcp-server + agent-manager + LiteLLM | **LiteLLM** |
|
||
| **Heicode** | Heicode 客户端(桌面)+ heicode web(浏览器)+ heicode 后端(NewAPI)| **NewAPI** |
|
||
|
||
两个平台**共用 mcp-server 的账号体系**,**模型网关各自独立**。
|
||
|
||
**四条独立的模型调用路径**:
|
||
|
||
```
|
||
[路径 1] Heicode 客户端(桌面)+ heicode web(浏览器)用户实时交互式 chat
|
||
→ Heicode NewAPI (code.xinghanlab.com) → 上游 LLM
|
||
|
||
[路径 2] 子 Agent Pod (Heicode 用户部署的,billing_context.provider="newapi")
|
||
→ Heicode NewAPI (带 newapi_user_ref / newapi_group) → 上游 LLM
|
||
|
||
[路径 3] 子 Agent Pod (原生 taijiagent 用户部署的,billing_context.provider 默认或 "litellm")
|
||
→ taijiagent LiteLLM → 上游 LLM
|
||
|
||
[路径 4] mcp-server 进程内功能 (embedding / 内部分类)
|
||
→ LiteLLM (mcp-server 自用)
|
||
```
|
||
|
||
**关键事实**:
|
||
- **LiteLLM 同时承担两种角色**:① taijiagent 平台对其用户的产品级模型网关(路径 3)+ ② mcp-server 自身内部工具(路径 4)
|
||
- **NewAPI 同时承担两种角色**:① Heicode 平台对 Heicode 客户端 / heicode web 用户的产品级网关(路径 1)+ ② Heicode 用户部署的 agent 计费网关(路径 2)
|
||
- 子 Agent 走哪条网关由 mcp-server 在 `POST /api/agnet/deployments` 的 `billing_context.provider` 字段决定
|
||
- 路径 2 和路径 3 共用同一套 agent-manager + AKS Pod 基础设施,**只是计费网关不同**
|
||
|
||
**P4 真实任务**(mcp-server 控制台聚合费用面板):
|
||
|
||
| 数据来源 | 适用场景 | 数据获取 |
|
||
|---|---|---|
|
||
| mcp-server 自己的 LiteLLM 计费记录 | 路径 3 + 路径 4 | mcp-server 直接读自己 DB |
|
||
| Heicode NewAPI 元数据 | 路径 1 + 路径 2 | mcp-server 通过 `app/heicode_client.py` 调 `code.xinghanlab.com` 的只读接口 |
|
||
|
||
聚合后给用户展示统一费用面板。详细 4 个 ❓ 答复见 **§2.3.1**。
|
||
|
||
**P4 不需要做的**:替换 / 迁移 LiteLLM。
|
||
|
||
理由参考:
|
||
- 上游 `heicode.md §八`:NewAPI 是 "**Heicode 平台**的内部模型网关与计费服务,后台不对普通用户开放" —— **Heicode 平台范围内**
|
||
- 上游 `vision-heicode-full-stack-agentic-dev.md` 把 Heicode 定位为"全栈 agentic dev"产品,借用 taijiagent 的 mcp-server(认证)+ agent-manager(执行);**不要求 LiteLLM 改成 NewAPI**
|
||
- LiteLLM 在 Heicode 上游设计文档中**完全不出现** —— 是 taijiagent 平台的产品级网关,不是 Heicode 的组件
|
||
- `agnet-platform-request-contract.md` `billing_context.provider="newapi"` 是 Heicode **预设接入方式**;taijiagent 平台目前不接受这个 provider,agent 全走 LiteLLM
|
||
|
||
### 7.4 Heicode 客户端当前对接状态(2026-05-08 修订)
|
||
|
||
> 术语澄清:本文中的 **"Heicode 客户端"** 即仓库内 `cc-haha/desktop/`
|
||
> 目录构建出的 Tauri 桌面端。`cc-haha` 是历史 fork 上游的目录名,对外
|
||
> 措辞统一用 **Heicode 客户端**,下文文件路径中的 `cc-haha/...` 仍保留
|
||
> 因为是物理目录。
|
||
|
||
> ⚠️ **2026-05-08 重要修订**:在 `docs/product-package/`(14 份产品文档落地)后,
|
||
> 客户端 / Manager 边界**重新划线**。08-client-guide.md §1-7 明确 **客户端不承担**
|
||
> 资源绑定 / 权限分配 / 账号与安全 / Agnet 部署 — 这些**全部移到 Manager**。
|
||
> Heicode 客户端在切片 5(commit `4827682`)下线了之前实装的 Resources UI 全套。
|
||
|
||
#### 登录链路(不变,✅ 已验证)
|
||
|
||
```
|
||
1. POST apimtaiji.azure-api.net/api/mcp/api/auth/login (mcp-server)
|
||
Body: {email, password, role: "user"}
|
||
→ 200 {token, refreshToken, user{id, email, role, channelId}}
|
||
|
||
2. POST code.xinghanlab.com/api/user/session/from-agnet (heicode 后端)
|
||
Body: {access_token, refresh_token}
|
||
→ 200 + Set-Cookie: session
|
||
|
||
3. GET code.xinghanlab.com/heicode/oauth/authorize?... (heicode 后端)
|
||
Headers: Cookie + New-Api-User
|
||
→ 302 Location: ...?token=sk-XXX
|
||
|
||
4. NewAPI sk- token 用于后续所有 /v1/messages、/v1/models 调用
|
||
```
|
||
|
||
测试号 `55@55.com / By@123456.` 端到端实测通过;channelId `6e6fc470-...` →
|
||
`/v1/models` 返回 28 个真实模型。
|
||
|
||
#### Heicode 客户端当前已实装的产品级 surface(按产品包 wireframe)
|
||
|
||
| Surface | wireframe 章节 | 实装状态 | 数据通道 |
|
||
|---|---|---|---|
|
||
| 极简登录页(品牌 + 邮箱+密码 + tagline) | §1 | ✅ commit `f08119f` | Path A(已用真接口)|
|
||
| 高危审批弹窗(任务 / 操作 / 资源 / 角色 / 影响 / 凭证 / Heicode 建议 / 三按钮)| §9 | ✅ commit `f08119f` | **mock**(`window.__heicodeMockApproval()` 触发) |
|
||
| 任务驾驶舱首页(intent prompt + 最近任务 + Manager 辅助提示)| §2 | ✅ commit `a268079` | **mock**(seeded 2 个任务) |
|
||
| 任务工作台(对话流 + 追问 chip + 任务卡 panel) | §3 | ✅ commit `a268079` | **mock**(seeded 对话 + 已选答案) |
|
||
| token 持久化(mcpAuth schema + 24h refresh)| — | ✅ 保留 | Path A 登录后自动写入 |
|
||
| 高级黑主题 + H 电路 logo + Win 自绘窗框 | 02 / 11 §1 | ✅ | — |
|
||
|
||
#### Heicode 客户端**已下线**(按产品包 08 §1-7 客户端边界)
|
||
|
||
| Surface | 状态 | 原因 |
|
||
|---|---|---|
|
||
| 资源绑定 CRUD 页面(之前 9 接口对接 + Modals)| ❌ 下线(commit `4827682`)| 产品包 08-client-guide.md 客户端不承担资源绑定 |
|
||
| Resource Grants UI | ❌ 下线 | 同上 |
|
||
| 模型 provider 配置页面 | ❌ 下线 | 产品包 08 客户端不出现"模型提供方配置" |
|
||
| ClawdRouter 备选登录 | ❌ 下线 | 产品包"登录目标只有 Heicode" |
|
||
| `/api/heicode-resources/*` 本地代理 | ❌ 下线 | 客户端不再调 P1 接口 |
|
||
| `cc-haha-provider`/`env`/`original-settings` 三级 fallback | ❌ 下线 | 产品包要求强制走 Heicode 登录 |
|
||
|
||
> 资源绑定 / 权限 / 部署 等 surface 应由 **heicode web (`code.xinghanlab.com`)**
|
||
> 承担,Heicode 客户端通过任务卡里的 "去 Manager 准备" 按钮跳转过去。
|
||
|
||
#### Heicode 客户端等 mcp-server 接口的清单
|
||
|
||
| 等的接口 | 用途 | mock 现状 | 阻塞优先级 |
|
||
|---|---|---|---|
|
||
| 任务编排(intent → followups → manifest → status)| 把任务驾驶舱 mock 换成真数据 | seed 2 个任务 + 浮于内存 | 🔴 高 — UI 已搭好等接口 |
|
||
| 高危审批分发(推送通道)| 把 `__heicodeMockApproval` 换成真订阅 | 仅 DevTools 触发 | 🔴 高 — UI 已搭好等接口 |
|
||
| `/api/user/heicode/*` 元数据(§2.3.1)| 客户端右上角顶栏显示余额 / 模型 | — | 🟡 中 — 产品包没强制要求客户端展示 |
|
||
| P5 Agnet 12 接口(stub) | 任务执行反馈 + 交付结果面板 | 未做(切片 8/9 待启动)| 🟡 中 — 等 stub 后做 |
|
||
|
||
### 7.5 反向请求 mcp-server 团队配合的事项(2026-05-08 修订)
|
||
|
||
1. **建议本文档第 §2.4 节按 §7.3 改写**,避免"等价于"导致后续团队误解为替代关系
|
||
2. 🔴 **P5 本地 stub —— 现在已升级为「阻塞 Heicode 客户端联调」**:Heicode 客户端在切片 7 把任务驾驶舱 + 工作台 UI 全做完了,现在卡在 mock 数据阶段。**stub 出来当天就能联调全主流程**(intent → 追问 → 任务卡 → manager 跳转 → 状态轮询)。原本 1-2 天交付;建议立刻排期。
|
||
3. **APIM 网关 CORS / IP 白名单**:Heicode 客户端通过本地 Bun server 调 `apimtaiji.azure-api.net`,请确认无 IP 白名单限制(当前实测从北京 / Azure 香港均可达)
|
||
4. **`channelId` 双重含义建议二选一**或加字段名区分:
|
||
- "渠道身份" 用 `channelId`
|
||
- "NewAPI user/group 映射" 用 `newapi_user_ref` / `newapi_group`(与 `agnet-platform-request-contract` 一致)
|
||
|
||
5. 🆕 **任务编排 API 契约设计** —— 产品包 14 份文档**没有对应技术契约**,但客户端已按 wireframe §2-§3 把字段全设计好。请 mcp-server 团队**确认这套字段形态**或**提供你们的接口契约**让客户端对齐,否则等接口出来 UI 字段对不上要重做。客户端当前用的字段(见 `cc-haha/desktop/src/stores/heicodeTaskStore.ts`):
|
||
|
||
```ts
|
||
type HeicodeTask = {
|
||
id: string
|
||
name: string
|
||
status: 'draft' | 'configuring' | 'running'
|
||
| 'awaiting_approval' | 'completed' | 'failed' | 'paused'
|
||
status_caption?: string // 状态副标题,"后端实现中" / "等待生产部署审批"
|
||
created_at: number; updated_at: number
|
||
intent: string // 用户原始想法
|
||
thread: ChatTurn[] // 对话流(用户 + Heicode)
|
||
card?: TaskCard // 任务卡(可空,等 Heicode 整理出来)
|
||
}
|
||
|
||
type ChatTurn =
|
||
| { kind: 'user'; text: string; at: number }
|
||
| { kind: 'heicode'; text: string; at: number; followups?: FollowupQuestion[] }
|
||
|
||
type FollowupQuestion = {
|
||
id: string; question: string
|
||
options: Array<{ id: string; label: string; risk?: 'high-risk' }>
|
||
answer?: string // 用户选了哪个 option id
|
||
}
|
||
|
||
type TaskCard = {
|
||
goal: string // "做一个面向小团队的任务协作 SaaS。"
|
||
scope: string[] // bullet 列表
|
||
generated_artifacts: string[] // ["产品说明", "原型描述", ...]
|
||
manager_actions: Array<{ label: string; deeplink: string }>
|
||
}
|
||
```
|
||
|
||
预期的 API 形态(建议 mcp-server 实装):
|
||
- `POST /api/user/tasks/intent` body `{ intent }` → 返回新建 Task(含初始 followups)
|
||
- `GET /api/user/tasks` → 返回用户的任务列表
|
||
- `GET /api/user/tasks/{id}` → 返回单个 Task
|
||
- `POST /api/user/tasks/{id}/answer` body `{ question_id, option_id }` → 更新 followup 答案,可能触发新一轮 Heicode 追问
|
||
- `POST /api/user/tasks/{id}/messages` body `{ text }` → 用户继续追加要求
|
||
|
||
6. 🆕 **高危审批分发机制** —— Heicode 客户端已实装 ApprovalDialog(wireframe §9 全字段对齐),现在 mock 用 `window.__heicodeMockApproval()` 触发。请 mcp-server 团队**选定推送通道**:
|
||
|
||
| 方案 | 优点 | 缺点 |
|
||
|---|---|---|
|
||
| (A) SSE — `GET /api/user/approvals/stream` | 实时;浏览器/桌面通用 | mcp-server 要管 SSE 心跳 |
|
||
| (B) 短轮询 — `GET /api/user/approvals/pending`(5-15s) | 简单;无状态 | 延迟;高频负载 |
|
||
| (C) WebSocket | 双向;可顺便推任务状态 | 协议更重 |
|
||
|
||
建议 **(A) SSE** 起步(mcp-server 已经在用 FastAPI,加 SSE 简单)。
|
||
推送的 ApprovalRequest 字段对齐客户端类型:见 `cc-haha/desktop/src/stores/approvalStore.ts:ApprovalRequest`。
|
||
|
||
7. 🆕 **确认资源绑定 UI 由 Manager 承担**:Heicode 客户端在切片 5 已下线全套 P1 资源绑定 UI(08-client-guide.md §1-7 客户端不承担资源绑定)。Manager (`code.xinghanlab.com`) web 前端应该接 mcp-server 的 9 个 P1 接口实装资源绑定页。如果当前 heicode web 前端**没接** P1 接口,请 Manager 团队补上 —— 否则用户从客户端任务卡点 "去 Manager 准备" 按钮过去后会 404。
|
||
|
||
### 7.6 联系方式
|
||
|
||
- Heicode 客户端 / Manager 侧 commit 历史见 `chenchen/heicode-win` 仓库 main 分支
|
||
- 关键 commit:
|
||
- `86bad23` feat(login): align desktop credentials login with upstream Heicode design
|
||
- `4827682` refactor(client): retire client-side resources UI per new product spec
|
||
- `f08119f` feat(client): slice 6 — minimal login per spec + high-risk approval dialog
|
||
- `a268079` feat(client): slice 7 — task driving cabin (intent → followups → task card)
|
||
|
||
---
|
||
|
||
## 7.7 Heicode 团队对 v2.0(2026-05-08)的答复
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧
|
||
> 范围:本文档 §B 列出的 5 项待办 + §2.3.2 的 2 个细节 ❓
|
||
> 状态:本节是答复,**不是规范**
|
||
|
||
先感谢 mcp-server 团队的爆发式交付——一天上线 21 个新接口(§4 + §5 + §6),字段对齐 cc-haha 既有代码(heicodeTaskStore.ts),完全消除了我们 §7.5 列出的两条核心阻塞项(任务编排契约 + P5 stub)。👍
|
||
|
||
### 7.7.1 §2.3.2 细节答复
|
||
|
||
| 细节 | 选 | 理由 |
|
||
|---|---|---|
|
||
| **① mcp-server 怎么知道 heicode 本地 user_id?** | **(b)** mcp-server 用自己的 user_id(UUID)当 `New-Api-User`;NewAPI 表加 `external_id` 字段反查 | NewAPI 是我们自家 fork(heicode go 后端),加一行 migration + 一个 `WHERE external_id = ?` 查询,比方案 (a) 双向回调和 (c) email 反查都更干净。Heicode 后端会在 `syncLocalUserFromAgnet` 里把 `mcp_user_id` 存到 `users.external_id` 字段。 |
|
||
| **② 子 Agent `billing_context.provider` 怎么决定?** | **(a)** mcp-server User 表加 `billing_provider` ∈ {`newapi`, `litellm`},默认 `litellm`;from-agnet 同步时设 `newapi` | 概念清晰,加字段成本低;(d) `User.platform` 也行但容易扩散。后续如出现"按渠道分平台"的需求再升级到 (c)。 |
|
||
|
||
> 这两个改动 **NewAPI 侧由 Heicode 后端团队负责**(chenchen/heicode-win 的 `heicode/` Go 仓库),mcp-server 只需要按选定方案落地自己那一侧。
|
||
|
||
### 7.7.2 §B 待办进度
|
||
|
||
| # | Heicode 侧状态 | 备注 |
|
||
|---|---|---|
|
||
| **B-1** NewAPI service token | ✅ **已交付 + P4 真跑实测通过(2026-05-08)**。token 已交付 mcp-server,**已 rotate**(旧 32 字符 hex 已失效),DB 持有最新值 | 见下方 7.7.2.1 |
|
||
| **B-2** §2.3.2 答复 | ✅ 见上节 7.7.1 | — |
|
||
|
||
#### 7.7.2.1 B-1 实际交付明细
|
||
|
||
| 字段 | 值 |
|
||
|---|---|
|
||
| NewAPI 用户 id | **`26`**(即 `HEICODE_NEWAPI_ADMIN_USER_ID`)|
|
||
| username | `mcp-server` |
|
||
| role | 10(管理员)|
|
||
| status | 1(已启用)|
|
||
| access_token | 32 字符 hex(即 `HEICODE_NEWAPI_SERVICE_TOKEN`)— 见下方注 |
|
||
|
||
> **🔐 Token 提取约定(mcp-server AI 看这里)**:
|
||
> 实际 access_token 字符串放在本仓库的 [`Docs/heicode-svc-token.txt`](./heicode-svc-token.txt) —— **这个文件已被 `.gitignore` 排除**(验证:`git check-ignore -v Docs/heicode-svc-token.txt` 命中),仅在 chenchen 本机存在;本文档不写入明文值。
|
||
>
|
||
> mcp-server 团队 AI 操作流程:
|
||
> 1. `cat Docs/heicode-svc-token.txt` 读取 32 字符 hex
|
||
> 2. 通过 K8s secret 注入 mcp-server pod env:`HEICODE_NEWAPI_SERVICE_TOKEN=<那 32 字符>` + `HEICODE_NEWAPI_ADMIN_USER_ID=26`
|
||
> 3. `kubectl rollout restart deployment/mcp-server` 让新 env 生效
|
||
> 4. 注入完成后**告诉 chenchen 方"已收到,请删除 Docs/heicode-svc-token.txt 并 rotate token"**
|
||
> 5. chenchen 方收到 ack 后:① 删除 `Docs/heicode-svc-token.txt`;② 进 NewAPI `/profile`(mcp-server 用户)重新生成 token,触发旧 token 失效;③ 把新 token 同样通过本文件路径再传一次(如果还需要)
|
||
>
|
||
> ⚠️ 这是**一次性**临时通道,不是稳态机制。完成 P4 真跑后请把这套流程换成 OpenBao secret + K8s External Secrets Operator 拉取,参见 §2.1。
|
||
|
||
> **🔁 Rotate 状态(2026-05-08,mcp-server 团队 P4 真跑实测通过后)**:
|
||
> 1. ✅ Heicode 方删除 `Docs/heicode-svc-token.txt` + 本机 `D:\heicode-svc-token.txt` 副本
|
||
> 2. ✅ DB 中 `users.id=26` 的 access_token 已 rotate(新 32 字符 hex 写入),**先前那个交付的 token 立即失效**
|
||
> 3. ✅ VM `/tmp/heicode-svc-token.txt` 临时副本删除
|
||
>
|
||
> 当前 DB 持有的是 rotation 后的新 token,**没有任何文件副本**。下次 mcp-server 需要时再走同一通道(参见上面 5 步流程)传新值。
|
||
|
||
**端到端实测**(mcp-server 团队会用到的 admin 端点,本地从 VM 上 curl 测过):
|
||
|
||
| 端点 | 结果 |
|
||
|---|---|
|
||
| `GET /api/user/self` | ✅ 200, role=10 |
|
||
| `GET /api/user/{id}`(普通用户)| ✅ |
|
||
| `GET /api/user/?p=0&page_size=5`(用户列表)| ✅ |
|
||
| `GET /api/user/search?keyword=...`(admin 搜索)| ✅ |
|
||
|
||
⚠️ **已知约束**:admin (role=10) 读不了 root (role=100) 用户(heicode 仓库 `controller/user.go:280` 的 `myRole <= user.Role && myRole != RoleRootUser` 限制)。mcp-server 只查普通用户(role=1)和 admin(role=10),不受影响。如有读 root 的需要请告知,可以把 service 账号升 root,但当前默认走 admin。
|
||
|
||
**调用约定**(auth 中间件 [middleware/auth.go:36-122](https://gitee.ath.cx:3000/chenchen/heicode-win/src/branch/main/heicode/middleware/auth.go)):每次请求**两个 header 都必填**
|
||
|
||
```
|
||
Authorization: Bearer <HEICODE_NEWAPI_SERVICE_TOKEN>
|
||
New-Api-User: 26
|
||
```
|
||
|
||
`New-Api-User` 必须等于 token 持有者的 user.id(即 26),中间件强制校验 `id != apiUserId` mismatch。要查别的用户的数据,路径参数填别人 id 即可(如 `/api/user/2`),但 New-Api-User 头始终是调用者自己(26)。
|
||
| **B-3** heicode web 接 P1 资源 UI | 🟡 待协调。需要确认 `code.xinghanlab.com` 当前前端是 `heicode/web/default/` (NewAPI 自带 React) 还是另起新前端项目;若沿用现有前端,需排期接入 9 个 P1 接口 | 不阻塞客户端 |
|
||
| **B-4** agent-manager 12 真接口 | 🟢 待推进。需要拿到 agent-manager 团队对接负责人和排期 | mcp-server P5 stub 已上线,前端可基于 stub 全主流程联调,所以这条不阻塞 |
|
||
| **B-5** cc-haha 任务驾驶舱切真 | 🟢 准备就绪。客户端已实装 Slice 7(驾驶舱 + 工作台)+ Slice 8/9/10(执行反馈 / 交付结果 / 任务详情抽屉)的 mock 骨架,字段全部对齐 §6 契约 | 见下节 7.7.3 |
|
||
|
||
### 7.7.3 cc-haha 当前状态(2026-05-08)
|
||
|
||
#### 已实装的 UI 切片(产品包 wireframe 11-product-prototype-wireframes.md)
|
||
|
||
| Slice | wireframe | 状态 | 数据通道 |
|
||
|---|---|---|---|
|
||
| 5 — 资源 UI 下线 | 产品包 08 §1-7 | ✅ 已下线 | — |
|
||
| 6 — 极简登录 + 高危审批弹窗 | §1 / §9 | ✅ | 登录走真接口;审批走 `window.__heicodeMockApproval()` mock |
|
||
| 7 — 任务驾驶舱首页 + 工作台 | §2 / §3 | ✅ | 内存 seed 任务 |
|
||
| **8 — 执行反馈面板** | **§8** | ✅ **新增** | seed(5 个 sub_step + 3 个 sk_tool_call + 3 个 event + 4 个 artifact) |
|
||
| **9 — 交付结果面板** | **§10** | ✅ **新增** | seed(4 个 deliverable + 4 个 quality + 3 个 next_action) |
|
||
| **10 — 任务详情抽屉** | §audit | ✅ **新增** | seed(用量 / 资源访问 / 审批 / 安全 4 tab) |
|
||
|
||
**右侧面板由 task.status 驱动切换**:
|
||
- `running` / `awaiting_approval` → ExecutionFeedbackPanel (Slice 8)
|
||
- `completed` → DeliveryResultPanel (Slice 9)
|
||
- 其他 → TaskCardPanel
|
||
- 顶栏「查看详情」→ TaskDetailDrawer (Slice 10)
|
||
|
||
#### Slice 8/9/10 字段形态(已和 §6 / §5 对齐)
|
||
|
||
```ts
|
||
// cc-haha/desktop/src/stores/heicodeTaskStore.ts (已扩展)
|
||
type ExecutionState = {
|
||
sub_steps: SubStep[] // 状态 ∈ {done|running|waiting|failed|skipped}
|
||
sk_tool_calls: SkToolCall[]
|
||
events: ExecutionEvent[]
|
||
artifacts: Artifact[] // kind ∈ {doc|api|diff|report}
|
||
spend_today?: string
|
||
}
|
||
type DeliveryResult = {
|
||
summary: string
|
||
deliverables: Deliverable[] // kind ∈ {product-spec|code-diff|test-env|prod-env}
|
||
quality: QualityCheck[]
|
||
next_actions: Array<{ label: string; intent: string }>
|
||
}
|
||
type TaskAudit = {
|
||
usage: UsageRecord[] // 模型用量
|
||
resources: ResourceAccess[]
|
||
approvals: ApprovalRecord[]
|
||
security: SecurityRecord[]
|
||
}
|
||
```
|
||
|
||
完整定义见 [`cc-haha/desktop/src/stores/heicodeTaskStore.ts`](https://gitee.ath.cx:3000/chenchen/heicode-win/src/branch/main/cc-haha/desktop/src/stores/heicodeTaskStore.ts)。
|
||
|
||
### 7.7.4 反向请求 mcp-server 团队
|
||
|
||
1. 🟡 **Slice 8/9 的执行反馈 / 交付结果数据从哪里来?** 当前 §6 task 对象里没有 `execution` / `delivery` 字段。预期是:
|
||
- **运行时数据**(sub_steps / sk_tool_calls / artifacts)从 §5 Agnet stub 的 `events` + `metrics` + `deployments/{id}` 派生?还是 §6 task 对象将来扩展成 `task.execution = {...}`?
|
||
- **交付结果**(deliverables / quality)类似——§5 events 里捞,还是 task 字段直接带?
|
||
|
||
建议:**§6 task 扩展为这样**(前端只需要订阅一个对象):
|
||
|
||
```jsonc
|
||
{
|
||
"id": "...", "status": "running",
|
||
"thread": [...], "card": {...},
|
||
"execution": { // 新增(task.status ∈ running/awaiting_approval 时填)
|
||
"sub_steps": [...],
|
||
"sk_tool_calls": [...],
|
||
"events": [...], // 可截取最近 N 条
|
||
"artifacts": [...],
|
||
"spend_today": "¥12.30"
|
||
},
|
||
"delivery": { // 新增(task.status === completed 时填)
|
||
"summary": "...",
|
||
"deliverables": [...],
|
||
"quality": [...],
|
||
"next_actions": [...]
|
||
},
|
||
"audit": { // 新增(详情抽屉数据,可懒加载)
|
||
"usage": [...], "resources": [...],
|
||
"approvals": [...], "security": [...]
|
||
}
|
||
}
|
||
```
|
||
|
||
或者另起 5 个端点:`GET /api/user/tasks/{id}/execution` / `delivery` / `audit/usage` / `audit/resources` / `audit/approvals`。**两种方案我们都能接,请 mcp-server 团队拍板**。
|
||
|
||
2. 🟢 **高危审批 SSE 通道**(§7.5 旧条目,仍未答复)。建议 (A) SSE:`GET /api/user/approvals/stream`,事件字段对齐 [`cc-haha/desktop/src/stores/approvalStore.ts:ApprovalRequest`](https://gitee.ath.cx:3000/chenchen/heicode-win/src/branch/main/cc-haha/desktop/src/stores/approvalStore.ts)。
|
||
|
||
3. 🟢 **任务状态推送通道**:当任务从 `running` → `completed` / `awaiting_approval` 时,前端如何感知?
|
||
- 建议用第 2 项的 SSE 通道复用,或加 `GET /api/user/tasks/stream` SSE
|
||
- 短期可用轮询(`GET /api/user/tasks` 5-15s)兜底
|
||
|
||
### 7.7.5 关键 commit(2026-05-08 增量)
|
||
|
||
- `cc-haha` 仓库(chenchen/heicode-win main):
|
||
- Slice 8/9/10 + 第 3 个种子任务(completed 演示):本次 push(commit hash 待补)
|
||
- 新文件:`cc-haha/desktop/src/components/tasks/TaskRightPanels.tsx`
|
||
- 改动:`heicodeTaskStore.ts` / `pages/HeicodeTasksHome.tsx` / i18n locales
|
||
- 客户端 MSI 安装包(带新 logo + Slice 8/9/10 + Path A 真登录)已重打:62.85 MB · 2026-05-08 14:36
|
||
|
||
---
|
||
|
||
## 7.8 mcp-server 团队对 §7.7 的答复(2026-05-08)
|
||
|
||
> 回复人:mcp-server 后端团队
|
||
> 状态:本节是答复,**不是规范**
|
||
|
||
### 7.8.1 接受 §7.7.1 两个细节决策
|
||
|
||
| 细节 | Heicode 选 | mcp-server 落地 |
|
||
|---|---|---|
|
||
| ① `New-Api-User` 头映射 | (b) UUID 当外部 id | **mcp-server 调 NewAPI 时,用 `principal.user_id`(UUID 字符串)作为 `New-Api-User` 头**。等 Heicode 后端给 NewAPI 加 `users.external_id` 字段 + 反查逻辑后,自动生效。当前 P4 透传层用的"email→admin search"方案保留作为 fallback,等 NewAPI 加 `external_id` 后切换 |
|
||
| ② `billing_context.provider` | (a) User 表加字段 | **mcp-server 加 `users.billing_provider` 字段**(migration 027),默认 `litellm`。Heicode 后端做 `from-agnet` 同步时通过 mcp-server 接口设为 `newapi` |
|
||
|
||
**mcp-server 这边工作量**:
|
||
- migration 027 加字段:~1 小时
|
||
- heicode_client.py 切换 `New-Api-User` 用 UUID:~1 小时
|
||
- 让 Heicode 后端能写 `billing_provider`:再加一个 `PUT /api/auth/internal/billing-provider` 内部端点,需要服务令牌(不是用户 JWT):~2 小时
|
||
|
||
合计 **~半天**。
|
||
|
||
### 7.8.2 §7.7.4 第 1 项答复 — Slice 8/9/10 数据 schema
|
||
|
||
**选拆端点方案**(即 §7.7.4 的"另起 5 个端点"),不扩展 §6 task 主对象。
|
||
|
||
理由:
|
||
- task 主对象保持轻量 + 高频更新(thread 追加 / status 变化)
|
||
- execution / delivery / audit **生命周期不同**(execution 实时刷新、delivery 一次性生成、audit 累积),混进 task 会让 GET 响应肿大
|
||
- 拆开后前端可按 panel 切换懒加载,省带宽
|
||
- 后端聚合各自的源(execution 来自 Agnet stub events、audit 来自 audit_logs)也更清晰
|
||
|
||
**计划新增 3 个端点**(合并 audit 5 类为 1 个,前端 tab 切换即可):
|
||
|
||
| 端点 | 字段 | 数据源 | 触发更新 |
|
||
|---|---|---|---|
|
||
| `GET /api/user/tasks/{id}/execution` | `sub_steps[]` / `sk_tool_calls[]` / `events[]` / `artifacts[]` / `spend_today` | Agnet stub events + metrics 派生 | task.status ∈ {running, awaiting_approval} |
|
||
| `GET /api/user/tasks/{id}/delivery` | `summary` / `deliverables[]` / `quality[]` / `next_actions[]` | 任务编排器在 status=completed 时生成 | task.status == completed |
|
||
| `GET /api/user/tasks/{id}/audit?tab=usage\|resources\|approvals\|security` | 4 tab 各自数据 | audit_logs + 资源使用 + 审批 + 安全事件聚合 | 懒加载 |
|
||
|
||
**MVP 阶段**:3 个端点都返回 mock 数据(与 cc-haha seeded 数据格式一致),等真正的 deployment / approval 链路联通后切真。
|
||
|
||
工作量预估:~1.5-2 天(3 端点 + mock 数据 + 测试)。
|
||
|
||
### 7.8.3 §7.7.4 第 2-3 项答复 — 高危审批 SSE + 任务状态推送
|
||
|
||
**接受方案 A(SSE)**,且**合并成单一 SSE 通道**:
|
||
|
||
```
|
||
GET /api/user/events/stream
|
||
Accept: text/event-stream
|
||
Authorization: Bearer <accessToken>
|
||
```
|
||
|
||
事件类型(按 SSE `event:` 字段路由):
|
||
|
||
| event 类型 | 用途 | 字段对齐 |
|
||
|---|---|---|
|
||
| `approval.requested` | 高危审批弹窗(cc-haha ApprovalDialog) | `cc-haha/desktop/src/stores/approvalStore.ts:ApprovalRequest` |
|
||
| `approval.resolved` | 审批已被响应(其他设备已处理)| 同上 + `decision` 字段 |
|
||
| `task.status_changed` | 任务 running → completed/awaiting_approval/failed | `{task_id, old_status, new_status, at}` |
|
||
| `task.execution_progress` | sub_step 状态变化 | `{task_id, sub_step_id, status, at}` |
|
||
| `heartbeat` | 保活(每 25s)| `{}` |
|
||
|
||
合并成单通道的好处:
|
||
- 客户端只维护 1 个长连接(节省资源)
|
||
- 后端只管 1 个推送泵
|
||
- 不同事件类型互不冲突(按 SSE event name 区分)
|
||
|
||
**额外配套端点**:
|
||
- `GET /api/user/approvals` — 拉取当前未处理审批列表(启动时拉一次,之后靠 SSE 增量)
|
||
- `POST /api/user/approvals/{id}/decision` — 用户选择批准/拒绝/转人工
|
||
|
||
工作量预估:~2 天(SSE 实现 + Approval 模型 + 联调)。
|
||
|
||
### 7.8.4 落地排期(mcp-server 自己点单的)
|
||
|
||
按工作量从小到大、不阻塞 Heicode 排序:
|
||
|
||
| 顺序 | 任务 | 工作量 | 何时开 |
|
||
|---|---|---|---|
|
||
| 1 | §7.8.1 细节①② 落地(migration 027 + heicode_client 切换 + 内部 set provider 端点)| 半天 | **现在就能开** |
|
||
| 2 | §7.8.3 SSE 审批 + 状态推送(含 Approval 模型 + 4 个端点)| ~2 天 | 1 完成后 |
|
||
| 3 | §7.8.2 Slice 8/9/10 三个扩展端点(mock 数据)| ~1.5-2 天 | 2 完成后 |
|
||
| 4 | 等 B-1 token:rollout 配 token,P4 真跑 | 30 分钟 | 拿到 token |
|
||
|
||
**4 项做完后(约 1 周)mcp-server 端 Heicode 全主流程接口齐齐**。届时 cc-haha + heicode web + agent-manager 真接口落地后,mcp-server 改少量配置即可全联通。
|
||
|
||
### 7.8.5 上游回声 — 给 cc-haha 的小提醒
|
||
|
||
- 任务编排 §6 的 `option.id` 是稳定的(`mvp` / `polish` / `prod` / `modern_web` / `py_backend` / `let_heicode`),可以放心 hardcode 在 i18n 文案里
|
||
- §6 `card.manager_actions[].deeplink` 当前 `/manager/resources?from=task` / `/manager/team?from=task`,等 heicode web (`code.xinghanlab.com`) 接 P1 后,前端实际跳转目标可能换域名 — 建议做成 deeplink scheme 让 mcp-server 后续可调
|
||
- §5 Agnet stub 的 `Idempotency-Key` header 已实现,cc-haha 创建部署时建议传 UUID 避免重复
|
||
|
||
### 7.8.6 关键 commit(mcp-server 增量,2026-05-08)
|
||
|
||
| commit / image tag | 内容 |
|
||
|---|---|
|
||
| `mcp-server:heicode-p4-proxy-20260507` | P4 NewAPI 透传 4 端点 |
|
||
| `mcp-server:heicode-p5-stub-v2-20260508` | P5 Agnet stub 12 端点(含 max_tokens 误杀 fix) |
|
||
| `mcp-server:heicode-tasks-20260508` | 任务编排 5 端点(**当前生产**) |
|
||
| 待发:`mcp-server:heicode-7.8-impl-20260509` | §7.8 落地 |
|
||
|
||
镜像数字 digest 等部署后回填。
|
||
|
||
---
|
||
|
||
## 7.9 Heicode 团队对 §7.8 方案的确认(2026-05-08)
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧
|
||
> 范围:mcp-server §7.8 自报方案(拆端点 + 单 SSE 通道 + 内部 set provider 端点)的 ack
|
||
> 状态:本节是确认,**不是规范**
|
||
|
||
### 7.9.1 方案全部 ack,不阻塞
|
||
|
||
| §7.8 节 | 方案 | Heicode 这边的态度 |
|
||
|---|---|---|
|
||
| **7.8.1** 细节①② 落地(migration 027 + UUID `New-Api-User` + 内部 set-provider 端点)| 同意。无前端改动 | ✅ 直接开工 |
|
||
| **7.8.2** 拆 3 个端点(execution / delivery / audit),不扩 task 主对象 | 同意。理由完全 OK(生命周期不同 + 懒加载 + 数据源清晰)| ✅ cc-haha 已按拆端点字段形态 mock,对得上(见 §7.7.3 字段表)|
|
||
| **7.8.3** 单 SSE 通道 `GET /api/user/events/stream` + 5 类 event | 同意。建议这 5 个事件类型的 schema **冻结后写进 [Heicode-接口契约文档.md](./Heicode-接口契约文档.md) §7**,cc-haha 实装订阅时按文档字段对齐 | ✅ |
|
||
| **7.8.4** 1→2→3 串行 ~1 周 | 同意。cc-haha 这边 mock 已就绪,等 mcp-server 任意一段端点上线即可切真,不存在阻塞 | ✅ |
|
||
|
||
### 7.9.2 §7.8.5 三条提醒已落地(cc-haha 这边)
|
||
|
||
| 提醒 | 状态 | 落地点 |
|
||
|---|---|---|
|
||
| ① `option.id` 稳定,可放心 hardcode | ✅ 已在 cc-haha seed 数据里使用稳定 id(`mvp` / `polish` / `prod` / `modern_web` / `py_backend` / `let_heicode`)。i18n 文案 hardcode 重构推迟到从 mock 切真时再批量做 | `cc-haha/desktop/src/stores/heicodeTaskStore.ts:seedFollowups()` |
|
||
| ② `manager_actions[].deeplink` 域名可配置化 | ✅ 新增 `lib/managerLink.ts` 集中处理路径→URL 解析;任务卡 manager_actions 按钮、"去 Manager 准备"主按钮、Slice 9 deliverable primary/secondary 按钮均统一走 `openManagerLink(deeplink)`。后续 Manager 域名变更只需改 `MANAGER_BASE_URL` 一行 | `cc-haha/desktop/src/lib/managerLink.ts` 新建;`HeicodeTasksHome.tsx` + `components/tasks/TaskRightPanels.tsx` 调用 |
|
||
| ③ §5 Agnet stub `Idempotency-Key` 建议传 UUID | 🟡 已记录。当前 cc-haha 还未调 §5(任务驾驶舱仍是 mock 态),**Slice 11 mock→真切换时**会在 deployment 创建路径加 `Idempotency-Key: <crypto.randomUUID()>` 头 | 待办,写进 cc-haha 切真任务清单 |
|
||
|
||
### 7.9.3 给 mcp-server 团队的 1 个小请求
|
||
|
||
冻结 §7.8.3 SSE 5 类 event 的字段 schema 后,请同步到 [`Heicode-接口契约文档.md`](./Heicode-接口契约文档.md) 新增章节(建议 §7「Server-Sent Events」),尤其是:
|
||
|
||
- `approval.requested` — 字段对齐 `cc-haha/desktop/src/stores/approvalStore.ts:ApprovalRequest`(task_name / operation / target_resource / requesting_role / risk_level / impact_summary / heicode_suggestion / derives_short_lived_credential / ttl_minutes / enqueued_at)
|
||
- `approval.resolved` — 加 `decision: "approve" | "reject" | "expired"` + `resolved_at`
|
||
- `task.status_changed` — `{task_id, old_status, new_status, status_caption?, at}`
|
||
- `task.execution_progress` — `{task_id, sub_step_id, status, caption?, at}`
|
||
- `heartbeat` — 空 payload,建议带服务端时间 `{server_time}` 方便客户端时钟漂移检测
|
||
|
||
### 7.9.4 全主流程联调时间线(双方对齐版)
|
||
|
||
```
|
||
Day 0 (今天): B-1 token 已交付 ✅ + cc-haha Slice 8/9/10 mock 已完成 ✅ + mcp-server 4 个待开工事项排好
|
||
Day 0.5: mcp-server §7.8.1 完成(细节①② 落地) + B-1 rollout 配 token → P4 真跑可验证
|
||
Day 2.5: mcp-server §7.8.3 完成(SSE 通道 + Approval 模型)
|
||
Day 4.5: mcp-server §7.8.2 完成(execution / delivery / audit 3 端点)
|
||
Day 5: cc-haha 启动 Slice 11(mock → 真接口切换),1-2 天
|
||
Day 6-7: 全主流程端到端联调(登录 → 输入想法 → 追问 → 任务卡 → 去 Manager → 部署 Agnet → 执行反馈 → 审批 → 交付)
|
||
```
|
||
|
||
期间 agent-manager 团队(B-4)与 heicode web 团队(B-3)独立排期,不阻塞 mcp-server ↔ cc-haha 的联调。
|
||
|
||
---
|
||
|
||
## 7.10 Heicode 客户端 Slice 11(mock → §6 真接口)已上线(2026-05-08)
|
||
|
||
> 回复人:Heicode 客户端侧
|
||
> 范围:cc-haha 任务驾驶舱 / 工作台从 seed mock 切换到 mcp-server §6 任务编排真接口
|
||
|
||
### 7.10.1 实装内容
|
||
|
||
| 层 | 文件 | 改动 |
|
||
|---|---|---|
|
||
| **桌面 Bun server 代理** | `cc-haha/src/server/api/heicode-tasks.ts`(新建)| 5 个本地路由 `/api/heicode-tasks/{intent,list,:id,:id/answer,:id/messages}`,从当前 active provider 的 `mcpAuth.accessToken` 取 Bearer 头转发到 `<managerLoginUrl>/api/user/tasks/*`(默认 `apimtaiji.azure-api.net/api/mcp`)|
|
||
| **路由挂载** | `cc-haha/src/server/router.ts` | 加 `case 'heicode-tasks'` 分发 |
|
||
| **前端 typed client** | `cc-haha/desktop/src/lib/heicodeTasksApi.ts`(新建)| 5 个方法 `submitIntent` / `list` / `get` / `answer` / `appendMessage`,包成 `HeicodeTask` 强类型返回 |
|
||
| **Store 切真** | `cc-haha/desktop/src/stores/heicodeTaskStore.ts` | 新增 `loadTasks()` action(启动 hydrate)+ `mode: 'mock' \| 'live' \| 'loading' \| 'error'` 状态字段;`submitIntent` / `answerFollowup` / `appendMessage` 全部异步化,乐观更新 + 真接口同步 |
|
||
| **UI 状态指示** | `cc-haha/desktop/src/pages/HeicodeTasksHome.tsx` | 启动时 `useEffect(loadTasks)`;首页右下角加 `ModePill`,显示 `live · §6` / `mock` / `加载中` / `mock · 离线` |
|
||
|
||
### 7.10.2 行为契约
|
||
|
||
- **登录后启动**:首页 mount 自动 GET `/api/heicode-tasks/list?limit=50`;返回 ≥1 条用真数据替换 seed,否则保留 seed
|
||
- **乐观更新**:`submitIntent` / `answer` / `appendMessage` 即时改本地 state,再 await 真接口,**API 成功后用服务端响应覆盖**(拿到真 id + 真 followups + 真 card)
|
||
- **失败兜底**:API 报错(401 / 网络断 / 5xx)不清空本地 state,仅切 `mode = 'error'` + 把错误文案写进 `errorMessage`,UI 通过 `ModePill` 的 hover title 暴露详情
|
||
- **mock 任务保护**:本地优化插入的临时 task(id 以 `task-` 开头且 mode 非 live)不会触发 answer/messages 真接口,避免对不存在的 task id 反复 404
|
||
|
||
### 7.10.3 字段对齐验证
|
||
|
||
| §6 契约字段 | cc-haha `HeicodeTask` | 状态 |
|
||
|---|---|---|
|
||
| `id` / `name` / `status` / `status_caption` | 一致 | ✅ |
|
||
| `thread[]` (kind/text/at/followups) | 一致 | ✅ |
|
||
| `card.{goal,scope,generated_artifacts,manager_actions[]}` | 一致 | ✅ |
|
||
| `created_at` / `updated_at` | 一致 | ✅ |
|
||
| `user_id`(§6 返回顶层)| cc-haha 类型未声明,**忽略 ok**(前端不用)| 🟢 |
|
||
|
||
### 7.10.4 mcp-server 联调建议
|
||
|
||
cc-haha 客户端这边 Slice 11 已合并到 `chenchen/heicode-win` main 分支。重新出 MSI 后即可端到端验证。建议 mcp-server 团队配合:
|
||
|
||
1. 给个 staging / prod 区分的 base URL,让 cc-haha 切环境只改 provider preset
|
||
2. §6 `POST /api/user/tasks/intent` 当前返回 `status: 'configuring'` + 空 card,cc-haha 期望首屏立即看到追问选项(thread[1].followups),请确认 mcp-server 在 intent 提交时**首条 heicode 回复就携带 followups**(与 §6.1 契约示例一致)
|
||
3. 如果 §6 任务列表对新用户返回空,cc-haha 默认仍展示 seed mock(id `task-saas-001` / `task-feishu-002` / `task-portal-003`)—— 这些是演示数据,不会被认为是用户真实任务;如希望首次登录直接展示空态,告知后我们去掉 seed fallback
|
||
|
||
### 7.10.5 客户端**未阻塞**的后续 slice
|
||
|
||
| 后续 slice | 等的 mcp-server 端点 |
|
||
|---|---|
|
||
| Slice 12 — execution 面板切真 | §7.8.2 `GET /api/user/tasks/{id}/execution` 上线 |
|
||
| Slice 13 — delivery 面板切真 | §7.8.2 `GET /api/user/tasks/{id}/delivery` |
|
||
| Slice 14 — 任务详情抽屉切真 | §7.8.2 `GET /api/user/tasks/{id}/audit` |
|
||
| Slice 15 — 高危审批 + 任务状态 SSE 订阅 | §7.8.3 `GET /api/user/events/stream` |
|
||
|
||
每个 slice 都是 **拷贝 Slice 11 模板**:加一个 proxy 路由 + 一个 typed client method + 在对应 React 组件里 fetch(懒加载)+ 把 ModePill 切到 live。每个估 ~1-2 小时。等 mcp-server 7.8.x 镜像出来当天即可联调。
|
||
|
||
---
|
||
|
||
## 7.11 Heicode 对 mcp-server 「§7.8.x 下一步顺序?」的答复(2026-05-08)
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧
|
||
> 触发:mcp-server P4 真跑通后问 "继续 §7.9.4 串行做 §7.8.1,还是先把 SSE 5 类 event schema 写进契约文档(响应 §7.9.3 请求)?"
|
||
|
||
### 7.11.1 推荐顺序:先 §7.9.3(doc-only),再 §7.8.1 → .3 → .2
|
||
|
||
理由:
|
||
- **§7.9.3 是纯文档活**(把 5 个 event 字段 schema 写进 [`Heicode-接口契约文档.md`](./Heicode-接口契约文档.md) §7「Server-Sent Events」),估 30 分钟,**不消耗 mcp-server 工程时间**
|
||
- 文档落地后,cc-haha 这边可以**立即**搭 Slice 15 的 SSE 订阅骨架(按合同字段建 typed client + EventSource wrapper),等 §7.8.3 真接口上线当天即可联通
|
||
- §7.8.1(migration 027 + UUID `New-Api-User` + 内部 set-provider 端点)属于**基础设施**(其他 slice 不强依赖它,但它一旦换上后所有代用 email-search 的 fallback 路径就退役)—— 紧排在 §7.9.3 后做即可,**~半天**
|
||
- §7.8.3 SSE 通道(~2 天)+ §7.8.2 拆 3 端点(~2 天)按 §7.9.4 既定顺序串行
|
||
|
||
调整后的时间线:
|
||
|
||
| Day | mcp-server 端 | Heicode 客户端端(并行)|
|
||
|---|---|---|
|
||
| **0**(今天)| §7.9.3 doc 落地(30 min)| 等 doc → 起 Slice 15 SSE 订阅骨架(~1h)|
|
||
| **0.5** | §7.8.1 落地(migration + heicode_client 切 UUID + 内部端点)| 无影响(透明)|
|
||
| **1** | (continued) | Slice 12-14 骨架批量起(拷 Slice 11 模板,3 个端点 ~3h)|
|
||
| **2.5** | §7.8.3 SSE 通道完成 | Slice 15 切真(~30 min)|
|
||
| **4.5** | §7.8.2 拆 3 端点完成 | Slice 12/13/14 切真(~30 min × 3)|
|
||
| **5+** | rollout / 联调 | 全主流程 mock → live |
|
||
|
||
净结果:**1 周内 mcp-server ↔ cc-haha 全主流程接口齐**,agent-manager(B-4)和 heicode web(B-3)独立排期不影响。
|
||
|
||
### 7.11.2 关于 `/api/models` 透传 count=0 的观察
|
||
|
||
mcp-server 调的是 `/api/models`(路由 [`heicode/router/api-router.go:25`](../../工单相关/heicode/heicode/router/api-router.go#L25) → `controller.DashboardListModels`),返回 schema:
|
||
|
||
```go
|
||
// controller/model.go:248-252
|
||
c.JSON(200, gin.H{
|
||
"success": true,
|
||
"data": channelId2Models, // map[channelId]string[] —— 渠道维度,不是 user 维度
|
||
})
|
||
```
|
||
|
||
**关键点**:
|
||
- 这是**仪表盘视角**(channel admin 看自己渠道下哪些模型),key 是 channelId(UUID 字符串),value 是模型名数组
|
||
- mcp-server-service(user 26)`group=default`,没有任何 channel 关联,所以 `channelId2Models` 自然为空 / 不含它能用的模型 → mcp-server 看到 count=0 是正常的
|
||
- 这个端点不适合作 mcp-server P4「列出某个用户能看到的模型」的数据源
|
||
|
||
**正确的端点是这两个之一**(看 mcp-server 的语义需要):
|
||
|
||
| 端点 | 路由 | 返回 | 适用场景 |
|
||
|---|---|---|---|
|
||
| `GET /api/user/self/models` | [`api-router.go:82`](../../工单相关/heicode/heicode/router/api-router.go#L82) `selfRoute` | `string[]`(按当前 token 持有者的 group 过滤)| 想看「这个用户能用哪些模型」(以调用者身份)|
|
||
| `GET /api/user/{id}/models` | (admin 路径,需对应权限)| `string[]` | mcp-server 替任意用户查 |
|
||
|
||
mcp-server 端 P4 「列模型」如果是按当前调用用户视角,**应改调 `/api/user/self/models`**,配 `New-Api-User: <target_user_id>` 头切身份。如果 admin 想查别的用户的模型清单,调 `/api/user/<id>/models`。`/api/models` 不是 P4 该用的端点。
|
||
|
||
不阻塞主路径,按你当前 fallback 处理即可。等 §7.8.1 落地后顺手切到 `/api/user/{id}/models`(用 `users.external_id` 反查 heicode local id)。
|
||
|
||
### 7.11.3 给 cc-haha 自己的待办(已记入)
|
||
|
||
- ✅ Slice 11 (mock → §6 真接口) 完成(见 §7.10)
|
||
- 🟡 Slice 15 SSE 订阅骨架 —— 等 §7.9.3 contract doc 出来再起
|
||
- 🟡 Slice 12 / 13 / 14(execution / delivery / audit)骨架 —— 现在就可以起,字段已对齐 §7.8.2 mcp-server 自报方案
|
||
|
||
---
|
||
|
||
## 7.12 Heicode 客户端 Slice 12/13/14 骨架已就绪(2026-05-08)
|
||
|
||
> 回复人:Heicode 客户端侧
|
||
> 范围:拷 Slice 11 模板预先搭好 execution / delivery / audit 三个面板的真接口管线,等 mcp-server §7.8.2 上线当天即可零改动联通
|
||
|
||
### 7.12.1 实装内容
|
||
|
||
| 层 | 改动 |
|
||
|---|---|
|
||
| **代理路由** | `cc-haha/src/server/api/heicode-tasks.ts` 加 3 个 route:`GET /:id/execution` / `GET /:id/delivery` / `GET /:id/audit?tab=...`,全部转发到 `<mgrBase>/api/user/tasks/{id}/{path}` |
|
||
| **typed client** | `cc-haha/desktop/src/lib/heicodeTasksApi.ts` 加 3 个方法 `execution(id)` / `delivery(id)` / `audit(id, tab?)`,返回 `ExecutionState` / `DeliveryResult` / `TaskAudit` |
|
||
| **Store actions** | `cc-haha/desktop/src/stores/heicodeTaskStore.ts` 加 3 个 lazy-fetch action:`loadExecution(taskId)` / `loadDelivery(taskId)` / `loadAudit(taskId, tab?)` —— 每个把对应字段 patch 进 `task.execution` / `.delivery` / `.audit`,复用 mode/errorMessage 失败兜底 |
|
||
| **Lazy-load 触发** | `cc-haha/desktop/src/components/tasks/TaskRightPanels.tsx`:`ExecutionFeedbackPanel` / `DeliveryResultPanel` 在 `useEffect([task.id])` 上拉真数据;`TaskDetailDrawer` 在 `useEffect([open, task.id, tab])` 拉真数据(tab 切换重新拉,按 server 过滤减传输量)|
|
||
|
||
### 7.12.2 触发 gate(防止对 mock 数据无脑发请求)
|
||
|
||
`shouldFetchPanel(state, taskId)` 同时要求:
|
||
1. `state.mode === 'live'`(store 已经至少一次成功调通 §6 端点)
|
||
2. `taskId` **不**以 `task-` 开头(seed mock id 形如 `task-saas-001`,真接口返回的是 UUID)
|
||
|
||
任一不满足则跳过 fetch,保留本地 mock 数据原样展示。这意味着:
|
||
- 用户登录前 / 离线时点开 demo 任务,看到的是 seed mock,UI 不发任何请求
|
||
- 登录后真任务的面板首次渲染才发请求
|
||
|
||
### 7.12.3 字段对齐(与 mcp-server §7.8.2 自报方案 1:1)
|
||
|
||
| 端点 | 返回字段 | cc-haha 类型 |
|
||
|---|---|---|
|
||
| `GET /api/user/tasks/{id}/execution` | `sub_steps[]` / `sk_tool_calls[]` / `events[]` / `artifacts[]` / `spend_today` | `ExecutionState`([`heicodeTaskStore.ts`](https://gitee.ath.cx:3000/chenchen/heicode-win/src/branch/main/cc-haha/desktop/src/stores/heicodeTaskStore.ts))|
|
||
| `GET /api/user/tasks/{id}/delivery` | `summary` / `deliverables[]` / `quality[]` / `next_actions[]` | `DeliveryResult` |
|
||
| `GET /api/user/tasks/{id}/audit?tab=usage\|resources\|approvals\|security` | 4 tab 各自数据 | `TaskAudit` |
|
||
|
||
### 7.12.4 联调时切真路径(mcp-server §7.8.2 上线当天)
|
||
|
||
零代码改动,仅需 mcp-server 端 3 个端点对外可达 + 字段形态如 §7.12.3。
|
||
|
||
实测路径:
|
||
1. cc-haha 客户端登录后进入"小团队任务管理 SaaS"等真任务(id 为 UUID)
|
||
2. 右侧执行反馈面板 mount → 自动 GET `/api/heicode-tasks/<uuid>/execution` → 期望返回 `ExecutionState`
|
||
3. 顶栏「查看详情」打开 → 自动 GET `/api/heicode-tasks/<uuid>/audit?tab=usage` → 期望返回 `TaskAudit.usage`
|
||
4. 切到 resources/approvals/security tab → 重新发对应 query
|
||
|
||
如响应字段名 / 形态有偏差,按 §9 排障流程提交,附 `X-Request-Id`。
|
||
|
||
### 7.12.5 校验
|
||
|
||
- ✅ `bunx tsc -b --noEmit`(desktop)干净
|
||
- ✅ `bun build src/server/api/heicode-tasks.ts`(cc-haha 根)通过 (86 modules / 0.55 MB)
|
||
|
||
### 7.12.6 还差的最后一片:Slice 15 SSE 订阅
|
||
|
||
等 mcp-server **§7.9.3 SSE 5 类 event schema** 写进 [`Heicode-接口契约文档.md`](./Heicode-接口契约文档.md) 后即可起。约束已锁定到现有 `approvalStore.ts:ApprovalRequest` 字段,30 分钟内可上线骨架。
|
||
|
||
---
|
||
|
||
## 7.13 Heicode 对 mcp-server「两件事」请求的执行回执(2026-05-08,~18:30 本机时间)
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧(chenchen 方)
|
||
|
||
### 7.13.1 ✅ 新 NewAPI service token 已就位
|
||
|
||
旧 token 在 7.7.2.1 第二轮 rotate 时失效,mcp-server 那边 K8s secret 没同步导致 P4 透传 401。本轮重新 rotate:
|
||
|
||
| 步 | 状态 |
|
||
|---|---|
|
||
| `users.id=26` access_token SQL UPDATE 写新 32 字符 hex | ✅ |
|
||
| 新值通过 `Docs/heicode-svc-token.txt`(gitignored 验证 .gitignore:167)staged | ✅ |
|
||
| VM `/tmp/heicode-svc-token.txt` 临时副本删除 | ✅ |
|
||
|
||
mcp-server 团队从 `Docs/heicode-svc-token.txt` 读 → `kubectl create secret generic newapi-token --from-literal=HEICODE_NEWAPI_SERVICE_TOKEN=<value> --dry-run=client -o yaml | kubectl apply -f -` → `kubectl rollout restart deployment/mcp-server`,30 秒内 P4 透传 200 恢复。
|
||
|
||
读完后请:① 你方删除 `Docs/heicode-svc-token.txt`;② 我方收到你 ack 后从 DB 再 rotate 一次(与 §7.7.2.1 既有流程一致)。
|
||
|
||
### 7.13.2 ✅ Internal token 已注入 Heicode 后端 + Go 代码已上线
|
||
|
||
mcp-server 在 `Docs/heicode-internal-token.txt` 留的 32 字符 hex(前缀 `bd05cf16…`,gitignored 验证 .gitignore:168)已被消费。落地:
|
||
|
||
| 改动 | 位置 |
|
||
|---|---|
|
||
| 新增 `markBillingProviderNewapi(email)` helper | [`heicode/controller/heicode_agnet_session.go`](https://gitee.ath.cx:3000/chenchen/heicode-win/src/branch/main/heicode/controller/heicode_agnet_session.go)(commit `fc2c811`)|
|
||
| 调用挂在 `syncLocalUserFromAgnet` 末尾(goroutine fire-and-forget)| 同上 |
|
||
| 容器环境变量 `MCP_SERVER_INTERNAL_TOKEN` | VM `/home/heicode/heicode/heicode/.env` |
|
||
| 镜像重建 + 容器重启 | `docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml up -d --build heicode` |
|
||
| 健康检查 | `Up About a minute (healthy)` + `/api/status` HTTP 200 |
|
||
| 镜像清理 | `docker image prune -f` 已跑(0 dangling)|
|
||
|
||
**调用约定**:
|
||
- 每次 Heicode Manager `/api/user/session/from-agnet` JIT 同步用户(首次或重复登录)后触发
|
||
- HTTP method `PUT`,URL `https://apimtaiji.azure-api.net/api/mcp/api/auth/internal/billing-provider`,header `Authorization: Bearer <MCP_SERVER_INTERNAL_TOKEN>`,body `{"email": "...", "billing_provider": "newapi"}`
|
||
- goroutine 调用,**任何错误都仅 SysLog 不阻塞登录**
|
||
- mcp-server 那边内部端点应**幂等**——同一 email 重复 set 不出错
|
||
|
||
mcp-server 团队可以独立测:拿任意 email(比如 `55@55.com`)按上述 PUT 直接打到自己的内部端点验证。
|
||
|
||
本地 `Docs/heicode-internal-token.txt` 副本已删除(值已固化在 VM env)。
|
||
|
||
### 7.13.3 状态
|
||
|
||
- 你方 P4 透传可恢复(拿新 NewAPI token 后)
|
||
- 你方 §7.8.1 内部 set-provider 端点已有真实下游调用方(Heicode 后端),可以做端到端联调
|
||
- 你方继续 §7.8.3 SSE 通道 / §7.8.2 拆 3 端点不阻塞
|
||
|
||
加油 🚀
|
||
|
||
---
|
||
|
||
## 7.14 mcp-server §7.8.3 + §7.8.2 全部上线(2026-05-08)
|
||
|
||
> 回复人:mcp-server 后端团队
|
||
|
||
### 7.14.1 ✅ §7.8.3 SSE 单通道 + Approval 模型上线
|
||
|
||
| 项 | 状态 |
|
||
|---|---|
|
||
| migration 028 `heicode_approvals` 表(含 `created_at`/`updated_at`) | ✅ 已应用 |
|
||
| `models.HeicodeApproval` ORM | ✅ |
|
||
| `app/event_bus.py` 进程内 pub/sub(per-user `asyncio.Queue`,maxsize=256) | ✅ |
|
||
| `GET /api/user/events/stream` SSE(25s heartbeat) | ✅ |
|
||
| `GET /api/user/approvals` 待处理列表 + lazy expire | ✅ |
|
||
| `POST /api/user/approvals/{id}/decision` (approve / reject) | ✅ |
|
||
| `POST /api/auth/internal/approvals` (service-token 鉴权,创建 + 广播 approval.requested) | ✅ |
|
||
| 修复 `_is_expired()` offset-naive vs aware 比较 bug | ✅ |
|
||
| 联调 smoke:12/12 全过 | ✅ 见 §7.14.3 |
|
||
|
||
**镜像**:`taiji.azurecr.io/mcp-server:heicode-7.8.3-sse-v2-20260508`
|
||
|
||
### 7.14.2 ✅ §7.8.2 三个任务扩展端点上线
|
||
|
||
按 §7.8.2 自报方案,**不扩 task 主对象**,而是开 3 个独立端点(懒加载 / 数据源各异):
|
||
|
||
| 端点 | 数据形态 | 数据源 | 生命周期 |
|
||
|---|---|---|---|
|
||
| `GET /api/user/tasks/{id}/execution` | `ExecutionState`(sub_steps/sk_tool_calls/events/artifacts/spend_today)| 当前 deterministic mock,5 sub_step 按 task.status 自动切 done/running/waiting | task.status ∈ {running, awaiting_approval, completed} 才填 |
|
||
| `GET /api/user/tasks/{id}/delivery` | `DeliveryResult`(summary/deliverables/quality/next_actions)| 当前 deterministic mock,4 deliverable + 4 quality + 3 next_action | 仅 task.status == completed 时填 |
|
||
| `GET /api/user/tasks/{id}/audit?tab=usage\|resources\|approvals\|security` | `TaskAudit` 4 tab | **approvals 真表查 heicode_approvals**;其他 3 tab deterministic mock | 懒加载,传 tab 只填该 tab |
|
||
|
||
**字段形态严格对齐 cc-haha `heicodeTaskStore.ts:ExecutionState/DeliveryResult/TaskAudit`**——cc-haha 现有 mock 数据可零改动切真。
|
||
|
||
错误码:
|
||
- 400 `INVALID_TAB`(audit)/ `TASK_STATE_INVALID`
|
||
- 404 `NOT_FOUND` / 403 `FORBIDDEN_SCOPE` / 401
|
||
|
||
**镜像**:`taiji.azurecr.io/mcp-server:heicode-7.8.2-tasks-ext-20260508`
|
||
|
||
**联调 smoke**:13/13 全过(含 keys 完整性 / sub_step 状态分布 / 跨用户 403 / 完成态 deliverables=4 / 非完成态 deliverables=0 / tab 过滤 / INVALID_TAB / NOT_FOUND / 401)
|
||
|
||
### 7.14.3 SSE smoke 详情
|
||
|
||
```
|
||
✓ internal POST /approvals
|
||
✓ SSE 收到 approval.requested
|
||
✓ GET /approvals total >= 1
|
||
✓ invalid decision -> 400
|
||
✓ NOT_FOUND -> 404
|
||
✓ internal no-token -> 401
|
||
✓ internal wrong-token -> 403
|
||
✓ decide approve
|
||
✓ SSE 收到 approval.resolved
|
||
✓ duplicate decide -> 409
|
||
✓ SSE heartbeat
|
||
✓ /api/auth/me 回归
|
||
```
|
||
|
||
### 7.14.4 接口文档同步
|
||
|
||
`Docs/Heicode-接口契约文档.md` 已更新到 v2.2:
|
||
- §7(SSE)写在 v2.1 增量
|
||
- §6.6 / §6.7 / §6.8(execution / delivery / audit)写在 v2.2 增量
|
||
- 接口总数 13 → 34 → 38 → **41**
|
||
|
||
### 7.14.5 反向请求 — Heicode 团队侧的下一步
|
||
|
||
请 cc-haha:
|
||
1. **Slice 12(execution 切真)**:`heicodeTasksApi.ts` 加 `execution(id)` → 调 `GET /api/user/tasks/{id}/execution`,store action `loadExecution(taskId)` 把响应 patch 进 `task.execution`。预计 ~30 min(按 §7.12.2 模板)。
|
||
2. **Slice 13(delivery 切真)**:同上,`delivery(id)` + `loadDelivery(taskId)`。
|
||
3. **Slice 14(audit 抽屉切真)**:`audit(id, tab?)` + `loadAudit(taskId, tab?)`,按 tab 懒加载。
|
||
4. **Slice 11+ SSE 客户端**:可参考契约文档 §7.9 实现,订阅 `approval.requested` / `approval.resolved` / `task.status_changed` / `task.execution_progress`。
|
||
|
||
### 7.14.6 mcp-server 自己的 next(按 §7.11.1 时间线)
|
||
|
||
- ⏳ Day 4.5+ — 等 cc-haha Slice 12/13/14 联调,按反馈优化 mock 数据
|
||
- ⏳ 后续可把 `/execution` 的数据源接到 Agnet stub events / metrics 派生(无前端改动)
|
||
- ⏳ 后续可把 `/audit` 的 usage 接到 NewAPI logs(需要 NewAPI service token 落地)
|
||
|
||
|
||
---
|
||
|
||
## 7.15 Heicode 对 §7.14 的回执(2026-05-08,~21:00)
|
||
|
||
> 回复人:Heicode 客户端 / Manager 侧(chenchen 方)
|
||
|
||
### 7.15.1 ✅ §7.14.5 第 1-3 条(Slice 12/13/14 切真)**早已完成**,请刷新理解
|
||
|
||
mcp-server 团队列出的"请 cc-haha 做"清单 1-3 项实际**已经在 commit `15ac001` (`feat(client): slices 8-14 — exec/delivery/audit panels + §6 task orchestration wiring`,今天下午)落地**,详情见 §7.12(`Heicode 客户端 Slice 12/13/14 骨架已就绪`)。当前仓库 `chenchen/heicode-win/main` 的状态:
|
||
|
||
| §7.14.5 项 | 文件 / 函数 | 状态 |
|
||
|---|---|---|
|
||
| 1. Slice 12 execution 切真 | `cc-haha/desktop/src/lib/heicodeTasksApi.ts` `execution(id)` + `cc-haha/desktop/src/stores/heicodeTaskStore.ts` `loadExecution(taskId)` + `TaskRightPanels.tsx:ExecutionFeedbackPanel` `useEffect → loadExecution` | ✅ 已合 |
|
||
| 2. Slice 13 delivery 切真 | 同上 `delivery(id)` / `loadDelivery(taskId)` / `DeliveryResultPanel useEffect` | ✅ 已合 |
|
||
| 3. Slice 14 audit 抽屉切真 | `audit(id, tab?)` / `loadAudit(taskId, tab?)` / `TaskDetailDrawer useEffect([open, task.id, tab])` 按 tab 重新拉 | ✅ 已合 |
|
||
|
||
**触发 gate**:`shouldFetchPanel` 函数同时要求 `mode === 'live'`(store 至少调通过一次 §6)+ `taskId` 不以 `task-` 开头(避 mock seed)。所以 mcp-server §7.8.2 三端点上线后,**只要 cc-haha 在登录态下打开 UUID 任务,三块 panel 就自动从真接口拉数据**——零代码改动,零部署。
|
||
|
||
**等待联调实测**:用户装新 MSI(已部署 `c09e6b6c…` → 现升级为 `903ec8a6…` 含一键登录) + 一键登录 + 通过 `POST /api/user/tasks/intent` 创个真任务 + 进任务 → 看 ModePill 是否变 `live · §6`、看右侧 panel 数据是否来自真接口。如有偏差按 §9 排障流程提交 X-Request-Id。
|
||
|
||
### 7.15.2 🟡 §7.14.5 第 4 条(Slice 15 SSE)**正在起骨架**
|
||
|
||
按 §7.14.1 上线的 SSE 单通道(`GET /api/user/events/stream`,4 个 event 类型 + heartbeat)我方现在起客户端订阅骨架:
|
||
|
||
| 模块 | 计划 |
|
||
|---|---|
|
||
| `cc-haha/src/server/api/heicode-tasks.ts`(已有) | 加一条 SSE 转发路由 `GET /api/heicode-tasks/events/stream`,把 `Authorization: Bearer <accessToken>` 注入后透传 mcp-server 的 SSE,**保持长连接**(`fetch` 流式 → Bun `Response` ReadableStream)|
|
||
| `cc-haha/desktop/src/lib/heicodeEventsClient.ts`(新建)| EventSource wrapper:自动重连、heartbeat 监听、按 event name 路由到 callback |
|
||
| `cc-haha/desktop/src/stores/approvalStore.ts`(已存在)| 监听 `approval.requested` → `enqueue`;`approval.resolved` → 更新对应 request 状态 |
|
||
| `cc-haha/desktop/src/stores/heicodeTaskStore.ts`(已存在)| 监听 `task.status_changed` → patch 对应 task 的 status;`task.execution_progress` → patch sub_step 状态 |
|
||
| `cc-haha/desktop/src/main.tsx` | 启动 hooks:登录后启 SSE 订阅,登出后断开 |
|
||
|
||
预计 ~2 小时上线。完成后客户端的高危审批弹窗 + 任务驾驶舱状态都会**实时**收 mcp-server 推送,不再依赖轮询。
|
||
|
||
### 7.15.3 关于「要不要 commit 这 2 份 md」
|
||
|
||
**强烈建议你方 commit + push**:
|
||
- 这 2 份 md 是 mcp-server / agent-manager / Heicode 三方对齐的 SoT 看板,不进 git 等于私聊
|
||
- 不含敏感凭证(token 走 `Docs/heicode-svc-token.txt` 已 .gitignore:167 排除;internal token 走 `.gitignore:168`)
|
||
- 让契约演进 v2.0 → v2.2 + 进度 §7.0 → §7.15 在 git 历史里可追溯
|
||
- agent-manager 团队后续接手时直接拉就有完整上下文
|
||
|
||
我这边没有 `taijibaga/taiji-AI-PAD.git` 的 push 权限,请你方直接:
|
||
|
||
```bash
|
||
cd /path/to/taiji-AI-PAD
|
||
git add Docs/Heicode-对接进度与待办.md Docs/Heicode-接口契约文档.md Docs/Heicode-完整调用流程图.md
|
||
git commit -m "docs(heicode): v2.2 contract + progress §7.0 → §7.15"
|
||
git push
|
||
```
|
||
|
||
### 7.15.4 NewAPI service token rollout(B-1 round 3)
|
||
|
||
token 已 staged 在 `Docs/heicode-svc-token.txt`(gitignored),32 字符 hex。等你方 `kubectl create secret ... | apply` 覆盖 + `rollout restart`,P4 透传立刻恢复 200。完成后跟我们 ack,我会 rotate 一次关闭通道(按 §7.7.2.1 协议)。
|
||
|
||
---
|