feat(tui): add transcript compaction progress marker

This commit is contained in:
Hypatia May
2026-07-31 11:46:43 +08:00
parent afe8d49691
commit 949b9fba8d
11 changed files with 115 additions and 26 deletions
@@ -6,19 +6,21 @@ Status: implemented
## 问题
独立手动压缩(compaction)在轮次之间运行,此时 agent(智能体)保持空闲。因此,在缓慢的摘要操作期间,TUI 的轮次阶段指示器始终显示普通的 `>` 光标;尝试失败时,由于没有替换检查点落地,也不会产生 transcript(文本记录)行。
独立手动压缩(compaction)在轮次之间运行,此时 agent(智能体)保持空闲。因此,在缓慢的摘要操作期间,TUI 的轮次阶段指示器始终显示普通的 `>` 光标;尝试失败时,由于没有替换检查点落地,也不会产生 transcript(文本记录)行。仅把该光标替换成单格字形后,操作虽然在技术上可见,但当注意力仍停留在 transcript 时依然很容易错过。
进程终止后,持久日志中可能保留未匹配的 `compact/start`。该未匹配标记是有用的恢复证据,但无法证明当前进程中有工作正在运行;若将其回放为进度,恢复后的会话便会永久显示虚假的进度指示。
## 决策
TUI 将实时独立的 `compact/start { turn: null }` 与匹配的 `compact/end` 组成的标记对,作为显示进行中压缩状态的真源。模块局部的 `compacting` 状态记录渲染时钟的起始时间,并独占一个动画定时器。现有的单格指示器通过与轮次阶段字形相同的明暗渐变和呼吸律动路径渲染 `⊙`,终端进度标志位会保持活跃,直至标记对闭合。
TUI 将实时独立的 `compact/start { turn: null }` 与匹配的 `compact/end` 组成的标记对,作为显示进行中压缩状态的真源。模块局部的 `compacting` 状态记录渲染时钟的起始时间,独占一个动画定时器,并保存一个仅存在于终端的进度组件。现有的单格指示器通过与轮次阶段字形相同的明暗渐变和呼吸律动路径渲染 `⊙`,组件则渲染一行 `◐` / `◓` / `◑` / `◒ Compaction in progress…`;终端进度标志位会保持活跃,直至标记对闭合。
进度组件拥有其前导空行,并会在每次压缩渲染时重新固定到 transcript 尾部。因此,新增会话内容、`/clear` 和 transcript 重建都无法让实时标记滞留在旧位置或消失。压缩定时器会同时刷新提示符字形与该行;该行不独占另一个定时器。
轮次阶段字形的优先级高于 `⊙`。带编号的压缩标记对会被忽略,因为它们处于运行中的轮次内,该轮次的阶段已经激活指示器。压缩状态不会改变空闲编辑器边框、提示或 steering(中途引导)徽标,因此,在独立压缩预留轮次准入期间,界面仍会明确显示提示词已获接纳。
该状态只反映实时事件。挂载和 transcript 回放绝不会扫描历史以查找未匹配的 start;只有已挂载的 TUI 观察到 `session/event` 通知,才能开启该状态。轮次状态转换会保留该状态,而终端清理会清除其定时器和进度标志位。
该状态与该行只反映实时事件。挂载和 transcript 回放绝不会扫描历史以查找未匹配的 start;只有已挂载的 TUI 观察到 `session/event` 通知,才能开启它们。轮次状态转换会保留该状态,而终端清理会移除该行,并清除其定时器和进度标志位。
收到 `compact/end` 时,TUI 会先清除实时状态,再启动普通字形的淡出。携带 `error` 的结束事件会以警告形式添加 `Compaction failed: <error>`。成功完成仍由已落地替换项的 transcript 标记呈现;无需再添加可见行,也可从匹配且已持久记录的开始与结束时间戳推导持续时间。
收到 `compact/end` 时,TUI 会先移除实时行并清除状态,再启动普通字形的淡出。携带 `error` 的结束事件会以警告形式添加 `Compaction failed: <error>`。成功完成仍由已落地替换项的 transcript 标记呈现;无需再添加已结算的行,也可从匹配且已持久记录的开始与结束时间戳推导持续时间。
本决策仅部分取代[终端 transcript 决策](../bug-fix/2026-07-29-human-transcript-append-origin.md)和[浏览器 transcript 决策](../bug-fix/2026-07-30-web-transcript-log-ordered-projection.md)中与进度相关的延期条款:进度显示不要求标记携带规模信息,也不要求重构替换项渲染。两份记录均保持活动状态,并继续负责基于追加来源的 transcript 投影和已落地检查点标记。[排队式手动压缩决策](2026-07-30-queued-manual-compaction.md)继续负责标记对顺序、锁定机制和陈旧未匹配标记分类。
@@ -36,12 +38,14 @@ TUI 将实时独立的 `compact/start { turn: null }` 与匹配的 `compact/end`
**使用通用的命令运行指示器。** 本行为不采用该方案,因为压缩标记对是更精确的真源,并且还覆盖非命令路径。未来若实现通用命令指示器,应归属于 `command/run` 和 `command/done` 生命周期。
**仅保留提示符光标字形。** 不予采用:该光标只是外围的单个字符单元,而缓慢压缩期间,用户的注意力主要仍停留在 transcript 上。实时 transcript 行无需创建持久会话事件,也能让同一个标记对清晰可见。
**打印包含持续时间的成功通知。** 不予采用:已落地的替换项已经提供完成标记。标记对的时间戳保留了持续时间,可供未来能够证明新增 transcript 行合理的展示方式使用。
## 后果
手动压缩在 agent 空闲时会显示正在运行,失败会直接产生警告,恢复会话时的陈旧未匹配标记绝不会显示为活动状态。指示器保持一个终端字符单元宽,并复用现有的动画、颜色和终端进度行为。
手动压缩在 agent 空闲时会同时在 transcript 与提示符中显示正在运行,失败会直接产生警告,恢复会话时的陈旧未匹配标记绝不会显示为活动状态。提示符指示器保持一个终端字符单元宽,两种显示共享现有的压缩定时器、语义调色板和终端进度生命周期。
实时状态及其定时器是额外的进程局部状态,在标记对闭合和 TUI 清理这两种情况下都会清除。按设计,这种显示状态不可重建:持久历史提供成功标记与计时事实,只有当前进程的观察才能提供运行中状态。
实时状态、实时行及其定时器是额外的进程局部状态,在标记对闭合和 TUI 清理这两种情况下都会清除。按设计,这种显示状态不可重建:持久历史提供成功标记与计时事实,只有当前进程的观察才能提供运行中状态。
包(package)级 TUI 测试固定了以下行为:独立开始事件、排除带编号的开始事件、淡出、失败警告、保留空闲状态、运行轮次优先级、存在未匹配标记时的恢复,以及定时器释放。组装后的 `queued-manual-compact` 终端场景还会在真实摘要边界保持开放期间观察到 `dsh ⊙`。
包(package)级 TUI 测试固定了以下行为:独立开始事件、旋转动画、重新固定到 transcript 尾部、排除带编号的开始事件、淡出、失败警告、保留空闲状态、运行轮次优先级、存在未匹配标记时的恢复,以及定时器释放。组装后的 `queued-manual-compact` 终端场景会在真实摘要边界保持开放期间同时观察到 `dsh ⊙` 和 `Compaction in progress…`。