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>
9.0 KiB
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-agentartifact_ids可能为空。 - 阶段细分
phases[]:Runtime 现仅上报单个phase,故默认是「当前阶段」一条;待上报阶段历史后展开。