125 lines
7.6 KiB
Markdown
125 lines
7.6 KiB
Markdown
---
|
||
name: gateway-task
|
||
description: 向 A2A 智能网关(gateway)提交任务、订阅完成事件、查询状态、取消任务的 API 使用指南。当用户(CLI/模型对话场景)要求"提交任务"、"发任务"、"上报任务"、"查询任务状态/结果"、"取消任务"、"给网关下发任务",或需要 Agent 注册/心跳/回传结果时使用本技能。
|
||
---
|
||
|
||
# Gateway Task
|
||
|
||
## Overview
|
||
|
||
A2A 智能网关通过 REST API 接收 CLI 提交的任务、让 Agent 注册并领取任务,并持久化任务状态供随时查询。本技能提供任务从提交到拿到结果的**完整流程接口用法**,覆盖 **SSE 事件订阅(推荐,免轮询)** 与 **轮询查询(兜底)** 两种取结果方式,保证请求体格式、认证字段与 `cli_session_id` 用法、中文编码处理正确。
|
||
|
||
### 关键实践经验(务必遵守)
|
||
|
||
- **中文 payload 必须用 UTF-8 文件 + `--data-binary @file` 提交**。在 Windows PowerShell 下若直接用 `curl -d '{"prompt":"中文"}'` 或 `Invoke-WebRequest` 传中文,会被转成 `?` 乱码,agent 收到损坏的指令。正确做法见 `references/api_reference.md` 的"中文编码"小节。
|
||
- **先订阅 SSE 再提交任务**,且 `cli_session_id` 必须一致,即可免轮询拿到结果。
|
||
- **任务卡在 `pending` 且 `error_info` 提示"无可用 Agent"时**,先查 Agent 状态(`GET /api/admin/agents`,用 `X-Admin-Auth: <ADMIN_AUTH>`),确认标签是否匹配、状态是否为 `ready`/`processing`、是否满载(`current_load < max_concurrent`)。Agent 处于 `stopping`/`unavailable`/`offline` 或满载时都不会被分配。
|
||
- **成功任务的 `result` 结构**:`{"reply": "Agent接受任务后的首条回复", "output": "Agent执行的最终总结"}`。前端据此展示"Agent 接受任务回复"和"Agent 总结"。
|
||
|
||
## 前置条件
|
||
|
||
- 网关 Base URL:`http://localhost:8000`(生产环境以实际地址为准)。
|
||
- 认证 `GATEWAY_AUTH`:读取网关 `.env` 中的 `GATEWAY_AUTH` 值(未配置时默认 `dev-gateway-auth`)。
|
||
- **认证传递方式不同**:
|
||
- **POST 写入型接口**(提交任务、Agent 注册/心跳/结果/注销):`auth` 放在**请求体 JSON** 中。
|
||
- **GET 查询、SSE 订阅、取消**:`auth` 作为 **query 参数**(`?auth=<GATEWAY_AUTH>`)。
|
||
- 缺失或错误返回 `401`;字段缺失返回 `422`。
|
||
- **任务要能被分配,`task_tags` 必须与某个已注册 Agent 的 `agent_tags` 至少有一个交集**,且该 Agent 状态为 `ready`/`processing` 且未满载,否则任务会一直卡在 `pending`(`error_info` 提示"无可用 Agent")。
|
||
|
||
## 提交任务携带 `cli_session_id`(关键)
|
||
|
||
- 若希望通过 **SSE 免轮询**拿到任务完成结果,**提交任务时必须传 `cli_session_id`**(自定义会话标识,如 `cli-123`)。
|
||
- 网关仅在任务到达终态时,向该 `cli_session_id` 对应的 SSE 通道推送 `task_done` 事件;**未传 `cli_session_id` 时网关不会推送**,只能靠轮询查询。
|
||
- 因此推荐流程:**先订阅 SSE → 再提交任务(带 `cli_session_id`)→ 从事件流中收结果**。
|
||
|
||
## 任务提交流程(Workflow)
|
||
|
||
### 推荐流程(SSE 免轮询)
|
||
|
||
1. **订阅完成事件**:`GET /api/cli/events?cli_session_id=<sid>&auth=<AUTH>` 建立 SSE 长连接。
|
||
- 连接建立后先**回放**该会话已完成的 `task_done` 事件(连接晚于任务完成也不丢),再实时接收新事件。
|
||
- 事件帧格式:`data: {"event": "task_done", "request_id": "...", "status": "...", "result": ..., "error_info": ...}`。
|
||
2. **提交任务**:`POST /api/cli/tasks`,请求体**必须带与上面相同的 `cli_session_id`**。
|
||
3. **收结果**:从 SSE 事件流中收到该 `request_id` 的 `task_done` 事件即完成,无需轮询。
|
||
|
||
### 兜底流程(轮询)
|
||
|
||
提交任务后 `GET /api/cli/tasks/{request_id}?auth=<AUTH>` 每 2~5 秒轮询,直到 `success` / `failed`。
|
||
|
||
### 1. 提交任务
|
||
|
||
`POST /api/cli/tasks`
|
||
|
||
请求体字段:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `auth` | string | 是 | 网关认证密码(body 内) |
|
||
| `task_type` | string | 是 | 任务类型,如 `compile` / `build` / `test` / `generate` |
|
||
| `task_tags` | list[str] | 否 | 能力标签,**必须与某 Agent 的 `agent_tags` 有交集**才可被调度 |
|
||
| `payload` | dict | 否 | 任务载荷(`prompt` / `cmd` 等) |
|
||
| `request_id` | string | 否 | 幂等键,不传自动生成 |
|
||
| `cli_session_id` | string | 否 | **若要 SSE 免轮询必须传**,且与订阅用的 session 一致 |
|
||
| `timeout` | int | 否 | 超时秒数,0 使用默认值 |
|
||
|
||
响应返回 `TaskInfo`(含 `request_id`、`status`)。**务必从响应中记录 `request_id`,后续查询/取消都依赖它。**
|
||
|
||
curl 示例见 `references/api_reference.md`。
|
||
|
||
### 2. 订阅任务完成事件(SSE,推荐)
|
||
|
||
`GET /api/cli/events?cli_session_id=<sid>&auth=<AUTH>`
|
||
|
||
- 长连接,任务到达终态时网关主动推送 `task_done`,**无需轮询**。
|
||
- 支持回放:连接晚于任务完成也能先收到历史事件。
|
||
- 事件字段:`event`、`request_id`、`status`、`result`、`error_info`。
|
||
|
||
### 3. 查询任务状态(兜底)
|
||
|
||
`GET /api/cli/tasks/{request_id}?auth=<AUTH>`
|
||
|
||
任务不存在返回 `404`。`status` 为 `pending` / `running` / `success` / `failed`;`success` 后结果在 `result` 字段,`failed` 时原因在 `error_info`。
|
||
|
||
**`result` 结构(成功任务):**
|
||
|
||
```json
|
||
{
|
||
"reply": "我先查看工作目录环境,然后创建文件。",
|
||
"output": "生成的文件路径:.../cool_clock.html(18026 字节)..."
|
||
}
|
||
```
|
||
|
||
- `reply`:Agent **接受任务后的首条回复**(前端"Agent 接受任务回复")。
|
||
- `output`:Agent **执行完的最终总结**(前端"Agent 总结")。
|
||
- 失败/取消/超时任务的 `result` 为 `null`,此时看 `error_info` 判断原因。
|
||
|
||
### 排查"任务卡在 pending / 无可用 Agent"
|
||
|
||
任务一直 `pending` 且 `error_info` 含"无可用 Agent"时,按序排查:
|
||
|
||
1. 查 Agent 列表:`GET /api/admin/agents`(Header `X-Admin-Auth: <ADMIN_AUTH>`,认证书见网关 `.env` 的 `ADMIN_AUTH`)。
|
||
2. 关注三件事:
|
||
- **标签匹配**:任务的 `task_tags` 与 Agent 的 `agent_tags` 是否有交集;
|
||
- **状态可用**:Agent 须为 `ready` 或 `processing`;`stopping`/`unavailable`/`offline` 不参与调度;
|
||
- **未满载**:`current_load < max_concurrent`(`max_concurrent=1` 时任何遗留负载都会导致不再分配)。
|
||
3. 若 Agent 状态为 `stopping`/异常,可尝试 `POST /api/admin/agents/{id}/available` 置为可用(部分场景心跳会自动恢复)。
|
||
4. 若 Agent 负载计数异常(完成的任务未释放负载),检查是否有 `running` 但实际已超时的任务残留,必要时取消以释放负载。
|
||
|
||
### 4. 取消任务
|
||
|
||
`POST /api/cli/tasks/{request_id}/cancel?auth=<AUTH>`
|
||
|
||
仅 `pending` / `running` 可取消,已结束任务返回 `400`。成功返回 `{"ok": true, "request_id": "..."}`。
|
||
|
||
## Agent 协议
|
||
|
||
Agent 是任务的执行方,接入网关同样需要认证(`auth` 在请求体 JSON 中):
|
||
|
||
- `POST /api/agent/register`:启动注册,请求体含 `auth`、`agent_id`、`endpoint`、`agent_tags`、`max_concurrent`。
|
||
- `POST /api/agent/heartbeat`:约每 10 秒心跳。
|
||
- `POST /api/agent/result`:任务完成回传 `request_id` + `agent_id` + `status` + `result`。
|
||
- `POST /api/agent/unregister`:优雅注销。
|
||
|
||
## 完整示例与典型对话引导
|
||
|
||
在 `references/api_reference.md` 中查看带真实参数的 curl 示例、`TaskInfo` 完整响应结构、SSE 订阅示例,以及典型对话引导(先取 `GATEWAY_AUTH`,再订阅 SSE,再提交任务,从事件流收结果)。 |