Files
social-app/docs/protocols/ui/data-flow.md
T
qzl b34697660d feat: 实现 Auth 全局状态机与 401 统一处理机制
- 新增 AuthSessionInvalidated 事件处理 token 失效场景
- ApiInterceptor 新增 authFailureCallback 单飞机制
- AuthBloc 区分 manual logout 与 auto expiry 语义
- 新增 startup recovery fallback 防止启动卡死

feat: 重构 Calendar DayWeek 视图事件布局引擎

- 新增 DayEventLayoutEngine 解耦事件计算与渲染
- 新增 DayTimelineMetrics 统一时间轴常量
- 新增 DayViewScale 支持捏合缩放

feat: 新增 Settings 页面共享 UI 组件

- 新增 BackTitlePageHeader 统一页面 header
- 新增 DetailHeaderActionMenu 统一操作菜单
- 新增 DestructiveActionSheet 统一删除确认
- 新增 AppToggleSwitch 统一开关组件

feat: Chat UI Schema 支持导航操作

- 支持 navigation 类型 action 触发内部路由跳转
- 新增路径验证与参数处理

chore: 更新相关测试覆盖 auth 失效路径
2026-03-18 13:35:25 +08:00

148 lines
4.0 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(...)`**worker**`ui_hints` 编译为可渲染结构:
- events:在 runtime 发送事件前编译,字段名为 `ui_schema`
- history:在历史转换时编译,字段名为 `ui_schema`
tool 结果不再走 UI 编译链路:`TOOL_CALL_RESULT` 提供 `tool_call_args` + `result` 组合。
- `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 使用 `ui_hints.action.type = navigation` 产出导航动作。
- 编译后在 `ui_schema` 中保持 `action.type = navigation``action.path``action.params`
- 路由来源应受后端静态路由目录约束:
- `backend/src/core/config/static/route/frontend_routes.yaml`
### 7.2 前端消费(统一解析规则)
-`type = navigation`,前端仅走一条解析路径:
1. 读取 `path` 作为内部路由目标;
2.`params` 仅视为 query 参数(不用于 path 模板替换);
3. 执行 GoRouter 跳转(建议 `context.go(...)`)。
- `path` 必须是已落地页面路由,且应是已实参化路径(如 `/todo/123`,而非 `/todo/:id`)。
### 7.3 约束建议
- 为了让前端只保留一种解析逻辑,推荐强约束:
- `path` 只接受内部路由;
- `params` 只接受标量值(string/number/boolean);
- 禁止在 `params` 里放嵌套对象数组。