Files
social-app/docs/protocols/ui/data-flow.md
T

159 lines
4.7 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 Chat)
本文档仅描述**当前后端实现**的 runs/events/history 数据流,不定义视觉细节。
---
## 1) 总体流程
1. 客户端 `POST /api/v1/agent/runs` 提交 `RunAgentInput`
2. 后端返回 `202` + `taskId/threadId/runId/created`
3. 客户端 `GET /api/v1/agent/runs/{threadId}/events` 订阅 SSE
4. 后端输出 AG-UI 事件(如 `RUN_STARTED``TOOL_CALL_RESULT``TEXT_MESSAGE_END`
5. 客户端按需 `GET /api/v1/agent/history` 拉取历史快照(按天)
---
## 2) `/runs` 请求与响应
### 请求
- Body: `RunAgentInput`
- user message 可为纯文本,也可为文本+binary(图片 URL
### 响应
```json
{
"taskId": "...",
"threadId": "...",
"runId": "...",
"created": true
}
```
`created` 语义:是否在本次请求中创建了新会话。
---
## 3) `/runs/{threadId}/events` 事件流
### SSE 形式
```text
id: <stream-id>
event: <EVENT_TYPE>
data: <json>
```
### 事件类型
`docs/protocols/agent/sse-events.md` 为准。当前重点是:
- 运行生命周期:`RUN_STARTED` / `RUN_FINISHED` / `RUN_ERROR`
- 阶段:`STEP_STARTED` / `STEP_FINISHED`
- 工具:`TOOL_CALL_START` / `TOOL_CALL_ARGS` / `TOOL_CALL_END` / `TOOL_CALL_RESULT`
- 文本完成:`TEXT_MESSAGE_END`
### 文本流策略
当前后端不提供 token 级 `TEXT_MESSAGE_CONTENT` 增量流作为主路径;
而是在 worker 完成后通过 `TEXT_MESSAGE_END` 一次性携带完整语义结果。
---
## 4) `/history` 快照
`GET /api/v1/agent/history` 返回 `HistorySnapshotResponse`
```json
{
"scope": "history_day",
"threadId": "...",
"day": "2026-03-16",
"hasMore": false,
"messages": []
}
```
说明:
- 这是普通 JSON 响应,不是 SSE 事件包装。
- `messages` 已按 seq 升序组织。
- `before` 采用 `YYYY-MM-DD`,语义是向更早日期翻页。
---
## 5) events 与 history 的一致性机制
### 5.1 语义来源一致
两条链路都来自同一运行时输出(worker/tool output)及其持久化元数据。
### 5.2 UI 编译器一致
两条链路都使用后端 `ui_compiler.compile(...)`**tool**`ui_hints` 编译为可渲染结构:
- events:在 runtime 发送事件前编译,字段名为 `ui_schema`
- history:在历史转换时编译,字段名为 `ui_schema`
tool 结果走 UI 编译链路:`TOOL_CALL_RESULT` 在保留 `tool_call_args` + `result` 的同时可携带 `ui_schema`
- `metadata.tool_agent_output` 是 tool 消息的完整信源(用于 runtime observation 与 history replay)。
- `message.content` 保持轻量摘要(当前等于 `result`)。
- `tool_call_args` 记录输入参数,`result` 记录输出事实,二者不做冗余重复。
### 5.3 当前命名差异(实现现状)
两条链路字段命名已统一:
- events: `ui_schema`snake_case
- history: `ui_schema`snake_case
---
## 6) 推荐消费顺序(面向客户端重构)
1. 先以 `/history` 获取首屏快照
2. 再接入 `/events` 处理后续增量
3.`runId` + `messageId/toolCallId` 做去重与合并
4. 统一消费 `ui_schema`
---
## 7) Navigation Action 数据流(ui_schema.actions
### 7.1 后端生成
- runtime 基于 tool 输出中的 `ui_hints.action.type = navigation` 产出导航动作。
- 编译后在 `ui_schema` 中保持 `action.type = navigation``action.path``action.params`
- 路由由工具能力直接给出 concrete pathagent 本身不需要维护 route_id 概念。
### 7.2 前端消费(统一解析规则)
-`type = navigation`,前端仅走一条解析路径:
1. 读取 `path` 作为内部路由目标;
2.`params` 仅视为 query 参数(不用于 path 模板替换);
3. 执行 GoRouter 跳转(建议 `context.go(...)`)。
- `path` 必须是已落地页面路由,且应是已实参化路径(如 `/todo/123`,而非 `/todo/:id`)。
### 7.3 路由表达粒度(Route-First 约束)
- 关键业务动作(创建、编辑、分享、处理邀请等)应优先设计为可深链页面路由,而不是仅存在于临时弹层。
- 若 UI 采用 sheet 风格展示,也应由页面路由承载状态,再以页面内 surface 呈现 sheet 视觉。
- `todo.edit` 必须落地为独立子页面(`/todo/{id}/edit`),不应通过详情页内弹窗承载编辑主流程。
- 推荐工具能力优先输出以下 concrete path(示例):
- `/calendar/events/new`
- `/calendar/events/{id}/edit`
- `/calendar/events/{id}/share`
- `/todo/new`
- `/todo/{id}/edit`
### 7.4 约束建议
- 为了让前端只保留一种解析逻辑,推荐强约束:
- `path` 只接受内部路由;
- `params` 只接受标量值(string/number/boolean);
- 禁止在 `params` 里放嵌套对象数组。