Files
heicode/docs/integration/heicode-desktop-unified-api.md
T
chenchenandClaude Opus 4.8 c4e84258b7 docs(integration): desktop client API doc for the template-agent model
New authoritative client doc (heicode-desktop-client-api.md): the desktop client
lists its agents from HM, gets each agent's subdomain + access_token, and
connects to the agent directly over SSE; models for both client and agent go
through HM /v1/*. Grounded in the production-verified responses (19 Chinese
templates, agent list/deploy/status shapes, error codes). Marks the old
unified-api doc (sub task-orchestration) as superseded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:41:07 +08:00

41 KiB
Raw Blame History

Heicode 桌面客户端统一接口对接文档(v0.1)

⛔ 已废弃(2026-06-04):本文描述的是已下线的 sub 任务编排模型(tasks/workflow/display_status/git_ref/产物下载/部署租约等,相关后端已删除)。 新客户端请改用 heicode-desktop-client-api.md(模板 Agent 模型)。 本文仅作历史留存。

更新时间:2026-06-03 适用范围:Heicode Desktop 对接 Heicode Manager 的统一接口层(Sub Agile / Swarm 两模式)。端到端流程与三端职责以 heicode-sub-mode-flow-spec.md 为准,本文是其接口层。 Manager 生产地址:https://code.xinghanlab.com 基准:统一调用方案 v0.1 + agent_management Sub Mode Runtime 对接指南。

本文取代旧的 heicode-desktop-sub-agile-api.md(其 /api/agnet/* 路由已废弃)。新客户端一律使用本文的 /api/heicode/* 与 /api/agent/* 接口。

⚠️ 2026-06-03 流程对齐(权威端到端流程见 heicode-sub-mode-flow-spec.md,本文是其接口层)。几处认知已纠正:

  • 客户端是 Claude-Code 式智能体程序(本地能跑 agent、执行命令、本地部署),不是无 AI 的壳;HM = 模型网关(/v1/*)+ 控制面,给客户端和 agent_management 两边都提供模型;agent_management = 云端多 agent 运行时。
  • sub 模式 = 把多 agent 任务派到云端 agent_management 跑(区别于客户端本地自己跑小任务)。
  • display_status 只代表"跑完没/有没有真产物(防空壳)",不代表"代码对不对"。代码对错 = 客户端(本地能跑能测)+ 用户 review 判,不是 HM 判(HM 没 AI、不读代码)。详见 spec §6。
  • 部署 = 客户端执行 + 用户必须确认;HM 只把凭据从 Key Vault 安全发给客户端,HM 不部署、不连 VM(见 §7,已改)。
  • 产物归宿是用户自己的 git 仓库(github/gitea);先绑仓库(及 vm/db/blob)→ §8 资源绑定。

2026-06-02 更新(gap-analysis P0/P1 闭环并实跑验证):GET 无 body 设备签名(§1)、审批列表(§3.2)、Swarm 同形(§3)。

2026-06-03 更新(产物模型对齐):sub 模式强制绑定 git 才能用,否则只能本地跑——因此代码产物的唯一归宿是用户自己的 git 仓库(clone/pull)。早期"HM 把文本产物解析成项目文件夹(project_folder/manifest/files/archive)"是无 git 流程的残留,不再作为代码交付路径;artifacts 接口仅保留给非代码产物(test_report/摘要)。详见 §5。

0. 命名与总原则

  • 命名统一:agnet 是历史拼写错误,已全量改为 agent。所有新接口为 /api/agent/*、/api/heicode/*;旧 /api/agnet/* 已下线(404)。
  • 客户端只调 Heicode Manager(HM):任务/控制走 /api/heicode/*、/api/agent/*,模型走 /v1/*;禁止直连 agent_management / HeiCode-Swarm / Runtime artifact 接口。
  • display_status 是 HM 的"进度/有无产物"裁决,不是"对错"裁决:客户端用它判断"跑完没、是不是空交付"(防空壳),但代码对不对由客户端自己拉下来跑/测 + 用户 review 决定(HM 没 AI、不读代码、不编译)。
  • task_id ≡ deployment_id:统一任务接口里 {task_id} 即 HM 的 deployment_id。

0.1 推荐完整流程

0. (★必做) 绑定 git 仓库 (github/gitea) + (可选) vm/db/blob -> 凭据进 Key Vault, 拿 resource_binding_id (§8)
   未绑 git 则禁用 sub 入口 (强制绑 git, §3.1)
1. GET  /api/heicode/capabilities                      取模式/模型,渲染模式与模型选择
2. POST /api/heicode/sub-agile/tasks   (需求包, 带 resource_bindings.git + X-Idempotency-Key)
                                                        创建任务 -> 响应里拿 deployment_id(=task_id) (§3.1)
3. (可选) POST .../tasks/{id}/execute                  若需"先建后跑"或重试派发
4. 轮询 GET .../tasks/{id}/workflow (运行中 3-5s) / 将来 SSE  读 display_status + 三层状态 + agents + git_ref (§4b)
5. 出现 approval 时: GET .../approvals?status=pending  -> approve/reject
6. display_status=completed 后: 按 workflow 里的 git_ref 做 git clone/pull (完整工程+历史+diff) (§5)
   (非代码运行信息如 test_report/摘要 -> GET .../artifacts 查看; HM 不托管/不解析项目代码)
7. 不满意 -> 改/重做: POST .../messages|/execute 回云端改; 或 git pull 本地用客户端自己的 agent 改 (§6)
8. (可选) 部署: 用户确认 -> 客户端凭 resource_binding_id 取短期租约(V2) -> 客户端本地 git/ssh/部署 (§7, HM 不代执行)

成功判据:display_status=completed 且 git_ref 有新 commit = 跑完且有真东西;但**"代码对不对"客户端自己拉下来跑/测 + 用户 review**(completed 不保证正确,见 §4)。

1. 认证与加密(重要)

桌面客户端调用本文所有 /api/heicode/* 接口,body 加密与签名和模型调用(/v1/*)完全一致——直接复用同一套 encryptedFetch / V2 设备签名实现,无需新增协议。

方式 适用
V2 加密 body + 设备签名(Content-Encoding: heicode-aead-v1 + X-Heicode-*,ChaCha20-Poly1305 + Ed25519) 有 body 的请求(POST/PUT/DELETE)
V2 无 body 设备签名(X-Heicode-* 签名头,不带 Content-Encoding) GET 等无 body 请求(fetch 规范禁止 GET 带 body)
Manager session cookie + New-Api-User: <user_id> Web 控制台兼容路径(桌面端可不用)

要点(与模型调用相同,未变):

  • aad / canonical 里的 path_with_query 必须是 Manager 实际收到的 path,例如 /api/heicode/sub-agile/tasks,不含 origin。
  • 每次新 X-Heicode-Nonce + 新 X25519 临时 key;签名里 sha256_hex(plaintext_body) 与加密前 JSON 字节一致。
  • 服务端在新路由上用同一中间件 UserOrV2DeviceAuth 解密+验签,从设备绑定 token 解析用户身份;失败读响应头 X-Heicode-Auth-Error。

GET 全程无 cookie 的设备签名(已支持):GET 没有 body,因此不发 Content-Encoding、不加密,但仍发同一套签名头并用相同 canonical 公式签名,sha256_hex(plaintext_body) 处填空 body 的哈希 sha256(""):

canonical = method + "\n"            # "GET"
          + path_with_query + "\n"   # 例如 /api/heicode/sub-agile/tasks/dep_x/workflow
          + timestamp_ms + "\n"
          + nonce_hex + "\n"
          + device_fingerprint + "\n"
          + ephemeral_pubkey_b64 + "\n"   # GET 仍生成一对临时 X25519 key 并带 X-Heicode-Eph-Pubkey
          + sha256_hex("")               # e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
signature = base64( ed25519_sign(device_priv, sha256(canonical)) )

即:GET 与写请求共用同一签名实现,区别仅是「不加密 body、body 哈希为空串哈希」。服务端凭 X-Heicode-Signature + X-Heicode-Device-Id + X-Heicode-Eph-Pubkey 三个头识别该模式(gap P0-1 已闭环)。客户端可用同一 encryptedFetch,对 GET 走「跳过加密、空 body」分支即可。

2. 能力发现

GET /api/heicode/capabilities

无需登录,返回模式与模型目录。

{ "success": true, "data": {
  "modes": [
    {"id":"sub_agile","name":"Sub Agile","runtime_kind":"agent_management","model_selection":"per_role","supports_roles":true,"supports_task_graph":false,"supports_artifacts":true,"supports_continue_chat":true,"enabled":true},
    {"id":"swarm","name":"Swarm","runtime_kind":"heicode_swarm","model_selection":"primary","supports_roles":false,"supports_task_graph":true,"supports_artifacts":true,"supports_continue_chat":true,"enabled":false}
  ],
  "models": [{"id":"gpt-5.4","name":"gpt-5.4","available":true}]
}}

enabled 反映该模式 Runtime 当前是否接通(HM 探测 agent_management / HeiCode-Swarm 的健康;enabled:false 时不要让用户进该模式)。 字段:runtime_kind(后端运行时)、model_selection(default|per_role|primary)、supports_roles/task_graph/continue_chat(UI 能力位)、models[].available(该模型当前可用)。

2.1 判断 sub 模式是否可用(就绪闸门)🟡

客户端在让用户点「sub 模式」前,必须先过四道闸门;任一不满足就禁用 sub 入口并提示对应引导。这是一个客户端本地组合判断(HM 不提供单一「ready」接口):

# 闸门 数据来源 不满足时
1 Runtime 接通 GET /api/heicode/capabilities → modes[id=sub_agile].enabled === true 灰掉 sub,提示「云端暂不可用」
2 已认证(设备已绑定) 本地有设备绑定 token(§1;无则先走 heicode-auth 登录/配对) 引导登录
3 已绑有效 git 仓库 GET /api/heicode/resources?type=git&status=active(§8.2)非空 引导去「资源绑定」绑 git,或改用本地模式
4 余额充足 GET /api/user/self → quota - used_quota > 0(§2.2) 引导充值
canUseSub =
     capabilities.modes.find(m => m.id==='sub_agile')?.enabled
  && isDeviceBound()
  && gitBindings.some(b => b.status==='active')
  && self.quota > self.used_quota
  • 闸门 3「强制绑 git」对齐 spec §3.1;建任务时若仍没传有效 git binding,HM 也会兜底拒绝(SUB_GIT_BINDING_REQUIRED,§11)。
  • 闸门 1/4 用现有接口(🟢);闸门 3 的客户端版资源列表是 🔴 待建(§8.2),上线前可临时用 /api/resources/(会话鉴权)联调。
  • 本地模式(客户端自己跑 agent)不需要闸门 1/3,只需 2/4。

2.2 账户与余额(判断能不能跑 / 给概览用)🟢

方法 路径 鉴权 说明
GET /api/user/self 会话/设备 当前用户:quota(剩余额度)、used_quota(累计已用)、request_count(调用次数)、分组等
GET /api/user/self/groups 同上 用户可用模型分组
GET /api/user/self/models 同上 当前用户可用模型列表(与 capabilities.models 互补,按分组过滤)
// GET /api/user/self → data 摘要
{ "id":22, "username":"...", "quota":160470000, "used_quota":39530000, "request_count":521, "group":"default" }
  • 余额/用量单位是内部 quota(展示按汇率换算);quota 为剩余,used_quota 为累计已用。
  • 建任务前应检查 quota > used_quota(闸门 4);运行中若超预算 HM 会把任务标 budget_exceeded(§4)。
  • 模型选择(需求包 model_selection)只能用 capabilities.models ∩ /api/user/self/models 里 available 的模型。

3. 统一任务接口

两套前缀,按模式选择:/api/heicode/sub-agile/*(→ agent_management)、/api/heicode/swarm/*(→ HeiCode-Swarm)。下表以 sub-agile 为例,swarm 路径把前缀 sub-agile 换成 swarm 后完全同形(approvals/deployments/workflow 等子接口)——两组路由由同一注册函数生成,不存在「只实现了 sub-agile」的情况。(注:files/archive/revisions/local-edits 这些遗留子接口两侧也都还在,但已不作为代码交付路径,见 §5/§6。)

方法 路径 说明
POST /api/heicode/sub-agile/tasks 创建任务(body = 需求包,见 §3.1)
GET /api/heicode/sub-agile/tasks 任务列表
GET /api/heicode/sub-agile/tasks/{task_id} 任务详情(含 display_status,读取时自动从 Runtime 收敛)
POST /api/heicode/sub-agile/tasks/{task_id}/messages 持续对话:追加用户消息
POST /api/heicode/sub-agile/tasks/{task_id}/execute 触发/确保执行(未派发则派发 Runtime)
DELETE /api/heicode/sub-agile/tasks/{task_id} 删除/停止任务
GET /api/heicode/sub-agile/tasks/{task_id}/workflow 工作流投影(右侧面板:mode/display_status/phases/agents(含 current_action/branch/tokens/tools/elapsed/artifact_ids)/metrics/git_ref/artifacts)
POST /api/heicode/sub-agile/tasks/{task_id}/stop 停止
GET /api/heicode/sub-agile/tasks/{task_id}/timeline 时间线(events/callbacks/artifacts 聚合)
GET /api/heicode/sub-agile/tasks/{task_id}/logs 日志(含 user_logs 友好 + debug_logs 原始两层)
GET /api/heicode/sub-agile/tasks/{task_id}/events 事件
GET /api/heicode/sub-agile/tasks/{task_id}/metrics 指标
GET /api/heicode/sub-agile/tasks/{task_id}/diagnostics 诊断(直查 Runtime 状态 + warnings)
GET /api/heicode/sub-agile/tasks/{task_id}/sk-snapshots SK 快照
GET /api/heicode/sub-agile/tasks/{task_id}/artifacts 产物列表(仅非代码产物:test_report/摘要等;代码看 git,见 §5)
GET /api/heicode/sub-agile/tasks/{task_id}/artifacts/{artifact_id}/content 单产物正文(如测试报告)
GET .../artifacts/{artifact_id}/{manifest,files,archive,revisions} 遗留:无 git 流程的"HM 解析项目文件夹"接口,sub 强制 git 后不再作为代码交付路径(后端仍在,见 §5)
POST .../artifacts/{artifact_id}/local-edits[/batch] 遗留:本地改产物改用 git 提交
GET /api/heicode/sub-agile/tasks/{task_id}/approvals?status=pending 审批列表(gap P0-2)
POST /api/heicode/sub-agile/tasks/{task_id}/approvals/{approval_id}/approve 同意审批
POST /api/heicode/sub-agile/tasks/{task_id}/approvals/{approval_id}/reject 拒绝审批
GET /api/heicode/sub-agile/tasks/{task_id}/deployments · POST 同路径 ⚠️ 旧的「Manager 代部署」控制面,不再作为部署主路径;新部署=客户端执行(见 §7)

3.1 创建 body(需求包)

客户端提交需求包,不提交 Runtime 原始参数;Manager 内部翻译成 orchestration_plan 并创建。

{
  "mode": "sub_agile",
  "client_role": "main_agent",
  "conversation_id": "conv_xxx",
  "requirement": {
    "objective": "做一个 Oracle 云代理商网站,前后端分离",
    "context": [], "attachments": [], "constraints": [], "acceptance_criteria": []
  },
  "model_selection": {
    "type": "per_role",
    "default_model": "gpt-5.4",
    "roles": {"backend":"gpt-5.4","frontend":"gpt-5.4"}
  },
  "roles": ["backend", "frontend"],
  "resource_bindings": {
    "git": "rb_git_xxx",                 // ★ 必填:用户绑定的 git 仓库(§8)。缺则拒绝建任务
    "vm": "rb_vm_xxx",                   // 可选:部署目标,仅在需要时
    "database": "rb_db_xxx",             // 可选
    "blob": "rb_blob_xxx"                // 可选
  },
  "git_options": {                        // 可选:覆盖 binding 默认
    "base_branch": "main",               // 从哪个分支拉基线
    "mode": "existing",                  // greenfield(绿地新建) | existing(已有代码上增量改)
    "allowed_paths": ["backend/", "frontend/"],   // 限定 agent 工作目录,避免动无关代码
    "write_mode": "pr"                   // pr(开 PR/交付分支,建议) | branch | main
  }
}
  • ★ resource_bindings.git 必填:sub 模式强制绑 git(spec §3.1 决策)。未传或 binding 失效 → HM 拒绝建任务,返回 SUB_GIT_BINDING_REQUIRED(见 §11)。客户端 UI 应在未绑 git 时禁用 sub 入口,引导先绑(§8)或改用本地模式。
  • 只传 resource_binding_id(如 rb_git_xxx),绝不内联明文凭据;HM 从 Key Vault 解出短期 PAT 注入 AM。
  • model_selection.type:default(全局 default_model)/ per_role(roles 映射)/ primary(Swarm 用 primary_model)。
  • conversation_id 作为任务关联键(落到 correlation_id)。
  • 模型必须用生产 NewAPI 已存在模型(当前推荐 gpt-5.4)。
  • 兼容:也接受直接传 { "orchestration_plan": {...} }(高级用法)。

幂等:创建请求带 X-Idempotency-Key: <uuid>(spec §9.3)。HM 对同 key 去重,网络重试不会建重复任务/重复 git 分支;重复命中返回首次的 deployment_id。

状态标注:resource_bindings / git_options / SUB_GIT_BINDING_REQUIRED / X-Idempotency-Key 均为 🔴 待建(随 git 化与客户端版资源接口一起上线,见 §8)。当前后端建任务尚未强制 git;客户端应按本规范预留字段,HM 侧补齐校验后即对齐。

/messages body:{"message":"继续把测试补上","role":"user"}。 /execute body 可空;用于"创建后再触发"或重试派发。

创建响应(deployment_id 即后续所有 {task_id}):

{ "success": true, "message": "", "data": {
  "deployment_id": "dep_b5fab27e9255",
  "sub_mode": "agile",
  "status": "accepted",
  "display_status": "accepted",
  "runtime_state": "runtime_syncing",
  "runtime_swarm_id": "",
  "agent_instances": [
    {"instance_id":"agi_xxx","role":"backend","phase":"pending","runtime_state":"queued","failure_reason":""}
  ],
  "permission_manifest": {"user_id":"22","binding_scope":"","resource_grants":[]}
}}

任务详情 GET .../tasks/{task_id} 返回同形 + 完整 orchestration_plan;任务列表 GET .../tasks 返回 {"items":[ ...同上... ],"total":N}。客户端按 display_status 渲染,详情/列表读取时 Manager 会自动从 Runtime 收敛终态。

3.2 审批列表(gap P0-2)

GET .../tasks/{task_id}/approvals?status=pending:

{ "success": true, "data": {
  "task_id":"dep_xxx","total":1,
  "items":[
    {"approval_id":"appr_xxx","deployment_id":"dep_xxx","type":"deploy","risk_level":"high",
     "title":"生产部署审批","status":"pending","created_at":"2026-06-02T00:00:00Z"}
  ]
}}

status 省略则返回全部;对每条 pending 项调 .../approvals/{approval_id}/approve|reject 闭环。

4. 状态模型(display_status)

客户端只展示 display_status(Manager 裁决结果):

display_status 含义
accepted / running / waiting_approval 进行中
completed 跑完且有真实产物(非空、非兜底)—— 注意:不代表代码正确
completed_without_deliverable Runtime 完成但无产物(无 git 提交)
needs_codegen 只有方案/总结,需继续生成代码
budget_exceeded 🔴 超 token/时长/成本上限,已暂停待用户决定续不续(spec §9.3)
failed / stopped 终态

裁决规则(对齐 spec §6.4):AM 说 completed 后,HM 看有没有真交付——

  • 目标态:回调带 git_ref 且有真实提交(commit/改了 N 个文件)→ completed ✅。
  • 只有方案/总结、没有提交 → needs_codegen;什么都没有 → completed_without_deliverable。
  • 过渡期(AM 未 git 化):带"改了 N 个文件"信号的非兜底 artifact(metadata.synthesized!=true 且非纯总结)也按真交付算。 HM 判的是**"有没有真东西"这个事实**,不读代码、不判对错。

⚠️ display_status 的边界(重要,见 spec §6.6):HM 只判事实——跑完没、有没有真产物、是不是空壳/兜底;HM 不读代码、不编译、不测试,判不了"代码对不对"。completed 只保证"有真东西",不保证代码正确。对错由客户端自己拉产物跑/测 + 用户 review 决定。若 agent_management 跑了测试,会作为 test_report 产物给客户端看,不是给 HM 裁决。

4.1 三层状态(GET .../workflow)

GET /api/heicode/sub-agile/tasks/{task_id}/workflow 返回客户端右侧面板需要的三层状态对象:

{ "success": true, "data": {
  "task_id":"dep_xxx","conversation_id":"conv_xxx",
  "mode":"sub_agile",                         // 顶层模式 sub_agile|swarm(与 capabilities 一致)
  "sub_mode":"agile",                         // sub_agile 内的节奏 agile|waterfall
  "cloud_deployment_status":"completed",      // Manager 控制面状态
  "runtime_execution_status":"completed",     // Runtime 上报状态
  "display_status":"completed",               // 唯一展示状态(客户端只看这个)
  "last_synced_at":"2026-06-02T...",
  "title":"...","summary":"...","phase":"development","agent_count":1,
  "phases":[                                  // 阶段列表(runtime 未给细分时为当前阶段单条)
    {"phase_id":"development","name":"development","status":"completed","agents":["backend"]}
  ],
  "agents":[
    {"agent_id":"agi_x","name":"backend","role":"backend","status":"completed",
     "current_action":"已合并到交付分支",       // 🔴 一句话「现在在干啥」,给 work 视图滚动
     "branch":"agent/backend",                  // 🔴 该 agent 的分支(看单角色 diff)
     "tokens":0,"tools":0,"elapsed_seconds":0,"artifact_ids":["art_x"]}
  ],
  "git_ref": {                                  // 🔴 交付引用(见 §5.2);未就绪时为 null
    "provider":"github","repo_url":"https://github.com/owner/repo",
    "branch":"delivery/dep_xxx","commit_sha":"a1b2c3d","tag":"delivery-dep_xxx-rev1",
    "pull_request_url":null
  },
  "artifacts":[{"artifact_id":"art_x","title":"测试报告","artifact_type":"test_report"}],  // 仅非代码运行信息
  "artifact_ids":["art_x"],
  "metrics":{"tokens_used":618,"tools":0,"elapsed_seconds":33,"total_messages":2},
  "tokens":618,"tools":0,"elapsed_seconds":33
}}

字段说明(gap A/D/F):

  • mode:顶层 sub_agile|swarm,与 capabilities 一致;列表 GET .../tasks 的每个 item 也带 mode 和 display_status,重启后从列表恢复任务不会把 swarm 当成 sub-agile。sub_mode 是 sub_agile 内部节奏。
  • git_ref:客户端据此 git pull 看产物(§5.2)。completed + git_ref 有 commit_sha = 本轮真交付落到了用户仓库;续跑/重做后 commit_sha 会更新。🔴 待 AM 回调带 git_ref + HM 透出。
  • phases[]:始终是数组。当前 sub-mode runtime 只上报单个 phase,故默认是「当前阶段」一条;待 runtime 上报阶段细分后会展开。
  • metrics / 顶层 tokens/tools/elapsed_seconds:来自 runtime 状态指标(tokens_used/elapsed_seconds/total_messages 为真实值)。
  • 每个 agent 的 current_action/branch/tokens/tools/elapsed_seconds:待 agent_management 上报 per-agent 富字段(🔴),未上报时为空/0;artifact_ids 按 source_agent_role 归到对应 agent。
  • artifacts[]:只放非代码运行信息(test_report/summary);代码看 git_ref,不在此处。

client_task_status(本地交互态)由客户端自己维护,不由 Manager 返回。

4.2 运行信息接口(日志 / 时间线 / 诊断 / 事件 / 指标)🟢

work 视图除 /workflow 外,下列接口给过程信息(都只读、GET、V2 无 body 签名)。它们只承载"运行信息",不承载代码产物(代码看 git_ref,§5)。

方法 路径 data 关键字段 用途
GET .../tasks/{id}/logs user_logs[](友好)、debug_logs[](原始) 日志面板分两层:普通用户看 user,调试面板看 debug
GET .../tasks/{id}/timeline events[](task./agent./phase./handoff./delivery.)、callbacks[]、artifacts[] 聚合 任务时间线
GET .../tasks/{id}/events events[](原始事件流) 细粒度事件
GET .../tasks/{id}/metrics tokens_used、elapsed_seconds、total_messages 指标卡
GET .../tasks/{id}/diagnostics runtime_status、warnings[](直查 Runtime) 排障
GET .../tasks/{id}/sk-snapshots snapshots[] SK 快照
// GET .../logs → data
{ "task_id":"dep_xxx",
  "user_logs":[{"ts":"2026-06-03T..","level":"info","agent":"backend","message":"开始实现登录接口"}],
  "debug_logs":[{"ts":"2026-06-03T..","level":"debug","message":"tool: write_file path=backend/auth.go"}] }
// GET .../timeline → data
{ "task_id":"dep_xxx",
  "events":[{"event_type":"phase.changed","occurred_at":"..","payload":{"phase":"development"}},
            {"event_type":"delivery.pushed","occurred_at":"..","payload":{"git_ref":{"branch":"delivery/dep_xxx","commit_sha":"a1b2c3d"}}}],
  "callbacks":[], "artifacts":[{"artifact_id":"art_x","artifact_type":"test_report"}] }

轮询建议:work 视图主要轮询 /workflow(含 display_status + agents + git_ref,一次拿全);需要日志/时间线明细时再单独拉 /logs、/timeline。SSE 上线后这些都可由事件流推送(§4b)。

4b. 响应 envelope 与实时刷新

成功:{ "success": true, "message": "", "data": {...} } 失败:{ "success": false, "message": "...", "error": { "code": "...", "message": "...", "retryable": false, "request_id": "..." } }

task_id / deployment_id / conversation_id / correlation_id 在各接口的 data 内返回(无独立 trace 字段)。

实时刷新(现状 🟢 轮询):当前未提供 SSE;客户端按统一方案 §17.3 兜底用轮询刷新:

  • 运行中:每 3–5 秒 GET .../workflow(或 .../timeline);
  • 终态:降到 15–30 秒或停止。
  • 现在不要订阅 .../events/stream(未提供,会 404)。

实时流(目标 🔴,对齐 spec §5):上线后 HM 提供 GET /api/heicode/sub-agile/tasks/{id}/events/stream(SSE),把 AM 回调实时转发给客户端,只推运行信息(不推产物文件)。统一事件信封:

{ "event_type":"agent.action", "deployment_id":"dep_xxx", "agent_id":"agi_x",
  "phase":"development", "occurred_at":"2026-06-03T...", "payload":{ "...": "..." } }

事件类型(最小集):agent.action(某 agent 现在在干啥)、tool.call(调了什么工具)、phase.changed(阶段切换)、log.line(日志行,分 user/debug)、delivery.pushed(产物就绪通知,payload 带 git_ref,不是文件)、status.changed(display_status 变化)、approval.required(出现待审批)。

  • 断线重连:用 Last-Event-ID(基于 HM 事件游标)续传。
  • 降级:SSE 不可用自动回落轮询,UI 行为一致(只是延迟);未上线前 /events/stream 返回未实现,客户端按 capabilities/探测决定走哪条,别硬连。

5. 产物(代码只在 git;artifacts 仅非代码运行信息)

前提:sub 模式强制绑定 git 才能用(未绑 git 只能本地跑,进不了 sub)。所以代码产物的唯一归宿就是用户自己绑定的 git 仓库。没有"下载产物"这回事(project_folder/manifest/files/archive zip 全部退役,见 5.4)。

5.1 代码产物 = git 仓库(唯一路径)🟡

display_status=completed 后,客户端直接对用户自己绑定的仓库(§8 资源绑定里的 git 类型)做 git clone / git pull,拿到完整工程 + 提交历史 + diff。本地改、重做、合并、部署都在工作副本上走标准 git,不经 HM——HM 不托管、不解析、不打包项目代码。

状态:AM 真正"git 入库 + 多 agent 分支 + 合并"为 🔴 待建;当前过渡实现见 spec §3.5。

5.2 交付引用 git_ref:客户端怎么知道去哪 pull 🔴

客户端不需要自己猜分支——HM 在任务详情 / workflow 里回带一个 git_ref,指明交付落在哪个仓库/分支/commit;客户端据此 pull:

"git_ref": {
  "provider": "github",
  "repo_url": "https://github.com/owner/repo",
  "branch": "delivery/dep_b5fab27e9255",      // 交付分支(或 PR 源分支)
  "commit_sha": "a1b2c3d…",                    // 本轮交付的提交
  "tag": "delivery-dep_b5fab27e9255-rev2",     // 可选:版本标签,便于回溯/指定版本部署
  "pull_request_url": "https://github.com/owner/repo/pull/12",  // 若走 PR 模式
  "agent_branches": [                            // 可选:各 agent 的分支,便于看单角色 diff
    {"role":"backend","branch":"agent/backend"},
    {"role":"frontend","branch":"agent/frontend"}
  ]
}
  • git_ref 出现 = 本轮已 push 到用户仓库(配合 display_status=completed)。客户端 git fetch && git checkout <branch>(或 pull)即可。
  • 重做/续跑会更新 commit_sha(及可能新的 branch/tag);客户端 pull 最新即可。
  • HM 只记录并回带这个引用,自己不执行任何 git 操作(git 由 AM 用注入的短期 PAT 执行,见 spec §7)。
  • 状态:🔴 待建——需 AM 回调带 git_ref、HM 在 workflow/详情透出。当前过渡期 AM 还回 blob artifact(见 5.4)。

5.3 非代码产物 = artifacts 接口(运行信息,非下载交付物)🟡

agent_management 跑出的非代码东西(如 test_report 测试报告、summary 摘要、说明),通过 artifacts 列表给客户端在 work 视图里查看,不是可下载的工程产物:

方法 路径 说明
GET .../tasks/{task_id}/artifacts 非代码产物列表(test_report / summary 等运行信息记录)
GET .../artifacts/{artifact_id}/content 单条记录正文(如测试报告全文)

test_report 只是给客户端/用户看,不参与 HM 的 display_status 裁决(HM 不读代码、不判对错,见 §4 / spec §6.6)。

5.4 遗留接口(已退役,新集成勿用)

早期「无 git 流程」里 runtime 只吐一坨 markdown 文本,HM 现解析成项目文件树(project_folder / manifest / files?path= / archive / revisions / local-edits)供浏览、下载、回传。sub 强制 git 后这套全部退役:看代码=git 工作副本,回传改动=git commit/push。后端实现暂保留(向后兼容),但新集成不要依赖,也不要再用 is_project / display_artifact_type:"project_folder" 判交付——交付以 display_status=completed(§4)+ git_ref 有新 commit 为准。

6. 修改 / 重做(基线 = git)🟡🔴

唯一基线 = 用户仓库的最新提交。不存在 HM 侧 local-edits/revision 回传机制(已退役)。

动作 接口 谁干 状态
续跑/改(路径 A,回云端) POST .../tasks/{id}/messages(追加要求) AM 先 git pull 取最新提交作基线 → 在其上改 → push;HM 转发 🟡 HM 转发已通;AM 中途续跑 🔴
重做 POST .../tasks/{id}/execute(或将来 /redo) AM 在新分支重新生成(旧交付分支保留可对比),回带新 git_ref 🔴 待 AM 支持 redo 语义
本地改(路径 B,回本地模式) 客户端 git pull → 本地 agent 改 → git push 客户端(模型仍走 HM /v1/*);想让云端接力就 push 后再 /messages,AM pull 自然拿到 🟡
停止 POST .../tasks/{id}/stop / DELETE .../tasks/{id} 已 commit 的代码保留在分支不回滚,任务标 stopped;可在该分支续跑或丢弃 🟢/🟡

/messages body:{"message":"继续把测试补上","role":"user"}。/execute body 可空。

7. 部署(✅ 客户端执行 + 用户必须确认;HM 只发凭据)

⚠️ 流程已改(对齐 spec §3.8):HM 不部署、不连 VM、不执行命令。部署由客户端在用户机器上执行(客户端是 Claude-Code 式程序),且必须用户显式确认。HM 的角色仅是:把绑定的凭据从 Key Vault 解出 → 经 V2 加密通道安全发给客户端 → 记审计。下面这套「Manager 代部署/Deploy Worker」是旧模型,已废弃。

新流程:

  1. 用户先在 HM 绑定 git/vm/db/blob 资源(§8),拿到 resource_binding_id(凭据已进 Key Vault,只留 secret_ref)。
  2. 客户端发起部署 → 弹窗让用户确认(目标 VM / 环境 / 用哪条 binding / 影响范围)。
  3. 用户确认 → 客户端向 HM 的凭据租约接口(V2 加密)凭 resource_binding_id 换取短期凭据租约(经加密通道返回,带 TTL + 审计)。
  4. 客户端在用户机器上执行:git pull 用户仓库 → ssh 到 VM → 跑部署命令 → 在 VM 上看日志。全程 HM 不碰 VM。

凭据租约接口(🔴 待建,对齐 spec §3.8/§4.5):

POST /api/heicode/resources/{binding_id}/lease(V2 加密 + 设备签名)

请求:{ "purpose":"deploy", "target":"vm:rb_vm_xxx", "task_id":"dep_xxx", "ttl_seconds":600 }

响应:

{ "success": true, "data": {
  "lease_id": "lease_xxx",
  "binding_id": "rb_vm_xxx",
  "credential": { "type":"ssh_key", "username":"deploy", "private_key":"<经 V2 通道明文,仅本次>" },
  "expires_at": "2026-06-03T...Z",        // 短 TTL
  "revocable": true
}}
  • 凭据只在本次响应内经 V2 加密通道下发,客户端用完即弃、不落盘、不进日志(§10)。
  • 高危目标(如生产 VM):HM 先建一条审批(display_status=waiting_approval / §3.2),审批通过后才发租约。
  • 吊销:DELETE /api/heicode/resources/leases/{lease_id},或用户删 binding → 已发租约到期自然失效。
  • HM 只发租约 + 记审计(谁/哪条 binding/用途/时间/TTL,明文不入审计),不代执行部署。

旧的 /deployment-targets、POST .../deployments(executor:pending_worker)已废弃,不再作为部署路径。

8. 资源绑定(git/vm/db/blob → Key Vault)

用户先把自己的资源绑定到 HM,凭据进 Azure Key Vault,库里只留 secret_ref;任务/部署只引用 resource_binding_id,绝不传明文凭据。详见 spec §4。

5 种类型:git(github/gitea,用 provider 区分,即用户自己的仓库 URL + PAT)、vm(ssh)、database、blob。git 仓库是产物归宿(agent 在此 commit/合并,客户端 clone/pull)。

8.1 网页控制台接口(🟢 已用,UserAuth 会话鉴权)

Manager 网页控制台「资源绑定」页已在用:

方法 路径 说明
GET /api/resources/?status=active 列出已绑资源
POST /api/resources/ 建绑定(非密字段进 metadata,不含凭据)
POST /api/resources/{id}/secret 写凭据 → Key Vault,返回 secret_ref
DELETE /api/resources/{id} 解绑(吊销)

建绑定示例(github):

{ "name":"my-repo", "resource_type":"git", "provider":"github",
  "external_id":"https://github.com/owner/repo",
  "metadata":{ "repo_url":"https://github.com/owner/repo", "default_branch":"main",
    "api_base":null,                  // gitea 自建需填 API 地址
    "mode":"existing",               // greenfield | existing
    "allowed_paths":["backend/","frontend/"],
    "permission_scope":"repo:write" } }

→ 再 POST /{id}/secret {"data":{"token":"ghp_..."}}(PAT 进 KV,库里只留 secret_ref)。

  • provider 由 repo_url 推断:github.com → github API;其他 → gitea(需 api_base)。
  • 凭据有效性预检:HM 在用前对 git binding 做一次 GET repo 预检;失效则标 status=invalid,建任务/部署时报 RESOURCE_BINDING_INVALID,提示用户重新绑定,不静默失败。
  • vm:{resource_type:"vm",metadata:{host,port,user,auth:"ssh_key|password"}};database:{engine,host,port,db};blob:{account,container}。secret 一律走 /{id}/secret 进 KV。

8.2 客户端接口(🔴 待建,V2 设备签名)

桌面客户端不走会话 cookie,需要一套 V2 设备签名版资源接口(与任务接口同一套加密/签名,§1):

方法 路径 说明 状态
GET /api/heicode/resources?type=git&status=active 列已绑资源 → 让用户/任务选 resource_binding_id 🔴
GET /api/heicode/resources/{id} 单条详情(非密元数据 + status) 🔴
POST /api/heicode/resources + /{id}/secret 客户端内直接绑定(经 V2 加密传凭据) 🔴
DELETE /api/heicode/resources/{id} 解绑 🔴
POST /api/heicode/resources/{id}/lease 取短期凭据租约(部署用,见 §7) 🔴

这两层(网页 8.1 / 客户端 8.2)操作的是同一份绑定数据,只是鉴权方式不同。8.2 上线后客户端即可"列绑定 → 建任务时引用 → 部署时取租约"全闭环。当前客户端可先用 8.1 的会话路径联调,待 8.2 就绪切换。

9. Runtime 回调(仅 Runtime 用,客户端无需关心)

agent_management → HM 统一回调:POST /api/agent/callbacks/runtime-events。 Schema 查询:GET /api/agent/callbacks/runtime-events/schema。

10. 客户端生产约束

  • 审批 approve/reject 必须调 HM,禁止本地伪造。
  • 生产包禁用 mock 任务/审批/产物。
  • 用 HM 的 display_status 判进度/有无产物;代码对错客户端自己跑/测 + 用户 review(见 §4)。
  • 部署只在用户确认后由客户端本地执行;凭据凭 resource_binding_id 向 HM 取(§7),不本地存明文凭据。
  • 普通用户文案不出现 newapi、上游厂商、模型网关字眼。
  • 任务接口认证:写请求用 V2 加密 body + 设备签名,GET 用 V2 无 body 设备签名(见 §1),均复用模型调用同一套实现;base_url 来自 preset。

11. 错误码(新增)

code 场景 retryable
SUB_GIT_BINDING_REQUIRED 🔴 sub 建任务未带(或失效的)resource_bindings.git——强制绑 git(§3.1) false
RESOURCE_BINDING_INVALID resource_binding_id 不存在/非本人/预检失效(提示重新绑定,§8.1) false
LEASE_EXPIRED 🔴 凭据租约已过期(重新取,§7) true
LEASE_REVOKED 🔴 租约已被吊销/binding 已删 false
APPROVAL_REQUIRED 🔴 高危部署需先过审批(waiting_approval,§3.2/§7) false
BUDGET_EXCEEDED 🔴 任务超 token/时长/成本上限,已暂停待用户决定(spec §9.3) false
DEPLOY_TARGET_DISABLED 目标未启用 false
ARTIFACT_REVISION_CONFLICT / ARTIFACT_ARCHIVE_NOT_READY / ARTIFACT_ARCHIVE_FAILED / FILE_NOT_FOUND / FILE_PATH_REQUIRED 遗留(local-edits/archive/files 已退役,见 §5.4/§6) —

其余错误码沿用旧文档 §13。所有错误统一形如 {"success":false,"error":{"code","message","retryable"}},可读 error.retryable 决定是否重试。

12. 完整接口清单(按流程,覆盖核查)

以真实路由为准(router/api-router.go)。sub-agile 路径把前缀换 swarm 即同形。状态:🟢 已实现 / 🟡 部分 / 🔴 待建。

① 启动与就绪(§2)

接口 状态 章节
GET /api/heicode/capabilities 🟢 §2
GET /api/user/self、/self/groups、/self/models 🟢 §2.2
sub 可用性组合判断(客户端本地) 🟡 §2.1
设备绑定 / 登录(/api/heicode-auth/*、/api/user/...) 🟢 见 heicode-auth 文档

② 建任务与对话(§3)

接口 状态
POST /api/heicode/sub-agile/tasks(需求包,含 resource_bindings、X-Idempotency-Key) 🟢 建任务 / 🔴 强制 git 校验 + 幂等
GET .../tasks、GET .../tasks/{id} 🟢
POST .../tasks/{id}/messages、.../execute 🟢
POST .../tasks/{id}/stop、DELETE .../tasks/{id} 🟢

③ 运行监控 / work 视图(§4)

接口 状态
GET .../tasks/{id}/workflow(含 git_ref、per-agent 富字段) 🟢 本体 / 🔴 git_ref + per-agent 字段
GET .../tasks/{id}/logs、/timeline、/events、/metrics、/diagnostics、/sk-snapshots 🟢
GET .../tasks/{id}/events/stream(SSE) 🔴 §4b

④ 审批(§3.2)

接口 状态
GET .../tasks/{id}/approvals?status=pending 🟢
POST .../approvals/{approval_id}/approve、/reject 🟢

⑤ 产物(§5)

接口 状态
git_ref(在 workflow/详情里)→ 客户端 git clone/pull 🔴
GET .../tasks/{id}/artifacts、.../artifacts/{aid}/content(仅非代码运行信息) 🟢
.../artifacts/{aid}/{manifest,files,archive,revisions,local-edits} 退役(§5.4)

⑥ 修改 / 重做(§6):复用 ②的 messages/execute(+ 将来 /redo 🔴);本地改走 git。

⑦ 部署(§7)

接口 状态
POST /api/heicode/resources/{id}/lease(短期凭据租约) 🔴
DELETE /api/heicode/resources/leases/{lease_id}(吊销) 🔴
GET /api/heicode/deployment-targets、POST/GET .../tasks/{id}/deployments 废弃(旧代部署)

⑧ 资源绑定(§8)

接口 状态
GET/POST /api/resources/、POST /{id}/secret、PUT/DELETE /{id}(会话鉴权,网页台) 🟢 §8.1
GET/POST/DELETE /api/heicode/resources*、/{id}/lease(V2 设备签名,客户端) 🔴 §8.2

凡标 🔴 的,客户端按本文契约预埋字段即可;HM 侧补齐后无需改协议直接对齐。本清单即"整个流程要用到的接口"的核查表——发现遗漏请回填本表对应分组。