polite-furniture-24847
07/24/2025, 3:33 AMtall-airline-16756
07/24/2025, 3:33 AMtall-airline-16756
07/24/2025, 3:34 AMroom.disconnect() // Triggers DisconnectReason.CLIENT_INITIATED
• Server-initiated disconnections: These can be triggered by server actions such as:
◦ Calling RoomService.RemoveParticipant (results in PARTICIPANT_REMOVED)
◦ Calling RoomService.DeleteRoom (results in ROOM_DELETED)
◦ Server shutdown (results in SERVER_SHUTDOWN)
Retrieving Disconnect Reasons
1. Through Room Events:
◦ JavaScript/TypeScript: room.on('disconnected', (reason) => {
console.log('Disconnected with reason:', reason);
});
◦ Go SDK: roomCallback := &lksdk.RoomCallback{
OnDisconnectedWithReason: func(reason lksdk.DisconnectionReason) {
fmt.Printf("Disconnected: %s\n", reason)
},
}
1. Through Participant Properties:
◦ Python SDK: disconnect_reason = participant.disconnect_reason
if disconnect_reason is not None:
print(f"Participant disconnected: {disconnect_reason}")
◦ Rust SDK: let reason = participant.disconnect_reason();
Available Disconnect ReasonsThe following disconnect reasons are available:
• UNKNOWN_REASON (0)
• CLIENT_INITIATED (1)
• DUPLICATE_IDENTITY (2)
• SERVER_SHUTDOWN (3)
• PARTICIPANT_REMOVED (4)
• ROOM_DELETED (5)
• STATE_MISMATCH (6)
• JOIN_FAILURE (7)
• MIGRATION (8)
• SIGNAL_CLOSE (9)
• ROOM_CLOSED (10)
• USER_UNAVAILABLE (11)
• USER_REJECTED (12)
• SIP_TRUNK_FAILURE (13)
• CONNECTION_TIMEOUT (14)
• MEDIA_FAILURE (15)
Let me know if you need further details on implementing this in a specific SDK.
Sources: livekit/src/room/participant/mod.rs | packages/livekit-rtc/src/proto/room_pb.ts | livekit-android-test/src/test/java/io/livekit/android/room/RoomMockE2ETest.... | agent-console/lib/event-types.ts | callback.gopolite-furniture-24847
07/24/2025, 3:41 AMtall-airline-16756
07/24/2025, 3:42 AMfrom livekit.rtc import Participant
# Get disconnect reason from a participant
reason = participant.disconnect_reason
if reason is not None:
print(f"Participant disconnected with reason: {reason}")
There are quite a few reasons why someone might disconnect, like:
• CLIENT_INITIATED - they chose to leave
• DUPLICATE_IDENTITY - someone else with the same identity joined
• SERVER_SHUTDOWN - the server is taking a quick break
• PARTICIPANT_REMOVED - someone removed the participant
• ROOM_DELETED - the room got closed
• STATE_MISMATCH - a little connection hiccup
• JOIN_FAILURE - trouble connecting fully
• And some SIP-related reasons like USER_UNAVAILABLE, USER_REJECTED, and SIP_TRUNK_FAILURE
2. Using Agent Session Close Events: Want to catch those disconnect moments? Here's a friendly way to do it:
from livekit.agents import AgentSession, CloseEvent
@session.on("close")
def on_close(ev: CloseEvent):
print(f"Agent Session closed, reason: {ev.reason}")
# Handle the disconnect reason as needed
Triggering Disconnections 1. Agent Shutdown: Need to disconnect an agent? Here's a smooth way to do it:
async def entrypoint(ctx: JobContext):
# do some work
...
# disconnect from the room
ctx.shutdown(reason="Session ended")
2. Session Close from Agent: Sometimes you just need to wrap things up:
class MyAgent(Agent):
@llm.function_tool
async def close_session(self):
"""Called when user wants to leave the conversation"""
<http://logger.info|logger.info>("Closing session from function tool")
await self.session.generate_reply(instructions="say goodbye to the user")
# Close the session
self._closing_task = asyncio.create_task(self.session.aclose())
Got questions? I'm here to help! Feel free to reach out if anything's unclear or you need more details. Sources: livekit-protocol/livekit/protocol/models.pyi | examples/voice_agents/session_close_callback.py | Job lifecycle | LiveKit Docs