Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/wework/developer-guide/wework-e2e-automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The model protocol matrix defines 18 combinations across execution location, mod

Matrix submissions use a 10-second timeout. If the composer already displays a submission error, the runner throws that exact error immediately. Otherwise, a stalled protocol stage reports its current stage and captured requests instead of waiting through the general UI timeout.

`e2e:desktop:streaming-text` runs an isolated streaming-message state regression through a scenario module. It uses the real Tauri WebView, Executor, and Codex app-server while a loopback Responses SSE keeps a partial reply active. The test first verifies that “Thinking” appears below the visible reply, then scrolls upward while a long response continues to append, records a visible text anchor, and asserts that later streaming deltas do not move that anchor within the viewport. It also verifies that “Thinking” disappears after the response is released. The scenario retains screenshots for its ready, streaming, and completed stages; its scenario-specific Codex configuration disables plugin extensions to isolate direct message streaming.
`e2e:desktop:streaming-text` runs an isolated streaming-message state regression through a scenario module. It uses the real Tauri WebView, Executor, and Codex app-server while a loopback Responses SSE keeps a partial reply active. The scenario builds a long multi-turn conversation beyond the virtualization threshold. It first verifies that “Thinking” appears below the visible reply, then scrolls to completed history so the active response remains offscreen while it continues growing. The test waits for the list's total height to grow and asserts that the visible text anchor and `scrollTop` stay stable during streaming, after completion, and after reopening the task. It also verifies that “Thinking” disappears after the response is released. The scenario retains screenshots for its ready, streaming, and completed stages; its scenario-specific Codex configuration disables plugin extensions to isolate direct message streaming.

The main desktop flow's short-conversation layout regression stores `short-conversation-00-ready.png`, `short-conversation-01-prompt-filled.png`, `short-conversation-02-completed-top-aligned.png`, and `short-conversation-layout-metrics.json`. The final screenshot and metrics are captured after switching away and reopening the conversation. The gate requires the first message to remain within `160px` of the message viewport's top edge. For focused local diagnosis, run `node wework/e2e/desktop/task-flow.e2e.mjs --short-conversation-only`; the same check remains part of the regular `e2e:desktop` flow rather than a separate CI entrypoint.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ Conversation rendering still uses `WorkbenchMessage` values produced from transc

The desktop workbench caches at most 10 ordinary panes and evicts them in least-recently-used order. An inactive pane that is no longer running releases transcript messages, historical DOM, pagination ranges, navigation indexes, and processing expansion state; returning to it reloads from the original runtime transcript.

Tauri conversations use one `@tanstack/react-virtual` message-row virtualizer for every conversation size instead of switching implementations at a message-count threshold. The virtualizer uses `anchorTo: 'end'` to anchor the list at its end, while scroll snapshots are consistently represented as the distance from the viewport bottom to the list bottom. Its shared `ResizeObserver` measures mounted message rows. While the user remains at the bottom, height changes preserve the end distance. After the user scrolls upward, the list instead records the first visible text scroll anchor and its viewport offset, then restores that text anchor when streaming content is remeasured. This keeps bottom-follow behavior without allowing the text being read to drift upward during streaming. The rendered range keeps 2 rows of overscan on each side. Message rows no longer use `IntersectionObserver` as a second windowing layer; an individual oversized Markdown response retains independent chunk windowing to bound the DOM inside one visible message. Remaining `IntersectionObserver` usage covers independent behavior such as bottom-follow state and attachment previews.
Tauri conversations use one `@tanstack/react-virtual` message-row virtualizer for every conversation size instead of switching implementations at a message-count threshold. The virtualizer uses `anchorTo: 'end'` to anchor the list at its end, while scroll snapshots are consistently represented as the distance from the viewport bottom to the list bottom. Its shared `ResizeObserver` measures mounted message rows. An active streaming message must remain in the virtual range even when it is outside the visible range and overscan, so its growth continues to reach TanStack Virtual's measurement pipeline; otherwise, replacing its estimated height with its real height when it remounts can corrupt the historical reading position. While the user remains at the bottom, height changes preserve the end distance. After the user scrolls upward, the list instead records the first visible text scroll anchor and its viewport offset, then restores that text anchor when streaming content is remeasured. This keeps bottom-follow behavior without allowing the text being read to drift upward during streaming. The rendered range keeps 2 rows of overscan on each side. Message rows no longer use `IntersectionObserver` as a second windowing layer; an individual oversized Markdown response retains independent chunk windowing to bound the DOM inside one visible message. Remaining `IntersectionObserver` usage covers independent behavior such as bottom-follow state and attachment previews.

Each conversation stores only a bounded TanStack measurement snapshot alongside its distance-from-bottom scroll snapshot. Changes to this path must cover short and long conversations, streaming bottom-follow behavior, text-anchor stability after scrolling upward, historical-position restoration, reopen after switching away, forced mounting for turn navigation, and cache eviction when a task is archived.
Each conversation stores only a bounded TanStack measurement snapshot alongside its distance-from-bottom scroll snapshot. Changes to this path must cover short and long conversations, streaming bottom-follow behavior, continuous measurement of offscreen streaming messages, text-anchor stability after scrolling upward, historical-position restoration, reopen after switching away, forced mounting for turn navigation, and cache eviction when a task is archived.

Terminal and built-in browser sessions are stateful active resources and do not follow ordinary pane eviction. A pane remains mounted while it owns a Terminal or browser tab so its terminal process and page session survive task switches. After the corresponding resources close, the pane is subject to the ordinary cache limit again. Changes to this boundary must continue to cover ordinary-pane LRU eviction, resource-pane retention, message-row virtualization, and the desktop memory E2E.

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/wework/developer-guide/wework-e2e-automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ node e2e/utils/mock-connector-upstream-server.mjs

矩阵提交等待上限为 10 秒。如果编辑器已经显示提交错误,runner 会立即抛出该错误;否则在协议阶段未按时推进时输出当前阶段和已捕获请求,避免失败后长时间无反馈。

`e2e:desktop:streaming-text` 通过场景模块运行独立的流式消息状态回归。它使用真实 Tauri WebView、Executor 和 Codex app-server,通过 loopback Responses SSE 保持部分回复处于运行状态。场景先验证“正在思考”位于可见回复下方,再在长回复持续追加时向上滚动,记录一个可见文本锚点,断言后续流式增量不会改变该锚点的视口位置;释放响应后还会验证“正在思考”消失。该场景会保存就绪、流式和完成阶段的截图;场景专用 Codex 配置会关闭插件扩展,以隔离验证消息直出链路。
`e2e:desktop:streaming-text` 通过场景模块运行独立的流式消息状态回归。它使用真实 Tauri WebView、Executor 和 Codex app-server,通过 loopback Responses SSE 保持部分回复处于运行状态。场景会构造超过虚拟化阈值的多轮长对话,先验证“正在思考”位于可见回复下方,再滚动到已完成的历史消息,使活动响应位于屏幕外并继续增长。测试等待列表总高度真实增长,并断言当前可见文本锚点和 `scrollTop` 在流式过程、完成以及重新打开任务后都保持稳定;释放响应后还会验证“正在思考”消失。该场景会保存就绪、流式和完成阶段的截图;场景专用 Codex 配置会关闭插件扩展,以隔离验证消息直出链路。

主桌面流程的短对话布局回归会保存 `short-conversation-00-ready.png`、`short-conversation-01-prompt-filled.png`、`short-conversation-02-completed-top-aligned.png` 和 `short-conversation-layout-metrics.json`。最后一个截图和 metrics 均在切走并重新打开对话后生成;门禁要求首条消息距离消息视口顶部不超过 `160px`。本地排查该回归时可直接运行 `node wework/e2e/desktop/task-flow.e2e.mjs --short-conversation-only`,但该检查同时属于常规 `e2e:desktop` 主流程,不是独立 CI 入口。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ Debug 面板的快照会附带当前 runtime pane 的轻量内存摘要,用于

桌面工作台最多缓存 10 个普通 pane,并按最近使用顺序淘汰。非活跃且已停止运行的 pane 会释放 transcript 消息、历史 DOM、分页范围、导航索引和 processing 展开状态;再次切回时从 runtime transcript 原始数据重新加载。

Tauri 对话统一使用 `@tanstack/react-virtual` 的消息行虚拟列表,不再根据消息数量切换实现。虚拟列表通过 `anchorTo: 'end'` 以列表末端为锚点;滚动快照统一表示为“视口底部到列表底部的距离”。库内共享 `ResizeObserver` 测量已挂载消息的真实高度。用户停留在底部时,高度变化继续按末端距离补偿;用户主动向上滚动后,则记录视口内首个文本滚动锚点及其视口偏移,并在流式消息重新测量时恢复该文本锚点。这样既能保持底部自动跟随,也能避免正在阅读的文本随流式输出持续向上漂移。渲染范围在可见区前后各保留 2 条消息。消息行不再使用 `IntersectionObserver` 做第二层窗口化;单条超长 Markdown 仍保留独立的块级窗口化,以限制一个可见消息内部的 DOM 数量。其余 `IntersectionObserver` 用途包括跟随底部状态和附件预览等独立功能。
Tauri 对话统一使用 `@tanstack/react-virtual` 的消息行虚拟列表,不再根据消息数量切换实现。虚拟列表通过 `anchorTo: 'end'` 以列表末端为锚点;滚动快照统一表示为“视口底部到列表底部的距离”。库内共享 `ResizeObserver` 测量已挂载消息的真实高度。活动中的流式消息即使位于可见范围和 overscan 之外,也必须保留在虚拟 range 中,使其高度增长持续进入 TanStack Virtual 的测量;否则消息重新挂载时从估算高度切换到真实高度,会破坏历史阅读位置。用户停留在底部时,高度变化继续按末端距离补偿;用户主动向上滚动后,则记录视口内首个文本滚动锚点及其视口偏移,并在流式消息重新测量时恢复该文本锚点。这样既能保持底部自动跟随,也能避免正在阅读的文本随流式输出持续向上漂移。渲染范围在可见区前后各保留 2 条消息。消息行不再使用 `IntersectionObserver` 做第二层窗口化;单条超长 Markdown 仍保留独立的块级窗口化,以限制一个可见消息内部的 DOM 数量。其余 `IntersectionObserver` 用途包括跟随底部状态和附件预览等独立功能。

每个对话只缓存有界的 TanStack 测量快照,并与距底部滚动快照一起恢复。修改这套逻辑时,应覆盖短对话、长对话、底部流式跟随、向上滚动后的文本锚点稳定性、历史位置恢复、切换后重开、导航强制挂载和归档缓存淘汰。
每个对话只缓存有界的 TanStack 测量快照,并与距底部滚动快照一起恢复。修改这套逻辑时,应覆盖短对话、长对话、底部流式跟随、屏幕外流式消息持续测量、向上滚动后的文本锚点稳定性、历史位置恢复、切换后重开、导航强制挂载和归档缓存淘汰。

Terminal 和内置浏览器属于有状态活动资源,不跟随普通 pane 淘汰。只要 pane 中仍有 Terminal 或浏览器标签,它就保持挂载,以保留终端进程和网页会话;关闭对应资源后,该 pane 才重新受普通缓存上限约束。修改这条边界时,必须同时覆盖普通 pane 的 LRU 淘汰、资源 pane 保活、消息行虚拟化和桌面内存 E2E。

Expand Down
Loading
Loading