@wix/legends-platform-sdk 1.20.0 → 1.21.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 +43 -19
- package/dist/cjs/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/cjs/hooks/useConversation/useConversation.js +4 -0
- package/dist/cjs/hooks/useConversation/useConversation.js.map +1 -1
- package/dist/cjs/hooks/useConversationEvents/types.js.map +1 -1
- package/dist/cjs/hooks/useParticipantTrack/getTrackStats.js +9 -0
- package/dist/cjs/hooks/useParticipantTrack/getTrackStats.js.map +1 -0
- package/dist/cjs/hooks/useParticipantTrack/index.js +12 -0
- package/dist/cjs/hooks/useParticipantTrack/index.js.map +1 -1
- package/dist/cjs/hooks/useParticipantTrack/parseTrackStats.js +30 -0
- package/dist/cjs/hooks/useParticipantTrack/parseTrackStats.js.map +1 -0
- package/dist/esm/hooks/useConversation/livekit/useConversation.js +45 -19
- package/dist/esm/hooks/useConversation/livekit/useConversation.js.map +1 -1
- package/dist/esm/hooks/useConversation/useConversation.js +4 -0
- package/dist/esm/hooks/useConversation/useConversation.js.map +1 -1
- package/dist/esm/hooks/useConversationEvents/types.js.map +1 -1
- package/dist/esm/hooks/useParticipantTrack/getTrackStats.js +5 -0
- package/dist/esm/hooks/useParticipantTrack/getTrackStats.js.map +1 -0
- package/dist/esm/hooks/useParticipantTrack/index.js +2 -0
- package/dist/esm/hooks/useParticipantTrack/index.js.map +1 -1
- package/dist/esm/hooks/useParticipantTrack/parseTrackStats.js +26 -0
- package/dist/esm/hooks/useParticipantTrack/parseTrackStats.js.map +1 -0
- package/dist/types/hooks/useConversation/livekit/useConversation.d.ts.map +1 -1
- package/dist/types/hooks/useConversation/useConversation.d.ts.map +1 -1
- package/dist/types/hooks/useConversationEvents/types.d.ts +11 -0
- package/dist/types/hooks/useConversationEvents/types.d.ts.map +1 -1
- package/dist/types/hooks/useParticipantTrack/getTrackStats.d.ts +3 -0
- package/dist/types/hooks/useParticipantTrack/getTrackStats.d.ts.map +1 -0
- package/dist/types/hooks/useParticipantTrack/index.d.ts +2 -0
- package/dist/types/hooks/useParticipantTrack/index.d.ts.map +1 -1
- package/dist/types/hooks/useParticipantTrack/parseTrackStats.d.ts +7 -0
- package/dist/types/hooks/useParticipantTrack/parseTrackStats.d.ts.map +1 -0
- package/package.json +6 -6
|
@@ -13,6 +13,7 @@ var _jotai = require("jotai");
|
|
|
13
13
|
var _conversation = require("../../../conversation");
|
|
14
14
|
var _useCreateConversation = require("../../useCreateConversation");
|
|
15
15
|
var _useSpeechActivityDetector = require("../../useSpeechActivityDetector");
|
|
16
|
+
var _useParticipantTrack = require("../../useParticipantTrack");
|
|
16
17
|
var _useEmitConversationEvent = require("../../useConversationEvents/useEmitConversationEvent");
|
|
17
18
|
var _useToolCallingRuntime = require("../../useTools/runtime/useToolCallingRuntime");
|
|
18
19
|
var _utils = require("./utils");
|
|
@@ -73,6 +74,14 @@ function useConversation({
|
|
|
73
74
|
const acousticT0Ref = (0, _react.useRef)(null);
|
|
74
75
|
const latestTurnMetadataRef = (0, _react.useRef)({});
|
|
75
76
|
const isConnectedRef = (0, _react.useRef)(false);
|
|
77
|
+
const userMicPublication = (0, _useParticipantTrack.useParticipantTrack)({
|
|
78
|
+
type: 'user',
|
|
79
|
+
source: _useParticipantTrack.Source.Microphone
|
|
80
|
+
});
|
|
81
|
+
const agentMicPublication = (0, _useParticipantTrack.useParticipantTrack)({
|
|
82
|
+
type: 'agent',
|
|
83
|
+
source: _useParticipantTrack.Source.Microphone
|
|
84
|
+
});
|
|
76
85
|
const timer = (0, _reactTimerHook.useTimer)({
|
|
77
86
|
autoStart: false,
|
|
78
87
|
onExpire: handleExpire,
|
|
@@ -240,6 +249,21 @@ function useConversation({
|
|
|
240
249
|
sequence: latestTurnMetadataRef.current.sequence,
|
|
241
250
|
speechId: latestTurnMetadataRef.current.speechId
|
|
242
251
|
});
|
|
252
|
+
void emitConversationTurnLatency(latencyMs);
|
|
253
|
+
}
|
|
254
|
+
async function emitConversationTurnLatency(clientAcousticLatencyMs) {
|
|
255
|
+
var _conversationRef$curr3;
|
|
256
|
+
const [userStats, agentStats] = await Promise.all([(0, _useParticipantTrack.getTrackStats)(userMicPublication).then(_useParticipantTrack.parseTrackStats), (0, _useParticipantTrack.getTrackStats)(agentMicPublication).then(_useParticipantTrack.parseTrackStats)]);
|
|
257
|
+
emitEvent('conversationTurnLatency', {
|
|
258
|
+
conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id,
|
|
259
|
+
speechId: latestTurnMetadataRef.current.speechId,
|
|
260
|
+
sequence: latestTurnMetadataRef.current.sequence,
|
|
261
|
+
clientAcousticLatencyMs,
|
|
262
|
+
rttMs: userStats.roundTripTimeMs,
|
|
263
|
+
jitterBufferDelayMs: agentStats.jitterBufferDelayMs,
|
|
264
|
+
userPacketsLost: userStats.packetsLost,
|
|
265
|
+
agentPacketsLost: agentStats.packetsLost
|
|
266
|
+
});
|
|
243
267
|
}
|
|
244
268
|
function handleAcousticAgentOffset() {
|
|
245
269
|
acousticPhaseRef.current = 'idle';
|
|
@@ -258,17 +282,17 @@ function useConversation({
|
|
|
258
282
|
hangoverMs: _constants.ACOUSTIC_AGENT_HANGOVER_MS
|
|
259
283
|
});
|
|
260
284
|
function handleInactivityWarningEvent(data) {
|
|
261
|
-
var _conversationRef$
|
|
285
|
+
var _conversationRef$curr4;
|
|
262
286
|
emitEvent('inactivityWarning', {
|
|
263
|
-
conversationId: (_conversationRef$
|
|
287
|
+
conversationId: (_conversationRef$curr4 = conversationRef.current) == null ? void 0 : _conversationRef$curr4.id,
|
|
264
288
|
gracePeriodSec: data.grace_period_sec
|
|
265
289
|
});
|
|
266
290
|
}
|
|
267
291
|
function handleInactivityTimeoutEvent(_data) {
|
|
268
|
-
var _conversationRef$
|
|
292
|
+
var _conversationRef$curr5;
|
|
269
293
|
inactivityTimeoutRef.current = true;
|
|
270
294
|
emitEvent('inactivityTimeout', {
|
|
271
|
-
conversationId: (_conversationRef$
|
|
295
|
+
conversationId: (_conversationRef$curr5 = conversationRef.current) == null ? void 0 : _conversationRef$curr5.id
|
|
272
296
|
});
|
|
273
297
|
}
|
|
274
298
|
async function handleToolCallsEvent(data) {
|
|
@@ -305,12 +329,12 @@ function useConversation({
|
|
|
305
329
|
}
|
|
306
330
|
}
|
|
307
331
|
function handleConnectedEvent() {
|
|
308
|
-
var _conversationRef$
|
|
332
|
+
var _conversationRef$curr6;
|
|
309
333
|
isConnectedRef.current = true;
|
|
310
334
|
setUserConnectionState('joined');
|
|
311
335
|
setAgentConnectionState('joining');
|
|
312
336
|
emitEvent('callStarted', {
|
|
313
|
-
conversationId: (_conversationRef$
|
|
337
|
+
conversationId: (_conversationRef$curr6 = conversationRef.current) == null ? void 0 : _conversationRef$curr6.id
|
|
314
338
|
});
|
|
315
339
|
}
|
|
316
340
|
async function handleEncryptionErrorEvent(error) {
|
|
@@ -349,18 +373,18 @@ function useConversation({
|
|
|
349
373
|
}
|
|
350
374
|
}
|
|
351
375
|
function handleAgentJoin(participant) {
|
|
352
|
-
var _conversationRef$
|
|
376
|
+
var _conversationRef$curr7;
|
|
353
377
|
setAgentConnectionState('joined');
|
|
354
378
|
emitEvent('agentJoined', {
|
|
355
|
-
conversationId: (_conversationRef$
|
|
379
|
+
conversationId: (_conversationRef$curr7 = conversationRef.current) == null ? void 0 : _conversationRef$curr7.id,
|
|
356
380
|
participant
|
|
357
381
|
});
|
|
358
382
|
}
|
|
359
383
|
function handleParticipantDisconnectedEvent(participant) {
|
|
360
|
-
var _conversationRef$
|
|
384
|
+
var _conversationRef$curr8;
|
|
361
385
|
setAgentConnectionState('left');
|
|
362
386
|
emitEvent('agentLeft', {
|
|
363
|
-
conversationId: (_conversationRef$
|
|
387
|
+
conversationId: (_conversationRef$curr8 = conversationRef.current) == null ? void 0 : _conversationRef$curr8.id,
|
|
364
388
|
participant
|
|
365
389
|
});
|
|
366
390
|
}
|
|
@@ -369,13 +393,13 @@ function useConversation({
|
|
|
369
393
|
return;
|
|
370
394
|
}
|
|
371
395
|
try {
|
|
372
|
-
var _conversationRef$
|
|
396
|
+
var _conversationRef$curr9;
|
|
373
397
|
setUserConnectionState('leaving');
|
|
374
398
|
await (room == null ? void 0 : room.disconnect(true));
|
|
375
399
|
setConversationStatus('destroyed');
|
|
376
400
|
setJoinedAt(undefined);
|
|
377
401
|
emitEvent('callEnded', {
|
|
378
|
-
conversationId: (_conversationRef$
|
|
402
|
+
conversationId: (_conversationRef$curr9 = conversationRef.current) == null ? void 0 : _conversationRef$curr9.id
|
|
379
403
|
});
|
|
380
404
|
} catch (error) {
|
|
381
405
|
console.error('Failed to leave', error);
|
|
@@ -383,18 +407,18 @@ function useConversation({
|
|
|
383
407
|
}
|
|
384
408
|
}
|
|
385
409
|
async function handleExpire() {
|
|
386
|
-
var _conversationRef$
|
|
410
|
+
var _conversationRef$curr0, _conversationRef$curr1;
|
|
387
411
|
emitEvent('timeExceeded', {
|
|
388
|
-
conversationId: (_conversationRef$
|
|
389
|
-
limit: (_conversationRef$
|
|
412
|
+
conversationId: (_conversationRef$curr0 = conversationRef.current) == null ? void 0 : _conversationRef$curr0.id,
|
|
413
|
+
limit: (_conversationRef$curr1 = conversationRef.current) == null ? void 0 : _conversationRef$curr1.limit
|
|
390
414
|
});
|
|
391
415
|
await leave();
|
|
392
416
|
setConversationStatus('exceeded');
|
|
393
417
|
}
|
|
394
418
|
async function interrupt() {
|
|
395
|
-
var _conversationRef$
|
|
419
|
+
var _conversationRef$curr10;
|
|
396
420
|
emitEvent('interrupt', {
|
|
397
|
-
conversationId: (_conversationRef$
|
|
421
|
+
conversationId: (_conversationRef$curr10 = conversationRef.current) == null ? void 0 : _conversationRef$curr10.id
|
|
398
422
|
});
|
|
399
423
|
await (0, _utils.publishConversationDataMessage)(room, {}, 'interrupt');
|
|
400
424
|
}
|
|
@@ -404,7 +428,7 @@ function useConversation({
|
|
|
404
428
|
}, 'inactivity_dismiss');
|
|
405
429
|
}
|
|
406
430
|
async function send(message, attachments = []) {
|
|
407
|
-
var _conversationRef$
|
|
431
|
+
var _conversationRef$curr11;
|
|
408
432
|
await (room == null ? void 0 : room.localParticipant.sendText(message, {
|
|
409
433
|
topic: 'lk.chat',
|
|
410
434
|
attributes: {
|
|
@@ -412,7 +436,7 @@ function useConversation({
|
|
|
412
436
|
}
|
|
413
437
|
}));
|
|
414
438
|
emitEvent('userSendMessage', {
|
|
415
|
-
conversationId: (_conversationRef$
|
|
439
|
+
conversationId: (_conversationRef$curr11 = conversationRef.current) == null ? void 0 : _conversationRef$curr11.id,
|
|
416
440
|
message
|
|
417
441
|
});
|
|
418
442
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useSpeechActivityDetector","_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","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","source","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","handleAcousticAgentOffset","useSpeechActivityDetector","onSpeechStart","onSpeechEnd","thresholdRms","ACOUSTIC_USER_THRESHOLD_RMS","hangoverMs","ACOUSTIC_AGENT_HANGOVER_MS","handleInactivityWarningEvent","_conversationRef$curr3","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr4","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","checkIsToolCallsData","handle","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","payload","decoded","decodeDataPayload","Promise","resolve","catch","handleConnectedEvent","_conversationRef$curr5","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","DisconnectReason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","shouldHandleParticipantConnected","_conversationRef$curr6","handleParticipantDisconnectedEvent","_conversationRef$curr7","leave","_conversationRef$curr8","disconnect","_conversationRef$curr9","_conversationRef$curr0","interrupt","_conversationRef$curr1","publishConversationDataMessage","dismissInactivity","send","attachments","_conversationRef$curr10","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';\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 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\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":["_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":[]}
|
|
@@ -46,6 +46,7 @@ function useConversation(options) {
|
|
|
46
46
|
agentSpeakStart,
|
|
47
47
|
agentSpeakStop,
|
|
48
48
|
responseLatency,
|
|
49
|
+
conversationTurnLatency,
|
|
49
50
|
userSendMessage,
|
|
50
51
|
callStarted,
|
|
51
52
|
agentVideoLoaded,
|
|
@@ -69,6 +70,9 @@ function useConversation(options) {
|
|
|
69
70
|
function responseLatency(_payload) {
|
|
70
71
|
// BI logging handled by private impl (IBILogger interface — coming soon)
|
|
71
72
|
}
|
|
73
|
+
function conversationTurnLatency(_payload) {
|
|
74
|
+
// BI logging handled by private impl (IBILogger interface — coming soon)
|
|
75
|
+
}
|
|
72
76
|
function userSpeakStart(_payload) {
|
|
73
77
|
setUserLastActivity(Date.now());
|
|
74
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_jotai","require","_reactUse","state","_interopRequireWildcard","_sdkConsumer","_useConversation","_useConversationEvents","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","useConversation","options","type","chatId","namespace","useSdkConsumer","setConversationStatus","useSetAtom","conversationStatus","setUserConnectionState","userConnectionState","setUserActivityState","userActivityState","setAgentConnectionState","agentConnectionState","setAgentActivityState","agentActivityState","setConversation","conversation","setTranscriptions","transcriptions","setJoinedAt","joinedAt","userLastActivity","setUserLastActivity","useAtom","setUserInactivityDuration","userInactivityDuration","useUnmount","cleanup","useUpdateEffect","useInterval","Date","now","Error","useConversationEvents","userSpeakStart","userSpeakStop","agentSpeakStart","agentSpeakStop","responseLatency","userSendMessage","callStarted","agentVideoLoaded","agentJoined","useLivekitConversation","undefined","_payload","joined"],"sources":["../../../../src/hooks/useConversation/useConversation.ts"],"sourcesContent":["import { useSetAtom, useAtom } from 'jotai';\nimport { useUpdateEffect, useUnmount, useInterval } from 'react-use';\n\nimport * as state from '../../conversation/state';\nimport { useSdkConsumer } from '../../sdk-consumer';\n\nimport { useConversation as useLivekitConversation } from './livekit/useConversation';\n\nimport {\n useConversationEvents,\n type UserSpeakStartPayload,\n type UserSpeakStopPayload,\n type AgentSpeakStartPayload,\n type AgentSpeakStopPayload,\n type ResponseLatencyPayload,\n} from '../useConversationEvents';\nimport type { UseConversationResult, UseConversationOptions } from './types';\n\ntype BiEventPayload =\n | UserSpeakStartPayload\n | UserSpeakStopPayload\n | AgentSpeakStartPayload\n | AgentSpeakStopPayload;\n\nexport function useConversation(\n options: UseConversationOptions,\n): UseConversationResult {\n const { type } = options;\n const { chatId, namespace } = useSdkConsumer();\n\n const setConversationStatus = useSetAtom(state.conversationStatus);\n const setUserConnectionState = useSetAtom(state.userConnectionState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const setAgentConnectionState = useSetAtom(state.agentConnectionState);\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setConversation = useSetAtom(state.conversation);\n const setTranscriptions = useSetAtom(state.transcriptions);\n const setJoinedAt = useSetAtom(state.joinedAt);\n const [userLastActivity, setUserLastActivity] = useAtom(\n state.userLastActivity,\n );\n const setUserInactivityDuration = useSetAtom(state.userInactivityDuration);\n\n useUnmount(cleanup);\n\n useUpdateEffect(() => {\n cleanup();\n }, [chatId, namespace]);\n\n useInterval(() => {\n if (!userLastActivity) {\n return;\n }\n setUserInactivityDuration(Date.now() - userLastActivity);\n }, 1000);\n\n useUpdateEffect(() => {\n throw new Error(\n 'Conversation type & vendor cannot be changed once are set',\n );\n }, [type]);\n\n useConversationEvents({\n userSpeakStart,\n userSpeakStop,\n agentSpeakStart,\n agentSpeakStop,\n responseLatency,\n userSendMessage,\n callStarted,\n agentVideoLoaded,\n agentJoined,\n });\n\n return useLivekitConversation(options);\n\n function cleanup() {\n setConversationStatus('pending');\n setUserConnectionState('idle');\n setUserActivityState('idle');\n setAgentConnectionState('idle');\n setAgentActivityState('idle');\n setTranscriptions([]);\n setConversation(undefined);\n setJoinedAt(undefined);\n setUserLastActivity(null);\n setUserInactivityDuration(0);\n }\n\n // Conversation Events\n function responseLatency(_payload: ResponseLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function userSpeakStart(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function userSpeakStop(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function agentSpeakStart(_payload: BiEventPayload) {\n // no-op\n }\n function agentSpeakStop(_payload: BiEventPayload) {\n // no-op\n }\n function userSendMessage() {\n setUserLastActivity(Date.now());\n }\n function callStarted() {\n setUserLastActivity(Date.now());\n }\n\n function agentVideoLoaded() {\n setJoinedAt((joined) => joined ?? new Date());\n }\n\n function agentJoined() {\n if (type === 'audio') {\n setJoinedAt((joined) => joined ?? new Date());\n }\n }\n}\n"],"mappings":";;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,SAAA,GAAAD,OAAA;AAEA,IAAAE,KAAA,GAAAC,uBAAA,CAAAH,OAAA;AACA,IAAAI,YAAA,GAAAJ,OAAA;AAEA,IAAAK,gBAAA,GAAAL,OAAA;AAEA,IAAAM,sBAAA,GAAAN,OAAA;
|
|
1
|
+
{"version":3,"names":["_jotai","require","_reactUse","state","_interopRequireWildcard","_sdkConsumer","_useConversation","_useConversationEvents","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","useConversation","options","type","chatId","namespace","useSdkConsumer","setConversationStatus","useSetAtom","conversationStatus","setUserConnectionState","userConnectionState","setUserActivityState","userActivityState","setAgentConnectionState","agentConnectionState","setAgentActivityState","agentActivityState","setConversation","conversation","setTranscriptions","transcriptions","setJoinedAt","joinedAt","userLastActivity","setUserLastActivity","useAtom","setUserInactivityDuration","userInactivityDuration","useUnmount","cleanup","useUpdateEffect","useInterval","Date","now","Error","useConversationEvents","userSpeakStart","userSpeakStop","agentSpeakStart","agentSpeakStop","responseLatency","conversationTurnLatency","userSendMessage","callStarted","agentVideoLoaded","agentJoined","useLivekitConversation","undefined","_payload","joined"],"sources":["../../../../src/hooks/useConversation/useConversation.ts"],"sourcesContent":["import { useSetAtom, useAtom } from 'jotai';\nimport { useUpdateEffect, useUnmount, useInterval } from 'react-use';\n\nimport * as state from '../../conversation/state';\nimport { useSdkConsumer } from '../../sdk-consumer';\n\nimport { useConversation as useLivekitConversation } from './livekit/useConversation';\n\nimport {\n useConversationEvents,\n type UserSpeakStartPayload,\n type UserSpeakStopPayload,\n type AgentSpeakStartPayload,\n type AgentSpeakStopPayload,\n type ResponseLatencyPayload,\n type ConversationTurnLatencyPayload,\n} from '../useConversationEvents';\nimport type { UseConversationResult, UseConversationOptions } from './types';\n\ntype BiEventPayload =\n | UserSpeakStartPayload\n | UserSpeakStopPayload\n | AgentSpeakStartPayload\n | AgentSpeakStopPayload;\n\nexport function useConversation(\n options: UseConversationOptions,\n): UseConversationResult {\n const { type } = options;\n const { chatId, namespace } = useSdkConsumer();\n\n const setConversationStatus = useSetAtom(state.conversationStatus);\n const setUserConnectionState = useSetAtom(state.userConnectionState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const setAgentConnectionState = useSetAtom(state.agentConnectionState);\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setConversation = useSetAtom(state.conversation);\n const setTranscriptions = useSetAtom(state.transcriptions);\n const setJoinedAt = useSetAtom(state.joinedAt);\n const [userLastActivity, setUserLastActivity] = useAtom(\n state.userLastActivity,\n );\n const setUserInactivityDuration = useSetAtom(state.userInactivityDuration);\n\n useUnmount(cleanup);\n\n useUpdateEffect(() => {\n cleanup();\n }, [chatId, namespace]);\n\n useInterval(() => {\n if (!userLastActivity) {\n return;\n }\n setUserInactivityDuration(Date.now() - userLastActivity);\n }, 1000);\n\n useUpdateEffect(() => {\n throw new Error(\n 'Conversation type & vendor cannot be changed once are set',\n );\n }, [type]);\n\n useConversationEvents({\n userSpeakStart,\n userSpeakStop,\n agentSpeakStart,\n agentSpeakStop,\n responseLatency,\n conversationTurnLatency,\n userSendMessage,\n callStarted,\n agentVideoLoaded,\n agentJoined,\n });\n\n return useLivekitConversation(options);\n\n function cleanup() {\n setConversationStatus('pending');\n setUserConnectionState('idle');\n setUserActivityState('idle');\n setAgentConnectionState('idle');\n setAgentActivityState('idle');\n setTranscriptions([]);\n setConversation(undefined);\n setJoinedAt(undefined);\n setUserLastActivity(null);\n setUserInactivityDuration(0);\n }\n\n // Conversation Events\n function responseLatency(_payload: ResponseLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function conversationTurnLatency(_payload: ConversationTurnLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function userSpeakStart(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function userSpeakStop(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function agentSpeakStart(_payload: BiEventPayload) {\n // no-op\n }\n function agentSpeakStop(_payload: BiEventPayload) {\n // no-op\n }\n function userSendMessage() {\n setUserLastActivity(Date.now());\n }\n function callStarted() {\n setUserLastActivity(Date.now());\n }\n\n function agentVideoLoaded() {\n setJoinedAt((joined) => joined ?? new Date());\n }\n\n function agentJoined() {\n if (type === 'audio') {\n setJoinedAt((joined) => joined ?? new Date());\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type ConversationTurnLatencyPayload = {\n conversationId: string;\n speechId?: string;\n sequence?: number;\n clientAcousticLatencyMs: number;\n rttMs?: number;\n jitterBufferDelayMs?: number;\n userPacketsLost?: number;\n agentPacketsLost?: number;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n conversationTurnLatency: ConversationTurnLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.getTrackStats = getTrackStats;
|
|
5
|
+
async function getTrackStats(publication) {
|
|
6
|
+
const track = publication == null ? void 0 : publication.track;
|
|
7
|
+
return track == null ? void 0 : track.getRTCStatsReport();
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=getTrackStats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["getTrackStats","publication","track","getRTCStatsReport"],"sources":["../../../../src/hooks/useParticipantTrack/getTrackStats.ts"],"sourcesContent":["import type { LocalTrack, RemoteTrack, TrackPublication } from 'livekit-client';\n\nexport async function getTrackStats(\n publication: TrackPublication | undefined,\n): Promise<RTCStatsReport | undefined> {\n const track = publication?.track as LocalTrack | RemoteTrack | undefined;\n return track?.getRTCStatsReport();\n}\n"],"mappings":";;;;AAEO,eAAeA,aAAaA,CACjCC,WAAyC,EACJ;EACrC,MAAMC,KAAK,GAAGD,WAAW,oBAAXA,WAAW,CAAEC,KAA6C;EACxE,OAAOA,KAAK,oBAALA,KAAK,CAAEC,iBAAiB,CAAC,CAAC;AACnC","ignoreList":[]}
|
|
@@ -7,4 +7,16 @@ Object.keys(_useParticipantTrack).forEach(function (key) {
|
|
|
7
7
|
if (key in exports && exports[key] === _useParticipantTrack[key]) return;
|
|
8
8
|
exports[key] = _useParticipantTrack[key];
|
|
9
9
|
});
|
|
10
|
+
var _getTrackStats = require("./getTrackStats");
|
|
11
|
+
Object.keys(_getTrackStats).forEach(function (key) {
|
|
12
|
+
if (key === "default" || key === "__esModule") return;
|
|
13
|
+
if (key in exports && exports[key] === _getTrackStats[key]) return;
|
|
14
|
+
exports[key] = _getTrackStats[key];
|
|
15
|
+
});
|
|
16
|
+
var _parseTrackStats = require("./parseTrackStats");
|
|
17
|
+
Object.keys(_parseTrackStats).forEach(function (key) {
|
|
18
|
+
if (key === "default" || key === "__esModule") return;
|
|
19
|
+
if (key in exports && exports[key] === _parseTrackStats[key]) return;
|
|
20
|
+
exports[key] = _parseTrackStats[key];
|
|
21
|
+
});
|
|
10
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_useParticipantTrack","require","Object","keys","forEach","key","exports"],"sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"sourcesContent":["export * from './useParticipantTrack';\n"],"mappings":";;;AAAA,IAAAA,oBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,oBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,oBAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,oBAAA,CAAAK,GAAA;AAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_useParticipantTrack","require","Object","keys","forEach","key","exports","_getTrackStats","_parseTrackStats"],"sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"sourcesContent":["export * from './useParticipantTrack';\nexport * from './getTrackStats';\nexport * from './parseTrackStats';\n"],"mappings":";;;AAAA,IAAAA,oBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,oBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,oBAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,oBAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,cAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,cAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,cAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,cAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,gBAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,gBAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,gBAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,gBAAA,CAAAH,GAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.parseTrackStats = parseTrackStats;
|
|
5
|
+
function parseTrackStats(report) {
|
|
6
|
+
if (!report) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
const result = {};
|
|
10
|
+
for (const stat of report.values()) {
|
|
11
|
+
if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {
|
|
12
|
+
if (typeof stat.roundTripTime === 'number') {
|
|
13
|
+
result.roundTripTimeMs = stat.roundTripTime * 1000;
|
|
14
|
+
}
|
|
15
|
+
if (typeof stat.packetsLost === 'number') {
|
|
16
|
+
result.packetsLost = stat.packetsLost;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {
|
|
20
|
+
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number' && stat.jitterBufferEmittedCount > 0) {
|
|
21
|
+
result.jitterBufferDelayMs = stat.jitterBufferDelay / stat.jitterBufferEmittedCount * 1000;
|
|
22
|
+
}
|
|
23
|
+
if (typeof stat.packetsLost === 'number') {
|
|
24
|
+
result.packetsLost = stat.packetsLost;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=parseTrackStats.js.map
|
|
@@ -0,0 +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 result.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 stat.jitterBufferEmittedCount > 0\n ) {\n result.jitterBufferDelayMs =\n (stat.jitterBufferDelay / stat.jitterBufferEmittedCount) * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n result.packetsLost = stat.packetsLost;\n }\n }\n }\n\n return result;\n}\n"],"mappings":";;;;AAMO,SAASA,eAAeA,CAC7BC,MAAkC,EAChB;EAClB,IAAI,CAACA,MAAM,EAAE;IACX,OAAO,CAAC,CAAC;EACX;EAEA,MAAMC,MAAwB,GAAG,CAAC,CAAC;EAEnC,KAAK,MAAMC,IAAI,IAAIF,MAAM,CAACG,MAAM,CAAC,CAAC,EAAE;IAClC,IAAID,IAAI,CAACE,IAAI,KAAK,oBAAoB,IAAIF,IAAI,CAACG,IAAI,KAAK,OAAO,EAAE;MAC/D,IAAI,OAAOH,IAAI,CAACI,aAAa,KAAK,QAAQ,EAAE;QAC1CL,MAAM,CAACM,eAAe,GAAGL,IAAI,CAACI,aAAa,GAAG,IAAI;MACpD;MACA,IAAI,OAAOJ,IAAI,CAACM,WAAW,KAAK,QAAQ,EAAE;QACxCP,MAAM,CAACO,WAAW,GAAGN,IAAI,CAACM,WAAW;MACvC;IACF;IAEA,IAAIN,IAAI,CAACE,IAAI,KAAK,aAAa,IAAIF,IAAI,CAACG,IAAI,KAAK,OAAO,EAAE;MACxD,IACE,OAAOH,IAAI,CAACO,iBAAiB,KAAK,QAAQ,IAC1C,OAAOP,IAAI,CAACQ,wBAAwB,KAAK,QAAQ,IACjDR,IAAI,CAACQ,wBAAwB,GAAG,CAAC,EACjC;QACAT,MAAM,CAACU,mBAAmB,GACvBT,IAAI,CAACO,iBAAiB,GAAGP,IAAI,CAACQ,wBAAwB,GAAI,IAAI;MACnE;MACA,IAAI,OAAOR,IAAI,CAACM,WAAW,KAAK,QAAQ,EAAE;QACxCP,MAAM,CAACO,WAAW,GAAGN,IAAI,CAACM,WAAW;MACvC;IACF;EACF;EAEA,OAAOP,MAAM;AACf","ignoreList":[]}
|
|
@@ -8,6 +8,7 @@ import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
|
|
8
8
|
import { state } from '../../../conversation';
|
|
9
9
|
import { useCreateConversation } from '../../useCreateConversation';
|
|
10
10
|
import { useSpeechActivityDetector } from '../../useSpeechActivityDetector';
|
|
11
|
+
import { useParticipantTrack, Source, getTrackStats, parseTrackStats } from '../../useParticipantTrack';
|
|
11
12
|
import { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';
|
|
12
13
|
import { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';
|
|
13
14
|
import { checkIsTurnDetectionData, checkIsInactivityWarningData, checkIsInactivityTimeoutData, checkIsToolCallsData, createLivekitToolAdapter, decodeDataPayload, findJoinedAgentParticipant, mergeTranscriptions, publishConversationDataMessage, safeStringify, shouldHandleParticipantConnected } from './utils';
|
|
@@ -79,6 +80,14 @@ export function useConversation(_ref) {
|
|
|
79
80
|
const acousticT0Ref = useRef(null);
|
|
80
81
|
const latestTurnMetadataRef = useRef({});
|
|
81
82
|
const isConnectedRef = useRef(false);
|
|
83
|
+
const userMicPublication = useParticipantTrack({
|
|
84
|
+
type: 'user',
|
|
85
|
+
source: Source.Microphone
|
|
86
|
+
});
|
|
87
|
+
const agentMicPublication = useParticipantTrack({
|
|
88
|
+
type: 'agent',
|
|
89
|
+
source: Source.Microphone
|
|
90
|
+
});
|
|
82
91
|
const timer = useTimer({
|
|
83
92
|
autoStart: false,
|
|
84
93
|
onExpire: handleExpire,
|
|
@@ -244,6 +253,23 @@ export function useConversation(_ref) {
|
|
|
244
253
|
sequence: latestTurnMetadataRef.current.sequence,
|
|
245
254
|
speechId: latestTurnMetadataRef.current.speechId
|
|
246
255
|
});
|
|
256
|
+
void emitConversationTurnLatency(latencyMs);
|
|
257
|
+
}
|
|
258
|
+
async function emitConversationTurnLatency(clientAcousticLatencyMs) {
|
|
259
|
+
var _conversationRef$curr3;
|
|
260
|
+
const _await$Promise$all = await Promise.all([getTrackStats(userMicPublication).then(parseTrackStats), getTrackStats(agentMicPublication).then(parseTrackStats)]),
|
|
261
|
+
userStats = _await$Promise$all[0],
|
|
262
|
+
agentStats = _await$Promise$all[1];
|
|
263
|
+
emitEvent('conversationTurnLatency', {
|
|
264
|
+
conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id,
|
|
265
|
+
speechId: latestTurnMetadataRef.current.speechId,
|
|
266
|
+
sequence: latestTurnMetadataRef.current.sequence,
|
|
267
|
+
clientAcousticLatencyMs,
|
|
268
|
+
rttMs: userStats.roundTripTimeMs,
|
|
269
|
+
jitterBufferDelayMs: agentStats.jitterBufferDelayMs,
|
|
270
|
+
userPacketsLost: userStats.packetsLost,
|
|
271
|
+
agentPacketsLost: agentStats.packetsLost
|
|
272
|
+
});
|
|
247
273
|
}
|
|
248
274
|
function handleAcousticAgentOffset() {
|
|
249
275
|
acousticPhaseRef.current = 'idle';
|
|
@@ -262,17 +288,17 @@ export function useConversation(_ref) {
|
|
|
262
288
|
hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS
|
|
263
289
|
});
|
|
264
290
|
function handleInactivityWarningEvent(data) {
|
|
265
|
-
var _conversationRef$
|
|
291
|
+
var _conversationRef$curr4;
|
|
266
292
|
emitEvent('inactivityWarning', {
|
|
267
|
-
conversationId: (_conversationRef$
|
|
293
|
+
conversationId: (_conversationRef$curr4 = conversationRef.current) == null ? void 0 : _conversationRef$curr4.id,
|
|
268
294
|
gracePeriodSec: data.grace_period_sec
|
|
269
295
|
});
|
|
270
296
|
}
|
|
271
297
|
function handleInactivityTimeoutEvent(_data) {
|
|
272
|
-
var _conversationRef$
|
|
298
|
+
var _conversationRef$curr5;
|
|
273
299
|
inactivityTimeoutRef.current = true;
|
|
274
300
|
emitEvent('inactivityTimeout', {
|
|
275
|
-
conversationId: (_conversationRef$
|
|
301
|
+
conversationId: (_conversationRef$curr5 = conversationRef.current) == null ? void 0 : _conversationRef$curr5.id
|
|
276
302
|
});
|
|
277
303
|
}
|
|
278
304
|
async function handleToolCallsEvent(data) {
|
|
@@ -308,12 +334,12 @@ export function useConversation(_ref) {
|
|
|
308
334
|
}
|
|
309
335
|
}
|
|
310
336
|
function handleConnectedEvent() {
|
|
311
|
-
var _conversationRef$
|
|
337
|
+
var _conversationRef$curr6;
|
|
312
338
|
isConnectedRef.current = true;
|
|
313
339
|
setUserConnectionState('joined');
|
|
314
340
|
setAgentConnectionState('joining');
|
|
315
341
|
emitEvent('callStarted', {
|
|
316
|
-
conversationId: (_conversationRef$
|
|
342
|
+
conversationId: (_conversationRef$curr6 = conversationRef.current) == null ? void 0 : _conversationRef$curr6.id
|
|
317
343
|
});
|
|
318
344
|
}
|
|
319
345
|
async function handleEncryptionErrorEvent(error) {
|
|
@@ -352,18 +378,18 @@ export function useConversation(_ref) {
|
|
|
352
378
|
}
|
|
353
379
|
}
|
|
354
380
|
function handleAgentJoin(participant) {
|
|
355
|
-
var _conversationRef$
|
|
381
|
+
var _conversationRef$curr7;
|
|
356
382
|
setAgentConnectionState('joined');
|
|
357
383
|
emitEvent('agentJoined', {
|
|
358
|
-
conversationId: (_conversationRef$
|
|
384
|
+
conversationId: (_conversationRef$curr7 = conversationRef.current) == null ? void 0 : _conversationRef$curr7.id,
|
|
359
385
|
participant
|
|
360
386
|
});
|
|
361
387
|
}
|
|
362
388
|
function handleParticipantDisconnectedEvent(participant) {
|
|
363
|
-
var _conversationRef$
|
|
389
|
+
var _conversationRef$curr8;
|
|
364
390
|
setAgentConnectionState('left');
|
|
365
391
|
emitEvent('agentLeft', {
|
|
366
|
-
conversationId: (_conversationRef$
|
|
392
|
+
conversationId: (_conversationRef$curr8 = conversationRef.current) == null ? void 0 : _conversationRef$curr8.id,
|
|
367
393
|
participant
|
|
368
394
|
});
|
|
369
395
|
}
|
|
@@ -372,13 +398,13 @@ export function useConversation(_ref) {
|
|
|
372
398
|
return;
|
|
373
399
|
}
|
|
374
400
|
try {
|
|
375
|
-
var _conversationRef$
|
|
401
|
+
var _conversationRef$curr9;
|
|
376
402
|
setUserConnectionState('leaving');
|
|
377
403
|
await (room == null ? void 0 : room.disconnect(true));
|
|
378
404
|
setConversationStatus('destroyed');
|
|
379
405
|
setJoinedAt(undefined);
|
|
380
406
|
emitEvent('callEnded', {
|
|
381
|
-
conversationId: (_conversationRef$
|
|
407
|
+
conversationId: (_conversationRef$curr9 = conversationRef.current) == null ? void 0 : _conversationRef$curr9.id
|
|
382
408
|
});
|
|
383
409
|
} catch (error) {
|
|
384
410
|
console.error('Failed to leave', error);
|
|
@@ -386,18 +412,18 @@ export function useConversation(_ref) {
|
|
|
386
412
|
}
|
|
387
413
|
}
|
|
388
414
|
async function handleExpire() {
|
|
389
|
-
var _conversationRef$
|
|
415
|
+
var _conversationRef$curr0, _conversationRef$curr1;
|
|
390
416
|
emitEvent('timeExceeded', {
|
|
391
|
-
conversationId: (_conversationRef$
|
|
392
|
-
limit: (_conversationRef$
|
|
417
|
+
conversationId: (_conversationRef$curr0 = conversationRef.current) == null ? void 0 : _conversationRef$curr0.id,
|
|
418
|
+
limit: (_conversationRef$curr1 = conversationRef.current) == null ? void 0 : _conversationRef$curr1.limit
|
|
393
419
|
});
|
|
394
420
|
await leave();
|
|
395
421
|
setConversationStatus('exceeded');
|
|
396
422
|
}
|
|
397
423
|
async function interrupt() {
|
|
398
|
-
var _conversationRef$
|
|
424
|
+
var _conversationRef$curr10;
|
|
399
425
|
emitEvent('interrupt', {
|
|
400
|
-
conversationId: (_conversationRef$
|
|
426
|
+
conversationId: (_conversationRef$curr10 = conversationRef.current) == null ? void 0 : _conversationRef$curr10.id
|
|
401
427
|
});
|
|
402
428
|
await publishConversationDataMessage(room, {}, 'interrupt');
|
|
403
429
|
}
|
|
@@ -407,7 +433,7 @@ export function useConversation(_ref) {
|
|
|
407
433
|
}, 'inactivity_dismiss');
|
|
408
434
|
}
|
|
409
435
|
async function send(message, attachments) {
|
|
410
|
-
var _conversationRef$
|
|
436
|
+
var _conversationRef$curr11;
|
|
411
437
|
if (attachments === void 0) {
|
|
412
438
|
attachments = [];
|
|
413
439
|
}
|
|
@@ -418,7 +444,7 @@ export function useConversation(_ref) {
|
|
|
418
444
|
}
|
|
419
445
|
}));
|
|
420
446
|
emitEvent('userSendMessage', {
|
|
421
|
-
conversationId: (_conversationRef$
|
|
447
|
+
conversationId: (_conversationRef$curr11 = conversationRef.current) == null ? void 0 : _conversationRef$curr11.id,
|
|
422
448
|
message
|
|
423
449
|
});
|
|
424
450
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","DisconnectReason","setLogLevel","ParticipantKind","LogLevel","invariant","useTimer","useLatest","useUpdateEffect","useEnsureRoom","useMediaDeviceSelect","useAtom","useAtomValue","useSetAtom","state","useCreateConversation","useSpeechActivityDetector","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","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","source","AGENT","old","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","handleAcousticAgentOffset","onSpeechStart","onSpeechEnd","thresholdRms","hangoverMs","handleInactivityWarningEvent","_conversationRef$curr3","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr4","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","handle","handleDataReceivedEvent","payload","decoded","_ref2","Promise","resolve","catch","handleConnectedEvent","_conversationRef$curr5","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","_conversationRef$curr6","handleParticipantDisconnectedEvent","_conversationRef$curr7","leave","_conversationRef$curr8","disconnect","_conversationRef$curr9","_conversationRef$curr0","interrupt","_conversationRef$curr1","dismissInactivity","send","attachments","_conversationRef$curr10","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';\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 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\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","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":[]}
|
|
@@ -40,6 +40,7 @@ export function useConversation(options) {
|
|
|
40
40
|
agentSpeakStart,
|
|
41
41
|
agentSpeakStop,
|
|
42
42
|
responseLatency,
|
|
43
|
+
conversationTurnLatency,
|
|
43
44
|
userSendMessage,
|
|
44
45
|
callStarted,
|
|
45
46
|
agentVideoLoaded,
|
|
@@ -63,6 +64,9 @@ export function useConversation(options) {
|
|
|
63
64
|
function responseLatency(_payload) {
|
|
64
65
|
// BI logging handled by private impl (IBILogger interface — coming soon)
|
|
65
66
|
}
|
|
67
|
+
function conversationTurnLatency(_payload) {
|
|
68
|
+
// BI logging handled by private impl (IBILogger interface — coming soon)
|
|
69
|
+
}
|
|
66
70
|
function userSpeakStart(_payload) {
|
|
67
71
|
setUserLastActivity(Date.now());
|
|
68
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useSetAtom","useAtom","useUpdateEffect","useUnmount","useInterval","state","useSdkConsumer","useConversation","useLivekitConversation","useConversationEvents","options","type","_useSdkConsumer","chatId","namespace","setConversationStatus","conversationStatus","setUserConnectionState","userConnectionState","setUserActivityState","userActivityState","setAgentConnectionState","agentConnectionState","setAgentActivityState","agentActivityState","setConversation","conversation","setTranscriptions","transcriptions","setJoinedAt","joinedAt","_useAtom","userLastActivity","setUserLastActivity","setUserInactivityDuration","userInactivityDuration","cleanup","Date","now","Error","userSpeakStart","userSpeakStop","agentSpeakStart","agentSpeakStop","responseLatency","userSendMessage","callStarted","agentVideoLoaded","agentJoined","undefined","_payload","joined"],"sources":["../../../../src/hooks/useConversation/useConversation.ts"],"sourcesContent":["import { useSetAtom, useAtom } from 'jotai';\nimport { useUpdateEffect, useUnmount, useInterval } from 'react-use';\n\nimport * as state from '../../conversation/state';\nimport { useSdkConsumer } from '../../sdk-consumer';\n\nimport { useConversation as useLivekitConversation } from './livekit/useConversation';\n\nimport {\n useConversationEvents,\n type UserSpeakStartPayload,\n type UserSpeakStopPayload,\n type AgentSpeakStartPayload,\n type AgentSpeakStopPayload,\n type ResponseLatencyPayload,\n} from '../useConversationEvents';\nimport type { UseConversationResult, UseConversationOptions } from './types';\n\ntype BiEventPayload =\n | UserSpeakStartPayload\n | UserSpeakStopPayload\n | AgentSpeakStartPayload\n | AgentSpeakStopPayload;\n\nexport function useConversation(\n options: UseConversationOptions,\n): UseConversationResult {\n const { type } = options;\n const { chatId, namespace } = useSdkConsumer();\n\n const setConversationStatus = useSetAtom(state.conversationStatus);\n const setUserConnectionState = useSetAtom(state.userConnectionState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const setAgentConnectionState = useSetAtom(state.agentConnectionState);\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setConversation = useSetAtom(state.conversation);\n const setTranscriptions = useSetAtom(state.transcriptions);\n const setJoinedAt = useSetAtom(state.joinedAt);\n const [userLastActivity, setUserLastActivity] = useAtom(\n state.userLastActivity,\n );\n const setUserInactivityDuration = useSetAtom(state.userInactivityDuration);\n\n useUnmount(cleanup);\n\n useUpdateEffect(() => {\n cleanup();\n }, [chatId, namespace]);\n\n useInterval(() => {\n if (!userLastActivity) {\n return;\n }\n setUserInactivityDuration(Date.now() - userLastActivity);\n }, 1000);\n\n useUpdateEffect(() => {\n throw new Error(\n 'Conversation type & vendor cannot be changed once are set',\n );\n }, [type]);\n\n useConversationEvents({\n userSpeakStart,\n userSpeakStop,\n agentSpeakStart,\n agentSpeakStop,\n responseLatency,\n userSendMessage,\n callStarted,\n agentVideoLoaded,\n agentJoined,\n });\n\n return useLivekitConversation(options);\n\n function cleanup() {\n setConversationStatus('pending');\n setUserConnectionState('idle');\n setUserActivityState('idle');\n setAgentConnectionState('idle');\n setAgentActivityState('idle');\n setTranscriptions([]);\n setConversation(undefined);\n setJoinedAt(undefined);\n setUserLastActivity(null);\n setUserInactivityDuration(0);\n }\n\n // Conversation Events\n function responseLatency(_payload: ResponseLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function userSpeakStart(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function userSpeakStop(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function agentSpeakStart(_payload: BiEventPayload) {\n // no-op\n }\n function agentSpeakStop(_payload: BiEventPayload) {\n // no-op\n }\n function userSendMessage() {\n setUserLastActivity(Date.now());\n }\n function callStarted() {\n setUserLastActivity(Date.now());\n }\n\n function agentVideoLoaded() {\n setJoinedAt((joined) => joined ?? new Date());\n }\n\n function agentJoined() {\n if (type === 'audio') {\n setJoinedAt((joined) => joined ?? new Date());\n }\n }\n}\n"],"mappings":"AAAA,SAASA,UAAU,EAAEC,OAAO,QAAQ,OAAO;AAC3C,SAASC,eAAe,EAAEC,UAAU,EAAEC,WAAW,QAAQ,WAAW;AAEpE,OAAO,KAAKC,KAAK,MAAM,0BAA0B;AACjD,SAASC,cAAc,QAAQ,oBAAoB;AAEnD,SAASC,eAAe,IAAIC,sBAAsB,QAAQ,2BAA2B;AAErF,SACEC,qBAAqB,
|
|
1
|
+
{"version":3,"names":["useSetAtom","useAtom","useUpdateEffect","useUnmount","useInterval","state","useSdkConsumer","useConversation","useLivekitConversation","useConversationEvents","options","type","_useSdkConsumer","chatId","namespace","setConversationStatus","conversationStatus","setUserConnectionState","userConnectionState","setUserActivityState","userActivityState","setAgentConnectionState","agentConnectionState","setAgentActivityState","agentActivityState","setConversation","conversation","setTranscriptions","transcriptions","setJoinedAt","joinedAt","_useAtom","userLastActivity","setUserLastActivity","setUserInactivityDuration","userInactivityDuration","cleanup","Date","now","Error","userSpeakStart","userSpeakStop","agentSpeakStart","agentSpeakStop","responseLatency","conversationTurnLatency","userSendMessage","callStarted","agentVideoLoaded","agentJoined","undefined","_payload","joined"],"sources":["../../../../src/hooks/useConversation/useConversation.ts"],"sourcesContent":["import { useSetAtom, useAtom } from 'jotai';\nimport { useUpdateEffect, useUnmount, useInterval } from 'react-use';\n\nimport * as state from '../../conversation/state';\nimport { useSdkConsumer } from '../../sdk-consumer';\n\nimport { useConversation as useLivekitConversation } from './livekit/useConversation';\n\nimport {\n useConversationEvents,\n type UserSpeakStartPayload,\n type UserSpeakStopPayload,\n type AgentSpeakStartPayload,\n type AgentSpeakStopPayload,\n type ResponseLatencyPayload,\n type ConversationTurnLatencyPayload,\n} from '../useConversationEvents';\nimport type { UseConversationResult, UseConversationOptions } from './types';\n\ntype BiEventPayload =\n | UserSpeakStartPayload\n | UserSpeakStopPayload\n | AgentSpeakStartPayload\n | AgentSpeakStopPayload;\n\nexport function useConversation(\n options: UseConversationOptions,\n): UseConversationResult {\n const { type } = options;\n const { chatId, namespace } = useSdkConsumer();\n\n const setConversationStatus = useSetAtom(state.conversationStatus);\n const setUserConnectionState = useSetAtom(state.userConnectionState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const setAgentConnectionState = useSetAtom(state.agentConnectionState);\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setConversation = useSetAtom(state.conversation);\n const setTranscriptions = useSetAtom(state.transcriptions);\n const setJoinedAt = useSetAtom(state.joinedAt);\n const [userLastActivity, setUserLastActivity] = useAtom(\n state.userLastActivity,\n );\n const setUserInactivityDuration = useSetAtom(state.userInactivityDuration);\n\n useUnmount(cleanup);\n\n useUpdateEffect(() => {\n cleanup();\n }, [chatId, namespace]);\n\n useInterval(() => {\n if (!userLastActivity) {\n return;\n }\n setUserInactivityDuration(Date.now() - userLastActivity);\n }, 1000);\n\n useUpdateEffect(() => {\n throw new Error(\n 'Conversation type & vendor cannot be changed once are set',\n );\n }, [type]);\n\n useConversationEvents({\n userSpeakStart,\n userSpeakStop,\n agentSpeakStart,\n agentSpeakStop,\n responseLatency,\n conversationTurnLatency,\n userSendMessage,\n callStarted,\n agentVideoLoaded,\n agentJoined,\n });\n\n return useLivekitConversation(options);\n\n function cleanup() {\n setConversationStatus('pending');\n setUserConnectionState('idle');\n setUserActivityState('idle');\n setAgentConnectionState('idle');\n setAgentActivityState('idle');\n setTranscriptions([]);\n setConversation(undefined);\n setJoinedAt(undefined);\n setUserLastActivity(null);\n setUserInactivityDuration(0);\n }\n\n // Conversation Events\n function responseLatency(_payload: ResponseLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function conversationTurnLatency(_payload: ConversationTurnLatencyPayload) {\n // BI logging handled by private impl (IBILogger interface — coming soon)\n }\n function userSpeakStart(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function userSpeakStop(_payload: BiEventPayload) {\n setUserLastActivity(Date.now());\n }\n function agentSpeakStart(_payload: BiEventPayload) {\n // no-op\n }\n function agentSpeakStop(_payload: BiEventPayload) {\n // no-op\n }\n function userSendMessage() {\n setUserLastActivity(Date.now());\n }\n function callStarted() {\n setUserLastActivity(Date.now());\n }\n\n function agentVideoLoaded() {\n setJoinedAt((joined) => joined ?? new Date());\n }\n\n function agentJoined() {\n if (type === 'audio') {\n setJoinedAt((joined) => joined ?? new Date());\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"sourcesContent":["import React from 'react';\nimport type { RemoteParticipant } from 'livekit-client';\n\nexport type UserSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type TimeExceededPayload = {\n conversationId: string;\n limit: number;\n};\n\nexport type UserSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStartPayload = {\n conversationId: string;\n};\n\nexport type AgentSpeakStopPayload = {\n conversationId: string;\n};\n\nexport type ResponseLatencyPayload = {\n conversationId: string;\n latencyMs: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n};\n\nexport type ConversationTurnLatencyPayload = {\n conversationId: string;\n speechId?: string;\n sequence?: number;\n clientAcousticLatencyMs: number;\n rttMs?: number;\n jitterBufferDelayMs?: number;\n userPacketsLost?: number;\n agentPacketsLost?: number;\n};\n\nexport type InterruptPayload = {\n conversationId: string;\n};\n\nexport type CallStartedPayload = {\n conversationId: string;\n};\n\nexport type CallEndedPayload = {\n conversationId: string;\n};\n\nexport type UserSendMessagePayload = {\n conversationId: string;\n message: string;\n};\n\nexport type AgentJoinedPayload = {\n conversationId: string;\n participant: RemoteParticipant;\n};\n\nexport type AgentLeftPayload = {\n conversationId: string;\n participant?: RemoteParticipant;\n};\n\nexport type AgentVideoLoadedPayload = {\n videoRef: React.RefObject<HTMLVideoElement>;\n};\n\nexport type InactivityWarningPayload = {\n conversationId: string;\n gracePeriodSec: number;\n};\n\nexport type InactivityTimeoutPayload = {\n conversationId: string;\n};\n\nexport type ConversationEventMap = {\n userSpeakStart: UserSpeakStartPayload;\n userSpeakStop: UserSpeakStopPayload;\n agentSpeakStart: AgentSpeakStartPayload;\n agentSpeakStop: AgentSpeakStopPayload;\n responseLatency: ResponseLatencyPayload;\n conversationTurnLatency: ConversationTurnLatencyPayload;\n interrupt: InterruptPayload;\n callStarted: CallStartedPayload;\n callEnded: CallEndedPayload;\n userSendMessage: UserSendMessagePayload;\n agentJoined: AgentJoinedPayload;\n agentLeft: AgentLeftPayload;\n timeExceeded: TimeExceededPayload;\n agentVideoLoaded: AgentVideoLoadedPayload;\n inactivityWarning: InactivityWarningPayload;\n inactivityTimeout: InactivityTimeoutPayload;\n};\n\nexport type ConversationEvent = keyof ConversationEventMap;\n\nexport type EventPayload<T extends ConversationEvent> = ConversationEventMap[T];\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["getTrackStats","publication","track","getRTCStatsReport"],"sources":["../../../../src/hooks/useParticipantTrack/getTrackStats.ts"],"sourcesContent":["import type { LocalTrack, RemoteTrack, TrackPublication } from 'livekit-client';\n\nexport async function getTrackStats(\n publication: TrackPublication | undefined,\n): Promise<RTCStatsReport | undefined> {\n const track = publication?.track as LocalTrack | RemoteTrack | undefined;\n return track?.getRTCStatsReport();\n}\n"],"mappings":"AAEA,OAAO,eAAeA,aAAaA,CACjCC,WAAyC,EACJ;EACrC,MAAMC,KAAK,GAAGD,WAAW,oBAAXA,WAAW,CAAEC,KAA6C;EACxE,OAAOA,KAAK,oBAALA,KAAK,CAAEC,iBAAiB,CAAC,CAAC;AACnC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"sourcesContent":["export * from './useParticipantTrack';\n"],"mappings":"AAAA,cAAc,uBAAuB","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"sourcesContent":["export * from './useParticipantTrack';\nexport * from './getTrackStats';\nexport * from './parseTrackStats';\n"],"mappings":"AAAA,cAAc,uBAAuB;AACrC,cAAc,iBAAiB;AAC/B,cAAc,mBAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function parseTrackStats(report) {
|
|
2
|
+
if (!report) {
|
|
3
|
+
return {};
|
|
4
|
+
}
|
|
5
|
+
const result = {};
|
|
6
|
+
for (const stat of report.values()) {
|
|
7
|
+
if (stat.type === 'remote-inbound-rtp' && stat.kind === 'audio') {
|
|
8
|
+
if (typeof stat.roundTripTime === 'number') {
|
|
9
|
+
result.roundTripTimeMs = stat.roundTripTime * 1000;
|
|
10
|
+
}
|
|
11
|
+
if (typeof stat.packetsLost === 'number') {
|
|
12
|
+
result.packetsLost = stat.packetsLost;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (stat.type === 'inbound-rtp' && stat.kind === 'audio') {
|
|
16
|
+
if (typeof stat.jitterBufferDelay === 'number' && typeof stat.jitterBufferEmittedCount === 'number' && stat.jitterBufferEmittedCount > 0) {
|
|
17
|
+
result.jitterBufferDelayMs = stat.jitterBufferDelay / stat.jitterBufferEmittedCount * 1000;
|
|
18
|
+
}
|
|
19
|
+
if (typeof stat.packetsLost === 'number') {
|
|
20
|
+
result.packetsLost = stat.packetsLost;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=parseTrackStats.js.map
|
|
@@ -0,0 +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 result.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 stat.jitterBufferEmittedCount > 0\n ) {\n result.jitterBufferDelayMs =\n (stat.jitterBufferDelay / stat.jitterBufferEmittedCount) * 1000;\n }\n if (typeof stat.packetsLost === 'number') {\n result.packetsLost = stat.packetsLost;\n }\n }\n }\n\n return result;\n}\n"],"mappings":"AAMA,OAAO,SAASA,eAAeA,CAC7BC,MAAkC,EAChB;EAClB,IAAI,CAACA,MAAM,EAAE;IACX,OAAO,CAAC,CAAC;EACX;EAEA,MAAMC,MAAwB,GAAG,CAAC,CAAC;EAEnC,KAAK,MAAMC,IAAI,IAAIF,MAAM,CAACG,MAAM,CAAC,CAAC,EAAE;IAClC,IAAID,IAAI,CAACE,IAAI,KAAK,oBAAoB,IAAIF,IAAI,CAACG,IAAI,KAAK,OAAO,EAAE;MAC/D,IAAI,OAAOH,IAAI,CAACI,aAAa,KAAK,QAAQ,EAAE;QAC1CL,MAAM,CAACM,eAAe,GAAGL,IAAI,CAACI,aAAa,GAAG,IAAI;MACpD;MACA,IAAI,OAAOJ,IAAI,CAACM,WAAW,KAAK,QAAQ,EAAE;QACxCP,MAAM,CAACO,WAAW,GAAGN,IAAI,CAACM,WAAW;MACvC;IACF;IAEA,IAAIN,IAAI,CAACE,IAAI,KAAK,aAAa,IAAIF,IAAI,CAACG,IAAI,KAAK,OAAO,EAAE;MACxD,IACE,OAAOH,IAAI,CAACO,iBAAiB,KAAK,QAAQ,IAC1C,OAAOP,IAAI,CAACQ,wBAAwB,KAAK,QAAQ,IACjDR,IAAI,CAACQ,wBAAwB,GAAG,CAAC,EACjC;QACAT,MAAM,CAACU,mBAAmB,GACvBT,IAAI,CAACO,iBAAiB,GAAGP,IAAI,CAACQ,wBAAwB,GAAI,IAAI;MACnE;MACA,IAAI,OAAOR,IAAI,CAACM,WAAW,KAAK,QAAQ,EAAE;QACxCP,MAAM,CAACO,WAAW,GAAGN,IAAI,CAACM,WAAW;MACvC;IACF;EACF;EAEA,OAAOP,MAAM;AACf","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;AAqClB,wBAAgB,eAAe,CAAC,EAC9B,QAAe,EACf,IAAI,EACJ,MAAM,EACN,mBAA2B,EAC3B,eAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACtB,EAAE,sBAAsB,GAAG,qBAAqB,CAqfhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConversation.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useConversation/useConversation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useConversation.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useConversation/useConversation.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAQ7E,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAmGvB"}
|
|
@@ -23,6 +23,16 @@ export type ResponseLatencyPayload = {
|
|
|
23
23
|
sequence?: number;
|
|
24
24
|
speechId?: string;
|
|
25
25
|
};
|
|
26
|
+
export type ConversationTurnLatencyPayload = {
|
|
27
|
+
conversationId: string;
|
|
28
|
+
speechId?: string;
|
|
29
|
+
sequence?: number;
|
|
30
|
+
clientAcousticLatencyMs: number;
|
|
31
|
+
rttMs?: number;
|
|
32
|
+
jitterBufferDelayMs?: number;
|
|
33
|
+
userPacketsLost?: number;
|
|
34
|
+
agentPacketsLost?: number;
|
|
35
|
+
};
|
|
26
36
|
export type InterruptPayload = {
|
|
27
37
|
conversationId: string;
|
|
28
38
|
};
|
|
@@ -60,6 +70,7 @@ export type ConversationEventMap = {
|
|
|
60
70
|
agentSpeakStart: AgentSpeakStartPayload;
|
|
61
71
|
agentSpeakStop: AgentSpeakStopPayload;
|
|
62
72
|
responseLatency: ResponseLatencyPayload;
|
|
73
|
+
conversationTurnLatency: ConversationTurnLatencyPayload;
|
|
63
74
|
interrupt: InterruptPayload;
|
|
64
75
|
callStarted: CallStartedPayload;
|
|
65
76
|
callEnded: CallEndedPayload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,qBAAqB,CAAC;IACtC,aAAa,EAAE,oBAAoB,CAAC;IACpC,eAAe,EAAE,sBAAsB,CAAC;IACxC,cAAc,EAAE,qBAAqB,CAAC;IACtC,eAAe,EAAE,sBAAsB,CAAC;IACxC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,eAAe,EAAE,sBAAsB,CAAC;IACxC,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,YAAY,EAAE,mBAAmB,CAAC;IAClC,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,iBAAiB,EAAE,wBAAwB,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,CAAC;AAE3D,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,iBAAiB,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useConversationEvents/types.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTrackStats.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useParticipantTrack/getTrackStats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEhF,wBAAsB,aAAa,CACjC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GACxC,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAGrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useParticipantTrack/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +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,GACjC,gBAAgB,CAiClB"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.21.0",
|
|
3
3
|
"name": "@wix/legends-platform-sdk",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
"@types/jest": "^27.4.0",
|
|
62
62
|
"@types/react": "^18.2.15",
|
|
63
63
|
"@types/react-dom": "^18.2.7",
|
|
64
|
-
"@wix/eslint-config-yoshi": "^6.
|
|
65
|
-
"@wix/jest-yoshi-preset": "^6.
|
|
66
|
-
"@wix/yoshi-flow-library": "^6.
|
|
67
|
-
"@wix/yoshi-style-dependencies": "^6.
|
|
64
|
+
"@wix/eslint-config-yoshi": "^6.190.0",
|
|
65
|
+
"@wix/jest-yoshi-preset": "^6.190.0",
|
|
66
|
+
"@wix/yoshi-flow-library": "^6.190.0",
|
|
67
|
+
"@wix/yoshi-style-dependencies": "^6.190.0",
|
|
68
68
|
"express": "^4.17.2",
|
|
69
69
|
"lodash": "^4.18.1",
|
|
70
70
|
"react": "^19.0.0",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"wallaby": {
|
|
104
104
|
"autoDetect": true
|
|
105
105
|
},
|
|
106
|
-
"falconPackageHash": "
|
|
106
|
+
"falconPackageHash": "c403b16a291bbce2547100d018cc92b0323493c61aaf67ddca4096fc"
|
|
107
107
|
}
|