Skip to content

feat(llm): keep provider-specific handlers attached across realtime fallback swaps - #6628

Open
biztex wants to merge 1 commit into
livekit:mainfrom
biztex:feat/fallback-child-session-handlers
Open

feat(llm): keep provider-specific handlers attached across realtime fallback swaps#6628
biztex wants to merge 1 commit into
livekit:mainfrom
biztex:feat/fallback-child-session-handlers

Conversation

@biztex

@biztex biztex commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #6556. Related: #6553 (reduces the need to isinstance-check the private class at all).

Problem

Plugin-specific realtime events (e.g. the openai plugin's openai_server_event_received / openai_client_event_queued) can only be observed on the child session of RealtimeModelFallbackAdapter — the wrapper only forwards the generic event set. When a failover swaps the child, every handler the application attached to it is silently lost. Today the workaround is isinstance-checking the private _FallbackRealtimeSession, reaching into ._active, and manually resubscribing — with no signal for when a swap happened (the issue's exact pain).

Change

A handler registry on the fallback session, so resubscription is automatic:

  • on_active_session(event, callback) — attaches to the current child and re-attaches to every child a failover or restart brings up (_bind/_unbind already run on each swap; the registry rides along). Events a child's provider never emits simply don't fire, so openai-specific handlers are inert while a different provider's model is active — exactly the "resubscribe when fallbacked to the same plugin-type model" semantics requested, with no provider bookkeeping.
  • off_active_session(event, callback) — detaches everywhere.
  • active_session property — the child currently in use, documented as replaced on swap (mirrors the naming already used by the test fakes).

Tests

Four new cases in tests/test_realtime_fallback.py on the existing fake-model harness: the property exposes the live child; a registered handler receives events from both the pre-swap and post-swap child; off_active_session detaches across swaps; and the direct-attachment failure mode is documented by contrast.

Happy to adjust naming/shape — on_active_session was chosen to make the "re-attached on swap" semantics part of the name.

…allback swaps

Plugin-specific realtime events (e.g. the openai plugin''s
openai_server_event_received) can only be observed on the child session, but
a failover closes that child and brings up a new one - silently dropping
every handler the application attached. Users had to isinstance-check the
private _FallbackRealtimeSession and resubscribe by hand, with no signal for
when a swap happened.

Add a handler registry to the fallback session:

- on_active_session(event, callback): attaches to the current child and
  re-attaches automatically to every child a failover or restart brings up.
  Events a child''s provider never emits simply don''t fire, so handlers stay
  inert while a different provider''s model is active.
- off_active_session(event, callback): detaches everywhere.
- active_session property: the child currently in use, documented as
  replaced on swap.

Fixes livekit#6556
@biztex
biztex requested a review from a team as a code owner July 30, 2026 16:28

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant