@wix/legends-platform-sdk 1.4.0 → 1.6.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.
Files changed (54) hide show
  1. package/dist/cjs/hooks/index.js +6 -0
  2. package/dist/cjs/hooks/index.js.map +1 -1
  3. package/dist/cjs/hooks/useConversation/livekit/constants.js +4 -1
  4. package/dist/cjs/hooks/useConversation/livekit/constants.js.map +1 -1
  5. package/dist/cjs/hooks/useConversation/livekit/useConversation.js +87 -35
  6. package/dist/cjs/hooks/useConversation/livekit/useConversation.js.map +1 -1
  7. package/dist/cjs/hooks/useSpeechActivityDetector/helpers.js +87 -0
  8. package/dist/cjs/hooks/useSpeechActivityDetector/helpers.js.map +1 -0
  9. package/dist/cjs/hooks/useSpeechActivityDetector/index.js +16 -0
  10. package/dist/cjs/hooks/useSpeechActivityDetector/index.js.map +1 -0
  11. package/dist/cjs/hooks/useSpeechActivityDetector/speechActivityProcessorSource.js +55 -0
  12. package/dist/cjs/hooks/useSpeechActivityDetector/speechActivityProcessorSource.js.map +1 -0
  13. package/dist/cjs/hooks/useSpeechActivityDetector/types.js +4 -0
  14. package/dist/cjs/hooks/useSpeechActivityDetector/types.js.map +1 -0
  15. package/dist/cjs/hooks/useSpeechActivityDetector/useSpeechActivityDetector.js +52 -0
  16. package/dist/cjs/hooks/useSpeechActivityDetector/useSpeechActivityDetector.js.map +1 -0
  17. package/dist/cjs/sdk.js +6 -0
  18. package/dist/cjs/sdk.js.map +1 -1
  19. package/dist/esm/hooks/index.js +1 -0
  20. package/dist/esm/hooks/index.js.map +1 -1
  21. package/dist/esm/hooks/useConversation/livekit/constants.js +3 -0
  22. package/dist/esm/hooks/useConversation/livekit/constants.js.map +1 -1
  23. package/dist/esm/hooks/useConversation/livekit/useConversation.js +87 -35
  24. package/dist/esm/hooks/useConversation/livekit/useConversation.js.map +1 -1
  25. package/dist/esm/hooks/useSpeechActivityDetector/helpers.js +83 -0
  26. package/dist/esm/hooks/useSpeechActivityDetector/helpers.js.map +1 -0
  27. package/dist/esm/hooks/useSpeechActivityDetector/index.js +3 -0
  28. package/dist/esm/hooks/useSpeechActivityDetector/index.js.map +1 -0
  29. package/dist/esm/hooks/useSpeechActivityDetector/speechActivityProcessorSource.js +51 -0
  30. package/dist/esm/hooks/useSpeechActivityDetector/speechActivityProcessorSource.js.map +1 -0
  31. package/dist/esm/hooks/useSpeechActivityDetector/types.js +2 -0
  32. package/dist/esm/hooks/useSpeechActivityDetector/types.js.map +1 -0
  33. package/dist/esm/hooks/useSpeechActivityDetector/useSpeechActivityDetector.js +44 -0
  34. package/dist/esm/hooks/useSpeechActivityDetector/useSpeechActivityDetector.js.map +1 -0
  35. package/dist/esm/sdk.js +1 -0
  36. package/dist/esm/sdk.js.map +1 -1
  37. package/dist/types/hooks/index.d.ts +1 -0
  38. package/dist/types/hooks/index.d.ts.map +1 -1
  39. package/dist/types/hooks/useConversation/livekit/constants.d.ts +3 -0
  40. package/dist/types/hooks/useConversation/livekit/constants.d.ts.map +1 -1
  41. package/dist/types/hooks/useConversation/livekit/useConversation.d.ts.map +1 -1
  42. package/dist/types/hooks/useSpeechActivityDetector/helpers.d.ts +19 -0
  43. package/dist/types/hooks/useSpeechActivityDetector/helpers.d.ts.map +1 -0
  44. package/dist/types/hooks/useSpeechActivityDetector/index.d.ts +3 -0
  45. package/dist/types/hooks/useSpeechActivityDetector/index.d.ts.map +1 -0
  46. package/dist/types/hooks/useSpeechActivityDetector/speechActivityProcessorSource.d.ts +3 -0
  47. package/dist/types/hooks/useSpeechActivityDetector/speechActivityProcessorSource.d.ts.map +1 -0
  48. package/dist/types/hooks/useSpeechActivityDetector/types.d.ts +14 -0
  49. package/dist/types/hooks/useSpeechActivityDetector/types.d.ts.map +1 -0
  50. package/dist/types/hooks/useSpeechActivityDetector/useSpeechActivityDetector.d.ts +10 -0
  51. package/dist/types/hooks/useSpeechActivityDetector/useSpeechActivityDetector.d.ts.map +1 -0
  52. package/dist/types/sdk.d.ts +1 -0
  53. package/dist/types/sdk.d.ts.map +1 -1
  54. package/package.json +3 -3
@@ -55,4 +55,10 @@ Object.keys(_useTools).forEach(function (key) {
55
55
  if (key in exports && exports[key] === _useTools[key]) return;
56
56
  exports[key] = _useTools[key];
57
57
  });
58
+ var _useSpeechActivityDetector = require("./useSpeechActivityDetector");
59
+ Object.keys(_useSpeechActivityDetector).forEach(function (key) {
60
+ if (key === "default" || key === "__esModule") return;
61
+ if (key in exports && exports[key] === _useSpeechActivityDetector[key]) return;
62
+ exports[key] = _useSpeechActivityDetector[key];
63
+ });
58
64
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_useConversation","require","Object","keys","forEach","key","exports","_useCreateConversation","_useConversationStatus","_useTextChat","_useConversationEvents","_useUserActivity","_useScreenShare","_usePictureInPicture","_useTools"],"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export * from './useConversation';\nexport * from './useCreateConversation';\nexport * from './useConversationStatus';\nexport * from './useTextChat';\nexport * from './useConversationEvents';\nexport * from './useUserActivity';\nexport * from './useScreenShare';\nexport * from './usePictureInPicture';\nexport * from './useTools';\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_useConversation","require","Object","keys","forEach","key","exports","_useCreateConversation","_useConversationStatus","_useTextChat","_useConversationEvents","_useUserActivity","_useScreenShare","_usePictureInPicture","_useTools","_useSpeechActivityDetector"],"sources":["../../../src/hooks/index.ts"],"sourcesContent":["export * from './useConversation';\nexport * from './useCreateConversation';\nexport * from './useConversationStatus';\nexport * from './useTextChat';\nexport * from './useConversationEvents';\nexport * from './useUserActivity';\nexport * from './useScreenShare';\nexport * from './usePictureInPicture';\nexport * from './useTools';\nexport * from './useSpeechActivityDetector';\n"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.SPEAKING_STATE_EVENT_MAP = void 0;
4
+ exports.SPEAKING_STATE_EVENT_MAP = exports.ACOUSTIC_USER_THRESHOLD_RMS = exports.ACOUSTIC_USER_HANGOVER_MS = exports.ACOUSTIC_AGENT_HANGOVER_MS = void 0;
5
5
  const SPEAKING_STATE_EVENT_MAP = exports.SPEAKING_STATE_EVENT_MAP = {
6
6
  STANDARD: {
7
7
  speaking: 'userSpeakStart',
@@ -12,4 +12,7 @@ const SPEAKING_STATE_EVENT_MAP = exports.SPEAKING_STATE_EVENT_MAP = {
12
12
  listening: 'agentSpeakStop'
13
13
  }
14
14
  };
15
+ const ACOUSTIC_USER_THRESHOLD_RMS = exports.ACOUSTIC_USER_THRESHOLD_RMS = 0.025;
16
+ const ACOUSTIC_USER_HANGOVER_MS = exports.ACOUSTIC_USER_HANGOVER_MS = 400;
17
+ const ACOUSTIC_AGENT_HANGOVER_MS = exports.ACOUSTIC_AGENT_HANGOVER_MS = 900;
15
18
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["SPEAKING_STATE_EVENT_MAP","exports","STANDARD","speaking","listening","AGENT"],"sources":["../../../../../src/hooks/useConversation/livekit/constants.ts"],"sourcesContent":["import type { TurnDetectionData } from './types';\nimport type { ConversationEvent } from '../../useConversationEvents';\n\nexport const SPEAKING_STATE_EVENT_MAP: Record<\n TurnDetectionData['participantKind'],\n Record<TurnDetectionData['state'], ConversationEvent>\n> = {\n STANDARD: {\n speaking: 'userSpeakStart',\n listening: 'userSpeakStop',\n },\n AGENT: {\n speaking: 'agentSpeakStart',\n listening: 'agentSpeakStop',\n },\n};\n"],"mappings":";;;;AAGO,MAAMA,wBAGZ,GAAAC,OAAA,CAAAD,wBAAA,GAAG;EACFE,QAAQ,EAAE;IACRC,QAAQ,EAAE,gBAAgB;IAC1BC,SAAS,EAAE;EACb,CAAC;EACDC,KAAK,EAAE;IACLF,QAAQ,EAAE,iBAAiB;IAC3BC,SAAS,EAAE;EACb;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["SPEAKING_STATE_EVENT_MAP","exports","STANDARD","speaking","listening","AGENT","ACOUSTIC_USER_THRESHOLD_RMS","ACOUSTIC_USER_HANGOVER_MS","ACOUSTIC_AGENT_HANGOVER_MS"],"sources":["../../../../../src/hooks/useConversation/livekit/constants.ts"],"sourcesContent":["import type { TurnDetectionData } from './types';\nimport type { ConversationEvent } from '../../useConversationEvents';\n\nexport const SPEAKING_STATE_EVENT_MAP: Record<\n TurnDetectionData['participantKind'],\n Record<TurnDetectionData['state'], ConversationEvent>\n> = {\n STANDARD: {\n speaking: 'userSpeakStart',\n listening: 'userSpeakStop',\n },\n AGENT: {\n speaking: 'agentSpeakStart',\n listening: 'agentSpeakStop',\n },\n};\n\nexport const ACOUSTIC_USER_THRESHOLD_RMS = 0.025;\nexport const ACOUSTIC_USER_HANGOVER_MS = 400;\nexport const ACOUSTIC_AGENT_HANGOVER_MS = 900;\n"],"mappings":";;;;AAGO,MAAMA,wBAGZ,GAAAC,OAAA,CAAAD,wBAAA,GAAG;EACFE,QAAQ,EAAE;IACRC,QAAQ,EAAE,gBAAgB;IAC1BC,SAAS,EAAE;EACb,CAAC;EACDC,KAAK,EAAE;IACLF,QAAQ,EAAE,iBAAiB;IAC3BC,SAAS,EAAE;EACb;AACF,CAAC;AAEM,MAAME,2BAA2B,GAAAL,OAAA,CAAAK,2BAAA,GAAG,KAAK;AACzC,MAAMC,yBAAyB,GAAAN,OAAA,CAAAM,yBAAA,GAAG,GAAG;AACrC,MAAMC,0BAA0B,GAAAP,OAAA,CAAAO,0BAAA,GAAG,GAAG","ignoreList":[]}
@@ -12,9 +12,11 @@ var _componentsReact = require("@livekit/components-react");
12
12
  var _jotai = require("jotai");
13
13
  var _conversation = require("../../../conversation");
14
14
  var _useCreateConversation = require("../../useCreateConversation");
15
+ var _useSpeechActivityDetector = require("../../useSpeechActivityDetector");
15
16
  var _useEmitConversationEvent = require("../../useConversationEvents/useEmitConversationEvent");
16
17
  var _useToolCallingRuntime = require("../../useTools/runtime/useToolCallingRuntime");
17
18
  var _utils = require("./utils");
19
+ var _constants = require("./constants");
18
20
  function useConversation({
19
21
  autoJoin = true,
20
22
  type,
@@ -62,8 +64,11 @@ function useConversation({
62
64
  const setAgentActivityState = (0, _jotai.useSetAtom)(_conversation.state.agentActivityState);
63
65
  const setUserActivityState = (0, _jotai.useSetAtom)(_conversation.state.userActivityState);
64
66
  const emitEvent = (0, _useEmitConversationEvent.useEmitConversationEvent)();
65
- const userStopRef = (0, _react.useRef)(null);
66
67
  const inactivityTimeoutRef = (0, _react.useRef)(false);
68
+ const acousticPhaseRef = (0, _react.useRef)('idle');
69
+ const acousticT0Ref = (0, _react.useRef)(null);
70
+ const latestTurnMetadataRef = (0, _react.useRef)({});
71
+ const isConnectedRef = (0, _react.useRef)(false);
67
72
  const timer = (0, _reactTimerHook.useTimer)({
68
73
  autoStart: false,
69
74
  onExpire: handleExpire,
@@ -172,14 +177,11 @@ function useConversation({
172
177
  switch (participantKind) {
173
178
  case 'STANDARD':
174
179
  if (eventState === 'listening') {
175
- userStopRef.current = {
176
- ts: performance.now(),
180
+ latestTurnMetadataRef.current = {
177
181
  turnDetectionStrategy: data.turnDetectionStrategy,
178
182
  sequence: data.sequence,
179
183
  speechId: data.speechId
180
184
  };
181
- } else {
182
- userStopRef.current = null;
183
185
  }
184
186
  emitEvent(eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop', {
185
187
  conversationId: conversationId
@@ -187,16 +189,11 @@ function useConversation({
187
189
  setUserActivityState(eventState);
188
190
  break;
189
191
  case 'AGENT':
190
- if (eventState === 'speaking' && userStopRef.current) {
191
- const latencyMs = performance.now() - userStopRef.current.ts;
192
- emitEvent('responseLatency', {
193
- conversationId: conversationId,
194
- latencyMs,
195
- turnDetectionStrategy: userStopRef.current.turnDetectionStrategy,
196
- sequence: userStopRef.current.sequence,
197
- speechId: data.speechId ?? userStopRef.current.speechId
198
- });
199
- userStopRef.current = null;
192
+ if (data.speechId) {
193
+ latestTurnMetadataRef.current = {
194
+ ...latestTurnMetadataRef.current,
195
+ speechId: data.speechId
196
+ };
200
197
  }
201
198
  emitEvent(eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop', {
202
199
  conversationId: conversationId
@@ -205,18 +202,69 @@ function useConversation({
205
202
  break;
206
203
  }
207
204
  }
208
- function handleInactivityWarningEvent(data) {
205
+ function handleAcousticUserOnset() {
206
+ if (!isConnectedRef.current) {
207
+ return;
208
+ }
209
+ if (acousticPhaseRef.current === 'waitingForAgent') {
210
+ acousticPhaseRef.current = 'idle';
211
+ acousticT0Ref.current = null;
212
+ }
213
+ }
214
+ function handleAcousticUserOffset(timestampMs) {
215
+ if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {
216
+ return;
217
+ }
218
+ acousticT0Ref.current = timestampMs - _constants.ACOUSTIC_USER_HANGOVER_MS;
219
+ acousticPhaseRef.current = 'waitingForAgent';
220
+ }
221
+ function handleAcousticAgentOnset(timestampMs) {
209
222
  var _conversationRef$curr2;
210
- emitEvent('inactivityWarning', {
223
+ if (!isConnectedRef.current || acousticPhaseRef.current !== 'waitingForAgent' || acousticT0Ref.current == null) {
224
+ return;
225
+ }
226
+ const latencyMs = timestampMs - acousticT0Ref.current;
227
+ acousticT0Ref.current = null;
228
+ acousticPhaseRef.current = 'busy';
229
+ if (latencyMs < 0 || latencyMs > 15000) {
230
+ return;
231
+ }
232
+ emitEvent('responseLatency', {
211
233
  conversationId: (_conversationRef$curr2 = conversationRef.current) == null ? void 0 : _conversationRef$curr2.id,
234
+ latencyMs,
235
+ turnDetectionStrategy: latestTurnMetadataRef.current.turnDetectionStrategy,
236
+ sequence: latestTurnMetadataRef.current.sequence,
237
+ speechId: latestTurnMetadataRef.current.speechId
238
+ });
239
+ }
240
+ function handleAcousticAgentOffset() {
241
+ acousticPhaseRef.current = 'idle';
242
+ }
243
+ (0, _useSpeechActivityDetector.useSpeechActivityDetector)({
244
+ source: 'user',
245
+ onSpeechStart: handleAcousticUserOnset,
246
+ onSpeechEnd: handleAcousticUserOffset,
247
+ thresholdRms: _constants.ACOUSTIC_USER_THRESHOLD_RMS,
248
+ hangoverMs: _constants.ACOUSTIC_USER_HANGOVER_MS
249
+ });
250
+ (0, _useSpeechActivityDetector.useSpeechActivityDetector)({
251
+ source: 'agent',
252
+ onSpeechStart: handleAcousticAgentOnset,
253
+ onSpeechEnd: handleAcousticAgentOffset,
254
+ hangoverMs: _constants.ACOUSTIC_AGENT_HANGOVER_MS
255
+ });
256
+ function handleInactivityWarningEvent(data) {
257
+ var _conversationRef$curr3;
258
+ emitEvent('inactivityWarning', {
259
+ conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id,
212
260
  gracePeriodSec: data.grace_period_sec
213
261
  });
214
262
  }
215
263
  function handleInactivityTimeoutEvent(_data) {
216
- var _conversationRef$curr3;
264
+ var _conversationRef$curr4;
217
265
  inactivityTimeoutRef.current = true;
218
266
  emitEvent('inactivityTimeout', {
219
- conversationId: (_conversationRef$curr3 = conversationRef.current) == null ? void 0 : _conversationRef$curr3.id
267
+ conversationId: (_conversationRef$curr4 = conversationRef.current) == null ? void 0 : _conversationRef$curr4.id
220
268
  });
221
269
  }
222
270
  async function handleToolCallsEvent(data) {
@@ -253,11 +301,12 @@ function useConversation({
253
301
  }
254
302
  }
255
303
  function handleConnectedEvent() {
256
- var _conversationRef$curr4;
304
+ var _conversationRef$curr5;
305
+ isConnectedRef.current = true;
257
306
  setUserConnectionState('joined');
258
307
  setAgentConnectionState('joining');
259
308
  emitEvent('callStarted', {
260
- conversationId: (_conversationRef$curr4 = conversationRef.current) == null ? void 0 : _conversationRef$curr4.id
309
+ conversationId: (_conversationRef$curr5 = conversationRef.current) == null ? void 0 : _conversationRef$curr5.id
261
310
  });
262
311
  }
263
312
  async function handleEncryptionErrorEvent(error) {
@@ -265,7 +314,10 @@ function useConversation({
265
314
  setConversationStatus('error');
266
315
  }
267
316
  function handleDisconnectedEvent(reason) {
268
- userStopRef.current = null;
317
+ isConnectedRef.current = false;
318
+ acousticPhaseRef.current = 'idle';
319
+ acousticT0Ref.current = null;
320
+ latestTurnMetadataRef.current = {};
269
321
  setAgentActivityState('idle');
270
322
  setAgentConnectionState('idle');
271
323
  setUserActivityState('idle');
@@ -293,18 +345,18 @@ function useConversation({
293
345
  }
294
346
  }
295
347
  function handleAgentJoin(participant) {
296
- var _conversationRef$curr5;
348
+ var _conversationRef$curr6;
297
349
  setAgentConnectionState('joined');
298
350
  emitEvent('agentJoined', {
299
- conversationId: (_conversationRef$curr5 = conversationRef.current) == null ? void 0 : _conversationRef$curr5.id,
351
+ conversationId: (_conversationRef$curr6 = conversationRef.current) == null ? void 0 : _conversationRef$curr6.id,
300
352
  participant
301
353
  });
302
354
  }
303
355
  function handleParticipantDisconnectedEvent(participant) {
304
- var _conversationRef$curr6;
356
+ var _conversationRef$curr7;
305
357
  setAgentConnectionState('left');
306
358
  emitEvent('agentLeft', {
307
- conversationId: (_conversationRef$curr6 = conversationRef.current) == null ? void 0 : _conversationRef$curr6.id,
359
+ conversationId: (_conversationRef$curr7 = conversationRef.current) == null ? void 0 : _conversationRef$curr7.id,
308
360
  participant
309
361
  });
310
362
  }
@@ -313,13 +365,13 @@ function useConversation({
313
365
  return;
314
366
  }
315
367
  try {
316
- var _conversationRef$curr7;
368
+ var _conversationRef$curr8;
317
369
  setUserConnectionState('leaving');
318
370
  await (room == null ? void 0 : room.disconnect(true));
319
371
  setConversationStatus('destroyed');
320
372
  setJoinedAt(undefined);
321
373
  emitEvent('callEnded', {
322
- conversationId: (_conversationRef$curr7 = conversationRef.current) == null ? void 0 : _conversationRef$curr7.id
374
+ conversationId: (_conversationRef$curr8 = conversationRef.current) == null ? void 0 : _conversationRef$curr8.id
323
375
  });
324
376
  } catch (error) {
325
377
  console.error('Failed to leave', error);
@@ -327,18 +379,18 @@ function useConversation({
327
379
  }
328
380
  }
329
381
  async function handleExpire() {
330
- var _conversationRef$curr8, _conversationRef$curr9;
382
+ var _conversationRef$curr9, _conversationRef$curr0;
331
383
  emitEvent('timeExceeded', {
332
- conversationId: (_conversationRef$curr8 = conversationRef.current) == null ? void 0 : _conversationRef$curr8.id,
333
- limit: (_conversationRef$curr9 = conversationRef.current) == null ? void 0 : _conversationRef$curr9.limit
384
+ conversationId: (_conversationRef$curr9 = conversationRef.current) == null ? void 0 : _conversationRef$curr9.id,
385
+ limit: (_conversationRef$curr0 = conversationRef.current) == null ? void 0 : _conversationRef$curr0.limit
334
386
  });
335
387
  await leave();
336
388
  setConversationStatus('exceeded');
337
389
  }
338
390
  async function interrupt() {
339
- var _conversationRef$curr0;
391
+ var _conversationRef$curr1;
340
392
  emitEvent('interrupt', {
341
- conversationId: (_conversationRef$curr0 = conversationRef.current) == null ? void 0 : _conversationRef$curr0.id
393
+ conversationId: (_conversationRef$curr1 = conversationRef.current) == null ? void 0 : _conversationRef$curr1.id
342
394
  });
343
395
  await (0, _utils.publishConversationDataMessage)(room, {}, 'interrupt');
344
396
  }
@@ -348,7 +400,7 @@ function useConversation({
348
400
  }, 'inactivity_dismiss');
349
401
  }
350
402
  async function send(message, attachments = []) {
351
- var _conversationRef$curr1;
403
+ var _conversationRef$curr10;
352
404
  await (room == null ? void 0 : room.localParticipant.sendText(message, {
353
405
  topic: 'lk.chat',
354
406
  attributes: {
@@ -356,7 +408,7 @@ function useConversation({
356
408
  }
357
409
  }));
358
410
  emitEvent('userSendMessage', {
359
- conversationId: (_conversationRef$curr1 = conversationRef.current) == null ? void 0 : _conversationRef$curr1.id,
411
+ conversationId: (_conversationRef$curr10 = conversationRef.current) == null ? void 0 : _conversationRef$curr10.id,
360
412
  message
361
413
  });
362
414
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useEmitConversationEvent","_useToolCallingRuntime","_utils","useConversation","autoJoin","type","config","startWithMicrophone","startWithCamera","_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","userStopRef","useRef","inactivityTimeoutRef","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","ts","performance","now","turnDetectionStrategy","sequence","speechId","latencyMs","handleInactivityWarningEvent","_conversationRef$curr2","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr3","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","checkIsToolCallsData","handle","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","payload","decoded","decodeDataPayload","Promise","resolve","catch","handleConnectedEvent","_conversationRef$curr4","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","DisconnectReason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","shouldHandleParticipantConnected","_conversationRef$curr5","handleParticipantDisconnectedEvent","_conversationRef$curr6","leave","_conversationRef$curr7","disconnect","_conversationRef$curr8","_conversationRef$curr9","interrupt","_conversationRef$curr0","publishConversationDataMessage","dismissInactivity","send","attachments","_conversationRef$curr1","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';\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';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({ type, config });\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\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\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 userStopRef = useRef<{\n ts: number;\n turnDetectionStrategy: string;\n sequence?: number;\n speechId?: string;\n } | null>(null);\n const inactivityTimeoutRef = 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 userStopRef.current = {\n ts: performance.now(),\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n } else {\n userStopRef.current = null;\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (eventState === 'speaking' && userStopRef.current) {\n const latencyMs = performance.now() - userStopRef.current.ts;\n emitEvent('responseLatency', {\n conversationId: conversationId!,\n latencyMs,\n turnDetectionStrategy: userStopRef.current.turnDetectionStrategy,\n sequence: userStopRef.current.sequence,\n speechId: data.speechId ?? userStopRef.current.speechId,\n });\n userStopRef.current = null;\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\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 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 userStopRef.current = null;\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;AAEA,IAAAU,yBAAA,GAAAV,OAAA;AACA,IAAAW,sBAAA,GAAAX,OAAA;AACA,IAAAY,MAAA,GAAAZ,OAAA;AAcO,SAASa,eAAeA,CAAC;EAC9BC,QAAQ,GAAG,IAAI;EACfC,IAAI;EACJC,MAAM;EACNC,mBAAmB,GAAG,KAAK;EAC3BC,eAAe,GAAG;AACI,CAAC,EAAyB;EAAA,IAAAC,mBAAA;EAChD,IAAAC,0BAAW,EAACC,uBAAQ,CAACC,MAAM,CAAC;EAE5B,MAAMC,YAAY,GAAG,IAAAC,4CAAqB,EAAC;IAAET,IAAI;IAAEC;EAAO,CAAC,CAAC;EAC5D,MAAMS,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;EAEF,MAAM;IAAEH,oBAAoB,EAAEI;EAAmB,CAAC,GAAG,IAAAF,qCAAoB,EAAC;IACxEC,IAAI,EAAE;EACR,CAAC,CAAC;EAEF,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,WAAW,GAAG,IAAAC,aAAM,EAKhB,IAAI,CAAC;EACf,MAAMC,oBAAoB,GAAG,IAAAD,aAAM,EAAC,KAAK,CAAC;EAE1C,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,CAACrD,IAAI,EAAE;MACT;IACF;IACAsD,kBAAkB,CAAC,CAAC;IAEpB,OAAO,MAAM;MACXC,oBAAoB,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,CAACvD,IAAI,CAAC,CAAC;EAEV,IAAAwD,yBAAe,EAAC,MAAM;IACpB/B,qBAAqB,CAACpB,UAAU,CAACoD,QAAQ,CAAC;EAC5C,CAAC,EAAE,CAACpD,UAAU,CAACoD,QAAQ,CAAC,CAAC;EAEzB,IAAAD,yBAAe,EAAC,MAAM;IACpB5B,kBAAkB,CAAC1B,OAAO,CAACuD,QAAQ,CAAC;EACtC,CAAC,EAAE,CAACvD,OAAO,CAACuD,QAAQ,CAAC,CAAC;EAEtB,IAAAD,yBAAe,EAAC,MAAM;IACpB3B,iBAAiB,CAACrB,MAAM,CAACiD,QAAQ,CAAC;EACpC,CAAC,EAAE,CAACjD,MAAM,CAACiD,QAAQ,CAAC,CAAC;EAErB,IAAAD,yBAAe,EAAC,MAAM;IACpB,IAAIrB,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACAnC,IAAI,CAAC0D,gBAAgB,CAACC,oBAAoB,CAACtD,UAAU,CAAC0B,OAAO,CAAC;EAChE,CAAC,EAAE,CAAC1B,UAAU,CAAC0B,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE9C,IAAAqB,yBAAe,EAAC,MAAM;IACpB,IAAIrB,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACAnC,IAAI,CAAC0D,gBAAgB,CAACE,gBAAgB,CAACpD,MAAM,CAACuB,OAAO,EAAE;MACrD8B,UAAU,EAAE;QAAEC,KAAK,EAAE,IAAI;QAAEC,MAAM,EAAE;MAAK;IAC1C,CAAC,CAAC;EACJ,CAAC,EAAE,CAACvD,MAAM,CAACuB,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE1C,IAAAkB,gBAAS,EAAC,MAAM;IACd,IAAI,CAAChE,QAAQ,EAAE;MACb;IACF;IAEA,IAAI6B,kBAAkB,KAAK,SAAS,EAAE;MACpC,KAAK8C,IAAI,CAAC,CAAC;IACb;EACF,CAAC,EAAE,CAAC9C,kBAAkB,EAAE7B,QAAQ,CAAC,CAAC;EAElC,IAAAgE,gBAAS,EAAC,MAAM;IAAA,IAAAY,kBAAA;IACd,IAAI,CAAC3C,QAAQ,IAAI,EAAA2C,kBAAA,GAAAnE,YAAY,CAACkB,IAAI,qBAAjBiD,kBAAA,CAAmBC,KAAK,MAAKC,SAAS,EAAE;MACvD;IACF;IAEArB,KAAK,CAACsB,OAAO,CAAC,IAAIhB,IAAI,CAAC9B,QAAQ,CAAC+C,OAAO,CAAC,CAAC,GAAGvE,YAAY,CAACkB,IAAI,CAAEkD,KAAM,CAAC,CAAC;EACzE,CAAC,EAAE,CAAC5C,QAAQ,GAAA5B,mBAAA,GAAEI,YAAY,CAACkB,IAAI,qBAAjBtB,mBAAA,CAAmBwE,KAAK,CAAC,CAAC;EAExC,eAAeF,IAAIA,CAAA,EAAG;IAAA,IAAAM,mBAAA;IACpB,IAAAC,kBAAS,EAACnD,mBAAmB,KAAK,MAAM,EAAE,gBAAgB,CAAC;IAC3D,IAAAmD,kBAAS,EAACzE,YAAY,CAACkB,IAAI,EAAE,2BAA2B,CAAC;IACzD,MAAMwD,GAAG,GAAG,IAAIC,GAAG,CAAC,CAAA3E,YAAY,aAAAwE,mBAAA,GAAZxE,YAAY,CAAEkB,IAAI,qBAAlBsD,mBAAA,CAAoBE,GAAG,KAAI,EAAE,CAAC;IAClD,MAAME,WAAW,GAAGF,GAAG,CAACG,YAAY,CAACC,GAAG,CAAC,OAAO,CAAC;IACjD,IAAI;MACFvD,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMrB,IAAI,oBAAJA,IAAI,CAAE6E,OAAO,CAAC/E,YAAY,CAACkB,IAAI,CAACwD,GAAG,EAAEE,WAAW,EAAG,CAAC,CAAC,CAAC;;MAE5D;MACA,MAAMI,iBAAiB,GAAG,IAAAC,iCAA0B,EAAC/E,IAAI,EAAEV,IAAI,CAAC;MAChE,IAAIwF,iBAAiB,IAAI3C,oBAAoB,KAAK,QAAQ,EAAE;QAC1D6C,eAAe,CAACF,iBAAiB,CAAC;MACpC;MAEAG,kBAAkB,CAAC,CAAC;IACtB,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,gBAAgB,EAAEA,KAAK,CAAC;MACtC7D,sBAAsB,CAAC,YAAY,CAAC;IACtC;EACF;EAEA,SAAS4D,kBAAkBA,CAAA,EAAG;IAC5B,IAAIzF,mBAAmB,EAAE;MACvBc,aAAa,CAAC;QAAE,GAAGD,UAAU;QAAE0B,OAAO,EAAE;MAAK,CAAC,CAAC;IACjD;IACA,IAAItC,eAAe,IAAIH,IAAI,KAAK,OAAO,EAAE;MACvCmB,SAAS,CAAC;QAAE,GAAGD,MAAM;QAAEuB,OAAO,EAAE;MAAK,CAAC,CAAC;IACzC;EACF;EAEA,SAASqD,gCAAgCA,CACvCC,QAAgC,EAChCC,WAAyB,EACzB;IACA,MAAMpD,cAA2C,GAAGmD,QAAQ,CAACE,GAAG,CAAEC,CAAC,KAAM;MACvEC,EAAE,EAAED,CAAC,CAACC,EAAE;MACRC,OAAO,EAAEF,CAAC,CAACG,IAAI;MACfC,MAAM,EAAE,CAAAN,WAAW,oBAAXA,WAAW,CAAE3D,IAAI,MAAKkE,8BAAe,CAACC,KAAK,GAAG,OAAO,GAAG;IAClE,CAAC,CAAC,CAAC;IAEH9D,iBAAiB,CAAE+D,GAAG,IAAK,IAAAC,0BAAmB,EAAC9D,cAAc,EAAE6D,GAAG,CAAC,CAAC;EACtE;EAEA,SAASE,wBAAwBA,CAACjF,IAAuB,EAAE;IAAA,IAAAkF,qBAAA;IACzD,MAAMC,cAAc,IAAAD,qBAAA,GAAGpF,eAAe,CAACsF,OAAO,qBAAvBF,qBAAA,CAAyBT,EAAE;IAClD,MAAM;MAAEY,eAAe;MAAEjG,KAAK,EAAEkG;IAAW,CAAC,GAAGtF,IAAI;IACnD,QAAQqF,eAAe;MACrB,KAAK,UAAU;QACb,IAAIC,UAAU,KAAK,WAAW,EAAE;UAC9B3D,WAAW,CAACyD,OAAO,GAAG;YACpBG,EAAE,EAAEC,WAAW,CAACC,GAAG,CAAC,CAAC;YACrBC,qBAAqB,EAAE1F,IAAI,CAAC0F,qBAAqB;YACjDC,QAAQ,EAAE3F,IAAI,CAAC2F,QAAQ;YACvBC,QAAQ,EAAE5F,IAAI,CAAC4F;UACjB,CAAC;QACH,CAAC,MAAM;UACLjE,WAAW,CAACyD,OAAO,GAAG,IAAI;QAC5B;QACA3D,SAAS,CACP6D,UAAU,KAAK,UAAU,GAAG,gBAAgB,GAAG,eAAe,EAC9D;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACD5D,oBAAoB,CAAC+D,UAAU,CAAC;QAChC;MACF,KAAK,OAAO;QACV,IAAIA,UAAU,KAAK,UAAU,IAAI3D,WAAW,CAACyD,OAAO,EAAE;UACpD,MAAMS,SAAS,GAAGL,WAAW,CAACC,GAAG,CAAC,CAAC,GAAG9D,WAAW,CAACyD,OAAO,CAACG,EAAE;UAC5D9D,SAAS,CAAC,iBAAiB,EAAE;YAC3B0D,cAAc,EAAEA,cAAe;YAC/BU,SAAS;YACTH,qBAAqB,EAAE/D,WAAW,CAACyD,OAAO,CAACM,qBAAqB;YAChEC,QAAQ,EAAEhE,WAAW,CAACyD,OAAO,CAACO,QAAQ;YACtCC,QAAQ,EAAE5F,IAAI,CAAC4F,QAAQ,IAAIjE,WAAW,CAACyD,OAAO,CAACQ;UACjD,CAAC,CAAC;UACFjE,WAAW,CAACyD,OAAO,GAAG,IAAI;QAC5B;QACA3D,SAAS,CACP6D,UAAU,KAAK,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,EAChE;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACD9D,qBAAqB,CAACiE,UAAU,CAAC;QACjC;IACJ;EACF;EAEA,SAASQ,4BAA4BA,CAAC9F,IAA2B,EAAE;IAAA,IAAA+F,sBAAA;IACjEtE,SAAS,CAAC,mBAAmB,EAAE;MAC7B0D,cAAc,GAAAY,sBAAA,GAAEjG,eAAe,CAACsF,OAAO,qBAAvBW,sBAAA,CAAyBtB,EAAG;MAC5CuB,cAAc,EAAEhG,IAAI,CAACiG;IACvB,CAAC,CAAC;EACJ;EAEA,SAASC,4BAA4BA,CAACC,KAA4B,EAAE;IAAA,IAAAC,sBAAA;IAClEvE,oBAAoB,CAACuD,OAAO,GAAG,IAAI;IACnC3D,SAAS,CAAC,mBAAmB,EAAE;MAC7B0D,cAAc,GAAAiB,sBAAA,GAAEtG,eAAe,CAACsF,OAAO,qBAAvBgB,sBAAA,CAAyB3B;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAe4B,oBAAoBA,CAACrG,IAAmB,EAAE;IACvD,MAAMC,cAAc,CAACmF,OAAO,CAACkB,wBAAwB,CAACtG,IAAI,EAAEJ,WAAW,CAAC;EAC1E;EAEA,MAAM2G,mBAGH,GAAG,CACJ;IACEC,KAAK,EAAEC,2BAAoB;IAC3BC,MAAM,EAAEL;EACV,CAAC,EACD;IACEG,KAAK,EAAEG,+BAAwB;IAC/BD,MAAM,EAAEzB;EACV,CAAC,EACD;IACEuB,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,KAAKE,OAAO,CAACC,OAAO,CAACT,MAAM,CAACM,OAAO,CAAC,CAAC,CAACI,KAAK,CAAElD,KAAK,IAAK;UACrDC,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;QAC/D,CAAC,CAAC;QACF;MACF;IACF;EACF;EAEA,SAASmD,oBAAoBA,CAAA,EAAG;IAAA,IAAAC,sBAAA;IAC9BjH,sBAAsB,CAAC,QAAQ,CAAC;IAChCe,uBAAuB,CAAC,SAAS,CAAC;IAClCK,SAAS,CAAC,aAAa,EAAE;MACvB0D,cAAc,GAAAmC,sBAAA,GAAExH,eAAe,CAACsF,OAAO,qBAAvBkC,sBAAA,CAAyB7C;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAe8C,0BAA0BA,CAACrD,KAAY,EAAE;IACtDC,OAAO,CAACD,KAAK,CAAC,kBAAkB,EAAEA,KAAK,CAAC;IACxC/D,qBAAqB,CAAC,OAAO,CAAC;EAChC;EAEA,SAASqH,uBAAuBA,CAACC,MAAyB,EAAE;IAC1D9F,WAAW,CAACyD,OAAO,GAAG,IAAI;IAC1B/D,qBAAqB,CAAC,MAAM,CAAC;IAC7BD,uBAAuB,CAAC,MAAM,CAAC;IAC/BG,oBAAoB,CAAC,MAAM,CAAC;IAC5BlB,sBAAsB,CAAC,MAAM,CAAC;IAE9B,IAAIwB,oBAAoB,CAACuD,OAAO,EAAE;MAChCvD,oBAAoB,CAACuD,OAAO,GAAG,KAAK;MACpCjF,qBAAqB,CAAC,oBAAoB,CAAC;MAC3C;IACF;IAEA,QAAQsH,MAAM;MACZ,KAAKC,+BAAgB,CAACC,gBAAgB;QACpC;MACF,KAAKD,+BAAgB,CAACE,WAAW;QAC/BzH,qBAAqB,CAAC,WAAW,CAAC;QAClC;MACF;QACEgE,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEuD,MAAM,CAAC;QAC9DtH,qBAAqB,CAAC,OAAO,CAAC;QAC9B;IACJ;EACF;EAEA,SAAS0H,+BAA+BA,CAACvD,WAA8B,EAAE;IACvE,IAAI,IAAAwD,uCAAgC,EAACxD,WAAW,EAAEhG,IAAI,CAAC,EAAE;MACvD0F,eAAe,CAACM,WAAW,CAAC;IAC9B;EACF;EAEA,SAASN,eAAeA,CAACM,WAA8B,EAAE;IAAA,IAAAyD,sBAAA;IACvD3G,uBAAuB,CAAC,QAAQ,CAAC;IACjCK,SAAS,CAAC,aAAa,EAAE;MACvB0D,cAAc,GAAA4C,sBAAA,GAAEjI,eAAe,CAACsF,OAAO,qBAAvB2C,sBAAA,CAAyBtD,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,SAAS0D,kCAAkCA,CAAC1D,WAA8B,EAAE;IAAA,IAAA2D,sBAAA;IAC1E7G,uBAAuB,CAAC,MAAM,CAAC;IAC/BK,SAAS,CAAC,WAAW,EAAE;MACrB0D,cAAc,GAAA8C,sBAAA,GAAEnI,eAAe,CAACsF,OAAO,qBAAvB6C,sBAAA,CAAyBxD,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,eAAe4D,KAAKA,CAAA,EAAG;IACrB,IAAI9H,mBAAmB,KAAK,QAAQ,IAAIA,mBAAmB,KAAK,SAAS,EAAE;MACzE;IACF;IAEA,IAAI;MAAA,IAAA+H,sBAAA;MACF9H,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMrB,IAAI,oBAAJA,IAAI,CAAEoJ,UAAU,CAAC,IAAI,CAAC;MAC5BjI,qBAAqB,CAAC,WAAW,CAAC;MAClCI,WAAW,CAAC4C,SAAS,CAAC;MACtB1B,SAAS,CAAC,WAAW,EAAE;QACrB0D,cAAc,GAAAgD,sBAAA,GAAErI,eAAe,CAACsF,OAAO,qBAAvB+C,sBAAA,CAAyB1D;MAC3C,CAAC,CAAC;IACJ,CAAC,CAAC,OAAOP,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,iBAAiB,EAAEA,KAAK,CAAC;MACvC/D,qBAAqB,CAAC,OAAO,CAAC;IAChC;EACF;EAEA,eAAe+B,YAAYA,CAAA,EAAG;IAAA,IAAAmG,sBAAA,EAAAC,sBAAA;IAC5B7G,SAAS,CAAC,cAAc,EAAE;MACxB0D,cAAc,GAAAkD,sBAAA,GAAEvI,eAAe,CAACsF,OAAO,qBAAvBiD,sBAAA,CAAyB5D,EAAG;MAC5CvB,KAAK,GAAAoF,sBAAA,GAAExI,eAAe,CAACsF,OAAO,qBAAvBkD,sBAAA,CAAyBpF;IAClC,CAAC,CAAC;IACF,MAAMgF,KAAK,CAAC,CAAC;IACb/H,qBAAqB,CAAC,UAAU,CAAC;EACnC;EAEA,eAAeoI,SAASA,CAAA,EAAG;IAAA,IAAAC,sBAAA;IACzB/G,SAAS,CAAC,WAAW,EAAE;MACrB0D,cAAc,GAAAqD,sBAAA,GAAE1I,eAAe,CAACsF,OAAO,qBAAvBoD,sBAAA,CAAyB/D;IAC3C,CAAC,CAAC;IAEF,MAAM,IAAAgE,qCAA8B,EAACzJ,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC;EAC7D;EAEA,eAAe0J,iBAAiBA,CAAA,EAAG;IACjC,MAAM,IAAAD,qCAA8B,EAClCzJ,IAAI,EACJ;MAAEV,IAAI,EAAE;IAAqB,CAAC,EAC9B,oBACF,CAAC;EACH;EAEA,eAAeqK,IAAIA,CAACjE,OAAe,EAAEkE,WAAyB,GAAG,EAAE,EAAE;IAAA,IAAAC,sBAAA;IACnE,OAAM7J,IAAI,oBAAJA,IAAI,CAAE0D,gBAAgB,CAACoG,QAAQ,CAACpE,OAAO,EAAE;MAC7CqE,KAAK,EAAE,SAAS;MAChBC,UAAU,EAAE;QACVJ,WAAW,EAAE,IAAAK,oBAAa,EAACL,WAAW;MACxC;IACF,CAAC,CAAC;IACFnH,SAAS,CAAC,iBAAiB,EAAE;MAC3B0D,cAAc,GAAA0D,sBAAA,GAAE/I,eAAe,CAACsF,OAAO,qBAAvByD,sBAAA,CAAyBpE,EAAG;MAC5CC;IACF,CAAC,CAAC;EACJ;EAEA,SAASpC,kBAAkBA,CAAA,EAAG;IAC5BtD,IAAI,CACDkK,EAAE,CAAC,WAAW,EAAE7B,oBAAoB,CAAC,CACrC6B,EAAE,CAAC,iBAAiB,EAAE3B,0BAA0B,CAAC,CACjD2B,EAAE,CAAC,cAAc,EAAE1B,uBAAuB,CAAC,CAC3C0B,EAAE,CAAC,uBAAuB,EAAE9E,gCAAgC,CAAC,CAC7D8E,EAAE,CAAC,sBAAsB,EAAErB,+BAA+B,CAAC,CAC3DqB,EAAE,CAAC,yBAAyB,EAAElB,kCAAkC,CAAC,CACjEkB,EAAE,CAAC,cAAc,EAAEpC,uBAAuB,CAAC;EAChD;EAEA,SAASvE,oBAAoBA,CAAA,EAAG;IAC9BvD,IAAI,CAACmK,GAAG,CAAC,WAAW,EAAE9B,oBAAoB,CAAC;IAC3CrI,IAAI,CAACmK,GAAG,CAAC,iBAAiB,EAAE5B,0BAA0B,CAAC;IACvDvI,IAAI,CAACmK,GAAG,CAAC,cAAc,EAAE3B,uBAAuB,CAAC;IACjDxI,IAAI,CAACmK,GAAG,CAAC,uBAAuB,EAAE/E,gCAAgC,CAAC;IACnEpF,IAAI,CAACmK,GAAG,CAAC,sBAAsB,EAAEtB,+BAA+B,CAAC;IACjE7I,IAAI,CAACmK,GAAG,CAAC,yBAAyB,EAAEnB,kCAAkC,CAAC;IACvEhJ,IAAI,CAACmK,GAAG,CAAC,cAAc,EAAErC,uBAAuB,CAAC;EACnD;EAEA,OAAO;IACLsC,MAAM,EAAElJ,kBAAkB;IAC1BpB,YAAY,EAAEA,YAAY,CAACkB,IAAI;IAC/BgD,IAAI;IACJ2F,IAAI;IACJJ,SAAS;IACTG,iBAAiB;IACjBR;EACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useSpeechActivityDetector","_useEmitConversationEvent","_useToolCallingRuntime","_utils","_constants","useConversation","autoJoin","type","config","startWithMicrophone","startWithCamera","_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}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({ type, config });\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":[]}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.setupSpeechActivityDetector = setupSpeechActivityDetector;
5
+ var _speechActivityProcessorSource = require("./speechActivityProcessorSource");
6
+ const DEFAULT_THRESHOLD_RMS = 0.015;
7
+ const DEFAULT_HANGOVER_MS = 300;
8
+ const WORKLET_BLOCK_SIZE = 128;
9
+ /**
10
+ * Attaches an AudioWorkletNode-based RMS threshold+hangover detector to a
11
+ * LiveKit track's underlying MediaStreamTrack. Runs on the dedicated audio
12
+ * rendering thread — unlike requestAnimationFrame+AnalyserNode, it keeps
13
+ * running when the tab is backgrounded.
14
+ */
15
+ function setupSpeechActivityDetector(track, options) {
16
+ if (!track) {
17
+ return {
18
+ cleanup: () => {}
19
+ };
20
+ }
21
+ let cancelled = false;
22
+ let audioContext = null;
23
+ let mediaStreamSource = null;
24
+ let node = null;
25
+ const thresholdRms = options.thresholdRms ?? DEFAULT_THRESHOLD_RMS;
26
+ const hangoverMs = options.hangoverMs ?? DEFAULT_HANGOVER_MS;
27
+ const setup = async () => {
28
+ const ctx = new AudioContext();
29
+ audioContext = ctx;
30
+ if (ctx.state === 'suspended') {
31
+ await ctx.resume();
32
+ }
33
+
34
+ // Hangover is expressed in ms; convert to a block count using this
35
+ // context's actual sample rate (block size is fixed at 128 samples by
36
+ // the Web Audio spec, but wall-clock duration per block varies with
37
+ // sample rate across devices/browsers).
38
+ const hangoverBlocks = Math.max(1, Math.round(hangoverMs / 1000 * (ctx.sampleRate / WORKLET_BLOCK_SIZE)));
39
+ const blob = new Blob([_speechActivityProcessorSource.SPEECH_ACTIVITY_PROCESSOR_SOURCE], {
40
+ type: 'application/javascript'
41
+ });
42
+ const blobUrl = URL.createObjectURL(blob);
43
+ try {
44
+ await ctx.audioWorklet.addModule(blobUrl);
45
+ } finally {
46
+ URL.revokeObjectURL(blobUrl);
47
+ }
48
+ if (cancelled) {
49
+ await ctx.close();
50
+ return;
51
+ }
52
+ mediaStreamSource = ctx.createMediaStreamSource(new MediaStream([track.mediaStreamTrack]));
53
+ node = new AudioWorkletNode(ctx, _speechActivityProcessorSource.SPEECH_ACTIVITY_PROCESSOR_NAME, {
54
+ processorOptions: {
55
+ thresholdRms,
56
+ hangoverBlocks
57
+ }
58
+ });
59
+ node.port.onmessage = event => {
60
+ var _event$data, _event$data2;
61
+ const timestampMs = performance.now();
62
+ if (((_event$data = event.data) == null ? void 0 : _event$data.type) === 'onset') {
63
+ options.onSpeechStart == null || options.onSpeechStart(timestampMs);
64
+ } else if (((_event$data2 = event.data) == null ? void 0 : _event$data2.type) === 'offset') {
65
+ options.onSpeechEnd == null || options.onSpeechEnd(timestampMs);
66
+ }
67
+ };
68
+ mediaStreamSource.connect(node);
69
+ };
70
+ setup().catch(error => {
71
+ // eslint-disable-next-line no-console
72
+ console.error('[useSpeechActivityDetector] failed to set up AudioWorklet', error);
73
+ });
74
+ return {
75
+ cleanup: () => {
76
+ var _mediaStreamSource, _audioContext;
77
+ cancelled = true;
78
+ if (node) {
79
+ node.port.onmessage = null;
80
+ node.disconnect();
81
+ }
82
+ (_mediaStreamSource = mediaStreamSource) == null || _mediaStreamSource.disconnect();
83
+ void ((_audioContext = audioContext) == null ? void 0 : _audioContext.close());
84
+ }
85
+ };
86
+ }
87
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_speechActivityProcessorSource","require","DEFAULT_THRESHOLD_RMS","DEFAULT_HANGOVER_MS","WORKLET_BLOCK_SIZE","setupSpeechActivityDetector","track","options","cleanup","cancelled","audioContext","mediaStreamSource","node","thresholdRms","hangoverMs","setup","ctx","AudioContext","state","resume","hangoverBlocks","Math","max","round","sampleRate","blob","Blob","SPEECH_ACTIVITY_PROCESSOR_SOURCE","type","blobUrl","URL","createObjectURL","audioWorklet","addModule","revokeObjectURL","close","createMediaStreamSource","MediaStream","mediaStreamTrack","AudioWorkletNode","SPEECH_ACTIVITY_PROCESSOR_NAME","processorOptions","port","onmessage","event","_event$data","_event$data2","timestampMs","performance","now","data","onSpeechStart","onSpeechEnd","connect","catch","error","console","_mediaStreamSource","_audioContext","disconnect"],"sources":["../../../../src/hooks/useSpeechActivityDetector/helpers.ts"],"sourcesContent":["import { Track } from 'livekit-client';\nimport {\n SPEECH_ACTIVITY_PROCESSOR_NAME,\n SPEECH_ACTIVITY_PROCESSOR_SOURCE,\n} from './speechActivityProcessorSource';\n\nconst DEFAULT_THRESHOLD_RMS = 0.015;\nconst DEFAULT_HANGOVER_MS = 300;\nconst WORKLET_BLOCK_SIZE = 128;\n\nexport type SetupSpeechActivityDetectorOptions = {\n thresholdRms?: number;\n hangoverMs?: number;\n minSpeechMs?: number;\n onSpeechStart?: (timestampMs: number) => void;\n onSpeechEnd?: (timestampMs: number) => void;\n onMisfire?: () => void;\n};\n\n/**\n * Attaches an AudioWorkletNode-based RMS threshold+hangover detector to a\n * LiveKit track's underlying MediaStreamTrack. Runs on the dedicated audio\n * rendering thread — unlike requestAnimationFrame+AnalyserNode, it keeps\n * running when the tab is backgrounded.\n */\nexport function setupSpeechActivityDetector(\n track: Track | undefined,\n options: SetupSpeechActivityDetectorOptions,\n): { cleanup: () => void } {\n if (!track) {\n return { cleanup: () => {} };\n }\n\n let cancelled = false;\n let audioContext: AudioContext | null = null;\n let mediaStreamSource: MediaStreamAudioSourceNode | null = null;\n let node: AudioWorkletNode | null = null;\n\n const thresholdRms = options.thresholdRms ?? DEFAULT_THRESHOLD_RMS;\n const hangoverMs = options.hangoverMs ?? DEFAULT_HANGOVER_MS;\n\n const setup = async () => {\n const ctx = new AudioContext();\n audioContext = ctx;\n if (ctx.state === 'suspended') {\n await ctx.resume();\n }\n\n // Hangover is expressed in ms; convert to a block count using this\n // context's actual sample rate (block size is fixed at 128 samples by\n // the Web Audio spec, but wall-clock duration per block varies with\n // sample rate across devices/browsers).\n const hangoverBlocks = Math.max(\n 1,\n Math.round((hangoverMs / 1000) * (ctx.sampleRate / WORKLET_BLOCK_SIZE)),\n );\n\n const blob = new Blob([SPEECH_ACTIVITY_PROCESSOR_SOURCE], {\n type: 'application/javascript',\n });\n const blobUrl = URL.createObjectURL(blob);\n try {\n await ctx.audioWorklet.addModule(blobUrl);\n } finally {\n URL.revokeObjectURL(blobUrl);\n }\n\n if (cancelled) {\n await ctx.close();\n return;\n }\n\n mediaStreamSource = ctx.createMediaStreamSource(\n new MediaStream([track.mediaStreamTrack]),\n );\n node = new AudioWorkletNode(ctx, SPEECH_ACTIVITY_PROCESSOR_NAME, {\n processorOptions: { thresholdRms, hangoverBlocks },\n });\n node.port.onmessage = (event: MessageEvent) => {\n const timestampMs = performance.now();\n if (event.data?.type === 'onset') {\n options.onSpeechStart?.(timestampMs);\n } else if (event.data?.type === 'offset') {\n options.onSpeechEnd?.(timestampMs);\n }\n };\n mediaStreamSource.connect(node);\n };\n\n setup().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\n '[useSpeechActivityDetector] failed to set up AudioWorklet',\n error,\n );\n });\n\n return {\n cleanup: () => {\n cancelled = true;\n if (node) {\n node.port.onmessage = null;\n node.disconnect();\n }\n mediaStreamSource?.disconnect();\n void audioContext?.close();\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ var _useSpeechActivityDetector = require("./useSpeechActivityDetector");
5
+ Object.keys(_useSpeechActivityDetector).forEach(function (key) {
6
+ if (key === "default" || key === "__esModule") return;
7
+ if (key in exports && exports[key] === _useSpeechActivityDetector[key]) return;
8
+ exports[key] = _useSpeechActivityDetector[key];
9
+ });
10
+ var _types = require("./types");
11
+ Object.keys(_types).forEach(function (key) {
12
+ if (key === "default" || key === "__esModule") return;
13
+ if (key in exports && exports[key] === _types[key]) return;
14
+ exports[key] = _types[key];
15
+ });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_useSpeechActivityDetector","require","Object","keys","forEach","key","exports","_types"],"sources":["../../../../src/hooks/useSpeechActivityDetector/index.ts"],"sourcesContent":["export * from './useSpeechActivityDetector';\nexport * from './types';\n"],"mappings":";;;AAAA,IAAAA,0BAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,0BAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,0BAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,0BAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,MAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,MAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,MAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,MAAA,CAAAF,GAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.SPEECH_ACTIVITY_PROCESSOR_SOURCE = exports.SPEECH_ACTIVITY_PROCESSOR_NAME = void 0;
5
+ // AudioWorkletProcessor source, kept as a plain string and loaded via a Blob
6
+ // URL (see helpers.ts). AudioWorkletGlobalScope runs isolated code on the
7
+ // dedicated audio rendering thread — it is not throttled when the tab is
8
+ // backgrounded, unlike requestAnimationFrame-driven analysis. Threshold
9
+ // crossings are posted back to the main thread via `port.postMessage`.
10
+ const SPEECH_ACTIVITY_PROCESSOR_NAME = exports.SPEECH_ACTIVITY_PROCESSOR_NAME = 'speech-activity-processor';
11
+ const SPEECH_ACTIVITY_PROCESSOR_SOURCE = exports.SPEECH_ACTIVITY_PROCESSOR_SOURCE = `
12
+ class SpeechActivityProcessor extends AudioWorkletProcessor {
13
+ constructor(options) {
14
+ super();
15
+ const opts = (options && options.processorOptions) || {};
16
+ this.threshold = typeof opts.thresholdRms === 'number' ? opts.thresholdRms : 0.015;
17
+ this.hangoverBlocks = typeof opts.hangoverBlocks === 'number' ? opts.hangoverBlocks : 8;
18
+ this.speaking = false;
19
+ this.silentBlockCount = 0;
20
+ }
21
+
22
+ process(inputs) {
23
+ const input = inputs[0];
24
+ const channel = input && input[0];
25
+ if (!channel || channel.length === 0) {
26
+ return true;
27
+ }
28
+
29
+ let sumSquares = 0;
30
+ for (let i = 0; i < channel.length; i++) {
31
+ sumSquares += channel[i] * channel[i];
32
+ }
33
+ const rms = Math.sqrt(sumSquares / channel.length);
34
+ const isLoud = rms > this.threshold;
35
+
36
+ if (isLoud) {
37
+ this.silentBlockCount = 0;
38
+ if (!this.speaking) {
39
+ this.speaking = true;
40
+ this.port.postMessage({ type: 'onset', rms: rms });
41
+ }
42
+ } else if (this.speaking) {
43
+ this.silentBlockCount += 1;
44
+ if (this.silentBlockCount >= this.hangoverBlocks) {
45
+ this.speaking = false;
46
+ this.port.postMessage({ type: 'offset', rms: rms });
47
+ }
48
+ }
49
+ return true;
50
+ }
51
+ }
52
+
53
+ registerProcessor('${SPEECH_ACTIVITY_PROCESSOR_NAME}', SpeechActivityProcessor);
54
+ `;
55
+ //# sourceMappingURL=speechActivityProcessorSource.js.map