7b8865e256
- 新增 stepStarted/stepFinished 事件类型支持 - 前端实现图片附件上传和预览功能 - 后端增强工具结果存储和事件处理 - 完善相关单元测试和集成测试
174 lines
6.1 KiB
Markdown
174 lines
6.1 KiB
Markdown
# Agent Tool UI Schema and Frontend Event Wiring Design
|
||
|
||
## Goal
|
||
|
||
修正 agent 工具结果的数据契约与前后端对接:
|
||
|
||
1. SSE `TOOL_CALL_RESULT` 继续携带可实时渲染的 `ui`。
|
||
2. 落库时 `messages.content` 仅存关键摘要,完整工具结果(含 `ui schema`)存对象存储。
|
||
3. `messages.metadata` 仅存访问路径和索引字段,history 通过 metadata 回填完整工具卡片数据。
|
||
4. 前端正式接通 runs/events/history 三路,并统一实时与历史渲染行为。
|
||
|
||
## Constraints
|
||
|
||
- 暂缓冒烟测试,先完成工具数据修正与前后端接口对接。
|
||
- 保持现有前端 `UiSchemaRenderer` 可解析格式,不做破坏性协议改动。
|
||
- `resume` 新需求暂不扩展。
|
||
- 遵循 AG-UI 事件语义和现有 FastAPI 路由约定。
|
||
|
||
## Selected Approach
|
||
|
||
采用兼容增强方案:
|
||
|
||
- 事件流对前端保持兼容(`TOOL_CALL_RESULT` 带 `ui` + `content`)。
|
||
- 持久化与回放做结构化增强(storage + metadata 索引 + 摘要 content)。
|
||
- 前端实时与历史统一映射层,保证同类消息一致渲染。
|
||
|
||
## Design A: Unified Data Contract
|
||
|
||
### SSE Event Contract (Realtime)
|
||
|
||
`TOOL_CALL_RESULT` 事件继续包含前端当前可解析字段:
|
||
|
||
- `callId`
|
||
- `toolName`
|
||
- `args`
|
||
- `result`
|
||
- `error`
|
||
- `content` (关键结果摘要)
|
||
- `ui` (工具卡片 schema)
|
||
|
||
这保证前端实时流不需要等待 history 即可显示工具卡片。
|
||
|
||
### Persistence Contract (Database + Storage)
|
||
|
||
对 tool message 持久化采用双层:
|
||
|
||
- `messages.content`: 仅保存 `content_summary`(短文本,供低成本上下文和兜底展示)。
|
||
- 对象存储: 保存完整 payload(`ui`、`args`、`result`、`error`、时间戳、工具标识等)。
|
||
- `messages.metadata`: 只保存索引和访问路径:
|
||
- `tool_call_id`
|
||
- `tool_name`
|
||
- `run_id`
|
||
- `stage`
|
||
- `task_id`
|
||
- `storage_bucket`
|
||
- `storage_path`
|
||
- `summary_version`
|
||
|
||
### History Contract
|
||
|
||
history 序列化时:
|
||
|
||
1. 先通过 `metadata.storage_bucket/storage_path` 读取完整 payload。
|
||
2. 从 payload 回填 `ui`,并保留摘要 `content`。
|
||
3. storage 读取失败时,回退 `messages.content`,确保历史可读。
|
||
|
||
## Design B: Frontend Wiring (runs/events/history)
|
||
|
||
### runs
|
||
|
||
- `POST /api/v1/agent/runs` 仅负责创建 run 与启动执行。
|
||
- 前端保留 `threadId/runId` 和本地流状态,不承载渲染业务。
|
||
|
||
### events
|
||
|
||
- SSE 作为唯一实时渲染来源。
|
||
- `TOOL_CALL_RESULT` 直接读取事件内 `ui` 渲染 `ToolResultItem`。
|
||
- `STEP_STARTED/STEP_FINISHED` 显示三阶段状态(intent/execution/report)。
|
||
|
||
### history
|
||
|
||
- 通过 `/api/v1/agent/history` 或 `/api/v1/agent/runs/{threadId}/history` 回放。
|
||
- tool message 优先读 `ui`(由后端从 metadata+storage 回填)。
|
||
- user message 读取 `attachments` 渲染多模态内容。
|
||
|
||
### Consistency Rule
|
||
|
||
- 实时事件与历史快照统一进入同一 `ChatListItem` 映射层。
|
||
- `content` 只做兜底文本,不作为工具卡片主数据。
|
||
|
||
## Design C: Backend Implementation Details
|
||
|
||
### Modules to Change
|
||
|
||
- `backend/src/core/agentscope/events/store.py`
|
||
- 增加 tool result 的摘要生成与 storage 上传。
|
||
- `append_message` 时写入摘要 content + metadata 索引。
|
||
- `backend/src/core/agentscope/tools/tool_result_storage.py`
|
||
- 复用现有 `upload_json/read_json`,作为完整 payload 存取层。
|
||
- `backend/src/v1/agent/repository.py`
|
||
- `_to_snapshot_message` 对 tool message 优先按 metadata 读取 storage 并回填 `ui`。
|
||
- `backend/src/core/agentscope/runtime/agent_route_runtime.py`
|
||
- 确保 `tool.result` 事件继续带 `ui` 和摘要 `content`。
|
||
|
||
### Failure Fallback
|
||
|
||
- storage 写失败:不阻断主流程,至少保证 `messages.content` 可读,metadata 标记缺失。
|
||
- storage 读失败:history 返回摘要 `content`,`ui` 为空。
|
||
|
||
## Design D: content_summary Rule Engine
|
||
|
||
### Function
|
||
|
||
新增纯函数:
|
||
|
||
`build_tool_content_summary(tool_name, args, result, error) -> str`
|
||
|
||
### Rules (Priority)
|
||
|
||
1. 错误优先:有 `error` 直接输出失败摘要。
|
||
2. 工具专用模板:
|
||
- `calendar_write`: `已创建日程:{title}({start_time})`
|
||
- `calendar_read`: `查询到 {count} 条日程({date_range})`
|
||
- `calendar_delete`: `已删除日程:{title_or_id}`
|
||
- `calendar_share`: `已分享日程给 {target}`
|
||
- `user_resolve`: `已匹配用户:{name_or_id}`
|
||
3. 通用回退:优先 `result.content`,否则抽取常见键拼句。
|
||
4. 最终兜底:`{tool_name} 执行完成/执行失败`。
|
||
5. 清洗:去换行与多空格,限制长度,避免大段 JSON。
|
||
|
||
### Summary Storage Policy
|
||
|
||
- `messages.content` 存摘要。
|
||
- `summary_version` 存入 metadata,支持未来摘要算法演进。
|
||
|
||
## Testing and Acceptance
|
||
|
||
### Backend
|
||
|
||
- 单元测试:
|
||
- `events/store`: tool result 摘要写入、metadata 路径写入、storage 异常回退。
|
||
- `v1/agent/repository`: history 按 metadata 回填 `ui`;storage 缺失回退 content。
|
||
- 摘要函数:覆盖成功/失败/缺字段/超长文本场景。
|
||
- 集成测试:
|
||
- `/runs` + `/events`:实时 `TOOL_CALL_RESULT` 带 `ui`。
|
||
- `/history`:返回 tool message 的 `ui` 来自 metadata+storage。
|
||
|
||
### Frontend
|
||
|
||
- 单元/组件测试:
|
||
- `AgUiService` 解析 `TOOL_CALL_RESULT` 的 `ui`。
|
||
- `ChatBloc`:实时事件与 history 快照都能产出 `ToolResultItem`。
|
||
- `UiSchemaRenderer`:history 回放卡片渲染一致。
|
||
- user message 附件渲染(history)。
|
||
- 页面行为验证:
|
||
- events 到达即实时更新消息列表。
|
||
- step 三阶段状态正确切换。
|
||
- 上拉历史后工具卡片可正常显示。
|
||
|
||
## Risks and Mitigations
|
||
|
||
- 风险:storage 不可用导致 history 卡片缺失。
|
||
- 缓解:保底展示摘要 content,不阻断对话。
|
||
- 风险:事件格式变更导致前端实时解析失败。
|
||
- 缓解:维持现有 `ToolCallResultEvent` 字段,不做破坏性改名。
|
||
- 风险:摘要规则覆盖不足。
|
||
- 缓解:规则版本化 + 测试样例扩展。
|
||
|
||
## Out of Scope
|
||
|
||
- resume 扩展协议与交互策略。
|
||
- 新一轮 live 冒烟验收。
|
||
- 新 UI 风格重构,仅实现链路打通与数据契约修正。
|