Files
heicode/docs/integration/heicode-am-contract.md
T
chenchenandClaude Opus 4.8 27459bb476 fix(agent): align AM lifecycle paths to /agents/{id} (real-test: create works)
Real production test (user account) confirmed HM->AM POST /agents creates a real
agent (returned subdomain + status). But stop/delete still used the old
/api/agent/agents/{id} defaults and 404'd. Aligned status/stop/delete defaults to
the same namespace as create: /agents/{id}, /agents/{id}/stop. AM contract doc
notes these are HM's best guess pending AM's confirmation of the real lifecycle
endpoints (their doc only specified create).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:41:34 +08:00

137 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HM ↔ AM 接口契约(模板 Agent 模型)— 给 agent_management 团队
> 更新时间:2026-06-04
> 角色:**HM** = Heicode Manager(网关/控制面/模型网关)。**AM** = agent_management(云端 agent 运行时,你们)。
> 现状:HM 侧已全部实现并生产验证;**等 AM 实现本文 4 个接口 + agent 直连端**,整条链路即打通。HM 调 AM 的代码全部隔离在 `heicode/controller/agent_template_runtime.go`,字段/路径可按本文对齐;路径都支持环境变量覆盖(见末尾)。
---
## 0. 模型一句话
用户在 HM 网页台选「资源 + agent 模板」部署 → **HM 把 agent 定义(.md)+ 解好的资源 env 交给 AM 启动** → AM 起一个**常驻 agent**、分配**唯一子域名 + 访问 token** 返回 → 桌面客户端从 HM 拿到地址+token 后**直连 agent(SSE)对话**。HM 不在对话回路;agent 用模型走 HM `/v1/*`。
---
## 1. AM 需要提供的 4 个接口
HM 用 `Authorization: Bearer <service_token>` 调 AM。统一响应信封建议 `{ "success": true, "data": {...} }`(HM 会从 `data` 取值;失败给 `{ "success": false, "message": "..." }`)。
### 1.1 启动 agent(核心,已对齐你们的 `POST /agents`)
`POST {AM}/agents`
**请求体(HM 实际发送的,已按你们 CODING_A2A §2 对齐):**
```json
{
"name": "dep-b5fab27e9255", // 由 HM 部署 id 派生(DNS 安全)
"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<Agent_Prompt>...</Agent_Prompt>",
"OPENAI_BASE_URL": "https://code.xinghanlab.com/v1",
"MODEL_NAME": "gpt-5.4",
"GIT_PROVIDER": "github", "GIT_REPO_URL": "...", "GIT_TOKEN": "…",
"MYSQL_HOST": "...", "MYSQL_PASSWORD": "…"
}
}
```
**响应(HM 解析你们返回的字段):**
- `runtime_id` ← `runtime_id`/`agent_id`/`id`/`name`/`namespace`(取到的实例标识,用于 status/stop/delete)。
- `subdomain` ← `subdomain` 或 `access_info.domain` / `access_info.external_ip`(agent 直连地址)。
- `access_token` ← `access_token`/`token`(你们当前不返回 → HM 留空,客户端用 A2A `api_key`,见 §3)。
- `status` ← `status`/`runtime_status`(取不到默认 `running`)。
**AM 启动时做的(你们已实现):**用 `env.AGENT_INSTRUCTION_TEXT`+`AGENT_ROLE_NAME` 设角色;注入 env;agent 用模型走 `OPENAI_BASE_URL`(=HM `/v1`)。
> ⚠️ provisioning 同步:HM 超时默认 60s(`AGENT_RUNTIME_START_TIMEOUT_SECONDS`)。
> ⚠️ **下面 1.2–1.4 的路径是 HM 的推测**(你们文档只写了创建 + agent 自身 /health + A2A 调用,没写 agent-manager 的生命周期接口)。**实测:创建 `POST /agents` ✅ 通,但 stop/delete 用 `/api/agent/agents/{id}/...` 返回 404。** HM 已把默认改成与创建同命名空间的 `/agents/{id}`。**请 AM 确认真实的 状态/停止/删除 端点(方法 + 路径 + 用哪个 id),不一致我们改 env 覆盖即可。**
### 1.2 取 agent 状态
`GET {AM}/agents/{runtime_id}` → `data: { "status": "running" }`(HM 接受 `status`/`runtime_status`/`state`)。
### 1.3 停止 agent
`POST {AM}/agents/{runtime_id}/stop` → 2xx 即可。
### 1.4 删除 agent
`DELETE {AM}/agents/{runtime_id}` → 2xx 即可。
> `runtime_id` = HM 从创建响应取到的实例标识(优先 `runtime_id`/`agent_id`/`id`/`name`/`namespace`)。实测创建时 HM 发的 `name="dep-xxxx"`,若你们生命周期用别的 id,请在响应里明确返回 `runtime_id`。
---
## 2. env 命名约定(HM↔AM 必须一致,agent 模板按此读)
HM 把用户绑定的资源按**资源类型 + provider**解成固定 env 名(代码 `controller/agent_template_env.go`)。**AM 的 agent 模板按这些名字读 env**;用户在 HM 只填业务字段、看不到 env 名。
> **2026-06-04 已对齐 AM 的 `coding_a2a_agent`**:env 名按你们文档实现。当前**只支持 AM 已支持的 4 类**(git / mysql / postgres / azure blob);vm / redis / mongo / 对象桶等 HM 暂不下发,待 AM 支持再加。
| 资源类型 | provider | 注入的 env(非密 + 密钥) |
|---|---|---|
| git | github / gitea / gitlab | `GIT_PROVIDER` `GIT_REPO_URL` `GIT_DEFAULT_BRANCH` · `GIT_TOKEN`(密) |
| database | mysql | `MYSQL_HOST` `MYSQL_PORT` `MYSQL_DATABASE` `MYSQL_USER` · `MYSQL_PASSWORD`(密) |
| database | postgres | `POSTGRES_HOST` `POSTGRES_PORT` `POSTGRES_DATABASE` `POSTGRES_USER` · `POSTGRES_PASSWORD`(密) |
| storage | azure blob | `AZURE_BLOB_ACCOUNT_NAME` `AZURE_BLOB_CONTAINER` · `AZURE_BLOB_ACCOUNT_KEY`(密) |
另外随启动注入(模型网关):`OPENAI_BASE_URL`(= HM `/v1`)、`MODEL_NAME`。**`OPENAI_API_KEY` 不在启动时注入** —— 由客户端在 A2A 请求里带 `api_key`(你们文档 §7);后续若走 V2 解密路径再调整。
- 缺失的可选字段不会出现在 env 里(agent 自行容错)。
- 同类型资源 HM 限制只挂一个(避免 env 名冲突)。
- 角色/指令注入:HM 把模板 .md 放进 `env.AGENT_INSTRUCTION_TEXT`、模板 key 放进 `env.AGENT_ROLE_NAME`(对齐你们 §4)。
---
## 3. 客户端 ↔ agent 直连(AM 的 agent 端要定义)
- 客户端从 HM 拿到 `subdomain + access_token`,**直连 agent 子域名、SSE 双向通信**。HM 不在回路。
- **agent 端必须校验 access_token**(请求头携带);token 错/缺则拒绝(防公网裸奔)。
- **请由 AM 定义并回复 HM:** SSE 握手方式、token 放哪个请求头、消息/事件格式。HM 会把这段补进客户端文档 `heicode-desktop-client-api.md` §6。
---
## 4. 安全要求
- `env` 里**含明文密钥**(vm/db 密码、blob key、git token)。**AM 的启动接口必须 HTTPS 或私网**;HM 检测到明文密钥发往非 HTTPS AM 会打告警。
- **agent 绝不能把 `.env`/密钥回显**到对话、日志、或提交进 git——由 AM 保证。
- 生产密钥**只到 agent 运行环境**,不要再外传。
---
## 5. 回调(可选,lifecycle)
HM 提供 `POST /api/agent/callbacks/runtime-events`(HMAC 签名,`callback_url` 已随启动下发)。AM 可上报 agent 生命周期(started/stopped/unhealthy)。**当前 HM 主要用主动拉取(§1.2)判状态,回调非必须**;若 AM 走回调推送,与我们对齐事件格式即可。
---
## 6. 路径覆盖(联调期改路径无需改 HM 代码)
HM 这些路径都可用环境变量覆盖(默认值见 §1),AM 若用别的路径,运维改 env 即可:
| env | 默认 | 用途 |
|---|---|---|
| `AGENT_RUNTIME_BASE_URL` | — | AM 基址(必须配,HTTPS/私网) |
| `AGENT_RUNTIME_SERVICE_TOKEN` | — | HM 调 AM 的 Bearer |
| `AGENT_RUNTIME_AGENT_START_PATH` | `/agents` | 启动(你们的 create) |
| `AGENT_RUNTIME_AGENT_PATH` | `/api/agent/agents/{agent_id}` | 取状态(GET)/删除(DELETE) |
| `AGENT_RUNTIME_AGENT_STOP_PATH` | `/api/agent/agents/{agent_id}/stop` | 停止 |
| `AGENT_RUNTIME_START_TIMEOUT_SECONDS` | `60` | 启动超时 |
> 字段名若需调整(如 `subdomain`→别的),只改 `heicode/controller/agent_template_runtime.go` 中 `amStartTemplateAgent`/`amGetAgentStatus` 的解析键一处即可,其余 HM 代码不动。
---
## 7. 联调自检清单
- [ ] `POST /agents/start` 收到 `agent_definition`+`env`+`callback_url`,起 agent、注入 env、返回 `{runtime_id, subdomain, access_token, status}`。
- [ ] agent 用模型打到 HM `/v1/*`(带用户身份),计费正常。
- [ ] agent 子域名校验 access_token;非法连接被拒。
- [ ] `GET /agents/{id}` 返回真实 status;`stop`/`delete` 生效。
- [ ] agent 不泄露 env/密钥;启动接口 HTTPS/私网。
- [ ] 把 §3 的 SSE 直连契约回给 HM 补进客户端文档。