docs: remove obsolete 普通 sub (old model) integration docs
The 普通 sub task-orchestration model was replaced by the template-agent model
and its backend deleted. Removed the now-obsolete docs describing it:
- heicode-desktop-sub-agile-api.md, heicode-desktop-subagile-e2e-demo.md
- heicode-desktop-unified-api.md, heicode-sub-mode-flow-spec.md
- 普通sub敏捷模式-AgentManager对接任务清单.md
- AgentManager普通sub{产物回调缺失问题,剩余补充要求,联调整改要求}.md
Fixed dangling references in the new docs (client-api / template-agent-model).
Swarm (蜂群) docs kept — different mode, out of scope.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,389 +0,0 @@
|
||||
# Agent Manager 普通 sub 产物回调缺失问题
|
||||
|
||||
更新时间:2026-05-29
|
||||
发给:Agent Manager / Agent Runtime 负责人
|
||||
范围:普通 sub 敏捷模式,不包含 HeiCode-Swarm 独立蜂群 Runtime。
|
||||
|
||||
## 1. 问题现象
|
||||
|
||||
Heicode 桌面客户端执行任务:
|
||||
|
||||
```text
|
||||
给我做一个 oracle 云的代理商网站,做前后端分离
|
||||
```
|
||||
|
||||
客户端最终只显示:
|
||||
|
||||
```text
|
||||
Swarm initialized and planning started
|
||||
Swarm execution completed
|
||||
completed
|
||||
```
|
||||
|
||||
但右侧运行数据中:
|
||||
|
||||
```text
|
||||
ARTIFACTS = 0
|
||||
SK SNAPSHOTS = 0
|
||||
```
|
||||
|
||||
用户无法看到真正交付物,例如代码分支、提交、预览地址、部署清单、文档或最终结果摘要。
|
||||
|
||||
## 2. 本次链路归属
|
||||
|
||||
本次不是走 HeiCode-Swarm 独立蜂群 Runtime。
|
||||
|
||||
Heicode Manager 生产配置确认当前普通 sub 走:
|
||||
|
||||
```text
|
||||
AGENT_RUNTIME_BASE_URL=http://20.212.121.126
|
||||
AGENT_RUNTIME_CREATE_PATH=/api/swarms
|
||||
```
|
||||
|
||||
`SWARM_RUNTIME_BASE_URL` 当前为空。
|
||||
|
||||
因此本问题归属:
|
||||
|
||||
```text
|
||||
Heicode 桌面客户端
|
||||
-> Heicode Manager 生产
|
||||
-> Agent Manager / Agent Runtime 普通 sub 入口
|
||||
-> Heicode Manager callback
|
||||
-> 桌面客户端查询 artifacts/timeline
|
||||
```
|
||||
|
||||
不是独立蜂群 Runtime `http://52.139.240.116:8000` 的问题。
|
||||
|
||||
## 3. Heicode Manager 生产侧实查结果
|
||||
|
||||
Heicode Manager deployment:
|
||||
|
||||
```text
|
||||
dep_fa4f43da9e0a
|
||||
```
|
||||
|
||||
Runtime 返回并保存的 swarm/deployment id:
|
||||
|
||||
```text
|
||||
swm_f9ce3f6c90aa
|
||||
```
|
||||
|
||||
Heicode Manager 生产库记录:
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| `deployment_id` | `dep_fa4f43da9e0a` |
|
||||
| `status` | `completed` |
|
||||
| `phase` | `deploy` |
|
||||
| `runtime_state` | `completed` |
|
||||
| `runtime_deployment_id` | `swm_f9ce3f6c90aa` |
|
||||
| `runtime_swarm_id` | `swm_f9ce3f6c90aa` |
|
||||
| `created_at_text` | `2026-05-29T08:40:50Z` |
|
||||
| `updated_at_text` | `2026-05-29T08:40:51Z` |
|
||||
|
||||
Heicode Manager 收到的 callback 类型统计:
|
||||
|
||||
| callback event_type | count |
|
||||
|---|---:|
|
||||
| `agent.started` | 2 |
|
||||
| `budget.alert` | 1 |
|
||||
| `deployment.status_changed` | 3 |
|
||||
| `phase.changed` | 2 |
|
||||
| `timeline.updated` | 2 |
|
||||
|
||||
关键缺失:
|
||||
|
||||
```text
|
||||
artifact.created = 0
|
||||
task.completed = 0
|
||||
sk_tool.completed = 0
|
||||
```
|
||||
|
||||
Heicode Manager artifact 表查询结果:
|
||||
|
||||
```text
|
||||
agent_artifacts where deployment_id = 'dep_fa4f43da9e0a'
|
||||
=> 0 rows
|
||||
```
|
||||
|
||||
说明:Heicode Manager 没有收到任何产物事件,因此客户端显示 `ARTIFACTS 0` 是真实数据,不是客户端漏显示。
|
||||
|
||||
## 4. Heicode Manager callback 接收链路是通的
|
||||
|
||||
生产日志中,Agent Manager 在任务完成时间段连续请求:
|
||||
|
||||
```text
|
||||
POST /api/agent/callbacks/swarm-events
|
||||
```
|
||||
|
||||
HTTP 状态均为:
|
||||
|
||||
```text
|
||||
200
|
||||
```
|
||||
|
||||
这说明:
|
||||
|
||||
1. Agent Manager 能打到 Heicode Manager callback 地址。
|
||||
2. Heicode Manager 没有拒收这些 callback。
|
||||
3. 问题不是 callback 鉴权失败。
|
||||
4. 问题不是 Heicode Manager callback endpoint 不通。
|
||||
|
||||
但 callback 事件内容中没有 `artifact.created`,因此 Heicode Manager 无法落库 artifacts。
|
||||
|
||||
## 5. Agent Manager 侧直查结果
|
||||
|
||||
直查 Agent Manager Runtime:
|
||||
|
||||
```http
|
||||
GET http://20.212.121.126/api/swarms/swm_f9ce3f6c90aa
|
||||
```
|
||||
|
||||
返回关键信息:
|
||||
|
||||
```json
|
||||
{
|
||||
"deployment_id": "swm_f9ce3f6c90aa",
|
||||
"swarm_id": "swm_f9ce3f6c90aa",
|
||||
"status": "completed",
|
||||
"phase": "planning",
|
||||
"progress": 100,
|
||||
"agents": [
|
||||
{
|
||||
"agent_id": "agi_backend_59717a71",
|
||||
"role": "backend",
|
||||
"status": "running",
|
||||
"output": null
|
||||
},
|
||||
{
|
||||
"agent_id": "agi_frontend_3063c6c9",
|
||||
"role": "frontend",
|
||||
"status": "running",
|
||||
"output": null
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"total_messages": 0,
|
||||
"tokens_used": 0
|
||||
},
|
||||
"artifacts": []
|
||||
}
|
||||
```
|
||||
|
||||
直查日志:
|
||||
|
||||
```http
|
||||
GET http://20.212.121.126/api/swarms/swm_f9ce3f6c90aa/logs
|
||||
```
|
||||
|
||||
返回:
|
||||
|
||||
```text
|
||||
Logs will be fetched from K8s in Phase 2
|
||||
```
|
||||
|
||||
这说明 Agent Manager 自己也没有保存或返回真实产物。
|
||||
|
||||
## 6. 当前判断
|
||||
|
||||
本问题根因不在 Heicode Manager,也不在桌面客户端。
|
||||
|
||||
当前证据指向 Agent Manager / Agent Runtime:
|
||||
|
||||
1. Runtime 将 deployment 标记为 `completed`。
|
||||
2. Runtime 自身返回 `artifacts: []`。
|
||||
3. Runtime 没有 callback `artifact.created`。
|
||||
4. Runtime agents 仍显示 `running`,但 deployment 已 `completed`,状态不一致。
|
||||
5. Runtime metrics 中 `tokens_used=0`、`total_messages=0`,没有真实模型执行用量。
|
||||
6. Runtime logs 仍是占位文本,没有真实 K8s / Agent 日志。
|
||||
|
||||
因此客户端只能展示完成状态,不能展示交付结果。
|
||||
|
||||
## 7. Agent Manager 需要修复的内容
|
||||
|
||||
### P0:任务完成必须回调 artifact
|
||||
|
||||
普通 sub 任务完成时,Agent Manager 必须向 Heicode Manager callback:
|
||||
|
||||
```text
|
||||
POST https://code.xinghanlab.com/api/agent/callbacks/swarm-events
|
||||
event_type = artifact.created
|
||||
```
|
||||
|
||||
即使没有 Git 分支,也必须返回一个可展示的交付物。
|
||||
|
||||
建议 artifact 类型:
|
||||
|
||||
| 场景 | artifact_type | uri / 内容 |
|
||||
|---|---|---|
|
||||
| 代码已提交 | `code_patch` | `git://repo#<branch>` 或 repo URL + branch + commit |
|
||||
| 生成了前后端项目 | `deployment_manifest` | 项目结构、启动方式、服务端口、部署说明 |
|
||||
| 只产出设计/说明 | `document` | 文档地址或文档摘要 |
|
||||
| 无法生成正式产物 | `other` | 明确失败原因、已完成内容、下一步动作 |
|
||||
|
||||
最低要求:不能只发 `completed`,必须有一个 `artifact.created` 或明确失败事件。
|
||||
|
||||
### P0:completed 状态与 Agent 状态一致
|
||||
|
||||
当前 Runtime 返回:
|
||||
|
||||
```text
|
||||
deployment.status = completed
|
||||
agents[].status = running
|
||||
```
|
||||
|
||||
需要修复为一致状态:
|
||||
|
||||
1. 如果 deployment completed,则相关 agent 应为 `completed`、`stopped` 或明确的终态。
|
||||
2. 如果 agent 仍 running,则 deployment 不应为 completed。
|
||||
3. 如果任务未真实执行,应返回 `failed` 或 `blocked`,并说明原因。
|
||||
|
||||
### P0:回调 task.completed / task.failed
|
||||
|
||||
当前 Heicode Manager 没收到:
|
||||
|
||||
```text
|
||||
task.completed
|
||||
task.failed
|
||||
task.blocked
|
||||
```
|
||||
|
||||
Agent Manager 应在每个子 Agent / 子任务结束时回调任务状态,至少包含:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "task.completed",
|
||||
"deployment_id": "dep_fa4f43da9e0a",
|
||||
"swarm_id": "swm_f9ce3f6c90aa",
|
||||
"task_id": "task-backend-xxx",
|
||||
"agent_instance_id": "agi_backend_59717a71",
|
||||
"payload": {
|
||||
"task_id": "task-backend-xxx",
|
||||
"agent_role": "backend",
|
||||
"status": "completed",
|
||||
"summary": "后端实现完成,产物见 artifact"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### P1:回传真实 usage / cost
|
||||
|
||||
当前 Runtime 返回:
|
||||
|
||||
```text
|
||||
tokens_used = 0
|
||||
total_messages = 0
|
||||
```
|
||||
|
||||
如果任务真实调用了模型,应回传:
|
||||
|
||||
```json
|
||||
{
|
||||
"model_usage": {
|
||||
"input_tokens": 1234,
|
||||
"output_tokens": 5678,
|
||||
"total_tokens": 6912,
|
||||
"model_cost_usd": 0.0123,
|
||||
"model_id": "xxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果没有真实调用模型,应明确返回 `blocked` 或 `failed`,不能标记为正常 completed。
|
||||
|
||||
### P1:提供真实日志
|
||||
|
||||
当前日志仍是:
|
||||
|
||||
```text
|
||||
Logs will be fetched from K8s in Phase 2
|
||||
```
|
||||
|
||||
需要至少返回可排障日志摘要:
|
||||
|
||||
1. Agent 是否启动成功。
|
||||
2. 是否领取任务。
|
||||
3. 是否调用模型。
|
||||
4. 是否生成文件/分支/产物。
|
||||
5. 失败原因。
|
||||
|
||||
## 8. 建议的 artifact.created callback 示例
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_artifact_<unique>",
|
||||
"event_type": "artifact.created",
|
||||
"deployment_id": "dep_fa4f43da9e0a",
|
||||
"swarm_id": "swm_f9ce3f6c90aa",
|
||||
"agent_instance_id": "agi_backend_59717a71",
|
||||
"task_id": "task-backend-001",
|
||||
"occurred_at": "2026-05-29T08:40:51Z",
|
||||
"correlation_id": "corr_xxx",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"artifact_id": "art_swm_f9ce3f6c90aa_backend_001",
|
||||
"artifact_type": "code_patch",
|
||||
"title": "Oracle 云代理商网站后端实现",
|
||||
"summary": "已生成后端接口、数据模型和启动说明",
|
||||
"uri": "git://repo#feature/swm_f9ce3f6c90aa",
|
||||
"checksum": "commit_sha_if_available",
|
||||
"metadata": {
|
||||
"redacted": true,
|
||||
"agent_role": "backend",
|
||||
"runtime_deployment_id": "swm_f9ce3f6c90aa"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果没有 Git 分支,也可以先回:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "artifact.created",
|
||||
"deployment_id": "dep_fa4f43da9e0a",
|
||||
"swarm_id": "swm_f9ce3f6c90aa",
|
||||
"payload": {
|
||||
"artifact_id": "art_swm_f9ce3f6c90aa_summary",
|
||||
"artifact_type": "document",
|
||||
"title": "任务执行结果摘要",
|
||||
"summary": "Runtime 已完成任务,但未返回 Git 分支。这里应写清生成内容、文件位置或未生成原因。",
|
||||
"uri": "runtime://swm_f9ce3f6c90aa/artifacts/summary",
|
||||
"metadata": {
|
||||
"redacted": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
修复后请用同类任务重新跑一次:
|
||||
|
||||
```text
|
||||
给我做一个 oracle 云的代理商网站,做前后端分离
|
||||
```
|
||||
|
||||
必须满足:
|
||||
|
||||
| 验收项 | 标准 |
|
||||
|---|---|
|
||||
| Runtime 状态 | deployment 和 agents 状态一致 |
|
||||
| callback | Heicode Manager 收到 `artifact.created` |
|
||||
| Manager artifacts | `/api/agent/user/deployments/{deployment_id}/artifacts` 返回 total > 0 |
|
||||
| 客户端展示 | 右侧 `ARTIFACTS` 不再是 0 |
|
||||
| 交付物 | 能看到 Git 分支、提交、预览地址、部署清单或最终结果文档 |
|
||||
| usage | 如果真实调用模型,tokens/cost 不应一直为 0 |
|
||||
| logs | 不再只有 Phase 2 占位文本 |
|
||||
|
||||
## 10. 当前结论
|
||||
|
||||
Heicode Manager 和桌面客户端当前表现是正确反映 Runtime 数据。
|
||||
|
||||
真正缺口在 Agent Manager / Agent Runtime:
|
||||
|
||||
```text
|
||||
任务被标记 completed,但 Runtime 没有生成或回传 artifact.created。
|
||||
```
|
||||
|
||||
请 Agent Manager 优先修复任务完成后的产物生成、产物回调、状态一致性、usage 和日志回传。
|
||||
@@ -1,246 +0,0 @@
|
||||
# Agent Manager 普通 sub 剩余补充要求
|
||||
|
||||
更新时间:2026-05-28
|
||||
发给:Agent Manager / Agent Runtime 负责人
|
||||
范围:普通 sub 敏捷开发模式,不包含蜂群模式完整 task graph。
|
||||
|
||||
## 1. 当前已验证事实
|
||||
|
||||
Heicode Manager 生产版本 `1.4.19` 已完成并验证以下链路:
|
||||
|
||||
| 项目 | 状态 | 生产验证 |
|
||||
|------|------|----------|
|
||||
| Manager 创建普通 sub run | 已跑通 | `POST https://code.xinghanlab.com/api/swarms` 返回 `dep_*` |
|
||||
| Manager 调 Agent Manager | 已跑通 | Agent Manager 返回 `runtime_swarm_id=swm_*` |
|
||||
| Agent Manager 自动 callback | 已跑通 | Manager `events/timeline` 可查到 callback |
|
||||
| callback HMAC fallback | 已跑通 | 生产 callback 可验签入库 |
|
||||
| Manager 状态反写 | 已跑通 | callback 后 `deployment.status/phase/runtime_state/agent_instances` 会更新 |
|
||||
| billing_context 字段透传 | 已跑通 | `default_model_id/allowed_model_ids/secret_ref` 已保留 |
|
||||
|
||||
最新生产烟测样例:
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|----|
|
||||
| Manager deployment | `dep_be665a25f6bc` |
|
||||
| Runtime swarm | `swm_4c471d60972f` |
|
||||
| Manager detail status | `completed` |
|
||||
| Manager detail phase | `deploy` |
|
||||
| Manager runtime_state | `completed` |
|
||||
| Manager agent state | `completed` |
|
||||
| Manager callback 数 | `9` |
|
||||
| Manager event 数 | `12` |
|
||||
|
||||
因此,当前剩余问题主要不在 Manager 接收链路,而在 Agent Manager 真实执行数据、状态一致性、产物和用量回传。
|
||||
|
||||
## 2. Agent Manager 必须补充的 P0
|
||||
|
||||
| 优先级 | 缺口 | 当前实测表现 | Agent Manager 需要补什么 | 验收标准 |
|
||||
|--------|------|--------------|---------------------------|----------|
|
||||
| P0 | Runtime 状态一致性 | 直连 `GET /api/swarms/{swarm_id}/status` 返回整体 `completed`,但 `agents[].status` 仍是 `running` | 整体完成时同步更新 agent 状态,或发送 `agent.completed` callback | status 接口中整体和 agent 状态一致;Manager 不再需要兜底收敛 |
|
||||
| P0 | 真实 artifact 回传 | Manager 收到 callback,但 `/artifacts` 仍为 `[]` | 执行完成时回调 `artifact.created`,至少包含摘要型交付物 | Manager `/artifacts` 至少有 1 条真实 artifact |
|
||||
| P0 | 真实 usage / cost 回传 | `tokens_used=0`,budget callback 中 token/cost/runtime 多为 0 | 回传模型 token、模型成本、runtime 秒数、资源使用 | Manager timeline 中能看到非 0 或明确的真实 usage 字段 |
|
||||
| P0 | 真实日志 | `/logs` 返回占位文本 `Logs will be fetched from K8s in Phase 2` | 接入真实 Pod/Runtime 日志或回调日志摘要 | `GET /logs` 返回真实执行日志或明确失败原因 |
|
||||
| P0 | 阶段推进语义 | callback 有 phase/timeline,但当前非常短,直接 completed | 普通 sub 应按需求、设计、开发、测试、部署阶段推进 | 至少能看到 `requirements/design/development/testing/deploy` 中的真实阶段变化 |
|
||||
| P0 | 失败原因回传 | 当前成功场景没有问题,但失败链路未验证 | 失败时回调 `deployment.status_changed` + `agent.crashed` 或 `sk_tool.failed` | Manager detail 出现 `failed` 和可读 `failure_reason` |
|
||||
|
||||
## 3. Agent Manager 应补充的 P1
|
||||
|
||||
| 优先级 | 缺口 | 要求 | 验收标准 |
|
||||
|--------|------|------|----------|
|
||||
| P1 | SK 工具调用展示 | 回调 `sk_tool.called/completed/failed`,参数和结果必须脱敏 | Manager `/sk-snapshots` 或 timeline 能看到工具调用记录 |
|
||||
| P1 | 高危审批闭环 | 高危动作回调 `approval.requested`,等待 Manager/客户端 approve/reject 后继续或停止 | approve 后 Runtime 继续,reject 后 Runtime 停止或跳过高危动作 |
|
||||
| P1 | stop 后真实停止 | Manager stop 会调用 Runtime stop | stop 后 status 为 `stopped`,不再继续发 running/completed callback |
|
||||
| P1 | 幂等创建稳定性 | 同一个 `X-Idempotency-Key` 不重复创建 | 重放创建请求返回同一个 run |
|
||||
| P1 | callback 重试/死信 | 文档写了重试/死信,但也写失败只 warning | 明确当前真实策略;失败后至少可人工重放 |
|
||||
| P1 | runtime_id 字段稳定 | 当前 Manager 可兼容 `deployment_id=swm_*` | 后续响应和 callback 统一携带 `deployment_id`、`swarm_id`、`correlation_id` |
|
||||
|
||||
## 4. Callback 最低要求
|
||||
|
||||
Manager callback 地址:
|
||||
|
||||
```text
|
||||
https://code.xinghanlab.com/api/agent/callbacks/swarm-events
|
||||
```
|
||||
|
||||
创建 run 后,Agent Manager 至少需要主动回调这些事件:
|
||||
|
||||
| 事件 | 何时发送 | payload 最低字段 |
|
||||
|------|----------|------------------|
|
||||
| `deployment.status_changed` | accepted/running/completed/failed/stopped | `status` |
|
||||
| `phase.changed` | 普通 sub 阶段变化 | `stage`、`checkpoint`、`summary` |
|
||||
| `timeline.updated` | 用户可读进度 | `title`、`summary`、`stage`、`checkpoint` |
|
||||
| `agent.started` | 子 Agent 开始 | `agent_role`、`status` |
|
||||
| `agent.completed` | 子 Agent 完成 | `agent_role`、`status` |
|
||||
| `agent.crashed` | 子 Agent 异常 | `agent_role`、`reason` |
|
||||
| `artifact.created` | 产生中间或最终交付物 | `artifact_id`、`artifact_type`、`title`、`summary`、`uri` |
|
||||
| `budget.alert` | 用量更新或预算告警 | `model_tokens`、`model_cost_usd`、`runtime_seconds`、`consumed_usd` |
|
||||
| `sk_tool.completed` | SK 工具成功 | `tool_name`、`tool_invocation_id`、`summary` |
|
||||
| `sk_tool.failed` | SK 工具失败 | `tool_name`、`tool_invocation_id`、`reason` |
|
||||
| `approval.requested` | 需要高危审批 | `approval_id`、`operation`、`risk_level`、`reason` |
|
||||
|
||||
## 5. Artifact 最低格式
|
||||
|
||||
普通 sub 完成时至少回写一个 artifact:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "artifact.created",
|
||||
"deployment_id": "dep_xxx",
|
||||
"swarm_id": "swm_xxx",
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"payload": {
|
||||
"artifact_id": "art_dep_xxx_summary",
|
||||
"artifact_type": "test_report",
|
||||
"title": "普通 sub 执行结果",
|
||||
"summary": "本轮任务完成了哪些内容、测试结果、剩余风险",
|
||||
"uri": "azblob://heicode-artifacts/dep_xxx/report.json",
|
||||
"stage": "deploy",
|
||||
"checkpoint": "completed",
|
||||
"metadata": {
|
||||
"agent_role": "backend",
|
||||
"redacted": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- `summary` 可直接展示给用户。
|
||||
- 不允许出现明文 token、password、secret、private key、connection string。
|
||||
- 大文件只传 URI 和摘要,不在 callback body 内联完整内容。
|
||||
|
||||
## 6. Usage / Cost 最低格式
|
||||
|
||||
Agent Manager 需要让 Manager 能区分预算和真实消耗。
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "budget.alert",
|
||||
"deployment_id": "dep_xxx",
|
||||
"swarm_id": "swm_xxx",
|
||||
"payload": {
|
||||
"billing_source": "newapi",
|
||||
"model_id": "model-runtime-smoke",
|
||||
"prompt_tokens": 1200,
|
||||
"completion_tokens": 800,
|
||||
"model_tokens": 2000,
|
||||
"model_cost_usd": 0.012,
|
||||
"runtime_seconds": 42,
|
||||
"cpu_core_seconds": 21,
|
||||
"memory_mb_seconds": 86016,
|
||||
"consumed_usd": 0.012,
|
||||
"budget": {
|
||||
"max_cost_usd": 0.05,
|
||||
"remaining_usd": 0.038
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果当前测试任务确实没有模型调用,也需要明确回传:
|
||||
|
||||
```json
|
||||
{
|
||||
"model_tokens": 0,
|
||||
"model_cost_usd": 0,
|
||||
"runtime_seconds": 42,
|
||||
"billing_source": "runtime_no_model_call"
|
||||
}
|
||||
```
|
||||
|
||||
不能只返回全 0 又没有解释。
|
||||
|
||||
## 7. 状态一致性要求
|
||||
|
||||
当前实测中 Agent Manager 状态存在矛盾:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "completed",
|
||||
"agents": [
|
||||
{
|
||||
"status": "running"
|
||||
}
|
||||
],
|
||||
"tokens_used": 0,
|
||||
"artifacts": []
|
||||
}
|
||||
```
|
||||
|
||||
需要改为:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "completed",
|
||||
"phase": "deploy",
|
||||
"progress": 100,
|
||||
"agents": [
|
||||
{
|
||||
"status": "completed"
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"tokens_used": 2000,
|
||||
"elapsed_seconds": 42
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
"artifact_id": "art_xxx",
|
||||
"artifact_type": "test_report"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
如果执行失败,则整体和 agent 都要能表达失败:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "failed",
|
||||
"error_message": "模型调用失败或资源授权不足",
|
||||
"agents": [
|
||||
{
|
||||
"status": "failed",
|
||||
"error_message": "具体失败原因"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 联调验收步骤
|
||||
|
||||
Agent Manager 补完后,按以下步骤验收:
|
||||
|
||||
1. Heicode Manager 通过 `POST /api/swarms` 创建普通 sub run。
|
||||
2. Manager 返回 `deployment_id=dep_*`。
|
||||
3. Runtime 返回并持久化 `runtime_swarm_id=swm_*`。
|
||||
4. Agent Manager 主动 callback:
|
||||
- `deployment.status_changed`
|
||||
- `phase.changed`
|
||||
- `timeline.updated`
|
||||
- `agent.started`
|
||||
- `agent.completed`
|
||||
- `artifact.created`
|
||||
- `budget.alert`
|
||||
5. Manager 查询:
|
||||
- `/api/agent/user/deployments/{deployment_id}`
|
||||
- `/events`
|
||||
- `/timeline`
|
||||
- `/artifacts`
|
||||
- `/sk-snapshots`
|
||||
6. 期望结果:
|
||||
- detail 状态为真实 Runtime 状态。
|
||||
- timeline 有阶段推进。
|
||||
- artifacts 有真实产物。
|
||||
- usage 有可解释的真实消耗。
|
||||
- 不出现明文密钥。
|
||||
|
||||
## 9. 当前非阻塞但需记录
|
||||
|
||||
| 项目 | 当前状态 | 说明 |
|
||||
|------|----------|------|
|
||||
| Agent Manager 域名 | 暂未作为联调依赖 | 当前统一使用 `http://20.212.121.126` |
|
||||
| Azure Key Vault | Manager 侧 VM Managed Identity 未正式配好 | 当前 callback 使用 HMAC fallback 已跑通;正式 Key Vault 需后续云资源配置 |
|
||||
| Manager 状态兜底 | 已完成 | Manager `1.4.19` 会根据 callback 收敛 detail 状态,但 Runtime 仍应修正自身状态 |
|
||||
|
||||
@@ -1,609 +0,0 @@
|
||||
# Agent Manager 普通 sub 联调整改要求
|
||||
|
||||
更新时间:2026-05-28
|
||||
发给:Agent Manager / Agent Runtime 负责人
|
||||
范围:Heicode Manager 普通 sub 敏捷模式联调,不包含蜂群模式完整 task graph 的额外能力。
|
||||
|
||||
## 1. 当前结论
|
||||
|
||||
Agent Manager 新版文档 `HEICODE_API_INTEGRATION(5).md` 已经补充了 Runtime 主动 callback、HMAC、artifact、timeline、SK snapshot 等内容,方向基本对齐 Heicode Manager。
|
||||
|
||||
按 2026-05-28 生产实测,Manager 与 Agent Manager 的普通 sub 核心通讯链路已经跑通,但还不能认为“真实开发执行结果”完整闭环。当前结论是:
|
||||
|
||||
1. Agent Manager 当前联调统一使用 IP `http://20.212.121.126`;域名 `https://agent-manager.taijiagent.com` 后续解析和证书就绪后再切换,不作为当前联调阻塞项。
|
||||
2. Manager 生产已切到 `/api/swarms` 创建入口,并验证能拿到 `runtime_swarm_id=swm_*`。
|
||||
3. Agent Manager 自动 callback 已能写入 Manager `events/timeline`,Manager `1.4.19` 开始会把 callback 反写到 deployment 快照。
|
||||
4. 当前仍缺真实产物和真实用量:Agent Manager status 接口返回 `tokens_used=0`、`artifacts=[]`,并出现整体 `completed` 但 agent 仍 `running` 的状态不一致。
|
||||
5. 文档写了 callback 重试和死信,但同时又写“发送失败只 warning”,需要明确当前真实实现。
|
||||
|
||||
Heicode Manager 侧已确认:
|
||||
|
||||
- `POST https://code.xinghanlab.com/api/agent/callbacks/swarm-events` 生产路由在线。
|
||||
- callback 支持 HMAC 和旧 token 兼容;当前生产为了先跑通自动 callback,已配置 HMAC fallback。
|
||||
- `GET https://code.xinghanlab.com/api/agent/callbacks/swarm-events/schema` 已由 Manager 提供,用于联调前核对事件类型和必填字段。
|
||||
- Manager 可接收 `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started/completed/crashed`,并在 `1.4.19` 反写 deployment 详情状态。
|
||||
|
||||
## 2. Agent Manager 必须整改的 P0
|
||||
|
||||
| 优先级 | 事项 | 当前问题 | 要求 |
|
||||
|---|---|---|---|
|
||||
| P0 | 固定联调地址 | 当前阶段约定先走 IP,后续再切域名 | 文档和配置先统一使用 `http://20.212.121.126`;域名切换另行确认 |
|
||||
| P0 | 创建普通 sub deployment | `/api/swarms` 已能创建并返回 `swm_*` | 保持幂等和字段稳定,后续域名切换不能破坏 |
|
||||
| P0 | deployment detail | Manager 已能记录 callback;Agent Manager status 仍有 `completed` 与 agent `running` 不一致 | 返回真实 phase、agent 状态、失败原因和更新时间 |
|
||||
| P0 | deployment stop | `/api/agent/deployments/{deployment_id}/stop` 已可用 | 停止后 Runtime 真实停止,并回调 stopped 事件 |
|
||||
| P0 | callback 主动推送 | 已验证 status/phase/timeline/agent/budget callback 能进入 Manager | 继续补 artifact、SK、approval 的真实运行数据 |
|
||||
| P0 | usage 回传 | 当前 budget callback 中 token/cost/runtime 多为 0 | 通过 callback 或事件接口回传真实 token、成本、运行时长、资源使用 |
|
||||
|
||||
## 3. 推荐接口契约
|
||||
|
||||
### 3.1 健康检查
|
||||
|
||||
```http
|
||||
GET /api/agent/health
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- 不要求业务认证。
|
||||
- 返回 200。
|
||||
- 响应中包含 `success=true` 和 `data.status=healthy`。
|
||||
|
||||
### 3.2 创建普通 sub 运行
|
||||
|
||||
普通 sub 当前生产联调使用 Agent Manager `/api/agent/deployments`,蜂群 `/api/swarms` 另见 `AgentManager蜂群Runtime接口实现要求.md`。
|
||||
|
||||
```http
|
||||
POST /api/agent/deployments
|
||||
Authorization: Bearer <HEICODE_SERVICE_TOKEN>
|
||||
Content-Type: application/json
|
||||
X-User-ID: <user_id>
|
||||
X-Binding-Scope: <binding_scope>
|
||||
X-Correlation-ID: <correlation_id>
|
||||
X-Idempotency-Key: <idempotency_key>
|
||||
```
|
||||
|
||||
请求体示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"orchestration_plan": {
|
||||
"intent_id": "task_123",
|
||||
"template_hint": "heicode-task",
|
||||
"objective": "完成本轮普通 sub 敏捷任务",
|
||||
"sub_mode": "agile",
|
||||
"risk_level": "medium",
|
||||
"budget": {
|
||||
"max_tokens": 120000,
|
||||
"max_cost_usd": 8,
|
||||
"max_duration_sec": 3600
|
||||
},
|
||||
"user_context": {
|
||||
"user_id": "123",
|
||||
"channel_id": "heicode",
|
||||
"binding_scope": "task-task-123"
|
||||
},
|
||||
"billing_context": {
|
||||
"provider": "newapi",
|
||||
"default_model_id": "model_xxx",
|
||||
"allowed_model_ids": ["model_xxx"],
|
||||
"secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key"
|
||||
},
|
||||
"agile_context": {
|
||||
"iteration": "2026-05-28",
|
||||
"stage": "development",
|
||||
"checkpoint": "draft_created",
|
||||
"acceptance_criteria": [
|
||||
"Runtime 接收创建请求",
|
||||
"Runtime 主动回调 phase/timeline/artifact",
|
||||
"Manager 页面和接口可查到回调数据",
|
||||
"不出现明文密钥"
|
||||
],
|
||||
"next_action": "continue",
|
||||
"requires_user_approval": false
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"role": "backend"
|
||||
},
|
||||
{
|
||||
"role": "frontend"
|
||||
},
|
||||
{
|
||||
"role": "reviewer"
|
||||
}
|
||||
],
|
||||
"resource_grants": []
|
||||
},
|
||||
"callback": {
|
||||
"url": "https://code.xinghanlab.com/api/agent/callbacks/swarm-events",
|
||||
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agent-callback-signing-key",
|
||||
"subscribed_events": [
|
||||
"deployment.status_changed",
|
||||
"phase.changed",
|
||||
"timeline.updated",
|
||||
"agent.started",
|
||||
"agent.completed",
|
||||
"sk_tool.called",
|
||||
"sk_tool.completed",
|
||||
"sk_tool.failed",
|
||||
"approval.requested",
|
||||
"budget.alert",
|
||||
"artifact.created"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
成功响应必须包含:
|
||||
|
||||
```json
|
||||
{
|
||||
"deployment_id": "dep_runtime_123",
|
||||
"status": "initializing",
|
||||
"agent_instances": [
|
||||
{
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"role": "backend",
|
||||
"status": "pending"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-05-28T07:30:00Z",
|
||||
"estimated_ready_at": "2026-05-28T07:32:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
1. `deployment_id` 必须可用于 `/api/agent/deployments/{deployment_id}`、`/api/agent/deployments/{deployment_id}/stop`。
|
||||
2. 同一个 `X-Idempotency-Key` 重复请求必须返回同一个运行,不应重复创建。
|
||||
3. 请求缺少 `orchestration_plan`、`callback.url`、`sub_mode`、`user_context` 时必须返回 4xx。
|
||||
|
||||
### 3.3 查询普通 sub deployment
|
||||
|
||||
```http
|
||||
GET /api/agent/deployments/{deployment_id}
|
||||
Authorization: Bearer <HEICODE_SERVICE_TOKEN>
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deployment_id": "dep_runtime_123",
|
||||
"status": "running",
|
||||
"phase": "development",
|
||||
"agent_instances": [
|
||||
{
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"role": "backend",
|
||||
"status": "running",
|
||||
"current_task": "实现接口"
|
||||
}
|
||||
],
|
||||
"created_at": "2026-05-28T07:30:00Z",
|
||||
"updated_at": "2026-05-28T07:31:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 停止普通 sub deployment
|
||||
|
||||
```http
|
||||
POST /api/agent/deployments/{deployment_id}/stop
|
||||
Authorization: Bearer <HEICODE_SERVICE_TOKEN>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"reason": "Heicode Manager requested stop",
|
||||
"manager_deployment_id": "dep_manager_123"
|
||||
}
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"deployment_id": "dep_runtime_123",
|
||||
"status": "stopped",
|
||||
"stopped_at": "2026-05-28T07:40:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- 停止后不再继续执行任务。
|
||||
- 停止后可以继续查询状态。
|
||||
- 停止成功后建议 callback 一条 `deployment.status_changed`,状态为 `stopped`。
|
||||
|
||||
## 4. Callback 要求
|
||||
|
||||
Manager 生产 callback 地址:
|
||||
|
||||
```text
|
||||
https://code.xinghanlab.com/api/agent/callbacks/swarm-events
|
||||
```
|
||||
|
||||
### 4.1 认证方式
|
||||
|
||||
优先使用 HMAC:
|
||||
|
||||
```http
|
||||
X-Agent-Event-Id: evt_xxx
|
||||
X-Agent-Timestamp: <unix_ms>
|
||||
X-Agent-Signature: sha256=<hex>
|
||||
X-Correlation-ID: <correlation_id>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
签名规则:
|
||||
|
||||
```text
|
||||
signature_payload = timestamp + "." + event_id + "." + raw_body
|
||||
signature = HMAC_SHA256(callback_signing_secret, signature_payload)
|
||||
```
|
||||
|
||||
过渡期可使用旧 token:
|
||||
|
||||
```http
|
||||
X-Agent-Service-Token: <HEICODE_SERVICE_TOKEN>
|
||||
```
|
||||
|
||||
不要把真实 token 写入文档、日志或 artifact。
|
||||
|
||||
### 4.2 必须回调的事件
|
||||
|
||||
普通 sub 最少需要以下事件:
|
||||
|
||||
| 事件 | 目的 | 最低要求 |
|
||||
|---|---|---|
|
||||
| `deployment.status_changed` | 整体运行状态 | `status`、`stage`、`checkpoint` |
|
||||
| `phase.changed` | 普通 sub 阶段推进 | `stage`、`checkpoint`、`progress_pct` |
|
||||
| `timeline.updated` | 客户端可展示反馈 | `title`、`summary`、`stage`、`checkpoint` |
|
||||
| `agent.started` | Agent 开始工作 | `agent_role`、`task_id` |
|
||||
| `sk_tool.called` | 工具调用开始 | `tool_name`、脱敏参数摘要 |
|
||||
| `sk_tool.completed` | 工具调用成功 | `tool_name`、耗时、摘要、可选 artifact 引用 |
|
||||
| `sk_tool.failed` | 工具调用失败 | `tool_name`、脱敏错误 |
|
||||
| `artifact.created` | 中间/最终产物 | `artifact_id`、`artifact_type`、`title`、`summary`、`uri` |
|
||||
| `approval.requested` | 高危操作审批 | `operation`、`resource_type`、`risk_level`、`reason` |
|
||||
| `budget.alert` | 预算告警/用量 | usage / cost 摘要 |
|
||||
|
||||
### 4.3 Callback body 示例
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_phase_001",
|
||||
"event_type": "phase.changed",
|
||||
"deployment_id": "dep_manager_123",
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"occurred_at": "2026-05-28T07:35:00Z",
|
||||
"correlation_id": "corr_123",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"stage": "development",
|
||||
"checkpoint": "agent_running",
|
||||
"progress_pct": 35,
|
||||
"summary": "backend agent 已开始实现接口"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
artifact 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_artifact_001",
|
||||
"event_type": "artifact.created",
|
||||
"deployment_id": "dep_manager_123",
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"occurred_at": "2026-05-28T07:38:00Z",
|
||||
"correlation_id": "corr_123",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"artifact_id": "art_backend_patch_001",
|
||||
"artifact_type": "code_patch",
|
||||
"title": "Backend API patch",
|
||||
"summary": "新增普通 sub Runtime 联调接口",
|
||||
"uri": "azblob://heicode-artifacts/task-123/backend.patch",
|
||||
"mime_type": "text/x-diff",
|
||||
"size_bytes": 18420,
|
||||
"stage": "development",
|
||||
"checkpoint": "artifact_ready",
|
||||
"metadata": {
|
||||
"agent_role": "backend",
|
||||
"redacted": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 明文密钥禁止项
|
||||
|
||||
以下字段不能出现在 callback、artifact metadata、timeline、日志中:
|
||||
|
||||
- `password`
|
||||
- `token`
|
||||
- `secret`
|
||||
- `private_key`
|
||||
- `connection_string`
|
||||
- `access_key`
|
||||
- 明文数据库连接串
|
||||
- 明文模型网关 key
|
||||
- 明文 Git token
|
||||
|
||||
长期凭据只能传:
|
||||
|
||||
```text
|
||||
azkv://<vault>/secrets/<name>
|
||||
```
|
||||
|
||||
## 5. Usage / Cost 回传要求
|
||||
|
||||
Agent Manager 文档当前缺少真实 usage 字段。普通 sub 后续要支持模型费用、运行费用和审计归属,Runtime 必须回传至少以下字段。
|
||||
|
||||
可通过 `budget.alert`、`timeline.updated` 或专门的 `usage.updated` 事件回传。如果新增 `usage.updated`,需要提前和 Manager 对齐 schema。
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_usage_001",
|
||||
"event_type": "budget.alert",
|
||||
"deployment_id": "dep_manager_123",
|
||||
"agent_instance_id": "agi_backend_001",
|
||||
"occurred_at": "2026-05-28T07:39:00Z",
|
||||
"correlation_id": "corr_123",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"model_id": "model_xxx",
|
||||
"model_tokens": 12000,
|
||||
"prompt_tokens": 8000,
|
||||
"completion_tokens": 4000,
|
||||
"model_cost_usd": 0.23,
|
||||
"runtime_seconds": 180,
|
||||
"cpu_core_seconds": 36,
|
||||
"memory_mb_seconds": 92160,
|
||||
"billing_source": "newapi",
|
||||
"budget": {
|
||||
"max_tokens": 120000,
|
||||
"max_cost_usd": 8,
|
||||
"consumed_usd": 0.23,
|
||||
"remaining_usd": 7.77
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段要求:
|
||||
|
||||
| 字段 | 必需 | 说明 |
|
||||
|---|---|---|
|
||||
| `model_id` | 是 | 本次 Agent 调用的模型 |
|
||||
| `model_tokens` | 是 | 总 token |
|
||||
| `prompt_tokens` | 建议 | 输入 token |
|
||||
| `completion_tokens` | 建议 | 输出 token |
|
||||
| `model_cost_usd` | 是 | 可归属的模型成本 |
|
||||
| `runtime_seconds` | 是 | Agent 实际运行秒数 |
|
||||
| `cpu_core_seconds` | 建议 | 集群资源成本核算 |
|
||||
| `memory_mb_seconds` | 建议 | 集群资源成本核算 |
|
||||
| `billing_source` | 是 | `newapi` / `manager_wallet` / `manager_subscription` / 其他约定 |
|
||||
|
||||
注意:`budget.max_cost_usd` 是预算上限,不是已扣费金额。不能把预算当真实账单。
|
||||
|
||||
## 6. Approval Decision 接收要求
|
||||
|
||||
Manager 端已有 approval、credential lease、approve/reject 和 Runtime decision adapter。Agent Manager 需要提供接收审批结果的接口。
|
||||
|
||||
推荐接口:
|
||||
|
||||
```http
|
||||
POST /api/agent/deployments/{deployment_id}/approvals/{approval_id}
|
||||
Authorization: Bearer <HEICODE_SERVICE_TOKEN>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"approval_id": "apr_123",
|
||||
"decision": "approved",
|
||||
"manager_deployment_id": "dep_manager_123",
|
||||
"runtime_deployment_id": "dep_runtime_123",
|
||||
"operation": "git.write",
|
||||
"resource_type": "git",
|
||||
"resource_id": "repo_main",
|
||||
"risk_level": "high",
|
||||
"requires_credential": true,
|
||||
"credential_ref": "lease://agent/cred_123",
|
||||
"lease_id": "lease_123",
|
||||
"lease_expires_at": 1770000000000,
|
||||
"decided_by": "user_123",
|
||||
"reason": "允许本次写入",
|
||||
"decided_at": 1770000000000
|
||||
}
|
||||
```
|
||||
|
||||
要求:
|
||||
|
||||
- `approved` 后 Runtime 继续对应高危动作。
|
||||
- `rejected` 后 Runtime 停止该动作并回调 `timeline.updated` 或 `sk_tool.failed`。
|
||||
- 不要求 Manager 回传明文密钥,只能使用 `credential_ref` 或 `lease://...`。
|
||||
|
||||
## 7. Callback 重试策略需要说清楚
|
||||
|
||||
Agent Manager 文档当前有两种说法:
|
||||
|
||||
1. 当前发送失败只记录 warning,不阻塞任务执行。
|
||||
2. Runtime 推送失败时指数退避,最多重试 12 小时,超过进入死信队列。
|
||||
|
||||
请明确当前真实实现是哪一种:
|
||||
|
||||
| 能力 | 当前是否已实现 | 需要说明 |
|
||||
|---|---|---|
|
||||
| 失败重试 | 是/否 | 重试次数、间隔、最大时长 |
|
||||
| 死信队列 | 是/否 | 存储位置、人工重放方式 |
|
||||
| 幂等重放 | 是/否 | 是否复用原 `event_id` |
|
||||
| 失败告警 | 是/否 | 是否有日志、监控或告警 |
|
||||
|
||||
如果当前只 warning,不重试,请在文档中写成“当前未实现重试/死信,后续增强”,不要把建议方案写成已完成。
|
||||
|
||||
## 8. 联调验收步骤
|
||||
|
||||
Agent Manager 改完后,按下面步骤验收。
|
||||
|
||||
| 步骤 | 操作 | 通过标准 |
|
||||
|---:|---|---|
|
||||
| 1 | `GET /api/agent/health` | 返回 healthy |
|
||||
| 2 | `POST /api/agent/deployments` 创建普通 sub run | 返回 `deployment_id`、`status` |
|
||||
| 3 | 重复同一个 `X-Idempotency-Key` 创建 | 不重复创建,返回同一个 ID |
|
||||
| 4 | `GET /api/agent/deployments/{deployment_id}` | 返回真实状态和 agents |
|
||||
| 5 | Runtime 主动 callback `phase.changed` | Manager callback 返回 success |
|
||||
| 6 | Runtime 主动 callback `timeline.updated` | Manager timeline 可查到 |
|
||||
| 7 | Runtime 主动 callback `artifact.created` | Manager artifacts 可查到 |
|
||||
| 8 | Runtime 主动 callback `sk_tool.completed` | Manager SK/timeline 可查到 |
|
||||
| 9 | Runtime 主动 callback usage | Manager 能看到 usage 摘要或 callback event |
|
||||
| 10 | Runtime 主动 callback `approval.requested` | Manager pending approval 生成 |
|
||||
| 11 | Manager approve/reject | Agent Manager 收到 decision |
|
||||
| 12 | `POST /api/agent/deployments/{deployment_id}/stop` | Runtime 停止,状态变为 stopped |
|
||||
| 13 | 检查日志和 artifact metadata | 不包含明文密钥 |
|
||||
|
||||
## 9. 当前实测记录
|
||||
|
||||
2026-05-28 已测:
|
||||
|
||||
| 接口 | 结果 | 说明 |
|
||||
|---|---|---|
|
||||
| `GET http://20.212.121.126/api/agent/health` | 200 | Agent Manager IP 健康检查正常 |
|
||||
| `GET https://agent-manager.taijiagent.com/api/agent/health` | 暂不作为当前验收项 | 当前约定先走 IP,域名后续再切换 |
|
||||
| `POST https://code.xinghanlab.com/api/agent/callbacks/swarm-events` 无认证 | 业务返回 `CALLBACK_UNAUTHORIZED` | Manager callback 路由在线 |
|
||||
| `POST https://code.xinghanlab.com/api/agent/callbacks/swarm-events` 带旧 token 但空 body | 业务返回 `CALLBACK_INVALID` | 认证通过,进入事件校验 |
|
||||
| `GET https://code.xinghanlab.com/api/agent/callbacks/swarm-events/schema` | 404 | Manager schema GET 生产未通,Manager 侧需复核 |
|
||||
| `POST http://20.212.121.126/api/agent/deployments` | 200 | 普通 sub Runtime deployment 创建可用 |
|
||||
|
||||
### 9.1 2026-05-28 追加联调记录
|
||||
|
||||
本次按当前约定使用 Agent Manager IP `http://20.212.121.126`。
|
||||
|
||||
客户端完整用户态链路说明:
|
||||
|
||||
- 已尝试通过生产 Manager `/api/user/login` 获取用户 session,但手头用户名组合未登录成功。
|
||||
- 因此本次没有宣称“桌面客户端登录后走 Manager 用户态创建 deployment”完整通过。
|
||||
- 本次完成的是服务到服务联调:Manager/客户端等价 payload -> Agent Manager IP,以及 Agent Manager callback 协议 -> Heicode Manager callback 接收端。
|
||||
|
||||
Agent Manager `/api/agent/deployments` 服务到服务链路:
|
||||
|
||||
| 步骤 | 结果 | 证据 |
|
||||
|---|---|---|
|
||||
| `GET /api/agent/health` | 通过 | 返回 `success=true`、`status=healthy` |
|
||||
| `POST /api/agent/deployments` | 通过 | 返回 `deployment_id=dep_dbafd1ac37c3`,状态 `pending` |
|
||||
| `GET /api/agent/deployments/{deployment_id}` | 通过 | 能查到 `user_id`、`binding_scope`、`sub_mode=agile`、`callback_configured=true` |
|
||||
| `GET /api/agent/deployments/{deployment_id}/events` | 部分通过 | 只看到 `deployment.accepted`,未看到 `phase.changed/timeline.updated/artifact.created/sk_tool.*` |
|
||||
| `GET /api/agent/deployments/{deployment_id}/logs` | 部分通过 | 返回系统日志 `Pod ... has no logs yet` |
|
||||
| `GET /api/agent/deployments/{deployment_id}/metrics` | 通过但疑似占位 | 返回 CPU/内存/网络指标,但值看起来是固定模拟值,需要 Runtime 说明来源 |
|
||||
| `POST /api/agent/deployments/{deployment_id}/stop` | 通过 | `dep_dbafd1ac37c3` 停止成功,返回 `status=stopped` |
|
||||
|
||||
长等待测试:
|
||||
|
||||
| 项 | 结果 |
|
||||
|---|---|
|
||||
| 测试 deployment | `dep_cd170573cf47` |
|
||||
| 等待时间 | 约 2 分钟 |
|
||||
| 最终状态 | 已清理停止 |
|
||||
| 事件结果 | 只有 `deployment.accepted` 和 `deployment.stopped` |
|
||||
| 未观察到 | `phase.changed`、`timeline.updated`、`artifact.created`、`agent.started/completed`、`sk_tool.called/completed` |
|
||||
| 结论 | Agent Manager 文档声称的“Runtime 主动推送 status/phase/timeline/agent/tool/artifact 事件”在本次实测中没有跑出来,需要 Agent Manager 继续排查 |
|
||||
|
||||
Heicode Manager callback 接收端:
|
||||
|
||||
| 步骤 | 结果 | 证据 |
|
||||
|---|---|---|
|
||||
| 无认证 POST callback | 通过预期 | 返回 `CALLBACK_UNAUTHORIZED` |
|
||||
| 带旧 token 但缺事件字段 | 通过预期 | 返回 `CALLBACK_INVALID`,说明认证通过并进入业务校验 |
|
||||
| 带旧 token 发送合法 `timeline.updated` | 通过 | 返回 `success=true`、`inserted=true` |
|
||||
| 重复发送同一 `event_id` | 通过 | 返回 `deduplicated=true`、`inserted=false` |
|
||||
|
||||
本次合法 callback 测试事件:
|
||||
|
||||
```text
|
||||
event_id=evt_agent_manager_ip_smoke_1779954828884
|
||||
event_type=timeline.updated
|
||||
runtime_deployment_id=dep_cd170573cf47
|
||||
source=agent-manager-ip-smoke
|
||||
```
|
||||
|
||||
结论:
|
||||
|
||||
1. Heicode Manager callback 接收端可用,旧 token 认证和幂等可用。
|
||||
2. Agent Manager IP 的 `/api/agent/deployments` 创建、查询、停止可用。
|
||||
3. Agent Manager 当前没有在实测中产生普通 sub 所需的 phase/timeline/artifact/SK 主动回调。
|
||||
4. 因没有可用生产 Manager 用户 session,本次没有完成“客户端登录态 -> Manager 用户态 deployment -> Runtime”的完整端到端测试。
|
||||
|
||||
### 9.2 2026-05-28 测试用户客户端模拟链路
|
||||
|
||||
测试用户:
|
||||
|
||||
```text
|
||||
email: zsbgnw@gmail.com
|
||||
username: chenchen
|
||||
user_id: 22
|
||||
group: default
|
||||
```
|
||||
|
||||
说明:密码只用于本次登录测试,不写入本文档。
|
||||
|
||||
本次已完成“客户端模拟 -> Heicode Manager 生产用户态接口 -> Agent Manager IP Runtime”链路。
|
||||
|
||||
| 步骤 | 结果 | 证据 |
|
||||
|---|---|---|
|
||||
| 登录生产 Manager | 通过 | `/api/user/login` 返回 `success=true`,用户 `id=22` |
|
||||
| 查询用户信息 | 通过 | `/api/user/self` 返回用户 `chenchen`、`group=default` |
|
||||
| 查询 Runtime 健康 | 通过 | `/api/agent/runtime/health` 返回 `enabled=true`、`configured=true`、`status=healthy`、`create_path=/api/agent/deployments`、远端为 Agent Manager IP |
|
||||
| 客户端模拟创建 deployment | 通过 | `POST /api/agent/user/deployments` 返回 Manager deployment `dep_1ba14ccfb558` |
|
||||
| Manager -> Agent Manager create | 通过 | Manager detail 写回 `runtime_deployment_id=dep_3335e54e9bdf`,`runtime_state=pending` |
|
||||
| Manager 用户态 events | 通过 | 出现 `deployment.accepted`、`runtime.sync.started`、`runtime.sync.accepted` |
|
||||
| Manager 用户态 logs | 通过 | 出现 control-plane 日志和 runtime sync 日志,均为 redacted |
|
||||
| Manager 用户态 metrics | 部分通过 | 返回 `platform_estimated=true`,说明是 Manager 估算/占位,不是 Runtime 真实资源指标 |
|
||||
| Manager 用户态 artifacts | 未产出 | 返回空列表 |
|
||||
| Manager 用户态 timeline | 部分通过 | 能返回 deployment/events,但 callbacks/artifacts 为空 |
|
||||
| Manager stop | 通过 | `POST /api/agent/user/deployments/dep_1ba14ccfb558/stop` 返回 `status=stopped` |
|
||||
| Runtime stop 结果 | 通过 | 直查 Agent Manager `dep_3335e54e9bdf`,状态为 `stopped` |
|
||||
|
||||
本次真实 ID:
|
||||
|
||||
```text
|
||||
manager_deployment_id=dep_1ba14ccfb558
|
||||
runtime_deployment_id=dep_3335e54e9bdf
|
||||
correlation_id=manager-client-sim-1779955103016
|
||||
runtime_agent_instance_id=agi_ed399bf8cc70
|
||||
```
|
||||
|
||||
Agent Manager 侧直查 `dep_3335e54e9bdf`:
|
||||
|
||||
| 接口 | 结果 |
|
||||
|---|---|
|
||||
| `GET /api/agent/deployments/dep_3335e54e9bdf` | 200,状态 `stopped`,`user_id=22` |
|
||||
| `GET /api/agent/deployments/dep_3335e54e9bdf/events` | 200,仅有 `deployment.accepted`、`deployment.stopped` |
|
||||
| `GET /api/agent/deployments/dep_3335e54e9bdf/logs` | 200,仅有 `Pod ... has no logs yet` |
|
||||
| `GET /api/agent/deployments/dep_3335e54e9bdf/metrics` | 200,返回 CPU/内存/网络固定值 |
|
||||
|
||||
本次客户端模拟链路结论:
|
||||
|
||||
1. 测试用户登录、Manager 用户态接口、Manager Runtime bridge、Agent Manager create、Agent Manager stop 均已真实跑通。
|
||||
2. Manager 能拿到 Runtime 健康状态,并能把用户态 deployment 同步到 Agent Manager IP。
|
||||
3. Manager stop 能传递到 Agent Manager,Runtime deployment 已停止。
|
||||
4. Agent Manager 仍未真实产生普通 sub 必需的阶段、timeline、artifact、SK 工具和 usage 回调。
|
||||
5. 当前 metrics/logs 更像 Runtime 占位数据:日志显示 `Pod ... has no logs yet`,metrics 为固定 CPU/内存/网络值。
|
||||
6. 本次 Manager 请求中的 agile context 没有在 Runtime 详情中表现为有效阶段推进,Runtime 事件里 `agile_context` 为空字段,需要双方继续核对字段解析和透传。
|
||||
|
||||
## 10. 完成定义
|
||||
|
||||
只有满足以下条件,才能认为普通 sub 敏捷 Runtime 联调完成:
|
||||
|
||||
1. Manager 能创建 Runtime run,并保存 Runtime 返回的 `deployment_id`。
|
||||
2. Runtime 能主动回调 Manager,且 callback 通过认证、幂等、脱敏和 schema 校验。
|
||||
3. Manager 的 artifacts / timeline / sk-snapshots / events 能看到 Runtime 回传数据。
|
||||
4. Manager 发起 stop 后 Runtime 真实停止。
|
||||
5. Runtime 高危审批能暂停,Manager approve/reject 后 Runtime 收到 decision 并继续或停止。
|
||||
6. Runtime usage / cost 能按 user、deployment、task、agent role、model 归属。
|
||||
7. 整个流程不传递、不记录明文长期密钥。
|
||||
@@ -1,372 +0,0 @@
|
||||
# Heicode 客户端 — 登录接口对接文档
|
||||
|
||||
**版本**: v1.0
|
||||
**生效日期**: 2026-04-30
|
||||
**状态**: 已上线生产,已通过端到端测试
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述 Heicode 客户端(桌面/CLI)与 Heicode Manager(即 mcp-server)之间的**登录认证接口**。共 4 个接口,覆盖完整登录生命周期:
|
||||
|
||||
|
||||
| 接口 | 用途 |
|
||||
| ------------------------ | ----------------------- |
|
||||
| `POST /api/auth/login` | 账号密码登录,换取 token |
|
||||
| `GET /api/auth/me` | 校验 token 有效性 + 获取当前用户资料 |
|
||||
| `POST /api/auth/refresh` | access token 过期时换新的 |
|
||||
| `POST /api/auth/logout` | 登出(token 加入黑名单) |
|
||||
|
||||
|
||||
> 不在本期范围:注册、找回密码、改密码 — 这些走官网 web 端完成。
|
||||
|
||||
---
|
||||
|
||||
## 2. 接入信息
|
||||
|
||||
### 2.1 Base URL
|
||||
|
||||
生产环境通过 Azure APIM 网关接入:
|
||||
|
||||
```
|
||||
https://apimtaiji.azure-api.net/api/mcp
|
||||
```
|
||||
|
||||
完整路径示例:
|
||||
|
||||
```
|
||||
POST https://apimtaiji.azure-api.net/api/mcp/api/auth/login
|
||||
```
|
||||
|
||||
### 2.2 通用请求头
|
||||
|
||||
|
||||
| Header | 必填 | 说明 |
|
||||
| -------------------------------- | ----------- | -------------- |
|
||||
| `Content-Type: application/json` | 是(POST/PUT) | 请求体 JSON |
|
||||
| `Authorization: Bearer <token>` | 受保护接口必填 | 见 §3 |
|
||||
| `X-Request-Id: <uuid>` | 建议 | 全链路追踪 ID,客户端生成 |
|
||||
|
||||
|
||||
### 2.3 Token 模型
|
||||
|
||||
登录成功返回两个 token:
|
||||
|
||||
|
||||
| Token | 用途 | 有效期 |
|
||||
| ----------------- | ------------------------ | ----- |
|
||||
| **Access Token** | 调业务接口(含 `/me`、`/logout`) | 24 小时 |
|
||||
| **Refresh Token** | 仅用于 `/refresh` 换新 access | 7 天 |
|
||||
|
||||
|
||||
JWT claims 包含:`sub`(user_id)、`email`、`role`、`channelId`、`type`(access/refresh)、`iat`、`exp`。
|
||||
|
||||
---
|
||||
|
||||
## 3. 接口详情
|
||||
|
||||
### 3.1 POST /api/auth/login — 登录
|
||||
|
||||
**请求**
|
||||
|
||||
```http
|
||||
POST /api/auth/login HTTP/1.1
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "YourPassword123",
|
||||
"role": "user"
|
||||
}
|
||||
```
|
||||
|
||||
字段:
|
||||
|
||||
- `email` (string, 必填)
|
||||
- `password` (string, 必填)
|
||||
- `role` (string, 必填):Heicode 客户端**固定传 `"user"`**
|
||||
|
||||
**成功响应 200**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"user": {
|
||||
"id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
|
||||
"name": "张三",
|
||||
"email": "user@example.com",
|
||||
"role": "user",
|
||||
"channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应**
|
||||
|
||||
|
||||
| HTTP | 含义 | 客户端处理建议 |
|
||||
| ---- | ------------------------- | -------------------------------- |
|
||||
| 401 | 邮箱或密码错误 | 显示"账号或密码错误",让用户重新输入 |
|
||||
| 403 | 账户已被禁用 | 提示用户联系管理员 |
|
||||
| 429 | 登录尝试过于频繁(**每 IP 5 次/分钟**) | 显示倒计时;响应头 `Retry-After: 60` 表示秒数 |
|
||||
| 422 | 请求体校验失败(邮箱格式不合法等) | 检查 `detail` 字段 |
|
||||
| 500 | 服务异常 | 重试或提示稍后再试 |
|
||||
|
||||
|
||||
**重要:限流规则**
|
||||
|
||||
- **每 IP 每分钟最多 5 次**登录尝试(不区分成功失败)
|
||||
- 超出返回 **429 Too Many Requests**,含 `Retry-After` 头(秒)
|
||||
- 计数滑动窗口,60 秒后自动恢复
|
||||
|
||||
---
|
||||
|
||||
### 3.2 GET /api/auth/me — 获取当前用户
|
||||
|
||||
客户端**启动时**应调用此接口校验本地缓存的 access token 是否仍有效,并刷新用户信息。
|
||||
|
||||
**请求**
|
||||
|
||||
```http
|
||||
GET /api/auth/me HTTP/1.1
|
||||
Authorization: Bearer <accessToken>
|
||||
```
|
||||
|
||||
**成功响应 200**
|
||||
|
||||
```json
|
||||
{
|
||||
"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-04-30T06:38:14.765457"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应**
|
||||
|
||||
|
||||
| HTTP | 含义 | 客户端处理建议 |
|
||||
| ---- | --------------------- | ------------------------------------------ |
|
||||
| 401 | Token 无效/过期/已登出/用户不存在 | 调 `/refresh` 换新 token;若 refresh 也 401,跳登录页 |
|
||||
| 403 | 账户已被禁用 | 强制登出,提示联系管理员 |
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 3.3 POST /api/auth/refresh — 刷新 token
|
||||
|
||||
access token 接近或已过期时调用,使用 **refresh token** 换取新的 access + refresh token 对。
|
||||
|
||||
**请求**
|
||||
|
||||
```http
|
||||
POST /api/auth/refresh HTTP/1.1
|
||||
Authorization: Bearer <refreshToken>
|
||||
```
|
||||
|
||||
> ⚠️ **必须传 refresh token**,传 access token 会被拒绝。
|
||||
|
||||
**成功响应 200**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"refreshToken": "eyJhbGciOiJIUzI1NiIs..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
客户端收到新的 token 对后**应替换本地缓存**(包括 refresh token,旧的也作废)。
|
||||
|
||||
**错误响应**
|
||||
|
||||
|
||||
| HTTP | 含义 | 客户端处理建议 |
|
||||
| ---- | ---------------------------------------- | ------- |
|
||||
| 401 | refresh token 无效 / 过期 / 错传了 access token | 跳登录页 |
|
||||
|
||||
|
||||
实施细节:
|
||||
|
||||
- 服务端会校验 token claims `type == "refresh"`,否则拒绝
|
||||
- 旧 refresh token 不会被立即吊销(容许并发换发期),但客户端应丢弃旧的
|
||||
|
||||
---
|
||||
|
||||
### 3.4 POST /api/auth/logout — 登出
|
||||
|
||||
将当前 access token 加入黑名单,使其立即失效。
|
||||
|
||||
**请求**
|
||||
|
||||
```http
|
||||
POST /api/auth/logout HTTP/1.1
|
||||
Authorization: Bearer <accessToken>
|
||||
```
|
||||
|
||||
**成功响应 200**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": null,
|
||||
"message": "登出成功"
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应**
|
||||
|
||||
logout 容错性较强,token 黑名单写入失败也会返回 200(前端清理本地 token 即可)。
|
||||
|
||||
**客户端登出流程**:
|
||||
|
||||
1. 调 `/api/auth/logout`
|
||||
2. 清除本地存储的 access + refresh token
|
||||
3. 清除当前用户资料缓存
|
||||
4. 跳转到登录页
|
||||
|
||||
---
|
||||
|
||||
## 4. 完整登录流程(示例)
|
||||
|
||||
### 启动时
|
||||
|
||||
```
|
||||
┌─ 本地有 access token ?
|
||||
│
|
||||
├─ 是 ─→ GET /me
|
||||
│ ├─ 200 ─→ 进入主界面
|
||||
│ └─ 401 ─→ 本地有 refresh token ?
|
||||
│ ├─ 是 ─→ POST /refresh
|
||||
│ │ ├─ 200 ─→ 替换 token,进入主界面
|
||||
│ │ └─ 401 ─→ 跳登录页
|
||||
│ └─ 否 ─→ 跳登录页
|
||||
│
|
||||
└─ 否 ─→ 跳登录页
|
||||
```
|
||||
|
||||
### 登录页提交
|
||||
|
||||
```
|
||||
POST /login
|
||||
├─ 200 ─→ 存 token 对,进主界面
|
||||
├─ 401 ─→ 显示"账号或密码错误"
|
||||
├─ 429 ─→ 显示"尝试过于频繁,请 N 秒后重试"(N 取响应头 Retry-After)
|
||||
└─ 其他 ─→ 显示通用错误
|
||||
```
|
||||
|
||||
### 业务请求过程中 access token 过期
|
||||
|
||||
```
|
||||
任意业务接口返回 401
|
||||
└─→ POST /refresh (用 refresh token)
|
||||
├─ 200 ─→ 替换 token,重试原请求
|
||||
└─ 401 ─→ 清理 token,跳登录页
|
||||
```
|
||||
|
||||
### 登出按钮
|
||||
|
||||
```
|
||||
POST /logout
|
||||
└─→ 不论结果都清理本地 token,跳登录页
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 错误响应格式
|
||||
|
||||
当前为 FastAPI 默认格式(下个版本 `/api/v1/*` 路径会改为标准 envelope,本期保留兼容):
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "邮箱或密码错误"
|
||||
}
|
||||
```
|
||||
|
||||
422 校验错误格式(Pydantic):
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "value_error",
|
||||
"loc": ["body", "email"],
|
||||
"msg": "value is not a valid email address: ...",
|
||||
"input": "abc"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 安全注意事项
|
||||
|
||||
|
||||
| 项 | 说明 |
|
||||
| -------------- | -------------------------------------------------------------------------------------- |
|
||||
| **token 存储** | 桌面应用建议存到 OS 安全凭据存储(Windows Credential Manager / macOS Keychain / Linux Secret Service) |
|
||||
| **HTTPS 强制** | 生产 base URL 已是 HTTPS;客户端**禁止**回退 HTTP |
|
||||
| **token 泄露应对** | 用户怀疑泄露时提示去官网 web 端改密码(改密会导致所有 session 黑名单) |
|
||||
| **审计日志** | 所有 login 尝试(成功/失败)服务端均写审计 |
|
||||
| **状态码不泄漏** | 错误信息已统一用"邮箱或密码错误",不区分账号是否存在,防爆破 |
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 7. 测试账号(仅供联调)
|
||||
|
||||
|
||||
| 角色 | 邮箱 | 密码 |
|
||||
| ---- | ----------- | ------------ |
|
||||
| 普通用户 | `55@55.com` | `By@123456.` |
|
||||
|
||||
|
||||
> ⚠️ 测试账号仅用于联调阶段,正式上线前请务必关闭。
|
||||
|
||||
---
|
||||
|
||||
## 8. 已上线生产验证清单
|
||||
|
||||
|
||||
| 测试项 | 结果 |
|
||||
| ------------------------------------------ | --- |
|
||||
| login 200 + 返回 access/refresh token | ✅ |
|
||||
| /me 用 access token → 200 + 完整 profile | ✅ |
|
||||
| /refresh 用 refresh token → 200 + 新 token 对 | ✅ |
|
||||
| /refresh 用 access token → 401 拒绝 | ✅ |
|
||||
| logout → 200 | ✅ |
|
||||
| logout 后旧 token 调 /me → 401(黑名单生效) | ✅ |
|
||||
| 连续 7 次错密 → 第 6 次起 429(每 IP 5/min 限流) | ✅ |
|
||||
| 服务器审计日志记录所有 login(含成功/失败) | ✅ |
|
||||
|
||||
|
||||
镜像 digest: `sha256:339b64ae090dc81fa13cb29705958167e77fe0698e27ac227c05054ed5c42309`
|
||||
镜像 tag: `taiji.azurecr.io/mcp-server:heicode-auth-fix2-20260430`
|
||||
部署日期: 2026-04-30
|
||||
|
||||
---
|
||||
|
||||
## 9. 联系
|
||||
|
||||
如对接过程发现接口行为与本文档不一致,请联系 Heicode Manager 后端团队,附上:
|
||||
|
||||
- 请求完整 URL / Headers / Body
|
||||
- 响应 HTTP 状态 + Body
|
||||
- `X-Request-Id` 头值(便于服务端按 ID 反查日志)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
> 生产地址:`https://code.xinghanlab.com`
|
||||
> 状态图例:🟢 已实现并生产验证 · 🔴 待建(依赖 AM)
|
||||
|
||||
> **本文取代旧的 `heicode-desktop-unified-api.md`**(那份描述的是已下线的 sub 任务编排模型:tasks/workflow/display_status/git_ref/产物下载等,均已删除)。新客户端一律按本文对接。
|
||||
> **本文取代旧的桌面 sub 任务编排接口文档**(描述 tasks/workflow/display_status/git_ref/产物下载的那套已下线,相关 md 已删除)。新客户端一律按本文对接。
|
||||
|
||||
---
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,232 +0,0 @@
|
||||
# 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`](./heicode-desktop-unified-api.md)。
|
||||
|
||||
本演练验证的核心结论:**Sub Agile 任务跑完后,agent_management 产出的是真实代码文件 + 目录结构**,Manager 解析成 `project_folder`,客户端可拿到「文件树 / 单文件正文 / 整包 zip」,zip 解压即真实文件夹。
|
||||
|
||||
---
|
||||
|
||||
## 0. 角色与链路
|
||||
|
||||
```text
|
||||
桌面客户端 ──(只调 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 翻译成编排计划并创建。
|
||||
|
||||
**请求**
|
||||
```http
|
||||
POST /api/heicode/sub-agile/tasks
|
||||
Content-Type: application/json
|
||||
```
|
||||
```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"]
|
||||
}
|
||||
```
|
||||
|
||||
**响应(真实)**
|
||||
```json
|
||||
{ "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. 轮询工作流,直到终态
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/workflow
|
||||
```
|
||||
|
||||
运行中每 3–5 秒轮询一次,终态后停止。本次真实轨迹:
|
||||
|
||||
```text
|
||||
poll 1: display_status = accepted
|
||||
poll 2: display_status = running
|
||||
poll 3: display_status = completed <- 终态
|
||||
```
|
||||
|
||||
**workflow 响应(真实,节选)**
|
||||
```json
|
||||
{ "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. 取产物列表(确认是项目而非文本)
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts
|
||||
```
|
||||
|
||||
**响应(真实,节选)**
|
||||
```json
|
||||
{ "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,含目录层级)
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/manifest
|
||||
```
|
||||
|
||||
**响应(真实)**
|
||||
```json
|
||||
{ "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. 取单文件正文(确认是真代码)
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/files?path=backend%2Fmain.py
|
||||
```
|
||||
|
||||
**响应(真实,节选)**
|
||||
```python
|
||||
# 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(确认解压是真实文件夹)
|
||||
|
||||
**请求**
|
||||
```http
|
||||
GET /api/heicode/sub-agile/tasks/dep_39e53ee4c692/artifacts/art_swm_826fe9814483_backend_1/archive
|
||||
```
|
||||
|
||||
**响应头(真实)**
|
||||
```text
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/zip
|
||||
Content-Disposition: attachment; filename="art_swm_826fe9814483_backend_1.zip"
|
||||
Content-Length: 896
|
||||
```
|
||||
|
||||
**解压后真实落盘结构**
|
||||
```text
|
||||
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`,故默认是「当前阶段」一条;待上报阶段历史后展开。
|
||||
@@ -1,601 +0,0 @@
|
||||
# Heicode 桌面客户端统一接口对接文档(v0.1)
|
||||
|
||||
> ⛔ **已废弃(2026-06-04)**:本文描述的是**已下线的 sub 任务编排模型**(tasks/workflow/display_status/git_ref/产物下载/部署租约等,相关后端已删除)。
|
||||
> **新客户端请改用 [`heicode-desktop-client-api.md`](./heicode-desktop-client-api.md)(模板 Agent 模型)。** 本文仅作历史留存。
|
||||
|
||||
更新时间:2026-06-03
|
||||
适用范围:Heicode Desktop 对接 Heicode Manager 的**统一接口层**(Sub Agile / Swarm 两模式)。端到端流程与三端职责以 [`heicode-sub-mode-flow-spec.md`](./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`](./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 推荐完整流程
|
||||
|
||||
```text
|
||||
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("")`:
|
||||
```text
|
||||
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`
|
||||
无需登录,返回模式与模型目录。
|
||||
|
||||
```json
|
||||
{ "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) | 引导充值 |
|
||||
|
||||
```text
|
||||
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` 互补,按分组过滤) |
|
||||
|
||||
```json
|
||||
// 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 并创建。
|
||||
|
||||
```json
|
||||
{
|
||||
"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}`):
|
||||
|
||||
```json
|
||||
{ "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`:
|
||||
|
||||
```json
|
||||
{ "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` 返回客户端右侧面板需要的三层状态对象:
|
||||
|
||||
```json
|
||||
{ "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 快照 |
|
||||
|
||||
```json
|
||||
// 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"}] }
|
||||
```
|
||||
```json
|
||||
// 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 回调实时转发给客户端,**只推运行信息**(不推产物文件)。统一事件信封:
|
||||
|
||||
```json
|
||||
{ "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`:
|
||||
|
||||
```json
|
||||
"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 }`
|
||||
|
||||
响应:
|
||||
```json
|
||||
{ "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):
|
||||
```json
|
||||
{ "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 侧补齐后无需改协议直接对齐。本清单即"整个流程要用到的接口"的核查表——发现遗漏请回填本表对应分组。
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> 更新时间:2026-06-03
|
||||
> 范围:**HM 端**(后端 + 网页控制台)在「模板 agent + 客户端直连」新模型下的改造清单。
|
||||
> 关联文档:`heicode-sub-mode-flow-spec.md`、`heicode-desktop-unified-api.md`(这两份的旧「sub 任务编排」内容将按本文裁剪)。
|
||||
> 关联文档:客户端对接见 `heicode-desktop-client-api.md`;旧代码清理见 `heicode-hm-legacy-teardown.md`。(旧的「sub 任务编排」设计文档 heicode-sub-mode-flow-spec.md / heicode-desktop-unified-api.md 等已删除。)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
# Heicode Sub 模式 端到端流程与三端规范(v0.1 草案)
|
||||
|
||||
> **2026-06-03 产物模型钉死(最重要的认知)**:
|
||||
> - **sub 模式强制绑定 git** 才能用(未绑 git 只能走客户端本地模式,进不了 sub)。
|
||||
> - **最终产物只存在于用户自己的 git 仓库**。**没有"下载产物"这回事**——不存在 `project_folder` / `manifest` / `files` / `archive` zip / `local-edits` 回传这一整套(已全部退役)。要代码就 `git clone/pull`。
|
||||
> - **运行期间 HM 流式给客户端的,只有"运行信息"**:日志(user_logs/debug_logs)、状态(display_status + 三层状态)、work 视图杂项(每个 agent 在做什么、跑了什么工具、改了哪些文件、阶段进度、测试输出等)。这些是**给人看的过程信息,不是可下载交付物**。
|
||||
> - HM 眼里的 "artifact" 退化成**交付/完成记录**(带 `git_ref`、改了哪些文件、`source_agent_role` 等元数据),仅用于 ① `display_status` 的"有无真交付"防空壳核对、② 在 work 视图里展示;**客户端不从 HM 下载任何产物文件**。
|
||||
>
|
||||
> 更新时间:2026-06-03(产物模型对齐)/ 2026-06-02(初稿)
|
||||
> 范围:**Sub(普通子代理协作)模式**——桌面客户端(一个像 Claude Code 的智能体程序)把一个**多 agent 重活外包到云端 agent_management**:客户端发起 → 经 Heicode Manager(模型网关 + 控制面)→ agent_management 多 agent 并行执行 → 流式回客户端展示的**完整闭环**,含资源绑定、git 仓库、产物合并、修改/重做、部署。
|
||||
> 前提认知(**务必先读 §0**):客户端本身能本地跑 agent;**sub 模式是把大任务派到云端,不是客户端唯一的干活方式**;**模型统一由 HM 的 `/v1/*` 提供给客户端和 AM 两边**。
|
||||
> 目的:**统筹三端(桌面客户端 / Heicode Manager / agent_management)的颗粒度与理解**,作为三方共同对齐的权威流程文档与契约规范。
|
||||
> 性质:本文是**目标设计** + **现状标注**。每节用标记区分:
|
||||
> - 🟢 **已实现**(当前代码/线上已具备)
|
||||
> - 🟡 **部分实现**(有基础,缺字段/流式/打通)
|
||||
> - 🔴 **待建**(目标态,尚未实现)
|
||||
> - ❓ **待决策**(需产品/三端确认的设计点,附我的建议)
|
||||
|
||||
相关文档:客户端对接接口见 [`heicode-desktop-unified-api.md`](./heicode-desktop-unified-api.md);runtime 契约见 agent_management《Sub Mode Runtime 对接指南》。
|
||||
|
||||
---
|
||||
|
||||
## 0. 术语与三端角色(先把名字钉死,避免歧义)
|
||||
|
||||
> ⚠️ **名字钉死**:本文用 **HM** = Heicode Manager(那个 Go 网关),用 **AM** = agent_management(就是你口中的「Agent Manager / Sub Mode Runtime」)。两者**完全是两个不同的服务**,本文不再用模糊的「Manager」一词。三方按下表对号入座。
|
||||
|
||||
| 简称 | 全名 | 是什么 | 栈 |
|
||||
|---|---|---|---|
|
||||
| **客户端** | 桌面客户端 cc-haha / Desktop | **像 Claude Code 那样的智能体编程程序**:本地自己能跑 agent、写代码、执行命令。用模型时**调 HM 的模型接口** | TS(Tauri+React/CLI) |
|
||||
| **HM** | **Heicode Manager** | **① 模型调用网关(new-api)**——给「客户端」和「AM」**两边都提供模型调用接口 `/v1/*`**(鉴权/计费/路由都在这);**② 控制面 / 状态裁判 / 凭据中介**。HM 自己不跑 agent、不执行命令、不连 VM | Go(Gin/GORM) |
|
||||
| **AM** | **agent_management**(= 你说的 Agent Manager / Sub Mode Runtime,在 `20.212.121.126`) | **云端多 agent 运行时**:把任务拆成多 agent 并行干活、写代码、git 入库;这些 agent **也是调 HM 的模型接口 `/v1/*`** 来用模型 | 独立服务 |
|
||||
|
||||
> **「AI」从哪来**:AI = 模型。**模型统一由 HM 的 `/v1/*` 提供**。**智能体执行(跑 agent)发生在两处**:本地(桌面客户端,像 Claude Code)和云端(AM,sub 模式多 agent)。两边都**通过 HM 调模型**。HM 是大家共用的**模型网关**,自己不当 agent。
|
||||
|
||||
### 0.1 关键能力边界(谁跑 agent / 谁提供模型 / 谁执行命令)
|
||||
|
||||
| 能力 | 客户端 | **HM** | **AM** |
|
||||
|---|---|---|---|
|
||||
| 智能体程序 / 跑 agent | ✅ 本地跑(像 Claude Code) | ❌ 不跑 agent | ✅ 云端跑多 agent |
|
||||
| **提供模型调用接口 `/v1/*`** | ❌(是调用方) | ✅ **是模型网关,给客户端和 AM 都提供** | ❌(是调用方) |
|
||||
| 调模型 | ✅ 调 HM `/v1/*` | —(被调方) | ✅ 调 HM `/v1/*` |
|
||||
| 本地执行命令 / 部署 / 看 VM 日志 | ✅ 在用户机器上执行(像 Claude Code) | **❌ 从不执行、不连 VM** | ❌(AM 在自己沙箱产代码,不部署用户 VM) |
|
||||
| 解密验签 / 鉴权 / 计费 | ❌ | ✅ | ❌ |
|
||||
| 裁决 display_status | ❌ | ✅ **唯一裁判** | ❌(只报执行事实) |
|
||||
| 托管凭据(KV)/ 发短期凭据 | ❌ | ✅ | ❌ |
|
||||
|
||||
> **澄清几个之前易错的点**:
|
||||
> - **HM 不部署、不执行命令、不连 VM、不看 VM 日志**——它是模型网关 + 控制面,不是执行器。
|
||||
> - **部署到用户 VM + 在 VM 看日志 = 客户端**自己在用户机器上干(像 Claude Code 本地执行;用户确认后 HM 只把短期凭据加密发给客户端)。
|
||||
> - **sub 模式 = 把多 agent 任务派到云端 AM 跑**(区别于客户端本地自己跑一个小任务);AM 的 agent 调 HM 用模型,流式回 HM,HM 裁决后回客户端。
|
||||
|
||||
### 0.2 sub 模式是什么、什么时候用(既然客户端本地就能跑 agent)
|
||||
|
||||
> 关键澄清:客户端本身能在**本地**跑智能体(像 Claude Code)完成小/快任务。那为什么还要 sub?
|
||||
|
||||
- **本地模式**(客户端自己):在用户机器上跑单个/轻量 agent,适合小改动、即时、交互式。**计算在用户机器上**。
|
||||
- **sub 模式**(本文主题):客户端把一个**更大的、需要多 agent 并行协作、或希望云端异步跑(关掉电脑也继续)**的任务,**派发到云端 AM** 执行。**计算在云端 AM**,多 agent 并行(backend/frontend/reviewer 同时干)。
|
||||
- **两种模式的模型都走 HM `/v1/*`**,鉴权 + 计费统一在 HM。
|
||||
- **sub 模式下客户端的角色** = **发起任务 + 实时看 work + 本地看/改产物 + 本地执行部署**;真正的 codegen 多 agent 在云端 AM。客户端不在 sub 模式里本地跑 codegen agent(那是本地模式)。
|
||||
|
||||
> 一句话:**sub = 把多 agent 重活外包到云端 AM;客户端当指挥台 + 取货 + 本地部署。本地模式 = 客户端自己干小活。模型两边都问 HM 要。**
|
||||
|
||||
### 0.3 三端铁律
|
||||
1. 客户端**任务/控制走 HM**(`/api/heicode/*`、`/api/agent/*`),模型走 HM(`/v1/*`),**禁止直连 AM** / Runtime artifact。
|
||||
2. **HM 是唯一状态裁判**,客户端只消费 `display_status`(定义见 §6)。
|
||||
3. 凭据只进 **Azure Key Vault**,全链路只传/存 `secret_ref`,明文绝不落库/日志/回调。
|
||||
4. **HM 不执行任何命令、不部署、不连 VM、不跑 agent**;agent 执行在云端 AM(sub 任务期)或客户端本地(本地模式 / 部署期)。模型由 HM 提供给两边。
|
||||
|
||||
---
|
||||
|
||||
## 1. 端到端总体流程(时序)
|
||||
|
||||
```text
|
||||
┌── 桌面客户端 ──┐ ┌──── Heicode Manager ────┐ ┌── agent_management ──┐
|
||||
│ │ │ │ │ │
|
||||
│ 0 选 sub 模式 │ │ │ │ │
|
||||
│ 0.5 (可选)绑 git/vm/db ─┼─► 资源绑定→Key Vault │ │ │
|
||||
│ │ V2加密 │ 存 secret_ref │ │ │
|
||||
│ 1 填需求包 ────┼───────►│ 2 解密+验签+鉴权+配额 │ │ │
|
||||
│ │ │ 3 需求包→orchestration ├──────► │ 4 拆分多 agent │
|
||||
│ │ │ _plan + 注入资源授权 │ HMAC │ 分配角色/模型 │
|
||||
│ │ │ │ │ 5 各 agent 干活: │
|
||||
│ │ │ │ ◄──────┤ 流式回调状态/日志/ │
|
||||
│ 7 轮询/订阅 ◄──┼────────┤ 6 收敛三层状态+运行信息 │ callback│ 状态/日志/work + │
|
||||
│ 展示 work(只有 │ │ 裁决 display_status │ │ git 入库 + push │
|
||||
│ 日志/状态/work)│ │ (只转发运行信息) │ │ 8 各 agent 代码→分支 │
|
||||
│ │ │ │ │ 9 合并→交付分支(git) │
|
||||
│ 10 看产物 ─────┼──git──► (直接 git clone/pull 用户 │ ◄──────┤ push 用户仓库 + │
|
||||
│ 只走 git │ 自己的仓库; 不经 HM) │ git_ref │ 回调 git_ref 通知 HM │
|
||||
│ 11 不满意 ─────┼───────►│ /messages | /execute ├──────► │ 12 修改/重做(git) │
|
||||
│ │ │ │ │ │
|
||||
│ 13 本地 git │ ◄─git── (pull/改/push, 不经 HM) │ │ │
|
||||
│ 14 部署 VM ────┼───────►│ 取凭据(加密) → 客户端执行│ │ │
|
||||
└────────────────┘ └──────────────────────────┘ └──────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 三端颗粒度契约(一图看清谁给谁什么)
|
||||
|
||||
> 表头里 **HM = Heicode Manager**,**AM = agent_management**。
|
||||
|
||||
| 数据/动作 | 客户端 → **HM** | **HM → AM** | **AM → HM**(回调) | **HM → 客户端** |
|
||||
|---|---|---|---|---|
|
||||
| 建任务 | 需求包(objective/context/约束/验收/模型选择/角色) | orchestration_plan + 资源授权 grants | deployment_id/swarm_id | deployment_id(=task_id) + display_status |
|
||||
| 运行状态 | — | — | `status`+`runtime_execution_status`+`phase` | **`display_status`**(裁决后) |
|
||||
| 日志/work | — | — | 事件流(task./agent./phase./handoff./artifact.) | `user_logs`+`debug_logs` / work 视图(**只有运行信息**) |
|
||||
| 每 agent 指标 | — | — | 🔴 per-agent tokens/tools/elapsed | workflow.agents[].* |
|
||||
| 代码产物 | — | — | **git push + 回调 `git_ref`**(commit/分支/改了哪些文件 + `source_agent_role`,仅元数据) | **git_ref(让客户端去 git pull)**——HM 不提供产物文件下载 |
|
||||
| 修改/重做 | message / execute | 续跑/重做指令 | 新 commit + git_ref + 状态 | 新 display_status + 新 git_ref |
|
||||
| 凭据 | 只传 `resource_binding_id` | 注入 `secret_ref`(azkv://) | — | 只回 secret_ref(打码) |
|
||||
|
||||
> ⚠️ **上表只画了「任务控制面」。还有一条独立的并行通道——模型调用:**
|
||||
> - **客户端 → HM `/v1/*`**(客户端本地 agent 用模型)
|
||||
> - **AM → HM `/v1/*`**(AM 的 agent 用模型)
|
||||
> 两边用**同一套模型接口**,HM 统一做鉴权 + 计费 + 路由。模型调用与上面的任务控制面是**两条不同的通道**,别混在一起。
|
||||
|
||||
---
|
||||
|
||||
## 3. 阶段详解
|
||||
|
||||
### 3.0 完整执行流程(逐步,明确每一步谁做什么)
|
||||
|
||||
> 全程三个主体:**客户端**(像 Claude Code 的智能体程序)、**HM**(模型网关 + 控制面,不跑 agent、不执行命令)、**AM**(云端多 agent 运行时)。**客户端和 AM 的 agent 用模型时都调 HM 的 `/v1/*`。**
|
||||
|
||||
**A. 准备(一次性)**
|
||||
1. 用户在**客户端**绑定自己的 **git 仓库**(github/gitea URL + 一个 PAT)。客户端经 V2 加密把 PAT 发给 **HM** → **HM** 把 PAT 写进 **Key Vault**,库里只留 `secret_ref`,返回一个 `resource_binding_id`。
|
||||
2. (需要部署时)同样绑定 **VM**(host + ssh key)、数据库、blob,凭据进 KV,各得一个 `resource_binding_id`。
|
||||
|
||||
**B. 发起任务**
|
||||
3. 用户在**客户端**选 `sub` 模式、填**需求包**(目标/约束/验收/角色/模型/要用哪条 `resource_binding_id`)。
|
||||
4. **客户端** → `POST /api/heicode/sub-agile/tasks`(V2 加密 body + 设备签名)。
|
||||
5. **HM**:解密 → 验签 → 鉴权 → 查配额 → 把需求包译成 `orchestration_plan`,**从 KV 取出 git 凭据注入**(短期 token),落库,返回 `deployment_id`(= task_id)。**HM 不写代码、不跑 agent。**
|
||||
|
||||
**C. 执行(AM 干活,HM 中转)**
|
||||
6. **HM** → `POST /api/agent/sub-agile/deployments`(给 **AM**),带:需求、角色/模型、回调地址、HMAC 签名密钥、**git 仓库 + 短期凭据**。
|
||||
7. **AM**:把需求拆成多个 **agent**(如 backend / frontend / reviewer),各自分配模型,开始干活。**每个 agent 用模型时调 HM 的 `/v1/*`(和桌面客户端用同一套模型接口)。**
|
||||
8. **AM** 的每个 agent:clone 用户仓库 → 在自己分支(`agent/<role>`)写代码、跑工具/测试(调 HM `/v1/*` 用模型)→ **commit & push 到用户仓库**(用第 5/6 步注入的短期 PAT)。
|
||||
9. **AM** 持续把「每个 agent 在做什么 / 跑了什么工具 / 改了哪些文件 / 当前阶段 / 产物」**流式回调**给 **HM**(HMAC 签名):`POST /api/agent/callbacks/runtime-events`。
|
||||
10. **HM** 收回调 → 聚合事件 + **裁决 `display_status`**(见 §6)+ 持久化。
|
||||
|
||||
**D. 客户端看 work**
|
||||
11. **客户端**轮询 `GET .../tasks/{id}/workflow`(运行中 3–5s;将来 SSE)→ 拿 `display_status` + 各 agent 状态/动作 + 阶段 + 产物列表,渲染成「work 视图」(参考 Claude Code)。
|
||||
|
||||
**E. 合并与产物**
|
||||
12. **AM** 阶段结束 → 把各 agent 分支**合并**成一个交付分支(`delivery/<task_id>` 或 PR)→ push 到用户仓库 → 回调通知 **HM** 产物就绪(带 `git_ref` + artifact)。
|
||||
13. **客户端**看产物:直接 `git clone/pull` 用户自己的仓库(完整工程 + 历史 + diff)。**只此一条路**——产物在 git,HM 不托管/不打包/不提供产物文件下载;HM 给的只是 `git_ref`(告诉客户端去哪个仓库/分支/commit pull)。
|
||||
|
||||
**F. 不满意 → 改 / 重做**
|
||||
14. **客户端** → `POST .../messages`(追加要求)或 `.../execute`(重跑)→ **HM** 取最新 accepted 基线转给 **AM** → **AM** 在原产物上改/重做 → 回到第 9 步。
|
||||
|
||||
**G. 部署(客户端执行 + 用户确认;HM 只发凭据)**
|
||||
15. **客户端**发起部署 → **弹窗让用户确认**(目标 VM / 环境 / 用哪条 binding / 影响)。
|
||||
16. 用户确认 → **客户端**向 **HM** 换**短期凭据租约**(HM 从 KV 解出 VM ssh key,经 V2 加密发回客户端,带 TTL)。
|
||||
17. **客户端在用户自己机器上执行**部署:`git pull` 用户仓库 → ssh 到 VM → 跑部署命令 → **在 VM 上看日志**。**HM 全程不碰 VM、不执行命令、不看日志**;**HM 只记审计**(谁、哪条 binding、何时、TTL)。
|
||||
|
||||
> 一句话区分执行位:**写代码 = AM 沙箱里执行;部署到用户 VM + 看 VM 日志 = 客户端在用户机器上执行;HM 永远只做网关/裁判/凭据中介,不执行任何东西。**
|
||||
|
||||
---
|
||||
|
||||
### 3.1 选择 sub + 准备(资源绑定前置)
|
||||
|
||||
🟢 客户端选 `mode=sub_agile`(区别于 `swarm`)。
|
||||
✅ **决策(2026-06-02)**:**git 仓库 = 用户绑定自己的仓库**(gitea / github,用户提供 URL)。**没有 Heicode 托管仓库**。
|
||||
✅ **决策(2026-06-03)**:**sub 模式强制绑定 git**——未绑仓库则**不能进 sub**(UI 上禁用 sub,引导用户先绑 git 或改用客户端本地模式)。**不再有"未绑仓库走仅产物轻量路径"这种东西**(`project_folder`/manifest/files/archive 已退役)。代码产物的唯一归宿就是用户绑定的 git 仓库(§4.1):agent 在此入库/合并,客户端 `git clone/pull` 看产物。
|
||||
|
||||
### 3.2 客户端 → HM(加密 + 鉴权 + 建任务)
|
||||
|
||||
🟢 **加密链路**:与模型调用完全一致。
|
||||
- 写请求(POST/PUT/DELETE):`Content-Encoding: heicode-aead-v1`,X25519-ECDH + HKDF + ChaCha20-Poly1305 加密 body,Ed25519 设备签名(`X-Heicode-*`)。
|
||||
- GET:无 body 设备签名(同 canonical,body 哈希为空串哈希)。
|
||||
- HM 中间件 `UserOrV2DeviceAuth` 解密 + 验签 + 从设备绑定 token 解析用户身份。
|
||||
|
||||
🟢 **鉴权/配额**:解析 user_id、绑定 scope、计费上下文。
|
||||
🟢 **建任务**:`POST /api/heicode/sub-agile/tasks`,body = **需求包**(见客户端接口文档 §3.1),HM 译成 `orchestration_plan` 并落库,返回 `deployment_id`(= task_id)。
|
||||
|
||||
### 3.3 HM → agent_management(分发)
|
||||
|
||||
🟢 `POST /api/agent/sub-agile/deployments`(env 当前指向 `http://20.212.121.126`),Bearer service token。
|
||||
🟢 注入:callback URL(`/api/agent/callbacks/runtime-events`)+ HMAC 签名密钥引用 + metadata.manager_deployment_id + 角色/模型 + **资源授权 grants(secret_ref,不含明文)**。
|
||||
🟡 **回调竞态**:AM 回调可能早于 HM 存 runtime_id → HM 用「读时收敛」(`reconcileDeploymentFromRuntime`) 兜底(已实现)。
|
||||
|
||||
### 3.4 多 agent 执行 + 流式回传(work 视图,参考 Claude Code)
|
||||
|
||||
🟡 **现状**:AM 通过回调上报 `deployment.status_changed / task.* / handoff.* / artifact.created / phase.changed` 等事件;HM 聚合成 timeline/events/logs;客户端**轮询**展示。
|
||||
🔴 **目标(work 视图)**:像 Claude Code 的 work 面板那样**实时流式**展示「每个 agent 正在做什么、跑了哪些工具、产了哪些文件、各阶段进度」。需要补:
|
||||
|
||||
1. 🔴 **流式协议**:HM 提供 `GET .../tasks/{id}/events/stream`(SSE)或 WS,把 AM 回调实时转发给客户端。**现状无 SSE**,客户端轮询 `/workflow`(3–5s)兜底(见 §5)。
|
||||
2. 🔴 **per-agent 富字段**:AM 在状态/回调里上报每个 agent 的 `tokens / tools(工具调用数) / elapsed_seconds / 当前动作描述 / artifact_ids`。HM 的 `/workflow` 已预留这些字段(缺值时为 0/空),等 AM 填。
|
||||
3. 🔴 **artifact 来源角色**:AM 给 artifact 打 `source_agent_role`,HM 才能把产物准确归到对应 agent。
|
||||
4. 🔴 **阶段细分**:runtime 上报 `phases[]`(每阶段 status/agents),而非单个 `phase` 字符串。
|
||||
|
||||
> work 视图的最小可用版(不等 SSE):客户端轮询 `/workflow` 拿 `agents[] + phases[] + metrics`,3–5s 刷新即可先跑起来;SSE 是体验升级项。
|
||||
|
||||
### 3.5 代码入 git + 多 agent 产物合并
|
||||
|
||||
🔴 **目标**:每个 agent 把自己产的代码 **commit 到 git 仓库的独立分支**(如 `agent/backend`、`agent/frontend`),最后 **合并成一个完整产物**(merge 到 `main` 或一个交付分支)。
|
||||
|
||||
❓ **关键决策(§7 详述)**:
|
||||
- 仓库在哪?(Heicode 托管 vs 用户绑定的 git)
|
||||
- 谁负责合并?(agent_management 合并后给一个最终分支/commit;HM 不碰 git 操作,只记录引用)
|
||||
- 合并策略?(按目录隔离自然无冲突:backend/ + frontend/ 并列;同文件冲突由一个「集成 agent」或规则解决)
|
||||
|
||||
🟡 **现状**:sub 模式 AM 当前还是把产物当 blob/文本 artifact 回传(每角色一个,多角色=多个),**尚未真正 git 入库 + 合并**——这是**待迁移的旧实现**,不是目标态。目标态(本节)是 AM 全程在用户 git 仓库里 commit/合并,产物只在 git。客户端不再"拼 manifest 展示产物"。
|
||||
|
||||
### 3.6 产物查看(只走 git)
|
||||
|
||||
🔴 **唯一路径 = git**:sub 完成后客户端直接 `git clone/pull` 用户自己绑定的仓库,看完整工程 + 提交历史 + diff。HM 给的只是 `git_ref`(repo/branch/commit),告诉客户端去哪 pull。
|
||||
|
||||
> **退役**:旧的「经 HM 看产物」(`/artifacts`→`/manifest`→`/files?path=`→`/archive`)是无 git 流程的残留,**sub 强制 git 后不再使用**。HM 在运行期只向客户端流式推**运行信息**(日志/状态/work,见 §5),**不提供产物文件的浏览或下载**。HM 的 `/artifacts` 接口若保留,只列**非代码的运行信息记录**(如 `test_report` 测试报告、摘要),供 work 视图展示,**不是可下载交付物**。
|
||||
|
||||
### 3.7 不满意 → 修改 / 重做(**两条路:云端改 或 本地改**)
|
||||
|
||||
> 因为客户端本身是智能体程序(像 Claude Code),迭代有**两条等价路径**,用户按场景选:
|
||||
|
||||
> **基线就是 git**:两条路都以**用户仓库的最新提交**为唯一基线,不存在 HM 侧的 `local-edits`/revision 回传机制(已退役)。本地改完 `git push`,云端续跑前 `git pull`,冲突/历史/diff 全交给 git。
|
||||
|
||||
**路径 A — 回云端 AM 改(继续 sub)**
|
||||
- 🟡 **修改(续跑)**:`POST .../tasks/{id}/messages`(追加要求)→ HM 转给 AM → AM 先 `git pull` 取用户仓库最新提交作基线 → 在其上改 → 再 push。(AM 真正「中途续跑」🔴待支持)
|
||||
- 🔴 **重做**:`POST .../tasks/{id}/execute`(或新增 `/redo`)→ AM 在新分支上重新生成(旧交付分支保留可对比)。需 AM 支持「redo」语义。
|
||||
|
||||
**路径 B — 拉到本地用客户端自己的 agent 改(回到本地模式)**
|
||||
- 🟢/🔴 客户端 `git pull` 用户仓库 → 用**客户端本地 agent**(像 Claude Code,模型仍走 HM `/v1/*`)在本地改 → `git push` 回仓库。**不必每次回云端**,适合小修小补。
|
||||
- 改完想让云端接力:直接 push 后再 `/messages`,AM `git pull` 自然拿到本地改动——**无需任何 HM 回传接口**。
|
||||
|
||||
### 3.8 部署(✅ 必须客户端执行 + 必须用户确认)
|
||||
|
||||
✅ **决策(2026-06-02)**:**部署绝对走客户端,且必须用户显式确认才执行**。HM 不自动部署、AM 不自动部署。
|
||||
- 流程:客户端发起部署 → **弹用户确认**(目标/环境/影响) → 用户确认 → 客户端向 HM 的**加密密钥接口**换取**短期凭据租约**(VM SSH key / git PAT 等从 KV 解出,经 V2 加密通道回客户端,带 TTL) → **客户端本地执行**(git pull 用户仓库 → push/部署到 VM,或连库迁移)。
|
||||
- HM 角色:**只发短期凭据 + 记审计**(谁、哪条 binding、何时、TTL),不代执行。
|
||||
- 凭据租约:短 TTL、可吊销、用完即弃;高危目标(如生产)可叠加**审批门**(waiting_approval)后再发租约。
|
||||
🟡 **现状**:有云部署控制面占位(`/deployments`,返回 `executor:pending_worker`);凭据租约模型(approval→lease)有骨架。🔴 待建:客户端取凭据的加密接口 + 客户端本地执行器。
|
||||
|
||||
---
|
||||
|
||||
## 4. 资源绑定规范(git / vm / database / blob → Key Vault)
|
||||
|
||||
> 🔴 **前置硬卡点**:Azure Key Vault 当前**托管身份取 token 400、不可达**。资源绑定的核心是「凭据进 KV、只存 secret_ref」,**KV 不通则整个功能不可用**。必须先由运维给 VM 托管身份在目标 KV 授 `Key Vault Secrets Officer` 角色(Phase 0)。
|
||||
|
||||
### 4.0 通用模型
|
||||
|
||||
每个资源绑定 = `{ resource_binding_id, type, name, metadata(非敏感), secret_ref(azkv://…), permission_scope, binding_scope(租户/工作区), status }`。
|
||||
- 客户端**只传 `resource_binding_id`** 给任务;HM 内部解析为凭据注入 AM。
|
||||
- 客户端**禁止 inline** secret_ref / AccessKey / 连接串。
|
||||
- 凭据录入**一次性**:客户端经 V2 加密通道把凭据传给 HM → HM 写 KV → 库里只留 `azkv://`。
|
||||
|
||||
### 4.1 Git 仓库绑定 ✅(已定方向)
|
||||
|
||||
**模型**:**用户绑定自己的仓库**(gitea / github,用户提供 URL)。agent 在此仓库读写代码、git 入库、合并;客户端 clone/pull 看产物;后续从此仓库 git 到 VM 部署。
|
||||
|
||||
| 项 | 方案(已定 / 建议) |
|
||||
|---|---|
|
||||
| **仓库归属** | ✅ **用户自己的仓库**。用户提供 `repo_url`(github.com/... 或自建 gitea URL)。无 Heicode 托管仓库。 |
|
||||
| **绑定鉴权(用户输入密钥)** | ✅ **HTTPS + 细粒度 PAT(个人访问令牌)为主**——github 与 gitea **通用**、用户只需粘贴一个 token、可按仓库范围授权、可随时吊销、不暴露账号密码。流程:用户在自己 git 生成范围化 PAT(建议 `repo` 读写)→ 客户端经 V2 加密通道把 PAT 传 HM → HM 写 KV,库里只留 `secret_ref`。**备选**:SSH deploy key(用户把 HM 出示的公钥加到仓库 Deploy keys;适合不愿发 PAT 的场景)。 |
|
||||
| **provider 识别** | 由 `repo_url` 推断(github.com → github API;其他 → gitea,需带 `api_base`)。metadata:`provider / repo_url / default_branch / api_base?`。 |
|
||||
| **绑定粒度** | 单仓库级(一个 binding = 一个 repo + 默认分支 + 允许路径 allowed_paths)。permission_scope:`repo:read` / `repo:write`。 |
|
||||
| **凭据有效性/过期** | PAT 会过期/被吊销 → HM 在用前**预检**(一次 `GET repo`),失效则标记 binding `status=invalid` 并提示用户**重新绑定**,不静默失败。 |
|
||||
| **工单 / 里程碑** | **可选增强**(默认关,用户显式开):把 sub 子任务映射为 **issues**、阶段映射为 **milestone**、handoff/审批映射为 **issue 评论**,让用户在自己 git 看板跟踪 agent 进度。需要 PAT 额外授 issues 权限。 |
|
||||
| **分支模型 / 合并** | 见 §7。 |
|
||||
|
||||
### 4.2 VM 连接绑定 🔴
|
||||
`type=vm`,metadata:host/port/user/连接方式(ssh key / 密码);secret 进 KV。用于部署/运维。高危,建议绑定时声明用途 + 部署需审批。
|
||||
|
||||
### 4.3 数据库绑定 🔴
|
||||
`type=database`,metadata:引擎/host/port/db 名;连接串/密码进 KV。用于 agent 生成需要连库的代码或迁移。
|
||||
|
||||
### 4.4 Blob 存储绑定 🔴
|
||||
`type=blob`,metadata:账号/容器;key/SAS 进 KV。用于大产物/数据集存取。
|
||||
|
||||
### 4.5 凭据生命周期
|
||||
- 录入 → KV(HM 写)→ 只存 secret_ref。
|
||||
- 使用 → 任务/部署时 HM 从 KV 解出注入 AM,或发**短期租约**(TTL + 可吊销)给客户端。
|
||||
- 审计 → 谁在什么 scope 用了哪条绑定、发了哪些租约、何时吊销(只记 secret_ref + 打码摘要)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 流式协议规范(work 视图)
|
||||
|
||||
| 阶段 | 协议 | 状态 |
|
||||
|---|---|---|
|
||||
| 现状 | 客户端轮询 `GET .../workflow`(运行中 3–5s、终态 15–30s) | 🟢 |
|
||||
| 目标 | `GET .../tasks/{id}/events/stream`(SSE):HM 把 AM 回调实时转发;事件含 `agent.action / tool.call / phase.changed / log.line / delivery.pushed`(产物就绪=带 `git_ref` 的通知,**不是文件**) | 🔴 |
|
||||
|
||||
**规范**:
|
||||
- SSE event 统一信封:`{ event_type, deployment_id, agent_id?, phase?, occurred_at, payload }`。
|
||||
- 客户端断线重连用 `Last-Event-ID`(基于 HM 的事件游标)。
|
||||
- **降级**:SSE 不可用时自动回落轮询,UI 行为一致(只是延迟)。
|
||||
- 客户端**不要**订阅不存在的流(未上线前 `/events/stream` 返回未实现,别硬连)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 状态模型与 `display_status` 裁决(完整定义,给三方)
|
||||
|
||||
🟢 已实现。**这是全文最关键的概念之一,三方必须一致理解。**
|
||||
|
||||
### 6.1 HM 只做"事实透传 + 防空壳",**不判断代码对错**
|
||||
- **AM 只上报执行事实**(`completed` 只代表"我跑完了")。
|
||||
- **HM 没 AI、不读代码、不跑代码、不编译、不测试。** 所以 **HM 不判断"代码对不对、有没有效"**——那不是 HM 能做、也不该做的事。
|
||||
- HM 的 `display_status` 只做两件事:**① 忠实透传 AM 的执行状态**;**② 防"空壳/兜底假成功"**——AM 说 `completed` 时,HM 顺手核对一下"**到底有没有产物**"(这是**事实层面**的核对:有/无、是不是兜底占位,**不是质量判断**)。
|
||||
- **真正"对不对、有没有效"由客户端 + 用户判断**(见 §6.6):客户端是 Claude-Code 式程序,**能把产物/git 拉下来自己跑、自己测、看 diff**,用户 review 拍板。
|
||||
- 客户端只看 `display_status` 决定**"这轮跑完了没、是不是空交付"**;**"代码好不好"客户端自己看产物。**
|
||||
|
||||
### 6.2 三层状态(`GET .../tasks/{id}/workflow` 同时返回)
|
||||
| 字段 | 含义 | 谁产生 |
|
||||
|---|---|---|
|
||||
| `cloud_deployment_status` | HM 控制面状态(accepted/running/stopped…) | HM |
|
||||
| `runtime_execution_status` | **AM 上报的原始执行状态**(AM 说它自己到哪了) | AM |
|
||||
| **`display_status`** | **HM 裁决后、给用户展示的唯一状态** | **HM** |
|
||||
|
||||
### 6.3 `display_status` 的全部取值(枚举)
|
||||
| 值 | 含义 | 客户端该怎么展示 |
|
||||
|---|---|---|
|
||||
| `accepted` | 已受理,排队中 | 进行中(灰/黄) |
|
||||
| `running` | 正在执行 | 进行中(蓝,转圈) |
|
||||
| `waiting_approval` | 等用户审批高风险操作 | 黄,弹审批 |
|
||||
| `completed` | **完成,且有真实可交付的代码产物** | **绿,成功** |
|
||||
| `needs_codegen` | AM 说完成了,但**只产了方案/总结、没有真实代码** → 需继续生成 | 黄,提示"需补充代码/继续" |
|
||||
| `completed_without_deliverable` | AM 说完成了,但**完全没有产物** | 红/橙,**视为没成功** |
|
||||
| `failed` | 执行失败 | 红,失败 |
|
||||
| `stopped` | 被用户/系统停止 | 灰,已停止 |
|
||||
|
||||
### 6.4 裁决算法(HM 收到 AM 状态后怎么算 `display_status`)
|
||||
```text
|
||||
输入: AM 的 runtime_status, 该任务的 artifacts 列表
|
||||
规则:
|
||||
if runtime_status 不是 "completed":
|
||||
display_status = runtime_status 原样透传
|
||||
(running / waiting_approval / failed / stopped / accepted ...)
|
||||
else # AM 说 completed,进入"是否真有交付物"的裁决
|
||||
遍历该任务的 artifacts:
|
||||
只要存在 1 个"真实交付物" → display_status = "completed" ✅
|
||||
否则 if 有 artifacts 但全是总结/兜底 → display_status = "needs_codegen"
|
||||
否则 (一个 artifact 都没有) → display_status = "completed_without_deliverable"
|
||||
```
|
||||
**"真实交付物"的判定**(逐条排除"假产物"):AM 回报的交付记录满足以下**才算真实**——
|
||||
- **目标态(git)**:回调带 **`git_ref`**(repo/branch/commit_sha)且有**真实提交**(commit 数 > 0 / 改了 N 个文件) → 真交付。HM 据此判"有没有真东西",**不下载、不读代码内容**。
|
||||
- `metadata.synthesized != true`(不是 AM 的兜底占位记录),**且**
|
||||
- 不是纯总结类(标题/正文不含 "runtime execution summary"、"without per-agent artifacts" 等兜底标记;不是 `document`/`summary` 类)。
|
||||
- 兼容旧实现:在 AM 尚未 git 化前,带"改了 N 个文件"结构化信号的 `code_patch`/`diff` 记录也按真交付算(过渡期)。
|
||||
|
||||
> 注意:HM 判的是**"有没有真提交"这个事实**(防空壳),**不是判代码对不对**(§6.6)。`git_ref` 是元数据,不是可下载产物。
|
||||
|
||||
> 一句话:**`completed` 必须"AM 说完成 + 真的有代码产物"两个条件都满足;只有总结没代码 = `needs_codegen`;啥都没有 = `completed_without_deliverable`。客户端据此就能准确区分成败,不会被假成功骗到。**
|
||||
|
||||
### 6.5 成功判据(客户端用)
|
||||
> **`display_status == "completed"` 且 artifacts 非空 = 真成功**;其余都不是成功(各有不同处理)。
|
||||
|
||||
### 6.6 ⚠️ "对不对/有没有效"归谁判 —— **客户端 + 用户,不是 HM**(三方必读)
|
||||
|
||||
| 谁 | 判什么 | 怎么判 |
|
||||
|---|---|---|
|
||||
| **HM** | 只判**事实**:这轮跑完没?有没有产物?是不是空壳/兜底? | 看 AM 状态 + artifact 有无(**不读代码、不编译、不测试、不判对错**) |
|
||||
| **客户端**(Claude-Code 式) | 判**代码对不对、能不能跑、是不是要的** | **把产物/git 拉到本地,自己跑、自己测、看 diff**;有问题就本地改或回云端改 |
|
||||
| **用户** | **终裁**:满不满意、收不收货 | 在客户端 review 产物,满意才算真完;不满意 → 改/重做(§3.7) |
|
||||
|
||||
> **直接回答你的问题**:
|
||||
> - **HM 不需要、也不该编译/测试/判断代码真伪**——那不合理。HM 是网关,没 AI。
|
||||
> - **完成后是对是错,客户端当然知道**:它是智能体程序,把代码拉下来一跑一测就清楚,用户也会 review。**这才是判"有效"的地方。**
|
||||
> - HM 的 `display_status` 顶多帮客户端**省一步**:告诉它"这轮跑完了 / 是不是空交付",**避免把一个空壳当成功**;但**"代码好不好"绝不由 HM 判**。
|
||||
|
||||
**关于测试/编译**(纠正我之前的错误说法):
|
||||
- 跑测试/编译是 **AM 在自己沙箱里做**(任务执行的一部分),或**客户端在本地做**。
|
||||
- 若 AM 跑了测试,**测试结果就是一个产物(`test_report` artifact)给客户端看**——**不是回传给 HM 去"裁决"**。HM 不参与对错判断。
|
||||
|
||||
---
|
||||
|
||||
## 7. Git 仓库与分支 / 合并模型 ❓
|
||||
|
||||
**目标流程**:
|
||||
```text
|
||||
任务开始 → 建/选仓库 → 拉基线分支 base
|
||||
每个 agent → 自己分支 agent/<role> → 多次 commit(流式可见 diff)
|
||||
阶段结束 → 集成:合并各 agent 分支 → 交付分支 delivery/<task_id>(或 main)
|
||||
完成 → 交付分支即「完整产物」;客户端 clone/pull 看;不满意 → 在交付分支上续跑/重做
|
||||
```
|
||||
|
||||
**决策点**:
|
||||
| 点 | 方案(已定 / 建议) |
|
||||
|---|---|
|
||||
| 仓库归属 | ✅ **用户绑定的仓库**(github/gitea,用户给 URL)。无托管仓库。 |
|
||||
| 谁执行 git | ✅ **agent_management 执行**所有 git 操作(clone 用户仓库、各 agent commit 到分支、合并到交付分支、push)——用 HM 注入的**短期 PAT**(从 KV 解出,最小权限)。HM **只记录引用**(repo_url/branch/commit_sha)并在 artifact metadata 带 `git_ref`,**不做 git**。 |
|
||||
| 提交身份 | agent 提交用一个明确的 **bot 身份**(如 `heicode-agent <bot@heicode>`)+ commit message 带任务/agent/角色标注,便于用户在 git 历史里分辨人/机改动。 |
|
||||
| 合并冲突 | 目录隔离(backend/、frontend/ 并列)天然无冲突;同文件冲突由「集成 agent」或规则化合并解决,无法自动解则上报 `needs_codegen` 让用户介入/再跑一轮。 |
|
||||
| 写入方式 | ❓建议:agent **不直接 push 到用户的 `main`**,而是 push 到 `delivery/<task_id>` 或开 **PR**,由用户在自己 git 上 review/merge → 既安全又复用用户的 PR/CI 工作流。是否强制 PR 模式待定。 |
|
||||
| 客户端看产物 | **只走 git**:直接对用户自己的仓库 `git clone/pull`。HM 不提供 `/archive` 等产物下载(已退役)。 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 决策点(部分已定,2026-06-02)
|
||||
|
||||
| # | 决策 | 结论 |
|
||||
|---|---|---|
|
||||
| 1 | git 归属 | ✅ **用户绑自己的仓库**(github/gitea,给 URL),无托管仓库 |
|
||||
| 2 | git 鉴权 | ✅ **HTTPS + 细粒度 PAT 为主**(github/gitea 通用、用户粘贴 token)、SSH deploy key 备选 |
|
||||
| 3 | 部署 | ✅ **必须客户端执行 + 必须用户确认**;HM 只发短期凭据 + 记审计 |
|
||||
| 4 | git 执行方 | ✅ **agent_management 执行 git**(用注入的短期 PAT),HM 只记引用 |
|
||||
| 5 | 工单/里程碑 | 可选增强,默认关 —— ❓ 是否纳入 v1? |
|
||||
| 6 | 流式 | v1 先轮询 work、SSE 放 v1.1 —— ❓ 接受? |
|
||||
| 7 | 写入方式 | ❓ agent 是 push 到 `delivery/<task_id>` 分支 / 开 PR,还是直接进 main? 建议 PR/分支模式 |
|
||||
| 8 | 未绑仓库 | ✅ **未绑 git 则禁用 sub**(强制绑 git)。不再有"仅产物"轻量路径;产物只在 git,无 project_folder/manifest/archive/local-edits |
|
||||
|
||||
---
|
||||
|
||||
## 9. 更多需要考虑的细节(我补充的,超出已提问题)
|
||||
|
||||
> 这些是我认为**必须在 v1 前定清**的边界/细节,大多附我的建议,标 ❓ 的需你拍板。
|
||||
|
||||
### 9.1 仓库与代码库状态
|
||||
- **空仓库 vs 已有代码**:agent 是在**已有代码库上增量改**,还是**绿地新建**? 建议 binding 时声明 `mode: greenfield | existing`;existing 时 agent 先读现有结构再改,且**只动 allowed_paths 内**的文件。
|
||||
- **多仓库任务**:一个任务是否可能跨多个仓库(前端仓 + 后端仓)? 建议 v1 **单仓库**,多仓库 v2。
|
||||
- **monorepo / 子目录**:用 `allowed_paths` 限定 agent 工作目录,避免动到无关代码。
|
||||
- **大文件 / LFS**:是否支持 git-lfs? v1 可不支持,但要**拒绝把大二进制/数据集塞进 git**(走 blob 绑定)。
|
||||
- **.gitignore + 防止误提交密钥**:agent **绝不能把任何凭据/secret_ref/.env 提交进仓库**;runtime 侧需有 secret 扫描,提交前拦截。
|
||||
|
||||
### 9.2 凭据与安全
|
||||
- **PAT 最小权限 + 短时效**:注入 AM 的 PAT 应尽量是**短期/单仓库范围**;若用户给的是长期 PAT,HM 至少做范围校验并提醒。
|
||||
- **凭据只在内存**:AM 用完 PAT 不落盘、不进日志;HM 注入走加密。
|
||||
- **scope 隔离**:一条 binding 的凭据**只能被该用户(binding_scope)的任务**使用,跨用户禁用。
|
||||
- **审计**:每次「解 KV、注入 AM、发客户端租约」都留审计(user / binding / 用途 / 时间 / TTL),明文不入审计。
|
||||
- **吊销**:用户删 binding 或吊销租约后,进行中的任务该如何? 建议:已注入的短期凭据自然过期,新操作立即失效。
|
||||
|
||||
### 9.3 任务执行与失败
|
||||
- **预算/配额**:每任务 token/时长/成本上限;**跑超预算**时如何? 建议:到上限**暂停 + 标 `needs_codegen`/`budget_exceeded`**,让用户决定续不续,不静默烧钱。
|
||||
- **中途停止(stop)**:停止时已 commit 的代码**保留在分支**(不回滚),任务标 stopped;用户可在该分支续跑或丢弃。
|
||||
- **agent 崩溃 / 部分失败**:多 agent 里某个失败 → 整体 `completed_without_deliverable`/部分交付? 建议:HM 裁决时若有 agent 失败但有有效产物,仍可 `completed` 但带 warning;全失败则 failed。
|
||||
- **幂等**:同一需求重复提交(网络重试)用 `X-Idempotency-Key` 去重,避免建重复任务/重复 git 分支。
|
||||
- **超时**:AM 长时间无回调 → HM 标 `stale`/超时,客户端可见。
|
||||
|
||||
### 9.4 产物与验收
|
||||
- **验收标准如何验证**:需求包里的 `acceptance_criteria` 谁来验? 建议:AM 跑测试(若有)并把**测试结果作为 `test_report` 产物给客户端**;**客户端 + 用户**据此判对错(**不经 HM 裁决**,§6.6)。
|
||||
- **产物版本/标签**:每次交付打 tag(`delivery-<task>-rev<N>`)或记 commit_sha,便于回溯 + 部署指定版本。
|
||||
- **修改 vs 重做的边界**:`/messages`(在现有产物上改)与 `/redo`(重新生成)语义要清晰;redo 是否丢弃旧分支? 建议:redo 开新分支,旧的保留可对比。
|
||||
|
||||
### 9.5 协作与团队
|
||||
- **谁能看/操作一个任务**:binding_scope = 租户/工作区;同 scope 内成员可见,跨 scope 禁。
|
||||
- **并发任务同仓库**:两个任务同时改一个 repo → 用不同 `delivery/<task_id>` 分支隔离,合并到 main 时各自 PR,冲突由用户处理。
|
||||
|
||||
### 9.6 git provider 细节
|
||||
- **rate limit**:github/gitea API 有限流,频繁 commit/查询要退避,避免触发封禁。
|
||||
- **私有 / 公开仓库**:都支持;私有仓库凭 PAT 访问。
|
||||
- **网络可达**:runtime 要能访问用户的 git(公网 github 没问题;自建 gitea 若在内网,需用户提供可达地址或白名单)。
|
||||
- **webhook 回写(可选)**:若用户在自己仓库手动改了代码,是否要 webhook 通知 HM 同步基线? v2 考虑。
|
||||
|
||||
### 9.7 部署细节(客户端执行 + 用户确认)
|
||||
- **确认内容**:弹窗要清楚展示**部署目标、环境(prod/staging)、用哪条 binding、影响范围**,用户确认后才发凭据。
|
||||
- **目标多样性**:v1 先支持 **VM(SSH)**;k8s/serverless v2。
|
||||
- **回滚**:部署失败/效果不好 → 客户端能回滚到上一个交付 tag。
|
||||
- **租约最小化**:发给客户端的凭据是**单目标、短 TTL**;用完吊销。
|
||||
|
||||
### 9.8 体验(参考 Claude Code work)
|
||||
- **work 视图最小信息**:每个 agent 的「当前在做什么(一句话)+ 正在改哪个文件 + 跑了什么命令/工具 + 产出」,实时滚动。
|
||||
- **可中断**:用户能在 work 视图里随时停/插话(`/messages`)。
|
||||
- **可读日志分层**:普通用户看 `user_logs`(友好),调试面板看 `debug_logs`(原始)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 与现状的差距清单(三端 TODO)
|
||||
|
||||
**Phase 0(运维,硬卡点)**
|
||||
- 🔴 打通 Key Vault 托管身份(VM identity 授 KV Secrets Officer)——不通则资源绑定/凭据全链路不可用。
|
||||
|
||||
**Heicode Manager**
|
||||
- 🟡→🟢 资源绑定 API(git/vm/db/blob CRUD + 凭据写 KV + secret_ref;KV 通后启用)
|
||||
- 🔴 SSE 事件流转发(`/events/stream`)
|
||||
- 🔴 给 agent/客户端的「绑定读取 + 短期租约」接口(部署取凭据用)
|
||||
- 🟡 workflow per-agent 富字段(已预留,等 AM 填)
|
||||
- 🔴 资源绑定 UI(重做干净版)
|
||||
|
||||
**agent_management(runtime)**
|
||||
- 🔴 真正 git 入库 + 多 agent 分支 + 合并成交付分支
|
||||
- 🔴 跑测试/编译并把结果作为 **`test_report` 产物给客户端看**(**不是给 HM 裁决**;对错由客户端+用户判,§6.6)
|
||||
- 🔴 对照 `acceptance_criteria` 自检,结果同样作为产物给客户端
|
||||
- 🔴 per-agent 指标上报(tokens/tools/elapsed/当前动作)
|
||||
- 🔴 artifact 带 `source_agent_role` + `git_ref`
|
||||
- 🔴 phases[] 阶段细分上报
|
||||
- 🔴 中途续跑 / redo 语义
|
||||
|
||||
**桌面客户端**(本身是 Claude-Code 式智能体程序)
|
||||
- 🟡 模式选择:本地模式(本地跑 agent)vs sub 模式(派云端 AM);**未绑 git 时禁用 sub 入口**
|
||||
- 🟡 work 视图(先轮询 workflow,SSE 后接)——**只展示运行信息**(日志/状态/work),不做产物下载
|
||||
- 🔴 **看产物 = git**:`git clone/pull` 用户仓库展示工程/历史/diff(不再拼 artifact 项目树)
|
||||
- 🔴 迭代路径 B:`git pull` → 本地 agent 改 → push(复用本地能力,不必每次回云端)
|
||||
- 🔴 部署:经 HM 取短期凭据 + 用户确认后本地执行
|
||||
|
||||
---
|
||||
|
||||
*本文为 v0.1 草案,决策点(§8)确认后转 v1。三端以本文对齐颗粒度与职责边界。*
|
||||
@@ -1,516 +0,0 @@
|
||||
# Agent Manager 普通 sub 敏捷模式对接任务清单
|
||||
|
||||
更新时间:2026-05-28
|
||||
发给:Agent Manager 负责人
|
||||
范围:普通 sub 模式,也就是 Heicode 的普通敏捷开发 Agent 模式。本文不要求 Agent Manager 实现完整蜂群 task graph;蜂群模式另见 `蜂群模式-AgentManager对接任务清单.md`。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
普通 sub 敏捷模式下,Heicode 桌面客户端是用户主体验,Manager 是控制面,Agent Manager 是执行层。
|
||||
|
||||
Agent Manager 需要做的是:接收 Manager 生成的 deployment payload,按 `sub_mode=agile` 和 `agile_context` 执行阶段化开发,持续把阶段状态、日志、事件、artifact、审批请求、用量和最终结果回传给 Manager。
|
||||
|
||||
计费边界:PayPal 只作为 Heicode Manager 未来收款渠道,用于余额充值或购买 Heicode 内部订阅套餐;普通 sub 任务执行中的模型费用仍按 Manager/NewAPI 的钱包余额或订阅额度扣费。Agent Manager 不需要接 PayPal,但必须回传模型用量和运行 usage,方便 Manager/NewAPI 做归属和审计。
|
||||
|
||||
普通 sub 不等于蜂群模式:
|
||||
|
||||
| 项 | 普通 sub 敏捷 | 蜂群模式 |
|
||||
|---|---|---|
|
||||
| 重点 | 需求、设计、开发、测试、修复、部署等阶段推进 | 多 Agent 任务图、claim、heartbeat、handoff |
|
||||
| 是否必须 task graph | 否 | 是 |
|
||||
| 是否需要 artifact 回流 | 是 | 是 |
|
||||
| 是否需要高危审批 | 是 | 是 |
|
||||
| 是否需要日志/事件/指标 | 是 | 是 |
|
||||
| 客户端主体验 | 是 | 是 |
|
||||
|
||||
## 2. 当前 Manager 已完成
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
|---|---|---|
|
||||
| HeicodeTask -> deployment draft | 已完成 | `POST /api/agent/user/tasks/{task_id}/deployment-draft` |
|
||||
| 用户态 deployment 创建 | 已完成 | `POST /api/agent/user/deployments` |
|
||||
| Runtime create bridge | 已完成 | 通过环境变量调用 Agent Manager |
|
||||
| Runtime stop bridge | 已完成 | 停止时同步 Runtime |
|
||||
| callback 接收 | 已完成 | `POST /api/agent/callbacks/swarm-events` |
|
||||
| phase / timeline 聚合 | 已完成 | deployment timeline 聚合 audit、callback、artifact、SK |
|
||||
| artifact 查询 | 已完成 | `GET /api/agent/user/deployments/{deployment_id}/artifacts` |
|
||||
| approval 查询/approve/reject | 已完成 | `/api/agent/approvals` |
|
||||
| V2 body 加密 | 已完成 | 桌面客户端到 Manager 的 POST 请求复用模型调用加密协议 |
|
||||
| 生产验证 | 已完成核心链路 | 生产已验证 Manager `1.4.18` 可通过 `/api/swarms` 创建普通 sub run,持久化 `runtime_swarm_id=swm_*`,Agent Manager 自动 callback 可写入 `events/timeline`;`1.4.19` 补齐 callback 后反写 deployment 快照 |
|
||||
| callback 状态反写 | 已完成 | Manager 接收 `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started/completed/crashed` 后,会同步更新 deployment `status/phase/runtime_state/agent_instances`,避免详情页长期停留 `initializing/pending` |
|
||||
| PayPal/计费边界文档 | 已完成 | `docs/integration/Heicode-Manager-PayPal支付接入与计费关系说明.md` 已明确收款、余额、订阅、NewAPI 扣费和 Agent 运行预算关系 |
|
||||
|
||||
## 3. Agent Manager 需要实现或确认的 P0
|
||||
|
||||
| 任务 | 必需 | 原因 | 验收 |
|
||||
|---|---:|---|---|
|
||||
| 接收 Manager 创建请求 | 是 | Manager 会把普通 sub deployment 发送给 Agent Manager | `POST /api/agent/deployments` 或配置的 create path 返回 2xx |
|
||||
| 支持 `sub_mode=agile` | 是 | 普通敏捷模式核心标识 | 不认识时不能按蜂群 task graph 强制处理 |
|
||||
| 支持 `agile_context` | 是 | 用于阶段、检查点、验收标准和下一步动作 | Runtime 能读取并在回调里更新 stage/checkpoint |
|
||||
| 支持阶段状态回传 | 是 | 客户端需要知道当前处在需求/设计/开发/测试/修复/部署哪个环节 | 回调 `phase.changed` 或 `timeline.updated` |
|
||||
| 支持 artifact 回写 | 是 | 中间交付物和最终结果必须回到 Heicode | 回调 `artifact.created` |
|
||||
| 支持审批请求 | 是 | 高危操作必须客户端审批 | 回调 `approval.requested` 并等待 decision |
|
||||
| 支持 stop | 是 | 用户停止任务时 Runtime 必须停止真实执行 | stop 接口返回 stopped |
|
||||
| 支持日志/事件/指标 | 是 | 联调和验收需要排障数据 | 提供 callback 或查询接口 |
|
||||
| 支持用量归属 | 是 | NewAPI / CodeGW 计费要按 deployment/task/role 归属 | 回传 usage/budget 事件或在模型调用中带 correlation |
|
||||
| 支持 Runtime usage 回传 | 是 | `budget.max_cost_usd` 只是预算上限,真实 Agent 运行费用不能由 Manager 猜 | 回传模型 token/cost、runtime 秒数、CPU/内存等可核对 usage |
|
||||
|
||||
## 4. Runtime 创建接口
|
||||
|
||||
Manager 当前默认 create path:
|
||||
|
||||
```text
|
||||
AGENT_RUNTIME_CREATE_PATH=/api/agent/deployments
|
||||
```
|
||||
|
||||
如果 Agent Manager 统一使用 `/api/swarms`,Manager 也可以配置切过去。但普通 sub 敏捷模式建议先支持:
|
||||
|
||||
```http
|
||||
POST /api/agent/deployments
|
||||
Authorization: Bearer <service_token>
|
||||
X-User-ID: <manager_user_id>
|
||||
X-Binding-Scope: <binding_scope>
|
||||
X-Correlation-ID: <correlation_id>
|
||||
X-Idempotency-Key: manager-<manager_deployment_id>
|
||||
Content-Type: application/json
|
||||
```
|
||||
|
||||
请求体核心形状:
|
||||
|
||||
```json
|
||||
{
|
||||
"orchestration_plan": {
|
||||
"intent_id": "task-client-sim-1779875397",
|
||||
"template_hint": "heicode-task",
|
||||
"objective": "交付轻量待办系统 MVP",
|
||||
"sub_mode": "agile",
|
||||
"risk_level": "low",
|
||||
"budget": {
|
||||
"max_tokens": 20000,
|
||||
"max_cost_usd": 1,
|
||||
"max_duration_sec": 600
|
||||
},
|
||||
"user_context": {
|
||||
"user_id": "22",
|
||||
"channel_id": "heicode",
|
||||
"binding_scope": "task-client-sim"
|
||||
},
|
||||
"billing_context": {
|
||||
"provider": "newapi",
|
||||
"default_model_id": "smoke-model",
|
||||
"allowed_model_ids": ["smoke-model"],
|
||||
"secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key"
|
||||
},
|
||||
"agile_context": {
|
||||
"iteration": "2026-05-28",
|
||||
"stage": "planning",
|
||||
"checkpoint": "draft_created",
|
||||
"acceptance_criteria": [
|
||||
"接口返回成功",
|
||||
"artifact 可回写到 timeline",
|
||||
"不出现明文密钥"
|
||||
],
|
||||
"next_action": "continue",
|
||||
"requires_user_approval": false
|
||||
},
|
||||
"agent_runtime": {
|
||||
"platform": "agent",
|
||||
"agents": [
|
||||
{
|
||||
"role": "backend",
|
||||
"model_ref": "smoke-model",
|
||||
"instance_count": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"role_template": "backend",
|
||||
"goal": "完成本轮后端任务",
|
||||
"default_model_id": "smoke-model",
|
||||
"resource_grants": []
|
||||
}
|
||||
],
|
||||
"resource_grants": []
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"role": "backend",
|
||||
"resource_grants": []
|
||||
}
|
||||
],
|
||||
"risk_level": "low",
|
||||
"budget": {
|
||||
"max_tokens": 20000,
|
||||
"max_cost_usd": 1,
|
||||
"max_duration_sec": 600
|
||||
},
|
||||
"billing_context": {
|
||||
"provider": "newapi",
|
||||
"default_model_id": "smoke-model",
|
||||
"allowed_model_ids": ["smoke-model"],
|
||||
"secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key"
|
||||
},
|
||||
"resource_grants": [
|
||||
{
|
||||
"grant_id": "grant-client-sim-git",
|
||||
"resource_id": "git-client-sim",
|
||||
"resource_type": "git",
|
||||
"permission_scope": ["repo:read"],
|
||||
"secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/client-sim-git",
|
||||
"ref": "azkv://heicode-kv.vault.azure.net/secrets/client-sim-git",
|
||||
"target_role": "backend"
|
||||
}
|
||||
],
|
||||
"callback": {
|
||||
"url": "https://code.xinghanlab.com/api/agent/callbacks/swarm-events",
|
||||
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agent-callback-signing-key",
|
||||
"subscribed_events": [
|
||||
"deployment.status_changed",
|
||||
"phase.changed",
|
||||
"agent.started",
|
||||
"agent.completed",
|
||||
"agent.crashed",
|
||||
"sk_tool.called",
|
||||
"sk_tool.completed",
|
||||
"sk_tool.failed",
|
||||
"approval.requested",
|
||||
"budget.alert",
|
||||
"artifact.created",
|
||||
"timeline.updated"
|
||||
]
|
||||
},
|
||||
"agile_context": {
|
||||
"iteration": "2026-05-28",
|
||||
"stage": "planning",
|
||||
"checkpoint": "draft_created",
|
||||
"next_action": "continue",
|
||||
"requires_user_approval": false
|
||||
},
|
||||
"sub_mode": "agile",
|
||||
"metadata": {
|
||||
"manager_deployment_id": "dep_xxx",
|
||||
"heicode_deployment_id": "dep_xxx",
|
||||
"heicode_runtime_bridge": true,
|
||||
"correlation_id": "corr_xxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"deployment_id": "runtime-dep-123",
|
||||
"status": "running",
|
||||
"estimated_ready_at": "2026-05-28T10:02:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
建议也返回 `swarm_id`,即使普通 sub 不强依赖蜂群任务图,后续统一追踪会更方便。
|
||||
|
||||
## 5. 普通 sub 敏捷阶段
|
||||
|
||||
Agent Manager 至少要支持以下阶段语义,并通过 callback 回写当前阶段:
|
||||
|
||||
| stage | 含义 | 建议 checkpoint |
|
||||
|---|---|---|
|
||||
| `planning` | 需求澄清/任务拆分 | `draft_created`, `requirements_confirmed` |
|
||||
| `design` | 方案/API/数据结构设计 | `design_ready` |
|
||||
| `development` | 编码实现 | `backend_done`, `frontend_done`, `artifact_ready` |
|
||||
| `testing` | 自动测试/手工验证 | `ready_for_test`, `test_passed`, `test_failed` |
|
||||
| `fixing` | 根据测试或用户反馈修复 | `fix_started`, `fix_ready` |
|
||||
| `deployment` | 部署/发布准备 | `deploy_ready`, `deployed` |
|
||||
| `review` | 复核/总结/交付 | `review_ready`, `completed` |
|
||||
| `done` | 结束 | `completed` |
|
||||
| `failed` | 失败 | `failed` |
|
||||
|
||||
阶段回调示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_phase_1",
|
||||
"event_type": "phase.changed",
|
||||
"deployment_id": "dep_xxx",
|
||||
"agent_instance_id": "agent-backend-1",
|
||||
"occurred_at": "2026-05-28T10:10:00Z",
|
||||
"correlation_id": "corr_xxx",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"stage": "development",
|
||||
"checkpoint": "backend_done",
|
||||
"title": "后端实现完成",
|
||||
"summary": "已完成工单列表和状态流转接口,等待测试",
|
||||
"agent_role": "backend",
|
||||
"severity": "success",
|
||||
"next_action": "submit_test_result"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果 Agent Manager 暂时不支持 `phase.changed`,也可以先使用 `timeline.updated`,但 payload 中必须带 `stage` 和 `checkpoint`。
|
||||
|
||||
## 6. timeline.updated
|
||||
|
||||
普通 sub 敏捷下,客户端主要看 timeline。Agent Manager 应持续回写可展示事件。
|
||||
|
||||
联调前可以先请求 Manager 当前接受的 callback schema:
|
||||
|
||||
```http
|
||||
GET https://code.xinghanlab.com/api/agent/callbacks/swarm-events/schema
|
||||
```
|
||||
|
||||
该接口只返回事件类型、分类和必填字段,不返回任何 token 或密钥。普通 sub 敏捷重点核对 `phase.changed`、`timeline.updated`、`artifact.created`、`approval.requested`、`sk_tool.*` 和 `budget.alert`。
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_timeline_1",
|
||||
"event_type": "timeline.updated",
|
||||
"deployment_id": "dep_xxx",
|
||||
"occurred_at": "2026-05-28T10:11:00Z",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"title": "测试完成",
|
||||
"summary": "接口测试通过 12 项,未发现阻塞问题",
|
||||
"stage": "testing",
|
||||
"checkpoint": "test_passed",
|
||||
"agent_role": "reviewer",
|
||||
"severity": "success",
|
||||
"next_action": "submit_artifact"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. artifact.created
|
||||
|
||||
普通 sub 模式必须回流中间交付物和最终交付结果。不要只写 Runtime 本地日志。
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_artifact_1",
|
||||
"event_type": "artifact.created",
|
||||
"deployment_id": "dep_xxx",
|
||||
"task_id": "task-backend-1",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"artifact_id": "art_test_report_1",
|
||||
"artifact_type": "test_report",
|
||||
"title": "接口测试报告",
|
||||
"summary": "12 项接口测试通过",
|
||||
"uri": "artifact://runtime/dep_xxx/test-report",
|
||||
"checksum": "sha256:abc123",
|
||||
"stage": "testing",
|
||||
"checkpoint": "test_passed"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
支持的 `artifact_type` 建议:
|
||||
|
||||
| artifact_type | 说明 |
|
||||
|---|---|
|
||||
| `code_patch` | 代码补丁或分支引用 |
|
||||
| `document` | 需求/设计/说明文档 |
|
||||
| `test_report` | 测试报告 |
|
||||
| `deployment_manifest` | 部署清单 |
|
||||
| `log_bundle` | 日志包 |
|
||||
| `other` | 其他 |
|
||||
|
||||
## 8. approval.requested 和 decision
|
||||
|
||||
普通 sub 模式也需要高危审批。高危动作包括但不限于:
|
||||
|
||||
| 操作 | 例子 |
|
||||
|---|---|
|
||||
| 写 Git 仓库 | push 分支、改配置、创建 PR |
|
||||
| 改云资源 | 创建/删除 VM、AKS、存储、数据库 |
|
||||
| 部署到生产 | 发布、迁移、重启服务 |
|
||||
| 使用敏感凭据 | 需要从 `secret_ref` 派生短期凭证 |
|
||||
|
||||
审批请求:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_approval_1",
|
||||
"event_type": "approval.requested",
|
||||
"deployment_id": "dep_xxx",
|
||||
"agent_instance_id": "agent-backend-1",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"approval_id": "appr_runtime_1",
|
||||
"operation": "git.write",
|
||||
"resource_id": "repo-main",
|
||||
"resource_type": "git",
|
||||
"resource_scope": "feature/*",
|
||||
"target_role": "backend",
|
||||
"risk_level": "high",
|
||||
"requires_credential": true,
|
||||
"secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/repo-main",
|
||||
"ttl_seconds": 900,
|
||||
"reason": "需要写入功能分支以提交本轮修改"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Manager 回传 decision:
|
||||
|
||||
```http
|
||||
POST /api/swarms/{swarm_id}/approvals/{approval_id}
|
||||
```
|
||||
|
||||
如果普通 sub 不使用 `swarm_id`,可让 Manager 配置为:
|
||||
|
||||
```text
|
||||
AGENT_RUNTIME_APPROVAL_DECISION_PATH=/api/agent/deployments/{deployment_id}/approvals/{approval_id}
|
||||
```
|
||||
|
||||
Runtime 需要接收:
|
||||
|
||||
```json
|
||||
{
|
||||
"approval_id": "appr_runtime_1",
|
||||
"decision": "approved",
|
||||
"manager_deployment_id": "dep_xxx",
|
||||
"runtime_deployment_id": "runtime-dep-123",
|
||||
"operation": "git.write",
|
||||
"resource_id": "repo-main",
|
||||
"resource_type": "git",
|
||||
"target_role": "backend",
|
||||
"requires_credential": true,
|
||||
"credential_ref": "lease://agent/lease_xxx",
|
||||
"lease_id": "lease_xxx",
|
||||
"lease_expires_at": 1779850900000
|
||||
}
|
||||
```
|
||||
|
||||
Runtime 收到:
|
||||
|
||||
| decision | Runtime 动作 |
|
||||
|---|---|
|
||||
| `approved` | 继续该高危动作,只使用 `credential_ref` 对应的短期凭证 |
|
||||
| `rejected` | 停止该动作,回调 `timeline.updated` 或 `phase.changed`,标记被拒绝 |
|
||||
|
||||
## 9. logs / events / metrics
|
||||
|
||||
Manager 当前有用户态查询位置,但真实数据需要 Agent Manager 产出。
|
||||
|
||||
Agent Manager 至少需要支持以下一种方式:
|
||||
|
||||
| 方式 | 说明 |
|
||||
|---|---|
|
||||
| callback 摘要 | 用 `timeline.updated` 持续回写阶段、耗时、错误摘要 |
|
||||
| 查询接口 | 提供 `/logs`、`/events`、`/metrics`,Manager 后续可拉取 |
|
||||
| 混合 | 关键状态 callback,详细日志走查询接口 |
|
||||
|
||||
建议指标:
|
||||
|
||||
| 指标 | 用途 |
|
||||
|---|---|
|
||||
| `status` | running/stopped/failed/completed |
|
||||
| `stage` / `checkpoint` | 当前敏捷阶段 |
|
||||
| `agent_role` | 哪个角色在执行 |
|
||||
| `tokens_used` / `cost_usd` | 用量归属 |
|
||||
| `duration_ms` | 阶段耗时 |
|
||||
| `error_code` / `error_message` | 失败排障 |
|
||||
| `artifact_count` | 产物数量 |
|
||||
|
||||
## 10. billing / NewAPI 用量归属
|
||||
|
||||
Agent Manager 调模型时,需要把 Manager 传入的上下文带上,便于 NewAPI / CodeGW 计费归属。
|
||||
|
||||
PayPal 不在这条链路里。PayPal 支付成功后只会把用户权益写入 Heicode 钱包余额或内部订阅;普通 sub 执行时,Agent Manager 仍然按 `billing_context.provider=newapi` 使用 Manager 传入的用户、deployment、role 和模型上下文。
|
||||
|
||||
至少保留:
|
||||
|
||||
| 字段 | 来源 | 用途 |
|
||||
|---|---|---|
|
||||
| `user_id` | `user_context.user_id` | 用户归属 |
|
||||
| `manager_deployment_id` | `metadata.manager_deployment_id` | deployment 归属 |
|
||||
| `correlation_id` | header 或 metadata | 链路追踪 |
|
||||
| `agent_role` | agents[].role | 角色归属 |
|
||||
| `task_id` | Runtime 内部任务 | 子任务归属 |
|
||||
| `model_id` | billing/default model | 模型用量 |
|
||||
|
||||
Agent Manager 回传 usage 时建议至少包含:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|---|---|
|
||||
| `model_tokens` | 本 deployment/task/role 消耗的模型 token。 |
|
||||
| `model_cost_usd` | Runtime 或 NewAPI 可确认的模型成本。 |
|
||||
| `runtime_seconds` | Agent 实际运行秒数。 |
|
||||
| `cpu_core_seconds` | 如 Runtime 具备集群指标,应回传 CPU 使用量。 |
|
||||
| `memory_mb_seconds` | 如 Runtime 具备集群指标,应回传内存使用量。 |
|
||||
| `billing_source` | 建议为 `newapi`、`manager_wallet`、`manager_subscription` 或 Runtime 约定值。 |
|
||||
|
||||
注意:`budget.max_tokens`、`budget.max_cost_usd`、`budget.max_duration_sec` 是预算和拦截上限,不是已结算金额。Manager 只能展示和审计预算;真实扣费或成本归属必须基于 Agent Manager / Runtime 回传的 usage。
|
||||
|
||||
如果发生预算告警,回调:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_budget_1",
|
||||
"event_type": "budget.alert",
|
||||
"deployment_id": "dep_xxx",
|
||||
"source": "agent-manager",
|
||||
"payload": {
|
||||
"consumed_usd": 7.2,
|
||||
"max_cost_usd": 8,
|
||||
"threshold_pct": 90,
|
||||
"severity": "warning"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 11. 安全要求
|
||||
|
||||
| 要求 | 说明 |
|
||||
|---|---|
|
||||
| 不接收/不打印明文长期密钥 | password/token/private_key/access_key/connection_string/model key 都不能出现在日志、callback、artifact metadata |
|
||||
| 只使用 `secret_ref` | 长期凭据引用统一 `azkv://<vault>/secrets/<name>` |
|
||||
| 只用 `credential_ref` 执行审批后的动作 | Manager 同意后返回 `lease://...`,不要要求长期密钥 |
|
||||
| callback 必须幂等 | 重试同一个 `event_id` 不能重复创建 artifact/approval |
|
||||
| callback 必须有来源 | `source=agent-manager` 或 `heicode-swarm-runtime` |
|
||||
|
||||
## 12. 普通 sub 联调验收步骤
|
||||
|
||||
| 步骤 | 操作 | 期望 |
|
||||
|---:|---|---|
|
||||
| 1 | Manager 调 Agent Manager health | healthy |
|
||||
| 2 | Manager 创建 `sub_mode=agile` deployment | Runtime 返回 `deployment_id`,建议返回 `swarm_id` |
|
||||
| 3 | Runtime 回调 `phase.changed` planning/design/development/testing | Manager timeline 可见阶段推进 |
|
||||
| 4 | Runtime 回调 `timeline.updated` | 客户端可展示当前子环节反馈 |
|
||||
| 5 | Runtime 回调 `artifact.created` | Manager artifacts 列表出现中间产物 |
|
||||
| 6 | Runtime 回调 `approval.requested` | Manager pending approval 出现 |
|
||||
| 7 | Manager approve/reject | Runtime 收到 decision 并继续/停止对应动作 |
|
||||
| 8 | Manager stop | Runtime deployment 真实停止 |
|
||||
| 9 | Runtime 回调 completed/failed | Manager detail/timeline 显示终态 |
|
||||
| 10 | Runtime 回调用量 | Manager 能看到 model token/cost 或 usage 摘要,且与 deployment/task/role/correlation 关联 |
|
||||
| 11 | 查日志 | 不出现明文密钥,不丢 `correlation_id` |
|
||||
| 12 | 生产路由复核 | `GET /api/agent/callbacks/swarm-events/schema` 返回 200,用户态/后台态接口使用有效登录态通过 smoke |
|
||||
|
||||
## 13. Agent Manager 不需要处理的内容
|
||||
|
||||
| 不需要处理 | 原因 |
|
||||
|---|---|
|
||||
| 桌面客户端 V2 body 加密 | 这是客户端到 Manager,Manager 已处理 |
|
||||
| Manager 用户登录/session | Manager 控制 |
|
||||
| HeicodeTask 追问/任务卡生成 | 客户端和 Manager 代理处理 |
|
||||
| Azure Key Vault 写入长期密钥 | Manager 负责资源绑定和 `secret_ref` 管理 |
|
||||
| Web 控制台页面展示 | Manager 负责 |
|
||||
| PayPal 收款和充值订单 | Manager 负责;Agent Manager 只需要回传执行和用量,不直接处理支付 |
|
||||
|
||||
## 14. 当前已知缺口
|
||||
|
||||
| 缺口 | 属于谁 | 说明 |
|
||||
|---|---|---|
|
||||
| 真实 Runtime 是否完整消费 `agile_context` | Agent Manager | 需要确认字段被使用,不只是透传 |
|
||||
| 阶段状态持续回传 | Agent Manager | 2026-05-31 生产复核已收到 running/completed、phase、timeline、task.completed 等真实回调;后续需在更复杂多阶段任务中继续验证 |
|
||||
| artifact 真实产出 | Agent Manager | 2026-05-31 生产复核已收到业务 `code_patch` artifact,并可通过 Manager content 代理下载;Git/部署 URL 类产物仍按具体任务继续验证 |
|
||||
| approval decision 接收路径 | Agent Manager + Manager 配置 | 需确认最终路径是 `/api/swarms/...` 还是 `/api/agent/deployments/...` |
|
||||
| 用量回传 | Agent Manager + NewAPI/CodeGW | 2026-05-31 生产复核已回传 `tokens_used=2682`、`newapi_request_id=chatcmpl-DlbZce3VZnsv5DptBILFoiRYy5ZHN`;后续需继续按 user/deployment/task/role 归属 |
|
||||
| Agent 运行费用真实结算 | Agent Manager + Manager | Runtime 已能回传 token usage;真实费用结算仍需按 Manager/NewAPI 订阅/钱包规则和 Runtime usage 口径统一 |
|
||||
| 生产 callback schema 路由 | Manager 部署/路由 | 本地代码和测试已覆盖,2026-05-28 生产公开访问 `/api/agent/callbacks/swarm-events/schema` 返回 404,需要重新上线或核对生产镜像/路由 |
|
||||
| 无 body GET 的 V2 签名 | 客户端 + Manager | 这是客户端全链路无 cookie 的后续项,不阻塞 Agent Manager 创建/回调联调 |
|
||||
Reference in New Issue
Block a user