mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-04 17:57:28 +08:00
Sticky prompt: The loop was skipping `first` (the first row in the viewport) when looking for a user message scrolled above the top edge. If `first` itself was a user row that had just ticked above the viewport, we'd fall through the early-return guard (`role === 'user' && !above`), then walk from `first - 1` backward — never rechecking `first`, never finding anything, returning '' and leaving the sticky empty. This is why it felt "stuck" at the start: one-turn sessions with the user row exactly at/near the top never surfaced the breadcrumb. Collapsed the two branches into one loop starting at `first`: nearest user wins — still-on-screen → empty (redundant to echo), already above → text. Same semantics, covers the gap. Scrollbar: `useSyncExternalStore` snapshot was `scrollTop:vp:scrollHeight` — scrollHeight ticks up by ~1 row on every streamed chunk, forcing a re-render per chunk. Quantized snapshot to the displayed values (`thumbTop:thumbSize:vp`) so we only re-render when the bar actually changes. Drops render count per turn by ~100x during streaming and stops the "constantly resizes" flicker.