fix(rtmg/web): re-send the active loop band on reconnect#288
Open
seanhanca wants to merge 1 commit into
Open
Conversation
After an automatic reconnect (network blip), the active loop band was silently dropped server-side. The reconnect success callback in useStartSession re-applies detected metadata, the LoRA catalog/cap, the network monitor, and timbre/structure refs via restoreRefs — but never re-sent the loop band. The band is NOT part of buildConfig, and the only other caller of sendLoopBand is WaveformScrubBox's sync effect, which doesn't re-run on reconnect (the AudioPlayer persists and loopBand is unchanged). So the fresh RemoteBackend never learned the band: the worklet kept looping locally while the new server decoded against the full timeline → drift / stale loop at the seam. Mirror the established "re-apply session state on reconnect" pattern (restoreRefs): add restoreLoopBand(remote), which reads the source-of-truth performance store and, when a band is active (gate matches WaveformScrubBox exactly), re-sends it via the existing sendLoopBand SDK method. Call it right after restoreRefs in the WsReconnector success callback. Extends the reconnect test to assert sendLoopBand is invoked with the active region after a reconnect, and is NOT called when no band is set, when the band is armed-but-off, or when the region is sub-50ms. Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Root cause (confirmed)
After an automatic reconnect (network blip), the active loop band is silently dropped server-side.
The
WsReconnectorsuccess callback indemos/realtime_motion_graph_web/web/hooks/useStartSession.tsre-applies detected metadata, the LoRA catalog/cap/strengths, the network monitor, and timbre/structure refs (await restoreRefs(remote)), but never re-sends the loop band:buildConfig(useStartSession.tsbuildConfig, ~L100-136) — it carries prompts, LoRAs, fixture, source mode, client id, but no band.remote.sendLoopBand(...)is theWaveformScrubBoxsync effect (components/Performance/WaveformScrubBox.tsx~L361-384), which depends on[bandState, bandLoopEnabled, hasPlayer, player]. On reconnect theAudioPlayerpersists andloopBand/bandLoopEnabledare unchanged, so the effect does not re-run.Result: the new
RemoteBackendnever learns the band. The worklet keeps looping the region locally while the new server session decodes against the full timeline → drift / a stale loop window at the seam.sendLoopBandis a real SDK method (packages/demon-client/protocol.ts~L1070), so the fix is wire-supported.Fix
Mirror the established "re-apply session state on reconnect" pattern (
restoreRefs):restoreLoopBand(remote)next torestoreRefs. It reads the source-of-truth performance store (usePerformanceStoreloopBand/bandLoopEnabled) and, when a band is active, re-sends it viaremote.sendLoopBand(start, end).WaveformScrubBoxexactly (band != null && bandLoopEnabled && end-start >= 0.05 && start >= 0) so we only re-send a band the listener is actually hearing loop.await restoreRefs(remote)in theWsReconnectorsuccess callback.No new subsystem; ~30 lines including doc comment, following the same extracted-function shape as
restoreRefs.No regression
Extended
tests/unit/wsReconnect.test.tswith arestoreLoopBand on reconnectblock asserting:Verification
Run in
demos/realtime_motion_graph_web/web/:npx vitest run tests/unit/wsReconnect.test.ts→ 11 passed (7 existing + 4 new).npm run typecheck→ clean (exit 0).npm run build→ compiled successfully (exit 0).(The full
tests/unitrun shows 8 pre-existing failures insliceEpoch.test.tsdue toMath.f16round is not a functionon this Node build — unrelated to this change; the touched test file passes.)Made with Cursor