Files
llm-wiki/docs/spark/2026-06-15-omp-tool-status-events-design.md
T
2026-07-12 21:26:08 +08:00

175 lines
6.9 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.
# OMP 风格动态工具状态设计
日期:2026-06-15
## 背景
当前工作台已经能接收 agent 的工具开始和工具结束事件,但前端会把每次工具调用都追加到当前回复里。复杂任务一多,聊天区会变成工具流水账,用户很难看清“agent 此刻到底在做什么”。
目标不是做一个简陋的工具提示,而是对齐 `omp` 的体验:当前动作始终以彩色动态状态呈现,历史动作沉淀为可折叠摘要。
## 已确认方向
- 动态工具条放在当前 assistant 回复内部,跟着当前回复走。
- 工具条是彩色、动态、持续刷新的“跑马灯”状态,而不是普通灰色文本。
- 工具结束后不再把所有动作摊开显示,改为丰富但折叠的历史摘要。
- 不走 MVP 思维,优先做完整体验。
- 采用“升级项目内 pi-agent 依赖 + 对齐新版 `omp` 事件模型”的路线。
- 升级对象是本项目的依赖,不是用户本机全局安装的 `omp``pi-agent`
## 目标体验
当 agent 开始调用工具时,当前 assistant 回复内部、正文之前出现一条动态工具条。它显示当前正在执行的动作,例如:
- Reading `workbench/PRODUCT.md`
- Writing `wiki/topics/agent-tools.md`
- Running `npm run typecheck`
- Searching current knowledge base
同一轮回复里,如果工具连续切换,工具条只显示当前正在进行的一项,之前完成的动作进入折叠摘要。
当 agent 开始输出正文时,工具条仍留在同一条回复内,固定在正文上方,不抢正文阅读。当前工具全部结束后,工具条消失或变为短暂完成态,历史摘要保留。
## 历史摘要
历史摘要默认折叠,但不是只显示一个数字。它要像 `omp` 一样让用户快速判断 agent 做过什么:
- 按工具类型分组:Read、Write、Bash、Search、Skill 等。
- 每组显示数量。
- 每组显示少量关键目标,例如文件名、页面名、命令摘要。
- 超过展示上限时显示“还有 N 项”。
- 用户展开后可以看到完整工具清单。
摘要示例:
```text
工具摘要
Read (6)
✓ SKILL.md:1-80
✓ README.md:1-80
✓ workbench/PRODUCT.md
Write (4)
✓ wiki/sources/...
Bash (2)
✓ npm run typecheck
```
## 底层升级策略
先开分支验证项目内 `pi-agent` 依赖升级,而不是直接改功能。
验证目标:
1. 项目能安装成功。
2. 后端能启动。
3. 前端能连接后端。
4. 基础对话能跑通。
5. 当前知识库上下文仍能注入。
6. Skill 调用仍能工作。
7. 会话历史仍能读取。
8. 新版事件里能拿到工具名、工具参数、工具状态、必要时的运行中更新。
如果新版依赖改了包名、导出路径或事件格式,后端要增加一个适配层,把新版事件统一整理成前端使用的稳定事件。
如果升级验证失败,不应退回到简陋前端方案;应记录失败点,并决定是补适配层、锁定可用版本,还是分阶段迁移。
## 事件设计
前端不直接依赖底层 `pi-agent` 原始事件。后端提供工作台自己的稳定事件:
- `assistant_text_delta`assistant 正文增量。
- `tool_status_start`:一个工具开始或当前工具切换。
- `tool_status_update`:工具参数、目标、运行中描述更新。
- `tool_status_end`:工具完成、失败或取消。
- `tool_status_summary`:一轮回复的工具摘要更新。
- `assistant_done`:本轮回复完成。
- `assistant_error`:本轮回复异常。
每个工具事件至少包含:
- 工具调用 ID。
- 工具名。
- 面向用户的动作标签。
- 目标对象,例如文件名、页面名、命令摘要。
- 状态:运行中、完成、失败、取消。
- 分组类型。
- 是否可放入折叠摘要。
面向用户的动作标签优先来自新版事件里的自然语言意图;如果没有,就由后端根据工具名和参数生成。
## 前端结构
当前 `ChatPanel` 已经同时承担消息流、工具流、输入框、命令菜单、引用菜单等职责。实现时应把工具状态拆成独立小模块,而不是继续把逻辑塞进消息数组。
建议拆分:
- `ToolStatusRunway`:当前动态工具条。
- `ToolHistorySummary`:折叠工具摘要。
- `tool-status-model`:把 start/update/end 事件归并成当前状态和历史摘要。
- `formatToolStatus`:把工具名和参数转成人能看懂的短句。
消息对象里不再存一长串实时工具标记。工具状态应作为当前 assistant 回复的附属状态存在;历史消息只保留完成后的摘要数据。
## 视觉设计
动态工具条应满足:
- 彩色流动背景或流动边框。
- 有明确的当前动作动词。
- 目标文字可截断,不撑破布局。
- 工具切换时有轻微过渡。
- 深色和浅色主题都可读。
- 在手机宽度下不遮挡正文,不横向溢出。
折叠摘要应满足:
- 默认占用空间小。
- 能一眼看出做过哪些类型的事。
- 展开后清单结构清楚。
- 不和正文 Markdown 表格、列表样式混在一起。
## 错误和边界状态
- 工具失败:当前工具条变为失败态,摘要中该项标红或标记失败。
- 工具取消:当前工具条显示取消态,摘要保留已完成部分。
- 工具事件缺参数:显示工具名和通用动作,不显示空目标。
- 多个工具并行:工具条显示最近活跃工具,摘要中保留所有工具;如新版事件能提供并行状态,可显示“另有 N 项运行中”。
- 长文件路径:中间截断,保留文件名或末尾路径。
- 长命令:保留主命令和关键参数,展开后看完整命令。
- 会话恢复:历史消息显示折叠摘要,不恢复动态跑马灯。
## 验证方式
升级依赖后先做底层验证:
- 安装依赖。
- 类型检查。
- 启动后端和前端。
- 发送普通对话。
- 发送会触发知识库检索的问题。
- 发送会触发 read/write/bash 的任务。
- 检查 Skill 调用是否仍可用。
界面实现后做体验验证:
- 打开本地页面实际跑一次长任务。
- 确认屏幕上始终只有一个当前工具条,而不是一长串工具。
- 确认工具结束后出现折叠摘要。
- 展开摘要,确认分组和明细正确。
- 在深色和浅色主题下检查可读性。
- 在窄屏尺寸下检查不溢出、不遮挡输入框。
## 不做的事
- 不改用户本机全局 `omp`
- 不直接修改 `node_modules`
- 不为了工具条重做整个聊天系统。
- 不把完整工具输出全部展示在主聊天区。
- 不把这次升级扩展成桌面打包或新知识库能力。
## 成功标准
用户给 agent 一个复杂任务时,聊天区不再被工具流水账占满。用户始终能看到 agent 当前正在做什么;任务结束后,也能通过折叠摘要快速确认 agent 读了什么、写了什么、跑了什么。
最终观感应接近 `omp`:活、清楚、有节奏,而不是普通 Web 应用里的静态日志。