# Heicode 桌面客户端 sub 敏捷流程 API 对接文档 更新时间:2026-05-28 适用范围:Heicode Desktop / 本地服务对接 Heicode Manager,跑通普通 sub 模式敏捷开发流程。 Manager 生产地址:`https://code.xinghanlab.com` ## 1. 对接目标 桌面客户端负责用户主体验:输入想法、回答追问、持续推进任务、查看子环节反馈、处理高危审批、接收交付结果。 Manager 负责辅助控制面:任务草稿桥接、资源/权限、Agnet deployment、状态/timeline/artifact/SK 查询、审批记录和短期凭证 lease。 本文只描述普通 sub 敏捷流程,不包含蜂群 task graph、claim、heartbeat、handoff 等蜂群模式能力。 ## 2. 认证与公共约定 ### 2.1 API 分组 | API 前缀 | 用途 | 认证 | |---|---|---| | `/api/heicode-auth/api/user/tasks/*` | HeicodeTask 任务编排代理,创建任务、追问、查询任务 | V2 加密 body + `Authorization: Bearer ` | | `/api/agnet/user/*` | Manager 用户态 Agnet 控制面,deployment、timeline、artifact、审批 | V2 加密 body;未加密 Web 控制台请求继续使用 Manager session + `New-Api-User` | | `/api/swarms` | 蜂群模式创建入口 / Runtime adapter 入口 | V2 加密 body;未加密 Web 控制台请求继续使用 Manager session + `New-Api-User` | | `/api/user/self` | 查询当前 Manager 用户 | Manager 登录 session cookie | ### 2.2 桌面端请求 body 加密 桌面客户端调用 Manager 的 sub / 蜂群入口时,应使用与模型调用一致的 V2 加密请求协议。普通 sub 用户态接口在生产 Manager `1.4.7+` 已支持;`POST /api/swarms` 蜂群入口在本次 Manager 代码中补齐同一套 V2 body 加密鉴权,需随下一次生产部署生效。 适用接口: | API 前缀 | V2 加密 body | 说明 | |---|---|---| | `/api/agnet/user/*` | 支持 | Manager 解密并校验设备签名后,按当前设备对应用户执行 | | `/api/swarms` | 支持 | Manager 解密并校验设备签名后,按当前设备对应用户创建蜂群/Runtime adapter deployment | | `/api/heicode-auth/*` | 支持 | Manager 解密并校验设备签名后,把明文 body 代理给上游 HeicodeTask 服务;仍需携带 `heicode_access_token` | | 浏览器后台普通页面请求 | 兼容未加密 JSON | 不影响现有 Manager Web 控制台 | V2 请求头与模型调用一致: ```http Content-Encoding: heicode-aead-v1 X-Heicode-Device-Id: X-Heicode-Timestamp: X-Heicode-Nonce: X-Heicode-Fingerprint: X-Heicode-Eph-Pubkey: X-Heicode-Signature: X-Heicode-Client-Version: Content-Type: application/json Accept: application/json ``` 加密和签名协议沿用模型调用: ```text body = nonce || ChaCha20-Poly1305(plaintext_json, aad) aad = device_id + "|" + timestamp + "|" + nonce + "|" + method + "|" + path_with_query canonical = method + "\n" + path_with_query + "\n" + timestamp_ms + "\n" + nonce_hex + "\n" + device_fingerprint + "\n" + ephemeral_pubkey_b64 + "\n" + sha256_hex(plaintext_body) signature = base64(ed25519_sign(device_private_key, sha256(canonical))) ``` `/api/heicode-auth/*` 额外要求: ```http Authorization: Bearer ``` 原因:该 token 是上游 HeicodeTask 服务认证用;V2 设备签名只证明请求来自已配对的 Manager 桌面设备。 客户端实现要求: 1. sub 流程调用不要新增一套加密协议,直接复用模型调用的 `encryptedFetch` / V2 设备签名实现。 2. `aad` 和 `canonical` 中的 `path_with_query` 必须是 Manager 实际收到的 path,例如 `/api/agnet/user/tasks/task-1/deployment-draft`,不能把 origin 写进去。 3. 加密前的 plaintext 必须是最终 JSON body;签名里的 `sha256_hex(plaintext_body)` 必须和该 JSON 字节完全一致。 4. 每次请求必须使用新的 `X-Heicode-Nonce` 和新的 X25519 ephemeral key。 5. V2 请求失败时优先读取 `X-Heicode-Auth-Error` 和 `X-Heicode-Server-Time`,用于提示设备未配对、时间漂移、nonce 重放、签名错误或解密失败。 ### 2.3 Manager 用户态 Header 未加密 Web 控制台请求调用 `/api/agnet/user/*` 或 `/api/swarms` 时必须带: ```http Cookie: session= New-Api-User: Content-Type: application/json Accept: application/json ``` `New-Api-User` 必须等于当前登录用户 ID,否则会返回未授权。 使用 V2 加密 body 时,`/api/agnet/user/*` 和 `/api/swarms` 不依赖浏览器 session cookie,也不需要 `New-Api-User`;Manager 会从设备绑定 token 中解析用户身份。为兼容当前 Web 控制台,未加密请求仍按 session cookie + `New-Api-User` 处理。 ### 2.4 蜂群入口加密边界 蜂群模式的业务流程与普通 sub 敏捷流程分开对接,但客户端到 Manager 的请求加密规则一致。 | 接口 | 所属模式 | 加密要求 | |---|---|---| | `POST /api/agnet/user/tasks/{task_id}/deployment-draft` | 普通 sub 敏捷 | V2 body 加密 | | `POST /api/agnet/user/deployments` | 普通 sub 敏捷 | V2 body 加密 | | `POST /api/swarms` | 蜂群模式 | V2 body 加密 | 注意:本文后续章节仍只描述普通 sub 敏捷主流程;蜂群 task graph、claim、heartbeat、handoff、approval decision 等字段以单独蜂群对接文档为准。 ### 2.5 统一响应 Envelope 成功: ```json { "success": true, "message": "", "data": {} } ``` 失败: ```json { "success": false, "message": "human readable message", "error": { "code": "ERROR_CODE", "message": "human readable message" } } ``` ## 3. 推荐完整流程 ```text 1. 桌面端确认 Manager 登录态,获取 /api/user/self 2. 创建 HeicodeTask:POST /api/heicode-auth/api/user/tasks/intent 3. 如果 status=configuring,回答追问:POST /api/heicode-auth/api/user/tasks/{task_id}/answer 4. 当任务卡生成后,创建 deployment draft:POST /api/agnet/user/tasks/{task_id}/deployment-draft 5. 创建 Manager deployment:POST /api/agnet/user/deployments 6. 轮询 deployment detail / events / timeline 7. 展示 artifacts / sk-snapshots / logs / metrics 8. 如出现 approval,桌面端展示审批并调用 approve/reject 9. 完成后继续迭代或停止 deployment ``` ### 3.1 2026-05-28 生产验证结果 本节记录已经按“桌面客户端应调用的顺序”在生产环境跑过的结果,客户端可按同一顺序和参数形状对接。 生产环境: | 项 | 值 | |---|---| | Manager | `https://code.xinghanlab.com` | | Manager 版本 | `1.4.19` | | Agent Manager Runtime | `http://20.212.121.126` | | Runtime health | `healthy` | | Manager callback | `https://code.xinghanlab.com/api/agnet/callbacks/swarm-events` | 已验证成功的链路: ```text Manager 登录 -> /api/user/self -> /api/agnet/runtime/health -> /api/agnet/user/tasks/{task_id}/deployment-draft -> /api/agnet/user/deployments -> Manager 调 Agent Manager Runtime create -> Runtime 自动 callback 到 Manager -> /api/agnet/user/deployments/{deployment_id} -> /api/agnet/user/deployments/{deployment_id}/metrics -> /api/agnet/user/deployments/{deployment_id}/events -> /api/agnet/user/deployments/{deployment_id}/logs -> /api/agnet/user/deployments/{deployment_id}/artifacts -> /api/agnet/user/deployments/{deployment_id}/sk-snapshots -> /api/agnet/user/deployments/{deployment_id}/timeline -> /api/agnet/user/deployments/{deployment_id}/stop ``` 最新生产烟测 ID: | 对象 | ID / 结果 | |---|---| | Manager deployment | `dep_be665a25f6bc` | | Runtime swarm | `swm_4c471d60972f` | | detail status | `completed` | | detail phase | `deploy` | | runtime_state | `completed` | | agent state | `completed` | | callback 数 | `9` | | event 数 | `12` | 已确认事实: - Manager 端普通 sub 控制面已经可创建 deployment、调用 Runtime、接收 callback、反写 deployment 状态、聚合 events/timeline。 - Manager 端 callback 支持 HMAC 和旧 token 两种校验;生产当前 HMAC fallback 和 legacy token 均使用同一个值,由运维私下提供给 Agent Manager,不写入本文。 - Agent Manager / Runtime 仍需补真实 artifact、真实 usage/cost、真实日志、失败原因和高危审批闭环;这些是 Runtime 执行数据质量,不阻塞桌面客户端按本文接口开始联调。 本次未由 Codex 直接跑通的步骤: | 步骤 | 结果 | 原因 | 客户端要求 | |---|---|---|---| | `POST /api/heicode-auth/api/user/tasks/intent` | 401 | Codex 没有桌面客户端持有的 `heicode_access_token` | 客户端必须带 `Authorization: Bearer ` | 说明: - 如果客户端已经有 HeicodeTask snapshot,可以直接从 `deployment-draft` 开始跑,生产已验证可通。 - 如果客户端需要从自然语言创建任务,必须先完成 Heicode 登录并拿到 `heicode_access_token`。 - 当前 create / callback / detail / metrics / events / timeline / stop 已真实有效;artifacts / sk-snapshots 需要 Runtime 在真实任务中回写 `artifact.created` / `sk_tool.*` 后才会有数据。 ### 3.2 桌面客户端联调结论 普通 sub 模式可以开始桌面客户端联调。建议先按 Windows 最新客户端跑通,因为生产已有 Windows 设备绑定记录;macOS 端必须先确认客户端版本和 Keychain 凭据。 | 项 | 当前结论 | 客户端动作 | |---|---|---| | Windows 设备绑定 | 生产已有 `windows` 设备绑定记录 | 可直接按本文流程联调 | | macOS 设备绑定 | 生产库当前没有 `darwin/macOS` 设备绑定记录 | 升级到最新 macOS 包,清理 Keychain 中旧 Heicode 凭据后重新登录 | | 用户模型列表 | Manager 端真实 token 请求 `/v1/models` 正常 | 如果桌面端 401,优先排查本地 token / device pair,不要先改模型配置 | | 普通 sub POST 请求 | Manager 支持 V2 body 加密 | 复用模型调用的 `encryptedFetch` | | 普通 sub GET 查询 | 当前仍建议使用 session + `New-Api-User` 兼容路径 | 后续如需完全无 cookie,再补无 body 签名 GET 协议 | ## 4. 当前用户信息 ### `GET /api/user/self` 获取当前 Manager 登录用户,用于拿 `id` 并设置 `New-Api-User`。 响应关键字段: ```json { "success": true, "data": { "id": 22, "username": "chenchen", "email": "", "group": "default", "role": 1, "status": 1 } } ``` 客户端处理: - 保存 `data.id`。 - 后续 `/api/agnet/user/*` 请求带 `New-Api-User: `。 ## 5. HeicodeTask 任务编排 这些接口通过 Manager 同源代理访问 mcp-server: ```text Base: /api/heicode-auth ``` ### 5.1 创建任务 #### `POST /api/heicode-auth/api/user/tasks/intent` 描述用户想做什么,创建 HeicodeTask。 请求头必须包含桌面客户端登录后持有的 Heicode access token: ```http Authorization: Bearer Content-Type: application/json Accept: application/json ``` 请求: ```json { "intent": "做一个客户工单管理系统,支持登录、工单列表、状态流转和后台统计", "name": "客户工单管理系统" } ``` 字段: | 字段 | 类型 | 必需 | 说明 | |---|---|---:|---| | `intent` | string | 是 | 用户自然语言目标 | | `name` | string | 否 | 任务名称,不传则由服务端生成 | 响应: ```json { "success": true, "data": { "id": "task_abc123", "user_id": "22", "name": "客户工单管理系统", "status": "configuring", "status_caption": "需要补充几个问题", "intent": "做一个客户工单管理系统...", "thread": [ { "kind": "user", "text": "做一个客户工单管理系统...", "at": 1779850000000 }, { "kind": "heicode", "text": "请选择第一版范围", "at": 1779850001000, "followups": [ { "id": "scope", "question": "第一版优先做什么?", "options": [ { "id": "mvp", "label": "MVP 基础功能" } ] } ] } ], "card": null, "created_at": 1779850000000, "updated_at": 1779850001000 } } ``` ### 5.2 查询任务列表 #### `GET /api/heicode-auth/api/user/tasks?status=running&limit=20&offset=0` 查询当前用户任务。 查询参数: | 参数 | 类型 | 必需 | 说明 | |---|---|---:|---| | `status` | string | 否 | `draft/configuring/running/awaiting_approval/completed/failed/paused` | | `limit` | number | 否 | 默认由服务端决定 | | `offset` | number | 否 | 分页偏移 | 响应: ```json { "success": true, "data": { "items": [], "total": 0, "offset": 0, "limit": 20 } } ``` ### 5.3 查询任务详情 #### `GET /api/heicode-auth/api/user/tasks/{task_id}` 响应同 HeicodeTask。 ### 5.4 回答追问 #### `POST /api/heicode-auth/api/user/tasks/{task_id}/answer` 同样必须携带: ```http Authorization: Bearer ``` 请求: ```json { "question_id": "scope", "option_id": "mvp" } ``` 响应: ```json { "success": true, "data": { "id": "task_abc123", "status": "running", "card": { "goal": "客户工单管理系统第一版", "scope": ["登录", "工单列表", "状态流转"], "generated_artifacts": ["产品说明", "接口草案", "开发任务"], "manager_actions": [ { "label": "绑定 Git", "deeplink": "/sk-sources" } ] } } } ``` 客户端处理: - `status=configuring`:继续展示 `thread[].followups`。 - `status=running` 且 `card` 存在:允许用户创建 Manager deployment。 - `status=awaiting_approval`:轮询审批接口。 - `status=completed/failed/paused`:停止高频轮询。 ## 6. 从任务生成 Agnet Deployment Draft ### `POST /api/agnet/user/tasks/{task_id}/deployment-draft` 把 HeicodeTask 快照转换成 Manager 可创建的 Agnet orchestration plan。 生产已验证:客户端只要能提供 task snapshot,就可以不依赖 Manager 再去拉 task,直接调用本接口生成 draft。 请求: ```json { "task": { "id": "task_abc123", "name": "客户工单管理系统", "intent": "做一个客户工单管理系统...", "status": "running", "card": { "goal": "客户工单管理系统第一版", "scope": ["登录", "工单列表", "状态流转"], "generated_artifacts": ["产品说明", "接口草案", "开发任务"] } }, "sub_mode": "agile", "binding_scope": "task-task_abc123", "role_templates": ["backend", "frontend", "reviewer"], "default_model_id": "agnet-model-builder", "budget": { "max_tokens": 120000, "max_cost_usd": 8, "max_duration_sec": 3600 }, "resource_grants": [] } ``` 生产烟测可用的最小请求形状: ```json { "task": { "id": "task-client-sim-1779875397", "name": "客户端模拟普通 sub 敏捷流程", "intent": "做一个轻量待办系统,包含任务列表、状态流转、基础测试和上线说明", "status": "running", "card": { "goal": "交付轻量待办系统 MVP", "scope": "普通 sub 敏捷流程接口联调", "generated_artifacts": [] } }, "sub_mode": "agile", "risk_level": "low", "budget": { "max_tokens": 20000, "max_cost_usd": 1, "max_duration_sec": 600 }, "binding_scope": "task-client-sim", "role_templates": ["backend"], "default_model_id": "smoke-model", "resource_grants": [ { "grant_id": "grant-client-sim-git", "resource_id": "git-client-sim", "resource_type": "git", "binding_scope": "task-client-sim", "target_role": "backend", "target_agent_ref": "agent-backend-1", "permission_scope": ["repo:read"], "metadata": { "repo_url": "https://example.invalid/heicode/client-sim.git" }, "secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/client-sim-git", "status": "active" } ] } ``` 字段: | 字段 | 类型 | 必需 | 说明 | |---|---|---:|---| | `task.id` | string | 是 | 必须和 URL `{task_id}` 一致 | | `task.name` | string | 否 | 任务名称 | | `task.intent` | string | 否 | 用户原始目标 | | `task.card.goal` | string | 否 | 优先作为 objective | | `sub_mode` | string | 是 | `agile` 或 `waterfall`,桌面客户端默认传 `agile` | | `binding_scope` | string | 否 | 建议 `task-` | | `role_templates` | string[] | 否 | 默认 `["backend"]` | | `default_model_id` | string | 否 | 子 Agnet 默认运行模型 | | `budget` | object | 否 | 不传使用默认预算 | | `resource_grants` | array | 否 | 不传时 Manager 生成只读 task context grant | 响应: ```json { "success": true, "data": { "task_id": "task_abc123", "orchestration_plan": { "intent_id": "task_abc123", "template_hint": "heicode-task", "objective": "客户工单管理系统第一版", "sub_mode": "agile", "risk_level": "low", "budget": { "max_tokens": 120000, "max_cost_usd": 8, "max_duration_sec": 3600 }, "user_context": { "user_id": "22", "role": "user", "channel_id": "default" }, "billing_context": { "provider": "newapi", "newapi_group": "default" }, "agent_runtime": { "platform": "agnet", "agents": [ { "role": "backend", "model_ref": "agnet-model-builder", "instance_count": 1 } ] }, "agents": [ { "role_template": "backend", "goal": "Execute the Heicode task as backend within the approved resource scope.", "default_model_id": "agnet-model-builder", "resource_grants": [] } ], "constraints": { "allowed_model_ids": [] }, "metadata": { "correlation_id": "task-task_abc123-xxxxxxxx" } } } } ``` ## 7. 创建 Manager Deployment ### `POST /api/agnet/user/deployments` 使用上一步 `orchestration_plan` 创建 Manager deployment。 请求: ```json { "orchestration_plan": { "intent_id": "task_abc123", "template_hint": "heicode-task", "objective": "客户工单管理系统第一版", "sub_mode": "agile", "risk_level": "low", "budget": { "max_tokens": 120000, "max_cost_usd": 8, "max_duration_sec": 3600 }, "user_context": { "user_id": "22", "role": "user", "channel_id": "default" }, "billing_context": { "provider": "newapi", "newapi_group": "default" }, "agent_runtime": { "platform": "agnet", "agents": [ { "role": "backend", "model_ref": "agnet-model-builder", "instance_count": 1 } ] }, "agents": [ { "role_template": "backend", "goal": "Execute the Heicode task as backend within the approved resource scope.", "default_model_id": "agnet-model-builder", "resource_grants": [] } ], "constraints": { "allowed_model_ids": [] }, "metadata": { "correlation_id": "task-task_abc123-xxxxxxxx" } } } ``` 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "sub_mode": "agile", "status": "accepted", "phase": "pending", "runtime_state": "queued", "runtime_deployment_id": "", "runtime_swarm_id": "", "failure_reason": "", "agent_instances": [ { "instance_id": "agi_1fddac9cded5", "role": "backend", "phase": "pending", "runtime_state": "queued", "failure_reason": "" } ], "permission_manifest": { "user_id": "22", "binding_scope": "task-task_abc123", "agent_role": "backend", "target_agent_ref": "agent-backend-1", "resource_grants": [] } } } ``` 客户端处理: - 保存 `deployment_id`。 - `runtime_state=queued` 表示 Manager 已建立本地控制面记录。 - 如果生产 Runtime 未配置,deployment 仍可创建,但不会进入真实执行。 ## 8. 查询 Deployment ### 8.1 列表 #### `GET /api/agnet/user/deployments` 响应: ```json { "success": true, "data": { "items": [ { "deployment_id": "dep_464a08b7b751", "sub_mode": "agile", "status": "accepted", "phase": "pending", "runtime_state": "queued", "failure_reason": "", "created_at": "2026-05-27T11:44:30+08:00", "updated_at": "2026-05-27T11:44:30+08:00", "permission_manifest": {}, "orchestration_plan": {} } ] } } ``` ### 8.2 详情 #### `GET /api/agnet/user/deployments/{deployment_id}` 响应字段同列表单项,包含完整 `orchestration_plan`。 ### 8.3 停止 #### `POST /api/agnet/user/deployments/{deployment_id}/stop` 请求: ```json { "reason": "用户停止本轮 sub 敏捷任务" } ``` 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "status": "stopped", "phase": "stopped" } } ``` ## 9. 执行反馈查询 ### 9.1 Events #### `GET /api/agnet/user/deployments/{deployment_id}/events` 用于展示 deployment 事件流。 响应: ```json { "success": true, "data": { "items": [ { "event_id": "evt_xxx", "event": "deployment.accepted", "deployment_id": "dep_464a08b7b751", "occurred_at": "2026-05-27T11:44:30+08:00", "result": "ok" } ] } } ``` ### 9.2 Logs #### `GET /api/agnet/user/deployments/{deployment_id}/logs` 用于展示最近日志。当前 Manager 未接真实 Runtime 时主要是审计日志。 响应: ```json { "success": true, "data": { "items": [ { "timestamp": "2026-05-27T11:44:30+08:00", "level": "info", "message": "deployment accepted", "source": "manager-audit" } ] } } ``` ### 9.3 Metrics #### `GET /api/agnet/user/deployments/{deployment_id}/metrics` 用于展示成本、耗时、token、资源指标。真实 Runtime 未接入时可能为空或为本地占位。 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "runtime_state": "queued", "metrics": {} } } ``` ### 9.4 Artifacts #### `GET /api/agnet/user/deployments/{deployment_id}/artifacts` 查询中间交付物和最终交付物摘要。 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "artifacts": [ { "artifact_id": "art_test_report_001", "artifact_type": "test_report", "title": "测试报告", "summary": "本轮后端接口测试通过", "uri": "artifact://task_abc123/test-report/art_test_report_001", "created_at": 1779850000000 } ], "items": [], "total": 1 } } ``` ### 9.5 SK Snapshots #### `GET /api/agnet/user/deployments/{deployment_id}/sk-snapshots` 查询本轮任务使用的 SK 快照。 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "sk_snapshots": [ { "snapshot_id": "sks_task_abc123_backend_001", "deployment_id": "dep_464a08b7b751", "agent_role": "backend", "source_type": "git", "source_ref": "git:https://example.com/tools.git#main:backend", "content_hash": "sha256:abc123", "tool_name": "repo_write", "created_at": "2026-05-27T11:45:00+08:00", "metadata": { "redacted": true } } ], "items": [], "total": 1 } } ``` ### 9.6 Timeline #### `GET /api/agnet/user/deployments/{deployment_id}/timeline` 聚合审计事件、Runtime callback、artifact、SK snapshot。桌面客户端推荐优先使用这个接口渲染“当前子环节进度”。 响应: ```json { "success": true, "data": { "deployment_id": "dep_464a08b7b751", "deployment": { "deployment_id": "dep_464a08b7b751", "sub_mode": "agile", "status": "accepted", "phase": "pending", "runtime_state": "queued" }, "events": [], "callbacks": [], "artifacts": [], "sk_snapshots": [], "timeline": [ { "kind": "audit", "at": 1779850000000, "event": "deployment.accepted" }, { "kind": "callback", "at": "2026-05-27T11:45:00+08:00", "event": "phase.changed", "event_id": "evt_phase_001", "event_type": "phase.changed" }, { "kind": "artifact", "at": 1779850060000, "event": "test_report", "artifact_id": "art_test_report_001" } ] } } ``` 客户端建议: - 轮询间隔:运行中 3-5 秒;终态 15-30 秒或停止。 - 优先展示 `timeline[]`。 - 如果存在 `artifact`,提供“查看交付物”入口。 - 如果存在 `callback.event_type=approval.requested` 或任务状态 `awaiting_approval`,拉取审批接口。 ## 10. 审批与短期凭证 高危操作审批必须由桌面客户端作为主体验展示。Manager 只提供记录、approve/reject 和 lease。 ### 10.1 查询待审批 #### `GET /api/agnet/approvals?status=pending&deployment_id={deployment_id}` 查询参数: | 参数 | 类型 | 必需 | 说明 | |---|---|---:|---| | `status` | string | 否 | `pending/approved/rejected/expired` | | `deployment_id` | string | 否 | 按 deployment 过滤 | 响应: ```json { "success": true, "data": { "items": [ { "approval_id": "appr_xxx", "user_id": 22, "deployment_id": "dep_464a08b7b751", "binding_scope": "task-task_abc123", "operation": "git.write", "resource_id": "res_git_main", "resource_type": "git", "resource_scope": "feature/*", "target_role": "backend", "risk_level": "high", "requires_credential": true, "credential_lease_id": "", "status": "pending", "requested_by": "agnet-runtime", "request_reason": "需要写入功能分支", "ttl_seconds": 900, "expires_at": 1779850900000, "created_at": 1779850000000 } ] } } ``` ### 10.2 同意审批 #### `POST /api/agnet/approvals/{approval_id}/approve` 请求: ```json { "reason": "用户确认允许本轮任务写入功能分支" } ``` 响应: ```json { "success": true, "data": { "approval_id": "appr_xxx", "status": "approved", "credential_lease_id": "lease_xxx", "credential_lease": { "lease_id": "lease_xxx", "credential_ref": "lease://agnet/lease_xxx", "status": "active", "expires_at": 1779850900000 } } } ``` 注意:响应只会返回 `lease://...` 引用,不返回明文凭证。 ### 10.3 拒绝审批 #### `POST /api/agnet/approvals/{approval_id}/reject` 请求: ```json { "reason": "用户拒绝生产环境写入" } ``` 响应: ```json { "success": true, "data": { "approval_id": "appr_xxx", "status": "rejected", "decision_reason": "用户拒绝生产环境写入" } } ``` ### 10.4 查询 lease #### `GET /api/agnet/credential-leases?status=active&deployment_id={deployment_id}` 响应: ```json { "success": true, "data": { "items": [ { "lease_id": "lease_xxx", "credential_ref": "lease://agnet/lease_xxx", "approval_id": "appr_xxx", "deployment_id": "dep_464a08b7b751", "resource_id": "res_git_main", "resource_type": "git", "target_role": "backend", "status": "active", "expires_at": 1779850900000 } ] } } ``` ### 10.5 撤销 lease #### `POST /api/agnet/credential-leases/{lease_id}/revoke` 请求: ```json { "reason": "用户停止任务" } ``` 响应: ```json { "success": true, "data": { "lease_id": "lease_xxx", "status": "revoked" } } ``` ## 11. 角色模板 ### `GET /api/agnet/role-templates` 获取推荐子 Agnet 角色,桌面端可用于角色选择页。 响应: ```json { "success": true, "data": { "items": [ { "key": "backend", "display_name": "Backend Agnet", "summary": "实现后端接口、数据模型和服务逻辑", "default_model": "agnet-model-backend", "default_permissions": ["repo:read", "repo:write"], "risk_level": "medium" } ] } } ``` ## 12. 状态枚举 ### HeicodeTask.status | 状态 | 说明 | 客户端动作 | |---|---|---| | `draft` | 草稿 | 可继续编辑 | | `configuring` | 等待回答追问 | 展示 followups | | `running` | 可推进/运行中 | 创建 deployment 或展示 timeline | | `awaiting_approval` | 等待审批 | 拉取 `/api/agnet/approvals` | | `completed` | 完成 | 展示交付物 | | `failed` | 失败 | 展示失败原因 | | `paused` | 暂停 | 允许继续或停止 | ### Agnet Deployment.status | 状态 | 说明 | |---|---| | `accepted` | Manager 已接受并落本地记录 | | `running` | Runtime 已开始执行 | | `stopped` | 已停止 | | `failed` | 失败 | ### Agnet Deployment.runtime_state | 状态 | 说明 | |---|---| | `queued` | Manager 本地队列/占位,尚未同步真实 Runtime | | `runtime_syncing` | 正在同步 Runtime | | `runtime_accepted` | Runtime 接受 | | `runtime_sync_failed` | Runtime 同步失败 | | `not_configured` | 生产 Runtime 未配置 | ### 普通 sub 子环节建议值 Runtime callback / timeline 中可使用: | 阶段 | 说明 | |---|---| | `requirements` | 需求 | | `design` | 设计 | | `backend` | 后端 | | `frontend` | 前端 | | `review` | 检查 | | `test` | 测试 | | `deploy` | 部署 | ## 13. 错误码 | 错误码 | 场景 | 客户端处理 | |---|---|---| | `TASK_NOT_FOUND` | 任务不存在或 task snapshot 缺失 | 重新拉取任务 | | `TASK_CONFLICT` | URL task_id 与 body task.id 不一致 | 修正请求 | | `POLICY_REJECTED` | 参数不符合策略 | 展示错误并阻止继续 | | `MODEL_NOT_ALLOWED` | 模型不在允许列表 | 让用户换模型或联系管理员 | | `BUDGET_EXCEEDED` | 预算超过平台策略 | 调低预算 | | `RESOURCE_GRANT_INVALID` | Resource Grant 字段缺失或角色不匹配 | 重新选择资源权限 | | `RESOURCE_GRANT_SECRET_REF_REQUIRED` | 凭据型资源缺少 `secret_ref` | 引导用户绑定资源/密钥 | | `SECRET_REF_INVALID` | `secret_ref` 不是 `azkv://...` | 禁止继续 | | `RESOURCE_GRANT_SECRET_REJECTED` | metadata/constraints/audit 疑似包含明文密钥 | 禁止继续并提示脱敏 | | `CALLBACK_SECRET_REJECTED` | Runtime 回调含明文密钥 | 展示安全错误 | ## 14. 桌面端最小伪代码 ```ts type Json = Record // 复用模型调用已经使用的 V2 加密 fetch: // - 自动拉取 /api/server-pubkey // - 每次请求生成 nonce + X25519 ephemeral key // - 用 ChaCha20-Poly1305 加密 body // - 用设备 Ed25519 私钥签名 canonical // - 设置 Content-Encoding: heicode-aead-v1 和所有 X-Heicode-* 头 async function encryptedManagerRequest( method: 'POST', path: string, body?: Json, extraHeaders: Record = {} ): Promise { return encryptedFetch(`${managerBaseUrl}${path}`, { method, plaintextJson: body, headers: { Accept: 'application/json', ...extraHeaders, }, }) } const self = await manager.get('/api/user/self') const userId = self.data.id const task = await encryptedManagerRequest>( 'POST', '/api/heicode-auth/api/user/tasks/intent', { intent: userInput }, { Authorization: `Bearer ${heicodeAccessToken}`, } ) let current = task.data while (current.status === 'configuring') { const followup = findNextFollowup(current) const answer = await askUser(followup) current = await encryptedManagerRequest>( 'POST', `/api/heicode-auth/api/user/tasks/${current.id}/answer`, { question_id: followup.id, option_id: answer.id, }, { Authorization: `Bearer ${heicodeAccessToken}`, } ).then((r) => r.data) } const draft = await encryptedManagerRequest>( 'POST', `/api/agnet/user/tasks/${current.id}/deployment-draft`, { task: current, sub_mode: 'agile', binding_scope: `task-${current.id}`, role_templates: ['backend', 'frontend', 'reviewer'], default_model_id: 'agnet-model-builder', } ) const deployment = await encryptedManagerRequest>( 'POST', '/api/agnet/user/deployments', { orchestration_plan: draft.data.orchestration_plan } ) const deploymentId = deployment.data.deployment_id setInterval(async () => { const timeline = await manager.get>( `/api/agnet/user/deployments/${deploymentId}/timeline`, { headers: { 'New-Api-User': String(userId) } } ) renderTimeline(timeline.data.timeline) const approvals = await manager.get>( `/api/agnet/approvals?status=pending&deployment_id=${deploymentId}`, { headers: { 'New-Api-User': String(userId) } } ) renderApprovals(approvals.data.items) }, 5000) ``` 兼容说明: - 桌面客户端对 `POST` 等有 body 的 sub 请求走 V2 加密时,`/api/agnet/user/*` 不需要 `New-Api-User`,也不依赖浏览器 cookie。 - `GET` 查询接口本身没有请求 body,当前生产兼容路径仍使用 Manager session cookie + `New-Api-User`。如果桌面本地服务后续要完全脱离 session cookie 查询 timeline / artifact / approval,需要再补“无 body 的 V2 设备签名 GET”协议。 - `/api/heicode-auth/*` 仍必须带 `Authorization: Bearer `,该 token 只用于上游 HeicodeTask 认证。 - 如果客户端临时还没有接入 V2 加密,只能作为调试兼容路径使用 Manager session + `New-Api-User` 调 `/api/agnet/user/*`;正式桌面流程不要依赖该路径。 ## 15. 当前生产注意事项 1. `https://code.xinghanlab.com` 的 Manager 用户态接口已上线;当前生产版本为 `1.4.19`。 2. Manager 本地控制面可创建 `sub_mode=agile/waterfall` deployment。 3. 生产 Manager 已配置 Agent Manager Runtime,当前直接走 `http://20.212.121.126`;域名和 HTTPS 后续单独处理,不作为客户端当前接入阻塞项。 4. V2 加密 `deployment-draft` 已在生产验证通过:真实构造 `Content-Encoding: heicode-aead-v1` 请求返回 200,`sub_mode=agile`,`user_id=22`。 5. `deployment-draft -> create -> Runtime callback -> detail -> events/timeline -> stop` 已在生产验证通过,客户端可按本文参数形状接入。 6. `events/logs/artifacts/sk-snapshots/timeline` 查询接口已验证不报错;真实 artifact、SK 调用结果和真实成本金额需要 Agent Manager / Runtime 在真实任务中回传。 7. `POST /api/heicode-auth/api/user/tasks/intent` 需要桌面客户端提供 `heicode_access_token`;没有该 token 会返回 401。 8. malformed V2 请求已在生产验证会返回 `X-Heicode-Auth-Error`,客户端应把该头转成可读错误提示。 9. 当前 `GET` 查询接口没有请求 body,仍按 session + `New-Api-User` 验证;这不影响 body 加密要求,但客户端若要全链路无 cookie,需要后续补无 body 签名 GET。 10. macOS 联调前必须确认客户端已完成设备绑定;若 Manager 设备页没有 macOS 设备,模型列表 401 应优先处理客户端本地凭据和 Keychain,而不是改 Manager 模型配置。