Skip to content

feat(infinity-ui): virtualize chat-view diffs - #85

Open
shadaj wants to merge 1 commit into
mainfrom
sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa
Open

feat(infinity-ui): virtualize chat-view diffs#85
shadaj wants to merge 1 commit into
mainfrom
sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa

Conversation

@shadaj

@shadaj shadaj commented Jul 27, 2026

Copy link
Copy Markdown
Member

Rendering every chat PatchDiff in full can cause substantial DOM bloat in sessions with many or large tool-call diffs.

Virtualize chat diffs

  • Create a stable Pierre Virtualizer in MessageList with a lazily initialized useRef.
  • Attach it to the existing chat scroll container and provide it through VirtualizerContext.
  • This makes chat PatchDiffs render as VirtualizedFileDiffs: off-screen diffs become height-preserving placeholders and materialize near the viewport.
  • Preserve the existing scroll-to-bottom and onScroll behavior by using the current scroll container rather than introducing a wrapper.
  • DiffView needs no change because CodeView already virtualizes internally.

Cover the diff path in web e2e

  • Add a reusable rap-test-servers stub edit_file RAP server that returns a production-shaped Diff display segment.
  • Add diff_tool_result_renders_diff_view, which verifies the displayScript label, added and removed diff lines, suppression of the text fallback, and a strict golden screenshot (chat-diff-result.png).

Validation

  • tsc -b
  • Prettier and cargo fmt --check
  • Clippy, including e2e-web
  • Full Playwright web e2e suite: 7/7 passing with strict 0-pixel screenshot comparison

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 27, 2026

Copy link
Copy Markdown

Deploying infinity with  Cloudflare Pages  Cloudflare Pages

Latest commit: f4ff633
Status: ✅  Deploy successful!
Preview URL: https://daf91026.infinity-dc7.pages.dev
Branch Preview URL: https://sandbox-29ea1df5-13a0-4334-8.infinity-dc7.pages.dev

View logs

@shadaj shadaj changed the title test(infinity-daemon): add web e2e test rendering a diff tool result feat(infinity-ui): virtualize chat-view diffs Jul 27, 2026
shadaj added a commit that referenced this pull request Jul 28, 2026
Previously every `PatchDiff` in the chat message list rendered its full DOM,
so sessions with many tool-call diffs bloated the DOM and slowed scrolling.

## Virtualization (`infinity-ui`)

* `MessageList` now creates Pierre's core `Virtualizer` (`@pierre/diffs`)
  in a lazily initialized `useRef` and attaches it to the existing scroll
  container via a merged callback ref (`setup()` on mount, `cleanUp()` on
  unmount). The inner content element is auto-discovered as the
  container's first child.
* The instance is provided through `VirtualizerContext`
  (`@pierre/diffs/react`), which makes every `PatchDiff` rendered in
  `MessageItem` automatically upgrade to a `VirtualizedFileDiff`:
  off-screen diffs are swapped for fixed-height placeholders and only
  re-materialized when scrolled near the viewport (default 1000px
  overscan).
* Providing the context directly (instead of wrapping in the library's
  `<Virtualizer>` component) keeps `MessageList`'s scroll container and
  its scroll-to-bottom/`onScroll` logic untouched.
* The `DiffView` side panel needed no changes — `CodeView` already
  virtualizes internally.

## E2E coverage for diff rendering

The web e2e suite never actually rendered a diff in the chat view, leaving
the `PatchDiff` path (and the new virtualization wiring) untested.

* `rap-test-servers`: add `start_stub_diff_server()`, a stub RAP server
  exposing an `edit_file` tool (with a `displayScript`) that answers with
  a `Diff` display segment. The patch is built by `stub_diff_patch()`
  exactly like sandbox-core's `build_edit_diff` (`similar` unified diff,
  context radius 3, path headers, trailing whitespace trimmed), so the
  test exercises the same wire shape as production.
* `web_e2e.rs`: new `diff_tool_result_renders_diff_view` test — the mock
  model calls `edit_file`, and the test asserts the displayScript label
  renders, the patch's added/removed lines are visible in the diff viewer
  (Playwright pierces the shadow DOM), the raw text fallback is *not*
  shown, and the page matches a new golden screenshot
  (`chat-diff-result.png`). Since the message list now provides a
  `Virtualizer` context, this covers the virtualized `PatchDiff` mount
  end to end.

Verified with `tsc -b`, prettier, clippy (incl. `e2e-web`), rustfmt, and
the full Playwright web e2e suite (7/7, strict 0-pixel screenshots).

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #85
@shadaj
shadaj force-pushed the sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa branch from 26c3456 to 029f6ec Compare July 28, 2026 00:02
Base automatically changed from sandbox-a179c018-4d8a-40c0-9a3d-9bd0926bdeff to main July 28, 2026 00:02
@shadaj
shadaj force-pushed the sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa branch from 029f6ec to 59fc787 Compare July 28, 2026 00:06
shadaj added a commit that referenced this pull request Jul 28, 2026
Previously every `PatchDiff` in the chat message list rendered its full DOM,
so sessions with many tool-call diffs bloated the DOM and slowed scrolling.

## Virtualization (`infinity-ui`)

* `MessageList` now creates Pierre's core `Virtualizer` (`@pierre/diffs`)
  in a lazily initialized `useRef` and attaches it to the existing scroll
  container via a merged callback ref (`setup()` on mount, `cleanUp()` on
  unmount). The inner content element is auto-discovered as the
  container's first child.
* The instance is provided through `VirtualizerContext`
  (`@pierre/diffs/react`), which makes every `PatchDiff` rendered in
  `MessageItem` automatically upgrade to a `VirtualizedFileDiff`:
  off-screen diffs are swapped for fixed-height placeholders and only
  re-materialized when scrolled near the viewport (default 1000px
  overscan).
* Providing the context directly (instead of wrapping in the library's
  `<Virtualizer>` component) keeps `MessageList`'s scroll container and
  its scroll-to-bottom/`onScroll` logic untouched.
* The `DiffView` side panel needed no changes — `CodeView` already
  virtualizes internally.

## E2E coverage for diff rendering

The web e2e suite never actually rendered a diff in the chat view, leaving
the `PatchDiff` path (and the new virtualization wiring) untested.

* `rap-test-servers`: add `start_stub_diff_server()`, a stub RAP server
  exposing an `edit_file` tool (with a `displayScript`) that answers with
  a `Diff` display segment. The patch is built by `stub_diff_patch()`
  exactly like sandbox-core's `build_edit_diff` (`similar` unified diff,
  context radius 3, path headers, trailing whitespace trimmed), so the
  test exercises the same wire shape as production.
* `web_e2e.rs`: new `diff_tool_result_renders_diff_view` test — the mock
  model calls `edit_file`, and the test asserts the displayScript label
  renders, the patch's added/removed lines are visible in the diff viewer
  (Playwright pierces the shadow DOM), the raw text fallback is *not*
  shown, and the page matches a new golden screenshot
  (`chat-diff-result.png`). Since the message list now provides a
  `Virtualizer` context, this covers the virtualized `PatchDiff` mount
  end to end.

Verified with `tsc -b`, prettier, clippy (incl. `e2e-web`), rustfmt, and
the full Playwright web e2e suite (7/7, strict 0-pixel screenshots).

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #85
shadaj added a commit that referenced this pull request Jul 29, 2026
Previously every `PatchDiff` in the chat message list rendered its full DOM,
so sessions with many tool-call diffs bloated the DOM and slowed scrolling.

## Virtualization (`infinity-ui`)

* `MessageList` now creates Pierre's core `Virtualizer` (`@pierre/diffs`)
  in a lazily initialized `useRef` and attaches it to the existing scroll
  container via a merged callback ref (`setup()` on mount, `cleanUp()` on
  unmount). The inner content element is auto-discovered as the
  container's first child.
* The instance is provided through `VirtualizerContext`
  (`@pierre/diffs/react`), which makes every `PatchDiff` rendered in
  `MessageItem` automatically upgrade to a `VirtualizedFileDiff`:
  off-screen diffs are swapped for fixed-height placeholders and only
  re-materialized when scrolled near the viewport (default 1000px
  overscan).
* Providing the context directly (instead of wrapping in the library's
  `<Virtualizer>` component) keeps `MessageList`'s scroll container and
  its scroll-to-bottom/`onScroll` logic untouched.
* The `DiffView` side panel needed no changes — `CodeView` already
  virtualizes internally.

## E2E coverage for diff rendering

The web e2e suite never actually rendered a diff in the chat view, leaving
the `PatchDiff` path (and the new virtualization wiring) untested.

* `rap-test-servers`: add `start_stub_diff_server()`, a stub RAP server
  exposing an `edit_file` tool (with a `displayScript`) that answers with
  a `Diff` display segment. The patch is built by `stub_diff_patch()`
  exactly like sandbox-core's `build_edit_diff` (`similar` unified diff,
  context radius 3, path headers, trailing whitespace trimmed), so the
  test exercises the same wire shape as production.
* `web_e2e.rs`: new `diff_tool_result_renders_diff_view` test — the mock
  model calls `edit_file`, and the test asserts the displayScript label
  renders, the patch's added/removed lines are visible in the diff viewer
  (Playwright pierces the shadow DOM), the raw text fallback is *not*
  shown, and the page matches a new golden screenshot
  (`chat-diff-result.png`). Since the message list now provides a
  `Virtualizer` context, this covers the virtualized `PatchDiff` mount
  end to end.

Verified with `tsc -b`, prettier, clippy (incl. `e2e-web`), rustfmt, and
the full Playwright web e2e suite (7/7, strict 0-pixel screenshots).

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #85
@shadaj
shadaj force-pushed the sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa branch from 59fc787 to c4110cf Compare July 29, 2026 00:07
Previously every `PatchDiff` in the chat message list rendered its full DOM,
so sessions with many tool-call diffs bloated the DOM and slowed scrolling.

## Virtualization (`infinity-ui`)

* `MessageList` now creates Pierre's core `Virtualizer` (`@pierre/diffs`)
  in a lazily initialized `useRef` and attaches it to the existing scroll
  container via a merged callback ref (`setup()` on mount, `cleanUp()` on
  unmount). The inner content element is auto-discovered as the
  container's first child.
* The instance is provided through `VirtualizerContext`
  (`@pierre/diffs/react`), which makes every `PatchDiff` rendered in
  `MessageItem` automatically upgrade to a `VirtualizedFileDiff`:
  off-screen diffs are swapped for fixed-height placeholders and only
  re-materialized when scrolled near the viewport (default 1000px
  overscan).
* Providing the context directly (instead of wrapping in the library's
  `<Virtualizer>` component) keeps `MessageList`'s scroll container and
  its scroll-to-bottom/`onScroll` logic untouched.
* The `DiffView` side panel needed no changes — `CodeView` already
  virtualizes internally.

## E2E coverage for diff rendering

The web e2e suite never actually rendered a diff in the chat view, leaving
the `PatchDiff` path (and the new virtualization wiring) untested.

* `rap-test-servers`: add `start_stub_diff_server()`, a stub RAP server
  exposing an `edit_file` tool (with a `displayScript`) that answers with
  a `Diff` display segment. The patch is built by `stub_diff_patch()`
  exactly like sandbox-core's `build_edit_diff` (`similar` unified diff,
  context radius 3, path headers, trailing whitespace trimmed), so the
  test exercises the same wire shape as production.
* `web_e2e.rs`: new `diff_tool_result_renders_diff_view` test — the mock
  model calls `edit_file`, and the test asserts the displayScript label
  renders, the patch's added/removed lines are visible in the diff viewer
  (Playwright pierces the shadow DOM), the raw text fallback is *not*
  shown, and the page matches a new golden screenshot
  (`chat-diff-result.png`). Since the message list now provides a
  `Virtualizer` context, this covers the virtualized `PatchDiff` mount
  end to end.

Verified with `tsc -b`, prettier, clippy (incl. `e2e-web`), rustfmt, and
the full Playwright web e2e suite (7/7, strict 0-pixel screenshots).

Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #85
@shadaj
shadaj force-pushed the sandbox-29ea1df5-13a0-4334-8a33-fa14ddc4aeaa branch from c4110cf to f4ff633 Compare July 29, 2026 22:21
@shadaj
shadaj marked this pull request as ready for review July 29, 2026 22:21
@shadaj
shadaj requested a review from a team July 29, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant