feat: 实现 AgentScope ReAct Runner 两阶段执行并重构事件处理

This commit is contained in:
zl-q
2026-03-16 09:01:01 +08:00
parent 072c09d99d
commit dcceb48d84
51 changed files with 5015 additions and 5663 deletions
+360
View File
@@ -0,0 +1,360 @@
# Agent API Endpoints
本文档列出所有 Agent 相关的 API 端点。
Base URL: `/api/v1/agent`
---
## 端点清单
| 方法 | 路径 | 描述 |
|------|------|------|
| POST | `/runs` | 发起 Agent 运行 |
| GET | `/runs/{thread_id}/events` | SSE 事件流 |
| GET | `/history` | 获取对话历史快照 |
| POST | `/attachments` | 上传附件 |
| GET | `/attachments/signed-url` | 生成附件签名 URL |
| POST | `/transcribe` | 语音转文字 (ASR) |
---
## 1. POST /runs
发起一个 Agent 运行任务。
### Request
Request Body: `RunAgentInput`
详细数据结构见 [run-agent-input.md](./run-agent-input.md)
### Response
```typescript
{
taskId: string, // 任务 ID
threadId: string, // 会话 ID
runId: string, // 运行 ID
created: string // ISO-8601 时间戳
}
```
### Example
```bash
curl -X POST https://api.example.com/api/v1/agent/runs \
-H "Content-Type: application/json" \
-d '{
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"runId": "run-001",
"state": {},
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "帮我查一下北京今天的天气"
}
],
"tools": [],
"context": [],
"forwardedProps": {}
}'
```
### Response Example
```json
{
"taskId": "task-abc123",
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"runId": "run-001",
"created": "2026-03-16T10:00:00Z"
}
```
---
## 2. GET /runs/{thread_id}/events
获取 SSE 事件流,用于实时接收 Agent 运行过程中的事件。
### Path Parameters
| 参数 | 类型 | 描述 |
|------|------|------|
| thread_id | string | 会话 ID |
### Query Parameters
| 参数 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| Last-Event-ID | string | - | 可选,用于断点续传的事件 ID |
| idle_limit | integer | 300 | 最大空闲轮询次数 (1-3600) |
### Headers
| 参数 | 描述 |
|------|------|
| Last-Event-ID | 可选的事件 ID,用于从指定位置恢复 |
### Response
SSE (Server-Sent Events) 流,Content-Type: `text/event-stream`
事件类型详情见 [sse-events.md](./sse-events.md)
### Example
```javascript
const eventSource = new EventSource(
'https://api.example.com/api/v1/agent/runs/550e8400-e29b-41d4-a716-446655440000/events'
);
eventSource.addEventListener('run.started', (e) => {
const data = JSON.parse(e.data);
console.log('Started:', data);
});
eventSource.addEventListener('text.delta', (e) => {
const data = JSON.parse(e.data);
console.log('Delta:', data.data.delta);
});
eventSource.addEventListener('run.finished', (e) => {
const data = JSON.parse(e.data);
console.log('Finished:', data);
});
```
---
## 3. GET /history
获取对话历史快照。
### Query Parameters
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| threadId | string | 否 | 会话 ID,不指定则返回最新会话 |
| before | date | 否 | 日期格式 `YYYY-MM-DD`,返回该日期之前的快照 |
### Response
```typescript
{
scope: "history_day",
threadId: string | null,
day: string | null, // ISO date format "YYYY-MM-DD"
hasMore: boolean,
messages: HistoryMessage[]
}
```
详细数据结构见 [run-agent-input.md](./run-agent-input.md)
### Example
```bash
curl "https://api.example.com/api/v1/agent/history?threadId=550e8400-e29b-41d4-a716-446655440000&before=2026-03-15"
```
### Response Example
```json
{
"scope": "history_day",
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"day": "2026-03-15",
"hasMore": false,
"messages": [
{
"id": "msg-001",
"seq": 1,
"role": "user",
"content": "帮我创建一个日程",
"url": null,
"timestamp": "2026-03-15T10:00:00Z"
},
{
"id": "msg-002",
"seq": 2,
"role": "assistant",
"content": "好的,我来帮您创建日程。",
"uiSchema": {
"version": "2.0",
"locale": "zh-CN",
"status": "success",
"theme": "default",
"root": {
"type": "stack",
"appearance": "card",
"children": [
{"type": "text", "content": "日程已创建", "role": "title"},
{"type": "badge", "label": "SUCCESS", "status": "success"}
]
}
},
"timestamp": "2026-03-15T10:00:05Z"
}
]
}
```
---
## 4. POST /attachments
上传附件到存储。
### Form Data
| 参数 | 类型 | 描述 |
|------|------|------|
| threadId | string | 会话 ID |
| file | file | 要上传的文件 |
### Response
```typescript
{
attachment: {
bucket: string,
path: string,
mimeType: string,
size: number,
url: string // 临时访问 URL
}
}
```
### Example
```bash
curl -X POST https://api.example.com/api/v1/agent/attachments \
-F "threadId=550e8400-e29b-41d4-a716-446655440000" \
-F "file=@/path/to/image.png"
```
### Limits
- 最大文件大小: 5MB
- 支持的文件类型: 见后端配置
---
## 5. GET /attachments/signed-url
生成附件的签名 URL,用于直接访问存储中的文件。
### Query Parameters
| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| bucket | string | 是 | 存储桶名称 |
| path | string | 是 | 文件路径 |
### Response
```typescript
{
bucket: string,
path: string,
url: string // 签名 URL
}
```
### Example
```bash
curl "https://api.example.com/api/v1/agent/attachments/signed-url?bucket=agent-inputs&path=user-123/image.png"
```
### Response Example
```json
{
"bucket": "agent-inputs",
"path": "user-123/image.png",
"url": "https://storage.example.com/agent-inputs/user-123/image.png?signature=abc123..."
}
```
---
## 6. POST /transcribe
语音转文字 (ASR)。
### Request
Form Data:
| 参数 | 类型 | 描述 |
|------|------|------|
| audio | file | 音频文件 (WAV 格式) |
### Headers
| 参数 | 描述 |
|------|------|
| content-length | 文件大小 |
### Response
```typescript
{
transcript: string, // 转录文本
language: string, // 检测到的语言
duration: number // 音频时长 (秒)
}
```
### Example
```bash
curl -X POST https://api.example.com/api/v1/agent/transcribe \
-F "audio=@/path/to/audio.wav"
```
### Response Example
```json
{
"transcript": "今天天气真不错",
"language": "zh-CN",
"duration": 3.5
}
```
### Limits
- 支持格式: `audio/wav`, `audio/x-wav`, `audio/wave`
- 最大文件大小: 10MB
- 速率限制: 20 次/分钟/用户
---
## 错误响应
所有端点可能返回以下错误:
| 状态码 | 描述 |
|--------|------|
| 400 | 请求参数错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 413 | 请求体过大 |
| 422 | 数据验证失败 |
| 429 | 速率限制 |
| 500 | 服务器内部错误 |
### Error Response Format
```json
{
"detail": "错误详情信息"
}
```