Repository navigation
feat(voice): send session_closed to the remote session when the session closes - #8099
Merged
Merged
Conversation
This was referenced Oct 23, 2026
Merged
u9g
force-pushed
the
feat/session-closed-event
branch
from
November 3, 2026 22:36
9fc5b20 to
a7ba97a
Compare
theomonnom
reviewed
Nov 4, 2026
Comment on lines
+555
to
+563
| if job_ctx.simulation_context() is not None and self._room is job_ctx.room: | ||
| # the simulator asks for on_simulation_end over this room after the session | ||
| # closes; the job deletes it only once that wait is over | ||
| async def _delete_room_on_shutdown() -> None: | ||
| await job_ctx.delete_room(room_name=self._room.name) | ||
|
|
||
| job_ctx.add_shutdown_callback(_delete_room_on_shutdown) | ||
| job_ctx.shutdown(reason=ev.reason.value) | ||
| return |
Member
There was a problem hiding this comment.
Can we consolidate both path?
The delete after session close vs delete after job_ctx close?
Member
There was a problem hiding this comment.
Tho mb it's a breaking change?
theomonnom
approved these changes
Nov 4, 2026
u9g
force-pushed
the
feat/session-closed-event
branch
from
November 4, 2026 23:06
6d506bb to
4a9c292
Compare
This was referenced Nov 4, 2026
…on closes A client learns the call is over from the session itself rather than from the agent leaving the room.
Split event unhooking out of aclose into unregister_session, let register_session replace the attached session, and expose it. Request handling captures the session once per request and finalize_simulation moves into its own method. No behavior change.
…outlives the session The SessionHost is now owned by the job rather than the AgentSession: the primary session attaches on start and detaches on close, and the job closes the host during shutdown. Under a simulation, shutdown keeps the host serving until the simulator finalizes, leaves, or session_end_timeout passes, so on_simulation_end still runs when the agent ends the call. While no session is attached, session requests fail with "no active session" instead of being dropped; finalize_simulation needs only the job and is answered either way.
…ssion_closed comes first
…s to send A finalize_simulation reply that the transport can't deliver left wait_for_simulation_finalized() pending, so job shutdown sat out the whole session_end_timeout unless the simulator happened to leave the room.
u9g
marked this pull request as ready for review
November 5, 2026 00:34
u9g
force-pushed
the
feat/session-closed-event
branch
from
November 5, 2026 00:34
4a9c292 to
a9038ed
Compare
u9g
force-pushed
the
feat/session-closed-event
branch
from
November 5, 2026 00:34
a9038ed to
47b70d0
Compare
A session restarted in another room reused the job's host, whose transport is bound to the job's room, so nothing in the new room could reach it. The job owns the host only so the simulator can finalize over the job's room; a session anywhere else owns its own host.
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.
What
SessionHostnow sends asession_closedevent (livekit/protocol#1888) to itsRemoteSessionclient when the attachedAgentSessioncloses. The event carries the session'sCloseReasonand its error, if there is one.RemoteSessionemits it assession_closed.Why
Today a client learns the call ended only when the agent leaves the room. #7986, stacked on this PR, keeps the host up for the whole job so the agent can still be asked for its
on_simulation_endverdict after it hangs up. That keeps the agent in the room, so the simulator needs this event to know the call is over.The event is safe to ship before the simulator reads it, because current clients ignore unknown events. Shipping it first means that by the time #7986 is released, the simulator already handles agents that stay in the room.
Blocked on
livekit/protocol#1888 being released in
livekit-protocol. This PR will then raiselivekit-protocol>=inlivekit-agents/pyproject.tomlto that version. It's a draft until then.Verification
tests/test_session_host.py: the host subscribes toclose, and_on_closesendssession_closedwith the mapped reason. ruff and mypy are clean. The tests were run against Python bindings generated locally from the protocol branch.Parity: livekit/agents-js needs the same event (tracked with livekit/agents-js#2793).