# Agent API Endpoints 本文档以当前后端实现为准,描述 `/api/v1/agent` 的 HTTP 接口契约。 Base URL: `/api/v1/agent` --- ## 端点清单 | 方法 | 路径 | 说明 | |---|---|---| | POST | `/runs` | 创建一次 agent run(异步入队) | | POST | `/runs/{thread_id}/cancel` | 请求取消指定 run | | GET | `/runs/{thread_id}/events` | 订阅 SSE 事件流 | | GET | `/history` | 获取历史快照(按天分页) | | POST | `/attachments` | 上传用户图片附件 | | GET | `/attachments/signed-url` | 获取附件临时签名链接 | | POST | `/transcribe` | WAV 音频转写 | --- ## 1) POST `/runs` 发起一次运行请求,后端会先持久化用户消息,再将命令放入异步队列。 ### Request - Body: `RunAgentInput` - 详细结构见 `docs/protocols/agent/run-agent-input.md` - `forwardedProps.runtime_mode` 必填,值为 `"chat"` 或 `"automation"` ### Response `202 Accepted` ```ts { taskId: string; threadId: string; runId: string; created: boolean; // 是否新建了会话 } ``` ### 错误码 - `401` 未认证 - `422` 请求结构校验失败 --- ## 2) GET `/runs/{thread_id}/events` 订阅指定 thread 的实时事件流(按 `runId` 隔离当前 run)。 ### Path | 参数 | 类型 | 说明 | |---|---|---| | `thread_id` | string | 会话 ID | ### Query | 参数 | 类型 | 默认 | 说明 | |---|---|---|---| | `runId` | string | - | 目标 run ID(必填)。SSE 仅输出该 run 事件 | | `idle_limit` | integer | `300` | 最大空闲轮询次数(1-3600) | ### Headers | Header | 必填 | 说明 | |---|---|---| | `Accept: text/event-stream` | 否 | 建议显式设置 | | `Last-Event-ID` | 否 | 从指定游标断点续流 | ### Response - `200 OK` - `Content-Type: text/event-stream` - 事件类型与字段见 `docs/protocols/agent/sse-events.md` - usage 审计与成本回退策略见 `docs/protocols/agent/sse-events.md`(5) Usage 审计协议) - 空闲时会发送 keep-alive 注释行 `: keep-alive` run 过滤语义: - 服务端会读取 thread 的事件流游标,但仅向客户端发送 `event.runId == query.runId` 的事件。 - SSE 连接终止条件为“目标 run 收到 `RUN_FINISHED` 或 `RUN_ERROR`”,其他 run 的 terminal 事件不会终止当前连接。 当前阶段执行说明: - `chat` 模式采用两阶段:`router` -> `worker`。 - `automation` 模式由后端业务逻辑决定具体 Agent 类型。 - 因此阶段事件可能出现 `router` / `worker`。 ### 错误码 - `401` 未认证 - `403` 非会话所有者 - `422` `runId` 非法 - `422` `Last-Event-ID` 非法 - `429` 超过 SSE 连接数限制 --- ## 3) POST `/runs/{thread_id}/cancel` 请求取消指定 run。该接口返回 `202` 仅表示取消请求已被后端接收,不保证运行已在同一时刻停止。 ### Path | 参数 | 类型 | 说明 | |---|---|---| | `thread_id` | string | 会话 ID | ### Query | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `runId` | string | 是 | 需要取消的 run ID | ### Response `202 Accepted` ```ts { threadId: string; runId: string; accepted: true; } ``` ### 错误码 - `401` 未认证 - `403` 非会话所有者 - `422` 参数非法 --- ## 4) GET `/history` 返回历史快照(`HistorySnapshotResponse`),不是 SSE 包装事件。 ### Query | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `threadId` | string | 否 | 指定会话,不传则取当前用户最近会话 | | `before` | `YYYY-MM-DD` | 否 | 返回该日期之前最近一天的快照 | ### Response ```ts { scope: "history_day"; threadId: string | null; day: string | null; // YYYY-MM-DD hasMore: boolean; messages: Array<{ id: string; seq: number; role: "user" | "assistant" | "tool"; content: string; suggestedActions?: string[]; attachments?: Array<{ // user 附件签名链接列表 mimeType: string; url: string; }>; ui_schema?: object | null; // tool 的编译后 UI timestamp: string; // ISO-8601 }>; } ``` `/history` 会返回 tool 消息用于 UI 重建。tool 消息的 `ui_schema` 来自 `metadata.tool_agent_output.ui_hints` 的编译结果。 `messages[].content` 在当前协议中始终是字符串: - assistant: answer 文本 - tool: tool result 的 JSON 文本投影 - user: 用户输入文本 结构化字段(如 tool result/ui hints、suggested actions)通过 metadata 派生,不要求把 `content` 升级为 JSON 对象。 可见性说明: - `/history` 仅返回命中 `ui.history` 可见位的消息。 - 内部消息(例如 memory 私有输入)可落库但不会出现在 `/history`。 ### 说明 - 若用户没有任何会话:返回 - `threadId = null` - `day = null` - `hasMore = false` - `messages = []` --- ## 5) POST `/attachments` 上传图片附件,返回可直接用于 `RunAgentInput.messages[].content[].url` 的签名链接。 ### Request - `multipart/form-data` | 字段 | 类型 | 说明 | |---|---|---| | `threadId` | string | 会话 ID | | `file` | file | 附件文件 | ### Response ```ts { attachment: { bucket: string; path: string; mimeType: string; url: string; }; } ``` ### 错误码 - `401` 未认证 - `403` 非会话所有者 - `413` 附件超过大小限制 - `422` 文件类型不支持/空文件等 - `503` 存储服务不可用 --- ## 6) GET `/attachments/signed-url` 对已有存储对象重新签名。 ### Query | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `bucket` | string | 是 | 存储桶 | | `path` | string | 是 | 对象路径 | ### Response ```ts { bucket: string; path: string; url: string; } ``` --- ## 7) POST `/transcribe` WAV 音频转写。 ### Request - `multipart/form-data` | 字段 | 类型 | 说明 | |---|---|---| | `audio` | file | WAV 文件 | ### Response ```ts { transcript: string; } ``` ### 限制 - 内容类型:`audio/wav` / `audio/x-wav` / `audio/wave` - 文件大小:最大 10MB --- ## 错误约定(Agent) Agent 路由的错误同样遵循统一 HTTP 错误契约,详见: - `docs/protocols/common/http-error-codes.md` 本文件只补充 Agent 相关错误码示例: - `AGENT_RUN_INPUT_INVALID` - `AGENT_RUN_MESSAGES_INVALID` - `AGENT_INVALID_RUN_ID` - `AGENT_INVALID_LAST_EVENT_ID` - `AGENT_SSE_CONNECTION_LIMIT` - `AGENT_ATTACHMENT_EMPTY` - `AGENT_ATTACHMENT_TOO_LARGE` - `AGENT_AUDIO_UNSUPPORTED_FORMAT` - `AGENT_AUDIO_TOO_LARGE` - `AGENT_AUDIO_EMPTY` - `AGENT_ASR_UNAVAILABLE`