fix(desktop): stream the transcript while the window is backgrounded#42399
Merged
Conversation
The chat transcript reaches the screen through a requestAnimationFrame-gated flush (useSessionStateCache). The main BrowserWindow never set backgroundThrottling, so Chromium paused rAF and clamped timers whenever the window was blurred or occluded -- the live answer would stall until the window regained focus or the user refreshed. In practice this bit any time Hermes wasn't the focused window mid-turn (typing in your editor while the agent replies, detached devtools, another window on top), presenting as "thinking, no text, have to refresh." Opt the renderer out of background throttling so a streaming chat app actually streams in the background: - backgroundThrottling: false on the main window (matches the secondary windows that already set it) - disable-renderer-backgrounding / disable-backgrounding-occluded-windows / disable-background-timer-throttling at the process level for the occlusion case Latent since the desktop app landed (#20059), not a recent regression.
Contributor
🔎 Lint report:
|
wachoo
pushed a commit
to wachoo/hermes-agent
that referenced
this pull request
Jun 10, 2026
…ousResearch#42399) The chat transcript reaches the screen through a requestAnimationFrame-gated flush (useSessionStateCache). The main BrowserWindow never set backgroundThrottling, so Chromium paused rAF and clamped timers whenever the window was blurred or occluded -- the live answer would stall until the window regained focus or the user refreshed. In practice this bit any time Hermes wasn't the focused window mid-turn (typing in your editor while the agent replies, detached devtools, another window on top), presenting as "thinking, no text, have to refresh." Opt the renderer out of background throttling so a streaming chat app actually streams in the background: - backgroundThrottling: false on the main window (matches the secondary windows that already set it) - disable-renderer-backgrounding / disable-backgrounding-occluded-windows / disable-background-timer-throttling at the process level for the occlusion case Latent since the desktop app landed (NousResearch#20059), not a recent regression.
changman
pushed a commit
to changman/hermes-agent
that referenced
this pull request
Jun 10, 2026
…ousResearch#42399) The chat transcript reaches the screen through a requestAnimationFrame-gated flush (useSessionStateCache). The main BrowserWindow never set backgroundThrottling, so Chromium paused rAF and clamped timers whenever the window was blurred or occluded -- the live answer would stall until the window regained focus or the user refreshed. In practice this bit any time Hermes wasn't the focused window mid-turn (typing in your editor while the agent replies, detached devtools, another window on top), presenting as "thinking, no text, have to refresh." Opt the renderer out of background throttling so a streaming chat app actually streams in the background: - backgroundThrottling: false on the main window (matches the secondary windows that already set it) - disable-renderer-backgrounding / disable-backgrounding-occluded-windows / disable-background-timer-throttling at the process level for the occlusion case Latent since the desktop app landed (NousResearch#20059), not a recent regression.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The desktop chat transcript reaches the screen through a
requestAnimationFrame-gated flush (useSessionStateCache). The mainBrowserWindownever setbackgroundThrottling, so Chromium paused rAF and clamped timers whenever the window was blurred or occluded — the live answer stalled until the window regained focus or the user refreshed.In practice this bit any time Hermes wasn't the focused window mid-turn (typing in your editor while the agent replies, detached devtools, another window covering it), presenting as the recurring "thinking, no text, have to refresh" report. It resolves the instant you tab back, because rAF resumes on focus.
This is latent since the desktop app first landed (#20059) — not a regression from any recent PR. Backend event emission and renderer event routing were both verified correct (headless RPC probe + in-renderer event trace); the only broken hop was the final paint, throttled by Chromium.
Changes
apps/desktop/electron/main.cjs:backgroundThrottling: falseon the main window — matches the secondary windows in this same file that already set it.disable-renderer-backgrounding,disable-backgrounding-occluded-windows,disable-background-timer-throttling.Test plan
npm run type-checkcleanCmd+N, send a prompt, immediately click into another window; the reply streams in live while Hermes is unfocused (no refresh, no tab-back)