hermes - 💡(How to fix) Fix Long user prompts pinned via sticky top-0 consume the whole viewport, hiding the assistant response

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

In the macOS desktop app, the most recent user prompt is pinned to the top of the conversation while the assistant's reply is read. For short prompts this works well. For a long prompt, the pinned message renders at full height and consumes most or all of the visible thread area, so the assistant response is pushed below the fold and stays mostly hidden — scrolling does not help, because the pinned message keeps re-pinning to the top.

Root Cause

The latest user message is wrapped in a sticky container in apps/desktop/src/components/assistant-ui/thread.tsx (StickyHumanMessageContainer):

sticky top-0 z-40 ... flex w-[calc(100%+2rem)] min-w-0 max-w-none overflow-visible ...

This is intentional — the virtualizer renders items as natural flex siblings specifically so position: sticky on the human bubble resolves against the scroller (see the comment in apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx). The pin itself is the desired "keep my question visible as a header" behavior.

The bug is that the sticky container and the inner bubble have no height ceiling and no internal scroll:

  • StickyHumanMessageContainer is overflow-visible with no max-height.
  • The inner bubble base class is ... overflow-hidden ... max-w-full ... with no max-h-*.

So the sticky element's height scales unbounded with prompt length. A short prompt yields a small sticky header; a long prompt yields a sticky header that fills the viewport and crowds out the response.

Code Example

sticky top-0 z-40 ... flex w-[calc(100%+2rem)] min-w-0 max-w-none overflow-visible ...

---

const bubbleContent = (
  <div className="max-h-[calc(var(--thread-viewport-height,100dvh)*0.4)] overflow-y-auto overscroll-contain">
    {/* existing attachmentRefs + UserMessageText */}
  </div>
)
RAW_BUFFERClick to expand / collapse

Summary

In the macOS desktop app, the most recent user prompt is pinned to the top of the conversation while the assistant's reply is read. For short prompts this works well. For a long prompt, the pinned message renders at full height and consumes most or all of the visible thread area, so the assistant response is pushed below the fold and stays mostly hidden — scrolling does not help, because the pinned message keeps re-pinning to the top.

Repro

  1. Open any chat in the desktop app.
  2. Send a long user prompt (~40+ lines, e.g. a big pasted spec or code block).
  3. Observe: the prompt sticks to the top at full height; the assistant's response gets a thin sliver of space underneath and is largely off-screen. Scrolling the thread does not reveal it because the prompt is position: sticky.

Expected: the pinned prompt should be height-bounded so the assistant response always has usable vertical space.

Root cause

The latest user message is wrapped in a sticky container in apps/desktop/src/components/assistant-ui/thread.tsx (StickyHumanMessageContainer):

sticky top-0 z-40 ... flex w-[calc(100%+2rem)] min-w-0 max-w-none overflow-visible ...

This is intentional — the virtualizer renders items as natural flex siblings specifically so position: sticky on the human bubble resolves against the scroller (see the comment in apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx). The pin itself is the desired "keep my question visible as a header" behavior.

The bug is that the sticky container and the inner bubble have no height ceiling and no internal scroll:

  • StickyHumanMessageContainer is overflow-visible with no max-height.
  • The inner bubble base class is ... overflow-hidden ... max-w-full ... with no max-h-*.

So the sticky element's height scales unbounded with prompt length. A short prompt yields a small sticky header; a long prompt yields a sticky header that fills the viewport and crowds out the response.

Suggested fix (minimal, low-risk)

Bound the pinned prompt's height against the thread viewport and let it scroll internally. The virtualizer already exposes --thread-viewport-height, so the cap stays correct regardless of window size or composer height (a vh/dvh cap would be wrong since the thread lives inside a panel).

In thread.tsx, wrap the user bubble body in a height-capped scroll region (~40% of the thread viewport):

const bubbleContent = (
  <div className="max-h-[calc(var(--thread-viewport-height,100dvh)*0.4)] overflow-y-auto overscroll-contain">
    {/* existing attachmentRefs + UserMessageText */}
  </div>
)

Notes:

  • The scroll must live on an inner region, because the read-only bubble is itself the edit <button> and is already overflow-hidden.
  • overscroll-contain prevents the inner scroll from chaining into the thread scroller.
  • A bottom fade when clipped would make it visually clear the prompt is scrollable rather than truncated.

Follow-up (preferred UX, separate change)

When the latest user message is pinned and exceeds a few lines, collapse it to ~3 lines with a fade and a "show more" toggle (matching common desktop chat apps). This gives the response nearly the full viewport while keeping the question visible, and avoids an inner scrollbar inside a sticky element. It needs slightly more logic (expanded state + line-clamp measurement, and the toggle must stop propagation so expanding doesn't trigger edit), so it's worth doing as a follow-up on top of the minimal cap above.

Environment

  • Hermes macOS desktop app (apps/desktop), chat built on @assistant-ui/react.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING