@wix/legends-platform-sdk 1.22.0 → 1.23.0
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/dist/cjs/hooks/useConversation/livekit/useConversation.js +9 -1
- package/dist/cjs/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/cjs/hooks/useParticipantTrack/parseTrackStats.js +41 -5
- package/dist/cjs/hooks/useParticipantTrack/parseTrackStats.js.map +1 -1
- package/dist/esm/hooks/useConversation/livekit/useConversation.js +11 -3
- package/dist/esm/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/esm/hooks/useParticipantTrack/parseTrackStats.js +41 -5
- package/dist/esm/hooks/useParticipantTrack/parseTrackStats.js.map +1 -1
- package/dist/types/hooks/useConversation/livekit/useConversation.d.ts.map +1 -1
- package/dist/types/hooks/useParticipantTrack/parseTrackStats.d.ts +10 -1
- package/dist/types/hooks/useParticipantTrack/parseTrackStats.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -74,6 +74,8 @@ function useConversation({
|
|
|
74
74
|
const acousticT0Ref = (0, _react.useRef)(null);
|
|
75
75
|
const latestTurnMetadataRef = (0, _react.useRef)({});
|
|
76
76
|
const isConnectedRef = (0, _react.useRef)(false);
|
|
77
|
+
const userCumulativeTrackStatsRef = (0, _react.useRef)(undefined);
|
|
78
|
+
const agentCumulativeTrackStatsRef = (0, _react.useRef)(undefined);
|
|
77
79
|
const userMicPublication = (0, _useParticipantTrack.useParticipantTrack)({
|
|
78
80
|
type: 'user',
|
|
79
81
|
source: _useParticipantTrack.Source.Microphone
|
|
@@ -253,7 +255,11 @@ function useConversation({
|
|
|
253
255
|
}
|
|
254
256
|
async function emitConversationTurnLatency(clientAcousticLatencyMs) {
|
|
255
257
|
var _conversationRef$curr3;
|
|
256
|
-
const [
|
|
258
|
+
const [userReport, agentReport] = await Promise.all([(0, _useParticipantTrack.getTrackStats)(userMicPublication), (0, _useParticipantTrack.getTrackStats)(agentMicPublication)]);
|
|
259
|
+
const userStats = (0, _useParticipantTrack.parseTrackStats)(userReport, userCumulativeTrackStatsRef.current);
|
|
260
|
+
const agentStats = (0, _useParticipantTrack.parseTrackStats)(agentReport, agentCumulativeTrackStatsRef.current);
|
|
261
|
+
userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;
|
|
262
|
+
agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;
|
|
257
263
|
emitEvent('conversationTurnLatency', {
|
|
258
264
|
conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id,
|
|
259
265
|
speechId: latestTurnMetadataRef.current.speechId,
|
|
@@ -346,6 +352,8 @@ function useConversation({
|
|
|
346
352
|
acousticPhaseRef.current = 'idle';
|
|
347
353
|
acousticT0Ref.current = null;
|
|
348
354
|
latestTurnMetadataRef.current = {};
|
|
355
|
+
userCumulativeTrackStatsRef.current = undefined;
|
|
356
|
+
agentCumulativeTrackStatsRef.current = undefined;
|
|
349
357
|
setAgentActivityState('idle');
|
|
350
358
|
setAgentConnectionState('idle');
|
|
351
359
|
setUserActivityState('idle');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useSpeechActivityDetector","_useParticipantTrack","_useEmitConversationEvent","_useToolCallingRuntime","_utils","_constants","useConversation","autoJoin","type","config","startWithMicrophone","startWithCamera","firstConversation","lastConversationTopic","_conversation$data2","setLogLevel","LogLevel","silent","conversation","useCreateConversation","room","useEnsureRoom","speaker","useAtomValue","state","microphone","setMicrophone","useAtom","camera","setCamera","toolRuntime","useToolCallingRuntime","toolAdapter","createLivekitToolAdapter","conversationRef","useLatest","data","toolRuntimeRef","conversationStatus","setConversationStatus","userConnectionState","setUserConnectionState","joinedAt","setJoinedAt","setActiveMediaDevice","setMicrophoneDeviceId","useMediaDeviceSelect","kind","setSpeakerDeviceId","setCameraDeviceId","requestPermissions","enabled","setTranscriptions","useSetAtom","transcriptions","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","useEmitConversationEvent","inactivityTimeoutRef","useRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userMicPublication","useParticipantTrack","source","Source","Microphone","agentMicPublication","timer","useTimer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","useEffect","registerRoomEvents","unregisterRoomEvents","useUpdateEffect","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","undefined","restart","getTime","_conversation$data3","invariant","url","URL","accessToken","searchParams","get","connect","remoteParticipant","findJoinedAgentParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","ParticipantKind","AGENT","old","mergeTranscriptions","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","ACOUSTIC_USER_HANGOVER_MS","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","userStats","agentStats","Promise","all","getTrackStats","then","parseTrackStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","useSpeechActivityDetector","onSpeechStart","onSpeechEnd","thresholdRms","ACOUSTIC_USER_THRESHOLD_RMS","hangoverMs","ACOUSTIC_AGENT_HANGOVER_MS","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","checkIsToolCallsData","handle","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","payload","decoded","decodeDataPayload","resolve","catch","handleConnectedEvent","_conversationRef$curr6","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","DisconnectReason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","shouldHandleParticipantConnected","_conversationRef$curr7","handleParticipantDisconnectedEvent","_conversationRef$curr8","leave","_conversationRef$curr9","disconnect","_conversationRef$curr0","_conversationRef$curr1","interrupt","_conversationRef$curr10","publishConversationDataMessage","dismissInactivity","send","attachments","_conversationRef$curr11","sendText","topic","attributes","safeStringify","on","off","status"],"sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n DisconnectReason,\n Participant,\n setLogLevel,\n ParticipantKind,\n RemoteParticipant,\n TranscriptionSegment,\n LogLevel,\n} from 'livekit-client';\nimport invariant from 'invariant';\nimport { useTimer } from 'react-timer-hook';\nimport { useLatest, useUpdateEffect } from 'react-use';\nimport { useEnsureRoom, useMediaDeviceSelect } from '@livekit/components-react';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\nimport {\n Conversation,\n state,\n type ConversationTranscription,\n} from '../../../conversation';\nimport type {\n UseConversationResult,\n UseConversationOptions,\n Attachment,\n} from '../types';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n ToolCallsData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n checkIsToolCallsData,\n createLivekitToolAdapter,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n publishConversationDataMessage,\n safeStringify,\n shouldHandleParticipantConnected,\n} from './utils';\nimport {\n ACOUSTIC_AGENT_HANGOVER_MS,\n ACOUSTIC_USER_HANGOVER_MS,\n ACOUSTIC_USER_THRESHOLD_RMS,\n} from './constants';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n firstConversation,\n lastConversationTopic,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({\n type,\n config,\n firstConversation,\n lastConversationTopic,\n });\n const room = useEnsureRoom();\n const speaker = useAtomValue(state.speaker);\n const [microphone, setMicrophone] = useAtom(state.microphone);\n const [camera, setCamera] = useAtom(state.camera);\n const toolRuntime = useToolCallingRuntime();\n const toolAdapter = createLivekitToolAdapter(room);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userStats, agentStats] = await Promise.all([\n getTrackStats(userMicPublication).then(parseTrackStats),\n getTrackStats(agentMicPublication).then(parseTrackStats),\n ]);\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleToolCallsEvent(data: ToolCallsData) {\n await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsToolCallsData,\n handle: handleToolCallsEvent as (data: unknown) => Promise<void>,\n },\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n }\n\n function unregisterRoomEvents() {\n room.off('connected', handleConnectedEvent);\n room.off('encryptionError', handleEncryptionErrorEvent);\n room.off('disconnected', handleDisconnectedEvent);\n room.off('transcriptionReceived', handleTranscriptionReceivedEvent);\n room.off('participantConnected', handleParticipantConnectedEvent);\n room.off('participantDisconnected', handleParticipantDisconnectedEvent);\n room.off('dataReceived', handleDataReceivedEvent);\n }\n\n return {\n status: conversationStatus,\n conversation: conversation.data,\n join,\n send,\n interrupt,\n dismissInactivity,\n leave,\n };\n}\n"],"mappings":";;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AASA,IAAAE,UAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AACA,IAAAK,SAAA,GAAAL,OAAA;AACA,IAAAM,gBAAA,GAAAN,OAAA;AACA,IAAAO,MAAA,GAAAP,OAAA;AACA,IAAAQ,aAAA,GAAAR,OAAA;AAgBA,IAAAS,sBAAA,GAAAT,OAAA;AACA,IAAAU,0BAAA,GAAAV,OAAA;AACA,IAAAW,oBAAA,GAAAX,OAAA;AAOA,IAAAY,yBAAA,GAAAZ,OAAA;AACA,IAAAa,sBAAA,GAAAb,OAAA;AACA,IAAAc,MAAA,GAAAd,OAAA;AAaA,IAAAe,UAAA,GAAAf,OAAA;AAMO,SAASgB,eAAeA,CAAC;EAC9BC,QAAQ,GAAG,IAAI;EACfC,IAAI;EACJC,MAAM;EACNC,mBAAmB,GAAG,KAAK;EAC3BC,eAAe,GAAG,KAAK;EACvBC,iBAAiB;EACjBC;AACsB,CAAC,EAAyB;EAAA,IAAAC,mBAAA;EAChD,IAAAC,0BAAW,EAACC,uBAAQ,CAACC,MAAM,CAAC;EAE5B,MAAMC,YAAY,GAAG,IAAAC,4CAAqB,EAAC;IACzCX,IAAI;IACJC,MAAM;IACNG,iBAAiB;IACjBC;EACF,CAAC,CAAC;EACF,MAAMO,IAAI,GAAG,IAAAC,8BAAa,EAAC,CAAC;EAC5B,MAAMC,OAAO,GAAG,IAAAC,mBAAY,EAACC,mBAAK,CAACF,OAAO,CAAC;EAC3C,MAAM,CAACG,UAAU,EAAEC,aAAa,CAAC,GAAG,IAAAC,cAAO,EAACH,mBAAK,CAACC,UAAU,CAAC;EAC7D,MAAM,CAACG,MAAM,EAAEC,SAAS,CAAC,GAAG,IAAAF,cAAO,EAACH,mBAAK,CAACI,MAAM,CAAC;EACjD,MAAME,WAAW,GAAG,IAAAC,4CAAqB,EAAC,CAAC;EAC3C,MAAMC,WAAW,GAAG,IAAAC,+BAAwB,EAACb,IAAI,CAAC;;EAElD;EACA,MAAMc,eAAe,GAAG,IAAAC,mBAAS,EAC/BjB,YAAY,CAACkB,IACf,CAAC;EACD,MAAMC,cAAc,GAAG,IAAAF,mBAAS,EAACL,WAAW,CAAC;EAE7C,MAAM,CAACQ,kBAAkB,EAAEC,qBAAqB,CAAC,GAAG,IAAAZ,cAAO,EACzDH,mBAAK,CAACc,kBACR,CAAC;EAED,MAAM,CAACE,mBAAmB,EAAEC,sBAAsB,CAAC,GAAG,IAAAd,cAAO,EAC3DH,mBAAK,CAACgB,mBACR,CAAC;EAED,MAAM,CAACE,QAAQ,EAAEC,WAAW,CAAC,GAAG,IAAAhB,cAAO,EAACH,mBAAK,CAACkB,QAAQ,CAAC;EAEvD,MAAM;IAAEE,oBAAoB,EAAEC;EAAsB,CAAC,GAAG,IAAAC,qCAAoB,EAAC;IAC3EC,IAAI,EAAE;EACR,CAAC,CAAC;EACF,MAAM;IAAEH,oBAAoB,EAAEI;EAAmB,CAAC,GAAG,IAAAF,qCAAoB,EAAC;IACxEC,IAAI,EAAE;EACR,CAAC,CAAC;EACF,MAAM;IAAEH,oBAAoB,EAAEK;EAAkB,CAAC,GAAG,IAAAH,qCAAoB,EAAC;IACvEC,IAAI,EAAE,YAAY;IAClBG,kBAAkB,EAAEtB,MAAM,CAACuB;EAC7B,CAAC,CAAC;EAEF,MAAMC,iBAAiB,GAAG,IAAAC,iBAAU,EAAC7B,mBAAK,CAAC8B,cAAc,CAAC;EAC1D,MAAM,CAACC,oBAAoB,EAAEC,uBAAuB,CAAC,GAAG,IAAA7B,cAAO,EAC7DH,mBAAK,CAAC+B,oBACR,CAAC;EACD,MAAME,qBAAqB,GAAG,IAAAJ,iBAAU,EAAC7B,mBAAK,CAACkC,kBAAkB,CAAC;EAClE,MAAMC,oBAAoB,GAAG,IAAAN,iBAAU,EAAC7B,mBAAK,CAACoC,iBAAiB,CAAC;EAChE,MAAMC,SAAS,GAAG,IAAAC,kDAAwB,EAAC,CAAC;EAE5C,MAAMC,oBAAoB,GAAG,IAAAC,aAAM,EAAC,KAAK,CAAC;EAC1C,MAAMC,gBAAgB,GAAG,IAAAD,aAAM,EAAsC,MAAM,CAAC;EAC5E,MAAME,aAAa,GAAG,IAAAF,aAAM,EAAgB,IAAI,CAAC;EACjD,MAAMG,qBAAqB,GAAG,IAAAH,aAAM,EAIjC,CAAC,CAAC,CAAC;EACN,MAAMI,cAAc,GAAG,IAAAJ,aAAM,EAAC,KAAK,CAAC;EAEpC,MAAMK,kBAAkB,GAAG,IAAAC,wCAAmB,EAAC;IAC7C9D,IAAI,EAAE,MAAM;IACZ+D,MAAM,EAAEC,2BAAM,CAACC;EACjB,CAAC,CAAC;EACF,MAAMC,mBAAmB,GAAG,IAAAJ,wCAAmB,EAAC;IAC9C9D,IAAI,EAAE,OAAO;IACb+D,MAAM,EAAEC,2BAAM,CAACC;EACjB,CAAC,CAAC;EAEF,MAAME,KAAK,GAAG,IAAAC,wBAAQ,EAAC;IACrBC,SAAS,EAAE,KAAK;IAChBC,QAAQ,EAAEC,YAAY;IACtBC,eAAe,EAAE,IAAIC,IAAI,CAAC;EAC5B,CAAC,CAAC;EAEF,IAAAC,gBAAS,EAAC,MAAM;IACd,IAAI,CAAC9D,IAAI,EAAE;MACT;IACF;IACA+D,kBAAkB,CAAC,CAAC;IAEpB,OAAO,MAAM;MACXC,oBAAoB,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,CAAChE,IAAI,CAAC,CAAC;EAEV,IAAAiE,yBAAe,EAAC,MAAM;IACpBxC,qBAAqB,CAACpB,UAAU,CAAC6D,QAAQ,CAAC;EAC5C,CAAC,EAAE,CAAC7D,UAAU,CAAC6D,QAAQ,CAAC,CAAC;EAEzB,IAAAD,yBAAe,EAAC,MAAM;IACpBrC,kBAAkB,CAAC1B,OAAO,CAACgE,QAAQ,CAAC;EACtC,CAAC,EAAE,CAAChE,OAAO,CAACgE,QAAQ,CAAC,CAAC;EAEtB,IAAAD,yBAAe,EAAC,MAAM;IACpBpC,iBAAiB,CAACrB,MAAM,CAAC0D,QAAQ,CAAC;EACpC,CAAC,EAAE,CAAC1D,MAAM,CAAC0D,QAAQ,CAAC,CAAC;EAErB,IAAAD,yBAAe,EAAC,MAAM;IACpB,IAAI9B,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACAnC,IAAI,CAACmE,gBAAgB,CAACC,oBAAoB,CAAC/D,UAAU,CAAC0B,OAAO,CAAC;EAChE,CAAC,EAAE,CAAC1B,UAAU,CAAC0B,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE9C,IAAA8B,yBAAe,EAAC,MAAM;IACpB,IAAI9B,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACAnC,IAAI,CAACmE,gBAAgB,CAACE,gBAAgB,CAAC7D,MAAM,CAACuB,OAAO,EAAE;MACrDuC,UAAU,EAAE;QAAEC,KAAK,EAAE,IAAI;QAAEC,MAAM,EAAE;MAAK;IAC1C,CAAC,CAAC;EACJ,CAAC,EAAE,CAAChE,MAAM,CAACuB,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE1C,IAAA2B,gBAAS,EAAC,MAAM;IACd,IAAI,CAAC3E,QAAQ,EAAE;MACb;IACF;IAEA,IAAI+B,kBAAkB,KAAK,SAAS,EAAE;MACpC,KAAKuD,IAAI,CAAC,CAAC;IACb;EACF,CAAC,EAAE,CAACvD,kBAAkB,EAAE/B,QAAQ,CAAC,CAAC;EAElC,IAAA2E,gBAAS,EAAC,MAAM;IAAA,IAAAY,kBAAA;IACd,IAAI,CAACpD,QAAQ,IAAI,EAAAoD,kBAAA,GAAA5E,YAAY,CAACkB,IAAI,qBAAjB0D,kBAAA,CAAmBC,KAAK,MAAKC,SAAS,EAAE;MACvD;IACF;IAEArB,KAAK,CAACsB,OAAO,CAAC,IAAIhB,IAAI,CAACvC,QAAQ,CAACwD,OAAO,CAAC,CAAC,GAAGhF,YAAY,CAACkB,IAAI,CAAE2D,KAAM,CAAC,CAAC;EACzE,CAAC,EAAE,CAACrD,QAAQ,GAAA5B,mBAAA,GAAEI,YAAY,CAACkB,IAAI,qBAAjBtB,mBAAA,CAAmBiF,KAAK,CAAC,CAAC;EAExC,eAAeF,IAAIA,CAAA,EAAG;IAAA,IAAAM,mBAAA;IACpB,IAAAC,kBAAS,EAAC5D,mBAAmB,KAAK,MAAM,EAAE,gBAAgB,CAAC;IAC3D,IAAA4D,kBAAS,EAAClF,YAAY,CAACkB,IAAI,EAAE,2BAA2B,CAAC;IACzD,MAAMiE,GAAG,GAAG,IAAIC,GAAG,CAAC,CAAApF,YAAY,aAAAiF,mBAAA,GAAZjF,YAAY,CAAEkB,IAAI,qBAAlB+D,mBAAA,CAAoBE,GAAG,KAAI,EAAE,CAAC;IAClD,MAAME,WAAW,GAAGF,GAAG,CAACG,YAAY,CAACC,GAAG,CAAC,OAAO,CAAC;IACjD,IAAI;MACFhE,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMrB,IAAI,oBAAJA,IAAI,CAAEsF,OAAO,CAACxF,YAAY,CAACkB,IAAI,CAACiE,GAAG,EAAEE,WAAW,EAAG,CAAC,CAAC,CAAC;;MAE5D;MACA,MAAMI,iBAAiB,GAAG,IAAAC,iCAA0B,EAACxF,IAAI,EAAEZ,IAAI,CAAC;MAChE,IAAImG,iBAAiB,IAAIpD,oBAAoB,KAAK,QAAQ,EAAE;QAC1DsD,eAAe,CAACF,iBAAiB,CAAC;MACpC;MAEAG,kBAAkB,CAAC,CAAC;IACtB,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,gBAAgB,EAAEA,KAAK,CAAC;MACtCtE,sBAAsB,CAAC,YAAY,CAAC;IACtC;EACF;EAEA,SAASqE,kBAAkBA,CAAA,EAAG;IAC5B,IAAIpG,mBAAmB,EAAE;MACvBgB,aAAa,CAAC;QAAE,GAAGD,UAAU;QAAE0B,OAAO,EAAE;MAAK,CAAC,CAAC;IACjD;IACA,IAAIxC,eAAe,IAAIH,IAAI,KAAK,OAAO,EAAE;MACvCqB,SAAS,CAAC;QAAE,GAAGD,MAAM;QAAEuB,OAAO,EAAE;MAAK,CAAC,CAAC;IACzC;EACF;EAEA,SAAS8D,gCAAgCA,CACvCC,QAAgC,EAChCC,WAAyB,EACzB;IACA,MAAM7D,cAA2C,GAAG4D,QAAQ,CAACE,GAAG,CAAEC,CAAC,KAAM;MACvEC,EAAE,EAAED,CAAC,CAACC,EAAE;MACRC,OAAO,EAAEF,CAAC,CAACG,IAAI;MACfjD,MAAM,EAAE,CAAA4C,WAAW,oBAAXA,WAAW,CAAEpE,IAAI,MAAK0E,8BAAe,CAACC,KAAK,GAAG,OAAO,GAAG;IAClE,CAAC,CAAC,CAAC;IAEHtE,iBAAiB,CAAEuE,GAAG,IAAK,IAAAC,0BAAmB,EAACtE,cAAc,EAAEqE,GAAG,CAAC,CAAC;EACtE;EAEA,SAASE,wBAAwBA,CAACzF,IAAuB,EAAE;IAAA,IAAA0F,qBAAA;IACzD,MAAMC,cAAc,IAAAD,qBAAA,GAAG5F,eAAe,CAAC8F,OAAO,qBAAvBF,qBAAA,CAAyBR,EAAE;IAClD,MAAM;MAAEW,eAAe;MAAEzG,KAAK,EAAE0G;IAAW,CAAC,GAAG9F,IAAI;IACnD,QAAQ6F,eAAe;MACrB,KAAK,UAAU;QACb,IAAIC,UAAU,KAAK,WAAW,EAAE;UAC9B/D,qBAAqB,CAAC6D,OAAO,GAAG;YAC9BG,qBAAqB,EAAE/F,IAAI,CAAC+F,qBAAqB;YACjDC,QAAQ,EAAEhG,IAAI,CAACgG,QAAQ;YACvBC,QAAQ,EAAEjG,IAAI,CAACiG;UACjB,CAAC;QACH;QACAxE,SAAS,CACPqE,UAAU,KAAK,UAAU,GAAG,gBAAgB,GAAG,eAAe,EAC9D;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACDpE,oBAAoB,CAACuE,UAAU,CAAC;QAChC;MACF,KAAK,OAAO;QACV,IAAI9F,IAAI,CAACiG,QAAQ,EAAE;UACjBlE,qBAAqB,CAAC6D,OAAO,GAAG;YAC9B,GAAG7D,qBAAqB,CAAC6D,OAAO;YAChCK,QAAQ,EAAEjG,IAAI,CAACiG;UACjB,CAAC;QACH;QACAxE,SAAS,CACPqE,UAAU,KAAK,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,EAChE;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACDtE,qBAAqB,CAACyE,UAAU,CAAC;QACjC;IACJ;EACF;EAEA,SAASI,uBAAuBA,CAAA,EAAG;IACjC,IAAI,CAAClE,cAAc,CAAC4D,OAAO,EAAE;MAC3B;IACF;IACA,IAAI/D,gBAAgB,CAAC+D,OAAO,KAAK,iBAAiB,EAAE;MAClD/D,gBAAgB,CAAC+D,OAAO,GAAG,MAAM;MACjC9D,aAAa,CAAC8D,OAAO,GAAG,IAAI;IAC9B;EACF;EAEA,SAASO,wBAAwBA,CAACC,WAAmB,EAAE;IACrD,IAAI,CAACpE,cAAc,CAAC4D,OAAO,IAAI/D,gBAAgB,CAAC+D,OAAO,KAAK,MAAM,EAAE;MAClE;IACF;IACA9D,aAAa,CAAC8D,OAAO,GAAGQ,WAAW,GAAGC,oCAAyB;IAC/DxE,gBAAgB,CAAC+D,OAAO,GAAG,iBAAiB;EAC9C;EAEA,SAASU,wBAAwBA,CAACF,WAAmB,EAAE;IAAA,IAAAG,sBAAA;IACrD,IACE,CAACvE,cAAc,CAAC4D,OAAO,IACvB/D,gBAAgB,CAAC+D,OAAO,KAAK,iBAAiB,IAC9C9D,aAAa,CAAC8D,OAAO,IAAI,IAAI,EAC7B;MACA;IACF;IAEA,MAAMY,SAAS,GAAGJ,WAAW,GAAGtE,aAAa,CAAC8D,OAAO;IACrD9D,aAAa,CAAC8D,OAAO,GAAG,IAAI;IAC5B/D,gBAAgB,CAAC+D,OAAO,GAAG,MAAM;IAEjC,IAAIY,SAAS,GAAG,CAAC,IAAIA,SAAS,GAAG,KAAK,EAAE;MACtC;IACF;IAEA/E,SAAS,CAAC,iBAAiB,EAAE;MAC3BkE,cAAc,GAAAY,sBAAA,GAAEzG,eAAe,CAAC8F,OAAO,qBAAvBW,sBAAA,CAAyBrB,EAAG;MAC5CsB,SAAS;MACTT,qBAAqB,EACnBhE,qBAAqB,CAAC6D,OAAO,CAACG,qBAAsB;MACtDC,QAAQ,EAAEjE,qBAAqB,CAAC6D,OAAO,CAACI,QAAQ;MAChDC,QAAQ,EAAElE,qBAAqB,CAAC6D,OAAO,CAACK;IAC1C,CAAC,CAAC;IAEF,KAAKQ,2BAA2B,CAACD,SAAS,CAAC;EAC7C;EAEA,eAAeC,2BAA2BA,CAACC,uBAA+B,EAAE;IAAA,IAAAC,sBAAA;IAC1E,MAAM,CAACC,SAAS,EAAEC,UAAU,CAAC,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAChD,IAAAC,kCAAa,EAAC/E,kBAAkB,CAAC,CAACgF,IAAI,CAACC,oCAAe,CAAC,EACvD,IAAAF,kCAAa,EAAC1E,mBAAmB,CAAC,CAAC2E,IAAI,CAACC,oCAAe,CAAC,CACzD,CAAC;IAEFzF,SAAS,CAAC,yBAAyB,EAAE;MACnCkE,cAAc,GAAAgB,sBAAA,GAAE7G,eAAe,CAAC8F,OAAO,qBAAvBe,sBAAA,CAAyBzB,EAAG;MAC5Ce,QAAQ,EAAElE,qBAAqB,CAAC6D,OAAO,CAACK,QAAQ;MAChDD,QAAQ,EAAEjE,qBAAqB,CAAC6D,OAAO,CAACI,QAAQ;MAChDU,uBAAuB;MACvBS,KAAK,EAAEP,SAAS,CAACQ,eAAe;MAChCC,mBAAmB,EAAER,UAAU,CAACQ,mBAAmB;MACnDC,eAAe,EAAEV,SAAS,CAACW,WAAW;MACtCC,gBAAgB,EAAEX,UAAU,CAACU;IAC/B,CAAC,CAAC;EACJ;EAEA,SAASE,yBAAyBA,CAAA,EAAG;IACnC5F,gBAAgB,CAAC+D,OAAO,GAAG,MAAM;EACnC;EAEA,IAAA8B,oDAAyB,EAAC;IACxBvF,MAAM,EAAE,MAAM;IACdwF,aAAa,EAAEzB,uBAAuB;IACtC0B,WAAW,EAAEzB,wBAAwB;IACrC0B,YAAY,EAAEC,sCAA2B;IACzCC,UAAU,EAAE1B;EACd,CAAC,CAAC;EACF,IAAAqB,oDAAyB,EAAC;IACxBvF,MAAM,EAAE,OAAO;IACfwF,aAAa,EAAErB,wBAAwB;IACvCsB,WAAW,EAAEH,yBAAyB;IACtCM,UAAU,EAAEC;EACd,CAAC,CAAC;EAEF,SAASC,4BAA4BA,CAACjI,IAA2B,EAAE;IAAA,IAAAkI,sBAAA;IACjEzG,SAAS,CAAC,mBAAmB,EAAE;MAC7BkE,cAAc,GAAAuC,sBAAA,GAAEpI,eAAe,CAAC8F,OAAO,qBAAvBsC,sBAAA,CAAyBhD,EAAG;MAC5CiD,cAAc,EAAEnI,IAAI,CAACoI;IACvB,CAAC,CAAC;EACJ;EAEA,SAASC,4BAA4BA,CAACC,KAA4B,EAAE;IAAA,IAAAC,sBAAA;IAClE5G,oBAAoB,CAACiE,OAAO,GAAG,IAAI;IACnCnE,SAAS,CAAC,mBAAmB,EAAE;MAC7BkE,cAAc,GAAA4C,sBAAA,GAAEzI,eAAe,CAAC8F,OAAO,qBAAvB2C,sBAAA,CAAyBrD;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAesD,oBAAoBA,CAACxI,IAAmB,EAAE;IACvD,MAAMC,cAAc,CAAC2F,OAAO,CAAC6C,wBAAwB,CAACzI,IAAI,EAAEJ,WAAW,CAAC;EAC1E;EAEA,MAAM8I,mBAGH,GAAG,CACJ;IACEC,KAAK,EAAEC,2BAAoB;IAC3BC,MAAM,EAAEL;EACV,CAAC,EACD;IACEG,KAAK,EAAEG,+BAAwB;IAC/BD,MAAM,EAAEpD;EACV,CAAC,EACD;IACEkD,KAAK,EAAEI,mCAA4B;IACnCF,MAAM,EAAEZ;EACV,CAAC,EACD;IACEU,KAAK,EAAEK,mCAA4B;IACnCH,MAAM,EAAER;EACV,CAAC,CACF;EAED,SAASY,uBAAuBA,CAACC,OAAmB,EAAE;IACpD,MAAMC,OAAO,GAAG,IAAAC,wBAAiB,EAACF,OAAO,CAAC;IAC1C,IAAIC,OAAO,KAAK,IAAI,EAAE;MACpB;IACF;IACA,KAAK,MAAM;MAAER,KAAK;MAAEE;IAAO,CAAC,IAAIH,mBAAmB,EAAE;MACnD,IAAIC,KAAK,CAACQ,OAAO,CAAC,EAAE;QAClB,KAAKrC,OAAO,CAACuC,OAAO,CAACR,MAAM,CAACM,OAAO,CAAC,CAAC,CAACG,KAAK,CAAE3E,KAAK,IAAK;UACrDC,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;QAC/D,CAAC,CAAC;QACF;MACF;IACF;EACF;EAEA,SAAS4E,oBAAoBA,CAAA,EAAG;IAAA,IAAAC,sBAAA;IAC9BxH,cAAc,CAAC4D,OAAO,GAAG,IAAI;IAC7BvF,sBAAsB,CAAC,QAAQ,CAAC;IAChCe,uBAAuB,CAAC,SAAS,CAAC;IAClCK,SAAS,CAAC,aAAa,EAAE;MACvBkE,cAAc,GAAA6D,sBAAA,GAAE1J,eAAe,CAAC8F,OAAO,qBAAvB4D,sBAAA,CAAyBtE;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAeuE,0BAA0BA,CAAC9E,KAAY,EAAE;IACtDC,OAAO,CAACD,KAAK,CAAC,kBAAkB,EAAEA,KAAK,CAAC;IACxCxE,qBAAqB,CAAC,OAAO,CAAC;EAChC;EAEA,SAASuJ,uBAAuBA,CAACC,MAAyB,EAAE;IAC1D3H,cAAc,CAAC4D,OAAO,GAAG,KAAK;IAC9B/D,gBAAgB,CAAC+D,OAAO,GAAG,MAAM;IACjC9D,aAAa,CAAC8D,OAAO,GAAG,IAAI;IAC5B7D,qBAAqB,CAAC6D,OAAO,GAAG,CAAC,CAAC;IAClCvE,qBAAqB,CAAC,MAAM,CAAC;IAC7BD,uBAAuB,CAAC,MAAM,CAAC;IAC/BG,oBAAoB,CAAC,MAAM,CAAC;IAC5BlB,sBAAsB,CAAC,MAAM,CAAC;IAE9B,IAAIsB,oBAAoB,CAACiE,OAAO,EAAE;MAChCjE,oBAAoB,CAACiE,OAAO,GAAG,KAAK;MACpCzF,qBAAqB,CAAC,oBAAoB,CAAC;MAC3C;IACF;IAEA,QAAQwJ,MAAM;MACZ,KAAKC,+BAAgB,CAACC,gBAAgB;QACpC;MACF,KAAKD,+BAAgB,CAACE,WAAW;QAC/B3J,qBAAqB,CAAC,WAAW,CAAC;QAClC;MACF;QACEyE,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEgF,MAAM,CAAC;QAC9DxJ,qBAAqB,CAAC,OAAO,CAAC;QAC9B;IACJ;EACF;EAEA,SAAS4J,+BAA+BA,CAAChF,WAA8B,EAAE;IACvE,IAAI,IAAAiF,uCAAgC,EAACjF,WAAW,EAAE3G,IAAI,CAAC,EAAE;MACvDqG,eAAe,CAACM,WAAW,CAAC;IAC9B;EACF;EAEA,SAASN,eAAeA,CAACM,WAA8B,EAAE;IAAA,IAAAkF,sBAAA;IACvD7I,uBAAuB,CAAC,QAAQ,CAAC;IACjCK,SAAS,CAAC,aAAa,EAAE;MACvBkE,cAAc,GAAAsE,sBAAA,GAAEnK,eAAe,CAAC8F,OAAO,qBAAvBqE,sBAAA,CAAyB/E,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,SAASmF,kCAAkCA,CAACnF,WAA8B,EAAE;IAAA,IAAAoF,sBAAA;IAC1E/I,uBAAuB,CAAC,MAAM,CAAC;IAC/BK,SAAS,CAAC,WAAW,EAAE;MACrBkE,cAAc,GAAAwE,sBAAA,GAAErK,eAAe,CAAC8F,OAAO,qBAAvBuE,sBAAA,CAAyBjF,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,eAAeqF,KAAKA,CAAA,EAAG;IACrB,IAAIhK,mBAAmB,KAAK,QAAQ,IAAIA,mBAAmB,KAAK,SAAS,EAAE;MACzE;IACF;IAEA,IAAI;MAAA,IAAAiK,sBAAA;MACFhK,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMrB,IAAI,oBAAJA,IAAI,CAAEsL,UAAU,CAAC,IAAI,CAAC;MAC5BnK,qBAAqB,CAAC,WAAW,CAAC;MAClCI,WAAW,CAACqD,SAAS,CAAC;MACtBnC,SAAS,CAAC,WAAW,EAAE;QACrBkE,cAAc,GAAA0E,sBAAA,GAAEvK,eAAe,CAAC8F,OAAO,qBAAvByE,sBAAA,CAAyBnF;MAC3C,CAAC,CAAC;IACJ,CAAC,CAAC,OAAOP,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,iBAAiB,EAAEA,KAAK,CAAC;MACvCxE,qBAAqB,CAAC,OAAO,CAAC;IAChC;EACF;EAEA,eAAewC,YAAYA,CAAA,EAAG;IAAA,IAAA4H,sBAAA,EAAAC,sBAAA;IAC5B/I,SAAS,CAAC,cAAc,EAAE;MACxBkE,cAAc,GAAA4E,sBAAA,GAAEzK,eAAe,CAAC8F,OAAO,qBAAvB2E,sBAAA,CAAyBrF,EAAG;MAC5CvB,KAAK,GAAA6G,sBAAA,GAAE1K,eAAe,CAAC8F,OAAO,qBAAvB4E,sBAAA,CAAyB7G;IAClC,CAAC,CAAC;IACF,MAAMyG,KAAK,CAAC,CAAC;IACbjK,qBAAqB,CAAC,UAAU,CAAC;EACnC;EAEA,eAAesK,SAASA,CAAA,EAAG;IAAA,IAAAC,uBAAA;IACzBjJ,SAAS,CAAC,WAAW,EAAE;MACrBkE,cAAc,GAAA+E,uBAAA,GAAE5K,eAAe,CAAC8F,OAAO,qBAAvB8E,uBAAA,CAAyBxF;IAC3C,CAAC,CAAC;IAEF,MAAM,IAAAyF,qCAA8B,EAAC3L,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC;EAC7D;EAEA,eAAe4L,iBAAiBA,CAAA,EAAG;IACjC,MAAM,IAAAD,qCAA8B,EAClC3L,IAAI,EACJ;MAAEZ,IAAI,EAAE;IAAqB,CAAC,EAC9B,oBACF,CAAC;EACH;EAEA,eAAeyM,IAAIA,CAAC1F,OAAe,EAAE2F,WAAyB,GAAG,EAAE,EAAE;IAAA,IAAAC,uBAAA;IACnE,OAAM/L,IAAI,oBAAJA,IAAI,CAAEmE,gBAAgB,CAAC6H,QAAQ,CAAC7F,OAAO,EAAE;MAC7C8F,KAAK,EAAE,SAAS;MAChBC,UAAU,EAAE;QACVJ,WAAW,EAAE,IAAAK,oBAAa,EAACL,WAAW;MACxC;IACF,CAAC,CAAC;IACFrJ,SAAS,CAAC,iBAAiB,EAAE;MAC3BkE,cAAc,GAAAoF,uBAAA,GAAEjL,eAAe,CAAC8F,OAAO,qBAAvBmF,uBAAA,CAAyB7F,EAAG;MAC5CC;IACF,CAAC,CAAC;EACJ;EAEA,SAASpC,kBAAkBA,CAAA,EAAG;IAC5B/D,IAAI,CACDoM,EAAE,CAAC,WAAW,EAAE7B,oBAAoB,CAAC,CACrC6B,EAAE,CAAC,iBAAiB,EAAE3B,0BAA0B,CAAC,CACjD2B,EAAE,CAAC,cAAc,EAAE1B,uBAAuB,CAAC,CAC3C0B,EAAE,CAAC,uBAAuB,EAAEvG,gCAAgC,CAAC,CAC7DuG,EAAE,CAAC,sBAAsB,EAAErB,+BAA+B,CAAC,CAC3DqB,EAAE,CAAC,yBAAyB,EAAElB,kCAAkC,CAAC,CACjEkB,EAAE,CAAC,cAAc,EAAEnC,uBAAuB,CAAC;EAChD;EAEA,SAASjG,oBAAoBA,CAAA,EAAG;IAC9BhE,IAAI,CAACqM,GAAG,CAAC,WAAW,EAAE9B,oBAAoB,CAAC;IAC3CvK,IAAI,CAACqM,GAAG,CAAC,iBAAiB,EAAE5B,0BAA0B,CAAC;IACvDzK,IAAI,CAACqM,GAAG,CAAC,cAAc,EAAE3B,uBAAuB,CAAC;IACjD1K,IAAI,CAACqM,GAAG,CAAC,uBAAuB,EAAExG,gCAAgC,CAAC;IACnE7F,IAAI,CAACqM,GAAG,CAAC,sBAAsB,EAAEtB,+BAA+B,CAAC;IACjE/K,IAAI,CAACqM,GAAG,CAAC,yBAAyB,EAAEnB,kCAAkC,CAAC;IACvElL,IAAI,CAACqM,GAAG,CAAC,cAAc,EAAEpC,uBAAuB,CAAC;EACnD;EAEA,OAAO;IACLqC,MAAM,EAAEpL,kBAAkB;IAC1BpB,YAAY,EAAEA,YAAY,CAACkB,IAAI;IAC/ByD,IAAI;IACJoH,IAAI;IACJJ,SAAS;IACTG,iBAAiB;IACjBR;EACF,CAAC;AACH","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useSpeechActivityDetector","_useParticipantTrack","_useEmitConversationEvent","_useToolCallingRuntime","_utils","_constants","useConversation","autoJoin","type","config","startWithMicrophone","startWithCamera","firstConversation","lastConversationTopic","_conversation$data2","setLogLevel","LogLevel","silent","conversation","useCreateConversation","room","useEnsureRoom","speaker","useAtomValue","state","microphone","setMicrophone","useAtom","camera","setCamera","toolRuntime","useToolCallingRuntime","toolAdapter","createLivekitToolAdapter","conversationRef","useLatest","data","toolRuntimeRef","conversationStatus","setConversationStatus","userConnectionState","setUserConnectionState","joinedAt","setJoinedAt","setActiveMediaDevice","setMicrophoneDeviceId","useMediaDeviceSelect","kind","setSpeakerDeviceId","setCameraDeviceId","requestPermissions","enabled","setTranscriptions","useSetAtom","transcriptions","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","useEmitConversationEvent","inactivityTimeoutRef","useRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userCumulativeTrackStatsRef","undefined","agentCumulativeTrackStatsRef","userMicPublication","useParticipantTrack","source","Source","Microphone","agentMicPublication","timer","useTimer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","useEffect","registerRoomEvents","unregisterRoomEvents","useUpdateEffect","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","restart","getTime","_conversation$data3","invariant","url","URL","accessToken","searchParams","get","connect","remoteParticipant","findJoinedAgentParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","ParticipantKind","AGENT","old","mergeTranscriptions","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","ACOUSTIC_USER_HANGOVER_MS","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","userReport","agentReport","Promise","all","getTrackStats","userStats","parseTrackStats","agentStats","cumulativeTrackStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","useSpeechActivityDetector","onSpeechStart","onSpeechEnd","thresholdRms","ACOUSTIC_USER_THRESHOLD_RMS","hangoverMs","ACOUSTIC_AGENT_HANGOVER_MS","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","checkIsToolCallsData","handle","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","payload","decoded","decodeDataPayload","resolve","catch","handleConnectedEvent","_conversationRef$curr6","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","DisconnectReason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","shouldHandleParticipantConnected","_conversationRef$curr7","handleParticipantDisconnectedEvent","_conversationRef$curr8","leave","_conversationRef$curr9","disconnect","_conversationRef$curr0","_conversationRef$curr1","interrupt","_conversationRef$curr10","publishConversationDataMessage","dismissInactivity","send","attachments","_conversationRef$curr11","sendText","topic","attributes","safeStringify","on","off","status"],"sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n DisconnectReason,\n Participant,\n setLogLevel,\n ParticipantKind,\n RemoteParticipant,\n TranscriptionSegment,\n LogLevel,\n} from 'livekit-client';\nimport invariant from 'invariant';\nimport { useTimer } from 'react-timer-hook';\nimport { useLatest, useUpdateEffect } from 'react-use';\nimport { useEnsureRoom, useMediaDeviceSelect } from '@livekit/components-react';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\nimport {\n Conversation,\n state,\n type ConversationTranscription,\n} from '../../../conversation';\nimport type {\n UseConversationResult,\n UseConversationOptions,\n Attachment,\n} from '../types';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n ToolCallsData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n type CumulativeTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n checkIsToolCallsData,\n createLivekitToolAdapter,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n publishConversationDataMessage,\n safeStringify,\n shouldHandleParticipantConnected,\n} from './utils';\nimport {\n ACOUSTIC_AGENT_HANGOVER_MS,\n ACOUSTIC_USER_HANGOVER_MS,\n ACOUSTIC_USER_THRESHOLD_RMS,\n} from './constants';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n firstConversation,\n lastConversationTopic,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({\n type,\n config,\n firstConversation,\n lastConversationTopic,\n });\n const room = useEnsureRoom();\n const speaker = useAtomValue(state.speaker);\n const [microphone, setMicrophone] = useAtom(state.microphone);\n const [camera, setCamera] = useAtom(state.camera);\n const toolRuntime = useToolCallingRuntime();\n const toolAdapter = createLivekitToolAdapter(room);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n const userCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n const agentCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userReport, agentReport] = await Promise.all([\n getTrackStats(userMicPublication),\n getTrackStats(agentMicPublication),\n ]);\n const userStats = parseTrackStats(\n userReport,\n userCumulativeTrackStatsRef.current,\n );\n const agentStats = parseTrackStats(\n agentReport,\n agentCumulativeTrackStatsRef.current,\n );\n userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;\n agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleToolCallsEvent(data: ToolCallsData) {\n await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsToolCallsData,\n handle: handleToolCallsEvent as (data: unknown) => Promise<void>,\n },\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n userCumulativeTrackStatsRef.current = undefined;\n agentCumulativeTrackStatsRef.current = undefined;\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n }\n\n function unregisterRoomEvents() {\n room.off('connected', handleConnectedEvent);\n room.off('encryptionError', handleEncryptionErrorEvent);\n room.off('disconnected', handleDisconnectedEvent);\n room.off('transcriptionReceived', handleTranscriptionReceivedEvent);\n room.off('participantConnected', handleParticipantConnectedEvent);\n room.off('participantDisconnected', handleParticipantDisconnectedEvent);\n room.off('dataReceived', handleDataReceivedEvent);\n }\n\n return {\n status: conversationStatus,\n conversation: conversation.data,\n join,\n send,\n interrupt,\n dismissInactivity,\n leave,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,29 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.parseTrackStats = parseTrackStats;
|
|
5
|
-
function parseTrackStats(report) {
|
|
5
|
+
function parseTrackStats(report, previous) {
|
|
6
6
|
if (!report) {
|
|
7
7
|
return {};
|
|
8
8
|
}
|
|
9
9
|
const result = {};
|
|
10
|
+
const cumulativeTrackStats = {};
|
|
10
11
|
for (const stat of report.values()) {
|
|
11
12
|
if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {
|
|
12
13
|
if (typeof stat.roundTripTime === 'number') {
|
|
13
14
|
result.roundTripTimeMs = stat.roundTripTime * 1000;
|
|
14
15
|
}
|
|
15
16
|
if (typeof stat.packetsLost === 'number') {
|
|
16
|
-
|
|
17
|
+
cumulativeTrackStats.packetsLost = stat.packetsLost;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {
|
|
20
|
-
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number'
|
|
21
|
-
|
|
21
|
+
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number') {
|
|
22
|
+
const jitterBuffer = {
|
|
23
|
+
delay: stat.jitterBufferDelay,
|
|
24
|
+
emittedCount: stat.jitterBufferEmittedCount
|
|
25
|
+
};
|
|
26
|
+
cumulativeTrackStats.jitterBuffer = jitterBuffer;
|
|
27
|
+
result.jitterBufferDelayMs = jitterBufferDelayMsForInterval(jitterBuffer, previous == null ? void 0 : previous.jitterBuffer);
|
|
22
28
|
}
|
|
23
29
|
if (typeof stat.packetsLost === 'number') {
|
|
24
|
-
|
|
30
|
+
cumulativeTrackStats.packetsLost = stat.packetsLost;
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
}
|
|
34
|
+
if (typeof cumulativeTrackStats.packetsLost === 'number') {
|
|
35
|
+
result.packetsLost = packetsLostForInterval(cumulativeTrackStats.packetsLost, previous == null ? void 0 : previous.packetsLost);
|
|
36
|
+
}
|
|
37
|
+
if (cumulativeTrackStats.jitterBuffer != null || cumulativeTrackStats.packetsLost != null) {
|
|
38
|
+
result.cumulativeTrackStats = cumulativeTrackStats;
|
|
39
|
+
}
|
|
28
40
|
return result;
|
|
29
41
|
}
|
|
42
|
+
function packetsLostForInterval(current, previous) {
|
|
43
|
+
const delta = current - (previous ?? 0);
|
|
44
|
+
if (delta >= 0) {
|
|
45
|
+
return delta;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Counters reset (new inbound track / SSRC).
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
function jitterBufferDelayMsForInterval(current, previous) {
|
|
52
|
+
const prevDelay = (previous == null ? void 0 : previous.delay) ?? 0;
|
|
53
|
+
const prevCount = (previous == null ? void 0 : previous.emittedCount) ?? 0;
|
|
54
|
+
const deltaDelay = current.delay - prevDelay;
|
|
55
|
+
const deltaCount = current.emittedCount - prevCount;
|
|
56
|
+
if (deltaCount > 0 && deltaDelay >= 0) {
|
|
57
|
+
return deltaDelay / deltaCount * 1000;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Counters reset (new inbound track / SSRC) — fall back to lifetime average.
|
|
61
|
+
if (previous && deltaCount < 0 && current.emittedCount > 0) {
|
|
62
|
+
return current.delay / current.emittedCount * 1000;
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
30
66
|
//# sourceMappingURL=parseTrackStats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["parseTrackStats","report","result","stat","values","type","kind","roundTripTime","roundTripTimeMs","packetsLost","jitterBufferDelay","jitterBufferEmittedCount","jitterBufferDelayMs"],"sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"sourcesContent":["export type ParsedTrackStats = {\n roundTripTimeMs?: number;\n jitterBufferDelayMs?: number;\n packetsLost?: number;\n};\n\nexport function parseTrackStats(\n report: RTCStatsReport | undefined,\n): ParsedTrackStats {\n if (!report) {\n return {};\n }\n\n const result: ParsedTrackStats = {};\n\n for (const stat of report.values()) {\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {\n if (typeof stat.roundTripTime === 'number') {\n result.roundTripTimeMs = stat.roundTripTime * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n
|
|
1
|
+
{"version":3,"names":["parseTrackStats","report","previous","result","cumulativeTrackStats","stat","values","type","kind","roundTripTime","roundTripTimeMs","packetsLost","jitterBufferDelay","jitterBufferEmittedCount","jitterBuffer","delay","emittedCount","jitterBufferDelayMs","jitterBufferDelayMsForInterval","packetsLostForInterval","current","delta","prevDelay","prevCount","deltaDelay","deltaCount","undefined"],"sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"sourcesContent":["export type ParsedTrackStats = {\n roundTripTimeMs?: number;\n jitterBufferDelayMs?: number;\n packetsLost?: number;\n cumulativeTrackStats?: CumulativeTrackStats;\n};\n\nexport type CumulativeJitterBufferStats = {\n delay: number;\n emittedCount: number;\n};\n\nexport type CumulativeTrackStats = {\n jitterBuffer?: CumulativeJitterBufferStats;\n packetsLost?: number;\n};\n\nexport function parseTrackStats(\n report: RTCStatsReport | undefined,\n previous?: CumulativeTrackStats,\n): ParsedTrackStats {\n if (!report) {\n return {};\n }\n\n const result: ParsedTrackStats = {};\n const cumulativeTrackStats: CumulativeTrackStats = {};\n\n for (const stat of report.values()) {\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {\n if (typeof stat.roundTripTime === 'number') {\n result.roundTripTimeMs = stat.roundTripTime * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n cumulativeTrackStats.packetsLost = stat.packetsLost;\n }\n }\n\n if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {\n if (\n typeof stat.jitterBufferDelay === 'number' &&\n typeof stat.jitterBufferEmittedCount === 'number'\n ) {\n const jitterBuffer: CumulativeJitterBufferStats = {\n delay: stat.jitterBufferDelay,\n emittedCount: stat.jitterBufferEmittedCount,\n };\n cumulativeTrackStats.jitterBuffer = jitterBuffer;\n result.jitterBufferDelayMs = jitterBufferDelayMsForInterval(\n jitterBuffer,\n previous?.jitterBuffer,\n );\n }\n if (typeof stat.packetsLost === 'number') {\n cumulativeTrackStats.packetsLost = stat.packetsLost;\n }\n }\n }\n\n if (typeof cumulativeTrackStats.packetsLost === 'number') {\n result.packetsLost = packetsLostForInterval(\n cumulativeTrackStats.packetsLost,\n previous?.packetsLost,\n );\n }\n\n if (\n cumulativeTrackStats.jitterBuffer != null ||\n cumulativeTrackStats.packetsLost != null\n ) {\n result.cumulativeTrackStats = cumulativeTrackStats;\n }\n\n return result;\n}\n\nfunction packetsLostForInterval(current: number, previous?: number): number {\n const delta = current - (previous ?? 0);\n if (delta >= 0) {\n return delta;\n }\n\n // Counters reset (new inbound track / SSRC).\n return current;\n}\n\nfunction jitterBufferDelayMsForInterval(\n current: CumulativeJitterBufferStats,\n previous?: CumulativeJitterBufferStats,\n): number | undefined {\n const prevDelay = previous?.delay ?? 0;\n const prevCount = previous?.emittedCount ?? 0;\n const deltaDelay = current.delay - prevDelay;\n const deltaCount = current.emittedCount - prevCount;\n\n if (deltaCount > 0 && deltaDelay >= 0) {\n return (deltaDelay / deltaCount) * 1000;\n }\n\n // Counters reset (new inbound track / SSRC) — fall back to lifetime average.\n if (previous && deltaCount < 0 && current.emittedCount > 0) {\n return (current.delay / current.emittedCount) * 1000;\n }\n\n return undefined;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -80,6 +80,8 @@ export function useConversation(_ref) {
|
|
|
80
80
|
const acousticT0Ref = useRef(null);
|
|
81
81
|
const latestTurnMetadataRef = useRef({});
|
|
82
82
|
const isConnectedRef = useRef(false);
|
|
83
|
+
const userCumulativeTrackStatsRef = useRef(undefined);
|
|
84
|
+
const agentCumulativeTrackStatsRef = useRef(undefined);
|
|
83
85
|
const userMicPublication = useParticipantTrack({
|
|
84
86
|
type: 'user',
|
|
85
87
|
source: Source.Microphone
|
|
@@ -257,9 +259,13 @@ export function useConversation(_ref) {
|
|
|
257
259
|
}
|
|
258
260
|
async function emitConversationTurnLatency(clientAcousticLatencyMs) {
|
|
259
261
|
var _conversationRef$curr3;
|
|
260
|
-
const _await$Promise$all = await Promise.all([getTrackStats(userMicPublication)
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
const _await$Promise$all = await Promise.all([getTrackStats(userMicPublication), getTrackStats(agentMicPublication)]),
|
|
263
|
+
userReport = _await$Promise$all[0],
|
|
264
|
+
agentReport = _await$Promise$all[1];
|
|
265
|
+
const userStats = parseTrackStats(userReport, userCumulativeTrackStatsRef.current);
|
|
266
|
+
const agentStats = parseTrackStats(agentReport, agentCumulativeTrackStatsRef.current);
|
|
267
|
+
userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;
|
|
268
|
+
agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;
|
|
263
269
|
emitEvent('conversationTurnLatency', {
|
|
264
270
|
conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id,
|
|
265
271
|
speechId: latestTurnMetadataRef.current.speechId,
|
|
@@ -351,6 +357,8 @@ export function useConversation(_ref) {
|
|
|
351
357
|
acousticPhaseRef.current = 'idle';
|
|
352
358
|
acousticT0Ref.current = null;
|
|
353
359
|
latestTurnMetadataRef.current = {};
|
|
360
|
+
userCumulativeTrackStatsRef.current = undefined;
|
|
361
|
+
agentCumulativeTrackStatsRef.current = undefined;
|
|
354
362
|
setAgentActivityState('idle');
|
|
355
363
|
setAgentConnectionState('idle');
|
|
356
364
|
setUserActivityState('idle');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","DisconnectReason","setLogLevel","ParticipantKind","LogLevel","invariant","useTimer","useLatest","useUpdateEffect","useEnsureRoom","useMediaDeviceSelect","useAtom","useAtomValue","useSetAtom","state","useCreateConversation","useSpeechActivityDetector","useParticipantTrack","Source","getTrackStats","parseTrackStats","useEmitConversationEvent","useToolCallingRuntime","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","checkIsToolCallsData","createLivekitToolAdapter","decodeDataPayload","findJoinedAgentParticipant","mergeTranscriptions","publishConversationDataMessage","safeStringify","shouldHandleParticipantConnected","ACOUSTIC_AGENT_HANGOVER_MS","ACOUSTIC_USER_HANGOVER_MS","ACOUSTIC_USER_THRESHOLD_RMS","useConversation","_ref","_conversation$data2","_ref$autoJoin","autoJoin","type","config","_ref$startWithMicroph","startWithMicrophone","_ref$startWithCamera","startWithCamera","firstConversation","lastConversationTopic","silent","conversation","room","speaker","_useAtom","microphone","setMicrophone","_useAtom2","camera","setCamera","toolRuntime","toolAdapter","conversationRef","data","toolRuntimeRef","_useAtom3","conversationStatus","setConversationStatus","_useAtom4","userConnectionState","setUserConnectionState","_useAtom5","joinedAt","setJoinedAt","_useMediaDeviceSelect","kind","setMicrophoneDeviceId","setActiveMediaDevice","_useMediaDeviceSelect2","setSpeakerDeviceId","_useMediaDeviceSelect3","requestPermissions","enabled","setCameraDeviceId","setTranscriptions","transcriptions","_useAtom6","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","inactivityTimeoutRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userMicPublication","source","Microphone","agentMicPublication","timer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","registerRoomEvents","unregisterRoomEvents","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","undefined","restart","getTime","_conversation$data3","url","URL","accessToken","searchParams","get","connect","remoteParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","AGENT","old","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","_await$Promise$all","Promise","all","then","userStats","agentStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","onSpeechStart","onSpeechEnd","thresholdRms","hangoverMs","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","handle","handleDataReceivedEvent","payload","decoded","_ref2","resolve","catch","handleConnectedEvent","_conversationRef$curr6","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","_conversationRef$curr7","handleParticipantDisconnectedEvent","_conversationRef$curr8","leave","_conversationRef$curr9","disconnect","_conversationRef$curr0","_conversationRef$curr1","interrupt","_conversationRef$curr10","dismissInactivity","send","attachments","_conversationRef$curr11","sendText","topic","attributes","on","off","status"],"sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n DisconnectReason,\n Participant,\n setLogLevel,\n ParticipantKind,\n RemoteParticipant,\n TranscriptionSegment,\n LogLevel,\n} from 'livekit-client';\nimport invariant from 'invariant';\nimport { useTimer } from 'react-timer-hook';\nimport { useLatest, useUpdateEffect } from 'react-use';\nimport { useEnsureRoom, useMediaDeviceSelect } from '@livekit/components-react';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\nimport {\n Conversation,\n state,\n type ConversationTranscription,\n} from '../../../conversation';\nimport type {\n UseConversationResult,\n UseConversationOptions,\n Attachment,\n} from '../types';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n ToolCallsData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n checkIsToolCallsData,\n createLivekitToolAdapter,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n publishConversationDataMessage,\n safeStringify,\n shouldHandleParticipantConnected,\n} from './utils';\nimport {\n ACOUSTIC_AGENT_HANGOVER_MS,\n ACOUSTIC_USER_HANGOVER_MS,\n ACOUSTIC_USER_THRESHOLD_RMS,\n} from './constants';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n firstConversation,\n lastConversationTopic,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({\n type,\n config,\n firstConversation,\n lastConversationTopic,\n });\n const room = useEnsureRoom();\n const speaker = useAtomValue(state.speaker);\n const [microphone, setMicrophone] = useAtom(state.microphone);\n const [camera, setCamera] = useAtom(state.camera);\n const toolRuntime = useToolCallingRuntime();\n const toolAdapter = createLivekitToolAdapter(room);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userStats, agentStats] = await Promise.all([\n getTrackStats(userMicPublication).then(parseTrackStats),\n getTrackStats(agentMicPublication).then(parseTrackStats),\n ]);\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleToolCallsEvent(data: ToolCallsData) {\n await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsToolCallsData,\n handle: handleToolCallsEvent as (data: unknown) => Promise<void>,\n },\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n }\n\n function unregisterRoomEvents() {\n room.off('connected', handleConnectedEvent);\n room.off('encryptionError', handleEncryptionErrorEvent);\n room.off('disconnected', handleDisconnectedEvent);\n room.off('transcriptionReceived', handleTranscriptionReceivedEvent);\n room.off('participantConnected', handleParticipantConnectedEvent);\n room.off('participantDisconnected', handleParticipantDisconnectedEvent);\n room.off('dataReceived', handleDataReceivedEvent);\n }\n\n return {\n status: conversationStatus,\n conversation: conversation.data,\n join,\n send,\n interrupt,\n dismissInactivity,\n leave,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","DisconnectReason","setLogLevel","ParticipantKind","LogLevel","invariant","useTimer","useLatest","useUpdateEffect","useEnsureRoom","useMediaDeviceSelect","useAtom","useAtomValue","useSetAtom","state","useCreateConversation","useSpeechActivityDetector","useParticipantTrack","Source","getTrackStats","parseTrackStats","useEmitConversationEvent","useToolCallingRuntime","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","checkIsToolCallsData","createLivekitToolAdapter","decodeDataPayload","findJoinedAgentParticipant","mergeTranscriptions","publishConversationDataMessage","safeStringify","shouldHandleParticipantConnected","ACOUSTIC_AGENT_HANGOVER_MS","ACOUSTIC_USER_HANGOVER_MS","ACOUSTIC_USER_THRESHOLD_RMS","useConversation","_ref","_conversation$data2","_ref$autoJoin","autoJoin","type","config","_ref$startWithMicroph","startWithMicrophone","_ref$startWithCamera","startWithCamera","firstConversation","lastConversationTopic","silent","conversation","room","speaker","_useAtom","microphone","setMicrophone","_useAtom2","camera","setCamera","toolRuntime","toolAdapter","conversationRef","data","toolRuntimeRef","_useAtom3","conversationStatus","setConversationStatus","_useAtom4","userConnectionState","setUserConnectionState","_useAtom5","joinedAt","setJoinedAt","_useMediaDeviceSelect","kind","setMicrophoneDeviceId","setActiveMediaDevice","_useMediaDeviceSelect2","setSpeakerDeviceId","_useMediaDeviceSelect3","requestPermissions","enabled","setCameraDeviceId","setTranscriptions","transcriptions","_useAtom6","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","inactivityTimeoutRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userCumulativeTrackStatsRef","undefined","agentCumulativeTrackStatsRef","userMicPublication","source","Microphone","agentMicPublication","timer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","registerRoomEvents","unregisterRoomEvents","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","restart","getTime","_conversation$data3","url","URL","accessToken","searchParams","get","connect","remoteParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","AGENT","old","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","_await$Promise$all","Promise","all","userReport","agentReport","userStats","agentStats","cumulativeTrackStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","onSpeechStart","onSpeechEnd","thresholdRms","hangoverMs","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","handle","handleDataReceivedEvent","payload","decoded","_ref2","resolve","catch","handleConnectedEvent","_conversationRef$curr6","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","_conversationRef$curr7","handleParticipantDisconnectedEvent","_conversationRef$curr8","leave","_conversationRef$curr9","disconnect","_conversationRef$curr0","_conversationRef$curr1","interrupt","_conversationRef$curr10","dismissInactivity","send","attachments","_conversationRef$curr11","sendText","topic","attributes","on","off","status"],"sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n DisconnectReason,\n Participant,\n setLogLevel,\n ParticipantKind,\n RemoteParticipant,\n TranscriptionSegment,\n LogLevel,\n} from 'livekit-client';\nimport invariant from 'invariant';\nimport { useTimer } from 'react-timer-hook';\nimport { useLatest, useUpdateEffect } from 'react-use';\nimport { useEnsureRoom, useMediaDeviceSelect } from '@livekit/components-react';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\nimport {\n Conversation,\n state,\n type ConversationTranscription,\n} from '../../../conversation';\nimport type {\n UseConversationResult,\n UseConversationOptions,\n Attachment,\n} from '../types';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n ToolCallsData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n type CumulativeTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n checkIsToolCallsData,\n createLivekitToolAdapter,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n publishConversationDataMessage,\n safeStringify,\n shouldHandleParticipantConnected,\n} from './utils';\nimport {\n ACOUSTIC_AGENT_HANGOVER_MS,\n ACOUSTIC_USER_HANGOVER_MS,\n ACOUSTIC_USER_THRESHOLD_RMS,\n} from './constants';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n firstConversation,\n lastConversationTopic,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({\n type,\n config,\n firstConversation,\n lastConversationTopic,\n });\n const room = useEnsureRoom();\n const speaker = useAtomValue(state.speaker);\n const [microphone, setMicrophone] = useAtom(state.microphone);\n const [camera, setCamera] = useAtom(state.camera);\n const toolRuntime = useToolCallingRuntime();\n const toolAdapter = createLivekitToolAdapter(room);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n const userCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n const agentCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userReport, agentReport] = await Promise.all([\n getTrackStats(userMicPublication),\n getTrackStats(agentMicPublication),\n ]);\n const userStats = parseTrackStats(\n userReport,\n userCumulativeTrackStatsRef.current,\n );\n const agentStats = parseTrackStats(\n agentReport,\n agentCumulativeTrackStatsRef.current,\n );\n userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;\n agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleToolCallsEvent(data: ToolCallsData) {\n await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsToolCallsData,\n handle: handleToolCallsEvent as (data: unknown) => Promise<void>,\n },\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n userCumulativeTrackStatsRef.current = undefined;\n agentCumulativeTrackStatsRef.current = undefined;\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n }\n\n function unregisterRoomEvents() {\n room.off('connected', handleConnectedEvent);\n room.off('encryptionError', handleEncryptionErrorEvent);\n room.off('disconnected', handleDisconnectedEvent);\n room.off('transcriptionReceived', handleTranscriptionReceivedEvent);\n room.off('participantConnected', handleParticipantConnectedEvent);\n room.off('participantDisconnected', handleParticipantDisconnectedEvent);\n room.off('dataReceived', handleDataReceivedEvent);\n }\n\n return {\n status: conversationStatus,\n conversation: conversation.data,\n join,\n send,\n interrupt,\n dismissInactivity,\n leave,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,26 +1,62 @@
|
|
|
1
|
-
export function parseTrackStats(report) {
|
|
1
|
+
export function parseTrackStats(report, previous) {
|
|
2
2
|
if (!report) {
|
|
3
3
|
return {};
|
|
4
4
|
}
|
|
5
5
|
const result = {};
|
|
6
|
+
const cumulativeTrackStats = {};
|
|
6
7
|
for (const stat of report.values()) {
|
|
7
8
|
if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {
|
|
8
9
|
if (typeof stat.roundTripTime === 'number') {
|
|
9
10
|
result.roundTripTimeMs = stat.roundTripTime * 1000;
|
|
10
11
|
}
|
|
11
12
|
if (typeof stat.packetsLost === 'number') {
|
|
12
|
-
|
|
13
|
+
cumulativeTrackStats.packetsLost = stat.packetsLost;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {
|
|
16
|
-
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number'
|
|
17
|
-
|
|
17
|
+
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number') {
|
|
18
|
+
const jitterBuffer = {
|
|
19
|
+
delay: stat.jitterBufferDelay,
|
|
20
|
+
emittedCount: stat.jitterBufferEmittedCount
|
|
21
|
+
};
|
|
22
|
+
cumulativeTrackStats.jitterBuffer = jitterBuffer;
|
|
23
|
+
result.jitterBufferDelayMs = jitterBufferDelayMsForInterval(jitterBuffer, previous == null ? void 0 : previous.jitterBuffer);
|
|
18
24
|
}
|
|
19
25
|
if (typeof stat.packetsLost === 'number') {
|
|
20
|
-
|
|
26
|
+
cumulativeTrackStats.packetsLost = stat.packetsLost;
|
|
21
27
|
}
|
|
22
28
|
}
|
|
23
29
|
}
|
|
30
|
+
if (typeof cumulativeTrackStats.packetsLost === 'number') {
|
|
31
|
+
result.packetsLost = packetsLostForInterval(cumulativeTrackStats.packetsLost, previous == null ? void 0 : previous.packetsLost);
|
|
32
|
+
}
|
|
33
|
+
if (cumulativeTrackStats.jitterBuffer != null || cumulativeTrackStats.packetsLost != null) {
|
|
34
|
+
result.cumulativeTrackStats = cumulativeTrackStats;
|
|
35
|
+
}
|
|
24
36
|
return result;
|
|
25
37
|
}
|
|
38
|
+
function packetsLostForInterval(current, previous) {
|
|
39
|
+
const delta = current - (previous ?? 0);
|
|
40
|
+
if (delta >= 0) {
|
|
41
|
+
return delta;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Counters reset (new inbound track / SSRC).
|
|
45
|
+
return current;
|
|
46
|
+
}
|
|
47
|
+
function jitterBufferDelayMsForInterval(current, previous) {
|
|
48
|
+
const prevDelay = (previous == null ? void 0 : previous.delay) ?? 0;
|
|
49
|
+
const prevCount = (previous == null ? void 0 : previous.emittedCount) ?? 0;
|
|
50
|
+
const deltaDelay = current.delay - prevDelay;
|
|
51
|
+
const deltaCount = current.emittedCount - prevCount;
|
|
52
|
+
if (deltaCount > 0 && deltaDelay >= 0) {
|
|
53
|
+
return deltaDelay / deltaCount * 1000;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Counters reset (new inbound track / SSRC) — fall back to lifetime average.
|
|
57
|
+
if (previous && deltaCount < 0 && current.emittedCount > 0) {
|
|
58
|
+
return current.delay / current.emittedCount * 1000;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
26
62
|
//# sourceMappingURL=parseTrackStats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["parseTrackStats","report","result","stat","values","type","kind","roundTripTime","roundTripTimeMs","packetsLost","jitterBufferDelay","jitterBufferEmittedCount","jitterBufferDelayMs"],"sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"sourcesContent":["export type ParsedTrackStats = {\n roundTripTimeMs?: number;\n jitterBufferDelayMs?: number;\n packetsLost?: number;\n};\n\nexport function parseTrackStats(\n report: RTCStatsReport | undefined,\n): ParsedTrackStats {\n if (!report) {\n return {};\n }\n\n const result: ParsedTrackStats = {};\n\n for (const stat of report.values()) {\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {\n if (typeof stat.roundTripTime === 'number') {\n result.roundTripTimeMs = stat.roundTripTime * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n
|
|
1
|
+
{"version":3,"names":["parseTrackStats","report","previous","result","cumulativeTrackStats","stat","values","type","kind","roundTripTime","roundTripTimeMs","packetsLost","jitterBufferDelay","jitterBufferEmittedCount","jitterBuffer","delay","emittedCount","jitterBufferDelayMs","jitterBufferDelayMsForInterval","packetsLostForInterval","current","delta","prevDelay","prevCount","deltaDelay","deltaCount","undefined"],"sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"sourcesContent":["export type ParsedTrackStats = {\n roundTripTimeMs?: number;\n jitterBufferDelayMs?: number;\n packetsLost?: number;\n cumulativeTrackStats?: CumulativeTrackStats;\n};\n\nexport type CumulativeJitterBufferStats = {\n delay: number;\n emittedCount: number;\n};\n\nexport type CumulativeTrackStats = {\n jitterBuffer?: CumulativeJitterBufferStats;\n packetsLost?: number;\n};\n\nexport function parseTrackStats(\n report: RTCStatsReport | undefined,\n previous?: CumulativeTrackStats,\n): ParsedTrackStats {\n if (!report) {\n return {};\n }\n\n const result: ParsedTrackStats = {};\n const cumulativeTrackStats: CumulativeTrackStats = {};\n\n for (const stat of report.values()) {\n if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {\n if (typeof stat.roundTripTime === 'number') {\n result.roundTripTimeMs = stat.roundTripTime * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n cumulativeTrackStats.packetsLost = stat.packetsLost;\n }\n }\n\n if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {\n if (\n typeof stat.jitterBufferDelay === 'number' &&\n typeof stat.jitterBufferEmittedCount === 'number'\n ) {\n const jitterBuffer: CumulativeJitterBufferStats = {\n delay: stat.jitterBufferDelay,\n emittedCount: stat.jitterBufferEmittedCount,\n };\n cumulativeTrackStats.jitterBuffer = jitterBuffer;\n result.jitterBufferDelayMs = jitterBufferDelayMsForInterval(\n jitterBuffer,\n previous?.jitterBuffer,\n );\n }\n if (typeof stat.packetsLost === 'number') {\n cumulativeTrackStats.packetsLost = stat.packetsLost;\n }\n }\n }\n\n if (typeof cumulativeTrackStats.packetsLost === 'number') {\n result.packetsLost = packetsLostForInterval(\n cumulativeTrackStats.packetsLost,\n previous?.packetsLost,\n );\n }\n\n if (\n cumulativeTrackStats.jitterBuffer != null ||\n cumulativeTrackStats.packetsLost != null\n ) {\n result.cumulativeTrackStats = cumulativeTrackStats;\n }\n\n return result;\n}\n\nfunction packetsLostForInterval(current: number, previous?: number): number {\n const delta = current - (previous ?? 0);\n if (delta >= 0) {\n return delta;\n }\n\n // Counters reset (new inbound track / SSRC).\n return current;\n}\n\nfunction jitterBufferDelayMsForInterval(\n current: CumulativeJitterBufferStats,\n previous?: CumulativeJitterBufferStats,\n): number | undefined {\n const prevDelay = previous?.delay ?? 0;\n const prevCount = previous?.emittedCount ?? 0;\n const deltaDelay = current.delay - prevDelay;\n const deltaCount = current.emittedCount - prevCount;\n\n if (deltaCount > 0 && deltaDelay >= 0) {\n return (deltaDelay / deltaCount) * 1000;\n }\n\n // Counters reset (new inbound track / SSRC) — fall back to lifetime average.\n if (previous && deltaCount < 0 && current.emittedCount > 0) {\n return (current.delay / current.emittedCount) * 1000;\n }\n\n return undefined;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConversation.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EAEvB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"useConversation.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EAEvB,MAAM,UAAU,CAAC;AAsClB,wBAAgB,eAAe,CAAC,EAC9B,QAAe,EACf,IAAI,EACJ,MAAM,EACN,mBAA2B,EAC3B,eAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACtB,EAAE,sBAAsB,GAAG,qBAAqB,CAugBhD"}
|
|
@@ -2,6 +2,15 @@ export type ParsedTrackStats = {
|
|
|
2
2
|
roundTripTimeMs?: number;
|
|
3
3
|
jitterBufferDelayMs?: number;
|
|
4
4
|
packetsLost?: number;
|
|
5
|
+
cumulativeTrackStats?: CumulativeTrackStats;
|
|
5
6
|
};
|
|
6
|
-
export
|
|
7
|
+
export type CumulativeJitterBufferStats = {
|
|
8
|
+
delay: number;
|
|
9
|
+
emittedCount: number;
|
|
10
|
+
};
|
|
11
|
+
export type CumulativeTrackStats = {
|
|
12
|
+
jitterBuffer?: CumulativeJitterBufferStats;
|
|
13
|
+
packetsLost?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function parseTrackStats(report: RTCStatsReport | undefined, previous?: CumulativeTrackStats): ParsedTrackStats;
|
|
7
16
|
//# sourceMappingURL=parseTrackStats.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseTrackStats.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"parseTrackStats.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useParticipantTrack/parseTrackStats.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,gBAAgB,CAsDlB"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.23.0",
|
|
3
3
|
"name": "@wix/legends-platform-sdk",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"wallaby": {
|
|
104
104
|
"autoDetect": true
|
|
105
105
|
},
|
|
106
|
-
"falconPackageHash": "
|
|
106
|
+
"falconPackageHash": "c9a2a0d69d8ebf191caa0b6b3288d08d88a81caa3e17868e5e42f48c"
|
|
107
107
|
}
|