# Heicode Agent Manager API 对接文档 ## 📋 目录 - [1. 概述](#1-概述) - [2. 认证方式](#2-认证方式) - [3. API 端点](#3-api-端点) - [4. 数据模型](#4-数据模型) - [5. 使用示例](#5-使用示例) - [6. 错误处理](#6-错误处理) - [7. 最佳实践](#7-最佳实践) - [8. 附录](#8-附录) --- ## 1. 概述 ### 1.1 服务信息 - **服务名称**: Agent Manager - Heicode Integration API - **版本**: v2.1.9 (heicode-v2) - **当前部署镜像**: `agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-20260529232620` - **当前 AKS 镜像 digest**: `sha256:b1931c1172fc23da8234e96dbdca34c4704644c2b2099391b362a48c47dc68f4` - **Base URL(当前联调)**: `http://20.212.121.126` - **Base URL(域名待切换)**: `https://agent-manager.taijiagnet.com` - **主 API 前缀**: `/api/agent` - **Runtime 兼容前缀**: `/api/swarms` ### 1.2 核心功能 - ✅ 多 Agent 编排部署 - ✅ Heicode sub 模式敏捷开发对接(agile / waterfall) - ✅ `/api/swarms` Runtime 适配入口 - ✅ 模板 Agent `/agents` 生命周期兼容接口 - ✅ 预算控制和计费管理 - ✅ 风险等级评估(low/medium/high) - ✅ Azure Key Vault `secret_ref` 引用 - ✅ 实时日志和事件追踪 - ✅ Callback / artifact / timeline / SK snapshot 对接 - ✅ 资源监控和指标统计 - ✅ 幂等性保证 ### 1.3 架构说明 ``` ┌─────────────┐ │ Heicode │ │ Platform │ └──────┬──────┘ │ HTTPS + Token Auth ▼ ┌─────────────────────────────┐ │ Agent Manager API │ │ /api/agent/* │ └──────┬──────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ Kubernetes Cluster (AKS) │ │ - Namespace 隔离 │ │ - Pod 管理 │ │ - ConfigMap/Secret │ └─────────────────────────────┘ ``` ### 1.4 Heicode sub 模式对接边界 本文件同时补充 Heicode Manager 当前 sub 模式敏捷开发所需的 Runtime 对接契约。 | 系统 | 职责 | 说明 | |------|------|------| | Heicode Manager | 用户、资源绑定、模型网关配置、审批、部署草稿、权限清单、回调持久化、artifact/timeline 展示 | 已有本地控制面和生产页面 | | Agent Manager / Agent Runtime | 接收 Manager 传入的部署计划,真实创建/调度子 Agent,执行任务,按回调协议回写状态、产物、用量和审批请求 | 需要支持本文定义的请求与回调字段 | | Azure Key Vault | 长期密钥托管 | Manager/Runtime 只能使用 `azkv://...` 引用,不能传明文密钥 | | NewAPI / CodeGW | 模型网关与计费入口 | Runtime 使用 Manager 提供的模型、预算和 `secret_ref` 上下文 | 重要边界: 1. `sub_mode` 是 Heicode 的任务组织方式,不等于 Agent Manager 内部固定执行引擎。 2. `agile` 和 `waterfall` 都属于 sub 模式;当前优先验证 `agile`。 3. 蜂群模式和 sub 模式不是同一个概念。`/api/swarms` 是为了对齐 Runtime 创建入口的适配层,不代表 Manager 把所有 sub 流程改成蜂群模式。 4. 所有凭据只能通过 `secret_ref` 传递,禁止在请求、回调、日志、artifact metadata 中出现明文密码、Token、私钥、连接串。 ### 1.5 当前 Manager / Runtime v2.1 落地状态 截至 `heicode-v2-20260529232620`,Manager / Runtime 已按本文 v2.1 契约落地以下兼容能力: | 能力 | 当前状态 | 说明 | |------|----------|------| | Callback HMAC 验签 | 已支持 | 支持 `X-Agnet-Signature` / `X-Agnet-Timestamp` / `X-Agnet-Event-Id` | | Callback 旧认证兼容 | 已支持 | 过渡期仍接受 `X-Agnet-Service-Token` 或 `Authorization: Bearer` | | Callback 幂等 | 已支持 | 优先读 `X-Agnet-Event-Id`,兼容 body `event_id` | | Runtime 主动回调 | 已支持 | `/api/agent/sub-agile/deployments` 与 `/api/swarms` 创建的 Runtime 执行阶段会主动推送 status/phase/timeline/agent/tool/artifact 事件 | | 普通 sub 真实 artifact 回调 | 已支持 | 普通 sub agent 真正执行后会生成 `artifact.created`,不再只返回 completed | | Runtime artifact 内容读取 | 已支持 | Runtime 会优先用 K8s Secret 中的 Azure Blob 凭据上传完整产物;失败时回落本地 artifact store,metadata 中返回 URI、`content_hash` 和下载路径 | | 普通 sub task 终态回调 | 已支持 | 新增 `task.completed` / `task.failed` / `task.blocked` 事件 | | deployment/agent 状态一致性 | 已支持 | deployment 进入终态时,`agents[].status` 会同步收敛到终态 | | 普通 sub agent 字段兼容 | 已支持 | `agents[].role_template` / `default_model_id` 会规范化为 Runtime `role` / `model` | | `payload.*` 格式 | 已支持 | `artifact.created` 等事件按 `payload` 解析;旧顶层 `artifact` 也兼容 | | `swarm_id` / `occurred_at` / `agent_instance_id` | 已支持 | 事件持久化时保留,并用于时间线与 Agent 实例展示 | | `agile_context` 透传 | 已支持 | 写入 Runtime 配置上下文,保留 stage/checkpoint/验收标准 | | `callback.signing_secret_ref` | 已支持 | 创建部署时保存;Runtime 发送 callback 时用它解析 HMAC secret | | 默认 `subscribed_events` | 已支持 | 未传时自动订阅 v2.1 标准事件集 | | 顶层 `resource_grants` | 已支持 | 兼容 `agents[].resource_grants` 汇总 | | legacy ResourceGrant 字段 | 已支持 | 兼容 `type / permissions / ref` 与 `resource_type / permission_scope / secret_ref` | | artifact/timeline/SK snapshot 查询 | 已支持 | 从 callback 事件投影到用户态查询接口 | | `approval.requested` / decision | 已支持 | callback 会持久化审批请求;Runtime 接收 `/api/swarms/{swarm_id}/approvals/{approval_id}` 与 `/api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}` decision | | `/api/swarms` 运行期查询 | 已支持 | 兼容 `status`、`stop`、`logs`、`events`、`metrics` 查询/控制路径 | | `/api/swarms` 创建校验 | 已支持 | 缺少 `orchestration_plan` / `callback.url` / `sub_mode` / `user_context.user_id` 返回 422;`dry_run:true` 返回 422 且不创建真实 run | | `/api/swarms` 幂等 | 已支持 | 同一个 `X-Idempotency-Key` 返回已有 run,不重复创建 | | usage / cost 回传 | 已支持 | `budget.alert` payload 带 `model_id`、token、成本、运行时长、资源秒、`billing_source` 和预算摘要 | | `/api/swarms/{id}/logs` 日志兜底 | 已支持 | 返回 Runtime 聚合日志摘要,不再只是固定占位文本 | | 空产物终态兜底 | 已支持 | 普通 sub terminal run 若未存储 concrete artifact,会生成 Runtime summary/failure artifact,并在 `/api/swarms/{id}`、`events`、`metrics` 中可见 | | 模板 Agent `/agents` 生命周期兼容 | 已支持 | `POST /agents` 响应补充 `runtime_id` / `agent_id` / `id` / `runtime_status` / `state` / `subdomain`,并新增 `GET /agents/{id}`、`POST /agents/{id}/stop` | 仍属于后续增强或 Runtime 侧职责: 1. `/logs`、`/events`、`/metrics` 当前提供 Runtime/Swarm 本地聚合与轮询兜底;其中 `/logs` 已不再返回固定占位文本,后续仍可接入真实 Pod 指标和日志后端。 2. Runtime callback 重试、死信队列和人工重放;当前发送失败只记录 warning,不阻塞任务执行。 3. credential lease 的真实凭证兑换由 Manager / Vault 链路负责,Runtime 只消费 `credential_ref`。 4. artifact 独立表字段化存储;当前查询结果由 callback event payload 投影生成。 ### 1.6 v2.1.4 联调速查 本节给联调同学快速定位当前可用路径;详细字段定义见后续 API 端点和数据模型章节。 | 场景 | 推荐接口 | 当前状态 | |------|----------|----------| | 健康检查 | `GET /api/agent/health` | 已支持,无需业务 Header | | 普通 sub 创建 Runtime run | `POST /api/swarms` | 已支持,要求结构化 `orchestration_plan` 和 `callback.url` | | 旧版 Agent 部署创建 | `POST /api/agent/sub-agile/deployments` | 已支持,可兼容结构化 sub plan | | Runtime 主动事件回写 | `POST /api/agent/callbacks/runtime-events` | 已支持 HMAC / 旧 token 过渡认证和幂等 | | 查询 Runtime 状态 | `GET /api/swarms/{swarm_id}` 或 `/status` | 已支持,`deployment_id` 与 `swarm_id` 当前同值 | | 查询产物 | `GET /api/agent/user/deployments/{deployment_id}/artifacts` | 已支持,由 callback event 投影 | | 查询时间线 | `GET /api/agent/user/deployments/{deployment_id}/timeline` | 已支持,由 callback event 合并 | | 查询 SK snapshot | `GET /api/agent/user/deployments/{deployment_id}/sk-snapshots` | 已支持投影查询,独立解析接口待增强 | | 审批 decision | `POST /api/swarms/{swarm_id}/approvals/{approval_id}` | 已支持 `approved` / `rejected` | | 模板 Agent 生命周期 | `POST /agents`、`GET /agents/{id}`、`POST /agents/{id}/stop`、`DELETE /agents/{id}` | 已支持,适合 HM 模板 Agent 联调 | 当前实现边界: 1. `/api/swarms` 的 `dry_run:true` 会返回 422,不创建真实 run。 2. Runtime callback 发送失败当前只记录 warning,不阻塞执行;重试队列、死信队列和 replay 属于后续增强。 3. `/api/swarms/{id}/logs`、`events`、`metrics` 是本地聚合兜底,不等同于完整日志/指标后端。 4. 所有 secret 都必须以引用形式传递,正式示例统一使用 `azkv:///secrets/`。 ### 1.7 产物获取速查 普通 sub Runtime 完成后,Manager 前端或服务端不要从 callback body 里直接读取完整产物。标准流程是:先查询 artifact 列表拿到 `artifact_id`、`uri`、摘要和大小,再通过 content 代理接口下载完整内容。 推荐调用顺序: 1. 创建 Runtime run 后保存返回的 `deployment_id` / `swarm_id`。当前实现里二者同值。 2. 通过 callback 里的 `artifact.created` 事件,或轮询 `GET /api/swarms/{swarm_id}/status` 判断是否已有 artifact。 3. 调用 `GET /api/agent/user/deployments/{deployment_id}/artifacts` 获取产物列表。 4. 从列表中取 `artifact_id`,调用 `GET /api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` 下载完整内容。 5. 如果 Manager 需要直接访问 Runtime 兼容层,也可以调用 `GET /api/swarms/{swarm_id}/artifacts/{artifact_id}/content`。 示例: ```bash BASE_URL="https://agent-manager.taijiagnet.com" TOKEN="" DEPLOYMENT_ID="swm_xxx" curl -sS \ -H "Authorization: Bearer ${TOKEN}" \ "${BASE_URL}/api/agent/user/deployments/${DEPLOYMENT_ID}/artifacts" ``` 列表响应中的关键字段: ```json { "success": true, "deployment_id": "swm_xxx", "artifacts": [ { "artifact_id": "art_backend_patch_001", "artifact_type": "code_patch", "title": "Backend API patch", "summary": "新增 deployment draft 到 Runtime 的桥接逻辑", "uri": "azblob://heicode-artifacts/runtime-artifacts/swm_xxx/art_backend_patch_001.patch", "mime_type": "text/x-diff", "size_bytes": 18420, "metadata": { "content_hash": "sha256:abc123...", "download_path": "/api/swarms/swm_xxx/artifacts/art_backend_patch_001/content" }, "created_at": "2026-05-27T10:40:00Z" } ] } ``` 下载完整内容: ```bash ARTIFACT_ID="art_backend_patch_001" curl -L \ -H "Authorization: Bearer ${TOKEN}" \ -o "${ARTIFACT_ID}.txt" \ "${BASE_URL}/api/agent/user/deployments/${DEPLOYMENT_ID}/artifacts/${ARTIFACT_ID}/content" ``` 生产环境产物存储规则: - `RUNTIME_ARTIFACT_BACKEND=azblob` 时,Runtime 优先把完整产物上传到 Azure Blob,并在 artifact 列表中返回 `azblob:///`。 - 如果 Azure Blob 上传失败,Runtime 会回落到本地 artifact store,并返回 `runtime:///artifacts/`。 - 无论 `uri` 是 `azblob://` 还是 `runtime://`,Manager / 前端都优先使用 content 代理接口读取;不要把 Blob 凭据、SAS URL 或明文连接串暴露给用户端。 - callback 的 `payload.summary` 只用于展示摘要;完整内容以 content 接口返回的文件为准。 生产环境 Blob 配置要求: | 环境变量 | 说明 | 默认值 | |----------|------|--------| | `RUNTIME_ARTIFACT_BACKEND` | artifact 后端,生产建议使用 `azblob` | `azblob` | | `RUNTIME_ARTIFACT_BLOB_SECRET_NAME` | 保存 Blob 凭据的 K8s Secret 名称 | `agent-manager-secret` | | `RUNTIME_ARTIFACT_BLOB_SECRET_NAMESPACE` | Secret namespace;为空时使用 `NAMESPACE` 或 `agent-manager` | 空 | | `RUNTIME_ARTIFACT_BLOB_CONTAINER` | 默认容器名 | `heicode-artifacts` | | `RUNTIME_ARTIFACT_BLOB_PREFIX` | Blob 路径前缀 | `runtime-artifacts` | K8s Secret 支持两种凭据格式: - `AZURE_STORAGE_CONNECTION_STRING` - 或 `AZURE_STORAGE_ACCOUNT` + `AZURE_STORAGE_KEY` 可选覆盖项: - `AZURE_BLOB_CONTAINER`:覆盖默认容器名。 排障提示: - artifact 列表为空:先确认 run 已进入 terminal 状态,或 callback 订阅包含 `artifact.created`。 - 列表有记录但 content 返回 404:检查 `uri` 是否为 `runtime://` / `azblob://`,以及 Runtime 本地文件或 Blob Secret 是否仍可访问。 - 下载内容与摘要不一致:以 content 接口返回的完整文件为准,并用 `metadata.content_hash` 做完整性校验。 --- ## 2. 认证方式 ### 2.1 Service Token 认证 除健康检查外,所有 API 请求必须在 HTTP Header 中携带服务令牌: ```http Authorization: Bearer ``` ### 2.2 必需的 HTTP Headers | Header | 必需 | 说明 | 示例 | |--------|------|------|------| | `Authorization` | ✅ | 服务令牌 | `Bearer sk_xxx` | | `X-User-ID` | ✅ | 用户标识 | `user_12345` | | `X-Binding-Scope` | ✅ | 绑定范围 | `workspace_abc` | | `X-Correlation-ID` | ✅ | 请求追踪 ID | `req_xyz789` | | `X-Idempotency-Key` | ⚪ | 幂等性键(推荐) | `idem_abc123` | | `Content-Type` | ✅ | 内容类型 | `application/json` | > `GET /api/agent/health` 用于 K8s / LB 探活,不要求 `Authorization` 或业务追踪 Header。 ### 2.3 获取 Service Token 请联系系统管理员获取 `HEICODE_SERVICE_TOKEN`。 --- ## 3. API 端点 ### 3.1 健康检查 #### `GET /api/agent/health` 检查服务状态。 **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/health" ``` **响应示例**: ```json { "success": true, "data": { "status": "healthy", "service": "agent-manager-agnet", "version": "1.0.0", "phase": "2-deployments" } } ``` --- ### 3.2 创建部署 #### `POST /api/agent/sub-agile/deployments` 创建一个新的 Agent 部署。 **请求体**: ```json { "orchestration_plan": "multi-agent-workflow", "risk_level": "medium", "approval_token": "optional_for_high_risk", "budget": { "max_usd": 100.0, "alert_threshold_pct": 80 }, "billing_context": { "provider": "newapi", "default_model_id": "gpt-4", "allowed_model_ids": ["gpt-4", "gpt-3.5-turbo"], "secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key" }, "agents": [ { "role": "researcher", "image": "agnettaiji.azurecr.io/ai-agents/search-agent:v1.2.0" }, { "role": "writer", "image": "agnettaiji.azurecr.io/ai-agents/doc-creator:v1.2.0" } ], "resource_grants": [ { "type": "database", "ref": "azkv://heicode-kv.vault.azure.net/secrets/db-credentials", "permissions": ["read"] } ], "callback": { "url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events", "signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key", "subscribed_events": [ "phase.changed", "sk_tool.called", "sk_tool.completed", "sk_tool.failed", "approval.requested", "budget.alert", "deployment.status_changed", "agent.crashed" ] } } ``` **响应示例**: ```json { "success": true, "deployment_id": "dep_a1b2c3d4e5f6", "swarm_id": "dep_a1b2c3d4e5f6", "status": "pending", "agent_instances": [ { "agent_instance_id": "agi_123abc", "role": "researcher", "status": "pending", "phase": null }, { "agent_instance_id": "agi_456def", "role": "writer", "status": "pending", "phase": null } ], "created_at": "2026-05-27T10:30:00Z", "estimated_ready_at": "2026-05-27T10:32:00Z", "data": { "deployment_id": "dep_a1b2c3d4e5f6", "swarm_id": "dep_a1b2c3d4e5f6", "status": "pending", "estimated_ready_at": "2026-05-27T10:32:00" } } ``` 普通 sub 敏捷兼容: - `orchestration_plan` 可传字符串,也可传 Heicode sub 结构化对象。 - `budget.max_usd` 和 `budget.max_cost_usd` 双向兼容;缺失预算会被拒绝。 - `orchestration_plan.agents[].role_template` 会规范化为 Runtime `role`。 - `orchestration_plan.agents[].target_role` 也可作为 `role` 兼容来源。 - `orchestration_plan.billing_context.default_model_id` / `allowed_model_ids` / `secret_ref` 会透传到 Runtime 配置。 - `resource_grants` 可放在顶层,也可放在 `agents[].resource_grants`,Runtime 会做兼容汇总。 - 如果请求包含 `callback`,Runtime 会按订阅事件主动回调 `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started`、`artifact.created`,并在需要审批时回调 `approval.requested`。 - `callback.url` 在 `/api/agent/sub-agile/deployments` 中必须为 `https://`,`callback.signing_secret_ref` 必须为 `azkv://`。 --- ### 3.3 列出部署 #### `GET /api/agent/sub-agile/deployments` 获取部署列表,支持过滤和分页。 **查询参数**: | 参数 | 类型 | 必需 | 说明 | |------|------|------|------| | `user_id` | string | ⚪ | 按用户过滤 | | `binding_scope` | string | ⚪ | 按绑定范围过滤 | | `status` | string | ⚪ | 按状态过滤 (pending/running/stopped/failed) | | `limit` | integer | ⚪ | 每页数量 (默认 50, 最大 200) | | `cursor` | string | ⚪ | 分页游标 | **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments?user_id=user_123&status=running&limit=10" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_list_001" ``` **响应示例**: ```json { "deployments": [ { "deployment_id": "dep_a1b2c3d4e5f6", "status": "running", "risk_level": "medium", "budget": { "max_usd": 100.0, "consumed_usd": 23.5, "remaining_usd": 76.5 }, "created_at": "2026-05-12T10:30:00Z", "agent_instances_count": 2 } ], "pagination": { "next_cursor": null, "has_more": false } } ``` --- ### 3.4 获取部署详情 #### `GET /api/agent/sub-agile/deployments/{deployment_id}` 获取指定部署的详细信息。 **路径参数**: - `deployment_id`: 部署 ID **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_get_001" ``` **响应示例**: ```json { "deployment_id": "dep_a1b2c3d4e5f6", "user_id": "user_123", "binding_scope": "workspace_abc", "status": "running", "phase": "executing", "orchestration_plan": "multi-agent-workflow", "risk_level": "medium", "budget": { "max_usd": 100.0, "consumed_usd": 23.5, "remaining_usd": 76.5 }, "billing_context": { "provider": "newapi", "default_model_id": "gpt-4", "allowed_model_ids": ["gpt-4", "gpt-3.5-turbo"] }, "agent_instances": [ { "agent_instance_id": "agi_123abc", "role": "researcher", "status": "running", "phase": "searching" }, { "agent_instance_id": "agi_456def", "role": "writer", "status": "running", "phase": "writing" } ], "resource_grants": [ { "type": "database", "ref": "azkv://heicode-kv.vault.azure.net/secrets/db-credentials" } ], "created_at": "2026-05-12T10:30:00Z", "updated_at": "2026-05-12T10:35:00Z" } ``` --- ### 3.5 停止部署 #### `POST /api/agent/sub-agile/deployments/{deployment_id}/stop` 停止一个正在运行的部署。 **路径参数**: - `deployment_id`: 部署 ID **请求体**: ```json { "reason": "User requested stop", "approval_token": "optional_for_high_risk" } ``` **请求示例**: ```bash curl -X POST "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/stop" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_stop_001" \ -H "Content-Type: application/json" \ -d '{ "reason": "Task completed" }' ``` **响应示例**: ```json { "deployment_id": "dep_a1b2c3d4e5f6", "status": "stopped", "stopped_at": "2026-05-12T11:00:00Z" } ``` --- ### 3.6 获取部署日志 #### `GET /api/agent/sub-agile/deployments/{deployment_id}/logs` 获取部署的实时日志。 **路径参数**: - `deployment_id`: 部署 ID **查询参数**: | 参数 | 类型 | 必需 | 说明 | |------|------|------|------| | `agent_instance_id` | string | ⚪ | 按 Agent 实例过滤 | | `since` | datetime | ⚪ | 起始时间 (ISO 8601) | | `limit` | integer | ⚪ | 日志条数 (默认 100) | **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/logs?limit=50" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_logs_001" ``` **响应示例**: ```json { "deployment_id": "dep_a1b2c3d4e5f6", "logs": [ { "timestamp": "2026-05-12T10:31:00Z", "agent_instance_id": "agi_123abc", "level": "info", "message": "Starting search task...", "source": "stdout" }, { "timestamp": "2026-05-12T10:31:05Z", "agent_instance_id": "agi_123abc", "level": "info", "message": "Found 10 relevant documents", "source": "stdout" } ], "pagination": { "has_more": false } } ``` --- ### 3.7 获取部署事件 #### `GET /api/agent/sub-agile/deployments/{deployment_id}/events` 获取部署的事件历史。 **路径参数**: - `deployment_id`: 部署 ID **查询参数**: | 参数 | 类型 | 必需 | 说明 | |------|------|------|------| | `event_type` | string | ⚪ | 事件类型过滤 | | `since` | datetime | ⚪ | 起始时间 (ISO 8601) | | `limit` | integer | ⚪ | 事件条数 (默认 100) | **事件类型**: - `deployment.accepted` - 部署已接受 - `deployment.started` - 部署已启动 - `deployment.stopped` - 部署已停止 - `deployment.failed` - 部署失败 - `agent.started` - Agent 启动 - `agent.completed` - Agent 完成 - `budget.alert` - 预算告警 **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/events" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_events_001" ``` **响应示例**: ```json { "deployment_id": "dep_a1b2c3d4e5f6", "events": [ { "event_id": "evt_abc123", "event_type": "deployment.accepted", "agent_instance_id": null, "occurred_at": "2026-05-12T10:30:00Z", "payload": { "risk_level": "medium" } }, { "event_id": "evt_def456", "event_type": "agent.started", "agent_instance_id": "agi_123abc", "occurred_at": "2026-05-12T10:31:00Z", "payload": { "role": "researcher" } } ], "pagination": { "has_more": false } } ``` --- ### 3.8 获取资源指标 #### `GET /api/agent/sub-agile/deployments/{deployment_id}/metrics` 获取部署的资源使用指标。 **路径参数**: - `deployment_id`: 部署 ID **请求示例**: ```bash curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/metrics" \ -H "Authorization: Bearer sk_xxx" \ -H "X-User-ID: user_123" \ -H "X-Binding-Scope: workspace_abc" \ -H "X-Correlation-ID: req_metrics_001" ``` **响应示例**: ```json { "deployment_id": "dep_a1b2c3d4e5f6", "timestamp": "2026-05-12T10:35:00Z", "agent_metrics": [ { "agent_instance_id": "agi_123abc", "role": "researcher", "status": "running", "resources": { "cpu_usage_cores": 0.25, "memory_usage_mb": 256.0, "network_rx_bytes": 1048576, "network_tx_bytes": 524288 }, "uptime_seconds": 300 }, { "agent_instance_id": "agi_456def", "role": "writer", "status": "running", "resources": { "cpu_usage_cores": 0.15, "memory_usage_mb": 128.0, "network_rx_bytes": 524288, "network_tx_bytes": 262144 }, "uptime_seconds": 300 } ], "total_resources": { "cpu_usage_cores": 0.40, "memory_usage_mb": 384.0, "network_rx_bytes": 1572864, "network_tx_bytes": 786432 } } ``` --- ### 3.9 Runtime Callback 回写 #### `POST /api/agent/callbacks/runtime-events` Agent Manager / Runtime 使用该接口向 Heicode Manager 回写 sub 模式事件、阶段变化、产物、预算告警、审批请求和 SK 工具调用结果。该接口是反向通知协议,不能仅依赖 `/events` 轮询替代。 #### `GET /api/agent/callbacks/runtime-events/schema` 联调前可读取 callback schema。该接口只返回事件类型、分类、必填字段、阶段枚举和 artifact 类型,不返回 token、secret 或任何明文密钥。 响应字段: | 字段 | 说明 | |------|------| | `event_types` | 支持的 `deployment.status_changed`、`phase.changed`、`timeline.updated`、`artifact.created`、`approval.requested`、`sk_tool.*`、`budget.alert` 等事件 | | `body_required_fields` | callback envelope 必填字段 | | `headers` | HMAC、幂等、追踪相关 Header 约定 | | `stages` | 普通 sub 敏捷阶段:`planning/design/development/testing/fixing/deployment/review/done/failed` | | `artifact_types` | `code_patch/document/test_report/deployment_manifest/log_bundle/other` | **请求 Header**: | Header | 必需 | 说明 | |--------|------|------| | `X-Agnet-Event-Id` | 是 | 全局唯一事件 ID,用于幂等去重 | | `X-Agnet-Signature` | 是 | HMAC-SHA256 签名,格式为 `sha256=` | | `X-Agnet-Timestamp` | 是 | Unix 毫秒时间戳,接收方应校验时间窗口 | | `X-Correlation-ID` | 推荐 | 全链路追踪 ID;缺失时 Manager 会使用 body `correlation_id` 或 deployment 记录兜底 | | `Content-Type` | 是 | `application/json` | 过渡兼容:当前 Manager v2.1 仍接受旧版 `X-Agnet-Service-Token` 或 `Authorization: Bearer ` callback 认证。Agent Manager / Runtime 新实现必须优先使用 HMAC。 **签名规范**: ```text signature_payload = timestamp + "." + event_id + "." + raw_body signature = HMAC_SHA256(callback_signing_secret, signature_payload) ``` 其中 `timestamp` 取 `X-Agnet-Timestamp`,`event_id` 取 `X-Agnet-Event-Id`,`raw_body` 必须使用 HTTP 请求原始 body 字节,不应在验签前重新格式化 JSON。 `callback_signing_secret` 不在请求中明文传输。创建部署或 `/api/swarms` 时通过 `callback.signing_secret_ref` 指向 Azure Key Vault。Manager 当前按 5 分钟时间窗校验 `X-Agnet-Timestamp`,超出窗口返回 `401 UNAUTHORIZED`。 Runtime 发送端签名密钥解析顺序: 1. 优先读取与 `signing_secret_ref` secret name 对应的环境变量。例如 `azkv://.../secrets/agnet-callback-signing-key` 会先查 `AGNET_CALLBACK_SIGNING_KEY`。 2. 其次读取通用环境变量:`HEICODE_CALLBACK_SIGNING_SECRET`、`CALLBACK_SIGNING_SECRET`。 3. 如果是 `azkv://` 引用且配置了 `AZURE_TENANT_ID`、`AZURE_CLIENT_ID`、`AZURE_CLIENT_SECRET`,Runtime 会使用 client credentials 从 Azure Key Vault 拉取 secret value。 4. 如果仍无法解析,Runtime 会使用 `HEICODE_SERVICE_TOKEN` 作为过渡期 fallback,并记录 warning。生产环境应配置明确的 callback signing secret。 **事件 Envelope**: ```json { "event_id": "evt_01HX...", "event_type": "phase.changed", "deployment_id": "dep_a1b2c3d4", "swarm_id": "dep_a1b2c3d4", "agent_instance_id": "agi_backend_001", "occurred_at": "2026-05-27T10:40:00Z", "correlation_id": "req_xxx", "payload": {} } ``` 字段兼容: - `event_id` 优先取 Header `X-Agnet-Event-Id`,body `event_id` 作为兼容字段。 - `deployment_id` 为主关联键;如果 Runtime 只传 `swarm_id`,Manager 当前会兼容用 `swarm_id` 查 deployment。 - `payload` 是标准业务载荷;旧版顶层 `artifact` 会被兼容合并到 `payload`。 - `occurred_at` 使用 Runtime 真实发生时间;解析失败时 Manager 使用接收时间兜底。 **标准事件类型**: | 事件类型 | 说明 | |----------|------| | `deployment.status_changed` | 部署整体状态变化 | | `phase.changed` | 7 阶段进度变化 | | `agent.started` | Agent 启动 | | `agent.completed` | Agent 完成 | | `agent.crashed` | Agent 异常退出或 Pod OOMKilled | | `task.completed` | 普通 sub 子任务完成 | | `task.failed` | 普通 sub 子任务失败 | | `task.blocked` | 普通 sub 子任务被阻塞 | | `sk_tool.called` | SK 工具开始调用,参数必须脱敏 | | `sk_tool.completed` | SK 工具调用成功,包含耗时、摘要和产物引用 | | `sk_tool.failed` | SK 工具调用失败,包含脱敏错误原因 | | `approval.requested` | 高危操作等待 Heicode / 桌面客户端审批 | | `budget.alert` | 预算告警 | | `artifact.created` | 产物已生成 | | `timeline.updated` | Runtime 时间线事件 | 默认订阅事件:创建部署时如果 `callback.subscribed_events` 为空,Manager 默认订阅上表中的 v2.1 标准事件集。 当前 Runtime 主动发送节点: | 触发时机 | 事件 | |----------|------| | `/api/agent/sub-agile/deployments` 创建 accepted/running | `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started`、`artifact.created` | | Swarm 初始化 / 运行 / 完成 / 失败 / 停止 | `deployment.status_changed` | | 规划、实现、检查、完成等阶段变化 | `phase.changed`、`timeline.updated` | | Agent 可运行 | `agent.started` | | Agent 任务完成 | `agent.completed` | | 普通 sub 子任务结束 | `task.completed`、`task.failed`、`task.blocked` | | Agent 任务派发 | `sk_tool.called` | | Agent 任务成功 | `sk_tool.completed` | | Agent 任务失败 | `sk_tool.failed` | | Swarm/普通 sub 产物生成 | `artifact.created` | | `agile_context.requires_user_approval=true` 或高风险任务 | `approval.requested` | | 设置成本预算 | `budget.alert` | 发送失败策略:当前 Runtime callback 发送失败只记录 warning,不阻塞 Agent 执行。指数退避、死信队列和人工重放属于后续增强项。 **7 阶段枚举**: | 阶段 | 说明 | |------|------| | `requirements` | 需求 | | `design` | 设计 | | `backend` | 后端 | | `frontend` | 前端 | | `review` | 检查 | | `test` | 测试 | | `deploy` | 部署 | **重试与幂等**: 1. Heicode Manager 按 `X-Agnet-Event-Id` 或 body `event_id` 去重;重复事件必须返回 2xx。 2. 重复事件仍需先通过认证校验;通过后返回 `deduplicated: true`。 3. 当前 Agent Manager Runtime 推送失败只记录 warning,不阻塞 Agent 执行。 4. 指数退避、死信队列和人工重放是后续增强目标;建议目标延迟为 1s、5s、30s、2m、10m,最多重试 12 小时。 5. 同一 `deployment_id` 内事件按 `occurred_at` 尽力有序;跨 deployment 不保证顺序。 **响应示例**: ```json { "success": true, "event_id": "evt_01HX...", "deduplicated": false } ``` --- ### 3.10 Heicode Manager 用户态接口边界 以下接口由 Heicode Manager 提供或作为 Manager 前端边界使用。Agent Manager 文档需要明确这些接口不全由 Runtime 实现;Runtime 主要调用 callback 接口、消费部署计划,并可实现 `/api/swarms` 兼容入口。 | 方法 | 路径 | 调用方 | 用途 | |------|------|--------|------| | `POST` | `/api/agent/user/tasks/{task_id}/deployment-draft` | Heicode 客户端 / Manager 前端 | 从任务卡生成 Agent deployment draft | | `POST` | `/api/agent/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态创建部署记录 | | `GET` | `/api/agent/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态部署列表 | | `GET` | `/api/agent/user/deployments/{deployment_id}` | Heicode 客户端 / Manager 前端 | 用户态部署详情 | | `POST` | `/api/swarms` | Runtime 对接适配 / Manager | 创建 Swarm Run 的兼容入口,目前映射到 Manager 本地部署控制面 | | `POST` | `/api/agent/callbacks/runtime-events` | Agent Manager / Runtime | Runtime 回写状态、事件、artifact | | `GET` | `/api/agent/user/deployments/{deployment_id}/artifacts` | Heicode 客户端 / Manager 前端 | 查询部署产物 | | `GET` | `/api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` | Heicode 客户端 / Manager 前端 | 下载完整产物内容 | | `GET` | `/api/agent/user/deployments/{deployment_id}/sk-snapshots` | Heicode 客户端 / Manager 前端 | 查询 SK 快照 | | `GET` | `/api/agent/user/deployments/{deployment_id}/timeline` | Heicode 客户端 / Manager 前端 | 查询合并时间线 | 说明: 1. `POST /api/swarms` 当前返回 `deployment_id` 和 `swarm_id`;当前二者同值,均可用于 Runtime 查询和停止。 2. 后续如果 Runtime 返回自己的真实 `swarm_id`,Manager 需要保存 `deployment_id <-> swarm_id` 映射。 3. Runtime 侧不能只支持 `/api/agent/sub-agile/deployments`,否则无法覆盖 Heicode 用户态任务流。 #### `POST /api/swarms` Heicode sub 模式兼容入口。该接口接受结构化 `orchestration_plan`,用于 agile / waterfall 任务流创建 Runtime run。 当前联调约束: - 缺少 `orchestration_plan`、`callback.url`、`orchestration_plan.sub_mode`、`orchestration_plan.user_context.user_id` 时返回 422。 - `dry_run:true` 当前返回 422,且不会创建真实 swarm;后续如果支持 dry-run,需要返回校验结果但不落库、不启动 Runtime。 - 同一个 `X-Idempotency-Key` 重复请求返回同一个 run。 - `sub_mode=agile` 默认使用 hybrid orchestration;`sub_mode=waterfall` 使用 sequential orchestration。 - `budget.max_duration_sec` 会换算为 Runtime timeout minutes,默认兜底为 1800 秒。 **请求示例**: ```json { "orchestration_plan": { "intent_id": "task_123", "template_hint": "heicode-task", "objective": "完成本轮任务目标", "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-27~2026-05-28", "stage": "development", "checkpoint": "ready_for_test", "acceptance_criteria": [ "接口返回成功", "Manager 前端可点击验证", "artifact 可回写到 timeline", "不出现明文密钥" ], "next_action": "submit_test_result", "requires_user_approval": false }, "agents": [], "resource_grants": [] }, "callback": { "url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events", "signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key" } } ``` **最小有效请求示例**: ```json { "orchestration_plan": { "intent_id": "task_123", "objective": "完成本轮任务目标", "sub_mode": "agile", "user_context": { "user_id": "123", "binding_scope": "task-task-123" }, "budget": { "max_cost_usd": 8 }, "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" } }, "callback": { "url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events", "signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key" } } ``` **校验失败示例**: ```json { "detail": "callback.url is required" } ``` **dry-run 拒绝示例**: ```json { "detail": "dry_run is not supported by Runtime create; no swarm was created" } ``` #### `/api/swarms` 运行期兼容接口 普通 sub 敏捷模式不要求完整蜂群 task graph,但 Runtime 需要提供 Manager 可调用的停止、审批和排障接口。当前 Agent Manager 在 `/api/swarms` 下支持以下兼容路径: | 方法 | 路径 | 说明 | |------|------|------| | `GET` | `/api/swarms/{swarm_id}` | 查询 Runtime run 详情,等价于 status 详情 | | `GET` | `/api/swarms/{swarm_id}/status` | 查询 Runtime run 状态、阶段、进度、Agent 和 artifact 摘要 | | `POST` | `/api/swarms/{swarm_id}/stop` | 停止 Runtime run;幂等返回 `stopped` | | `GET` | `/api/swarms/{swarm_id}/logs` | 查询 Runtime/Agent 日志聚合兜底 | | `GET` | `/api/swarms/{swarm_id}/events` | 查询 Runtime message/event 兜底 | | `GET` | `/api/swarms/{swarm_id}/metrics` | 查询基础用量、耗时、artifact 数量等指标 | | `GET` | `/api/swarms/{swarm_id}/artifacts/{artifact_id}/content` | 读取 Runtime-local 或 Azure Blob 中的完整 artifact 内容 | | `POST` | `/api/swarms/{swarm_id}/approvals/{approval_id}` | 接收 Manager 审批 decision,支持 `approved` / `rejected` | 审批 decision 请求示例: ```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://agnet/lease_xxx", "lease_id": "lease_xxx", "lease_expires_at": 1779850900000 } ``` 如果普通 sub 不走 `/api/swarms`,也支持: ```http POST /api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id} ``` **响应示例**: ```json { "deployment_id": "swm_a1b2c3d4e5f6", "swarm_id": "swm_a1b2c3d4e5f6", "status": "initializing", "agents": [], "created_at": "2026-05-27T10:30:00Z", "estimated_ready_at": "2026-05-27T10:32:00Z" } ``` **状态响应示例**: ```json { "deployment_id": "swm_a1b2c3d4e5f6", "swarm_id": "swm_a1b2c3d4e5f6", "status": "running", "phase": "planning", "progress": 10, "agents": [ { "agent_id": "agi_backend_12345678", "role": "backend", "status": "running", "namespace": "swarm-swm-a1b2c3d4e5f6", "service_url": null, "current_task": null, "output": null } ], "metrics": { "total_messages": 1, "tokens_used": 0, "elapsed_seconds": 30 }, "artifacts": [], "error_message": null, "created_at": "2026-05-28T10:30:00Z", "updated_at": "2026-05-28T10:30:30Z" } ``` #### `GET /api/agent/user/deployments/{deployment_id}/artifacts` 查询 Runtime 通过 `artifact.created` callback 回写的产物。当前 Manager 从 callback event payload 投影生成响应;大文件只返回 `uri`、摘要、大小和 hash 信息,完整内容需要继续调用 artifact content 接口读取。完整操作流程见 [1.7 产物获取速查](#17-产物获取速查)。 **响应示例**: ```json { "success": true, "deployment_id": "dep_a1b2c3d4", "artifacts": [ { "event_id": "evt_art_001", "artifact_id": "art_backend_patch_001", "artifact_type": "code_patch", "title": "Backend API patch", "summary": "新增 deployment draft 到 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 }, "created_at": "2026-05-27T10:40:00Z" } ] } ``` #### `GET /api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` 读取 Runtime artifact 的完整内容。该接口是 Manager / 前端获取产物正文的推荐入口,要求携带 `Authorization: Bearer `。 该接口支持两类 URI: - `runtime:///artifacts/`:从 Runtime 本地 artifact store 返回文件内容。 - `azblob:///`:使用 Runtime 从 K8s Secret 读取到的 Azure Blob 凭据代理读取内容。 Azure Blob 凭据来自 `RUNTIME_ARTIFACT_BLOB_SECRET_NAMESPACE` / `RUNTIME_ARTIFACT_BLOB_SECRET_NAME` 指定的 K8s Secret。Runtime 优先读取 `AZURE_STORAGE_CONNECTION_STRING`;若为空,则读取 `AZURE_STORAGE_ACCOUNT` + `AZURE_STORAGE_KEY`。容器名优先读取 Secret 中的 `AZURE_BLOB_CONTAINER`,否则使用 `RUNTIME_ARTIFACT_BLOB_CONTAINER`。 响应是原始文件内容,不再包一层 JSON。Runtime 会按存储记录或 Blob 属性设置 `Content-Type`,并通过 `Content-Disposition` 给出下载文件名。 **请求示例**: ```bash curl -L \ -H "Authorization: Bearer " \ -o artifact-output.txt \ "https://agent-manager.taijiagnet.com/api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content" ``` 如果调用方已经持有 Runtime `swarm_id`,也可以直接使用兼容接口: ```bash curl -L \ -H "Authorization: Bearer " \ -o artifact-output.txt \ "https://agent-manager.taijiagnet.com/api/swarms/{swarm_id}/artifacts/{artifact_id}/content" ``` #### `GET /api/agent/user/deployments/{deployment_id}/timeline` 查询合并时间线。当前 Manager 会合并 `timeline.updated`、阶段变化、Agent 状态、预算告警、审批请求、artifact 与 SK 工具事件。 **响应示例**: ```json { "success": true, "deployment_id": "dep_a1b2c3d4", "timeline": [ { "event_id": "evt_tl_001", "event_type": "timeline.updated", "occurred_at": "2026-05-27T10:41:00Z", "agent_instance_id": "agi_backend_001", "title": "后端实现完成", "summary": "backend agent 已生成 API patch,等待测试", "stage": "development", "checkpoint": "ready_for_test", "severity": "info", "next_action": "submit_test_result", "payload": { "agent_role": "backend" } } ] } ``` #### `GET /api/agent/user/deployments/{deployment_id}/sk-snapshots` 查询 Runtime 回写的 SK snapshot。当前 Manager 从 `sk_tool.called/completed/failed` 和包含 `sk_snapshot` 的 artifact 事件投影生成响应。 **响应示例**: ```json { "success": true, "deployment_id": "dep_a1b2c3d4", "sk_snapshots": [ { "event_id": "evt_tool_001", "snapshot_id": "sks_task_123_backend_001", "deployment_id": "dep_a1b2c3d4", "agent_instance_id": "agi_backend_001", "agent_role": "backend", "source_type": "git", "source_ref": "git:https://example.com/heicode-tools.git#main:backend", "content_hash": "sha256:abc123...", "tool_name": "repo_write", "tool_invocation_id": "inv_abc123", "created_at": "2026-05-27T10:35:00Z", "metadata": { "redacted": true } } ] } ``` --- ### 3.11 模板 Agent Runtime 兼容接口 除 sub-mode runtime 外,当前仓库也保留了模板 Agent 的旧版统一入口 `POST /agents`。为对齐 HM 的模板 Agent 联调,本节补充这组接口的生命周期兼容契约。 #### 生命周期接口列表 | 方法 | 路径 | 说明 | |------|------|------| | `POST` | `/agents` | 创建模板 Agent;返回 HM 可直接解析的实例标识和访问地址别名字段 | | `GET` | `/agents/{agent_name}` | 查询模板 Agent 生命周期状态;返回平铺 `status` / `runtime_status` / `state` | | `POST` | `/agents/{agent_name}/stop` | 幂等停止模板 Agent;停止运行 Pod,但保留数据库记录 | | `DELETE` | `/agents/{agent_name}` | 删除模板 Agent 运行资源和数据库记录 | | `GET` | `/agents/{agent_name}/status` | 查询详细 Pod/容器状态与访问信息,适合排障 | | `GET` | `/agents/{agent_name}/metrics` | 查询模板 Agent 资源使用信息 | #### `POST /agents` 请求示例: ```json { "name": "dep-b5fab27e9255", "template": "coding_a2a_agent", "framework": "A2A", "config": { "user_id": "22", "manager_deployment_id": "dep_b5fab27e9255", "callback_url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events" }, "env": { "AGENT_ROLE_NAME": "architect", "AGENT_INSTRUCTION_TEXT": "---\nname: architect\n---\n...", "OPENAI_BASE_URL": "https://code.xinghanlab.com/v1", "OPENAI_API_KEY": "sk-xxxx", "MODEL_NAME": "gpt-5.4", "AGENT_ACCESS_TOKEN": "550e8400-e29b-41d4-a716-446655440000", "HEICODE_AGENT_ID": "dep-b5fab27e9255" } } ``` 响应示例: ```json { "name": "dep-b5fab27e9255", "runtime_id": "dep-b5fab27e9255", "agent_id": "dep-b5fab27e9255", "id": "dep-b5fab27e9255", "namespace": "agent-dep-b5fab27e9255", "status": "running", "runtime_status": "running", "state": "running", "framework": "A2A", "subdomain": "dep-b5fab27e9255.taijiagnet.com", "access_token": null, "access_info": { "domain": "dep-b5fab27e9255.taijiagnet.com", "domain_url": "http://dep-b5fab27e9255.taijiagnet.com", "external_ip": "20.212.121.126" } } ``` 字段兼容约定: - `runtime_id` / `agent_id` / `id` 当前都等于 Agent 名称,可直接作为后续生命周期调用的实例标识。 - `subdomain` 取自 `access_info.domain`,若 DNS 尚未就绪则回退到 `access_info.external_ip`。 - `runtime_status` / `state` 是对 Pod 生命周期的兼容投影;当前可能值为 `pending`、`running`、`stopped`、`failed`。 #### 客户端直连鉴权 模板 Agent 当前支持 HM 约定的本地访问鉴权: - 当实例环境变量存在 `AGENT_ACCESS_TOKEN` 时,`POST /message/send`、`POST /message/stream`、`GET /tasks/{task_id}` 必须携带请求头 `X-Agent-Access-Token` - 服务端使用常量时间比较校验 `X-Agent-Access-Token == AGENT_ACCESS_TOKEN` - 请求头缺失时返回 `401` - 请求头不匹配时返回 `403` - 若实例未注入 `AGENT_ACCESS_TOKEN`,则继续兼容放行 职责边界: - `X-Agent-Access-Token` 用于“谁有权访问这个 agent” - A2A body 中的 `api_key` 仍用于“本次请求走谁的模型额度” #### `GET /agents/{agent_name}` 用于 HM 轮询模板 Agent 生命周期。返回体与 `POST /agents` 的核心生命周期字段保持一致,便于 HM 复用同一套解析逻辑。 #### `POST /agents/{agent_name}/stop` 响应示例: ```json { "status": "success", "message": "Agent dep-b5fab27e9255 已停止" } ``` 约定: - 该接口为幂等停止接口。 - 停止动作会删除当前运行 Pod,并将数据库中的 Agent 状态收敛为 `stopped`。 - 若要彻底清理实例,请在停止后继续调用 `DELETE /agents/{agent_name}`。 #### `DELETE /agents/{agent_name}` 说明: - 删除接口当前已修复模板 Agent 场景下的数据库变量引用问题,不再出现此前的 `UnboundLocalError` 500。 - 删除动作会清理 DNS、K8s namespace 以及数据库中的 Agent 记录。 --- ## 4. 数据模型 ### 4.1 部署状态 (DeploymentStatus) | 状态 | 说明 | |------|------| | `pending` | 等待启动 | | `running` | 运行中 | | `stopped` | 已停止 | | `failed` | 失败 | ### 4.2 风险等级 (RiskLevel) | 等级 | 说明 | 审批要求 | |------|------|----------| | `low` | 低风险 | 无需审批 | | `medium` | 中风险 | 无需审批 | | `high` | 高风险 | 需要 approval_token | ### 4.3 计费提供商 (BillingProvider) | 提供商 | 说明 | |--------|------| | `newapi` | Heicode NewAPI Gateway | | `litellm` | LiteLLM Proxy | ### 4.4 资源授权类型 (ResourceGrantType) | 类型 | 说明 | |------|------| | `database` | 数据库访问 | | `storage` | 存储访问 | | `api` | API 访问 | | `git` | 代码仓库访问 | | `custom` | 自定义资源 | ### 4.5 sub 模式 (SubMode) | 值 | 说明 | |----|------| | `agile` | 敏捷迭代模式,当前优先验证 | | `waterfall` | 瀑布模式,按阶段顺序执行 | 缺省策略:如果请求未传 `sub_mode`,Runtime 按 `agile` 处理。 ### 4.6 敏捷上下文 (AgileContext) ```json { "iteration": "2026-05-27~2026-05-28", "stage": "development", "checkpoint": "ready_for_test", "acceptance_criteria": [ "接口返回成功", "Manager 前端可点击验证", "artifact 可回写到 timeline", "不出现明文密钥" ], "next_action": "submit_test_result", "requires_user_approval": false } ``` 建议枚举: | 字段 | 建议值 | |------|--------| | `stage` | `planning`、`development`、`testing`、`deployment`、`review`、`done` | | `checkpoint` | `draft_created`、`runtime_accepted`、`agent_running`、`artifact_ready`、`ready_for_test`、`approval_required`、`completed`、`failed` | | `next_action` | `continue`、`request_approval`、`submit_artifact`、`submit_test_result`、`stop` | ### 4.7 Resource Grant 与 secret_ref Heicode sub 模式使用扩展 Resource Grant 表达任务资源授权。Runtime 必须接受 `resource_type / permission_scope / secret_ref` 形式,并可兼容旧字段 `type / permissions / ref`。 ```json { "grant_id": "grant-task-123-backend-1", "resource_id": "res_git_main", "resource_type": "git", "user_id": "123", "binding_scope": "task-task-123", "target_role": "backend", "target_agent_ref": "agent-backend-1", "permission_scope": ["read", "write"], "constraints": { "path_prefix": "heicode/" }, "metadata": { "repo": "heicode-manager" }, "status": "active", "secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/user-123-repo-main", "audit": { "source": "heicode-manager" } } ``` 安全规则: 1. 凭据型资源必须有 `secret_ref`。 2. `secret_ref` 必须使用 `azkv:///secrets/` 格式。 3. `azkv://` 是引用,不是明文密钥;Runtime 不应把它展开写入日志、回调或 artifact metadata。 4. `metadata`、`constraints`、`audit` 中禁止出现明文 `password`、`token`、`secret`、`private_key`、`connection_string`、`access_key`。 5. `vault:heicode/...` 仅作为旧版兼容,不再作为正式示例。 ### 4.8 Artifact 回写模型 Runtime 通过 `/api/agent/callbacks/runtime-events` 回写产物事件,Manager 将其持久化后供用户态接口查询。 ```json { "event_type": "artifact.created", "deployment_id": "dep_a1b2c3d4", "swarm_id": "dep_a1b2c3d4", "occurred_at": "2026-05-27T10:40:00Z", "payload": { "artifact_id": "art_backend_patch_001", "artifact_type": "code_patch", "title": "Backend API patch", "summary": "新增 deployment draft 到 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 } } } ``` 约束: - `payload.summary` 可展示给用户;不得包含密钥、Token、连接串。 - 大文件只传 `uri`、摘要和大小,不在 callback body 中内联完整内容。 - Runtime 上传成功时产物使用 `azblob:///`;上传失败时回落到 `runtime:///artifacts/`。完整内容通过 `/api/swarms/{swarm_id}/artifacts/{artifact_id}/content` 或用户态 artifact content 代理接口读取。 - `artifact_type` 建议值:`code_patch`、`document`、`test_report`、`deployment_manifest`、`log_bundle`、`other`。 ### 4.9 Timeline 事件模型 Runtime 事件需要能合并进 Manager 时间线。除 callback 契约中的标准事件外,sub 模式事件建议带上以下字段: ```json { "event_type": "timeline.updated", "deployment_id": "dep_a1b2c3d4", "occurred_at": "2026-05-27T10:41:00Z", "payload": { "title": "后端实现完成", "summary": "backend agent 已生成 API patch,等待测试", "stage": "development", "checkpoint": "ready_for_test", "agent_role": "backend", "severity": "info", "next_action": "submit_test_result" } } ``` `severity` 建议值:`info`、`warning`、`error`、`success`。 ### 4.10 SK Snapshot 模型 SK snapshot 用于追踪工具/技能来源、快照版本和执行上下文。Runtime 应在调用 SK 工具或生成 artifact 时回写快照引用。 ```json { "snapshot_id": "sks_task_123_backend_001", "deployment_id": "dep_a1b2c3d4", "agent_instance_id": "agi_backend_001", "agent_role": "backend", "source_type": "git", "source_ref": "git:https://example.com/heicode-tools.git#main:backend", "content_hash": "sha256:abc123...", "tool_name": "repo_write", "tool_invocation_id": "inv_abc123", "created_at": "2026-05-27T10:35:00Z", "metadata": { "redacted": true } } ``` 约束: - `source_ref` 不得包含账号密码、Token 或临时签名 URL。 - `metadata` 只允许放脱敏后的上下文。 - `tool_invocation_id` 应能与 `sk_tool.called/completed/failed` 事件关联。 --- ## 5. 使用示例 ### 5.1 完整工作流示例 ```python import requests import time # 配置 BASE_URL = "https://agent-manager.taijiagnet.com" TOKEN = "sk_your_service_token" USER_ID = "user_123" BINDING_SCOPE = "workspace_abc" headers = { "Authorization": f"Bearer {TOKEN}", "X-User-ID": USER_ID, "X-Binding-Scope": BINDING_SCOPE, "X-Correlation-ID": f"req_{int(time.time())}", "Content-Type": "application/json" } # 1. 创建部署 create_payload = { "orchestration_plan": "research-and-write", "risk_level": "medium", "budget": { "max_usd": 50.0, "alert_threshold_pct": 80 }, "billing_context": { "provider": "newapi", "default_model_id": "gpt-4", "allowed_model_ids": ["gpt-4", "gpt-3.5-turbo"], "secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/model-gateway-key" }, "agents": [ { "role": "researcher", "image": "agnettaiji.azurecr.io/ai-agents/search-agent:v1.2.0" }, { "role": "writer", "image": "agnettaiji.azurecr.io/ai-agents/doc-creator:v1.2.0" } ], "resource_grants": [] } response = requests.post( f"{BASE_URL}/api/agent/sub-agile/deployments", headers=headers, json=create_payload ) deployment = response.json() deployment_id = deployment["deployment_id"] print(f"✅ 部署创建成功: {deployment_id}") # 2. 等待部署就绪 time.sleep(120) # 等待 2 分钟 # 3. 获取部署详情 response = requests.get( f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}", headers=headers ) details = response.json() print(f"📊 部署状态: {details['status']}") # 4. 获取实时日志 response = requests.get( f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/logs?limit=20", headers=headers ) logs = response.json() print(f"📝 最新日志: {len(logs['logs'])} 条") # 5. 获取资源指标 response = requests.get( f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/metrics", headers=headers ) metrics = response.json() print(f"💻 CPU 使用: {metrics['total_resources']['cpu_usage_cores']} cores") print(f"💾 内存使用: {metrics['total_resources']['memory_usage_mb']} MB") # 6. 停止部署 stop_payload = { "reason": "Task completed successfully" } response = requests.post( f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/stop", headers=headers, json=stop_payload ) result = response.json() print(f"🛑 部署已停止: {result['stopped_at']}") ``` ### 5.2 幂等性示例 使用 `X-Idempotency-Key` 确保请求幂等性: ```python import uuid idempotency_key = f"idem_{uuid.uuid4().hex}" headers = { "Authorization": f"Bearer {TOKEN}", "X-User-ID": USER_ID, "X-Binding-Scope": BINDING_SCOPE, "X-Correlation-ID": f"req_{int(time.time())}", "X-Idempotency-Key": idempotency_key, # 幂等性键 "Content-Type": "application/json" } # 第一次请求 response1 = requests.post( f"{BASE_URL}/api/agent/sub-agile/deployments", headers=headers, json=create_payload ) # 重复请求(使用相同的 idempotency_key) response2 = requests.post( f"{BASE_URL}/api/agent/sub-agile/deployments", headers=headers, json=create_payload ) # response1 和 response2 返回相同的结果 assert response1.json()["deployment_id"] == response2.json()["deployment_id"] ``` ### 5.3 普通 sub Runtime 联调示例 以下示例使用 `/api/swarms` 入口创建普通 sub 敏捷 Runtime run,并查询状态与时间线。 ```python import requests import time import uuid BASE_URL = "http://20.212.121.126" TOKEN = "sk_your_service_token" headers = { "Authorization": f"Bearer {TOKEN}", "X-Correlation-ID": f"req_{int(time.time())}", "X-Idempotency-Key": f"idem_{uuid.uuid4().hex}", "Content-Type": "application/json" } payload = { "orchestration_plan": { "intent_id": "task_123", "objective": "完成本轮任务目标", "sub_mode": "agile", "user_context": { "user_id": "123", "binding_scope": "task-task-123" }, "budget": { "max_cost_usd": 8, "max_duration_sec": 3600 }, "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" }, "agents": [ { "role_template": "backend", "default_model_id": "model_xxx" } ] }, "callback": { "url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events", "signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key" } } created = requests.post(f"{BASE_URL}/api/swarms", headers=headers, json=payload) created.raise_for_status() run = created.json() swarm_id = run["swarm_id"] status = requests.get(f"{BASE_URL}/api/swarms/{swarm_id}/status", headers=headers) status.raise_for_status() print(status.json()["status"]) timeline = requests.get( f"{BASE_URL}/api/agent/user/deployments/{run['deployment_id']}/timeline", headers={"Authorization": f"Bearer {TOKEN}"} ) timeline.raise_for_status() print(len(timeline.json()["timeline"])) ``` --- ## 6. 错误处理 ### 6.1 错误响应格式 所有错误响应遵循统一格式: ```json { "success": false, "error": { "code": "ERROR_CODE", "message": "Human-readable error message", "request_id": "req_xyz789" } } ``` ### 6.2 错误码列表 | HTTP 状态码 | 错误码 | 说明 | |------------|--------|------| | 401 | `UNAUTHORIZED` | 认证失败,Token 无效 | | 403 | `FORBIDDEN` | 权限不足 | | 404 | `DEPLOYMENT_NOT_FOUND` | 部署不存在 | | 409 | `DEPLOYMENT_CONFLICT` | 部署状态冲突 | | 422 | `MODEL_NOT_ALLOWED` | 模型不在允许列表中 | | 422 | `POLICY_REJECTED` | 策略拒绝(如高风险需审批) | | 422 | `SUB_MODE_UNSUPPORTED` | `sub_mode` 不是 `agile` 或 `waterfall` | | 422 | `SECRET_REF_INVALID` | `secret_ref` 不是 `azkv:///secrets/` 格式 | | 422 | `RESOURCE_GRANT_INVALID` | Resource Grant 缺少资源类型、权限范围或 `secret_ref` | | 422 | `CALLBACK_URL_INVALID` | callback URL 非 HTTPS 或路径不符合约定 | | 422 | `ARTIFACT_METADATA_REJECTED` | artifact metadata 含疑似明文密钥 | | 422 | `SK_SNAPSHOT_INVALID` | SK snapshot 缺少 source/hash/invocation 关联字段 | | 422 | `VALIDATION_ERROR` | 请求参数验证失败 | | 429 | `RATE_LIMITED` | 请求过载或 callback 接收端限流 | | 500 | `INTERNAL_ERROR` | 服务器内部错误 | ### 6.3 错误处理示例 ```python try: response = requests.post( f"{BASE_URL}/api/agent/sub-agile/deployments", headers=headers, json=create_payload ) response.raise_for_status() deployment = response.json() except requests.exceptions.HTTPError as e: error_data = e.response.json() error_code = error_data["error"]["code"] error_message = error_data["error"]["message"] if error_code == "MODEL_NOT_ALLOWED": print(f"❌ 模型配置错误: {error_message}") elif error_code == "POLICY_REJECTED": print(f"❌ 需要审批: {error_message}") else: print(f"❌ 请求失败: {error_message}") ``` --- ## 7. 最佳实践 ### 7.1 认证和安全 ✅ **推荐做法**: - 将 Service Token 存储在环境变量或密钥管理系统中 - 使用 HTTPS 进行所有 API 调用 - 定期轮换 Service Token - 使用 Azure Key Vault 存储敏感配置,并只在请求中传递 `azkv://...` 引用 ❌ **避免**: - 在代码中硬编码 Token - 在日志中打印 Token - 在 URL 参数中传递敏感信息 - 在 callback、artifact metadata、timeline 或 SK snapshot 中写入明文密钥 ### 7.2 幂等性 ✅ **推荐做法**: - 对所有创建操作使用 `X-Idempotency-Key` - 使用 UUID 或时间戳生成唯一的幂等性键 - 在网络不稳定时重试请求 ### 7.3 预算控制 ✅ **推荐做法**: - 设置合理的 `max_usd` 预算上限 - 设置 `alert_threshold_pct` 为 80-90% - 定期检查 `consumed_usd` 和 `remaining_usd` - 在预算告警时及时停止部署 ### 7.4 日志和监控 ✅ **推荐做法**: - 使用 `X-Correlation-ID` 追踪请求链路 - 定期轮询 `/logs` 和 `/events` 端点 - 监控 `/metrics` 端点的资源使用情况 - 保存审计日志用于问题排查 ### 7.5 错误处理 ✅ **推荐做法**: - 实现指数退避重试机制 - 区分可重试错误(5xx)和不可重试错误(4xx) - 记录完整的错误上下文(request_id, correlation_id) - 为高风险操作准备回滚方案 ### 7.6 性能优化 ✅ **推荐做法**: - 使用分页参数避免一次性获取大量数据 - 缓存不常变化的数据(如模板列表) - 使用 `since` 参数增量获取日志和事件 - 并发调用独立的 API 端点 --- ## 8. 附录 ### 8.1 支持的 Agent 镜像 | Agent 类型 | 镜像地址 | 说明 | |-----------|---------|------| | Search Agent | `agnettaiji.azurecr.io/ai-agents/search-agent:v1.2.0` | 搜索和信息检索 | | Doc Creator | `agnettaiji.azurecr.io/ai-agents/doc-creator:v1.2.0` | 文档生成 | | Code AI Agent | `agnettaiji.azurecr.io/ai-agents/code-ai-agent:v1.2.0` | 代码生成和 CI/CD | | Ad Creator | `agnettaiji.azurecr.io/ai-agents/ad-creator:v1.2.0` | 广告创意生成 | | Video Generator | `agnettaiji.azurecr.io/ai-agents/video-generator:v1.2.0` | 视频生成 | ### 8.2 联系方式 - **技术支持**: support@taijiagnet.com - **API 文档**: https://agent-manager.taijiagnet.com/docs - **问题反馈**: https://github.com/your-org/agent-manager/issues ### 8.3 更新日志 | 版本 | 日期 | 更新内容 | |------|------|----------| | v2.1.11 | 2026-06-04 | 补充模板 Agent `/agents` 生命周期兼容文档:新增 `GET /agents/{id}`、`POST /agents/{id}/stop`、`DELETE /agents/{id}`、`GET /agents/{id}/status` 的联调说明;同步说明 `POST /agents` 额外返回 `runtime_id` / `agent_id` / `id` / `runtime_status` / `state` / `subdomain`,并记录删除接口 500 bug 已修复 | | v2.1.10 | 2026-05-30 | 文档补充生产环境产物获取路径:先查 artifact 列表,再用用户态 content 代理接口下载完整内容;明确 `azblob://` / `runtime://` 存储规则、Blob Secret 配置和排障提示 | | v2.1.9 | 2026-05-29 | Runtime artifact store 支持从 K8s Secret 读取 Azure Blob 凭据并上传完整产物,上传成功返回 `azblob://...` URI;内容读取接口支持 Runtime-local 与 AzBlob 两种来源 | | v2.1.8 | 2026-05-29 | 新增 Runtime-local artifact store:完整 agent 产物落盘保存,`artifact.created` 只回传摘要、URI、大小和 `content_hash`;新增 `/api/swarms/{id}/artifacts/{artifact_id}/content` 与用户态 artifact content 读取接口 | | v2.1.7 | 2026-05-29 | 修复普通 sub terminal run 空产物兜底:执行成功但无产物会生成 summary artifact,执行失败/blocked 会生成 failure artifact,历史空产物 run 的 `/api/swarms/{id}`、`events`、`metrics` 查询会合成可展示 artifact;部署镜像更新为 `heicode-v2-20260529232620` | | v2.1.6 | 2026-05-29 | 修复普通 sub 真实执行后缺失 `artifact.created` 的问题,新增 `task.completed` / `task.failed` / `task.blocked` 事件,修复 deployment 与 agents 终态不一致,`/api/swarms/{id}/logs` 改为返回 Runtime 聚合摘要;部署镜像更新为 `heicode-v2-20260529120632` | | v2.1.5 | 2026-05-28 | 文档修订:新增 v2.1.4 联调速查,补充 `/api/swarms` 最小请求、校验失败、状态响应和普通 sub 联调示例;修正 callback 当前实现为失败只记录 warning,重试/死信/replay 为后续增强 | | v2.1.4 | 2026-05-28 | 按普通 sub 联调整改要求补齐 `/api/swarms` 参数校验、`dry_run` 拒绝、`deployment_id` 返回、detail 根路径、幂等创建和 usage/cost callback 字段;当前联调 Base URL 明确为 `http://20.212.121.126`,部署镜像更新为 `heicode-v2-20260528164612` | | v2.1.3 | 2026-05-28 | 按普通 sub 敏捷模式任务清单补齐 `/api/agent/sub-agile/deployments` 主动回调、`role_template` 兼容、callback schema、`/api/swarms/{id}` stop/status/logs/events/metrics、approval decision 接收路径,部署镜像更新为 `heicode-v2-20260528161931` | | v2.1.2 | 2026-05-28 | Agent Manager Runtime 支持按 callback 配置主动推送 status/phase/timeline/agent/tool/artifact 事件,补充发送端签名密钥解析顺序和失败策略,部署镜像更新为 `heicode-v2-20260528144233` | | v2.1.1 | 2026-05-27 | 同步 Manager 当前实现状态:callback HMAC/旧 token 兼容、payload 投影、默认 subscribed_events、artifact/timeline/SK snapshot 查询示例、部署镜像版本 | | v2.1.0 | 2026-05-26 | 补充 Heicode sub 模式敏捷开发契约、`/api/swarms` 兼容入口、`azkv://` secret_ref、artifact/timeline/SK snapshot 模型 | | v2.0.0 | 2026-05-12 | 初始版本,支持 Heicode 集成 | --- **文档版本**: v2.1.11 **最后更新**: 2026-06-04 **维护者**: Agent Manager Team