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>
7.6 KiB
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 对齐):
{
"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 留空,客户端用 A2Aapi_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 补进客户端文档。