Files
taiji-AI-PAD/Docs/Heicode-接口契约文档.md
T
chenchenandClaude Opus 4.7 610fde5d03 feat(mcp-server): Heicode integration + register transaction hardening
== 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>
2026-05-12 15:43:10 +08:00

49 KiB
Raw Blame History

Heicode ↔ mcp-server 接口契约文档

版本: v2.2 生效日期: 2026-05-08 状态: 已上线生产,可直接对接 当前镜像: taiji.azurecr.io/mcp-server:heicode-7.8.2-tasks-ext-20260508

本文档列出 Heicode 客户端可调用的全部 mcp-server 接口、入参与出参。 所有接口已在生产环境通过端到端测试。

v2.2 修订(2026-05-08,本次):

  • 新增 §6.6 / §6.7 / §6.8(execution / delivery / audit)— Slice 8/9/10 配套,3 端点全过 13/13 smoke
  • 接口总数:38 → 41

v2.1 修订(2026-05-08):

  • 新增 §7 Server-Sent Events(5 类 event + 配套 REST)— §7.8.3 SSE 单通道全过 12/12 smoke
  • 接口总数:34 → 38

v2.0 修订(2026-05-08):

  • 新增 §4 NewAPI 元数据透传(4 接口)
  • 新增 §5 Agnet 平台本地 stub(12 接口,mock 数据,前端可立即联调)
  • 新增 §6 任务编排(5 接口,cc-haha 任务驾驶舱 / 工作台 配套)
  • 接口总数:13 → 34

📍 调用关系全景见 Heicode-完整调用流程图.md。 📍 进度与待办见 Heicode-对接进度与待办.md。


0. 接入信息

Base URL

https://apimtaiji.azure-api.net/api/mcp

完整路径示例:

POST https://apimtaiji.azure-api.net/api/mcp/api/auth/login
GET  https://apimtaiji.azure-api.net/api/mcp/api/resources

⚠️ 重要:登录接口被两类调用方共用

经过代码核实(2026-05-05),mcp-server 的登录接口实际被以下两个调用方依赖:

调用方 调用方式 关键依赖字段
heicode 前端 (web/default/src/features/auth/api.ts) 浏览器跨域,Authorization: Bearer data.token, data.refreshToken, data.user.{id,name,email,role,channelId}
heicode 后端 (controller/heicode_agnet_session.go) 服务端调 /me /refresh,验证前端给的 token data.{id,email,name,role,channelId,status}

字段形态任何变更都会破坏对接。增加字段安全;删/改字段名/字段类型 = breaking change。

通用请求头

Header 必填 说明
Content-Type: application/json POST/PUT 时是 请求体 JSON 格式
Authorization: Bearer <accessToken> 受保护接口必填 JWT access token
X-Request-Id: <uuid> 建议 客户端生成,便于排障反查日志

通用响应封装

成功:

{
  "success": true,
  "data": { ... }
}

部分接口含 message:

{
  "success": true,
  "data": { ... },
  "message": "操作成功"
}

失败(FastAPI 默认):

{
  "detail": "邮箱或密码错误"
}

失败(结构化错误):

{
  "detail": {
    "code": "RESOURCE_GRANT_INVALID",
    "message": "allowed_actions 超出对应 binding.permission_scope: ['repo:admin']"
  }
}

Token 模型

Token TTL 用途
Access Token 24 小时 调业务接口(含 /me、/logout)
Refresh Token 7 天 仅用于 /refresh 换新 access

JWT claims:sub(user_id)、email、role、channelId、type(access/refresh)、iat、exp。

Role 字段值与 heicode 前端解析

mcp-server 现有 role 取值(按用户类型):user, channel_admin, billing_admin, operations_admin, admin, super_admin, provider_admin。

heicode 前端 (api.ts:259-261) 硬编码解析为 3 档:

mcp-server role 值 heicode 前端解析 数值
root root 100
admin admin 10
user user 1
其他(channel_admin, super_admin, provider_admin 等) 默认 user 1

对 Heicode 客户端的实际影响:

  • Heicode 客户端预期登录的角色 = user,前端解析为 1 ✓
  • 高权限角色(admin/root)由 heicode 后端独立白名单 (HEICODE_ROOT_EMAILS / HEICODE_ADMIN_EMAILS 环境变量) 决定,不信任 mcp-server 返回的 role 字段
  • mcp-server 这边无需调整 role 取值,保持现有取值即可

CORS 当前状态

mcp-server 生产环境 CORS_ORIGINS 未显式配置 → fallback 到 ["*"]。代码同时设置 allow_credentials=True。

调用方式 当前是否能用
Authorization: Bearer <token> ✅ 能用(heicode 前端走这条)
浏览器 cookie + credentials ❌ 浏览器规范禁止 * + credentials 同用

Heicode 前端用 Bearer,不受影响。如需后续硬化(去掉 *),需 heicode 团队提供前端实际部署域名清单。


1. 登录认证(4 接口)

1.1 POST /api/auth/login

用途: 账号密码登录,换取 token 对。

请求

POST /api/auth/login
Content-Type: application/json
{
  "email": "user@example.com",
  "password": "YourPassword123",
  "role": "user"
}
字段 类型 必填 说明
email string 是 用户邮箱
password string 是 密码
role string 是 Heicode 客户端固定传 "user"

成功响应 200

{
  "success": true,
  "data": {
    "token": "eyJhbGc...",
    "refreshToken": "eyJhbGc...",
    "user": {
      "id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
      "name": "张三",
      "email": "user@example.com",
      "role": "user",
      "channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6"
    }
  }
}

错误响应

HTTP 含义
401 邮箱或密码错误
403 账户已被禁用 / 权限不足
422 请求体 Pydantic 校验失败(邮箱格式不合法等)
429 登录尝试过于频繁;响应头含 Retry-After: 60

限流: 每 IP 每 60 秒最多 5 次(不区分成功失败)。


1.2 GET /api/auth/me

用途: 校验 access token 有效性,返回当前用户资料。

⚠️ 高频调用 + 双调用方依赖:

  • heicode 前端:客户端启动 + token 续期后立即调一次
  • heicode 后端:每次走 from-agnet 流程时调一次(即每次"建立 Manager 会话")
  • 字段形态被 hardcode 解析(id/email/name/role/channelId/status),绝不能改
  • 性能敏感:响应时间影响登录用户体验

请求

GET /api/auth/me
Authorization: Bearer <accessToken>

成功响应 200

{
  "success": true,
  "data": {
    "id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "email": "user@example.com",
    "name": "张三",
    "role": "user",
    "channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6",
    "status": "active",
    "subscriptionTier": "free",
    "lastLoginAt": "2026-05-05T06:01:23.456789"
  }
}

错误响应

HTTP 含义
401 token 无效 / 过期 / 已登出 / 用户不存在
403 账户已被禁用

1.3 POST /api/auth/refresh

用途: 用 refresh token 换取新的 access + refresh token 对。

请求

POST /api/auth/refresh
Authorization: Bearer <refreshToken>

⚠️ 必须传 refresh token,传 access token 会被拒绝。

成功响应 200

{
  "success": true,
  "data": {
    "token": "eyJhbGc...",
    "refreshToken": "eyJhbGc..."
  }
}

客户端收到新 token 对后应替换本地缓存(旧的也作废)。

错误响应

HTTP 含义
401 refresh token 无效 / 过期 / 错传了 access token(必须使用 refresh token 调用此接口)

1.4 POST /api/auth/logout

用途: 登出,把当前 access token 加入黑名单。

请求

POST /api/auth/logout
Authorization: Bearer <accessToken>

成功响应 200

{
  "success": true,
  "data": null,
  "message": "登出成功"
}

说明: 容错性强,token 黑名单写入失败也会返回 200。客户端总是清理本地 token + 跳登录页。

⚠️ 登出双调用约定:heicode 前端登出时会同时调用:

  1. GET /api/user/logout(heicode 后端,清 heicode session cookie)
  2. POST /api/auth/logout(mcp-server,本接口;token 加黑名单)

两次调用都做容错处理(不阻断登出体验)。前端最后总是清 localStorage 跳登录页。


2. 资源绑定 ResourceBinding(5 接口)

2.0 公共说明

对象语义: 用户绑定到 Heicode 的外部资源(Git 仓库 / SK / 项目文档 / 云账号 / 云资源)。

安全红线:

  • DB 只保存元数据 + secret_ref,不保存明文密钥
  • metadata / constraints / permission_scope 中不得出现 key 包含以下关键词的字段(不区分大小写):
    password, token, secret, private_key, access_key, credential
    
    违反返回 422 RESOURCE_GRANT_SECRET_REJECTED
  • 例外:key 名为 secret_ref 视为引用(如 vault://...),允许通过

枚举值:

字段 允许值
type git / sk / project_doc / cloud_account / cloud_resource
status pending / active / disabled / revoked

2.1 POST /api/resources

用途: 创建资源绑定。

请求

POST /api/resources
Authorization: Bearer <accessToken>
Content-Type: application/json
{
  "type": "git",
  "name": "heicode-main-repo",
  "external_ref": "https://example.com/org/heicode.git",
  "metadata": {
    "provider": "gitee",
    "default_branch": "main"
  },
  "permission_scope": ["repo:read", "repo:write:current-branch"],
  "constraints": {
    "ref": "main",
    "allowed_paths": "services/**,docs/**"
  },
  "secret_ref": "vault://secret/users/{user_id}/bindings/heicode-main-repo",
  "status": "active"
}
字段 类型 必填 说明
type string (enum) 是 资源类型,见 §2.0
name string (≤255) 是 用户可见名称
external_ref string 否 外部资源定位(repo URL、subscription ID 等)
metadata object 否,默认 {} 元数据;不得含敏感 key
permission_scope string[] 否,默认 [] 该资源允许的最大动作集合
constraints object 否,默认 {} 路径/分支/网络等限制
secret_ref string (≤500) 否 凭证引用(vault://...),不是密钥本身
status string (enum) 否,默认 pending 见 §2.0

成功响应 200

{
  "success": true,
  "data": {
    "id": "88963d56-5a95-4863-8a0b-91a83e456028",
    "user_id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "type": "git",
    "name": "heicode-main-repo",
    "external_ref": "https://example.com/org/heicode.git",
    "metadata": { "provider": "gitee", "default_branch": "main" },
    "permission_scope": ["repo:read", "repo:write:current-branch"],
    "constraints": { "ref": "main", "allowed_paths": "services/**,docs/**" },
    "secret_ref": "vault://secret/users/.../bindings/heicode-main-repo",
    "status": "active",
    "created_by": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "updated_by": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "created_at": "2026-05-05T06:10:00.123456",
    "updated_at": "2026-05-05T06:10:00.123456"
  }
}

错误响应

HTTP code 含义
401 — 未登录
422 — type/status 枚举不合法
422 RESOURCE_GRANT_SECRET_REJECTED metadata/constraints/permission_scope 含敏感字段

2.2 GET /api/resources

用途: 列出当前登录用户的资源绑定。

请求

GET /api/resources?type=git&status=active&limit=100&offset=0
Authorization: Bearer <accessToken>
Query 类型 默认 说明
type string — 按类型过滤
status string — 按状态过滤
limit int (1-500) 100 返回上限
offset int (≥0) 0 偏移

成功响应 200

{
  "success": true,
  "data": {
    "items": [
      { "id": "...", "type": "git", "name": "...", ... }
    ],
    "total": 1,
    "offset": 0,
    "limit": 100
  }
}

items 元素结构同 §2.1 的成功响应 data 字段。


2.3 GET /api/resources/{binding_id}

用途: 获取单个资源绑定详情。

请求

GET /api/resources/88963d56-5a95-4863-8a0b-91a83e456028
Authorization: Bearer <accessToken>

成功响应 200: 同 §2.1 的 data 字段。

错误响应

HTTP 含义
400 binding_id 不是有效 UUID
401 未登录
403 该资源不属于当前用户
404 资源不存在

2.4 PUT /api/resources/{binding_id}

用途: 更新资源绑定(部分字段)。

请求

PUT /api/resources/88963d56-5a95-4863-8a0b-91a83e456028
Authorization: Bearer <accessToken>
Content-Type: application/json
{
  "name": "heicode-main-repo-renamed",
  "permission_scope": ["repo:read"],
  "status": "active"
}

可更新字段(全部可选):name / external_ref / metadata / permission_scope / constraints / secret_ref / status。

未传的字段保持原值。

成功响应 200: 同 §2.1(含更新后字段)。

错误响应: 同 §2.3 + §2.1 的 422。


2.5 DELETE /api/resources/{binding_id}

用途: 软删除资源绑定(设 status=revoked,保留历史)。

请求

DELETE /api/resources/88963d56-5a95-4863-8a0b-91a83e456028
Authorization: Bearer <accessToken>

成功响应 200

{
  "success": true,
  "data": {
    "id": "88963d56-5a95-4863-8a0b-91a83e456028",
    "status": "revoked"
  }
}

说明: 软删除后 GET /api/resources/{id} 仍可读到(status=revoked)。基于该 binding 已存在的 grant 不会自动撤销 — 业务层自行判断或调 DELETE /api/resource-grants/{id}。


3. 资源授权 ResourceGrant(4 接口)

3.0 公共说明

对象语义: 把某个 ResourceBinding 授给某个角色 / 子 Agent 使用。

核心约束:

  • allowed_actions 必须是对应 binding 的 permission_scope 的子集
    • 违反 → 400 RESOURCE_GRANT_INVALID
  • constraints 不得放宽对应 binding 的 constraints(应用层校验)
  • 仅能基于自己的 binding 创建 grant
  • 同一类敏感字段拒绝规则适用于 constraints / allowed_actions

枚举值:

字段 允许值
status active / suspended / revoked / expired
role(建议值) product / frontend / backend / reviewer / ops / 自定义字符串

3.1 POST /api/resource-grants

用途: 创建资源授权。

请求

POST /api/resource-grants
Authorization: Bearer <accessToken>
Content-Type: application/json
{
  "resource_id": "88963d56-5a95-4863-8a0b-91a83e456028",
  "binding_scope": "main",
  "role": "backend",
  "agent_id": null,
  "allowed_actions": ["repo:read"],
  "constraints": {
    "ref": "main",
    "allowed_paths": "services/api/**"
  },
  "expires_at": "2026-06-05T00:00:00",
  "status": "active"
}
字段 类型 必填 说明
resource_id string (UUID) 是 对应 ResourceBinding ID
binding_scope string (≤255) 是 repo/ref/path 或云资源引用
role string 否 子 Agent 角色
agent_id string (UUID) 否 子 Agent ID;空表示授下次该角色部署
allowed_actions string[] 否 必须是 binding.permission_scope 的子集
constraints object 否 限制条件
expires_at string (ISO 8601) 否 过期时间;高危资源建议必填
status string (enum) 否,默认 active 见 §3.0

成功响应 200

{
  "success": true,
  "data": {
    "id": "1e8d7a4d-3a2c-4d5e-9b1f-12c3d4e5f6a7",
    "user_id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "binding_scope": "main",
    "resource_id": "88963d56-5a95-4863-8a0b-91a83e456028",
    "role": "backend",
    "agent_id": null,
    "allowed_actions": ["repo:read"],
    "constraints": { "ref": "main", "allowed_paths": "services/api/**" },
    "status": "active",
    "expires_at": "2026-06-05T00:00:00",
    "created_by": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
    "revoked_by": null,
    "created_at": "2026-05-05T06:15:00.123456",
    "revoked_at": null
  }
}

错误响应

HTTP code 含义
400 — resource_id / agent_id 非合法 UUID
400 RESOURCE_GRANT_INVALID binding 状态不允许新建授权(如 disabled/revoked),或 allowed_actions 超出 binding.permission_scope
401 — 未登录
403 FORBIDDEN_SCOPE 不能基于他人的 binding 创建授权
404 NOT_FOUND 对应 binding 不存在
422 — status 枚举不合法
422 RESOURCE_GRANT_SECRET_REJECTED constraints/allowed_actions 含敏感字段

3.2 GET /api/resource-grants

用途: 列出当前用户的资源授权。

请求

GET /api/resource-grants?resource_id=...&role=backend&binding_scope=main&status=active&limit=100&offset=0
Authorization: Bearer <accessToken>
Query 类型 默认 说明
resource_id string (UUID) — 按 binding 过滤
role string — 按角色过滤
binding_scope string — 按作用域过滤
status string — 按状态过滤
limit int (1-500) 100 返回上限
offset int (≥0) 0 偏移

成功响应 200

{
  "success": true,
  "data": {
    "items": [ { "id": "...", ... } ],
    "total": 1,
    "offset": 0,
    "limit": 100
  }
}

3.3 GET /api/resource-grants/{grant_id}

用途: 获取单个授权详情。

请求

GET /api/resource-grants/1e8d7a4d-3a2c-4d5e-9b1f-12c3d4e5f6a7
Authorization: Bearer <accessToken>

成功响应 200: 同 §3.1 的 data 字段。

错误响应:

HTTP code 含义
400 — grant_id 非合法 UUID
401 — 未登录
403 FORBIDDEN_SCOPE 不属于当前用户
404 NOT_FOUND 授权不存在

3.4 DELETE /api/resource-grants/{grant_id}

用途: 撤销授权(软删除:status=revoked + revoked_at + revoked_by)。幂等:重复撤销返回 200。

请求

DELETE /api/resource-grants/1e8d7a4d-3a2c-4d5e-9b1f-12c3d4e5f6a7
Authorization: Bearer <accessToken>

成功响应 200: 同 §3.1 的 data 字段(含 revoked_at / revoked_by)。

错误响应: 同 §3.3。


4. 完整使用流程示例

4.1 客户端启动

1. 读取本地缓存的 access token
2. GET /api/auth/me
   - 200 → 进入主界面,刷新本地用户资料
   - 401 → 看是否有 refresh token
            ├─ 有 → POST /api/auth/refresh
            │       ├─ 200 → 替换 token 对,重试 /me
            │       └─ 401 → 清理本地 token,跳登录页
            └─ 无 → 跳登录页

4.2 用户登录

POST /api/auth/login {email, password, role: "user"}
 ├─ 200 → 存 token 对 + user 资料,进主界面
 ├─ 401 → 显示"邮箱或密码错误"
 ├─ 429 → 显示"尝试过于频繁,请 N 秒后再试"(N = Retry-After)
 └─ 其他 → 通用错误提示

4.3 绑定 Git 资源

POST /api/resources
{
  "type": "git",
  "name": "my-repo",
  "external_ref": "https://example.com/org/my-repo.git",
  "permission_scope": ["repo:read", "repo:write:current-branch"],
  "constraints": { "ref": "main" },
  "secret_ref": "vault://secret/users/{user_id}/bindings/my-repo",
  "status": "active"
}
 → 200, data.id = <binding_id>

4.4 把绑定授给一个 backend 子 Agent 角色

POST /api/resource-grants
{
  "resource_id": "<binding_id>",
  "binding_scope": "main",
  "role": "backend",
  "allowed_actions": ["repo:read"]
}
 → 200, data.id = <grant_id>

4.5 撤销与清理

DELETE /api/resource-grants/{grant_id}   # 撤销授权
DELETE /api/resources/{binding_id}        # 软删除 binding

4.6 业务请求中 token 过期

任意业务接口返回 401
 └→ POST /api/auth/refresh (用 refresh token)
     ├─ 200 → 替换 token,重试原请求
     └─ 401 → 清理 token,跳登录页

4.7 用户登出

POST /api/auth/logout
 → 不论结果都清理本地 token + 跳登录页

5. 错误码索引

code HTTP 接口 含义
RESOURCE_GRANT_INVALID 400 resource-grants binding 状态非法 / allowed_actions 超出 binding.permission_scope
RESOURCE_GRANT_SECRET_REJECTED 422 resources / resource-grants metadata/constraints/permission_scope/allowed_actions 含敏感字段
FORBIDDEN_SCOPE 403 resources / resource-grants 跨用户访问别人的资源/授权
NOT_FOUND 404 resource-grants 引用的 binding 或 grant 不存在
—(detail 字符串) 401 全部 未登录 / token 失效 / 已登出
—(detail 字符串) 403 登录 / /me 账户已禁用 / 权限不足
—(detail 字符串) 429 login 限流(每 IP 5 次/60s)
—(detail 数组) 422 全部 Pydantic 校验失败(邮箱格式、枚举值等)

6. 字段速查

资源类型枚举

type 子 Agent 可见内容 permission_scope 示例
git repo URL、ref、允许路径、读写范围 repo:read, repo:write:current-branch
sk SK 来源、版本、允许/禁止策略 sk:read, sk:list
project_doc 文档引用、版本、可读范围 doc:read, doc:list
cloud_account account/project/subscription 元数据、允许动作 cloud:list, cloud:read
cloud_resource 资源 ID、环境、网络边界、允许动作 vm:ssh:approved-window, service:restart

状态机

ResourceBinding:

pending ─→ active ─┬→ disabled ─→ active ...
                   └→ revoked  (终态)

ResourceGrant:

active ─┬→ suspended ─→ active ...
        ├→ revoked   (终态,由 DELETE 设置)
        └→ expired   (终态,由 expires_at 触发,当前由调用方判断)

7. 安全与配额

项 数值/规则
登录限流 每 IP 每 60 秒 ≤ 5 次(不区分成功失败)
Access token TTL 24 小时
Refresh token TTL 7 天
API 列表分页上限 limit ≤ 500
name 长度上限 255 字符
secret_ref 长度上限 500 字符
敏感字段拒绝模式 key 含 password|token|secret|private_key|access_key|credential(不区分大小写)→ 422
例外 key secret_ref 不算敏感(视为引用)

8. 测试账号(仅联调)

角色 邮箱 密码
普通用户 55@55.com By@123456.

Heicode 客户端固定使用 role="user"。其他角色(channel/admin)由 mcp-server 现有业务使用,不开放给 Heicode。


9. 排障

如发现接口行为与本文档不一致:

  1. 客户端应在所有请求带 X-Request-Id 头(UUID 格式)
  2. 报告内容:
    • 完整请求 URL + Method + Headers + Body
    • 完整响应 HTTP 状态 + Body
    • X-Request-Id 值
    • 时间戳(精确到秒)
  3. 后端按 X-Request-Id 反查日志和审计

4. NewAPI 元数据透传(4 接口)

4.0 公共说明

Heicode 决策 ④(透传方案):mcp-server 包一层 /api/user/heicode/*,背后调 NewAPI(code.xinghanlab.com)admin token,按当前登录用户的 email 反查 NewAPI 本地 user_id 后透传。

前端只对接 mcp-server 一个域,不直连 code.xinghanlab.com,零 CORS 问题。

当前状态:代码已上线 + 4 端点全注册;未配置 admin token 时返回 503 HEICODE_NEWAPI_NOT_CONFIGURED。Heicode 配齐 token 后立即生效,无需重新构建/部署。

4.1 GET /api/user/heicode/balance

响应 200:

{
  "success": true,
  "data": {
    "heicodeUserId": 123,
    "email": "user@example.com",
    "username": "user",
    "displayName": "张三",
    "group": "default",
    "status": 1,
    "quota": 100000,
    "usedQuota": 12345,
    "requestCount": 78
  }
}

4.2 GET /api/user/heicode/models

响应 200:

{
  "success": true,
  "data": {
    "heicodeUserId": 123,
    "email": "...",
    "items": [/* NewAPI 全部模型清单(admin 视角)*/],
    "count": 28
  }
}

客户端结合 /balance 的 group 字段做用户可见性过滤。

4.3 GET /api/user/heicode/usage

Query: days (1-90,默认 30)

响应 200:

{
  "success": true,
  "data": {
    "heicodeUserId": 123,
    "email": "...",
    "days": 30,
    "items": [/* NewAPI 按日 quota 统计 */],
    "count": 30
  }
}

4.4 GET /api/user/heicode/logs

Query: limit (1-200,默认 50),page (默认 1)

响应 200:

{
  "success": true,
  "data": {
    "heicodeUserId": 123,
    "email": "...",
    "page": 1,
    "limit": 50,
    "items": [/* NewAPI 调用日志 */],
    "count": 50
  }
}

4.x 共通错误码

HTTP code 含义
401 — 未登录
404 HEICODE_USER_NOT_FOUND 在 NewAPI 找不到 email 的用户(用户需先在 Heicode 完成首次登录建账)
502 HEICODE_NEWAPI_UPSTREAM_ERROR NewAPI 调用失败
503 HEICODE_NEWAPI_NOT_CONFIGURED mcp-server 未配置 admin token(见 §B-1)

5. Agnet 平台本地 stub(12 接口)

5.0 公共说明

按 Heicode 仓库 docs/integration/agnet-platform-request-contract.md 字段形态返回 mock 数据。用于前端联调,真实 agent-manager 12 接口落地后切换为出站调用,字段 / 路径 / 错误码 0 改动。

存储:内存 dict,重启清空(仅联调用)。

通用 Header:

Header 必填 说明
Authorization: Bearer <accessToken> 是 复用登录 token
X-Correlation-Id 建议 mcp-server 生成;全链路追踪 ID
X-Request-Id 建议 单次 HTTP 请求追踪
Idempotency-Key 创建类建议 同 key 返回原响应(避免重复创建)

通用错误码:

HTTP business code
400 POLICY_REJECTED (字段缺/非法 / 高危无审批)
403 MODEL_NOT_ALLOWED / FORBIDDEN_SCOPE / POLICY_REJECTED (高危)
404 NOT_FOUND
409 DEPLOYMENT_CONFLICT
422 RESOURCE_GRANT_INVALID / RESOURCE_GRANT_SECRET_REJECTED / RESOURCE_GRANT_SECRET_REF_REQUIRED

5.1 POST /api/agnet/deployments

请求体(详见 heicode 仓库 agnet-platform-request-contract.md §2,stub 严格按其字段校验):

{
  "orchestration_plan": {
    "intent_id": "intent_xxx",
    "template_hint": "manager-resource-binding",
    "objective": "...",
    "risk_level": "low",
    "budget": {"max_tokens": 100000, "max_cost_usd": 30, "max_duration_sec": 7200},
    "user_context": {"user_id": "...", "channel_id": "..."},
    "billing_context": {"provider": "newapi"},
    "agent_runtime": {"platform": "agnet", "agents": [...]},
    "metadata": {"correlation_id": "corr_xxx"},
    "agents": [{
      "role_template": "builder",
      "goal": "...",
      "default_model_id": "...",
      "resource_grants": [{
        "grant_id": "...", "resource_id": "...", "resource_type": "git",
        "user_id": "...", "binding_scope": "main",
        "target_role": "builder", "target_agent_ref": "...",
        "permission_scope": ["repo:read"], "status": "active",
        "secret_ref": "vault://...",
        "constraints": {}, "metadata": {}
      }]
    }]
  }
}

响应 200:

{"success": true, "data": {
  "deployment_id": "dep_xxx",
  "status": "accepted",
  "agent_instances": [{"instance_id": "agi_xxx", "role": "builder", "phase": "pending"}]
}}

校验规则(stub 已实现):

  • risk_level=high 必须有 resource_grants[].constraints.approval_id 或 audit.approval_id
  • billing_context.provider ∈ {newapi, litellm}
  • 凭据型资源(git/sk/cloud_*)必须有 secret_ref
  • metadata / constraints / audit key 不得含敏感词(password/token/secret/private_key/access_key/credential)→ 422 RESOURCE_GRANT_SECRET_REJECTED
  • target_role 必须等于所属 agent 的 role_template

5.2 GET /api/agnet/deployments

Query: user_id, binding_scope, status, limit (1-500) 响应 200: {success, data: {items: [...], total: N}}

5.3 GET /api/agnet/deployments/{id}

响应 200: 完整 deployment 详情(含 agent_instances / resource_grants_summary / budget_consumed)

5.4 POST /api/agnet/deployments/{id}/stop

请求体可空。幂等:已 stopped 重复调返 200。

5.5 GET /api/agnet/deployments/{id}/logs

Query: agent_instance_id, stream (stdout/stderr/system/audit), since, limit (1-1000), cursor 响应: {items: [{log_id, deployment_id, agent_instance_id, stream, level, message, redacted, occurred_at}], next_cursor, total}

5.6 GET /api/agnet/deployments/{id}/logs/stream (SSE)

返回 text/event-stream,事件类型:log / heartbeat / done。

5.7 GET /api/agnet/projects/{binding_scope}/dashboard-snapshot

路径名 projects 是契约保留旧名,参数实际是 binding_scope。

响应: {project_id, binding_scope, active_instances, phase_distribution, failure_rate_1h, avg_task_duration, budget, resource_usage, updated_at}

5.8 GET /api/agnet/deployments/{id}/metrics

Query: window (默认 15m), step (默认 60s) 响应: {deployment_id, window, step, series: [{metric, unit, points: [[time, value], ...]}, ...]}

返回 9 个 metric: tokens_used / cost_usd / duration_sec / cpu_millicores / memory_mb / restart_count / tool_call_count / error_count / queue_latency_ms

5.9 GET /api/agnet/deployments/{id}/events

事件名(mock 已 seed): deployment.accepted / instance.phase_changed / sk_snapshot_refreshed / resource_grant.attached / resource_grant.revoked / budget.threshold_reached / deployment.failed / deployment.stopped

响应: {items: [{event_id, event, schema_version, user_id, channel_id, binding_scope, deployment_id, correlation_id, occurred_at}], next_cursor, total}

5.10 GET /api/agnet/audit-logs

Query: user_id, binding_scope, actor, action, since, limit (1-1000), cursor

5.11 POST /api/agnet/sk-snapshots/resolve

请求体: {"deployment_id": "dep_xxx"} 响应: {deployment_id, items: [snapshot], total: 1}

snapshot 形态: {snapshot_id, deployment_id, user_id, binding_scope, source_type, source_ref, artifact_ref, checksum, status, resolved_at}

5.12 GET /api/agnet/deployments/{id}/sk-snapshots

Query: source_type, limit, cursor


6. 任务编排(5 接口) — cc-haha 任务驾驶舱 / 工作台 配套

字段形态严格对齐 cc-haha/desktop/src/stores/heicodeTaskStore.ts。

对象语义:用户输入想法(intent)→ Heicode 追问(followups)→ 全部答完 → 生成任务卡(TaskCard)→ 进入"准备资源 / 部署"阶段。

状态机:

draft → configuring → running → (后续 awaiting_approval / completed / failed / paused)

6.1 POST /api/user/tasks/intent

请求体:

{ "intent": "做一个面向小团队的任务协作 SaaS", "name": "可选" }

响应 200 (HeicodeTask):

{
  "success": true,
  "data": {
    "id": "uuid",
    "user_id": "uuid",
    "name": "做一个面向小团队的任务协作 SaaS",
    "status": "configuring",
    "status_caption": "等待你回答几个问题",
    "intent": "做一个面向小团队的任务协作 SaaS",
    "thread": [
      {"kind": "user",    "text": "...",         "at": 1715168400000},
      {"kind": "heicode", "text": "好的。我先问你两个问题...", "at": 1715168400001,
       "followups": [
         {"id": "scope", "question": "你希望第一阶段交付到什么程度?",
          "options": [
            {"id": "mvp",    "label": "MVP:能跑通主流程"},
            {"id": "polish", "label": "完整功能 + UI 细节打磨"},
            {"id": "prod",   "label": "直接上生产", "risk": "high-risk"}
          ]},
         {"id": "tech", "question": "技术栈倾向?",
          "options": [
            {"id": "modern_web",  "label": "现代 Web(React + Node/Python)"},
            {"id": "py_backend",  "label": "Python 后端为主"},
            {"id": "let_heicode", "label": "让 Heicode 决定"}
          ]}
       ]}
    ],
    "card": null,
    "created_at": 1715168400000,
    "updated_at": 1715168400000
  }
}

6.2 GET /api/user/tasks

Query: status, limit (1-200), offset 响应: {items: [HeicodeTask], total, offset, limit}

6.3 GET /api/user/tasks/{id}

响应: 单个 HeicodeTask 错误: 404 NOT_FOUND / 403 FORBIDDEN_SCOPE(跨用户)

6.4 POST /api/user/tasks/{id}/answer

请求体: {"question_id": "scope", "option_id": "mvp"}

响应 200:返回更新后的 HeicodeTask。

  • 还有未答的 followup → status 仍 configuring,card 仍 null
  • 所有 followup 都答完 → status → running,card 自动生成:
{
  "card": {
    "goal": "做一个面向小团队的任务协作 SaaS",
    "scope": ["MVP 范围:核心功能跑通", "技术债务可后续清理", "暂不做高级 UI/性能优化"],
    "generated_artifacts": ["产品说明", "原型描述", "技术方案", "代码骨架(React + Node/Python 后端)"],
    "manager_actions": [
      {"label": "去 Manager 准备资源", "deeplink": "/manager/resources?from=task"},
      {"label": "查看团队建议",        "deeplink": "/manager/team?from=task"}
    ]
  }
}

错误:

  • 400 INVALID_OPTION — option_id 不在该 followup 的 options 列表里
  • 404 QUESTION_NOT_FOUND — question_id 不存在
  • 400 TASK_STATE_INVALID — task 当前 status 不允许再答

6.5 POST /api/user/tasks/{id}/messages

请求体: {"text": "再补充:希望支持飞书集成"} 响应 200:thread 追加 user 消息 + heicode ack("收到。我会把这条要求纳入任务上下文。")。MVP 不再触发新 followups。

6.6 GET /api/user/tasks/{id}/execution(Slice 8 — 执行反馈)

请求: 仅需 Authorization: Bearer <jwt>,无 query。 响应 200:ExecutionState(字段对齐 cc-haha/desktop/src/stores/heicodeTaskStore.ts:ExecutionState)

{
  "success": true,
  "data": {
    "sub_steps": [
      {"id":"step_1","title":"需求分解","status":"done","caption":"已完成","at": 1778237397000}
      // status ∈ done|running|waiting|failed|skipped
    ],
    "sk_tool_calls": [
      {"id":"tc_1","name":"read_codebase","status":"done","summary":"...","at": 1778237397200}
    ],
    "events": [
      {"id":"ev_1","level":"info","message":"任务启动...","at": 1778237397100}
      // level ∈ info|warn|error
    ],
    "artifacts": [
      {"id":"art_1","kind":"doc","label":"产品说明(PRD)","url":"/manager/artifacts/<task_id>/prd.md"}
      // kind ∈ doc|api|diff|report
    ],
    "spend_today": "¥12.30"   // 可空
  }
}

生命周期约束:仅 task.status ∈ {running, awaiting_approval, completed} 才有数据;其他状态返回空 ExecutionState(5 个字段都是空数组 / spend_today=null)。前端可据此显示"等待启动"占位。

错误: 404 NOT_FOUND / 403 FORBIDDEN_SCOPE / 401。

6.7 GET /api/user/tasks/{id}/delivery(Slice 9 — 交付结果)

响应 200:DeliveryResult

{
  "success": true,
  "data": {
    "summary": "任务「...」已交付。包含产品说明、代码骨架、测试报告 3 大类产物...",
    "deliverables": [
      {
        "id":"deliv_1","kind":"product-spec","title":"产品说明 PRD v1",
        "primary_action":   {"label":"查看文档","deeplink":"/manager/artifacts/<task_id>/prd.md"},
        "secondary_action": {"label":"...","deeplink":"..."}   // 可选
      }
      // kind ∈ product-spec|code-diff|test-env|prod-env
    ],
    "quality": [
      {"id":"q_1","label":"单元测试覆盖率","status":"pass","detail":"82%"}
      // status ∈ pass|warn|fail
    ],
    "next_actions": [
      {"label":"去 Manager 准备资源","intent":"manager.resources"}
    ]
  }
}

生命周期约束:仅 task.status == "completed" 时返回完整数据;其他状态所有字段都为空字符串 / 空数组。前端可据此显示"任务尚未完成"占位。

错误: 404 / 403 / 401。

6.8 GET /api/user/tasks/{id}/audit(Slice 10 — 任务详情抽屉)

Query: tab 可选,∈ usage | resources | approvals | security。不传则一次性返回 4 个 tab 全量;传则只填该 tab,其他 tab 字段返回空数组(schema 始终稳定)。

响应 200:TaskAudit

{
  "success": true,
  "data": {
    "usage":     [{"id":"u_1","model":"gpt-4o-mini","input_tokens":12400,"output_tokens":3200,"cost":"¥4.20","at_iso":"2026-05-08T..."}],
    "resources": [{"id":"r_1","resource":"git/heicode-frontend","scope":"read","last_used_iso":"2026-05-08T..."}],
    "approvals": [{"id":"<approval_uuid>","operation":"deploy","target_resource":"prod-cluster","risk_level":"high","decision":"approve","enqueued_iso":"...","resolved_iso":"..."}],
    "security":  [{"id":"s_1","event":"task_created","level":"info","at_iso":"..."}]
  }
}

approvals tab 是真表查询(heicode_approvals where task_id=...,按 enqueued_at DESC,limit 50),其他 3 tab 当前是 deterministic mock,后续可接入真实数据源(usage 接 NewAPI logs / resources 接 resource_grants 使用日志 / security 接 audit_logs)。

错误:

  • 400 INVALID_TAB — tab 不在允许枚举内
  • 404 / 403 / 401

7. Server-Sent Events(单通道事件推送)

状态:契约定义(mcp-server 端实现待发,预计 Day 2.5 上线 — 见 Heicode-对接进度与待办.md §7.11.1)。本节字段形态已冻结,cc-haha 可立即按此搭 Slice 15 SSE 订阅骨架。

7.0 公共说明

mcp-server 提供唯一一条 SSE 长连接给前端订阅所有用户级实时事件(高危审批、任务状态、执行进度、保活)。

合并成单通道的好处:

  • 客户端只维护 1 个 EventSource(节省资源)
  • 后端只管 1 个推送泵
  • 不同事件类型按 SSE event: 字段路由,互不冲突

7.1 GET /api/user/events/stream

用途:当前登录用户的实时事件流。

请求:

GET /api/user/events/stream
Accept: text/event-stream
Authorization: Bearer <accessToken>

⚠️ 浏览器 EventSource 不支持自定义 header。前端建议用 fetch + ReadableStream 手动解析 SSE,或使用支持 header 的 polyfill(如 eventsource-polyfill)。

响应: 200 OK,Content-Type: text/event-stream,长连接。

事件路由(按 SSE event: 字段):

event 类型 用途
approval.requested 高危审批请求 — 弹审批弹窗
approval.resolved 审批已被响应(其他设备处理 / 过期)— 关闭对应弹窗
task.status_changed 任务 status 变化 — 切右侧面板
task.execution_progress sub_step 状态变化 — 刷新执行反馈面板
heartbeat 保活(每 25s)

7.2 event: approval.requested

字段对齐 cc-haha desktop/src/stores/approvalStore.ts:ApprovalRequest。

SSE 帧:

event: approval.requested
data: {"approval_id":"apr_xxx","task_id":"task_xxx","task_name":"…","operation":"在生产环境部署服务","target_resource":"vm://newapi-prod","requesting_role":"operator","risk_level":"high","impact_summary":["重启服务","回滚预案已备好"],"heicode_suggestion":"approve","derives_short_lived_credential":true,"ttl_minutes":60,"enqueued_at":"2026-05-08T10:00:00Z"}

字段:

字段 类型 说明
approval_id string 审批唯一 ID
task_id string 关联任务 ID(可空,如系统级审批)
task_name string 任务名(弹窗显示)
operation string 待批准的操作描述
target_resource string 受影响资源(如 vm://newapi-prod / repo://org/foo)
requesting_role string 发起请求的子 Agent 角色(builder / operator / reviewer 等)
risk_level enum low / medium / high
impact_summary string[] 影响摘要 bullet 列表
heicode_suggestion enum Heicode 给出的建议:approve / reject / delegate
derives_short_lived_credential bool 批准后是否会生成短期凭据注入 Pod
ttl_minutes int 审批有效时长(minutes),过期自动 expired
enqueued_at string (ISO 8601) 入队时间

7.3 event: approval.resolved

SSE 帧:

event: approval.resolved
data: {"approval_id":"apr_xxx","decision":"approve","resolved_by":"user_55","resolved_at":"2026-05-08T10:01:23Z"}

字段 类型 说明
approval_id string 与 approval.requested 对应
decision enum approve / reject / expired
resolved_by string | null 谁做的决定(其他设备同步时使用;expired 时为 null)
resolved_at string (ISO 8601) 决定时间

客户端收到该事件应关闭对应 approval_id 的弹窗(避免多设备登录时弹窗鬼影)。

7.4 event: task.status_changed

SSE 帧:

event: task.status_changed
data: {"task_id":"task_xxx","old_status":"running","new_status":"completed","status_caption":"已交付","at":"2026-05-08T10:05:00Z"}

字段 类型 说明
task_id string 任务 ID
old_status string 之前的 status(参见 §6.1 task.status 枚举)
new_status string 当前 status
status_caption string | null 副标题(如"等待生产部署审批")
at string (ISO 8601) 变化时间

客户端应据此切换右侧面板(running/awaiting_approval → ExecutionFeedbackPanel;completed → DeliveryResultPanel)。

7.5 event: task.execution_progress

SSE 帧:

event: task.execution_progress
data: {"task_id":"task_xxx","sub_step_id":"step_compile","status":"done","caption":"编译通过","at":"2026-05-08T10:03:12Z"}

字段 类型 说明
task_id string 任务 ID
sub_step_id string 步骤 ID(与 /api/user/tasks/{id}/execution 返回的 sub_steps[].id 对应)
status enum waiting / running / done / failed / skipped
caption string | null 步骤当前描述
at string (ISO 8601) 变化时间

客户端应据此就地刷新 ExecutionFeedbackPanel 中对应 sub_step 行(不需要重拉整个 execution)。

7.6 event: heartbeat

SSE 帧:

event: heartbeat
data: {"server_time":"2026-05-08T10:00:25Z"}

字段 类型 说明
server_time string (ISO 8601) 服务端时间,便于客户端检测时钟漂移

发送频率:每 25 秒一次。客户端 60 秒未收到 heartbeat 应主动重连。

7.7 配套 REST 端点

实时通道之外,前端启动时需要拉一次"当前未处理审批",并提供"用户响应审批"入口:

7.7.1 GET /api/user/approvals

用途:拉取当前用户待响应的审批列表(启动时调一次,后续靠 SSE 增量)。

响应 200:

{
  "success": true,
  "data": {
    "items": [/* ApprovalRequest 对象数组,字段同 §7.2 */],
    "total": 0
  }
}

7.7.2 POST /api/user/approvals/{approval_id}/decision

用途:用户在弹窗里选择批准/拒绝。

请求体:

{ "decision": "approve" }

decision ∈ approve / reject(不能传 expired,那是服务端自动设置)。

响应 200: 返回更新后的 ApprovalRequest 对象(含 decision / resolved_by / resolved_at)。

mcp-server 此时会广播 approval.resolved 事件到该用户所有 SSE 连接(其他设备的弹窗会自动关闭)。

错误响应:

HTTP code 含义
404 NOT_FOUND approval_id 不存在
403 FORBIDDEN_SCOPE 该审批不属于当前用户
410 APPROVAL_EXPIRED 已超时,决定无效
409 ALREADY_RESOLVED 已被响应(其他设备处理)

7.8 错误处理(SSE)

场景 mcp-server 行为 客户端建议
401(token 过期) 立即关闭流 调 /api/auth/refresh 后重连
503 / 网络抖动 — 指数退避重连(1s / 2s / 5s / 10s)
60s 无 heartbeat — 主动重连

7.9 客户端订阅最简实现(参考)

// cc-haha/desktop/src/lib/heicodeEventStream.ts
async function subscribe(token: string, handlers: { [evt: string]: (data: any) => void }) {
  const res = await fetch(`${BASE}/api/user/events/stream`, {
    headers: { Authorization: `Bearer ${token}`, Accept: 'text/event-stream' },
  })
  const reader = res.body!.getReader()
  const decoder = new TextDecoder()
  let buf = ''
  while (true) {
    const { value, done } = await reader.read()
    if (done) break
    buf += decoder.decode(value, { stream: true })
    let idx
    while ((idx = buf.indexOf('\n\n')) !== -1) {
      const frame = buf.slice(0, idx); buf = buf.slice(idx + 2)
      const evtLine = frame.split('\n').find(l => l.startsWith('event:'))
      const dataLine = frame.split('\n').find(l => l.startsWith('data:'))
      if (!evtLine || !dataLine) continue
      const event = evtLine.slice(6).trim()
      const data = JSON.parse(dataLine.slice(5).trim())
      handlers[event]?.(data)
    }
  }
}

10. 版本历史

版本 日期 变更
v1.0 2026-05-05 初版:登录 4 接口 + P1 资源模型 9 接口
v2.0 2026-05-08 + NewAPI 元数据透传 4 接口(§4) + Agnet stub 12 接口(§5) + 任务编排 5 接口(§6)。总计 34 接口
v2.1 2026-05-08 + SSE 单通道事件推送契约(§7)+ 配套审批 REST 2 接口(§7.7)。冻结字段形态供 cc-haha Slice 15 起骨架;mcp-server 实现 Day 2.5 上线

待开发(参考 Heicode-对接进度与待办.md):

  • 高危审批 SSE 推送(cc-haha 客户端 ApprovalDialog 配套)
  • P2 Secret Broker(等 Vault 部署)
  • P5 出站调用真实 Agnet 平台(等 agent-manager 12 接口)

B. Heicode 团队待办清单

按 mcp-server 当前已交付的能力,Heicode 这边需要做以下 5 件事让全链路真跑起来。括号内是优先级与阻塞影响。

B-1 配置 NewAPI service token(🔴 高优 — 阻塞 P4 真跑)

Heicode 端要做:

  1. 在 NewAPI 创建一个专用账号 mcp-server-service,角色 = admin
  2. 生成永久 access token
  3. 把 token + admin user_id 给 mcp-server 团队(通过安全通道,绝不写 Git/聊天/邮件)

mcp-server 端要做(拿到后 ~30 分钟):

  • 通过 K8s secret 注入 env:HEICODE_NEWAPI_SERVICE_TOKEN + HEICODE_NEWAPI_ADMIN_USER_ID
  • kubectl rollout restart 即可生效(无需重新构建镜像)

B-2 答复 P4 2 个细节(🟡 中优 — 不阻塞但影响实现细节)

详见 Heicode-对接进度与待办.md §2.3.2。两个问题:

  • 细节①:mcp-server 调 NewAPI 时 New-Api-User 怎么映射到 heicode 本地 user_id?(mcp-server 当前用 admin search by email,工作但有 1 次往返开销)
  • 细节②:子 Agent 部署 billing_context.provider 怎么决定?(mcp-server 默认 litellm,需 Heicode 用户场景默认 newapi 时给规则)

B-3 协调 heicode web 团队对接 P1 资源绑定 UI(🟡 中优)

cc-haha 桌面客户端切片 5 已下线 P1 UI(按 Heicode 产品包 08-client-guide.md 边界)。资源绑定 UI 现在归 heicode web (code.xinghanlab.com)。需要:

  • heicode web 团队接 mcp-server 的 9 个 P1 接口(§2 / §3)
  • 否则用户从客户端任务卡点"去 Manager 准备"会 404

B-4 推动 agent-manager 团队实现 12 真实接口(🟢 中优 — 阻塞 P5 出站联调)

agent-manager 12 接口契约见:

  • Heicode 仓库 docs/integration/agnet-platform-request-contract.md
  • mcp-server 仓库 Docs/Agent-Manager-Heicode对接需求文档.md

mcp-server 已上线 stub(§5)字段形态完全一致,agent-manager 实装时可直接对照。

Heicode 这边要给 mcp-server:

  • agent-manager 团队对接负责人
  • staging 联调环境地址(建议 staging-agnet.xinghanlab.com)
  • 服务令牌方案确认(建议 A pre-shared bearer 起步)

B-5 联调测试(🟢 低优 — 可并行)

cc-haha 客户端 / heicode web 拿到本文档后即可开始联调:

  • 登录链路(§1)已实测,无需 mcp-server 配合
  • P1 资源(§2 / §3)已实测,无需 mcp-server 配合
  • Agnet stub(§5)已实测,前端可立即开始任务执行联调
  • 任务编排(§6)已实测,cc-haha 可立即把任务驾驶舱 / 工作台从 mock 切真
  • NewAPI 透传(§4)等 B-1 完成后真跑

如发现接口问题,按 §9 排障流程提交。


C. 总账速查

模块 章节 端点数 状态
登录认证 §1 4 ✅ 上线 + Heicode 已对接
P1 资源绑定 §2 5 ✅ 上线
P1 资源授权 §3 4 ✅ 上线
P4 NewAPI 透传 §4 4 ✅ 上线(待 B-1 token 真跑)
P5 Agnet stub §5 12 ✅ 上线(mock 数据)
任务编排 §6 5 ✅ 上线
合计 — 34 全部上线