This commit is contained in:
2026-07-12 21:26:08 +08:00
commit 9dd41afd48
502 changed files with 129901 additions and 0 deletions
@@ -0,0 +1,174 @@
# 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 应用里的静态日志。