Files
heicode/docs/integration/heicode-desktop-subagile-e2e-demo.md
T
chenchenandClaude Opus 4.8 78048858b9 docs(heicode): add sub-agile end-to-end demo walkthrough for client cross-check
Step-by-step walkthrough of a real client-simulated run (task dep_39e53ee4c692)
with actual request/response at each stage: create -> poll workflow -> artifacts
-> manifest -> files -> archive. Confirms agent_management delivers real code
files + nested folders (backend/main.py, backend/models.py) surfaced as a
project_folder. Includes a client self-check list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 16:47:53 +08:00

9.0 KiB
Raw Blame History

Heicode 桌面客户端 ↔ Manager Sub Agile 端到端联调演练(真实数据)

更新时间:2026-06-02 环境:Heicode Manager(生产同构 VM)→ agent_management(Sub Agile Runtime) 用途:给桌面客户端团队逐步对照接入实现。本文每一步都是一次真实跑出来的请求 + 真实响应(任务 dep_39e53ee4c692,模型 gpt-5.4)。 配套:接口细节见同目录 heicode-desktop-unified-api.md。

本演练验证的核心结论:Sub Agile 任务跑完后,agent_management 产出的是真实代码文件 + 目录结构,Manager 解析成 project_folder,客户端可拿到「文件树 / 单文件正文 / 整包 zip」,zip 解压即真实文件夹。


0. 角色与链路

桌面客户端  ──(只调 Manager)──>  Heicode Manager  ──(归口)──>  agent_management(Sub Agile Runtime)
  • 客户端只调 https://code.xinghanlab.com/api/heicode/sub-agile/*,不直连 Runtime。
  • Manager 是唯一状态裁判:客户端只看 display_status。
  • 认证:与模型调用同一套(写请求 V2 加密 body + 设备签名;GET 无 body 设备签名)。详见统一文档 §1。本演练为聚焦业务流程,示例用已登录态表示,不展开加密细节。

1. 创建任务(提交需求包)

客户端提交需求包(不是 Runtime 原始参数),Manager 翻译成编排计划并创建。

请求

POST /api/heicode/sub-agile/tasks
Content-Type: application/json
{
  "mode": "sub_agile",
  "requirement": {
    "objective": "做一个前后端分离的 Todo 应用。后端放在 backend/ 目录:backend/main.py (FastAPI, 提供 /todos 增删查) 和 backend/models.py (Todo 数据模型)。前端放在 frontend/ 目录:frontend/src/App.jsx 和 frontend/package.json。根目录加 README.md。每个文件用对应语言代码块, 文件名写在代码块第一行注释里。"
  },
  "model_selection": { "type": "single", "default_model": "gpt-5.4" },
  "roles": ["backend"]
}

响应(真实)

{ "success": true, "data": {
  "deployment_id": "dep_39e53ee4c692",
  "sub_mode": "agile",
  "mode": "sub_agile",
  "status": "accepted",
  "display_status": "accepted",
  "runtime_state": "runtime_syncing",
  "agent_instances": [ { "instance_id": "agi_...", "role": "backend", "phase": "pending" } ]
}}

要点:

  • deployment_id 就是后续所有接口的 {task_id}(task_id ≡ deployment_id)。
  • 客户端本地保存:deployment_id / mode / display_status,以便重启后恢复。
  • roles 决定起几个 agent / 出哪些目录:本例只起了 backend,所以只产出 backend/ 下文件。要前后端并列目录,传 ["backend","frontend"]。

2. 轮询工作流,直到终态

请求

GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/workflow

运行中每 3–5 秒轮询一次,终态后停止。本次真实轨迹:

poll 1: display_status = accepted
poll 2: display_status = running
poll 3: display_status = completed   <- 终态

workflow 响应(真实,节选)

{ "success": true, "data": {
  "task_id": "dep_39e53ee4c692",
  "mode": "sub_agile",
  "sub_mode": "agile",
  "display_status": "completed",
  "cloud_deployment_status": "completed",
  "runtime_execution_status": "completed",
  "phase": "development",
  "phases": [ { "phase_id": "development", "name": "development", "status": "completed", "agents": ["backend"] } ],
  "agent_count": 1,
  "agents": [ { "agent_id": "agi_...", "role": "backend", "status": "completed",
               "tokens": 0, "tools": 0, "elapsed_seconds": 0, "artifact_ids": ["art_swm_826fe9814483_backend_1"] } ],
  "metrics": { "tokens_used": 618, "tools": 0, "elapsed_seconds": 33, "total_messages": 2 },
  "artifact_ids": ["art_swm_826fe9814483_backend_1"]
}}

客户端判定规则:

  • 只看 display_status。completed = 完成且有有效交付物;needs_codegen / completed_without_deliverable = 没有效产物,别当成功。
  • per-agent 的 tokens/tools 当前为 0(agent_management 暂未上报 per-agent 指标,顶层 metrics 是真实值)。

3. 取产物列表(确认是项目而非文本)

请求

GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts

响应(真实,节选)

{ "success": true, "data": { "items": [
  {
    "artifact_id": "art_swm_826fe9814483_backend_1",
    "artifact_type": "code_patch",
    "is_project": true,
    "display_artifact_type": "project_folder",
    "manifest_path": ".../artifacts/art_swm_826fe9814483_backend_1/manifest",
    "files_path":    ".../artifacts/art_swm_826fe9814483_backend_1/files",
    "archive_path":  ".../artifacts/art_swm_826fe9814483_backend_1/archive"
  }
] }}

要点:主产物类型看 display_artifact_type。即使 Runtime 原始 artifact_type=code_patch,Manager 归一化为 project_folder 且 is_project=true,并直接给出 manifest/files/archive 子路径,客户端不用自己猜。


4. 取文件树(manifest,含目录层级)

请求

GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/manifest

响应(真实)

{ "success": true, "data": {
  "artifact_id": "art_swm_826fe9814483_backend_1",
  "artifact_type": "project_folder",
  "root_dir": "project",
  "file_count": 2,
  "entries": [
    { "path": "backend/models.py", "type": "file", "mime_type": "text/x-python", "size_bytes": 228,
      "content_path": ".../files?path=backend%2Fmodels.py" },
    { "path": "backend/main.py",   "type": "file", "mime_type": "text/x-python", "size_bytes": 927,
      "content_path": ".../files?path=backend%2Fmain.py" }
  ],
  "archive": { "format": "zip", "download_path": ".../archive" }
}}

要点:entries[].path 带真实目录层级(backend/main.py)。客户端用 content_path(已是 ?path= URL 编码)直接取单文件,无需自己拼路径。


5. 取单文件正文(确认是真代码)

请求

GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/files?path=backend%2Fmain.py

响应(真实,节选)

# backend/main.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from .models import Todo, TodoCreate

app = FastAPI(title="Todo API")
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True,
                   allow_methods=["*"], allow_headers=["*"])

todos: list[Todo] = []
next_id = 1

@app.get("/todos", response_model=list[Todo])
def list_todos():
    ...

6. 下载整包 zip(确认解压是真实文件夹)

请求

GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/archive

响应头(真实)

HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="art_swm_826fe9814483_backend_1.zip"
Content-Length: 896

解压后真实落盘结构

project/
└── backend/
    ├── main.py
    └── models.py

客户端下载契约(务必遵守):

  • 读 Content-Disposition 文件名、按 Content-Length 校验后再落盘,保存成功才提示「已下载」。
  • 产物未就绪时返回 {"success":false,"error":{"code":"ARTIFACT_ARCHIVE_NOT_READY","retryable":true}},此时不要提示已下载。

7. 客户端核对清单(照此自检即三端对齐)

  • 创建任务用需求包(requirement.objective + model_selection + roles),从响应拿 deployment_id(=task_id)。
  • 运行中每 3–5 秒 GET .../workflow,只读 display_status 判断完成;不订阅 /events/stream(未提供)。
  • 列表/详情/workflow 都读顶层 mode(sub_agile|swarm)做模式标签与路由,重启后用它恢复。
  • 产物以 display_artifact_type=project_folder / is_project=true 为准,走 manifest → files?path= → archive。
  • files?path= 用 manifest 给的 content_path(已 URL 编码),支持 backend/main.py 这种嵌套路径。
  • archive 按响应头校验落盘;ARTIFACT_ARCHIVE_NOT_READY 时重试不报「已下载」。
  • 终态成功判据:display_status=completed 且 artifacts 非空(is_project=true)。

附:已知由 Runtime(agent_management)决定、非 Manager 缺陷的点

  • 目录范围由 roles 决定:只传 ["backend"] 就只出 backend/;要 frontend/ 等并列目录,传对应角色。
  • per-agent tokens/tools/elapsed_seconds:待 agent_management 在状态里上报 per-agent 指标,未上报时为 0(顶层 metrics 为真实值)。
  • artifact 归属 agent:依赖 Runtime 在 artifact metadata 标 source_agent_role,未标时 per-agent artifact_ids 可能为空。
  • 阶段细分 phases[]:Runtime 现仅上报单个 phase,故默认是「当前阶段」一条;待上报阶段历史后展开。