Repository navigation
cmux-next agent pane: render at full rate until scrolls miss frames - #16487
Conversation
AgentPaneView.rendersAtFullRate reads and sets WebKit's near-60 fps feature on the live web view's preferences, and debug.agent_pane gets a full_rate action to drive it, so the fling bench can measure whether a live switch takes effect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
Red first, with a stub that always renders at full rate. A scroll that misses frames at full rate should drop the pane to WebKit's capped rate. A clean capped scroll after a backoff should restore full rate, and the backoff should double on a quick relapse. A display already near 60 Hz should be left alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
WebKit pauses rendering in a web view whose window is covered, so a fling in a tagged build behind the user's windows got no frames. Each debug.agent_pane action now turns off the pane's window-occlusion detection (_setWindowOcclusionDetectionEnabled:, when present). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: manaflow-ai/cmux/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
#expect can't call the mutating record(...), so the frame pacing tests didn't compile. Each decision is now taken first and then checked. The stub still always renders at full rate, so the tests stay red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
AgentPaneFramePacing picks the rate from each settled scroll: - Full rate drops to WebKit's cap when more than 20% of a scroll's frames are late (over 1.5x the expected interval). - After a 10 s backoff, a capped scroll with at most 5% late frames brings full rate back. - The backoff doubles, up to 160 s, when full rate fails again within it. - A display already near 60 Hz is left alone. The page samples rAF intervals while the transcript scrolls (ScrollPacing). It sends them as pane.framePacing once the scroll has been still for 250 ms, an idle point. The model hands them to the view, which switches the live page's preference. AgentTabStore makes every pane adaptive. Debug builds can still fix the rate with CMUX_NEXT_AGENT_PANE_FULL_RATE (1 full, 0 capped). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Red at On the live switch, WebKit main's source says:
So a rate set when a scroll settles should take effect at the next visual-idle edge. A reload keeps the same This is unverified on hardware: no awake display above 60 Hz is available. The fleet minis run at 60 Hz, where capped and full are the same rate; a probe on cmux-mac-mini counted 120 frames per 2 s in every mode. Worst case, if the switch never applies live, an adaptive pane stays at the full rate it was created with. That is the same as #16471's switch on. |
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Requires human review: Auto-approval blocked because this review re-detected 2 unresolved issues already reported by Cubic.
Re-trigger cubic
…ptive-rate # Conflicts: # Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/Resources/agent-pane/index.html
The render-rate declarations had landed between close() and its doc comment. displayFramesPerSecond's doc now says what it is: the fallback when the pane has no window screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
|
Subagent review at 742521f, with checks run on 45fe16b (a base merge that changes no PR logic): LGTM.
Risk, accepted and noted in the body: if the live switch lags a scroll, the governor judges that scroll against the wrong rate, which could push backoffs toward 160 s capped. Hardening (infer the active rate from the median interval) is a follow-up once someone can dogfood at more than 60 Hz. Nits: |
CI failure attributionCI passes on Written by |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
|
Subagent review at 4d20a97: LGTM.
|
|
Live 120 Hz verification of the render-rate switch, run after merge on a fleet mini. Setup:
|
|
On the same 120 Hz virtual display, toggling the rate mid-session does nothing. I launched capped (
|
Summary
Follows #16471, per #16424. The agent pane renders at the display's full rate (160 Hz on a 160 Hz display) while scrolls keep up, and drops to WebKit's 80 Hz cap while the machine is loaded. The aim is 160 Hz on an idle machine and a steady 80 Hz under load, with no flag to dogfood.
How it works.
ScrollPacingsamples rAF intervals while the transcript scrolls. Once the scroll has been still for 250 ms, it posts them aspane.framePacing. That moment is an idle point, so a rate change never lands mid-scroll.AgentPaneFramePacingdecides the rate from those intervals:AgentPaneViewswitches WebKit'sPreferPageRenderingUpdatesNear60FPSEnabledon the live page's preferences.AgentTabStoremakes every pane adaptive. Debug builds can fix the rate withCMUX_NEXT_AGENT_PANE_FULL_RATE(1full,0capped).debug.agent_panegainsfull_rate, which reads or switches the live rate. Every action now turns off the pane's window-occlusion detection, so a tagged build can be measured behind other windows.When the live switch takes effect (unverified on hardware).
Page, so there is no reload fallback.Testing
AgentPaneFramePacingTests(swift test lane): red at25af4f2f99a, where a stub always renders at full rate; five tests fail, includingaScrollThatMissesFramesDropsToTheCappedRate. Green on the head.AgentPaneRenderingTests.anAdaptivePaneCapsItsRateAfterAScrollThatMissesFramescovers the wiring from the model through the view to the preference.AgentPaneHandshakeTestscovers decodingpane.framePacing.pacing.test.tscovers settle, report and stop.bun test src/agent-session/andtscare clean.check-concurrency,check-crash-safetyandbuild-agent-pane-web.sh --checkpass.Changelog
🤖 Generated with Claude Code
https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD