@werxt/livekit-components-react 2.9.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +36 -0
- package/dist/assets/icons/CameraDisabledIcon.d.ts +11 -0
- package/dist/assets/icons/CameraDisabledIcon.d.ts.map +1 -0
- package/dist/assets/icons/CameraIcon.d.ts +11 -0
- package/dist/assets/icons/CameraIcon.d.ts.map +1 -0
- package/dist/assets/icons/ChatCloseIcon.d.ts +11 -0
- package/dist/assets/icons/ChatCloseIcon.d.ts.map +1 -0
- package/dist/assets/icons/ChatIcon.d.ts +11 -0
- package/dist/assets/icons/ChatIcon.d.ts.map +1 -0
- package/dist/assets/icons/Chevron.d.ts +11 -0
- package/dist/assets/icons/Chevron.d.ts.map +1 -0
- package/dist/assets/icons/FocusToggleIcon.d.ts +11 -0
- package/dist/assets/icons/FocusToggleIcon.d.ts.map +1 -0
- package/dist/assets/icons/GearIcon.d.ts +11 -0
- package/dist/assets/icons/GearIcon.d.ts.map +1 -0
- package/dist/assets/icons/LeaveIcon.d.ts +11 -0
- package/dist/assets/icons/LeaveIcon.d.ts.map +1 -0
- package/dist/assets/icons/LockLockedIcon.d.ts +11 -0
- package/dist/assets/icons/LockLockedIcon.d.ts.map +1 -0
- package/dist/assets/icons/MicDisabledIcon.d.ts +11 -0
- package/dist/assets/icons/MicDisabledIcon.d.ts.map +1 -0
- package/dist/assets/icons/MicIcon.d.ts +11 -0
- package/dist/assets/icons/MicIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityExcellentIcon.d.ts +11 -0
- package/dist/assets/icons/QualityExcellentIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityGoodIcon.d.ts +11 -0
- package/dist/assets/icons/QualityGoodIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityPoorIcon.d.ts +11 -0
- package/dist/assets/icons/QualityPoorIcon.d.ts.map +1 -0
- package/dist/assets/icons/QualityUnknownIcon.d.ts +11 -0
- package/dist/assets/icons/QualityUnknownIcon.d.ts.map +1 -0
- package/dist/assets/icons/ScreenShareIcon.d.ts +11 -0
- package/dist/assets/icons/ScreenShareIcon.d.ts.map +1 -0
- package/dist/assets/icons/ScreenShareStopIcon.d.ts +11 -0
- package/dist/assets/icons/ScreenShareStopIcon.d.ts.map +1 -0
- package/dist/assets/icons/SpinnerIcon.d.ts +11 -0
- package/dist/assets/icons/SpinnerIcon.d.ts.map +1 -0
- package/dist/assets/icons/UnfocusToggleIcon.d.ts +11 -0
- package/dist/assets/icons/UnfocusToggleIcon.d.ts.map +1 -0
- package/dist/assets/icons/index.d.ts +20 -0
- package/dist/assets/icons/index.d.ts.map +1 -0
- package/dist/assets/icons/util.d.ts +11 -0
- package/dist/assets/icons/util.d.ts.map +1 -0
- package/dist/assets/images/ParticipantPlaceholder.d.ts +11 -0
- package/dist/assets/images/ParticipantPlaceholder.d.ts.map +1 -0
- package/dist/assets/images/index.d.ts +2 -0
- package/dist/assets/images/index.d.ts.map +1 -0
- package/dist/components/ChatEntry.d.ts +35 -0
- package/dist/components/ChatEntry.d.ts.map +1 -0
- package/dist/components/ConnectionState.d.ts +23 -0
- package/dist/components/ConnectionState.d.ts.map +1 -0
- package/dist/components/ConnectionStateToast.d.ts +13 -0
- package/dist/components/ConnectionStateToast.d.ts.map +1 -0
- package/dist/components/LiveKitRoom.d.ts +92 -0
- package/dist/components/LiveKitRoom.d.ts.map +1 -0
- package/dist/components/ParticipantLoop.d.ts +28 -0
- package/dist/components/ParticipantLoop.d.ts.map +1 -0
- package/dist/components/RoomAudioRenderer.d.ts +29 -0
- package/dist/components/RoomAudioRenderer.d.ts.map +1 -0
- package/dist/components/RoomName.d.ts +20 -0
- package/dist/components/RoomName.d.ts.map +1 -0
- package/dist/components/SessionProvider.d.ts +13 -0
- package/dist/components/SessionProvider.d.ts.map +1 -0
- package/dist/components/Toast.d.ts +14 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/TrackLoop.d.ts +26 -0
- package/dist/components/TrackLoop.d.ts.map +1 -0
- package/dist/components/controls/ChatToggle.d.ts +19 -0
- package/dist/components/controls/ChatToggle.d.ts.map +1 -0
- package/dist/components/controls/ClearPinButton.d.ts +20 -0
- package/dist/components/controls/ClearPinButton.d.ts.map +1 -0
- package/dist/components/controls/DisconnectButton.d.ts +19 -0
- package/dist/components/controls/DisconnectButton.d.ts.map +1 -0
- package/dist/components/controls/FocusToggle.d.ts +21 -0
- package/dist/components/controls/FocusToggle.d.ts.map +1 -0
- package/dist/components/controls/MediaDeviceSelect.d.ts +40 -0
- package/dist/components/controls/MediaDeviceSelect.d.ts.map +1 -0
- package/dist/components/controls/PaginationControl.d.ts +9 -0
- package/dist/components/controls/PaginationControl.d.ts.map +1 -0
- package/dist/components/controls/PaginationIndicator.d.ts +7 -0
- package/dist/components/controls/PaginationIndicator.d.ts.map +1 -0
- package/dist/components/controls/SettingsMenuToggle.d.ts +13 -0
- package/dist/components/controls/SettingsMenuToggle.d.ts.map +1 -0
- package/dist/components/controls/StartAudio.d.ts +24 -0
- package/dist/components/controls/StartAudio.d.ts.map +1 -0
- package/dist/components/controls/StartMediaButton.d.ts +22 -0
- package/dist/components/controls/StartMediaButton.d.ts.map +1 -0
- package/dist/components/controls/TrackToggle.d.ts +32 -0
- package/dist/components/controls/TrackToggle.d.ts.map +1 -0
- package/dist/components/index.d.ts +30 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/layout/CarouselLayout.d.ts +27 -0
- package/dist/components/layout/CarouselLayout.d.ts.map +1 -0
- package/dist/components/layout/FocusLayout.d.ts +25 -0
- package/dist/components/layout/FocusLayout.d.ts.map +1 -0
- package/dist/components/layout/GridLayout.d.ts +26 -0
- package/dist/components/layout/GridLayout.d.ts.map +1 -0
- package/dist/components/layout/LayoutContextProvider.d.ts +12 -0
- package/dist/components/layout/LayoutContextProvider.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +4 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/participant/AudioTrack.d.ts +33 -0
- package/dist/components/participant/AudioTrack.d.ts.map +1 -0
- package/dist/components/participant/AudioVisualizer.d.ts +22 -0
- package/dist/components/participant/AudioVisualizer.d.ts.map +1 -0
- package/dist/components/participant/BarVisualizer.d.ts +77 -0
- package/dist/components/participant/BarVisualizer.d.ts.map +1 -0
- package/dist/components/participant/ConnectionQualityIndicator.d.ts +16 -0
- package/dist/components/participant/ConnectionQualityIndicator.d.ts.map +1 -0
- package/dist/components/participant/ParticipantAudioTile.d.ts +14 -0
- package/dist/components/participant/ParticipantAudioTile.d.ts.map +1 -0
- package/dist/components/participant/ParticipantName.d.ts +17 -0
- package/dist/components/participant/ParticipantName.d.ts.map +1 -0
- package/dist/components/participant/ParticipantTile.d.ts +49 -0
- package/dist/components/participant/ParticipantTile.d.ts.map +1 -0
- package/dist/components/participant/TrackMutedIndicator.d.ts +19 -0
- package/dist/components/participant/TrackMutedIndicator.d.ts.map +1 -0
- package/dist/components/participant/VideoTrack.d.ts +23 -0
- package/dist/components/participant/VideoTrack.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/connectingSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/connectingSequence.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/listeningSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/listeningSequence.d.ts.map +1 -0
- package/dist/components/participant/animationSequences/thinkingSequence.d.ts +2 -0
- package/dist/components/participant/animationSequences/thinkingSequence.d.ts.map +1 -0
- package/dist/components/participant/animators/useBarAnimator.d.ts +3 -0
- package/dist/components/participant/animators/useBarAnimator.d.ts.map +1 -0
- package/dist/components-lNrIMTWQ.mjs +1051 -0
- package/dist/components-lNrIMTWQ.mjs.map +1 -0
- package/dist/context/chat-context.d.ts +23 -0
- package/dist/context/chat-context.d.ts.map +1 -0
- package/dist/context/feature-context.d.ts +14 -0
- package/dist/context/feature-context.d.ts.map +1 -0
- package/dist/context/index.d.ts +10 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/layout-context.d.ts +32 -0
- package/dist/context/layout-context.d.ts.map +1 -0
- package/dist/context/participant-context.d.ts +22 -0
- package/dist/context/participant-context.d.ts.map +1 -0
- package/dist/context/pin-context.d.ts +17 -0
- package/dist/context/pin-context.d.ts.map +1 -0
- package/dist/context/room-context.d.ts +22 -0
- package/dist/context/room-context.d.ts.map +1 -0
- package/dist/context/session-context.d.ts +22 -0
- package/dist/context/session-context.d.ts.map +1 -0
- package/dist/context/track-reference-context.d.ts +25 -0
- package/dist/context/track-reference-context.d.ts.map +1 -0
- package/dist/contexts-D4V9wQRc.mjs +4026 -0
- package/dist/contexts-D4V9wQRc.mjs.map +1 -0
- package/dist/hooks/cloud/krisp/useKrispNoiseFilter.d.ts +42 -0
- package/dist/hooks/cloud/krisp/useKrispNoiseFilter.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +54 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/internal/index.d.ts +10 -0
- package/dist/hooks/internal/index.d.ts.map +1 -0
- package/dist/hooks/internal/useMediaQuery.d.ts +7 -0
- package/dist/hooks/internal/useMediaQuery.d.ts.map +1 -0
- package/dist/hooks/internal/useObservableState.d.ts +6 -0
- package/dist/hooks/internal/useObservableState.d.ts.map +1 -0
- package/dist/hooks/internal/useResizeObserver.d.ts +14 -0
- package/dist/hooks/internal/useResizeObserver.d.ts.map +1 -0
- package/dist/hooks/useAgent.d.ts +219 -0
- package/dist/hooks/useAgent.d.ts.map +1 -0
- package/dist/hooks/useAudioPlayback.d.ts +15 -0
- package/dist/hooks/useAudioPlayback.d.ts.map +1 -0
- package/dist/hooks/useChat.d.ts +43 -0
- package/dist/hooks/useChat.d.ts.map +1 -0
- package/dist/hooks/useChatToggle.d.ts +21 -0
- package/dist/hooks/useChatToggle.d.ts.map +1 -0
- package/dist/hooks/useClearPinButton.d.ts +15 -0
- package/dist/hooks/useClearPinButton.d.ts.map +1 -0
- package/dist/hooks/useConnectionQualityIndicator.d.ts +20 -0
- package/dist/hooks/useConnectionQualityIndicator.d.ts.map +1 -0
- package/dist/hooks/useConnectionStatus.d.ts +12 -0
- package/dist/hooks/useConnectionStatus.d.ts.map +1 -0
- package/dist/hooks/useDataChannel.d.ts +38 -0
- package/dist/hooks/useDataChannel.d.ts.map +1 -0
- package/dist/hooks/useDisconnectButton.d.ts +21 -0
- package/dist/hooks/useDisconnectButton.d.ts.map +1 -0
- package/dist/hooks/useEvents.d.ts +9 -0
- package/dist/hooks/useEvents.d.ts.map +1 -0
- package/dist/hooks/useFacingMode.d.ts +10 -0
- package/dist/hooks/useFacingMode.d.ts.map +1 -0
- package/dist/hooks/useFocusToggle.d.ts +26 -0
- package/dist/hooks/useFocusToggle.d.ts.map +1 -0
- package/dist/hooks/useGridLayout.d.ts +27 -0
- package/dist/hooks/useGridLayout.d.ts.map +1 -0
- package/dist/hooks/useIsEncrypted.d.ts +12 -0
- package/dist/hooks/useIsEncrypted.d.ts.map +1 -0
- package/dist/hooks/useIsMuted.d.ts +22 -0
- package/dist/hooks/useIsMuted.d.ts.map +1 -0
- package/dist/hooks/useIsRecording.d.ts +11 -0
- package/dist/hooks/useIsRecording.d.ts.map +1 -0
- package/dist/hooks/useIsSpeaking.d.ts +11 -0
- package/dist/hooks/useIsSpeaking.d.ts.map +1 -0
- package/dist/hooks/useLiveKitRoom.d.ts +19 -0
- package/dist/hooks/useLiveKitRoom.d.ts.map +1 -0
- package/dist/hooks/useLocalParticipant.d.ts +29 -0
- package/dist/hooks/useLocalParticipant.d.ts.map +1 -0
- package/dist/hooks/useLocalParticipantPermissions.d.ts +12 -0
- package/dist/hooks/useLocalParticipantPermissions.d.ts.map +1 -0
- package/dist/hooks/useMediaDeviceSelect.d.ts +41 -0
- package/dist/hooks/useMediaDeviceSelect.d.ts.map +1 -0
- package/dist/hooks/useMediaDevices.d.ts +15 -0
- package/dist/hooks/useMediaDevices.d.ts.map +1 -0
- package/dist/hooks/useMediaTrackBySourceOrName.d.ts +18 -0
- package/dist/hooks/useMediaTrackBySourceOrName.d.ts.map +1 -0
- package/dist/hooks/usePagination.d.ts +24 -0
- package/dist/hooks/usePagination.d.ts.map +1 -0
- package/dist/hooks/useParticipantAttributes.d.ts +30 -0
- package/dist/hooks/useParticipantAttributes.d.ts.map +1 -0
- package/dist/hooks/useParticipantInfo.d.ts +21 -0
- package/dist/hooks/useParticipantInfo.d.ts.map +1 -0
- package/dist/hooks/useParticipantPermissions.d.ts +17 -0
- package/dist/hooks/useParticipantPermissions.d.ts.map +1 -0
- package/dist/hooks/useParticipantTile.d.ts +22 -0
- package/dist/hooks/useParticipantTile.d.ts.map +1 -0
- package/dist/hooks/useParticipantTracks.d.ts +14 -0
- package/dist/hooks/useParticipantTracks.d.ts.map +1 -0
- package/dist/hooks/useParticipants.d.ts +30 -0
- package/dist/hooks/useParticipants.d.ts.map +1 -0
- package/dist/hooks/usePersistentUserChoices.d.ts +35 -0
- package/dist/hooks/usePersistentUserChoices.d.ts.map +1 -0
- package/dist/hooks/usePinnedTracks.d.ts +14 -0
- package/dist/hooks/usePinnedTracks.d.ts.map +1 -0
- package/dist/hooks/useRemoteParticipant.d.ts +35 -0
- package/dist/hooks/useRemoteParticipant.d.ts.map +1 -0
- package/dist/hooks/useRemoteParticipants.d.ts +30 -0
- package/dist/hooks/useRemoteParticipants.d.ts.map +1 -0
- package/dist/hooks/useRoomInfo.d.ts +21 -0
- package/dist/hooks/useRoomInfo.d.ts.map +1 -0
- package/dist/hooks/useSequentialRoomConnectDisconnect.d.ts +27 -0
- package/dist/hooks/useSequentialRoomConnectDisconnect.d.ts.map +1 -0
- package/dist/hooks/useSession.d.ts +130 -0
- package/dist/hooks/useSession.d.ts.map +1 -0
- package/dist/hooks/useSessionMessages.d.ts +29 -0
- package/dist/hooks/useSessionMessages.d.ts.map +1 -0
- package/dist/hooks/useSettingsToggle.d.ts +20 -0
- package/dist/hooks/useSettingsToggle.d.ts.map +1 -0
- package/dist/hooks/useSortedParticipants.d.ts +7 -0
- package/dist/hooks/useSortedParticipants.d.ts.map +1 -0
- package/dist/hooks/useSpeakingParticipants.d.ts +16 -0
- package/dist/hooks/useSpeakingParticipants.d.ts.map +1 -0
- package/dist/hooks/useStartAudio.d.ts +27 -0
- package/dist/hooks/useStartAudio.d.ts.map +1 -0
- package/dist/hooks/useStartVideo.d.ts +26 -0
- package/dist/hooks/useStartVideo.d.ts.map +1 -0
- package/dist/hooks/useSwipe.d.ts +24 -0
- package/dist/hooks/useSwipe.d.ts.map +1 -0
- package/dist/hooks/useTextStream.d.ts +20 -0
- package/dist/hooks/useTextStream.d.ts.map +1 -0
- package/dist/hooks/useToken.d.ts +20 -0
- package/dist/hooks/useToken.d.ts.map +1 -0
- package/dist/hooks/useTrack.d.ts +4 -0
- package/dist/hooks/useTrack.d.ts.map +1 -0
- package/dist/hooks/useTrackByName.d.ts +10 -0
- package/dist/hooks/useTrackByName.d.ts.map +1 -0
- package/dist/hooks/useTrackMutedIndicator.d.ts +18 -0
- package/dist/hooks/useTrackMutedIndicator.d.ts.map +1 -0
- package/dist/hooks/useTrackRefBySourceOrName.d.ts +7 -0
- package/dist/hooks/useTrackRefBySourceOrName.d.ts.map +1 -0
- package/dist/hooks/useTrackSyncTime.d.ts +10 -0
- package/dist/hooks/useTrackSyncTime.d.ts.map +1 -0
- package/dist/hooks/useTrackToggle.d.ts +27 -0
- package/dist/hooks/useTrackToggle.d.ts.map +1 -0
- package/dist/hooks/useTrackTranscription.d.ts +26 -0
- package/dist/hooks/useTrackTranscription.d.ts.map +1 -0
- package/dist/hooks/useTrackVolume.d.ts +49 -0
- package/dist/hooks/useTrackVolume.d.ts.map +1 -0
- package/dist/hooks/useTracks.d.ts +29 -0
- package/dist/hooks/useTracks.d.ts.map +1 -0
- package/dist/hooks/useTranscriptions.d.ts +21 -0
- package/dist/hooks/useTranscriptions.d.ts.map +1 -0
- package/dist/hooks/useVisualStableUpdate.d.ts +27 -0
- package/dist/hooks/useVisualStableUpdate.d.ts.map +1 -0
- package/dist/hooks/useVoiceAssistant.d.ts +43 -0
- package/dist/hooks/useVoiceAssistant.d.ts.map +1 -0
- package/dist/hooks/useWarnAboutMissingStyles.d.ts +5 -0
- package/dist/hooks/useWarnAboutMissingStyles.d.ts.map +1 -0
- package/dist/hooks-hQJmeINB.mjs +1992 -0
- package/dist/hooks-hQJmeINB.mjs.map +1 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.mjs +64 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.docs.d.ts +6 -0
- package/dist/index.docs.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +157 -0
- package/dist/index.mjs.map +1 -0
- package/dist/krisp.d.ts +2 -0
- package/dist/krisp.js +2 -0
- package/dist/krisp.js.map +1 -0
- package/dist/krisp.mjs +45 -0
- package/dist/krisp.mjs.map +1 -0
- package/dist/mergeProps.d.ts +25 -0
- package/dist/mergeProps.d.ts.map +1 -0
- package/dist/prefabs/AudioConference.d.ts +22 -0
- package/dist/prefabs/AudioConference.d.ts.map +1 -0
- package/dist/prefabs/Chat.d.ts +35 -0
- package/dist/prefabs/Chat.d.ts.map +1 -0
- package/dist/prefabs/ControlBar.d.ts +45 -0
- package/dist/prefabs/ControlBar.d.ts.map +1 -0
- package/dist/prefabs/MediaDeviceMenu.d.ts +36 -0
- package/dist/prefabs/MediaDeviceMenu.d.ts.map +1 -0
- package/dist/prefabs/PreJoin.d.ts +59 -0
- package/dist/prefabs/PreJoin.d.ts.map +1 -0
- package/dist/prefabs/VideoConference.d.ts +35 -0
- package/dist/prefabs/VideoConference.d.ts.map +1 -0
- package/dist/prefabs/VoiceAssistantControlBar.d.ts +32 -0
- package/dist/prefabs/VoiceAssistantControlBar.d.ts.map +1 -0
- package/dist/prefabs/index.d.ts +8 -0
- package/dist/prefabs/index.d.ts.map +1 -0
- package/dist/prefabs.d.ts +2 -0
- package/dist/prefabs.js +2 -0
- package/dist/prefabs.js.map +1 -0
- package/dist/prefabs.mjs +579 -0
- package/dist/prefabs.mjs.map +1 -0
- package/dist/room-BP3SCCCd.mjs +191 -0
- package/dist/room-BP3SCCCd.mjs.map +1 -0
- package/dist/shared-88J2fzv7.js +2 -0
- package/dist/shared-88J2fzv7.js.map +1 -0
- package/dist/shared-BDr0qLg4.js +4 -0
- package/dist/shared-BDr0qLg4.js.map +1 -0
- package/dist/shared-CjI_UuOX.js +2 -0
- package/dist/shared-CjI_UuOX.js.map +1 -0
- package/dist/shared-DTHOl3uJ.js +2 -0
- package/dist/shared-DTHOl3uJ.js.map +1 -0
- package/dist/utils.d.ts +19 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +104 -0
- package/src/assets/icons/CameraDisabledIcon.tsx +15 -0
- package/src/assets/icons/CameraIcon.tsx +14 -0
- package/src/assets/icons/ChatCloseIcon.tsx +17 -0
- package/src/assets/icons/ChatIcon.tsx +25 -0
- package/src/assets/icons/Chevron.tsx +19 -0
- package/src/assets/icons/FocusToggleIcon.tsx +16 -0
- package/src/assets/icons/GearIcon.tsx +19 -0
- package/src/assets/icons/LeaveIcon.tsx +25 -0
- package/src/assets/icons/LockLockedIcon.tsx +19 -0
- package/src/assets/icons/MicDisabledIcon.tsx +15 -0
- package/src/assets/icons/MicIcon.tsx +19 -0
- package/src/assets/icons/QualityExcellentIcon.tsx +15 -0
- package/src/assets/icons/QualityGoodIcon.tsx +19 -0
- package/src/assets/icons/QualityPoorIcon.tsx +20 -0
- package/src/assets/icons/QualityUnknownIcon.tsx +17 -0
- package/src/assets/icons/ScreenShareIcon.tsx +25 -0
- package/src/assets/icons/ScreenShareStopIcon.tsx +21 -0
- package/src/assets/icons/SpinnerIcon.tsx +93 -0
- package/src/assets/icons/UnfocusToggleIcon.tsx +16 -0
- package/src/assets/icons/index.ts +19 -0
- package/src/assets/icons/util.tsx +47 -0
- package/src/assets/images/ParticipantPlaceholder.tsx +31 -0
- package/src/assets/images/index.ts +1 -0
- package/src/assets/template.js +21 -0
- package/src/components/ChatEntry.tsx +112 -0
- package/src/components/ConnectionState.tsx +36 -0
- package/src/components/ConnectionStateToast.tsx +47 -0
- package/src/components/LiveKitRoom.tsx +122 -0
- package/src/components/ParticipantLoop.tsx +41 -0
- package/src/components/RoomAudioRenderer.tsx +57 -0
- package/src/components/RoomName.tsx +36 -0
- package/src/components/SessionProvider.tsx +22 -0
- package/src/components/Toast.tsx +18 -0
- package/src/components/TrackLoop.tsx +45 -0
- package/src/components/controls/ChatToggle.tsx +32 -0
- package/src/components/controls/ClearPinButton.tsx +32 -0
- package/src/components/controls/DisconnectButton.tsx +32 -0
- package/src/components/controls/FocusToggle.tsx +54 -0
- package/src/components/controls/MediaDeviceSelect.tsx +144 -0
- package/src/components/controls/PaginationControl.tsx +51 -0
- package/src/components/controls/PaginationIndicator.tsx +26 -0
- package/src/components/controls/SettingsMenuToggle.tsx +26 -0
- package/src/components/controls/StartAudio.tsx +40 -0
- package/src/components/controls/StartMediaButton.tsx +41 -0
- package/src/components/controls/TrackToggle.tsx +54 -0
- package/src/components/index.ts +34 -0
- package/src/components/layout/CarouselLayout.tsx +80 -0
- package/src/components/layout/FocusLayout.tsx +37 -0
- package/src/components/layout/GridLayout.tsx +63 -0
- package/src/components/layout/LayoutContextProvider.tsx +36 -0
- package/src/components/layout/index.ts +3 -0
- package/src/components/participant/AudioTrack.tsx +89 -0
- package/src/components/participant/AudioVisualizer.tsx +67 -0
- package/src/components/participant/BarVisualizer.tsx +164 -0
- package/src/components/participant/ConnectionQualityIndicator.tsx +36 -0
- package/src/components/participant/ParticipantAudioTile.tsx +67 -0
- package/src/components/participant/ParticipantName.tsx +50 -0
- package/src/components/participant/ParticipantTile.tsx +192 -0
- package/src/components/participant/TrackMutedIndicator.tsx +53 -0
- package/src/components/participant/VideoTrack.tsx +92 -0
- package/src/components/participant/animationSequences/connectingSequence.ts +9 -0
- package/src/components/participant/animationSequences/listeningSequence.ts +6 -0
- package/src/components/participant/animationSequences/thinkingSequence.ts +12 -0
- package/src/components/participant/animators/useBarAnimator.ts +55 -0
- package/src/context/chat-context.ts +37 -0
- package/src/context/feature-context.ts +28 -0
- package/src/context/index.ts +27 -0
- package/src/context/layout-context.ts +72 -0
- package/src/context/participant-context.ts +44 -0
- package/src/context/pin-context.ts +27 -0
- package/src/context/room-context.ts +42 -0
- package/src/context/session-context.ts +43 -0
- package/src/context/track-reference-context.ts +47 -0
- package/src/hooks/cloud/krisp/useKrispNoiseFilter.ts +110 -0
- package/src/hooks/index.ts +72 -0
- package/src/hooks/internal/index.ts +10 -0
- package/src/hooks/internal/useMediaQuery.ts +46 -0
- package/src/hooks/internal/useObservableState.ts +24 -0
- package/src/hooks/internal/useResizeObserver.ts +124 -0
- package/src/hooks/useAgent.ts +945 -0
- package/src/hooks/useAudioPlayback.ts +34 -0
- package/src/hooks/useChat.ts +57 -0
- package/src/hooks/useChatToggle.ts +38 -0
- package/src/hooks/useClearPinButton.ts +29 -0
- package/src/hooks/useConnectionQualityIndicator.ts +33 -0
- package/src/hooks/useConnectionStatus.ts +22 -0
- package/src/hooks/useDataChannel.ts +73 -0
- package/src/hooks/useDisconnectButton.ts +36 -0
- package/src/hooks/useEvents.ts +39 -0
- package/src/hooks/useFacingMode.ts +22 -0
- package/src/hooks/useFocusToggle.ts +59 -0
- package/src/hooks/useGridLayout.ts +44 -0
- package/src/hooks/useIsEncrypted.ts +29 -0
- package/src/hooks/useIsMuted.ts +51 -0
- package/src/hooks/useIsRecording.ts +23 -0
- package/src/hooks/useIsSpeaking.ts +21 -0
- package/src/hooks/useLiveKitRoom.ts +186 -0
- package/src/hooks/useLocalParticipant.ts +73 -0
- package/src/hooks/useLocalParticipantPermissions.ts +24 -0
- package/src/hooks/useMediaDeviceSelect.ts +81 -0
- package/src/hooks/useMediaDevices.ts +28 -0
- package/src/hooks/useMediaTrackBySourceOrName.ts +97 -0
- package/src/hooks/usePagination.test.ts +77 -0
- package/src/hooks/usePagination.ts +67 -0
- package/src/hooks/useParticipantAttributes.ts +69 -0
- package/src/hooks/useParticipantInfo.ts +35 -0
- package/src/hooks/useParticipantPermissions.ts +29 -0
- package/src/hooks/useParticipantTile.ts +81 -0
- package/src/hooks/useParticipantTracks.ts +54 -0
- package/src/hooks/useParticipants.ts +42 -0
- package/src/hooks/usePersistentUserChoices.ts +64 -0
- package/src/hooks/usePinnedTracks.ts +24 -0
- package/src/hooks/useRemoteParticipant.ts +79 -0
- package/src/hooks/useRemoteParticipants.ts +45 -0
- package/src/hooks/useRoomInfo.ts +32 -0
- package/src/hooks/useSequentialRoomConnectDisconnect.ts +171 -0
- package/src/hooks/useSession.ts +642 -0
- package/src/hooks/useSessionMessages.ts +158 -0
- package/src/hooks/useSettingsToggle.ts +32 -0
- package/src/hooks/useSortedParticipants.ts +20 -0
- package/src/hooks/useSpeakingParticipants.ts +27 -0
- package/src/hooks/useStartAudio.ts +50 -0
- package/src/hooks/useStartVideo.ts +49 -0
- package/src/hooks/useSwipe.ts +68 -0
- package/src/hooks/useTextStream.ts +35 -0
- package/src/hooks/useToken.ts +54 -0
- package/src/hooks/useTrack.ts +11 -0
- package/src/hooks/useTrackByName.ts +15 -0
- package/src/hooks/useTrackMutedIndicator.ts +44 -0
- package/src/hooks/useTrackRefBySourceOrName.ts +30 -0
- package/src/hooks/useTrackSyncTime.ts +18 -0
- package/src/hooks/useTrackToggle.ts +93 -0
- package/src/hooks/useTrackTranscription.ts +75 -0
- package/src/hooks/useTrackVolume.ts +283 -0
- package/src/hooks/useTracks.test.ts +60 -0
- package/src/hooks/useTracks.ts +154 -0
- package/src/hooks/useTranscriptions.ts +48 -0
- package/src/hooks/useVisualStableUpdate.ts +63 -0
- package/src/hooks/useVoiceAssistant.ts +109 -0
- package/src/hooks/useWarnAboutMissingStyles.ts +11 -0
- package/src/index.docs.ts +12 -0
- package/src/index.ts +32 -0
- package/src/mergeProps.ts +87 -0
- package/src/prefabs/AudioConference.tsx +57 -0
- package/src/prefabs/Chat.tsx +153 -0
- package/src/prefabs/ControlBar.tsx +227 -0
- package/src/prefabs/MediaDeviceMenu.tsx +159 -0
- package/src/prefabs/PreJoin.tsx +439 -0
- package/src/prefabs/VideoConference.tsx +184 -0
- package/src/prefabs/VoiceAssistantControlBar.tsx +109 -0
- package/src/prefabs/index.ts +11 -0
- package/src/utils.ts +78 -0
|
@@ -0,0 +1,945 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConnectionState,
|
|
3
|
+
LocalTrackPublication,
|
|
4
|
+
ParticipantEvent,
|
|
5
|
+
ParticipantKind,
|
|
6
|
+
RemoteParticipant,
|
|
7
|
+
RoomEvent,
|
|
8
|
+
Track,
|
|
9
|
+
Participant,
|
|
10
|
+
} from 'livekit-client';
|
|
11
|
+
import type TypedEventEmitter from 'typed-emitter';
|
|
12
|
+
import { EventEmitter } from 'events';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import { ParticipantAgentAttributes, TrackReference } from '@livekit/components-core';
|
|
15
|
+
|
|
16
|
+
import { useParticipantTracks } from './useParticipantTracks';
|
|
17
|
+
import { useRemoteParticipants } from './useRemoteParticipants';
|
|
18
|
+
import { UseSessionReturn } from './useSession';
|
|
19
|
+
import { useMaybeSessionContext } from '../context';
|
|
20
|
+
import { useParticipantInfo } from './useParticipantInfo';
|
|
21
|
+
|
|
22
|
+
// FIXME: make this 10 seconds once room dispatch booting info is discoverable
|
|
23
|
+
const DEFAULT_AGENT_CONNECT_TIMEOUT_MILLISECONDS = 20_000;
|
|
24
|
+
|
|
25
|
+
/** @see https://github.com/livekit/agents/blob/65170238db197f62f479eb7aaef1c0e18bfad6e7/livekit-agents/livekit/agents/voice/events.py#L97 */
|
|
26
|
+
type AgentSdkStates = 'initializing' | 'idle' | 'listening' | 'thinking' | 'speaking';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* State representing the current status of the agent, whether it is ready for speach, etc
|
|
30
|
+
*
|
|
31
|
+
* For most agents (which have the preconnect audio buffer feature enabled), this is the lifecycle:
|
|
32
|
+
* connecting ➡️ pre-connect-buffering ➡️ initializing/listening/thinking/speaking
|
|
33
|
+
*
|
|
34
|
+
* For agents without the preconnect audio feature enabled:
|
|
35
|
+
* connecting ➡️ initializing ➡️ idle/listening/thinking/speaking
|
|
36
|
+
*
|
|
37
|
+
* If an agent fails to connect:
|
|
38
|
+
* connecting ➡️ pre-connect-buffering/initializing ➡️ failed
|
|
39
|
+
*
|
|
40
|
+
* Legacy useVoiceAssistant hook:
|
|
41
|
+
* disconnected ➡️ connecting ➡️ initializing ➡️ listening/thinking/speaking
|
|
42
|
+
*
|
|
43
|
+
* @beta
|
|
44
|
+
* */
|
|
45
|
+
export type AgentState =
|
|
46
|
+
| 'disconnected'
|
|
47
|
+
| 'connecting'
|
|
48
|
+
| 'pre-connect-buffering'
|
|
49
|
+
| 'failed'
|
|
50
|
+
| AgentSdkStates;
|
|
51
|
+
|
|
52
|
+
/** @beta */
|
|
53
|
+
export enum AgentEvent {
|
|
54
|
+
CameraChanged = 'cameraChanged',
|
|
55
|
+
MicrophoneChanged = 'microphoneChanged',
|
|
56
|
+
StateChanged = 'stateChanged',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @beta */
|
|
60
|
+
export type AgentCallbacks = {
|
|
61
|
+
[AgentEvent.CameraChanged]: (newTrack: TrackReference | undefined) => void;
|
|
62
|
+
[AgentEvent.MicrophoneChanged]: (newTrack: TrackReference | undefined) => void;
|
|
63
|
+
[AgentEvent.StateChanged]: (newAgentState: AgentState) => void;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type AgentStateCommon = {
|
|
67
|
+
// FIXME: maybe add some sort of schema to this?
|
|
68
|
+
attributes: Participant['attributes'];
|
|
69
|
+
|
|
70
|
+
internal: {
|
|
71
|
+
emitter: TypedEventEmitter<AgentCallbacks>;
|
|
72
|
+
|
|
73
|
+
agentParticipant: RemoteParticipant | null;
|
|
74
|
+
workerParticipant: RemoteParticipant | null;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
type AgentStateAvailable = AgentStateCommon & {
|
|
79
|
+
state: 'listening' | 'thinking' | 'speaking';
|
|
80
|
+
failureReasons: null;
|
|
81
|
+
|
|
82
|
+
/** The agent's assigned identity, coming from the JWT token. */
|
|
83
|
+
identity: Participant['identity'];
|
|
84
|
+
name: Participant['name'];
|
|
85
|
+
metadata: Participant['metadata'];
|
|
86
|
+
|
|
87
|
+
/** Is the agent connected to the client? */
|
|
88
|
+
isConnected: true;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Could the client be listening for user speech?
|
|
92
|
+
*
|
|
93
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
94
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
95
|
+
* */
|
|
96
|
+
canListen: true;
|
|
97
|
+
|
|
98
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
99
|
+
isFinished: false;
|
|
100
|
+
|
|
101
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
102
|
+
isPending: false;
|
|
103
|
+
|
|
104
|
+
cameraTrack?: TrackReference;
|
|
105
|
+
microphoneTrack?: TrackReference;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
type AgentStatePreConnectBuffering = AgentStateCommon & {
|
|
109
|
+
state: 'pre-connect-buffering';
|
|
110
|
+
failureReasons: null;
|
|
111
|
+
|
|
112
|
+
/** The client's assigned identity, coming from the JWT token. */
|
|
113
|
+
identity: Participant['identity'];
|
|
114
|
+
name: Participant['name'];
|
|
115
|
+
metadata: Participant['metadata'];
|
|
116
|
+
|
|
117
|
+
/** Is the agent connected to the client? */
|
|
118
|
+
isConnected: false;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Could the client be listening for user speech?
|
|
122
|
+
*
|
|
123
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
124
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
125
|
+
* */
|
|
126
|
+
canListen: true;
|
|
127
|
+
|
|
128
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
129
|
+
isFinished: false;
|
|
130
|
+
|
|
131
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
132
|
+
isPending: false;
|
|
133
|
+
|
|
134
|
+
cameraTrack?: TrackReference;
|
|
135
|
+
microphoneTrack?: TrackReference;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
type AgentStateUnAvailable = AgentStateCommon & {
|
|
139
|
+
state: 'initializing' | 'idle';
|
|
140
|
+
failureReasons: null;
|
|
141
|
+
|
|
142
|
+
/** The client's assigned identity, coming from the JWT token. */
|
|
143
|
+
identity: Participant['identity'];
|
|
144
|
+
name: Participant['name'];
|
|
145
|
+
metadata: Participant['metadata'];
|
|
146
|
+
|
|
147
|
+
/** Is the agent connected to the client? */
|
|
148
|
+
isConnected: false;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Could the client be listening for user speech?
|
|
152
|
+
*
|
|
153
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
154
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
155
|
+
* */
|
|
156
|
+
canListen: false;
|
|
157
|
+
|
|
158
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
159
|
+
isFinished: false;
|
|
160
|
+
|
|
161
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
162
|
+
isPending: true;
|
|
163
|
+
|
|
164
|
+
cameraTrack?: TrackReference;
|
|
165
|
+
microphoneTrack?: TrackReference;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
type AgentStateConnecting = AgentStateCommon & {
|
|
169
|
+
state: 'connecting';
|
|
170
|
+
failureReasons: null;
|
|
171
|
+
|
|
172
|
+
/** The client's assigned identity, coming from the JWT token. */
|
|
173
|
+
identity: undefined;
|
|
174
|
+
name: undefined;
|
|
175
|
+
metadata: undefined;
|
|
176
|
+
|
|
177
|
+
/** Is the agent connected to the client? */
|
|
178
|
+
isConnected: false;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Could the client be listening for user speech?
|
|
182
|
+
*
|
|
183
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
184
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
185
|
+
* */
|
|
186
|
+
canListen: false;
|
|
187
|
+
|
|
188
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
189
|
+
isFinished: false;
|
|
190
|
+
|
|
191
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
192
|
+
isPending: true;
|
|
193
|
+
|
|
194
|
+
cameraTrack: undefined;
|
|
195
|
+
microphoneTrack: undefined;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
type AgentStateDisconnected = AgentStateCommon & {
|
|
199
|
+
state: 'disconnected';
|
|
200
|
+
failureReasons: null;
|
|
201
|
+
|
|
202
|
+
/** The client's assigned identity, coming from the JWT token. */
|
|
203
|
+
identity: undefined;
|
|
204
|
+
name: undefined;
|
|
205
|
+
metadata: undefined;
|
|
206
|
+
|
|
207
|
+
/** Is the agent connected to the client? */
|
|
208
|
+
isConnected: false;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Could the client be listening for user speech?
|
|
212
|
+
*
|
|
213
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
214
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
215
|
+
* */
|
|
216
|
+
canListen: false;
|
|
217
|
+
|
|
218
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
219
|
+
isFinished: true;
|
|
220
|
+
|
|
221
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
222
|
+
isPending: false;
|
|
223
|
+
|
|
224
|
+
cameraTrack: undefined;
|
|
225
|
+
microphoneTrack: undefined;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
type AgentStateFailed = AgentStateCommon & {
|
|
229
|
+
state: 'failed';
|
|
230
|
+
failureReasons: Array<string>;
|
|
231
|
+
|
|
232
|
+
/** The client's assigned identity, coming from the JWT token. */
|
|
233
|
+
identity: undefined;
|
|
234
|
+
name: undefined;
|
|
235
|
+
metadata: undefined;
|
|
236
|
+
|
|
237
|
+
/** Is the agent connected to the client? */
|
|
238
|
+
isConnected: false;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Could the client be listening for user speech?
|
|
242
|
+
*
|
|
243
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
244
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
245
|
+
* */
|
|
246
|
+
canListen: false;
|
|
247
|
+
|
|
248
|
+
/** Has the client disconnected from the agent either for an expected or unexpected reason? */
|
|
249
|
+
isFinished: true;
|
|
250
|
+
|
|
251
|
+
/** Is the agent currently connecting or setting itself up? */
|
|
252
|
+
isPending: false;
|
|
253
|
+
|
|
254
|
+
cameraTrack: undefined;
|
|
255
|
+
microphoneTrack: undefined;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
type AgentActions = {
|
|
259
|
+
/** Returns a promise that resolves once the agent is connected and available for user input */
|
|
260
|
+
waitUntilConnected: (signal?: AbortSignal) => Promise<void>;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Returns a promise that resolves once the client could be listening for user speech (`canListen` is true)
|
|
264
|
+
*
|
|
265
|
+
* Note that this may not mean that the agent is actually connected - the audio pre-connect
|
|
266
|
+
* buffer could be active and recording user input before the agent actually connects.
|
|
267
|
+
* */
|
|
268
|
+
waitUntilCouldBeListening: (signal?: AbortSignal) => Promise<void>;
|
|
269
|
+
|
|
270
|
+
/** Returns a promise that resolves once the client has disconnected from the agent either for an expected or unexpected reason. */
|
|
271
|
+
waitUntilFinished: (signal?: AbortSignal) => Promise<void>;
|
|
272
|
+
|
|
273
|
+
/** Returns a promise that resolves once the agent has published a camera track */
|
|
274
|
+
waitUntilCamera: (signal?: AbortSignal) => Promise<TrackReference>;
|
|
275
|
+
|
|
276
|
+
/** Returns a promise that resolves once the agent has published a microphone track */
|
|
277
|
+
waitUntilMicrophone: (signal?: AbortSignal) => Promise<TrackReference>;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
type AgentStateCases =
|
|
281
|
+
| AgentStateConnecting
|
|
282
|
+
| AgentStateDisconnected
|
|
283
|
+
| AgentStateAvailable
|
|
284
|
+
| AgentStatePreConnectBuffering
|
|
285
|
+
| AgentStateUnAvailable
|
|
286
|
+
| AgentStateFailed;
|
|
287
|
+
|
|
288
|
+
/** @beta */
|
|
289
|
+
export type UseAgentReturn = AgentStateCases & AgentActions;
|
|
290
|
+
|
|
291
|
+
const generateDerivedStateValues = <State extends AgentState>(state: State) =>
|
|
292
|
+
({
|
|
293
|
+
isConnected: state === 'listening' || state === 'thinking' || state === 'speaking',
|
|
294
|
+
canListen:
|
|
295
|
+
state === 'pre-connect-buffering' ||
|
|
296
|
+
state === 'listening' ||
|
|
297
|
+
state === 'thinking' ||
|
|
298
|
+
state === 'speaking',
|
|
299
|
+
isFinished: state === 'disconnected' || state === 'failed',
|
|
300
|
+
isPending: state === 'connecting' || state === 'initializing' || state === 'idle',
|
|
301
|
+
}) as {
|
|
302
|
+
isConnected: State extends 'listening' | 'thinking' | 'speaking' ? true : false;
|
|
303
|
+
canListen: State extends 'pre-connect-buffering' | 'listening' | 'thinking' | 'speaking'
|
|
304
|
+
? true
|
|
305
|
+
: false;
|
|
306
|
+
isFinished: State extends 'disconnected' | 'failed' ? true : false;
|
|
307
|
+
isPending: State extends 'connecting' | 'initializing' | 'idle' ? true : false;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/** Internal hook used by useSession to store global agent state */
|
|
311
|
+
export const useAgentTimeoutIdStore = (): {
|
|
312
|
+
agentTimeoutFailureReason: string | null;
|
|
313
|
+
startAgentTimeout: (agentConnectTimeoutMilliseconds?: number) => void;
|
|
314
|
+
clearAgentTimeout: () => void;
|
|
315
|
+
clearAgentTimeoutFailureReason: () => void;
|
|
316
|
+
updateAgentTimeoutState: (agentState: AgentState) => void;
|
|
317
|
+
updateAgentTimeoutParticipantExists: (agentParticipantExists: boolean) => void;
|
|
318
|
+
} => {
|
|
319
|
+
const [agentTimeoutFailureReason, setAgentTimeoutFailureReason] = React.useState<string | null>(
|
|
320
|
+
null,
|
|
321
|
+
);
|
|
322
|
+
const [agentTimeoutId, setAgentTimeoutId] = React.useState<ReturnType<typeof setTimeout> | null>(
|
|
323
|
+
null,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
const agentStateRef = React.useRef<AgentState>('connecting');
|
|
327
|
+
const agentParticipantExistsRef = React.useRef(false);
|
|
328
|
+
|
|
329
|
+
const startAgentConnectedTimeout = (agentConnectTimeoutMilliseconds?: number) => {
|
|
330
|
+
return setTimeout(() => {
|
|
331
|
+
if (!agentParticipantExistsRef.current) {
|
|
332
|
+
setAgentTimeoutFailureReason('Agent did not join the room.');
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const { isConnected } = generateDerivedStateValues(agentStateRef.current);
|
|
337
|
+
if (!isConnected) {
|
|
338
|
+
setAgentTimeoutFailureReason('Agent joined the room but did not complete initializing.');
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
}, agentConnectTimeoutMilliseconds ?? DEFAULT_AGENT_CONNECT_TIMEOUT_MILLISECONDS);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
return {
|
|
345
|
+
agentTimeoutFailureReason,
|
|
346
|
+
startAgentTimeout: React.useCallback(
|
|
347
|
+
(agentConnectTimeoutMilliseconds?: number) => {
|
|
348
|
+
if (agentTimeoutId) {
|
|
349
|
+
clearTimeout(agentTimeoutId);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
setAgentTimeoutFailureReason(null);
|
|
353
|
+
setAgentTimeoutId(startAgentConnectedTimeout(agentConnectTimeoutMilliseconds));
|
|
354
|
+
agentStateRef.current = 'connecting';
|
|
355
|
+
agentParticipantExistsRef.current = false;
|
|
356
|
+
},
|
|
357
|
+
[agentTimeoutId],
|
|
358
|
+
),
|
|
359
|
+
clearAgentTimeout: React.useCallback(() => {
|
|
360
|
+
if (agentTimeoutId) {
|
|
361
|
+
clearTimeout(agentTimeoutId);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
setAgentTimeoutFailureReason(null);
|
|
365
|
+
setAgentTimeoutId(null);
|
|
366
|
+
agentStateRef.current = 'connecting';
|
|
367
|
+
agentParticipantExistsRef.current = false;
|
|
368
|
+
}, [agentTimeoutId]),
|
|
369
|
+
clearAgentTimeoutFailureReason: React.useCallback(() => {
|
|
370
|
+
setAgentTimeoutFailureReason(null);
|
|
371
|
+
}, []),
|
|
372
|
+
|
|
373
|
+
updateAgentTimeoutState: React.useCallback((agentState: AgentState) => {
|
|
374
|
+
agentStateRef.current = agentState;
|
|
375
|
+
}, []),
|
|
376
|
+
updateAgentTimeoutParticipantExists: React.useCallback((agentParticipantExists: boolean) => {
|
|
377
|
+
agentParticipantExistsRef.current = agentParticipantExists;
|
|
378
|
+
}, []),
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
type SessionStub = Pick<UseSessionReturn, 'connectionState' | 'room' | 'internal'>;
|
|
383
|
+
|
|
384
|
+
/** Internal hook used by useAgent which generates a function that when called, will return a
|
|
385
|
+
* promise which resolves when agent.isAvailable is enabled. */
|
|
386
|
+
function useAgentWaitUntilDerivedStates(
|
|
387
|
+
emitter: TypedEventEmitter<AgentCallbacks>,
|
|
388
|
+
state: AgentState,
|
|
389
|
+
) {
|
|
390
|
+
const stateRef = React.useRef(state);
|
|
391
|
+
React.useEffect(() => {
|
|
392
|
+
stateRef.current = state;
|
|
393
|
+
}, [state]);
|
|
394
|
+
|
|
395
|
+
const waitUntilConnected = React.useCallback(
|
|
396
|
+
async (signal?: AbortSignal) => {
|
|
397
|
+
const { isConnected } = generateDerivedStateValues(stateRef.current);
|
|
398
|
+
if (isConnected) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return new Promise<void>((resolve, reject) => {
|
|
403
|
+
const stateChangedHandler = (state: AgentState) => {
|
|
404
|
+
const { isConnected } = generateDerivedStateValues(state);
|
|
405
|
+
if (!isConnected) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
cleanup();
|
|
409
|
+
resolve();
|
|
410
|
+
};
|
|
411
|
+
const abortHandler = () => {
|
|
412
|
+
cleanup();
|
|
413
|
+
reject(new Error('useAgent(/* ... */).waitUntilConnected - signal aborted'));
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const cleanup = () => {
|
|
417
|
+
emitter.off(AgentEvent.StateChanged, stateChangedHandler);
|
|
418
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
emitter.on(AgentEvent.StateChanged, stateChangedHandler);
|
|
422
|
+
signal?.addEventListener('abort', abortHandler);
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
[emitter],
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
const waitUntilCouldBeListening = React.useCallback(
|
|
429
|
+
async (signal?: AbortSignal) => {
|
|
430
|
+
const { canListen } = generateDerivedStateValues(stateRef.current);
|
|
431
|
+
if (canListen) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return new Promise<void>((resolve, reject) => {
|
|
436
|
+
const stateChangedHandler = (state: AgentState) => {
|
|
437
|
+
const { canListen } = generateDerivedStateValues(state);
|
|
438
|
+
if (!canListen) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
cleanup();
|
|
442
|
+
resolve();
|
|
443
|
+
};
|
|
444
|
+
const abortHandler = () => {
|
|
445
|
+
cleanup();
|
|
446
|
+
reject(new Error('useAgent(/* ... */).waitUntilCouldBeListening - signal aborted'));
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
const cleanup = () => {
|
|
450
|
+
emitter.off(AgentEvent.StateChanged, stateChangedHandler);
|
|
451
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
emitter.on(AgentEvent.StateChanged, stateChangedHandler);
|
|
455
|
+
signal?.addEventListener('abort', abortHandler);
|
|
456
|
+
});
|
|
457
|
+
},
|
|
458
|
+
[emitter],
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
const waitUntilFinished = React.useCallback(
|
|
462
|
+
async (signal?: AbortSignal) => {
|
|
463
|
+
const { isFinished } = generateDerivedStateValues(stateRef.current);
|
|
464
|
+
if (isFinished) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return new Promise<void>((resolve, reject) => {
|
|
469
|
+
const stateChangedHandler = (state: AgentState) => {
|
|
470
|
+
const { isFinished } = generateDerivedStateValues(state);
|
|
471
|
+
if (!isFinished) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
cleanup();
|
|
475
|
+
resolve();
|
|
476
|
+
};
|
|
477
|
+
const abortHandler = () => {
|
|
478
|
+
cleanup();
|
|
479
|
+
reject(new Error('useAgent(/* ... */).waitUntilFinished - signal aborted'));
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
const cleanup = () => {
|
|
483
|
+
emitter.off(AgentEvent.StateChanged, stateChangedHandler);
|
|
484
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
emitter.on(AgentEvent.StateChanged, stateChangedHandler);
|
|
488
|
+
signal?.addEventListener('abort', abortHandler);
|
|
489
|
+
});
|
|
490
|
+
},
|
|
491
|
+
[emitter],
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
return { waitUntilConnected, waitUntilCouldBeListening, waitUntilFinished };
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* useAgent encapculates all agent state, normalizing some quirks around how LiveKit Agents work.
|
|
499
|
+
* @beta
|
|
500
|
+
*/
|
|
501
|
+
export function useAgent(session?: SessionStub): UseAgentReturn {
|
|
502
|
+
const sessionFromContext = useMaybeSessionContext();
|
|
503
|
+
session = session ?? sessionFromContext;
|
|
504
|
+
if (!session) {
|
|
505
|
+
throw new Error(
|
|
506
|
+
'No session provided, make sure you are inside a Session context or pass the session explicitly',
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const {
|
|
511
|
+
room,
|
|
512
|
+
internal: {
|
|
513
|
+
agentConnectTimeoutMilliseconds,
|
|
514
|
+
|
|
515
|
+
agentTimeoutFailureReason,
|
|
516
|
+
startAgentTimeout,
|
|
517
|
+
clearAgentTimeout,
|
|
518
|
+
clearAgentTimeoutFailureReason,
|
|
519
|
+
updateAgentTimeoutState,
|
|
520
|
+
updateAgentTimeoutParticipantExists,
|
|
521
|
+
},
|
|
522
|
+
} = session;
|
|
523
|
+
|
|
524
|
+
const emitter = React.useMemo(() => new EventEmitter() as TypedEventEmitter<AgentCallbacks>, []);
|
|
525
|
+
|
|
526
|
+
const roomRemoteParticipants = useRemoteParticipants({ room });
|
|
527
|
+
|
|
528
|
+
const agentParticipant = React.useMemo(() => {
|
|
529
|
+
return (
|
|
530
|
+
roomRemoteParticipants.find(
|
|
531
|
+
(p) =>
|
|
532
|
+
p.kind === ParticipantKind.AGENT &&
|
|
533
|
+
!(ParticipantAgentAttributes.PublishOnBehalf in p.attributes),
|
|
534
|
+
) ?? null
|
|
535
|
+
);
|
|
536
|
+
}, [roomRemoteParticipants]);
|
|
537
|
+
const workerParticipant = React.useMemo(() => {
|
|
538
|
+
if (!agentParticipant) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
return (
|
|
542
|
+
roomRemoteParticipants.find(
|
|
543
|
+
(p) =>
|
|
544
|
+
p.kind === ParticipantKind.AGENT &&
|
|
545
|
+
p.attributes[ParticipantAgentAttributes.PublishOnBehalf] === agentParticipant.identity,
|
|
546
|
+
) ?? null
|
|
547
|
+
);
|
|
548
|
+
}, [agentParticipant, roomRemoteParticipants]);
|
|
549
|
+
|
|
550
|
+
// 1. Listen for agent participant attribute changes
|
|
551
|
+
const [agentParticipantAttributes, setAgentParticipantAttributes] = React.useState<
|
|
552
|
+
Participant['attributes']
|
|
553
|
+
>(agentParticipant?.attributes ?? {});
|
|
554
|
+
React.useEffect(() => {
|
|
555
|
+
if (!agentParticipant) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const handleAttributesChanged = (attributes: UseAgentReturn['attributes']) => {
|
|
560
|
+
setAgentParticipantAttributes(attributes);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
agentParticipant.on(ParticipantEvent.AttributesChanged, handleAttributesChanged);
|
|
564
|
+
return () => {
|
|
565
|
+
agentParticipant.off(ParticipantEvent.AttributesChanged, handleAttributesChanged);
|
|
566
|
+
};
|
|
567
|
+
}, [agentParticipant, emitter]);
|
|
568
|
+
|
|
569
|
+
// 2. Listen for track updates
|
|
570
|
+
const agentTracks = useParticipantTracks([Track.Source.Camera, Track.Source.Microphone], {
|
|
571
|
+
room,
|
|
572
|
+
participantIdentity: agentParticipant?.identity,
|
|
573
|
+
});
|
|
574
|
+
const workerTracks = useParticipantTracks([Track.Source.Camera, Track.Source.Microphone], {
|
|
575
|
+
room,
|
|
576
|
+
participantIdentity: workerParticipant?.identity,
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const videoTrack = React.useMemo(
|
|
580
|
+
() =>
|
|
581
|
+
agentTracks.find((t) => t.source === Track.Source.Camera) ??
|
|
582
|
+
workerTracks.find((t) => t.source === Track.Source.Camera),
|
|
583
|
+
[agentTracks, workerTracks],
|
|
584
|
+
);
|
|
585
|
+
React.useEffect(() => {
|
|
586
|
+
emitter.emit(AgentEvent.CameraChanged, videoTrack);
|
|
587
|
+
}, [emitter, videoTrack]);
|
|
588
|
+
|
|
589
|
+
const audioTrack = React.useMemo(
|
|
590
|
+
() =>
|
|
591
|
+
agentTracks.find((t) => t.source === Track.Source.Microphone) ??
|
|
592
|
+
workerTracks.find((t) => t.source === Track.Source.Microphone),
|
|
593
|
+
[agentTracks, workerTracks],
|
|
594
|
+
);
|
|
595
|
+
React.useEffect(() => {
|
|
596
|
+
emitter.emit(AgentEvent.MicrophoneChanged, audioTrack);
|
|
597
|
+
}, [emitter, audioTrack]);
|
|
598
|
+
|
|
599
|
+
// Listen for room connection state updates
|
|
600
|
+
const [roomConnectionState, setRoomConnectionState] = React.useState(room.state);
|
|
601
|
+
React.useEffect(() => {
|
|
602
|
+
const handleConnectionStateChanged = (connectionState: ConnectionState) => {
|
|
603
|
+
setRoomConnectionState(connectionState);
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
room.on(RoomEvent.ConnectionStateChanged, handleConnectionStateChanged);
|
|
607
|
+
return () => {
|
|
608
|
+
room.off(RoomEvent.ConnectionStateChanged, handleConnectionStateChanged);
|
|
609
|
+
};
|
|
610
|
+
}, [room]);
|
|
611
|
+
|
|
612
|
+
// When the agent participant connects, reset the timeout failure state
|
|
613
|
+
React.useEffect(() => {
|
|
614
|
+
if (!agentParticipant) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
clearAgentTimeoutFailureReason();
|
|
619
|
+
}, [agentParticipant]);
|
|
620
|
+
|
|
621
|
+
// If the agent participant disconnects in the middle of a conversation unexpectedly, mark that as an explicit failure
|
|
622
|
+
const [agentDisconnectedFailureReason, setAgentDisconnectedFailureReason] = React.useState<
|
|
623
|
+
string | null
|
|
624
|
+
>(null);
|
|
625
|
+
React.useEffect(() => {
|
|
626
|
+
if (!agentParticipant) {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const onParticipantDisconnect = (participant: RemoteParticipant) => {
|
|
631
|
+
if (participant.identity !== agentParticipant?.identity) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
setAgentDisconnectedFailureReason('Agent left the room unexpectedly.');
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
room.on(RoomEvent.ParticipantDisconnected, onParticipantDisconnect);
|
|
638
|
+
|
|
639
|
+
return () => {
|
|
640
|
+
room.off(RoomEvent.ParticipantDisconnected, onParticipantDisconnect);
|
|
641
|
+
};
|
|
642
|
+
}, [agentParticipant, room]);
|
|
643
|
+
|
|
644
|
+
React.useEffect(() => {
|
|
645
|
+
if (roomConnectionState !== ConnectionState.Disconnected) {
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
// Clear the agent disconnect failure state when the room disconnects
|
|
649
|
+
setAgentDisconnectedFailureReason(null);
|
|
650
|
+
}, [roomConnectionState]);
|
|
651
|
+
|
|
652
|
+
const [localMicTrack, setLocalMicTrack] = React.useState<LocalTrackPublication | null>(
|
|
653
|
+
() => room.localParticipant.getTrackPublication(Track.Source.Microphone) ?? null,
|
|
654
|
+
);
|
|
655
|
+
React.useEffect(() => {
|
|
656
|
+
const handleLocalParticipantTrackPublished = () => {
|
|
657
|
+
setLocalMicTrack(room.localParticipant.getTrackPublication(Track.Source.Microphone) ?? null);
|
|
658
|
+
};
|
|
659
|
+
const handleLocalParticipantTrackUnPublished = () => {
|
|
660
|
+
setLocalMicTrack(null);
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
room.localParticipant.on(
|
|
664
|
+
ParticipantEvent.LocalTrackPublished,
|
|
665
|
+
handleLocalParticipantTrackPublished,
|
|
666
|
+
);
|
|
667
|
+
room.localParticipant.on(
|
|
668
|
+
ParticipantEvent.LocalTrackUnpublished,
|
|
669
|
+
handleLocalParticipantTrackUnPublished,
|
|
670
|
+
);
|
|
671
|
+
return () => {
|
|
672
|
+
room.localParticipant.off(
|
|
673
|
+
ParticipantEvent.LocalTrackPublished,
|
|
674
|
+
handleLocalParticipantTrackPublished,
|
|
675
|
+
);
|
|
676
|
+
room.localParticipant.off(
|
|
677
|
+
ParticipantEvent.LocalTrackUnpublished,
|
|
678
|
+
handleLocalParticipantTrackUnPublished,
|
|
679
|
+
);
|
|
680
|
+
};
|
|
681
|
+
}, [room.localParticipant]);
|
|
682
|
+
|
|
683
|
+
const failureReasons = React.useMemo(() => {
|
|
684
|
+
const reasons = [];
|
|
685
|
+
if (agentTimeoutFailureReason) {
|
|
686
|
+
reasons.push(agentTimeoutFailureReason);
|
|
687
|
+
}
|
|
688
|
+
if (agentDisconnectedFailureReason) {
|
|
689
|
+
reasons.push(agentDisconnectedFailureReason);
|
|
690
|
+
}
|
|
691
|
+
return reasons;
|
|
692
|
+
}, [agentTimeoutFailureReason, agentDisconnectedFailureReason]);
|
|
693
|
+
|
|
694
|
+
const state = React.useMemo(() => {
|
|
695
|
+
if (failureReasons.length > 0) {
|
|
696
|
+
return 'failed';
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
let state: AgentState = 'disconnected';
|
|
700
|
+
|
|
701
|
+
if (roomConnectionState !== ConnectionState.Disconnected) {
|
|
702
|
+
state = 'connecting';
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// If the microphone preconnect buffer is active, then a special 'pre-connect-buffering' state
|
|
706
|
+
// is set
|
|
707
|
+
if (localMicTrack) {
|
|
708
|
+
state = 'pre-connect-buffering';
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (agentParticipant && agentParticipantAttributes[ParticipantAgentAttributes.AgentState]) {
|
|
712
|
+
state = agentParticipantAttributes[ParticipantAgentAttributes.AgentState] as AgentSdkStates;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return state;
|
|
716
|
+
}, [
|
|
717
|
+
failureReasons,
|
|
718
|
+
roomConnectionState,
|
|
719
|
+
localMicTrack,
|
|
720
|
+
agentParticipant,
|
|
721
|
+
agentParticipantAttributes,
|
|
722
|
+
]);
|
|
723
|
+
|
|
724
|
+
React.useEffect(() => {
|
|
725
|
+
emitter.emit(AgentEvent.StateChanged, state);
|
|
726
|
+
updateAgentTimeoutState(state);
|
|
727
|
+
}, [emitter, state]);
|
|
728
|
+
React.useEffect(() => {
|
|
729
|
+
updateAgentTimeoutParticipantExists(agentParticipant !== null);
|
|
730
|
+
}, [agentParticipant]);
|
|
731
|
+
|
|
732
|
+
// When the session room begins connecting, start the agent timeout
|
|
733
|
+
const isSessionDisconnected = session.connectionState === 'disconnected';
|
|
734
|
+
React.useEffect(() => {
|
|
735
|
+
if (isSessionDisconnected) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
startAgentTimeout(agentConnectTimeoutMilliseconds);
|
|
740
|
+
return () => {
|
|
741
|
+
clearAgentTimeout();
|
|
742
|
+
};
|
|
743
|
+
}, [isSessionDisconnected, agentConnectTimeoutMilliseconds]);
|
|
744
|
+
|
|
745
|
+
const {
|
|
746
|
+
identity: agentParticipantIdentity,
|
|
747
|
+
name: agentParticipantName,
|
|
748
|
+
metadata: agentParticipantMetadata,
|
|
749
|
+
} = useParticipantInfo({ participant: agentParticipant ?? undefined });
|
|
750
|
+
|
|
751
|
+
const agentState: AgentStateCases = React.useMemo(() => {
|
|
752
|
+
const common: AgentStateCommon = {
|
|
753
|
+
attributes: agentParticipantAttributes,
|
|
754
|
+
|
|
755
|
+
internal: {
|
|
756
|
+
agentParticipant,
|
|
757
|
+
workerParticipant,
|
|
758
|
+
emitter,
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
switch (state) {
|
|
763
|
+
case 'disconnected':
|
|
764
|
+
return {
|
|
765
|
+
...common,
|
|
766
|
+
identity: undefined,
|
|
767
|
+
name: undefined,
|
|
768
|
+
metadata: undefined,
|
|
769
|
+
|
|
770
|
+
state,
|
|
771
|
+
...generateDerivedStateValues(state),
|
|
772
|
+
failureReasons: null,
|
|
773
|
+
|
|
774
|
+
// Clear inner values if no longer connected
|
|
775
|
+
cameraTrack: undefined,
|
|
776
|
+
microphoneTrack: undefined,
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
case 'connecting':
|
|
780
|
+
return {
|
|
781
|
+
...common,
|
|
782
|
+
identity: undefined,
|
|
783
|
+
name: undefined,
|
|
784
|
+
metadata: undefined,
|
|
785
|
+
|
|
786
|
+
state,
|
|
787
|
+
...generateDerivedStateValues(state),
|
|
788
|
+
failureReasons: null,
|
|
789
|
+
|
|
790
|
+
// Clear inner values if no longer connected
|
|
791
|
+
cameraTrack: undefined,
|
|
792
|
+
microphoneTrack: undefined,
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
case 'initializing':
|
|
796
|
+
case 'idle':
|
|
797
|
+
return {
|
|
798
|
+
...common,
|
|
799
|
+
identity: agentParticipantIdentity!,
|
|
800
|
+
name: agentParticipantName,
|
|
801
|
+
metadata: agentParticipantMetadata,
|
|
802
|
+
|
|
803
|
+
state,
|
|
804
|
+
...generateDerivedStateValues(state),
|
|
805
|
+
failureReasons: null,
|
|
806
|
+
|
|
807
|
+
cameraTrack: videoTrack,
|
|
808
|
+
microphoneTrack: audioTrack,
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
case 'pre-connect-buffering':
|
|
812
|
+
return {
|
|
813
|
+
...common,
|
|
814
|
+
identity: agentParticipantIdentity!,
|
|
815
|
+
name: agentParticipantName,
|
|
816
|
+
metadata: agentParticipantMetadata,
|
|
817
|
+
|
|
818
|
+
state,
|
|
819
|
+
...generateDerivedStateValues(state),
|
|
820
|
+
failureReasons: null,
|
|
821
|
+
|
|
822
|
+
cameraTrack: videoTrack,
|
|
823
|
+
microphoneTrack: audioTrack,
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
case 'listening':
|
|
827
|
+
case 'thinking':
|
|
828
|
+
case 'speaking':
|
|
829
|
+
return {
|
|
830
|
+
...common,
|
|
831
|
+
identity: agentParticipantIdentity!,
|
|
832
|
+
name: agentParticipantName,
|
|
833
|
+
metadata: agentParticipantMetadata,
|
|
834
|
+
|
|
835
|
+
state,
|
|
836
|
+
...generateDerivedStateValues(state),
|
|
837
|
+
failureReasons: null,
|
|
838
|
+
|
|
839
|
+
cameraTrack: videoTrack,
|
|
840
|
+
microphoneTrack: audioTrack,
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
case 'failed':
|
|
844
|
+
return {
|
|
845
|
+
...common,
|
|
846
|
+
identity: undefined,
|
|
847
|
+
name: undefined,
|
|
848
|
+
metadata: undefined,
|
|
849
|
+
|
|
850
|
+
state: 'failed',
|
|
851
|
+
...generateDerivedStateValues('failed'),
|
|
852
|
+
failureReasons,
|
|
853
|
+
|
|
854
|
+
// Clear inner values if no longer connected
|
|
855
|
+
cameraTrack: undefined,
|
|
856
|
+
microphoneTrack: undefined,
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
}, [
|
|
860
|
+
agentParticipantIdentity,
|
|
861
|
+
agentParticipantName,
|
|
862
|
+
agentParticipantMetadata,
|
|
863
|
+
agentParticipantAttributes,
|
|
864
|
+
emitter,
|
|
865
|
+
agentParticipant,
|
|
866
|
+
state,
|
|
867
|
+
videoTrack,
|
|
868
|
+
audioTrack,
|
|
869
|
+
]);
|
|
870
|
+
|
|
871
|
+
const { waitUntilConnected, waitUntilCouldBeListening, waitUntilFinished } =
|
|
872
|
+
useAgentWaitUntilDerivedStates(emitter, state);
|
|
873
|
+
|
|
874
|
+
const waitUntilCamera = React.useCallback(
|
|
875
|
+
(signal?: AbortSignal) => {
|
|
876
|
+
return new Promise<TrackReference>((resolve, reject) => {
|
|
877
|
+
const stateChangedHandler = (camera: TrackReference | undefined) => {
|
|
878
|
+
if (!camera) {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
cleanup();
|
|
882
|
+
resolve(camera);
|
|
883
|
+
};
|
|
884
|
+
const abortHandler = () => {
|
|
885
|
+
cleanup();
|
|
886
|
+
reject(new Error('useAgent(/* ... */).waitUntilCamera - signal aborted'));
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
const cleanup = () => {
|
|
890
|
+
emitter.off(AgentEvent.CameraChanged, stateChangedHandler);
|
|
891
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
892
|
+
};
|
|
893
|
+
|
|
894
|
+
emitter.on(AgentEvent.CameraChanged, stateChangedHandler);
|
|
895
|
+
signal?.addEventListener('abort', abortHandler);
|
|
896
|
+
});
|
|
897
|
+
},
|
|
898
|
+
[emitter],
|
|
899
|
+
);
|
|
900
|
+
|
|
901
|
+
const waitUntilMicrophone = React.useCallback(
|
|
902
|
+
(signal?: AbortSignal) => {
|
|
903
|
+
return new Promise<TrackReference>((resolve, reject) => {
|
|
904
|
+
const stateChangedHandler = (microphone: TrackReference | undefined) => {
|
|
905
|
+
if (!microphone) {
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
cleanup();
|
|
909
|
+
resolve(microphone);
|
|
910
|
+
};
|
|
911
|
+
const abortHandler = () => {
|
|
912
|
+
cleanup();
|
|
913
|
+
reject(new Error('useAgent(/* ... */).waitUntilMicrophone - signal aborted'));
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
const cleanup = () => {
|
|
917
|
+
emitter.off(AgentEvent.MicrophoneChanged, stateChangedHandler);
|
|
918
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
emitter.on(AgentEvent.MicrophoneChanged, stateChangedHandler);
|
|
922
|
+
signal?.addEventListener('abort', abortHandler);
|
|
923
|
+
});
|
|
924
|
+
},
|
|
925
|
+
[emitter],
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
return React.useMemo(() => {
|
|
929
|
+
return {
|
|
930
|
+
...agentState,
|
|
931
|
+
waitUntilConnected,
|
|
932
|
+
waitUntilCouldBeListening,
|
|
933
|
+
waitUntilFinished,
|
|
934
|
+
waitUntilCamera,
|
|
935
|
+
waitUntilMicrophone,
|
|
936
|
+
};
|
|
937
|
+
}, [
|
|
938
|
+
agentState,
|
|
939
|
+
waitUntilConnected,
|
|
940
|
+
waitUntilCouldBeListening,
|
|
941
|
+
waitUntilFinished,
|
|
942
|
+
waitUntilCamera,
|
|
943
|
+
waitUntilMicrophone,
|
|
944
|
+
]);
|
|
945
|
+
}
|