返回 DeepSeek-Reasonix
TRANSCRIPT_OUTLINE_NAVIGATION.zh-CN.md
根目录 / docs / TRANSCRIPT_OUTLINE_NAVIGATION.zh-CN.md
1 # 轮次大纲与跨分页跳转
2
3 [English](TRANSCRIPT_OUTLINE_NAVIGATION.md)
4
5 > **历史验收记录——已被 PR #10385(Follow v2)替代。**
6 > 本文记录 PR #10276 的完整大纲实现及当时执行的验证。文中的前后对比与测试结果
7 > 不构成当前生产链路的验收证据。
8
9 当前行为采用双向有界历史窗口,导航条仅展示已加载轮次;完整持久化历史仍可通过
10 权威历史搜索与定位访问。现行约定见[会话同步 v2](TRANSCRIPT_V2.md)、
11 [滚动与历史契约](TRANSCRIPT_SCROLL_CONTRACT.zh-CN.md)及
12 [自然流正文](TRANSCRIPT_ARCHITECTURE.zh-CN.md)。以下历史设计与验证结果保留用于追溯。
13
14 ## 原始问题
15
16 在工具密集的长对话中,首个正文分页只包含最新的 120 条记录。当这一页里少于两次用户提问时,导航条会整体隐藏:用户必须反复点击"加载更早消息"才会出现导航。切换到其他对话再切回,正文分页被重建,导航可能再次消失;标记还会从 1 重新编号,因为轮次序号取自已加载窗口。窗口之外的轮次完全无法到达。
17
18 | | 修复前 | 修复后 |
19 | --- | --- | --- |
20 | 导航内容 | 仅已加载的用户提问 | 完整会话的全部轮次 |
21 | 长会话首次进入 | 需手动加载历史后才出现 | 不加载正文即可完整显示 |
22 | A → B → A | 随正文窗口重建而重置 | 由快照索引恢复 |
23 | 轮次编号 | 按已加载窗口从 1 重排 | 会话内的绝对轮次号 |
24 | 未加载轮次 | 不列出 | 列出,可预览、可点击 |
25 | 点击结果 | 无法点击 | 连续加载历史后准确定位 |
26
27 ## 设计
28
29 - `internal/transcript` 在正文分页旁提供有界轮次大纲,与正文绑定同一不可变快照、投影修订和事件覆盖边界。每条携带用户记录的稳定 `RecordID`、可选 `MessageID`、绝对轮次号、该记录在快照中的 `order`,以及两段仅取展示正文的预览:提问 50 个字形簇,回答取该轮分组内最后一条非空助手正文的 120 个字形簇。推理、工具输出、提交文本和注入上下文不会进入大纲。
30 - 索引每个冻结快照只构建一次,重复读取复用同一遍扫描;正文分页不会缩减索引;预览内存计入现有快照缓存预算与生命周期。
31 - `GET /transcript/outline` 提供该数据,远程握手公布 `transcript-outline-v1`。`TranscriptOutlineAPI` 是 `TranscriptProjectionAPI` 之外的可选能力,旧控制器实现无需改动即可编译,不支持的路由返回 404/405/501 而不是空页。
32 - 前端为本地与远程会话共用一份大纲存储,按 tab generation 与快照身份设围栏。快照被回收时如实上报过期;只有用户明确重试才会替换正文。
33 - 点击未加载轮次会启动跳转事务:串行复用普通历史分页,每页之间等待逐批挂载推进,仅在目标节点真正挂载后才写入视口。阅读意图、显式取消、更新的目标或会话/快照替换都会结束待执行事务,且不会重新取得滚动控制权。
34
35 ## 验证
36
37 本地与远程路径的代码及自动化检查已完成。平台验证按下述分层如实记录,未运行的部分不予声明。
38
39 ### Go(已运行)
40
41 ```sh
42 go test ./internal/transcript/ ./internal/control/ ./internal/serve/
43 go test -race ./internal/transcript/
44 cd desktop && go test ./...
45 ```
46
47 覆盖:工具密集尾部导致正文分页不含用户提问时大纲仍完整;与正文记录一致的身份;绝对编号及更早分页后的保持;被回收快照的过期上报;预览长度、空白折叠、Unicode 安全及排除推理/工具输出;空提问保留轮次身份;字节预算与游标前进;响应上限;越界 offset;空会话编码为 `[]`;HTTP 端点的分页、会话绑定、能力公布,以及无该能力控制器返回 501;以及大纲读取与流式提交的并发竞争。
48
49 ### 前端(已运行)
50
51 ```sh
52 cd desktop/frontend
53 pnpm test:transcript # 含 transcript-outline-store、chat-turn-jump、
54 # chat-turn-outline-jump
55 pnpm test:remote
56 pnpm build # 类型检查、scroll-writer 门禁、CSS/主题、bundle 预算
57 ```
58
59 `transcript-outline-store` 覆盖多页组装、重复身份、过期快照、游标停滞、能力缺失与真实失败的区分,以及释放对在途读取的围栏。`chat-turn-jump` 覆盖挂载确认后的分页、无产出分页、历史耗尽、用户抢占、新目标取代、会话替换、显式取消,以及有界的挂载等待。`chat-turn-outline-jump` 在 jsdom 中驱动真实 `Transcript`:只加载最新几轮时导航条仍完整、较早轮次标记为未加载、点击后连续加载直到节点挂载、该过程不改变编号、busy 状态正确结束。
60
61 ### 浏览器(已运行)
62
63 ```sh
64 cd desktop/frontend
65 CHAT_BROWSER=chromium node bench/chat-transcript.mjs
66 ```
67
68 确认真实页面的渲染、流式与滚动在本次改动后保持正常。该次运行两个场景均报告零错误。记录时间 2026-09-14,arm64 darwin,Chromium 153.0.8010.12:
69
70 | 指标 | 240 轮 | 1000 轮 | 门槛 |
71 | --- | --- | --- | --- |
72 | 输入 P95 | 46.5 ms | 137.6 ms | ≤ 200 ms |
73 | 切换 P95 | — | 38.2 ms | ≤ 300 ms |
74 | 最长任务 | 53 ms | 218 ms | ≤ 500 ms |
75 | 堆增长 | — | 0.33 MiB | ≤ 20 MiB |
76 | 锚点 / 前置漂移 | 0 / 0.09 px | — | 无漂移 |
77 | 已挂载 DOM 节点 | 12089 | 47833 | 导航有界 |
78
79 这是对真实页面的回归检查,不替代下述原生平台验证。1000 轮数据同时说明导航不会按轮次创建等量 DOM:只渲染可视范围内的标记。
80
81 ### 窗口应用(未运行)
82
83 Electron 基准(`node bench/transcript-layout.mjs --electron`)及打包后的桌面构建需要已签名应用包,本环境未执行。
84
85 ### Windows(本环境未验证)
86
87 本环境未在 Windows 上重放原始路径,因此无法记录构建 SHA。在真实 Windows 桌面构建上重放原始场景仍属待验证的外部事项,本记录不作声明。
88
89 ## 兼容性
90
91 本次为增量扩展。不具备该能力的客户端继续使用已加载轮次导航,也不宣称拥有完整导航。不修改持久化会话格式、provider 消息、工具 schema、权限或提示缓存字节,因此不影响提示缓存。回退到上一版前端并忽略新增只读端点即可恢复。
92
92 lines MARKDOWN