Skip to content

Window long-session message rendering#1666

Closed
Michaelyklam wants to merge 1 commit into
nesquena:masterfrom
Michaelyklam:fix/734-message-windowing
Closed

Window long-session message rendering#1666
Michaelyklam wants to merge 1 commit into
nesquena:masterfrom
Michaelyklam:fix/734-message-windowing

Conversation

@Michaelyklam
Copy link
Copy Markdown
Contributor

Thinking Path

  • Long Hermes WebUI sessions lag because every visible transcript message is rebuilt into the DOM.
  • Issue feat(perf): DOM windowing / message virtualization for long sessions #734 asks for DOM windowing, but the maintainer comment recommends a safer first pass before full IntersectionObserver virtualization.
  • The current code already has server-side message pagination for unloaded history; this PR adds an in-memory DOM render cap on top of that.
  • The core constraint is preserving the existing render pipeline: markdown, thinking/activity groups, tool cards, timestamps, cache, and live streaming still need to anchor to the correct raw message.
  • This PR keeps the session transcript in memory, renders the latest 50 visible messages by default, and provides a top chip to reveal earlier in-memory messages one page at a time.

Closes #734.

What Changed

  • Added a default 50-message DOM render window inside renderMessages().
  • Added a Load earlier messages (N hidden) chip above the rendered transcript window.
  • Expanding the local DOM window preserves scroll position by measuring scrollHeight before/after inserting older messages.
  • Preserved the existing server-side _loadOlderMessages() path when the current in-memory session is already fully rendered but older server-paginated messages still exist.
  • Updated assistant/tool/thinking anchoring so hidden older tool activity is not accidentally attached to the newest visible assistant turn.
  • Included render-window size in the session HTML cache key and rewired the cached load-earlier button after cache restore.
  • Added source regression coverage for window size, local load-earlier behavior, scroll preservation, streaming/tool anchoring, cache rewiring, and chip styling.
  • Added UI evidence under docs/pr-media/734/message-window-top.png.

Why It Matters

  • Long sessions get the primary performance benefit immediately: fewer transcript nodes are built and re-highlighted on initial render.
  • The implementation stays within the existing vanilla JS architecture and avoids the bigger risk of full virtual scrolling/unloading.
  • Users can still access older transcript messages explicitly without dropping session data from memory or disk.

UI media

Synthetic 121-message browser validation, showing the windowed transcript starting at message 21 with 21 earlier messages hidden:

Message windowing load-earlier chip

Verification

  • node --check static/ui.js
  • node --check static/sessions.js
  • /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_issue734_message_windowing.py tests/test_auto_compression_card.py tests/test_1325_user_fenced_code.py tests/test_ui_tool_call_cleanup.py tests/test_turn_duration_display.py tests/test_parallel_session_switch.py -q -> 79 passed
  • git diff --check
  • Browser QA on isolated local WebUI (127.0.0.1:18734) with synthetic 121-message session:
    • default render showed 50 transcript messages, first raw message index 70, latest raw index 119, and Load earlier messages (70 hidden)
    • clicking the chip expanded to 100 transcript messages, first raw index 20, latest raw index 119, and scroll restoration matched the height delta
    • appending a live assistant message kept a 100-message window, moved the first raw index to 21, and rendered the live assistant turn at raw index 120
    • screenshot stored at docs/pr-media/734/message-window-top.png; raw GitHub URL verified 200 46119
  • Full suite attempted twice locally:
    • env -u HERMES_CONFIG_PATH /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/ -q initially failed after 6m32s with unrelated harness/state failures plus source-string drift that this PR then fixed.
    • env -u HERMES_CONFIG_PATH HERMES_HOME=/tmp/hermes-webui-kanban/t_c2343b16/full-test-home HERMES_BASE_HOME=/tmp/hermes-webui-kanban/t_c2343b16/full-test-home /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/ -q ran after fixes and failed after 6m28s with test-server/HERMES_HOME mismatch and connection-refused failures in login/media/session harness tests; targeted affected suites above are green.

Risks / Follow-ups

  • This is intentionally not full virtual scrolling: older in-memory messages stay in S.messages, and the user opts into rendering earlier pages with the chip.
  • Existing server pagination still uses the previous scroll-top loader; this PR preserves it but prioritizes the explicit chip for already-loaded hidden DOM messages.
  • A future larger pass can expose the window size as a preference if maintainers want it in settings.

Model Used

  • OpenAI Codex / GPT-5.5 via Hermes Agent.
  • Tool use included git/gh CLI, pytest, Node syntax checks, browser QA, and screenshot capture.

@nesquena-hermes
Copy link
Copy Markdown
Collaborator

Closed by the v0.51.1 release in PR #1681 (merged at e23ba59). Massive thanks @Michaelyklam — this is now 19 merged PRs across the v0.50.292–v0.51.1 release window, an extraordinary contribution rate. Each PR was per-claim-vs-diff verified against your description and every security-relevant code path checked under independent review (Opus advisor, 6/6 questions clean). Your closes #N references are all accurate, your Thinking Path / What Changed / Why It Matters body template is consistently helpful, and your test coverage is solid behavioral scope (not source-string scaffolding) on every PR.

Live on production: https://github.com/nesquena/hermes-webui/releases/tag/v0.51.1

🚀

nesquena-hermes pushed a commit to Michaelyklam/hermes-webui that referenced this pull request May 5, 2026
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.

feat(perf): DOM windowing / message virtualization for long sessions

2 participants