Files
social-app/docs/protocols/agent/run-agent-input.md
T
qzl ed86bfe9ae docs: 更新 Agent 协议文档与部署配置
- 更新 Agent API 端点文档
- 更新 SSE 事件与输入输出文档
- 新增 deploy/.env.prod.example 配置模板
2026-03-16 16:11:40 +08:00

451 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent Run Input Protocol
> **NOTE**: This document defines the RunAgentInput data structure for `POST /api/v1/agent/runs`.
## Version
- **Current**: `1.0`
- **Status**: Active
---
## Overview
`POST /api/v1/agent/runs` accepts `RunAgentInput` as request body to initiate an agent execution.
---
## RunAgentInput Schema
```typescript
interface RunAgentInput {
threadId: string; // 必须是有效 UUID
runId: string; // 最大 128 字符
parentRunId?: string;
state?: any;
messages: Message[]; // 最多 200 条
tools?: Tool[];
context?: Context[];
forwardedProps?: any;
}
```
### Required Fields
| Field | Type | Constraints |
|-------|------|-------------|
| `threadId` | string | 必须为有效 UUID |
| `runId` | string | 最大 128 字符 |
| `messages` | array | 最多 200 条,**必须恰好包含 1 条 user message** |
| `state` | any | - |
| `tools` | array | 可选 |
| `context` | array | 可选 |
| `forwardedProps` | any | - |
---
## Message Types
### UserMessage
```typescript
interface UserMessage {
id: string;
role: "user";
content: string | ContentBlock[];
name?: string;
encryptedValue?: string;
}
type ContentBlock = TextContentBlock | BinaryContentBlock;
interface TextContentBlock {
type: "text";
text: string;
}
interface BinaryContentBlock {
type: "binary";
mimeType: string; // 必须为 image/* 类型
id?: string;
url?: string; // 必须是有效的 signed URL
data?: string; // 不允许使用 data 字段
filename?: string;
}
```
### AssistantMessage
```typescript
interface AssistantMessage {
id: string;
role: "assistant";
content?: string | null;
name?: string | null;
toolCalls?: ToolCall[];
encryptedValue?: string | null;
}
interface ToolCall {
id: string;
type: "function";
function: {
name: string;
arguments: string;
};
encryptedValue?: string | null;
}
```
### SystemMessage
```typescript
interface SystemMessage {
id: string;
role: "system";
content: string;
name?: string | null;
encryptedValue?: string | null;
}
```
### ToolMessage
```typescript
interface ToolMessage {
id: string;
role: "tool";
content: string;
toolCallId: string;
error?: string | null;
encryptedValue?: string | null;
}
```
### Other Message Types
- **DeveloperMessage**: `role: "developer"`
- **ReasoningMessage**: `role: "reasoning"`
- **ActivityMessage**: `role: "activity"` (for progress updates)
---
## Tool Schema
```typescript
interface Tool {
name: string;
description: string;
parameters: object; // JSON Schema 格式
}
```
### Example
```json
{
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
```
### Backend Processing
Backend 使用 `build_tools_prompt` 函数将 tools 转换为 prompt 格式:
```
<!-- TOOLS_START -->
- get_weather: Get current weather for a location
- args_schema: {"type":"object","properties":{"location":{"type":"string","description":"City name"},"unit":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location"]}
- searchDocuments: Search for documents
- args_schema: {"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}
Note: tool arguments must strictly match args_schema.
<!-- TOOLS_END -->
```
---
## Context Schema
```typescript
interface Context {
description: string;
value: string;
}
```
---
## Validation Rules
Backend 实现了以下验证规则:
| Rule | Error Message |
|------|---------------|
| payload ≤ 256KB | `RunAgentInput payload exceeds size limit` |
| threadId 必须是 UUID | `threadId must be a valid UUID` |
| runId 最大 128 字符 | `runId exceeds length limit` |
| messages ≤ 200 条 | `RunAgentInput.messages exceeds limit` |
| user text ≤ 10,000 字符 | `RunAgentInput user message text exceeds limit` |
| **恰好 1 条 user message** | `RunAgentInput.messages must contain exactly one user message` |
| user message 必须在第一条 | `RunAgentInput.messages[0].role must be user` |
| binary 必须是 image/* | `binary content requires image mimeType` |
| binary 必须有 url | `binary content requires url` |
| binary 不允许使用 data | `binary content data is not allowed` |
---
## Request Example
### 纯文本请求
```json
{
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"runId": "run-001",
"state": {},
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "帮我查一下北京今天的天气"
}
],
"tools": [],
"context": [],
"forwardedProps": {}
}
```
### 多模态请求 (带图片)
```json
{
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"runId": "run-002",
"state": {},
"messages": [
{
"id": "msg-001",
"role": "user",
"content": [
{
"type": "text",
"text": "这张图片里的内容是什么?"
},
{
"type": "binary",
"mimeType": "image/png",
"url": "https://storage.example.com/agent-inputs/user-123/image.png?signature=xxx"
}
]
}
],
"tools": [],
"context": [],
"forwardedProps": {}
}
```
### 带 Tools 的请求
```json
{
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"runId": "run-003",
"state": {},
"messages": [
{
"id": "msg-001",
"role": "user",
"content": "北京天气怎么样?"
}
],
"tools": [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
],
"context": [],
"forwardedProps": {}
}
```
---
## Response
成功响应返回 `TaskAcceptedResponse`
```typescript
interface TaskAcceptedResponse {
taskId: string;
threadId: string;
runId: string;
created: boolean; // 是否新建会话
}
```
---
## History API
`GET /api/v1/agent/history` 返回对话历史快照。
### Request
| Parameter | Type | Description |
|-----------|------|-------------|
| `threadId` | string (query) | 可选,指定会话 ID,不指定则返回最新会话 |
| `before` | string (query) | 可选,日期格式 `YYYY-MM-DD`,返回该日期之前的快照 |
### Response
返回 `HistorySnapshotResponse`
```typescript
interface HistorySnapshotResponse {
scope: "history_day";
threadId: string | null;
day: string | null; // ISO date format "YYYY-MM-DD"
hasMore: boolean;
messages: HistoryMessage[];
}
```
### HistoryMessage
根据消息 role 不同,返回字段有所差异:
```typescript
// role = "user"
interface HistoryMessageUser {
id: string;
seq: number;
role: "user";
content: string;
url: string | null; // 附件临时访问 URL
timestamp: string; // ISO-8601 timestamp
}
// role = "tool"
interface HistoryMessageTool {
id: string;
seq: number;
role: "tool";
content: string;
ui_schema: UiSchemaRenderer | null; // 由 tool_agent_output.ui_hints 编译
timestamp: string;
}
// role = "assistant"
interface HistoryMessageAssistant {
id: string;
seq: number;
role: "assistant";
content: string;
ui_schema: UiSchemaRenderer | null; // 由 worker_agent_output.ui_hints 编译
timestamp: string;
}
type HistoryMessage = HistoryMessageUser | HistoryMessageTool | HistoryMessageAssistant;
```
### UiSchemaRenderer
编译后的 UI 渲染结构,详见 [UiSchema Protocol](../ui/ui-schema.md)
```typescript
interface UiSchemaRenderer {
version: "2.0";
locale: string;
status: "info" | "success" | "warning" | "error" | "pending";
theme: "default" | "light" | "dark";
meta?: {
requestId?: string;
toolId?: string;
traceId?: string;
userId?: string;
};
root: UiLayoutNode;
}
```
### Example
```json
{
"scope": "history_day",
"threadId": "550e8400-e29b-41d4-a716-446655440000",
"day": "2026-03-15",
"hasMore": true,
"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": "好的,我来帮您创建日程。",
"ui_schema": {
"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"},
{"type": "text", "content": "您的会议日程创建成功", "role": "body"}
]
}
},
"timestamp": "2026-03-15T10:00:05Z"
}
]
}
```
---
## Compatibility Notes
- `UserMessage.content` 支持 string 或 array 格式,前端优先使用 array 格式以支持多模态
- binary content 的 url 必须是有效的 signed URL,由 `/api/v1/agent/attachments` 端点生成
- backend 验证通过后,会将 binary url 转换为内部存储路径
- tools 为空数组时,prompt 中不会包含工具说明
- `RunAgentInput` 同时接受 camelCase 与 snake_case 别名输入(推荐统一使用 camelCase)