Skip to content

fix(desktop): stream the transcript while the window is backgrounded#42399

Merged
OutThisLife merged 1 commit into
mainfrom
bb/desktop-bg-throttle-stream
Jun 8, 2026
Merged

fix(desktop): stream the transcript while the window is backgrounded#42399
OutThisLife merged 1 commit into
mainfrom
bb/desktop-bg-throttle-stream

Conversation

@OutThisLife

Copy link
Copy Markdown
Collaborator

Summary

The desktop 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 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: false on the main window — matches the secondary windows in this same file that already set it.
  • Process-level switches for the occlusion path: disable-renderer-backgrounding, disable-backgrounding-occluded-windows, disable-background-timer-throttling.

Test plan

  • npm run type-check clean
  • Full restart of the app (Electron main-process change — HMR does not pick it up)
  • Cmd+N, send a prompt, immediately click into another window; the reply streams in live while Hermes is unfocused (no refresh, no tab-back)

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.
@OutThisLife OutThisLife merged commit 09a6a2d into main Jun 8, 2026
15 checks passed
@OutThisLife OutThisLife deleted the bb/desktop-bg-throttle-stream branch June 8, 2026 22:01
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: bb/desktop-bg-throttle-stream vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10525 on HEAD, 10525 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5529 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

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.
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