docs: publish chat history navigation workflow
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s
Deploy website to GitHub Pages / Deploy static website (push) Canceled after 0s
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s
Deploy website to GitHub Pages / Deploy static website (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# 聊天历史导航
|
||||
|
||||
聊天历史导航负责长会话的连续滚动、窗口化渲染,以及后续的对话 minimap。第一阶段先取消向上滚动时每次增加 80 条消息的产品限制,保留已有的消息窗口化机制;第二阶段再评估 minimap。
|
||||
|
||||
## 文档导航
|
||||
|
||||
| 文档 | 权威职责 |
|
||||
| --- | --- |
|
||||
| [产品需求](./prd.md) | 用户问题、范围、验收和非目标 |
|
||||
| [技术设计与测试计划](./technical-design.md) | 当前实现边界、实验分组、性能指标和执行步骤 |
|
||||
| [实施进度](./progress.md) | 已验证事实、命令、结果和遗留问题 |
|
||||
|
||||
## 术语
|
||||
|
||||
- **历史窗口**:允许滚动访问的消息范围。第一阶段扩大为当前已加载会话的全部消息。
|
||||
- **DOM 窗口**:实际挂载消息组件的范围。继续由消息高度估算和最多约 60 条挂载消息控制。
|
||||
- **minimap**:对话右侧的轻量纵向全局导航概览,不等于完整渲染所有消息。
|
||||
@@ -0,0 +1,34 @@
|
||||
# 聊天历史连续滚动
|
||||
|
||||
## 用户问题
|
||||
|
||||
长会话向上阅读时,当前界面每次只增加 80 条消息,并在顶部显示“加载更早的消息”控件。这个控件把连续滚动切成多个操作,用户无法像 VSCode 一样直接拖动滚动条或连续滚到会话顶部。
|
||||
|
||||
## 目标
|
||||
|
||||
- 已加载的当前会话可以从底部连续滚动到顶部。
|
||||
- 消息仍按可见范围挂载,长会话不会因为取消 80 条限制而一次性创建全部消息组件。
|
||||
- 滚动位置、锚点、消息展开状态和流式输出行为保持稳定。
|
||||
- 为后续 minimap 提供完整的消息索引和可定位滚动范围。
|
||||
|
||||
## 范围
|
||||
|
||||
- 取消真实聊天会话的 80 条历史窗口增量。
|
||||
- 保留现有消息窗口化、占位高度、滚动锚定和按需挂载。
|
||||
- 对 100、500、2,000、10,000 条消息进行功能和性能对比。
|
||||
- 记录 minimap 的下一阶段性能测试入口,但本阶段不实现 minimap。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不改变未打开会话的摘要加载策略。
|
||||
- 不要求一次从数据库加载所有未加载的会话历史。
|
||||
- 不取消最多约 60 条消息组件的 DOM 窗口化限制。
|
||||
- 不在本阶段加入 minimap、消息摘要接口或新的 IPC。
|
||||
|
||||
## 产品验收
|
||||
|
||||
- 打开一个已加载历史的会话后,顶部不再出现“加载更早的消息”按钮。
|
||||
- 用户可以连续滚动到第一条消息,滚动位置不会因消息挂载或高度测量而跳动。
|
||||
- 2,000 条消息会话仍保持窗口化渲染,实际挂载消息数量维持现有上限附近。
|
||||
- 流式输出、输入、消息展开、附件和工具输出行为没有回归。
|
||||
- 若会话只有摘要,仍按现有逻辑按需加载完整历史。
|
||||
@@ -0,0 +1,17 @@
|
||||
# 实施进度
|
||||
|
||||
## 2026-10-08
|
||||
|
||||
- 已确认 80 条限制由 `ChatHistoryPane` 的 `messageRenderBatchSize` 和 `revealEarlierMessages` 驱动。
|
||||
- 已确认消息窗口化仍以高度占位和最多约 60 条挂载消息为上限。
|
||||
- 已建立基线、本阶段和 minimap 阶段的对比测试计划。
|
||||
- 已将生产会话接线改为直接使用当前已加载消息总数,保留 DOM 窗口化。
|
||||
- `ChatHistoryPane` 与 `ChatTimeline` 定向测试通过:58/58。
|
||||
- 改动文件定向 web 类型检查和 lint 通过。
|
||||
- `npm run build:bundle` 通过。
|
||||
- `npm run perf:app` 通过。本次 B 组测量中,长会话打开交互延迟为 86.9 ms,长会话滚动帧间隔 p95 为 16.9 ms、无长任务;流式输入场景帧间隔 p95 为 16.9 ms,输入延迟 p95 为 17.1 ms。
|
||||
- B 组第二次运行仍通过:长会话打开交互延迟为 46.9 ms,长会话滚动帧间隔 p95 为 16.8 ms、无长任务;流式输入场景输入延迟 p95 为 19.1 ms。
|
||||
- App 测试通过 341/349;剩余 8 个失败集中在既有图片附件异步场景,未出现聊天历史窗口相关失败。
|
||||
- 全局 `npm run typecheck` 仍被既有 `src/main/desktop-storage-electron-fixture.ts:215-217` 类型错误阻断;全局 lint 仍包含生成的 VitePress cache 错误。
|
||||
- A 组临时恢复后连续两次在 composer 初始化阶段超时,未进入性能场景,因此没有有效 A 组数据,不能据此推导 A/B 数值差异。B 组代码已恢复并重新完成 bundle、定向类型检查、定向 lint 和 58/58 聊天窗口测试。
|
||||
- 下一步实现 minimap 前仍需先修复性能驱动在 A 组接线下的 composer 初始化问题,或建立不依赖 composer 的长会话专用 benchmark,再进行严格 A/B 测量。
|
||||
@@ -0,0 +1,52 @@
|
||||
# 技术设计与测试计划
|
||||
|
||||
## 当前边界
|
||||
|
||||
`ChatHistoryPane` 当前有两层机制:`messageRenderBatchSize = 80` 控制向上滚动时可访问的历史窗口;`maxRenderedMessageCount = 60` 控制实际挂载的消息组件。第一阶段只移除前者在生产接线中的作用,保留后者以及消息高度占位和锚点恢复。
|
||||
|
||||
已加载历史的消息数组仍由会话 store 提供。带 `messageSummary` 的会话继续先显示加载状态,由现有 `loadHistory` 路径取得完整历史。这样本实验测量的是滚动历史窗口的变化,不混入存储或 IPC 改造。
|
||||
|
||||
## 实验分组
|
||||
|
||||
| 组别 | 历史窗口 | DOM 窗口 | minimap |
|
||||
| --- | --- | --- | --- |
|
||||
| A 基线 | 每次增加 80 条 | 保留 | 无 |
|
||||
| B 本阶段 | 当前已加载消息全部可访问 | 保留 | 无 |
|
||||
| C 下一阶段 | 当前已加载消息全部可访问 | 保留 | 有 |
|
||||
|
||||
A 组保留在组件级回归测试中;B 组是当前生产实验;C 组待 B 组稳定后实现。
|
||||
|
||||
## 功能测试计划
|
||||
|
||||
- 100 条消息:打开会话后直接滚到第一条,不出现加载按钮。
|
||||
- 500 条消息:从底部连续滚到顶部,检查消息顺序、首尾消息和滚动位置。
|
||||
- 2,000 条消息:在中部、顶部和底部来回滚动,确认高度占位和锚点不跳动。
|
||||
- 消息交互:展开 reasoning/tool details、输入答案、选择文本、打开附件后滚出再滚回,确认状态保留。
|
||||
- 流式消息:生成过程中滚动、暂停跟随底部,再回到底部,确认自动跟随行为不变。
|
||||
- 摘要会话:打开只有 `messageSummary` 的会话,确认仍然先加载历史,不把摘要误当作完整消息。
|
||||
|
||||
## 性能测试计划
|
||||
|
||||
每个规模至少运行 5 次,分别记录冷打开和已经打开后的滚动表现。低端机模拟沿用已有性能测试配置,结果记录中注明运行环境。
|
||||
|
||||
记录指标:
|
||||
|
||||
- 会话打开到首屏可交互的耗时;
|
||||
- 首次滚到顶部的耗时;
|
||||
- 连续滚动期间长任务和掉帧;
|
||||
- Renderer 内存峰值和测试结束后的回收情况;
|
||||
- 实际挂载消息数量;
|
||||
- 流式输出时输入延迟。
|
||||
|
||||
通过条件:B 组功能测试全部通过,实际挂载消息数量仍受窗口上限控制;相对 A 组没有明显的输入、流式输出或滚动回归。若 B 组稳定,再以同一批数据实现 C 组并做增量对比。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```text
|
||||
npm exec vitest run src/renderer/src/ChatHistoryPane.test.tsx src/renderer/src/ChatTimeline.test.tsx
|
||||
npm run typecheck
|
||||
npm run lint
|
||||
npm run perf:app
|
||||
```
|
||||
|
||||
`perf:app` 的具体参数和输出以仓库脚本当前实现为准;无法在自动化环境观察的内存和掉帧指标,需要补充 Electron 手工记录。
|
||||
Reference in New Issue
Block a user