--- 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: `),确认标签是否匹配、状态是否为 `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=`)。 - 缺失或错误返回 `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=&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=` 每 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=&auth=` - 长连接,任务到达终态时网关主动推送 `task_done`,**无需轮询**。 - 支持回放:连接晚于任务完成也能先收到历史事件。 - 事件字段:`event`、`request_id`、`status`、`result`、`error_info`。 ### 3. 查询任务状态(兜底) `GET /api/cli/tasks/{request_id}?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: `,认证书见网关 `.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=` 仅 `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,再提交任务,从事件流收结果)。