@wix/legends-platform-sdk 1.24.0 → 1.26.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 (78) hide show
  1. package/README.md +21 -3
  2. package/dist/cjs/hooks/useConversation/livekit/constants.js +3 -1
  3. package/dist/cjs/hooks/useConversation/livekit/constants.js.map +1 -1
  4. package/dist/cjs/hooks/useConversation/livekit/types.js.map +1 -1
  5. package/dist/cjs/hooks/useConversation/livekit/useConversation.js +34 -6
  6. package/dist/cjs/hooks/useConversation/livekit/useConversation.js.map +1 -1
  7. package/dist/cjs/hooks/useConversation/livekit/utils/dataChannel.js +0 -4
  8. package/dist/cjs/hooks/useConversation/livekit/utils/dataChannel.js.map +1 -1
  9. package/dist/cjs/hooks/useConversation/livekit/utils/index.js +10 -4
  10. package/dist/cjs/hooks/useConversation/livekit/utils/index.js.map +1 -1
  11. package/dist/cjs/hooks/useConversation/livekit/utils/rpc.js +16 -0
  12. package/dist/cjs/hooks/useConversation/livekit/utils/rpc.js.map +1 -0
  13. package/dist/cjs/hooks/useConversation/livekit/utils/toolDefinitions.js +22 -0
  14. package/dist/cjs/hooks/useConversation/livekit/utils/toolDefinitions.js.map +1 -0
  15. package/dist/cjs/hooks/useTextChat/streamChatMessage.js +18 -1
  16. package/dist/cjs/hooks/useTextChat/streamChatMessage.js.map +1 -1
  17. package/dist/cjs/hooks/useTextChat/useTextChatStream.js +5 -2
  18. package/dist/cjs/hooks/useTextChat/useTextChatStream.js.map +1 -1
  19. package/dist/cjs/hooks/useTools/index.js.map +1 -1
  20. package/dist/cjs/hooks/useTools/model/types.js.map +1 -1
  21. package/dist/cjs/hooks/useTools/runtime/executeToolCall.js +2 -1
  22. package/dist/cjs/hooks/useTools/runtime/executeToolCall.js.map +1 -1
  23. package/dist/cjs/hooks/useTools/runtime/useToolCallingRuntime.js +10 -1
  24. package/dist/cjs/hooks/useTools/runtime/useToolCallingRuntime.js.map +1 -1
  25. package/dist/esm/hooks/useConversation/livekit/constants.js +2 -0
  26. package/dist/esm/hooks/useConversation/livekit/constants.js.map +1 -1
  27. package/dist/esm/hooks/useConversation/livekit/types.js.map +1 -1
  28. package/dist/esm/hooks/useConversation/livekit/useConversation.js +37 -8
  29. package/dist/esm/hooks/useConversation/livekit/useConversation.js.map +1 -1
  30. package/dist/esm/hooks/useConversation/livekit/utils/dataChannel.js +0 -3
  31. package/dist/esm/hooks/useConversation/livekit/utils/dataChannel.js.map +1 -1
  32. package/dist/esm/hooks/useConversation/livekit/utils/index.js +2 -1
  33. package/dist/esm/hooks/useConversation/livekit/utils/index.js.map +1 -1
  34. package/dist/esm/hooks/useConversation/livekit/utils/rpc.js +12 -0
  35. package/dist/esm/hooks/useConversation/livekit/utils/rpc.js.map +1 -0
  36. package/dist/esm/hooks/useConversation/livekit/utils/toolDefinitions.js +20 -0
  37. package/dist/esm/hooks/useConversation/livekit/utils/toolDefinitions.js.map +1 -0
  38. package/dist/esm/hooks/useTextChat/streamChatMessage.js +17 -1
  39. package/dist/esm/hooks/useTextChat/streamChatMessage.js.map +1 -1
  40. package/dist/esm/hooks/useTextChat/useTextChatStream.js +5 -2
  41. package/dist/esm/hooks/useTextChat/useTextChatStream.js.map +1 -1
  42. package/dist/esm/hooks/useTools/index.js.map +1 -1
  43. package/dist/esm/hooks/useTools/model/types.js.map +1 -1
  44. package/dist/esm/hooks/useTools/runtime/executeToolCall.js +2 -1
  45. package/dist/esm/hooks/useTools/runtime/executeToolCall.js.map +1 -1
  46. package/dist/esm/hooks/useTools/runtime/useToolCallingRuntime.js +10 -1
  47. package/dist/esm/hooks/useTools/runtime/useToolCallingRuntime.js.map +1 -1
  48. package/dist/types/hooks/useConversation/livekit/constants.d.ts +2 -0
  49. package/dist/types/hooks/useConversation/livekit/constants.d.ts.map +1 -1
  50. package/dist/types/hooks/useConversation/livekit/types.d.ts +4 -14
  51. package/dist/types/hooks/useConversation/livekit/types.d.ts.map +1 -1
  52. package/dist/types/hooks/useConversation/livekit/useConversation.d.ts.map +1 -1
  53. package/dist/types/hooks/useConversation/livekit/utils/dataChannel.d.ts +1 -2
  54. package/dist/types/hooks/useConversation/livekit/utils/dataChannel.d.ts.map +1 -1
  55. package/dist/types/hooks/useConversation/livekit/utils/index.d.ts +2 -1
  56. package/dist/types/hooks/useConversation/livekit/utils/index.d.ts.map +1 -1
  57. package/dist/types/hooks/useConversation/livekit/utils/rpc.d.ts +3 -0
  58. package/dist/types/hooks/useConversation/livekit/utils/rpc.d.ts.map +1 -0
  59. package/dist/types/hooks/useConversation/livekit/utils/toolDefinitions.d.ts +4 -0
  60. package/dist/types/hooks/useConversation/livekit/utils/toolDefinitions.d.ts.map +1 -0
  61. package/dist/types/hooks/useTextChat/streamChatMessage.d.ts +2 -0
  62. package/dist/types/hooks/useTextChat/streamChatMessage.d.ts.map +1 -1
  63. package/dist/types/hooks/useTextChat/useTextChatStream.d.ts +1 -0
  64. package/dist/types/hooks/useTextChat/useTextChatStream.d.ts.map +1 -1
  65. package/dist/types/hooks/useTools/index.d.ts +1 -1
  66. package/dist/types/hooks/useTools/index.d.ts.map +1 -1
  67. package/dist/types/hooks/useTools/model/types.d.ts +6 -1
  68. package/dist/types/hooks/useTools/model/types.d.ts.map +1 -1
  69. package/dist/types/hooks/useTools/runtime/executeToolCall.d.ts.map +1 -1
  70. package/dist/types/hooks/useTools/runtime/useToolCallingRuntime.d.ts +1 -0
  71. package/dist/types/hooks/useTools/runtime/useToolCallingRuntime.d.ts.map +1 -1
  72. package/package.json +2 -2
  73. package/dist/cjs/hooks/useConversation/livekit/utils/toolAdapter.js +0 -18
  74. package/dist/cjs/hooks/useConversation/livekit/utils/toolAdapter.js.map +0 -1
  75. package/dist/esm/hooks/useConversation/livekit/utils/toolAdapter.js +0 -14
  76. package/dist/esm/hooks/useConversation/livekit/utils/toolAdapter.js.map +0 -1
  77. package/dist/types/hooks/useConversation/livekit/utils/toolAdapter.d.ts +0 -4
  78. package/dist/types/hooks/useConversation/livekit/utils/toolAdapter.d.ts.map +0 -1
package/README.md CHANGED
@@ -174,9 +174,21 @@ Observe client-side tool calls executed by the SDK. Register tool handlers by pa
174
174
  import { LegendsPlatform, useTools, type ToolsRegistry } from '@wix/legends-platform-sdk/livekit/sdk';
175
175
 
176
176
  const tools: ToolsRegistry = {
177
- get_weather: async ({ city }) => {
178
- const data = await fetchWeather(city as string);
179
- return { temperature: data.temp };
177
+ fill_input: {
178
+ description:
179
+ 'Fill a form field on the current page with a value the user provided. Use when the user asks to enter, type or set a value in a field. Returns a confirmation.',
180
+ parameters: {
181
+ type: 'object',
182
+ properties: {
183
+ fieldId: { type: 'string', description: 'The id of the input to fill, e.g. "email"' },
184
+ value: { type: 'string', description: 'The exact value to enter' },
185
+ },
186
+ required: ['fieldId', 'value'],
187
+ },
188
+ handler: ({ fieldId, value }) => {
189
+ setFormValue(fieldId as string, value as string);
190
+ return `Filled ${fieldId} with ${value}`; // returned to the LLM as the tool result
191
+ },
180
192
  },
181
193
  };
182
194
 
@@ -195,6 +207,12 @@ function ToolLog() {
195
207
  </LegendsPlatform>
196
208
  ```
197
209
 
210
+ Frontend-defined tools are currently offered to the agent in LiveKit voice and video calls only. The SDK does not yet send tool definitions in text-chat requests. Text chat can execute registered handlers for tools configured on the backend, but registering a tool here does not make it available to the text-chat LLM.
211
+
212
+ During a voice or video call the SDK registers two LiveKit RPC methods on the room: the agent calls `get_tools` when the user joins to receive the definitions, and `execute_tool` with `{ functionCallId, name, arguments }` for each call. The SDK runs the handler and replies with `{ functionCallId, result, error }`.
213
+
214
+ A bare function is still accepted as a registry value for backwards compatibility. It runs when the backend requests it by name, but it has no schema so it is not sent to the agent.
215
+
198
216
  #### `useSpeechActivityDetector(options)`
199
217
 
200
218
  Acoustic speech onset/offset detector driven by `AudioWorkletNode`. Useful for measuring end-to-end latency or building custom VAD UI.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.SPEAKING_STATE_EVENT_MAP = exports.ACOUSTIC_USER_THRESHOLD_RMS = exports.ACOUSTIC_USER_HANGOVER_MS = exports.ACOUSTIC_AGENT_HANGOVER_MS = void 0;
4
+ exports.SPEAKING_STATE_EVENT_MAP = exports.GET_TOOLS_RPC_METHOD = exports.EXECUTE_TOOL_RPC_METHOD = 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',
@@ -15,4 +15,6 @@ const SPEAKING_STATE_EVENT_MAP = exports.SPEAKING_STATE_EVENT_MAP = {
15
15
  const ACOUSTIC_USER_THRESHOLD_RMS = exports.ACOUSTIC_USER_THRESHOLD_RMS = 0.025;
16
16
  const ACOUSTIC_USER_HANGOVER_MS = exports.ACOUSTIC_USER_HANGOVER_MS = 400;
17
17
  const ACOUSTIC_AGENT_HANGOVER_MS = exports.ACOUSTIC_AGENT_HANGOVER_MS = 900;
18
+ const GET_TOOLS_RPC_METHOD = exports.GET_TOOLS_RPC_METHOD = 'get_tools';
19
+ const EXECUTE_TOOL_RPC_METHOD = exports.EXECUTE_TOOL_RPC_METHOD = 'execute_tool';
18
20
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
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":[]}
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","GET_TOOLS_RPC_METHOD","EXECUTE_TOOL_RPC_METHOD"],"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\nexport const GET_TOOLS_RPC_METHOD = 'get_tools';\nexport const EXECUTE_TOOL_RPC_METHOD = 'execute_tool';\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;AAEtC,MAAMC,oBAAoB,GAAAR,OAAA,CAAAQ,oBAAA,GAAG,WAAW;AACxC,MAAMC,uBAAuB,GAAAT,OAAA,CAAAS,uBAAA,GAAG,cAAc","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../../../../src/hooks/useConversation/livekit/types.ts"],"sourcesContent":["import type { FunctionCall, FunctionCallResult } from '../../../types/service';\nimport type {\n ToolCallEnvelope,\n ToolRuntimeAdapter,\n} from '../../useTools/runtime/types';\n\nexport type InactivityWarningData = {\n type: 'inactivity_warning';\n grace_period_sec: number;\n};\n\nexport type InactivityTimeoutData = {\n type: 'inactivity_timeout';\n};\n\nexport type ToolRuntimeLike = {\n handleIncoming(\n envelope: ToolCallEnvelope,\n adapter: ToolRuntimeAdapter,\n ): Promise<void>;\n};\n\nexport type TurnDetectionData = {\n createdAt: number;\n participantIdentity: string;\n sequence: number;\n source: string;\n state: 'listening' | 'speaking';\n turnDetectionStrategy: 'livekit_turn_detector' | 'silero_vad';\n type: string;\n version: number;\n participantKind: 'STANDARD' | 'AGENT';\n speechId?: string;\n};\n\nexport type ToolCallsData = {\n type: 'tool_calls';\n requestId: string;\n functionCalls: FunctionCall[];\n};\n\nexport type ToolResultsData = {\n type: 'tool_results';\n requestId: string;\n functionCallResults: FunctionCallResult[];\n};\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["../../../../../src/hooks/useConversation/livekit/types.ts"],"sourcesContent":["export type InactivityWarningData = {\n type: 'inactivity_warning';\n grace_period_sec: number;\n};\n\nexport type InactivityTimeoutData = {\n type: 'inactivity_timeout';\n};\n\nexport type TurnDetectionData = {\n createdAt: number;\n participantIdentity: string;\n sequence: number;\n source: string;\n state: 'listening' | 'speaking';\n turnDetectionStrategy: 'livekit_turn_detector' | 'silero_vad';\n type: string;\n version: number;\n participantKind: 'STANDARD' | 'AGENT';\n speechId?: string;\n};\n\nexport type ClientToolDefinition = {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n};\n"],"mappings":"","ignoreList":[]}
@@ -11,11 +11,13 @@ var _reactUse = require("react-use");
11
11
  var _componentsReact = require("@livekit/components-react");
12
12
  var _jotai = require("jotai");
13
13
  var _conversation = require("../../../conversation");
14
+ var _sdkConsumer = require("../../../sdk-consumer");
14
15
  var _useCreateConversation = require("../../useCreateConversation");
15
16
  var _useSpeechActivityDetector = require("../../useSpeechActivityDetector");
16
17
  var _useParticipantTrack = require("../../useParticipantTrack");
17
18
  var _useEmitConversationEvent = require("../../useConversationEvents/useEmitConversationEvent");
18
19
  var _useToolCallingRuntime = require("../../useTools/runtime/useToolCallingRuntime");
20
+ var _serialize = require("../../useTools/utils/serialize");
19
21
  var _utils = require("./utils");
20
22
  var _constants = require("./constants");
21
23
  function useConversation({
@@ -39,8 +41,11 @@ function useConversation({
39
41
  const speaker = (0, _jotai.useAtomValue)(_conversation.state.speaker);
40
42
  const [microphone, setMicrophone] = (0, _jotai.useAtom)(_conversation.state.microphone);
41
43
  const [camera, setCamera] = (0, _jotai.useAtom)(_conversation.state.camera);
44
+ const {
45
+ tools: toolsRegistry = {}
46
+ } = (0, _sdkConsumer.useSdkConsumer)();
42
47
  const toolRuntime = (0, _useToolCallingRuntime.useToolCallingRuntime)();
43
- const toolAdapter = (0, _utils.createLivekitToolAdapter)(room);
48
+ const toolsRegistryRef = (0, _reactUse.useLatest)(toolsRegistry);
44
49
 
45
50
  // for use in register/unregister room events
46
51
  const conversationRef = (0, _reactUse.useLatest)(conversation.data);
@@ -301,13 +306,30 @@ function useConversation({
301
306
  conversationId: (_conversationRef$curr5 = conversationRef.current) == null ? void 0 : _conversationRef$curr5.id
302
307
  });
303
308
  }
304
- async function handleToolCallsEvent(data) {
305
- await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);
309
+ async function handleGetToolsRpc() {
310
+ return JSON.stringify((0, _utils.buildToolDefinitions)(toolsRegistryRef.current));
311
+ }
312
+ async function handleExecuteToolRpc(data) {
313
+ const call = (0, _utils.parseFunctionCallPayload)(data.payload);
314
+ if (!call) {
315
+ return JSON.stringify({
316
+ functionCallId: '',
317
+ result: '',
318
+ error: 'Malformed function call payload.'
319
+ });
320
+ }
321
+ try {
322
+ const [result] = await toolRuntimeRef.current.executeToolCalls([call]);
323
+ return JSON.stringify(result);
324
+ } catch (error) {
325
+ return JSON.stringify({
326
+ functionCallId: call.functionCallId,
327
+ result: '',
328
+ error: (0, _serialize.extractToolErrorMessage)(error)
329
+ });
330
+ }
306
331
  }
307
332
  const dataChannelHandlers = [{
308
- guard: _utils.checkIsToolCallsData,
309
- handle: handleToolCallsEvent
310
- }, {
311
333
  guard: _utils.checkIsTurnDetectionData,
312
334
  handle: handleTurnDetectionEvent
313
335
  }, {
@@ -450,8 +472,14 @@ function useConversation({
450
472
  }
451
473
  function registerRoomEvents() {
452
474
  room.on('connected', handleConnectedEvent).on('encryptionError', handleEncryptionErrorEvent).on('disconnected', handleDisconnectedEvent).on('transcriptionReceived', handleTranscriptionReceivedEvent).on('participantConnected', handleParticipantConnectedEvent).on('participantDisconnected', handleParticipantDisconnectedEvent).on('dataReceived', handleDataReceivedEvent);
475
+ room.unregisterRpcMethod(_constants.GET_TOOLS_RPC_METHOD);
476
+ room.unregisterRpcMethod(_constants.EXECUTE_TOOL_RPC_METHOD);
477
+ room.registerRpcMethod(_constants.GET_TOOLS_RPC_METHOD, handleGetToolsRpc);
478
+ room.registerRpcMethod(_constants.EXECUTE_TOOL_RPC_METHOD, handleExecuteToolRpc);
453
479
  }
454
480
  function unregisterRoomEvents() {
481
+ room.unregisterRpcMethod(_constants.GET_TOOLS_RPC_METHOD);
482
+ room.unregisterRpcMethod(_constants.EXECUTE_TOOL_RPC_METHOD);
455
483
  room.off('connected', handleConnectedEvent);
456
484
  room.off('encryptionError', handleEncryptionErrorEvent);
457
485
  room.off('disconnected', handleDisconnectedEvent);
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_useCreateConversation","_useSpeechActivityDetector","_useParticipantTrack","_useEmitConversationEvent","_useToolCallingRuntime","_utils","_constants","useConversation","autoJoin","type","config","startWithMicrophone","startWithCamera","firstConversation","lastConversationTopic","_conversation$data2","setLogLevel","LogLevel","silent","conversation","useCreateConversation","room","useEnsureRoom","speaker","useAtomValue","state","microphone","setMicrophone","useAtom","camera","setCamera","toolRuntime","useToolCallingRuntime","toolAdapter","createLivekitToolAdapter","conversationRef","useLatest","data","toolRuntimeRef","conversationStatus","setConversationStatus","userConnectionState","setUserConnectionState","joinedAt","setJoinedAt","setActiveMediaDevice","setMicrophoneDeviceId","useMediaDeviceSelect","kind","setSpeakerDeviceId","setCameraDeviceId","requestPermissions","enabled","setTranscriptions","useSetAtom","transcriptions","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","useEmitConversationEvent","inactivityTimeoutRef","useRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userCumulativeTrackStatsRef","undefined","agentCumulativeTrackStatsRef","userMicPublication","useParticipantTrack","source","Source","Microphone","agentMicPublication","timer","useTimer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","useEffect","registerRoomEvents","unregisterRoomEvents","useUpdateEffect","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","restart","getTime","_conversation$data3","invariant","url","URL","accessToken","searchParams","get","connect","remoteParticipant","findJoinedAgentParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","ParticipantKind","AGENT","old","mergeTranscriptions","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","ACOUSTIC_USER_HANGOVER_MS","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","userReport","agentReport","Promise","all","getTrackStats","userStats","parseTrackStats","agentStats","cumulativeTrackStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","useSpeechActivityDetector","onSpeechStart","onSpeechEnd","thresholdRms","ACOUSTIC_USER_THRESHOLD_RMS","hangoverMs","ACOUSTIC_AGENT_HANGOVER_MS","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleToolCallsEvent","resolveIncomingToolCalls","dataChannelHandlers","guard","checkIsToolCallsData","handle","checkIsTurnDetectionData","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","payload","decoded","decodeDataPayload","resolve","catch","handleConnectedEvent","_conversationRef$curr6","handleEncryptionErrorEvent","handleDisconnectedEvent","reason","DisconnectReason","CLIENT_INITIATED","ROOM_CLOSED","handleParticipantConnectedEvent","shouldHandleParticipantConnected","_conversationRef$curr7","handleParticipantDisconnectedEvent","_conversationRef$curr8","leave","_conversationRef$curr9","disconnect","_conversationRef$curr0","_conversationRef$curr1","interrupt","_conversationRef$curr10","publishConversationDataMessage","dismissInactivity","send","attachments","_conversationRef$curr11","sendText","topic","attributes","safeStringify","on","off","status"],"sources":["../../../../../src/hooks/useConversation/livekit/useConversation.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport {\n DisconnectReason,\n Participant,\n setLogLevel,\n ParticipantKind,\n RemoteParticipant,\n TranscriptionSegment,\n LogLevel,\n} from 'livekit-client';\nimport invariant from 'invariant';\nimport { useTimer } from 'react-timer-hook';\nimport { useLatest, useUpdateEffect } from 'react-use';\nimport { useEnsureRoom, useMediaDeviceSelect } from '@livekit/components-react';\nimport { useAtom, useAtomValue, useSetAtom } from 'jotai';\nimport {\n Conversation,\n state,\n type ConversationTranscription,\n} from '../../../conversation';\nimport type {\n UseConversationResult,\n UseConversationOptions,\n Attachment,\n} from '../types';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n ToolCallsData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n type CumulativeTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n checkIsToolCallsData,\n createLivekitToolAdapter,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n publishConversationDataMessage,\n safeStringify,\n shouldHandleParticipantConnected,\n} from './utils';\nimport {\n ACOUSTIC_AGENT_HANGOVER_MS,\n ACOUSTIC_USER_HANGOVER_MS,\n ACOUSTIC_USER_THRESHOLD_RMS,\n} from './constants';\n\nexport function useConversation({\n autoJoin = true,\n type,\n config,\n startWithMicrophone = false,\n startWithCamera = false,\n firstConversation,\n lastConversationTopic,\n}: UseConversationOptions): UseConversationResult {\n setLogLevel(LogLevel.silent);\n\n const conversation = useCreateConversation({\n type,\n config,\n firstConversation,\n lastConversationTopic,\n });\n const room = useEnsureRoom();\n const speaker = useAtomValue(state.speaker);\n const [microphone, setMicrophone] = useAtom(state.microphone);\n const [camera, setCamera] = useAtom(state.camera);\n const toolRuntime = useToolCallingRuntime();\n const toolAdapter = createLivekitToolAdapter(room);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n const userCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n const agentCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userReport, agentReport] = await Promise.all([\n getTrackStats(userMicPublication),\n getTrackStats(agentMicPublication),\n ]);\n const userStats = parseTrackStats(\n userReport,\n userCumulativeTrackStatsRef.current,\n );\n const agentStats = parseTrackStats(\n agentReport,\n agentCumulativeTrackStatsRef.current,\n );\n userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;\n agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleToolCallsEvent(data: ToolCallsData) {\n await toolRuntimeRef.current.resolveIncomingToolCalls(data, toolAdapter);\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsToolCallsData,\n handle: handleToolCallsEvent as (data: unknown) => Promise<void>,\n },\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n userCumulativeTrackStatsRef.current = undefined;\n agentCumulativeTrackStatsRef.current = undefined;\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n }\n\n function unregisterRoomEvents() {\n room.off('connected', handleConnectedEvent);\n room.off('encryptionError', handleEncryptionErrorEvent);\n room.off('disconnected', handleDisconnectedEvent);\n room.off('transcriptionReceived', handleTranscriptionReceivedEvent);\n room.off('participantConnected', handleParticipantConnectedEvent);\n room.off('participantDisconnected', handleParticipantDisconnectedEvent);\n room.off('dataReceived', handleDataReceivedEvent);\n }\n\n return {\n status: conversationStatus,\n conversation: conversation.data,\n join,\n send,\n interrupt,\n dismissInactivity,\n leave,\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_livekitClient","_invariant","_interopRequireDefault","_reactTimerHook","_reactUse","_componentsReact","_jotai","_conversation","_sdkConsumer","_useCreateConversation","_useSpeechActivityDetector","_useParticipantTrack","_useEmitConversationEvent","_useToolCallingRuntime","_serialize","_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","tools","toolsRegistry","useSdkConsumer","toolRuntime","useToolCallingRuntime","toolsRegistryRef","useLatest","conversationRef","data","toolRuntimeRef","conversationStatus","setConversationStatus","userConnectionState","setUserConnectionState","joinedAt","setJoinedAt","setActiveMediaDevice","setMicrophoneDeviceId","useMediaDeviceSelect","kind","setSpeakerDeviceId","setCameraDeviceId","requestPermissions","enabled","setTranscriptions","useSetAtom","transcriptions","agentConnectionState","setAgentConnectionState","setAgentActivityState","agentActivityState","setUserActivityState","userActivityState","emitEvent","useEmitConversationEvent","inactivityTimeoutRef","useRef","acousticPhaseRef","acousticT0Ref","latestTurnMetadataRef","isConnectedRef","userCumulativeTrackStatsRef","undefined","agentCumulativeTrackStatsRef","userMicPublication","useParticipantTrack","source","Source","Microphone","agentMicPublication","timer","useTimer","autoStart","onExpire","handleExpire","expiryTimestamp","Date","useEffect","registerRoomEvents","unregisterRoomEvents","useUpdateEffect","deviceId","localParticipant","setMicrophoneEnabled","setCameraEnabled","resolution","width","height","join","_conversation$data","limit","restart","getTime","_conversation$data3","invariant","url","URL","accessToken","searchParams","get","connect","remoteParticipant","findJoinedAgentParticipant","handleAgentJoin","enableMediaDevices","error","console","handleTranscriptionReceivedEvent","segments","participant","map","s","id","message","text","ParticipantKind","AGENT","old","mergeTranscriptions","handleTurnDetectionEvent","_conversationRef$curr","conversationId","current","participantKind","eventState","turnDetectionStrategy","sequence","speechId","handleAcousticUserOnset","handleAcousticUserOffset","timestampMs","ACOUSTIC_USER_HANGOVER_MS","handleAcousticAgentOnset","_conversationRef$curr2","latencyMs","emitConversationTurnLatency","clientAcousticLatencyMs","_conversationRef$curr3","userReport","agentReport","Promise","all","getTrackStats","userStats","parseTrackStats","agentStats","cumulativeTrackStats","rttMs","roundTripTimeMs","jitterBufferDelayMs","userPacketsLost","packetsLost","agentPacketsLost","handleAcousticAgentOffset","useSpeechActivityDetector","onSpeechStart","onSpeechEnd","thresholdRms","ACOUSTIC_USER_THRESHOLD_RMS","hangoverMs","ACOUSTIC_AGENT_HANGOVER_MS","handleInactivityWarningEvent","_conversationRef$curr4","gracePeriodSec","grace_period_sec","handleInactivityTimeoutEvent","_data","_conversationRef$curr5","handleGetToolsRpc","JSON","stringify","buildToolDefinitions","handleExecuteToolRpc","call","parseFunctionCallPayload","payload","functionCallId","result","executeToolCalls","extractToolErrorMessage","dataChannelHandlers","guard","checkIsTurnDetectionData","handle","checkIsInactivityWarningData","checkIsInactivityTimeoutData","handleDataReceivedEvent","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","unregisterRpcMethod","GET_TOOLS_RPC_METHOD","EXECUTE_TOOL_RPC_METHOD","registerRpcMethod","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 type RpcInvocationData,\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 { FunctionCallResult } from '../../../types/service';\nimport { useSdkConsumer } from '../../../sdk-consumer';\nimport type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n} from './types';\nimport { useCreateConversation } from '../../useCreateConversation';\nimport { useSpeechActivityDetector } from '../../useSpeechActivityDetector';\nimport {\n useParticipantTrack,\n Source,\n getTrackStats,\n parseTrackStats,\n type CumulativeTrackStats,\n} from '../../useParticipantTrack';\n\nimport { useEmitConversationEvent } from '../../useConversationEvents/useEmitConversationEvent';\nimport { useToolCallingRuntime } from '../../useTools/runtime/useToolCallingRuntime';\nimport { extractToolErrorMessage } from '../../useTools/utils/serialize';\nimport {\n checkIsTurnDetectionData,\n checkIsInactivityWarningData,\n checkIsInactivityTimeoutData,\n buildToolDefinitions,\n decodeDataPayload,\n findJoinedAgentParticipant,\n mergeTranscriptions,\n parseFunctionCallPayload,\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 EXECUTE_TOOL_RPC_METHOD,\n GET_TOOLS_RPC_METHOD,\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 { tools: toolsRegistry = {} } = useSdkConsumer();\n const toolRuntime = useToolCallingRuntime();\n const toolsRegistryRef = useLatest(toolsRegistry);\n\n // for use in register/unregister room events\n const conversationRef = useLatest<Conversation | undefined>(\n conversation.data,\n );\n const toolRuntimeRef = useLatest(toolRuntime);\n\n const [conversationStatus, setConversationStatus] = useAtom(\n state.conversationStatus,\n );\n\n const [userConnectionState, setUserConnectionState] = useAtom(\n state.userConnectionState,\n );\n\n const [joinedAt, setJoinedAt] = useAtom(state.joinedAt);\n\n const { setActiveMediaDevice: setMicrophoneDeviceId } = useMediaDeviceSelect({\n kind: 'audioinput',\n });\n const { setActiveMediaDevice: setSpeakerDeviceId } = useMediaDeviceSelect({\n kind: 'audiooutput',\n });\n const { setActiveMediaDevice: setCameraDeviceId } = useMediaDeviceSelect({\n kind: 'videoinput',\n requestPermissions: camera.enabled,\n });\n\n const setTranscriptions = useSetAtom(state.transcriptions);\n const [agentConnectionState, setAgentConnectionState] = useAtom(\n state.agentConnectionState,\n );\n const setAgentActivityState = useSetAtom(state.agentActivityState);\n const setUserActivityState = useSetAtom(state.userActivityState);\n const emitEvent = useEmitConversationEvent();\n\n const inactivityTimeoutRef = useRef(false);\n const acousticPhaseRef = useRef<'idle' | 'waitingForAgent' | 'busy'>('idle');\n const acousticT0Ref = useRef<number | null>(null);\n const latestTurnMetadataRef = useRef<{\n turnDetectionStrategy?: string;\n sequence?: number;\n speechId?: string;\n }>({});\n const isConnectedRef = useRef(false);\n const userCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n const agentCumulativeTrackStatsRef = useRef<CumulativeTrackStats | undefined>(\n undefined,\n );\n\n const userMicPublication = useParticipantTrack({\n type: 'user',\n source: Source.Microphone,\n });\n const agentMicPublication = useParticipantTrack({\n type: 'agent',\n source: Source.Microphone,\n });\n\n const timer = useTimer({\n autoStart: false,\n onExpire: handleExpire,\n expiryTimestamp: new Date(),\n });\n\n useEffect(() => {\n if (!room) {\n return;\n }\n registerRoomEvents();\n\n return () => {\n unregisterRoomEvents();\n };\n }, [room]);\n\n useUpdateEffect(() => {\n setMicrophoneDeviceId(microphone.deviceId);\n }, [microphone.deviceId]);\n\n useUpdateEffect(() => {\n setSpeakerDeviceId(speaker.deviceId);\n }, [speaker.deviceId]);\n\n useUpdateEffect(() => {\n setCameraDeviceId(camera.deviceId);\n }, [camera.deviceId]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setMicrophoneEnabled(microphone.enabled);\n }, [microphone.enabled, agentConnectionState]);\n\n useUpdateEffect(() => {\n if (agentConnectionState !== 'joined') {\n return;\n }\n room.localParticipant.setCameraEnabled(camera.enabled, {\n resolution: { width: 1920, height: 1080 },\n });\n }, [camera.enabled, agentConnectionState]);\n\n useEffect(() => {\n if (!autoJoin) {\n return;\n }\n\n if (conversationStatus === 'created') {\n void join();\n }\n }, [conversationStatus, autoJoin]);\n\n useEffect(() => {\n if (!joinedAt || conversation.data?.limit === undefined) {\n return;\n }\n\n timer.restart(new Date(joinedAt.getTime() + conversation.data!.limit!));\n }, [joinedAt, conversation.data?.limit]);\n\n async function join() {\n invariant(userConnectionState === 'idle', 'Already joined');\n invariant(conversation.data, 'Conversation is not ready');\n const url = new URL(conversation?.data?.url || '');\n const accessToken = url.searchParams.get('token');\n try {\n setUserConnectionState('joining');\n await room?.connect(conversation.data.url, accessToken!, {});\n\n // sometimes the agent is already joined before the user joins the conversation\n const remoteParticipant = findJoinedAgentParticipant(room, type);\n if (remoteParticipant && agentConnectionState !== 'joined') {\n handleAgentJoin(remoteParticipant);\n }\n\n enableMediaDevices();\n } catch (error) {\n console.error('Failed to join', error);\n setUserConnectionState('join-error');\n }\n }\n\n function enableMediaDevices() {\n if (startWithMicrophone) {\n setMicrophone({ ...microphone, enabled: true });\n }\n if (startWithCamera && type === 'video') {\n setCamera({ ...camera, enabled: true });\n }\n }\n\n function handleTranscriptionReceivedEvent(\n segments: TranscriptionSegment[],\n participant?: Participant,\n ) {\n const transcriptions: ConversationTranscription[] = segments.map((s) => ({\n id: s.id,\n message: s.text,\n source: participant?.kind === ParticipantKind.AGENT ? 'agent' : 'user',\n }));\n\n setTranscriptions((old) => mergeTranscriptions(transcriptions, old));\n }\n\n function handleTurnDetectionEvent(data: TurnDetectionData) {\n const conversationId = conversationRef.current?.id;\n const { participantKind, state: eventState } = data;\n switch (participantKind) {\n case 'STANDARD':\n if (eventState === 'listening') {\n latestTurnMetadataRef.current = {\n turnDetectionStrategy: data.turnDetectionStrategy,\n sequence: data.sequence,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'userSpeakStart' : 'userSpeakStop',\n { conversationId: conversationId! },\n );\n setUserActivityState(eventState);\n break;\n case 'AGENT':\n if (data.speechId) {\n latestTurnMetadataRef.current = {\n ...latestTurnMetadataRef.current,\n speechId: data.speechId,\n };\n }\n emitEvent(\n eventState === 'speaking' ? 'agentSpeakStart' : 'agentSpeakStop',\n { conversationId: conversationId! },\n );\n setAgentActivityState(eventState);\n break;\n }\n }\n\n function handleAcousticUserOnset() {\n if (!isConnectedRef.current) {\n return;\n }\n if (acousticPhaseRef.current === 'waitingForAgent') {\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n }\n }\n\n function handleAcousticUserOffset(timestampMs: number) {\n if (!isConnectedRef.current || acousticPhaseRef.current !== 'idle') {\n return;\n }\n acousticT0Ref.current = timestampMs - ACOUSTIC_USER_HANGOVER_MS;\n acousticPhaseRef.current = 'waitingForAgent';\n }\n\n function handleAcousticAgentOnset(timestampMs: number) {\n if (\n !isConnectedRef.current ||\n acousticPhaseRef.current !== 'waitingForAgent' ||\n acousticT0Ref.current == null\n ) {\n return;\n }\n\n const latencyMs = timestampMs - acousticT0Ref.current;\n acousticT0Ref.current = null;\n acousticPhaseRef.current = 'busy';\n\n if (latencyMs < 0 || latencyMs > 15000) {\n return;\n }\n\n emitEvent('responseLatency', {\n conversationId: conversationRef.current?.id!,\n latencyMs,\n turnDetectionStrategy:\n latestTurnMetadataRef.current.turnDetectionStrategy!,\n sequence: latestTurnMetadataRef.current.sequence,\n speechId: latestTurnMetadataRef.current.speechId,\n });\n\n void emitConversationTurnLatency(latencyMs);\n }\n\n async function emitConversationTurnLatency(clientAcousticLatencyMs: number) {\n const [userReport, agentReport] = await Promise.all([\n getTrackStats(userMicPublication),\n getTrackStats(agentMicPublication),\n ]);\n const userStats = parseTrackStats(\n userReport,\n userCumulativeTrackStatsRef.current,\n );\n const agentStats = parseTrackStats(\n agentReport,\n agentCumulativeTrackStatsRef.current,\n );\n userCumulativeTrackStatsRef.current = userStats.cumulativeTrackStats;\n agentCumulativeTrackStatsRef.current = agentStats.cumulativeTrackStats;\n\n emitEvent('conversationTurnLatency', {\n conversationId: conversationRef.current?.id!,\n speechId: latestTurnMetadataRef.current.speechId,\n sequence: latestTurnMetadataRef.current.sequence,\n clientAcousticLatencyMs,\n rttMs: userStats.roundTripTimeMs,\n jitterBufferDelayMs: agentStats.jitterBufferDelayMs,\n userPacketsLost: userStats.packetsLost,\n agentPacketsLost: agentStats.packetsLost,\n });\n }\n\n function handleAcousticAgentOffset() {\n acousticPhaseRef.current = 'idle';\n }\n\n useSpeechActivityDetector({\n source: 'user',\n onSpeechStart: handleAcousticUserOnset,\n onSpeechEnd: handleAcousticUserOffset,\n thresholdRms: ACOUSTIC_USER_THRESHOLD_RMS,\n hangoverMs: ACOUSTIC_USER_HANGOVER_MS,\n });\n useSpeechActivityDetector({\n source: 'agent',\n onSpeechStart: handleAcousticAgentOnset,\n onSpeechEnd: handleAcousticAgentOffset,\n hangoverMs: ACOUSTIC_AGENT_HANGOVER_MS,\n });\n\n function handleInactivityWarningEvent(data: InactivityWarningData) {\n emitEvent('inactivityWarning', {\n conversationId: conversationRef.current?.id!,\n gracePeriodSec: data.grace_period_sec,\n });\n }\n\n function handleInactivityTimeoutEvent(_data: InactivityTimeoutData) {\n inactivityTimeoutRef.current = true;\n emitEvent('inactivityTimeout', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleGetToolsRpc() {\n return JSON.stringify(buildToolDefinitions(toolsRegistryRef.current));\n }\n\n async function handleExecuteToolRpc(data: RpcInvocationData) {\n const call = parseFunctionCallPayload(data.payload);\n if (!call) {\n return JSON.stringify({\n functionCallId: '',\n result: '',\n error: 'Malformed function call payload.',\n } satisfies FunctionCallResult);\n }\n try {\n const [result] = await toolRuntimeRef.current.executeToolCalls([call]);\n return JSON.stringify(result);\n } catch (error) {\n return JSON.stringify({\n functionCallId: call.functionCallId,\n result: '',\n error: extractToolErrorMessage(error),\n } satisfies FunctionCallResult);\n }\n }\n\n const dataChannelHandlers: {\n guard: (data: unknown) => boolean;\n handle: (data: unknown) => void | Promise<void>;\n }[] = [\n {\n guard: checkIsTurnDetectionData,\n handle: handleTurnDetectionEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityWarningData,\n handle: handleInactivityWarningEvent as (data: unknown) => void,\n },\n {\n guard: checkIsInactivityTimeoutData,\n handle: handleInactivityTimeoutEvent as (data: unknown) => void,\n },\n ];\n\n function handleDataReceivedEvent(payload: Uint8Array) {\n const decoded = decodeDataPayload(payload);\n if (decoded === null) {\n return;\n }\n for (const { guard, handle } of dataChannelHandlers) {\n if (guard(decoded)) {\n void Promise.resolve(handle(decoded)).catch((error) => {\n console.error('Failed to handle data channel payload', error);\n });\n return;\n }\n }\n }\n\n function handleConnectedEvent() {\n isConnectedRef.current = true;\n setUserConnectionState('joined');\n setAgentConnectionState('joining');\n emitEvent('callStarted', {\n conversationId: conversationRef.current?.id!,\n });\n }\n\n async function handleEncryptionErrorEvent(error: Error) {\n console.error('Encryption error', error);\n setConversationStatus('error');\n }\n\n function handleDisconnectedEvent(reason?: DisconnectReason) {\n isConnectedRef.current = false;\n acousticPhaseRef.current = 'idle';\n acousticT0Ref.current = null;\n latestTurnMetadataRef.current = {};\n userCumulativeTrackStatsRef.current = undefined;\n agentCumulativeTrackStatsRef.current = undefined;\n setAgentActivityState('idle');\n setAgentConnectionState('idle');\n setUserActivityState('idle');\n setUserConnectionState('idle');\n\n if (inactivityTimeoutRef.current) {\n inactivityTimeoutRef.current = false;\n setConversationStatus('inactivity-timeout');\n return;\n }\n\n switch (reason) {\n case DisconnectReason.CLIENT_INITIATED:\n break;\n case DisconnectReason.ROOM_CLOSED:\n setConversationStatus('destroyed');\n break;\n default:\n console.error('Conversation disconnected with reason', reason);\n setConversationStatus('error');\n break;\n }\n }\n\n function handleParticipantConnectedEvent(participant: RemoteParticipant) {\n if (shouldHandleParticipantConnected(participant, type)) {\n handleAgentJoin(participant);\n }\n }\n\n function handleAgentJoin(participant: RemoteParticipant) {\n setAgentConnectionState('joined');\n emitEvent('agentJoined', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n function handleParticipantDisconnectedEvent(participant: RemoteParticipant) {\n setAgentConnectionState('left');\n emitEvent('agentLeft', {\n conversationId: conversationRef.current?.id!,\n participant,\n });\n }\n\n async function leave() {\n if (userConnectionState !== 'joined' && userConnectionState !== 'joining') {\n return;\n }\n\n try {\n setUserConnectionState('leaving');\n await room?.disconnect(true);\n setConversationStatus('destroyed');\n setJoinedAt(undefined);\n emitEvent('callEnded', {\n conversationId: conversationRef.current?.id!,\n });\n } catch (error) {\n console.error('Failed to leave', error);\n setConversationStatus('error');\n }\n }\n\n async function handleExpire() {\n emitEvent('timeExceeded', {\n conversationId: conversationRef.current?.id!,\n limit: conversationRef.current?.limit!,\n });\n await leave();\n setConversationStatus('exceeded');\n }\n\n async function interrupt() {\n emitEvent('interrupt', {\n conversationId: conversationRef.current?.id!,\n });\n\n await publishConversationDataMessage(room, {}, 'interrupt');\n }\n\n async function dismissInactivity() {\n await publishConversationDataMessage(\n room,\n { type: 'inactivity_dismiss' },\n 'inactivity_dismiss',\n );\n }\n\n async function send(message: string, attachments: Attachment[] = []) {\n await room?.localParticipant.sendText(message, {\n topic: 'lk.chat',\n attributes: {\n attachments: safeStringify(attachments),\n },\n });\n emitEvent('userSendMessage', {\n conversationId: conversationRef.current?.id!,\n message,\n });\n }\n\n function registerRoomEvents() {\n room\n .on('connected', handleConnectedEvent)\n .on('encryptionError', handleEncryptionErrorEvent)\n .on('disconnected', handleDisconnectedEvent)\n .on('transcriptionReceived', handleTranscriptionReceivedEvent)\n .on('participantConnected', handleParticipantConnectedEvent)\n .on('participantDisconnected', handleParticipantDisconnectedEvent)\n .on('dataReceived', handleDataReceivedEvent);\n room.unregisterRpcMethod(GET_TOOLS_RPC_METHOD);\n room.unregisterRpcMethod(EXECUTE_TOOL_RPC_METHOD);\n room.registerRpcMethod(GET_TOOLS_RPC_METHOD, handleGetToolsRpc);\n room.registerRpcMethod(EXECUTE_TOOL_RPC_METHOD, handleExecuteToolRpc);\n }\n\n function unregisterRoomEvents() {\n room.unregisterRpcMethod(GET_TOOLS_RPC_METHOD);\n room.unregisterRpcMethod(EXECUTE_TOOL_RPC_METHOD);\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;AAUA,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;AAWA,IAAAS,YAAA,GAAAT,OAAA;AAMA,IAAAU,sBAAA,GAAAV,OAAA;AACA,IAAAW,0BAAA,GAAAX,OAAA;AACA,IAAAY,oBAAA,GAAAZ,OAAA;AAQA,IAAAa,yBAAA,GAAAb,OAAA;AACA,IAAAc,sBAAA,GAAAd,OAAA;AACA,IAAAe,UAAA,GAAAf,OAAA;AACA,IAAAgB,MAAA,GAAAhB,OAAA;AAaA,IAAAiB,UAAA,GAAAjB,OAAA;AAQO,SAASkB,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,MAAM;IAAEE,KAAK,EAAEC,aAAa,GAAG,CAAC;EAAE,CAAC,GAAG,IAAAC,2BAAc,EAAC,CAAC;EACtD,MAAMC,WAAW,GAAG,IAAAC,4CAAqB,EAAC,CAAC;EAC3C,MAAMC,gBAAgB,GAAG,IAAAC,mBAAS,EAACL,aAAa,CAAC;;EAEjD;EACA,MAAMM,eAAe,GAAG,IAAAD,mBAAS,EAC/BlB,YAAY,CAACoB,IACf,CAAC;EACD,MAAMC,cAAc,GAAG,IAAAH,mBAAS,EAACH,WAAW,CAAC;EAE7C,MAAM,CAACO,kBAAkB,EAAEC,qBAAqB,CAAC,GAAG,IAAAd,cAAO,EACzDH,mBAAK,CAACgB,kBACR,CAAC;EAED,MAAM,CAACE,mBAAmB,EAAEC,sBAAsB,CAAC,GAAG,IAAAhB,cAAO,EAC3DH,mBAAK,CAACkB,mBACR,CAAC;EAED,MAAM,CAACE,QAAQ,EAAEC,WAAW,CAAC,GAAG,IAAAlB,cAAO,EAACH,mBAAK,CAACoB,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,EAAExB,MAAM,CAACyB;EAC7B,CAAC,CAAC;EAEF,MAAMC,iBAAiB,GAAG,IAAAC,iBAAU,EAAC/B,mBAAK,CAACgC,cAAc,CAAC;EAC1D,MAAM,CAACC,oBAAoB,EAAEC,uBAAuB,CAAC,GAAG,IAAA/B,cAAO,EAC7DH,mBAAK,CAACiC,oBACR,CAAC;EACD,MAAME,qBAAqB,GAAG,IAAAJ,iBAAU,EAAC/B,mBAAK,CAACoC,kBAAkB,CAAC;EAClE,MAAMC,oBAAoB,GAAG,IAAAN,iBAAU,EAAC/B,mBAAK,CAACsC,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;EACpC,MAAMK,2BAA2B,GAAG,IAAAL,aAAM,EACxCM,SACF,CAAC;EACD,MAAMC,4BAA4B,GAAG,IAAAP,aAAM,EACzCM,SACF,CAAC;EAED,MAAME,kBAAkB,GAAG,IAAAC,wCAAmB,EAAC;IAC7CnE,IAAI,EAAE,MAAM;IACZoE,MAAM,EAAEC,2BAAM,CAACC;EACjB,CAAC,CAAC;EACF,MAAMC,mBAAmB,GAAG,IAAAJ,wCAAmB,EAAC;IAC9CnE,IAAI,EAAE,OAAO;IACboE,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,CAACnE,IAAI,EAAE;MACT;IACF;IACAoE,kBAAkB,CAAC,CAAC;IAEpB,OAAO,MAAM;MACXC,oBAAoB,CAAC,CAAC;IACxB,CAAC;EACH,CAAC,EAAE,CAACrE,IAAI,CAAC,CAAC;EAEV,IAAAsE,yBAAe,EAAC,MAAM;IACpB3C,qBAAqB,CAACtB,UAAU,CAACkE,QAAQ,CAAC;EAC5C,CAAC,EAAE,CAAClE,UAAU,CAACkE,QAAQ,CAAC,CAAC;EAEzB,IAAAD,yBAAe,EAAC,MAAM;IACpBxC,kBAAkB,CAAC5B,OAAO,CAACqE,QAAQ,CAAC;EACtC,CAAC,EAAE,CAACrE,OAAO,CAACqE,QAAQ,CAAC,CAAC;EAEtB,IAAAD,yBAAe,EAAC,MAAM;IACpBvC,iBAAiB,CAACvB,MAAM,CAAC+D,QAAQ,CAAC;EACpC,CAAC,EAAE,CAAC/D,MAAM,CAAC+D,QAAQ,CAAC,CAAC;EAErB,IAAAD,yBAAe,EAAC,MAAM;IACpB,IAAIjC,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACArC,IAAI,CAACwE,gBAAgB,CAACC,oBAAoB,CAACpE,UAAU,CAAC4B,OAAO,CAAC;EAChE,CAAC,EAAE,CAAC5B,UAAU,CAAC4B,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE9C,IAAAiC,yBAAe,EAAC,MAAM;IACpB,IAAIjC,oBAAoB,KAAK,QAAQ,EAAE;MACrC;IACF;IACArC,IAAI,CAACwE,gBAAgB,CAACE,gBAAgB,CAAClE,MAAM,CAACyB,OAAO,EAAE;MACrD0C,UAAU,EAAE;QAAEC,KAAK,EAAE,IAAI;QAAEC,MAAM,EAAE;MAAK;IAC1C,CAAC,CAAC;EACJ,CAAC,EAAE,CAACrE,MAAM,CAACyB,OAAO,EAAEI,oBAAoB,CAAC,CAAC;EAE1C,IAAA8B,gBAAS,EAAC,MAAM;IACd,IAAI,CAAChF,QAAQ,EAAE;MACb;IACF;IAEA,IAAIiC,kBAAkB,KAAK,SAAS,EAAE;MACpC,KAAK0D,IAAI,CAAC,CAAC;IACb;EACF,CAAC,EAAE,CAAC1D,kBAAkB,EAAEjC,QAAQ,CAAC,CAAC;EAElC,IAAAgF,gBAAS,EAAC,MAAM;IAAA,IAAAY,kBAAA;IACd,IAAI,CAACvD,QAAQ,IAAI,EAAAuD,kBAAA,GAAAjF,YAAY,CAACoB,IAAI,qBAAjB6D,kBAAA,CAAmBC,KAAK,MAAK5B,SAAS,EAAE;MACvD;IACF;IAEAQ,KAAK,CAACqB,OAAO,CAAC,IAAIf,IAAI,CAAC1C,QAAQ,CAAC0D,OAAO,CAAC,CAAC,GAAGpF,YAAY,CAACoB,IAAI,CAAE8D,KAAM,CAAC,CAAC;EACzE,CAAC,EAAE,CAACxD,QAAQ,GAAA9B,mBAAA,GAAEI,YAAY,CAACoB,IAAI,qBAAjBxB,mBAAA,CAAmBsF,KAAK,CAAC,CAAC;EAExC,eAAeF,IAAIA,CAAA,EAAG;IAAA,IAAAK,mBAAA;IACpB,IAAAC,kBAAS,EAAC9D,mBAAmB,KAAK,MAAM,EAAE,gBAAgB,CAAC;IAC3D,IAAA8D,kBAAS,EAACtF,YAAY,CAACoB,IAAI,EAAE,2BAA2B,CAAC;IACzD,MAAMmE,GAAG,GAAG,IAAIC,GAAG,CAAC,CAAAxF,YAAY,aAAAqF,mBAAA,GAAZrF,YAAY,CAAEoB,IAAI,qBAAlBiE,mBAAA,CAAoBE,GAAG,KAAI,EAAE,CAAC;IAClD,MAAME,WAAW,GAAGF,GAAG,CAACG,YAAY,CAACC,GAAG,CAAC,OAAO,CAAC;IACjD,IAAI;MACFlE,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMvB,IAAI,oBAAJA,IAAI,CAAE0F,OAAO,CAAC5F,YAAY,CAACoB,IAAI,CAACmE,GAAG,EAAEE,WAAW,EAAG,CAAC,CAAC,CAAC;;MAE5D;MACA,MAAMI,iBAAiB,GAAG,IAAAC,iCAA0B,EAAC5F,IAAI,EAAEZ,IAAI,CAAC;MAChE,IAAIuG,iBAAiB,IAAItD,oBAAoB,KAAK,QAAQ,EAAE;QAC1DwD,eAAe,CAACF,iBAAiB,CAAC;MACpC;MAEAG,kBAAkB,CAAC,CAAC;IACtB,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,gBAAgB,EAAEA,KAAK,CAAC;MACtCxE,sBAAsB,CAAC,YAAY,CAAC;IACtC;EACF;EAEA,SAASuE,kBAAkBA,CAAA,EAAG;IAC5B,IAAIxG,mBAAmB,EAAE;MACvBgB,aAAa,CAAC;QAAE,GAAGD,UAAU;QAAE4B,OAAO,EAAE;MAAK,CAAC,CAAC;IACjD;IACA,IAAI1C,eAAe,IAAIH,IAAI,KAAK,OAAO,EAAE;MACvCqB,SAAS,CAAC;QAAE,GAAGD,MAAM;QAAEyB,OAAO,EAAE;MAAK,CAAC,CAAC;IACzC;EACF;EAEA,SAASgE,gCAAgCA,CACvCC,QAAgC,EAChCC,WAAyB,EACzB;IACA,MAAM/D,cAA2C,GAAG8D,QAAQ,CAACE,GAAG,CAAEC,CAAC,KAAM;MACvEC,EAAE,EAAED,CAAC,CAACC,EAAE;MACRC,OAAO,EAAEF,CAAC,CAACG,IAAI;MACfhD,MAAM,EAAE,CAAA2C,WAAW,oBAAXA,WAAW,CAAEtE,IAAI,MAAK4E,8BAAe,CAACC,KAAK,GAAG,OAAO,GAAG;IAClE,CAAC,CAAC,CAAC;IAEHxE,iBAAiB,CAAEyE,GAAG,IAAK,IAAAC,0BAAmB,EAACxE,cAAc,EAAEuE,GAAG,CAAC,CAAC;EACtE;EAEA,SAASE,wBAAwBA,CAAC3F,IAAuB,EAAE;IAAA,IAAA4F,qBAAA;IACzD,MAAMC,cAAc,IAAAD,qBAAA,GAAG7F,eAAe,CAAC+F,OAAO,qBAAvBF,qBAAA,CAAyBR,EAAE;IAClD,MAAM;MAAEW,eAAe;MAAE7G,KAAK,EAAE8G;IAAW,CAAC,GAAGhG,IAAI;IACnD,QAAQ+F,eAAe;MACrB,KAAK,UAAU;QACb,IAAIC,UAAU,KAAK,WAAW,EAAE;UAC9BjE,qBAAqB,CAAC+D,OAAO,GAAG;YAC9BG,qBAAqB,EAAEjG,IAAI,CAACiG,qBAAqB;YACjDC,QAAQ,EAAElG,IAAI,CAACkG,QAAQ;YACvBC,QAAQ,EAAEnG,IAAI,CAACmG;UACjB,CAAC;QACH;QACA1E,SAAS,CACPuE,UAAU,KAAK,UAAU,GAAG,gBAAgB,GAAG,eAAe,EAC9D;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACDtE,oBAAoB,CAACyE,UAAU,CAAC;QAChC;MACF,KAAK,OAAO;QACV,IAAIhG,IAAI,CAACmG,QAAQ,EAAE;UACjBpE,qBAAqB,CAAC+D,OAAO,GAAG;YAC9B,GAAG/D,qBAAqB,CAAC+D,OAAO;YAChCK,QAAQ,EAAEnG,IAAI,CAACmG;UACjB,CAAC;QACH;QACA1E,SAAS,CACPuE,UAAU,KAAK,UAAU,GAAG,iBAAiB,GAAG,gBAAgB,EAChE;UAAEH,cAAc,EAAEA;QAAgB,CACpC,CAAC;QACDxE,qBAAqB,CAAC2E,UAAU,CAAC;QACjC;IACJ;EACF;EAEA,SAASI,uBAAuBA,CAAA,EAAG;IACjC,IAAI,CAACpE,cAAc,CAAC8D,OAAO,EAAE;MAC3B;IACF;IACA,IAAIjE,gBAAgB,CAACiE,OAAO,KAAK,iBAAiB,EAAE;MAClDjE,gBAAgB,CAACiE,OAAO,GAAG,MAAM;MACjChE,aAAa,CAACgE,OAAO,GAAG,IAAI;IAC9B;EACF;EAEA,SAASO,wBAAwBA,CAACC,WAAmB,EAAE;IACrD,IAAI,CAACtE,cAAc,CAAC8D,OAAO,IAAIjE,gBAAgB,CAACiE,OAAO,KAAK,MAAM,EAAE;MAClE;IACF;IACAhE,aAAa,CAACgE,OAAO,GAAGQ,WAAW,GAAGC,oCAAyB;IAC/D1E,gBAAgB,CAACiE,OAAO,GAAG,iBAAiB;EAC9C;EAEA,SAASU,wBAAwBA,CAACF,WAAmB,EAAE;IAAA,IAAAG,sBAAA;IACrD,IACE,CAACzE,cAAc,CAAC8D,OAAO,IACvBjE,gBAAgB,CAACiE,OAAO,KAAK,iBAAiB,IAC9ChE,aAAa,CAACgE,OAAO,IAAI,IAAI,EAC7B;MACA;IACF;IAEA,MAAMY,SAAS,GAAGJ,WAAW,GAAGxE,aAAa,CAACgE,OAAO;IACrDhE,aAAa,CAACgE,OAAO,GAAG,IAAI;IAC5BjE,gBAAgB,CAACiE,OAAO,GAAG,MAAM;IAEjC,IAAIY,SAAS,GAAG,CAAC,IAAIA,SAAS,GAAG,KAAK,EAAE;MACtC;IACF;IAEAjF,SAAS,CAAC,iBAAiB,EAAE;MAC3BoE,cAAc,GAAAY,sBAAA,GAAE1G,eAAe,CAAC+F,OAAO,qBAAvBW,sBAAA,CAAyBrB,EAAG;MAC5CsB,SAAS;MACTT,qBAAqB,EACnBlE,qBAAqB,CAAC+D,OAAO,CAACG,qBAAsB;MACtDC,QAAQ,EAAEnE,qBAAqB,CAAC+D,OAAO,CAACI,QAAQ;MAChDC,QAAQ,EAAEpE,qBAAqB,CAAC+D,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,UAAU,EAAEC,WAAW,CAAC,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAClD,IAAAC,kCAAa,EAAC9E,kBAAkB,CAAC,EACjC,IAAA8E,kCAAa,EAACzE,mBAAmB,CAAC,CACnC,CAAC;IACF,MAAM0E,SAAS,GAAG,IAAAC,oCAAe,EAC/BN,UAAU,EACV7E,2BAA2B,CAAC6D,OAC9B,CAAC;IACD,MAAMuB,UAAU,GAAG,IAAAD,oCAAe,EAChCL,WAAW,EACX5E,4BAA4B,CAAC2D,OAC/B,CAAC;IACD7D,2BAA2B,CAAC6D,OAAO,GAAGqB,SAAS,CAACG,oBAAoB;IACpEnF,4BAA4B,CAAC2D,OAAO,GAAGuB,UAAU,CAACC,oBAAoB;IAEtE7F,SAAS,CAAC,yBAAyB,EAAE;MACnCoE,cAAc,GAAAgB,sBAAA,GAAE9G,eAAe,CAAC+F,OAAO,qBAAvBe,sBAAA,CAAyBzB,EAAG;MAC5Ce,QAAQ,EAAEpE,qBAAqB,CAAC+D,OAAO,CAACK,QAAQ;MAChDD,QAAQ,EAAEnE,qBAAqB,CAAC+D,OAAO,CAACI,QAAQ;MAChDU,uBAAuB;MACvBW,KAAK,EAAEJ,SAAS,CAACK,eAAe;MAChCC,mBAAmB,EAAEJ,UAAU,CAACI,mBAAmB;MACnDC,eAAe,EAAEP,SAAS,CAACQ,WAAW;MACtCC,gBAAgB,EAAEP,UAAU,CAACM;IAC/B,CAAC,CAAC;EACJ;EAEA,SAASE,yBAAyBA,CAAA,EAAG;IACnChG,gBAAgB,CAACiE,OAAO,GAAG,MAAM;EACnC;EAEA,IAAAgC,oDAAyB,EAAC;IACxBxF,MAAM,EAAE,MAAM;IACdyF,aAAa,EAAE3B,uBAAuB;IACtC4B,WAAW,EAAE3B,wBAAwB;IACrC4B,YAAY,EAAEC,sCAA2B;IACzCC,UAAU,EAAE5B;EACd,CAAC,CAAC;EACF,IAAAuB,oDAAyB,EAAC;IACxBxF,MAAM,EAAE,OAAO;IACfyF,aAAa,EAAEvB,wBAAwB;IACvCwB,WAAW,EAAEH,yBAAyB;IACtCM,UAAU,EAAEC;EACd,CAAC,CAAC;EAEF,SAASC,4BAA4BA,CAACrI,IAA2B,EAAE;IAAA,IAAAsI,sBAAA;IACjE7G,SAAS,CAAC,mBAAmB,EAAE;MAC7BoE,cAAc,GAAAyC,sBAAA,GAAEvI,eAAe,CAAC+F,OAAO,qBAAvBwC,sBAAA,CAAyBlD,EAAG;MAC5CmD,cAAc,EAAEvI,IAAI,CAACwI;IACvB,CAAC,CAAC;EACJ;EAEA,SAASC,4BAA4BA,CAACC,KAA4B,EAAE;IAAA,IAAAC,sBAAA;IAClEhH,oBAAoB,CAACmE,OAAO,GAAG,IAAI;IACnCrE,SAAS,CAAC,mBAAmB,EAAE;MAC7BoE,cAAc,GAAA8C,sBAAA,GAAE5I,eAAe,CAAC+F,OAAO,qBAAvB6C,sBAAA,CAAyBvD;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAewD,iBAAiBA,CAAA,EAAG;IACjC,OAAOC,IAAI,CAACC,SAAS,CAAC,IAAAC,2BAAoB,EAAClJ,gBAAgB,CAACiG,OAAO,CAAC,CAAC;EACvE;EAEA,eAAekD,oBAAoBA,CAAChJ,IAAuB,EAAE;IAC3D,MAAMiJ,IAAI,GAAG,IAAAC,+BAAwB,EAAClJ,IAAI,CAACmJ,OAAO,CAAC;IACnD,IAAI,CAACF,IAAI,EAAE;MACT,OAAOJ,IAAI,CAACC,SAAS,CAAC;QACpBM,cAAc,EAAE,EAAE;QAClBC,MAAM,EAAE,EAAE;QACVxE,KAAK,EAAE;MACT,CAA8B,CAAC;IACjC;IACA,IAAI;MACF,MAAM,CAACwE,MAAM,CAAC,GAAG,MAAMpJ,cAAc,CAAC6F,OAAO,CAACwD,gBAAgB,CAAC,CAACL,IAAI,CAAC,CAAC;MACtE,OAAOJ,IAAI,CAACC,SAAS,CAACO,MAAM,CAAC;IAC/B,CAAC,CAAC,OAAOxE,KAAK,EAAE;MACd,OAAOgE,IAAI,CAACC,SAAS,CAAC;QACpBM,cAAc,EAAEH,IAAI,CAACG,cAAc;QACnCC,MAAM,EAAE,EAAE;QACVxE,KAAK,EAAE,IAAA0E,kCAAuB,EAAC1E,KAAK;MACtC,CAA8B,CAAC;IACjC;EACF;EAEA,MAAM2E,mBAGH,GAAG,CACJ;IACEC,KAAK,EAAEC,+BAAwB;IAC/BC,MAAM,EAAEhE;EACV,CAAC,EACD;IACE8D,KAAK,EAAEG,mCAA4B;IACnCD,MAAM,EAAEtB;EACV,CAAC,EACD;IACEoB,KAAK,EAAEI,mCAA4B;IACnCF,MAAM,EAAElB;EACV,CAAC,CACF;EAED,SAASqB,uBAAuBA,CAACX,OAAmB,EAAE;IACpD,MAAMY,OAAO,GAAG,IAAAC,wBAAiB,EAACb,OAAO,CAAC;IAC1C,IAAIY,OAAO,KAAK,IAAI,EAAE;MACpB;IACF;IACA,KAAK,MAAM;MAAEN,KAAK;MAAEE;IAAO,CAAC,IAAIH,mBAAmB,EAAE;MACnD,IAAIC,KAAK,CAACM,OAAO,CAAC,EAAE;QAClB,KAAK/C,OAAO,CAACiD,OAAO,CAACN,MAAM,CAACI,OAAO,CAAC,CAAC,CAACG,KAAK,CAAErF,KAAK,IAAK;UACrDC,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;QAC/D,CAAC,CAAC;QACF;MACF;IACF;EACF;EAEA,SAASsF,oBAAoBA,CAAA,EAAG;IAAA,IAAAC,sBAAA;IAC9BpI,cAAc,CAAC8D,OAAO,GAAG,IAAI;IAC7BzF,sBAAsB,CAAC,QAAQ,CAAC;IAChCe,uBAAuB,CAAC,SAAS,CAAC;IAClCK,SAAS,CAAC,aAAa,EAAE;MACvBoE,cAAc,GAAAuE,sBAAA,GAAErK,eAAe,CAAC+F,OAAO,qBAAvBsE,sBAAA,CAAyBhF;IAC3C,CAAC,CAAC;EACJ;EAEA,eAAeiF,0BAA0BA,CAACxF,KAAY,EAAE;IACtDC,OAAO,CAACD,KAAK,CAAC,kBAAkB,EAAEA,KAAK,CAAC;IACxC1E,qBAAqB,CAAC,OAAO,CAAC;EAChC;EAEA,SAASmK,uBAAuBA,CAACC,MAAyB,EAAE;IAC1DvI,cAAc,CAAC8D,OAAO,GAAG,KAAK;IAC9BjE,gBAAgB,CAACiE,OAAO,GAAG,MAAM;IACjChE,aAAa,CAACgE,OAAO,GAAG,IAAI;IAC5B/D,qBAAqB,CAAC+D,OAAO,GAAG,CAAC,CAAC;IAClC7D,2BAA2B,CAAC6D,OAAO,GAAG5D,SAAS;IAC/CC,4BAA4B,CAAC2D,OAAO,GAAG5D,SAAS;IAChDb,qBAAqB,CAAC,MAAM,CAAC;IAC7BD,uBAAuB,CAAC,MAAM,CAAC;IAC/BG,oBAAoB,CAAC,MAAM,CAAC;IAC5BlB,sBAAsB,CAAC,MAAM,CAAC;IAE9B,IAAIsB,oBAAoB,CAACmE,OAAO,EAAE;MAChCnE,oBAAoB,CAACmE,OAAO,GAAG,KAAK;MACpC3F,qBAAqB,CAAC,oBAAoB,CAAC;MAC3C;IACF;IAEA,QAAQoK,MAAM;MACZ,KAAKC,+BAAgB,CAACC,gBAAgB;QACpC;MACF,KAAKD,+BAAgB,CAACE,WAAW;QAC/BvK,qBAAqB,CAAC,WAAW,CAAC;QAClC;MACF;QACE2E,OAAO,CAACD,KAAK,CAAC,uCAAuC,EAAE0F,MAAM,CAAC;QAC9DpK,qBAAqB,CAAC,OAAO,CAAC;QAC9B;IACJ;EACF;EAEA,SAASwK,+BAA+BA,CAAC1F,WAA8B,EAAE;IACvE,IAAI,IAAA2F,uCAAgC,EAAC3F,WAAW,EAAE/G,IAAI,CAAC,EAAE;MACvDyG,eAAe,CAACM,WAAW,CAAC;IAC9B;EACF;EAEA,SAASN,eAAeA,CAACM,WAA8B,EAAE;IAAA,IAAA4F,sBAAA;IACvDzJ,uBAAuB,CAAC,QAAQ,CAAC;IACjCK,SAAS,CAAC,aAAa,EAAE;MACvBoE,cAAc,GAAAgF,sBAAA,GAAE9K,eAAe,CAAC+F,OAAO,qBAAvB+E,sBAAA,CAAyBzF,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,SAAS6F,kCAAkCA,CAAC7F,WAA8B,EAAE;IAAA,IAAA8F,sBAAA;IAC1E3J,uBAAuB,CAAC,MAAM,CAAC;IAC/BK,SAAS,CAAC,WAAW,EAAE;MACrBoE,cAAc,GAAAkF,sBAAA,GAAEhL,eAAe,CAAC+F,OAAO,qBAAvBiF,sBAAA,CAAyB3F,EAAG;MAC5CH;IACF,CAAC,CAAC;EACJ;EAEA,eAAe+F,KAAKA,CAAA,EAAG;IACrB,IAAI5K,mBAAmB,KAAK,QAAQ,IAAIA,mBAAmB,KAAK,SAAS,EAAE;MACzE;IACF;IAEA,IAAI;MAAA,IAAA6K,sBAAA;MACF5K,sBAAsB,CAAC,SAAS,CAAC;MACjC,OAAMvB,IAAI,oBAAJA,IAAI,CAAEoM,UAAU,CAAC,IAAI,CAAC;MAC5B/K,qBAAqB,CAAC,WAAW,CAAC;MAClCI,WAAW,CAAC2B,SAAS,CAAC;MACtBT,SAAS,CAAC,WAAW,EAAE;QACrBoE,cAAc,GAAAoF,sBAAA,GAAElL,eAAe,CAAC+F,OAAO,qBAAvBmF,sBAAA,CAAyB7F;MAC3C,CAAC,CAAC;IACJ,CAAC,CAAC,OAAOP,KAAK,EAAE;MACdC,OAAO,CAACD,KAAK,CAAC,iBAAiB,EAAEA,KAAK,CAAC;MACvC1E,qBAAqB,CAAC,OAAO,CAAC;IAChC;EACF;EAEA,eAAe2C,YAAYA,CAAA,EAAG;IAAA,IAAAqI,sBAAA,EAAAC,sBAAA;IAC5B3J,SAAS,CAAC,cAAc,EAAE;MACxBoE,cAAc,GAAAsF,sBAAA,GAAEpL,eAAe,CAAC+F,OAAO,qBAAvBqF,sBAAA,CAAyB/F,EAAG;MAC5CtB,KAAK,GAAAsH,sBAAA,GAAErL,eAAe,CAAC+F,OAAO,qBAAvBsF,sBAAA,CAAyBtH;IAClC,CAAC,CAAC;IACF,MAAMkH,KAAK,CAAC,CAAC;IACb7K,qBAAqB,CAAC,UAAU,CAAC;EACnC;EAEA,eAAekL,SAASA,CAAA,EAAG;IAAA,IAAAC,uBAAA;IACzB7J,SAAS,CAAC,WAAW,EAAE;MACrBoE,cAAc,GAAAyF,uBAAA,GAAEvL,eAAe,CAAC+F,OAAO,qBAAvBwF,uBAAA,CAAyBlG;IAC3C,CAAC,CAAC;IAEF,MAAM,IAAAmG,qCAA8B,EAACzM,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC;EAC7D;EAEA,eAAe0M,iBAAiBA,CAAA,EAAG;IACjC,MAAM,IAAAD,qCAA8B,EAClCzM,IAAI,EACJ;MAAEZ,IAAI,EAAE;IAAqB,CAAC,EAC9B,oBACF,CAAC;EACH;EAEA,eAAeuN,IAAIA,CAACpG,OAAe,EAAEqG,WAAyB,GAAG,EAAE,EAAE;IAAA,IAAAC,uBAAA;IACnE,OAAM7M,IAAI,oBAAJA,IAAI,CAAEwE,gBAAgB,CAACsI,QAAQ,CAACvG,OAAO,EAAE;MAC7CwG,KAAK,EAAE,SAAS;MAChBC,UAAU,EAAE;QACVJ,WAAW,EAAE,IAAAK,oBAAa,EAACL,WAAW;MACxC;IACF,CAAC,CAAC;IACFjK,SAAS,CAAC,iBAAiB,EAAE;MAC3BoE,cAAc,GAAA8F,uBAAA,GAAE5L,eAAe,CAAC+F,OAAO,qBAAvB6F,uBAAA,CAAyBvG,EAAG;MAC5CC;IACF,CAAC,CAAC;EACJ;EAEA,SAASnC,kBAAkBA,CAAA,EAAG;IAC5BpE,IAAI,CACDkN,EAAE,CAAC,WAAW,EAAE7B,oBAAoB,CAAC,CACrC6B,EAAE,CAAC,iBAAiB,EAAE3B,0BAA0B,CAAC,CACjD2B,EAAE,CAAC,cAAc,EAAE1B,uBAAuB,CAAC,CAC3C0B,EAAE,CAAC,uBAAuB,EAAEjH,gCAAgC,CAAC,CAC7DiH,EAAE,CAAC,sBAAsB,EAAErB,+BAA+B,CAAC,CAC3DqB,EAAE,CAAC,yBAAyB,EAAElB,kCAAkC,CAAC,CACjEkB,EAAE,CAAC,cAAc,EAAElC,uBAAuB,CAAC;IAC9ChL,IAAI,CAACmN,mBAAmB,CAACC,+BAAoB,CAAC;IAC9CpN,IAAI,CAACmN,mBAAmB,CAACE,kCAAuB,CAAC;IACjDrN,IAAI,CAACsN,iBAAiB,CAACF,+BAAoB,EAAEtD,iBAAiB,CAAC;IAC/D9J,IAAI,CAACsN,iBAAiB,CAACD,kCAAuB,EAAEnD,oBAAoB,CAAC;EACvE;EAEA,SAAS7F,oBAAoBA,CAAA,EAAG;IAC9BrE,IAAI,CAACmN,mBAAmB,CAACC,+BAAoB,CAAC;IAC9CpN,IAAI,CAACmN,mBAAmB,CAACE,kCAAuB,CAAC;IACjDrN,IAAI,CAACuN,GAAG,CAAC,WAAW,EAAElC,oBAAoB,CAAC;IAC3CrL,IAAI,CAACuN,GAAG,CAAC,iBAAiB,EAAEhC,0BAA0B,CAAC;IACvDvL,IAAI,CAACuN,GAAG,CAAC,cAAc,EAAE/B,uBAAuB,CAAC;IACjDxL,IAAI,CAACuN,GAAG,CAAC,uBAAuB,EAAEtH,gCAAgC,CAAC;IACnEjG,IAAI,CAACuN,GAAG,CAAC,sBAAsB,EAAE1B,+BAA+B,CAAC;IACjE7L,IAAI,CAACuN,GAAG,CAAC,yBAAyB,EAAEvB,kCAAkC,CAAC;IACvEhM,IAAI,CAACuN,GAAG,CAAC,cAAc,EAAEvC,uBAAuB,CAAC;EACnD;EAEA,OAAO;IACLwC,MAAM,EAAEpM,kBAAkB;IAC1BtB,YAAY,EAAEA,YAAY,CAACoB,IAAI;IAC/B4D,IAAI;IACJ6H,IAAI;IACJJ,SAAS;IACTG,iBAAiB;IACjBR;EACF,CAAC;AACH","ignoreList":[]}
@@ -3,7 +3,6 @@
3
3
  exports.__esModule = true;
4
4
  exports.checkIsInactivityTimeoutData = checkIsInactivityTimeoutData;
5
5
  exports.checkIsInactivityWarningData = checkIsInactivityWarningData;
6
- exports.checkIsToolCallsData = checkIsToolCallsData;
7
6
  exports.checkIsTurnDetectionData = checkIsTurnDetectionData;
8
7
  exports.decodeDataPayload = decodeDataPayload;
9
8
  function decodeDataPayload(data) {
@@ -23,7 +22,4 @@ function checkIsInactivityWarningData(data) {
23
22
  function checkIsInactivityTimeoutData(data) {
24
23
  return typeof data === 'object' && data !== null && 'type' in data && data.type === 'inactivity_timeout';
25
24
  }
26
- function checkIsToolCallsData(data) {
27
- return typeof data === 'object' && data !== null && 'type' in data && data.type === 'tool_calls' && 'requestId' in data && typeof data.requestId === 'string' && 'functionCalls' in data && Array.isArray(data.functionCalls);
28
- }
29
25
  //# sourceMappingURL=dataChannel.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["decodeDataPayload","data","JSON","parse","TextDecoder","decode","error","console","checkIsTurnDetectionData","checkIsInactivityWarningData","type","grace_period_sec","checkIsInactivityTimeoutData","checkIsToolCallsData","requestId","Array","isArray","functionCalls"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/dataChannel.ts"],"sourcesContent":["import type {\n InactivityWarningData,\n InactivityTimeoutData,\n ToolCallsData,\n TurnDetectionData,\n} from '../types';\n\nexport function decodeDataPayload(data: Uint8Array): unknown {\n try {\n return JSON.parse(new TextDecoder().decode(data));\n } catch (error) {\n console.error('Failed to decode data received payload', error);\n return null;\n }\n}\n\nexport function checkIsTurnDetectionData(\n data: unknown,\n): data is TurnDetectionData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'participantKind' in data &&\n 'state' in data\n );\n}\n\nexport function checkIsInactivityWarningData(\n data: unknown,\n): data is InactivityWarningData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_warning' &&\n 'grace_period_sec' in data &&\n typeof (data as Record<string, unknown>).grace_period_sec === 'number'\n );\n}\n\nexport function checkIsInactivityTimeoutData(\n data: unknown,\n): data is InactivityTimeoutData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_timeout'\n );\n}\n\nexport function checkIsToolCallsData(data: unknown): data is ToolCallsData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'tool_calls' &&\n 'requestId' in data &&\n typeof (data as Record<string, unknown>).requestId === 'string' &&\n 'functionCalls' in data &&\n Array.isArray((data as Record<string, unknown>).functionCalls)\n );\n}\n"],"mappings":";;;;;;;;AAOO,SAASA,iBAAiBA,CAACC,IAAgB,EAAW;EAC3D,IAAI;IACF,OAAOC,IAAI,CAACC,KAAK,CAAC,IAAIC,WAAW,CAAC,CAAC,CAACC,MAAM,CAACJ,IAAI,CAAC,CAAC;EACnD,CAAC,CAAC,OAAOK,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,wCAAwC,EAAEA,KAAK,CAAC;IAC9D,OAAO,IAAI;EACb;AACF;AAEO,SAASE,wBAAwBA,CACtCP,IAAa,EACc;EAC3B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,iBAAiB,IAAIA,IAAI,IACzB,OAAO,IAAIA,IAAI;AAEnB;AAEO,SAASQ,4BAA4BA,CAC1CR,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB,IAC/D,kBAAkB,IAAIT,IAAI,IAC1B,OAAQA,IAAI,CAA6BU,gBAAgB,KAAK,QAAQ;AAE1E;AAEO,SAASC,4BAA4BA,CAC1CX,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB;AAEnE;AAEO,SAASG,oBAAoBA,CAACZ,IAAa,EAAyB;EACzE,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,YAAY,IACvD,WAAW,IAAIT,IAAI,IACnB,OAAQA,IAAI,CAA6Ba,SAAS,KAAK,QAAQ,IAC/D,eAAe,IAAIb,IAAI,IACvBc,KAAK,CAACC,OAAO,CAAEf,IAAI,CAA6BgB,aAAa,CAAC;AAElE","ignoreList":[]}
1
+ {"version":3,"names":["decodeDataPayload","data","JSON","parse","TextDecoder","decode","error","console","checkIsTurnDetectionData","checkIsInactivityWarningData","type","grace_period_sec","checkIsInactivityTimeoutData"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/dataChannel.ts"],"sourcesContent":["import type {\n InactivityWarningData,\n InactivityTimeoutData,\n TurnDetectionData,\n} from '../types';\n\nexport function decodeDataPayload(data: Uint8Array): unknown {\n try {\n return JSON.parse(new TextDecoder().decode(data));\n } catch (error) {\n console.error('Failed to decode data received payload', error);\n return null;\n }\n}\n\nexport function checkIsTurnDetectionData(\n data: unknown,\n): data is TurnDetectionData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'participantKind' in data &&\n 'state' in data\n );\n}\n\nexport function checkIsInactivityWarningData(\n data: unknown,\n): data is InactivityWarningData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_warning' &&\n 'grace_period_sec' in data &&\n typeof (data as Record<string, unknown>).grace_period_sec === 'number'\n );\n}\n\nexport function checkIsInactivityTimeoutData(\n data: unknown,\n): data is InactivityTimeoutData {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'type' in data &&\n (data as Record<string, unknown>).type === 'inactivity_timeout'\n );\n}\n"],"mappings":";;;;;;;AAMO,SAASA,iBAAiBA,CAACC,IAAgB,EAAW;EAC3D,IAAI;IACF,OAAOC,IAAI,CAACC,KAAK,CAAC,IAAIC,WAAW,CAAC,CAAC,CAACC,MAAM,CAACJ,IAAI,CAAC,CAAC;EACnD,CAAC,CAAC,OAAOK,KAAK,EAAE;IACdC,OAAO,CAACD,KAAK,CAAC,wCAAwC,EAAEA,KAAK,CAAC;IAC9D,OAAO,IAAI;EACb;AACF;AAEO,SAASE,wBAAwBA,CACtCP,IAAa,EACc;EAC3B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,iBAAiB,IAAIA,IAAI,IACzB,OAAO,IAAIA,IAAI;AAEnB;AAEO,SAASQ,4BAA4BA,CAC1CR,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB,IAC/D,kBAAkB,IAAIT,IAAI,IAC1B,OAAQA,IAAI,CAA6BU,gBAAgB,KAAK,QAAQ;AAE1E;AAEO,SAASC,4BAA4BA,CAC1CX,IAAa,EACkB;EAC/B,OACE,OAAOA,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,MAAM,IAAIA,IAAI,IACbA,IAAI,CAA6BS,IAAI,KAAK,oBAAoB;AAEnE","ignoreList":[]}
@@ -19,17 +19,23 @@ Object.keys(_participants).forEach(function (key) {
19
19
  if (key in exports && exports[key] === _participants[key]) return;
20
20
  exports[key] = _participants[key];
21
21
  });
22
+ var _rpc = require("./rpc");
23
+ Object.keys(_rpc).forEach(function (key) {
24
+ if (key === "default" || key === "__esModule") return;
25
+ if (key in exports && exports[key] === _rpc[key]) return;
26
+ exports[key] = _rpc[key];
27
+ });
22
28
  var _serialization = require("./serialization");
23
29
  Object.keys(_serialization).forEach(function (key) {
24
30
  if (key === "default" || key === "__esModule") return;
25
31
  if (key in exports && exports[key] === _serialization[key]) return;
26
32
  exports[key] = _serialization[key];
27
33
  });
28
- var _toolAdapter = require("./toolAdapter");
29
- Object.keys(_toolAdapter).forEach(function (key) {
34
+ var _toolDefinitions = require("./toolDefinitions");
35
+ Object.keys(_toolDefinitions).forEach(function (key) {
30
36
  if (key === "default" || key === "__esModule") return;
31
- if (key in exports && exports[key] === _toolAdapter[key]) return;
32
- exports[key] = _toolAdapter[key];
37
+ if (key in exports && exports[key] === _toolDefinitions[key]) return;
38
+ exports[key] = _toolDefinitions[key];
33
39
  });
34
40
  var _transcriptions = require("./transcriptions");
35
41
  Object.keys(_transcriptions).forEach(function (key) {
@@ -1 +1 @@
1
- {"version":3,"names":["_dataChannel","require","Object","keys","forEach","key","exports","_messaging","_participants","_serialization","_toolAdapter","_transcriptions"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/index.ts"],"sourcesContent":["export * from './dataChannel';\nexport * from './messaging';\nexport * from './participants';\nexport * from './serialization';\nexport * from './toolAdapter';\nexport * from './transcriptions';\n"],"mappings":";;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,YAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,YAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,YAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,UAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,UAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,UAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,UAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,aAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,aAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,aAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,aAAA,CAAAH,GAAA;AAAA;AACA,IAAAI,cAAA,GAAAR,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAM,cAAA,EAAAL,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAI,cAAA,CAAAJ,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAI,cAAA,CAAAJ,GAAA;AAAA;AACA,IAAAK,YAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,YAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,YAAA,CAAAL,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAK,YAAA,CAAAL,GAAA;AAAA;AACA,IAAAM,eAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,eAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,eAAA,CAAAN,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAM,eAAA,CAAAN,GAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["_dataChannel","require","Object","keys","forEach","key","exports","_messaging","_participants","_rpc","_serialization","_toolDefinitions","_transcriptions"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/index.ts"],"sourcesContent":["export * from './dataChannel';\nexport * from './messaging';\nexport * from './participants';\nexport * from './rpc';\nexport * from './serialization';\nexport * from './toolDefinitions';\nexport * from './transcriptions';\n"],"mappings":";;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,YAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,YAAA,CAAAK,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAL,YAAA,CAAAK,GAAA;AAAA;AACA,IAAAE,UAAA,GAAAN,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAI,UAAA,EAAAH,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAE,UAAA,CAAAF,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAE,UAAA,CAAAF,GAAA;AAAA;AACA,IAAAG,aAAA,GAAAP,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAK,aAAA,EAAAJ,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAG,aAAA,CAAAH,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAG,aAAA,CAAAH,GAAA;AAAA;AACA,IAAAI,IAAA,GAAAR,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAM,IAAA,EAAAL,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAI,IAAA,CAAAJ,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAI,IAAA,CAAAJ,GAAA;AAAA;AACA,IAAAK,cAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,cAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,cAAA,CAAAL,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAK,cAAA,CAAAL,GAAA;AAAA;AACA,IAAAM,gBAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,gBAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,gBAAA,CAAAN,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAM,gBAAA,CAAAN,GAAA;AAAA;AACA,IAAAO,eAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,eAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,eAAA,CAAAP,GAAA;EAAAC,OAAA,CAAAD,GAAA,IAAAO,eAAA,CAAAP,GAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.parseFunctionCallPayload = parseFunctionCallPayload;
5
+ function isFunctionCall(value) {
6
+ return typeof value === 'object' && value !== null && 'functionCallId' in value && typeof value.functionCallId === 'string' && 'name' in value && typeof value.name === 'string';
7
+ }
8
+ function parseFunctionCallPayload(payload) {
9
+ try {
10
+ const parsed = JSON.parse(payload);
11
+ return isFunctionCall(parsed) ? parsed : undefined;
12
+ } catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["isFunctionCall","value","functionCallId","name","parseFunctionCallPayload","payload","parsed","JSON","parse","undefined"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/rpc.ts"],"sourcesContent":["import type { FunctionCall } from '../../../../types/service';\n\nfunction isFunctionCall(value: unknown): value is FunctionCall {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'functionCallId' in value &&\n typeof value.functionCallId === 'string' &&\n 'name' in value &&\n typeof value.name === 'string'\n );\n}\n\nexport function parseFunctionCallPayload(\n payload: string,\n): FunctionCall | undefined {\n try {\n const parsed: unknown = JSON.parse(payload);\n return isFunctionCall(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;;;AAEA,SAASA,cAAcA,CAACC,KAAc,EAAyB;EAC7D,OACE,OAAOA,KAAK,KAAK,QAAQ,IACzBA,KAAK,KAAK,IAAI,IACd,gBAAgB,IAAIA,KAAK,IACzB,OAAOA,KAAK,CAACC,cAAc,KAAK,QAAQ,IACxC,MAAM,IAAID,KAAK,IACf,OAAOA,KAAK,CAACE,IAAI,KAAK,QAAQ;AAElC;AAEO,SAASC,wBAAwBA,CACtCC,OAAe,EACW;EAC1B,IAAI;IACF,MAAMC,MAAe,GAAGC,IAAI,CAACC,KAAK,CAACH,OAAO,CAAC;IAC3C,OAAOL,cAAc,CAACM,MAAM,CAAC,GAAGA,MAAM,GAAGG,SAAS;EACpD,CAAC,CAAC,MAAM;IACN,OAAOA,SAAS;EAClB;AACF","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.buildToolDefinitions = buildToolDefinitions;
5
+ function buildToolDefinitions(registry) {
6
+ const tools = [];
7
+ for (const [name, entry] of Object.entries(registry)) {
8
+ if (typeof entry === 'function') {
9
+ continue;
10
+ }
11
+ tools.push({
12
+ name,
13
+ description: entry.description ?? name,
14
+ parameters: entry.parameters ?? {
15
+ type: 'object',
16
+ properties: {}
17
+ }
18
+ });
19
+ }
20
+ return tools;
21
+ }
22
+ //# sourceMappingURL=toolDefinitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["buildToolDefinitions","registry","tools","name","entry","Object","entries","push","description","parameters","type","properties"],"sources":["../../../../../../src/hooks/useConversation/livekit/utils/toolDefinitions.ts"],"sourcesContent":["import type { ToolsRegistry } from '../../../useTools/model/types';\nimport type { ClientToolDefinition } from '../types';\n\nexport function buildToolDefinitions(\n registry: ToolsRegistry,\n): ClientToolDefinition[] {\n const tools: ClientToolDefinition[] = [];\n\n for (const [name, entry] of Object.entries(registry)) {\n if (typeof entry === 'function') {\n continue;\n }\n tools.push({\n name,\n description: entry.description ?? name,\n parameters: entry.parameters ?? { type: 'object', properties: {} },\n });\n }\n\n return tools;\n}\n"],"mappings":";;;;AAGO,SAASA,oBAAoBA,CAClCC,QAAuB,EACC;EACxB,MAAMC,KAA6B,GAAG,EAAE;EAExC,KAAK,MAAM,CAACC,IAAI,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACL,QAAQ,CAAC,EAAE;IACpD,IAAI,OAAOG,KAAK,KAAK,UAAU,EAAE;MAC/B;IACF;IACAF,KAAK,CAACK,IAAI,CAAC;MACTJ,IAAI;MACJK,WAAW,EAAEJ,KAAK,CAACI,WAAW,IAAIL,IAAI;MACtCM,UAAU,EAAEL,KAAK,CAACK,UAAU,IAAI;QAAEC,IAAI,EAAE,QAAQ;QAAEC,UAAU,EAAE,CAAC;MAAE;IACnE,CAAC,CAAC;EACJ;EAEA,OAAOT,KAAK;AACd","ignoreList":[]}
@@ -2,6 +2,7 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.createObjectScanner = createObjectScanner;
5
+ exports.extractCanSendChatMessage = extractCanSendChatMessage;
5
6
  exports.extractContent = extractContent;
6
7
  exports.streamChatMessage = streamChatMessage;
7
8
  // Same-origin Wix persona-chat gateway path. The transport always posts here
@@ -38,6 +39,17 @@ function extractContent(frame) {
38
39
  return null;
39
40
  }
40
41
 
42
+ // Same lookup order as extractContent: top level first, then the gateway body.
43
+ function extractCanSendChatMessage(frame) {
44
+ try {
45
+ const parsed = JSON.parse(frame);
46
+ const payload = typeof parsed.canSendChatMessage === 'boolean' || typeof parsed.body !== 'string' ? parsed : JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(parsed.body), char => char.charCodeAt(0))));
47
+ return typeof payload.canSendChatMessage === 'boolean' ? payload.canSendChatMessage : null;
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+
41
53
  // Feeds decoded text through a running scanner that emits each complete
42
54
  // top-level `{…}` object as its closing brace arrives.
43
55
  function createObjectScanner(onObject) {
@@ -91,7 +103,8 @@ async function streamChatMessage(params, callbacks, signal) {
91
103
  const {
92
104
  onChunk,
93
105
  onDone,
94
- onError
106
+ onError,
107
+ onCanSendChatMessage
95
108
  } = callbacks;
96
109
  const xsrfToken = readCookie('XSRF-TOKEN');
97
110
  const autoXsrf = !(headers != null && headers['x-xsrf-token']) && xsrfToken ? {
@@ -126,6 +139,10 @@ async function streamChatMessage(params, callbacks, signal) {
126
139
  if (content !== null) {
127
140
  onChunk(content);
128
141
  }
142
+ const canSend = extractCanSendChatMessage(frame);
143
+ if (canSend !== null) {
144
+ onCanSendChatMessage == null || onCanSendChatMessage(canSend);
145
+ }
129
146
  });
130
147
  const reader = response.body.getReader();
131
148
  const decoder = new TextDecoder();
@@ -1 +1 @@
1
- {"version":3,"names":["DEFAULT_STREAM_PATH","readCookie","name","_document$cookie$spli","document","undefined","cookie","split","map","part","trim","find","startsWith","slice","length","extractContent","frame","parsed","JSON","parse","content","body","decoded","TextDecoder","decode","Uint8Array","from","atob","char","charCodeAt","inner","createObjectScanner","onObject","buffer","cursor","braceDepth","objectStart","inString","escaped","feed","text","streamChatMessage","params","callbacks","signal","chatId","message","namespace","chatConfig","attachments","metadata","headers","onChunk","onDone","onError","xsrfToken","autoXsrf","response","fetch","method","credentials","stringify","ok","Error","status","scanForObjects","reader","getReader","decoder","done","value","read","stream","err"],"sources":["../../../../src/hooks/useTextChat/streamChatMessage.ts"],"sourcesContent":["// Same-origin Wix persona-chat gateway path. The transport always posts here\n// with `credentials: 'include'`, so the session cookie rides along and a\n// consumer needs no proxy route of its own.\nconst DEFAULT_STREAM_PATH =\n '/_api/persona-chat-service/v1/chat/messages/stream';\n\nexport type StreamCallbacks = {\n onChunk: (token: string) => void;\n onDone: () => void;\n onError: (err: Error) => void;\n};\n\nexport type StreamChatMessageParams = {\n chatId: string;\n message: string;\n namespace: string;\n chatConfig?: object;\n attachments?: object[];\n // Request metadata forwarded to the RPC (e.g. `additionalMetadata` carrying\n // opening-message context). Mirrors the top-level `metadata` object the unary\n // `sendChatMessage` request accepts, so a streamed send carries it identically.\n metadata?: object;\n // Extra request headers merged onto the POST. Lets the caller satisfy the\n // host's transport requirements the SDK can't know about — e.g. an\n // `x-xsrf-token` when the endpoint sits behind a CSRF-protected gateway.\n headers?: Record<string, string>;\n};\n\n// Read a cookie value by name in the browser. Returns undefined outside a\n// browser or when the cookie is absent.\nfunction readCookie(name: string): string | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n return document.cookie\n .split(';')\n .map((part) => part.trim())\n .find((part) => part.startsWith(`${name}=`))\n ?.slice(name.length + 1);\n}\n\n// Pull the assistant text out of one streamed frame. Two framings reach us: the\n// proxy route yields `{ content }` objects, while the gateway wraps each frame\n// as `{ body: base64(json) }`. Returns null for frames without content.\nexport function extractContent(frame: string): string | null {\n try {\n const parsed = JSON.parse(frame);\n if (typeof parsed.content === 'string') {\n return parsed.content;\n }\n if (typeof parsed.body === 'string') {\n const decoded = new TextDecoder().decode(\n Uint8Array.from(atob(parsed.body), (char) => char.charCodeAt(0)),\n );\n const inner = JSON.parse(decoded);\n return typeof inner.content === 'string' ? inner.content : null;\n }\n } catch {\n // Incomplete or non-object frame — skip it.\n }\n return null;\n}\n\n// Feeds decoded text through a running scanner that emits each complete\n// top-level `{…}` object as its closing brace arrives.\nexport function createObjectScanner(onObject: (frame: string) => void) {\n let buffer = '';\n let cursor = 0;\n let braceDepth = 0;\n let objectStart = -1;\n let inString = false;\n let escaped = false;\n\n return function feed(text: string) {\n buffer += text;\n for (; cursor < buffer.length; cursor++) {\n const char = buffer[cursor];\n if (inString) {\n if (escaped) {\n escaped = false;\n } else if (char === '\\\\') {\n escaped = true;\n } else if (char === '\"') {\n inString = false;\n }\n continue;\n }\n if (char === '\"') {\n inString = true;\n } else if (char === '{') {\n if (braceDepth === 0) {\n objectStart = cursor;\n }\n braceDepth++;\n } else if (char === '}' && braceDepth > 0) {\n braceDepth--;\n if (braceDepth === 0 && objectStart >= 0) {\n onObject(buffer.slice(objectStart, cursor + 1));\n objectStart = -1;\n }\n }\n }\n };\n}\n\nexport async function streamChatMessage(\n params: StreamChatMessageParams,\n callbacks: StreamCallbacks,\n signal?: AbortSignal,\n): Promise<void> {\n const {\n chatId,\n message,\n namespace,\n chatConfig,\n attachments,\n metadata,\n headers,\n } = params;\n const { onChunk, onDone, onError } = callbacks;\n\n const xsrfToken = readCookie('XSRF-TOKEN');\n const autoXsrf =\n !headers?.['x-xsrf-token'] && xsrfToken\n ? { 'x-xsrf-token': xsrfToken }\n : undefined;\n\n try {\n // eslint-disable-next-line no-undef\n const response = await fetch(DEFAULT_STREAM_PATH, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...autoXsrf, ...headers },\n body: JSON.stringify({\n chatId,\n message,\n namespace,\n chatConfig,\n attachments,\n metadata,\n }),\n signal,\n });\n\n if (!response.ok || !response.body) {\n onError(new Error(`Stream request failed: ${response.status}`));\n return;\n }\n\n const scanForObjects = createObjectScanner((frame) => {\n const content = extractContent(frame);\n if (content !== null) {\n onChunk(content);\n }\n });\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n scanForObjects(decoder.decode(value, { stream: true }));\n }\n scanForObjects(decoder.decode());\n onDone();\n } catch (err) {\n if ((err as Error).name !== 'AbortError') {\n onError(err as Error);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["DEFAULT_STREAM_PATH","readCookie","name","_document$cookie$spli","document","undefined","cookie","split","map","part","trim","find","startsWith","slice","length","extractContent","frame","parsed","JSON","parse","content","body","decoded","TextDecoder","decode","Uint8Array","from","atob","char","charCodeAt","inner","extractCanSendChatMessage","payload","canSendChatMessage","createObjectScanner","onObject","buffer","cursor","braceDepth","objectStart","inString","escaped","feed","text","streamChatMessage","params","callbacks","signal","chatId","message","namespace","chatConfig","attachments","metadata","headers","onChunk","onDone","onError","onCanSendChatMessage","xsrfToken","autoXsrf","response","fetch","method","credentials","stringify","ok","Error","status","scanForObjects","canSend","reader","getReader","decoder","done","value","read","stream","err"],"sources":["../../../../src/hooks/useTextChat/streamChatMessage.ts"],"sourcesContent":["// Same-origin Wix persona-chat gateway path. The transport always posts here\n// with `credentials: 'include'`, so the session cookie rides along and a\n// consumer needs no proxy route of its own.\nconst DEFAULT_STREAM_PATH =\n '/_api/persona-chat-service/v1/chat/messages/stream';\n\nexport type StreamCallbacks = {\n onChunk: (token: string) => void;\n onDone: () => void;\n onError: (err: Error) => void;\n onCanSendChatMessage?: (canSend: boolean) => void;\n};\n\nexport type StreamChatMessageParams = {\n chatId: string;\n message: string;\n namespace: string;\n chatConfig?: object;\n attachments?: object[];\n // Request metadata forwarded to the RPC (e.g. `additionalMetadata` carrying\n // opening-message context). Mirrors the top-level `metadata` object the unary\n // `sendChatMessage` request accepts, so a streamed send carries it identically.\n metadata?: object;\n // Extra request headers merged onto the POST. Lets the caller satisfy the\n // host's transport requirements the SDK can't know about — e.g. an\n // `x-xsrf-token` when the endpoint sits behind a CSRF-protected gateway.\n headers?: Record<string, string>;\n};\n\n// Read a cookie value by name in the browser. Returns undefined outside a\n// browser or when the cookie is absent.\nfunction readCookie(name: string): string | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n return document.cookie\n .split(';')\n .map((part) => part.trim())\n .find((part) => part.startsWith(`${name}=`))\n ?.slice(name.length + 1);\n}\n\n// Pull the assistant text out of one streamed frame. Two framings reach us: the\n// proxy route yields `{ content }` objects, while the gateway wraps each frame\n// as `{ body: base64(json) }`. Returns null for frames without content.\nexport function extractContent(frame: string): string | null {\n try {\n const parsed = JSON.parse(frame);\n if (typeof parsed.content === 'string') {\n return parsed.content;\n }\n if (typeof parsed.body === 'string') {\n const decoded = new TextDecoder().decode(\n Uint8Array.from(atob(parsed.body), (char) => char.charCodeAt(0)),\n );\n const inner = JSON.parse(decoded);\n return typeof inner.content === 'string' ? inner.content : null;\n }\n } catch {\n // Incomplete or non-object frame — skip it.\n }\n return null;\n}\n\n// Same lookup order as extractContent: top level first, then the gateway body.\nexport function extractCanSendChatMessage(frame: string): boolean | null {\n try {\n const parsed = JSON.parse(frame);\n const payload =\n typeof parsed.canSendChatMessage === 'boolean' ||\n typeof parsed.body !== 'string'\n ? parsed\n : JSON.parse(\n new TextDecoder().decode(\n Uint8Array.from(atob(parsed.body), (char) => char.charCodeAt(0)),\n ),\n );\n return typeof payload.canSendChatMessage === 'boolean'\n ? payload.canSendChatMessage\n : null;\n } catch {\n return null;\n }\n}\n\n// Feeds decoded text through a running scanner that emits each complete\n// top-level `{…}` object as its closing brace arrives.\nexport function createObjectScanner(onObject: (frame: string) => void) {\n let buffer = '';\n let cursor = 0;\n let braceDepth = 0;\n let objectStart = -1;\n let inString = false;\n let escaped = false;\n\n return function feed(text: string) {\n buffer += text;\n for (; cursor < buffer.length; cursor++) {\n const char = buffer[cursor];\n if (inString) {\n if (escaped) {\n escaped = false;\n } else if (char === '\\\\') {\n escaped = true;\n } else if (char === '\"') {\n inString = false;\n }\n continue;\n }\n if (char === '\"') {\n inString = true;\n } else if (char === '{') {\n if (braceDepth === 0) {\n objectStart = cursor;\n }\n braceDepth++;\n } else if (char === '}' && braceDepth > 0) {\n braceDepth--;\n if (braceDepth === 0 && objectStart >= 0) {\n onObject(buffer.slice(objectStart, cursor + 1));\n objectStart = -1;\n }\n }\n }\n };\n}\n\nexport async function streamChatMessage(\n params: StreamChatMessageParams,\n callbacks: StreamCallbacks,\n signal?: AbortSignal,\n): Promise<void> {\n const {\n chatId,\n message,\n namespace,\n chatConfig,\n attachments,\n metadata,\n headers,\n } = params;\n const { onChunk, onDone, onError, onCanSendChatMessage } = callbacks;\n\n const xsrfToken = readCookie('XSRF-TOKEN');\n const autoXsrf =\n !headers?.['x-xsrf-token'] && xsrfToken\n ? { 'x-xsrf-token': xsrfToken }\n : undefined;\n\n try {\n // eslint-disable-next-line no-undef\n const response = await fetch(DEFAULT_STREAM_PATH, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json', ...autoXsrf, ...headers },\n body: JSON.stringify({\n chatId,\n message,\n namespace,\n chatConfig,\n attachments,\n metadata,\n }),\n signal,\n });\n\n if (!response.ok || !response.body) {\n onError(new Error(`Stream request failed: ${response.status}`));\n return;\n }\n\n const scanForObjects = createObjectScanner((frame) => {\n const content = extractContent(frame);\n if (content !== null) {\n onChunk(content);\n }\n const canSend = extractCanSendChatMessage(frame);\n if (canSend !== null) {\n onCanSendChatMessage?.(canSend);\n }\n });\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n scanForObjects(decoder.decode(value, { stream: true }));\n }\n scanForObjects(decoder.decode());\n onDone();\n } catch (err) {\n if ((err as Error).name !== 'AbortError') {\n onError(err as Error);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -139,6 +139,7 @@ function useTextChatStream(options = {}) {
139
139
  let lastFrameTime = 0;
140
140
  let receivedContent = false;
141
141
  let errored = false;
142
+ let canSendChatMessage;
142
143
  const settle = () => {
143
144
  stopRaf();
144
145
  const finalAssistantMsg = {
@@ -205,12 +206,14 @@ function useTextChatStream(options = {}) {
205
206
  stopRaf();
206
207
  onError == null || onError(err);
207
208
  setStreamingMessages([]);
208
- }
209
+ },
210
+ onCanSendChatMessage: canSend => canSendChatMessage = canSend
209
211
  }, controller.signal);
210
212
  return {
211
213
  ok: streamDone && !errored,
212
214
  producedContent: receivedContent,
213
- aborted: !streamDone && !errored
215
+ aborted: !streamDone && !errored,
216
+ canSendChatMessage
214
217
  };
215
218
  }, [chatId, namespace, headers, onError, refetch, revealMsPerChar, stopRaf]);
216
219
  return {