Skip to content

Commit 12b69cb

Browse files
authored
Add explicit failure when agent disconnects from the room (#1228)
1 parent eaebee8 commit 12b69cb

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

.changeset/spicy-heads-smoke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@livekit/components-react': patch
3+
---
4+
5+
Add explicit failure when agent disconnects from the room

packages/react/src/hooks/useAgent.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
446446
emitter.emit(AgentEvent.MicrophoneChanged, audioTrack);
447447
}, [emitter, audioTrack]);
448448

449+
// Listen for room connection state updates
449450
const [roomConnectionState, setRoomConnectionState] = React.useState(room.state);
450451
React.useEffect(() => {
451452
const handleConnectionStateChanged = (connectionState: ConnectionState) => {
@@ -458,6 +459,37 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
458459
};
459460
}, [room]);
460461

462+
// If the agent participant disconnects in the middle of a conversation unexpectedly, mark that as an explicit failure
463+
const [agentDisconnectedFailureReason, setAgentDisconnectedFailureReason] = React.useState<
464+
string | null
465+
>(null);
466+
React.useEffect(() => {
467+
if (!agentParticipant) {
468+
return;
469+
}
470+
471+
const onParticipantDisconnect = (participant: RemoteParticipant) => {
472+
if (participant.identity !== agentParticipant?.identity) {
473+
return;
474+
}
475+
setAgentDisconnectedFailureReason('Agent left the room unexpectedly.');
476+
};
477+
478+
room.on(RoomEvent.ParticipantDisconnected, onParticipantDisconnect);
479+
480+
return () => {
481+
room.off(RoomEvent.ParticipantDisconnected, onParticipantDisconnect);
482+
};
483+
}, [agentParticipant, room]);
484+
485+
React.useEffect(() => {
486+
if (roomConnectionState !== ConnectionState.Disconnected) {
487+
return;
488+
}
489+
// Clear the agent disconnect failure state when the room disconnects
490+
setAgentDisconnectedFailureReason(null);
491+
}, [roomConnectionState]);
492+
461493
const [localMicTrack, setLocalMicTrack] = React.useState<LocalTrackPublication | null>(
462494
() => room.localParticipant.getTrackPublication(Track.Source.Microphone) ?? null,
463495
);
@@ -490,8 +522,15 @@ export function useAgent(session?: SessionStub): UseAgentReturn {
490522
}, [room.localParticipant]);
491523

492524
const failureReasons = React.useMemo(() => {
493-
return agentTimeoutFailureReason ? [agentTimeoutFailureReason] : [];
494-
}, [agentTimeoutFailureReason]);
525+
const reasons = [];
526+
if (agentTimeoutFailureReason) {
527+
reasons.push(agentTimeoutFailureReason);
528+
}
529+
if (agentDisconnectedFailureReason) {
530+
reasons.push(agentDisconnectedFailureReason);
531+
}
532+
return reasons;
533+
}, [agentTimeoutFailureReason, agentDisconnectedFailureReason]);
495534

496535
const state = React.useMemo(() => {
497536
if (failureReasons.length > 0) {

0 commit comments

Comments
 (0)