@elevenlabs/react-native 0.3.0 → 0.3.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"lib.umd.js","sources":["../src/version.ts","../src/components/MessageHandler.tsx","../src/components/LiveKitRoomWrapper.tsx","../src/ElevenLabsProvider.tsx","../src/utils/constants.ts","../src/hooks/useConversationCallbacks.ts","../src/hooks/useConversationSession.ts","../src/utils/tokenUtils.ts","../src/hooks/useLiveKitRoom.ts","../src/hooks/useMessageSending.ts","../src/utils/overrides.ts"],"sourcesContent":["// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.3.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent, ConversationEvent } from '../types';\nimport React from 'react';\n\ninterface MessageHandlerProps {\n onReady: (participant: LocalParticipant) => void;\n isConnected: boolean;\n callbacks: Callbacks;\n sendMessage: (message: unknown) => void;\n clientTools?: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: any): event is ConversationEvent {\n return !!event.type;\n}\n\nexport const MessageHandler = ({\n onReady,\n isConnected,\n callbacks,\n sendMessage,\n clientTools = {},\n updateCurrentEventId\n}: MessageHandlerProps) => {\n const { localParticipant } = useLocalParticipant();\n\n // Track agent response count for synthetic event IDs (WebRTC mode)\n const agentResponseCountRef = React.useRef(1);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.client_tool_call.tool_name](\n clientToolCall.client_tool_call.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.client_tool_call.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (callbacks.onUnhandledClientToolCall) {\n callbacks.onUnhandledClientToolCall(clientToolCall);\n return;\n }\n\n const errorMessage = `Client tool with name ${clientToolCall.client_tool_call.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.client_tool_call.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: errorMessage,\n is_error: true,\n });\n }\n };\n\n const _ = useDataChannel((msg) => {\n const decoder = new TextDecoder();\n const message = JSON.parse(decoder.decode(msg.payload));\n\n if (!isValidEvent(message)) {\n callbacks.onDebug?.({\n type: \"invalid_event\",\n message,\n });\n return;\n }\n\n callbacks.onMessage?.({\n message,\n source: msg.from?.isAgent ? 'ai' : 'user',\n });\n\n if (msg.from?.isAgent) {\n callbacks.onModeChange?.({\n mode: msg.from?.isSpeaking ? 'speaking' : 'listening'\n });\n\n // Track agent responses for feedback (WebRTC mode needs synthetic event IDs)\n if (message.type === \"agent_response\" && updateCurrentEventId) {\n const eventId = agentResponseCountRef.current++;\n updateCurrentEventId(eventId);\n }\n }\n\n switch (message.type) {\n case \"ping\":\n sendMessage({\n type: \"pong\",\n event_id: message.ping_event.event_id,\n });\n break;\n case \"client_tool_call\":\n handleClientToolCall(message);\n break;\n default:\n callbacks.onDebug?.(message);\n break;\n }\n });\n\n return null;\n};","import React from 'react';\nimport { LiveKitRoom } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig } from '../types';\nimport { MessageHandler } from './MessageHandler';\n\ninterface LiveKitRoomWrapperProps {\n children: React.ReactNode;\n serverUrl: string;\n token: string;\n connect: boolean;\n onConnected: () => void;\n onDisconnected: () => void;\n onError: (error: Error) => void;\n roomConnected: boolean;\n callbacks: Callbacks;\n onParticipantReady: (participant: LocalParticipant) => void;\n sendMessage: (message: unknown) => void;\n clientTools: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const LiveKitRoomWrapper = ({\n children,\n serverUrl,\n token,\n connect,\n onConnected,\n onDisconnected,\n onError,\n roomConnected,\n callbacks,\n onParticipantReady,\n sendMessage,\n clientTools,\n updateCurrentEventId,\n}: LiveKitRoomWrapperProps) => {\n return (\n <LiveKitRoom\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n audio={true}\n video={false}\n options={{\n adaptiveStream: { pixelDensity: 'screen' },\n }}\n onConnected={onConnected}\n onDisconnected={onDisconnected}\n onError={onError}\n >\n <MessageHandler\n onReady={onParticipantReady}\n isConnected={roomConnected}\n callbacks={callbacks}\n sendMessage={sendMessage}\n clientTools={clientTools}\n updateCurrentEventId={updateCurrentEventId}\n />\n {children}\n </LiveKitRoom>\n );\n};","import React from 'react';\nimport { createContext, useContext, useState } from 'react';\nimport { registerGlobals } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ConversationConfig, ConversationStatus, ClientToolsConfig } from './types';\nimport { constructOverrides } from './utils/overrides';\nimport { DEFAULT_SERVER_URL } from './utils/constants';\nimport { useConversationCallbacks } from './hooks/useConversationCallbacks';\nimport { useConversationSession } from './hooks/useConversationSession';\nimport { useLiveKitRoom } from './hooks/useLiveKitRoom';\nimport { useMessageSending } from './hooks/useMessageSending';\nimport { LiveKitRoomWrapper } from './components/LiveKitRoomWrapper';\n\ninterface ConversationOptions extends Callbacks, Partial<ClientToolsConfig> {\n serverUrl?: string;\n tokenFetchUrl?: string;\n}\n\nexport interface Conversation {\n startSession: (config: ConversationConfig) => Promise<void>;\n endSession: () => Promise<void>;\n status: ConversationStatus;\n isSpeaking: boolean;\n // TODO: Implement setVolume when LiveKit React Native supports it\n // setVolume: (volume: number) => void;\n canSendFeedback: boolean;\n getId: () => string;\n sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n setMicMuted: (muted: boolean) => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n tokenFetchUrl?: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (url: string) => void;\n setTokenFetchUrl: (url: string) => void;\n setClientTools: (tools: ClientToolsConfig['clientTools']) => void;\n}\n\nconst ElevenLabsContext = createContext<ElevenLabsContextType | null>(null);\n\nexport const useConversation = (options: ConversationOptions = {}): Conversation => {\n const context = useContext(ElevenLabsContext);\n if (!context) {\n throw new Error('useConversation must be used within ElevenLabsProvider');\n }\n\n const { serverUrl, tokenFetchUrl, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\n\n React.useEffect(() => {\n if (tokenFetchUrl) {\n context.setTokenFetchUrl(tokenFetchUrl);\n }\n }, [context, tokenFetchUrl]);\n\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n\n context.setCallbacks(callbacks);\n\n return context.conversation;\n};\n\ninterface ElevenLabsProviderProps {\n children: React.ReactNode;\n}\n\nexport const ElevenLabsProvider: React.FC<ElevenLabsProviderProps> = ({ children }) => {\n // Initialize globals on mount\n registerGlobals();\n\n // State management\n const [token, setToken] = useState('');\n const [connect, setConnect] = useState(false);\n const [status, setStatus] = useState<ConversationStatus>('disconnected');\n const [serverUrl, setServerUrl] = useState(DEFAULT_SERVER_URL);\n const [tokenFetchUrl, setTokenFetchUrl] = useState<string | undefined>(undefined);\n const [conversationId, setConversationId] = useState<string>('');\n const [isSpeaking, setIsSpeaking] = useState(false);\n const [canSendFeedback, setCanSendFeedback] = useState(false);\n\n // Feedback state tracking\n const currentEventIdRef = React.useRef(1);\n const lastFeedbackEventIdRef = React.useRef(1);\n\n // Use ref for clientTools to avoid re-renders (like callbacks)\n const clientToolsRef = React.useRef<ClientToolsConfig['clientTools']>({});\n\n // Custom hooks\n const { callbacksRef, setCallbacks: setCallbacksBase } = useConversationCallbacks();\n\n // Enhanced setCallbacks that wraps onModeChange to update isSpeaking state\n const setCallbacks = React.useCallback((callbacks: Callbacks) => {\n const wrappedCallbacks = {\n ...callbacks,\n onModeChange: (event: { mode: 'speaking' | 'listening' }) => {\n setIsSpeaking(event.mode === 'speaking');\n callbacks.onModeChange?.(event);\n }\n };\n setCallbacksBase(wrappedCallbacks);\n }, [setCallbacksBase]);\n\n const {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setConversationId, tokenFetchUrl);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, conversationId);\n\n // Enhanced connection handler to initialize feedback state\n const handleConnectedWithFeedback = React.useCallback(() => {\n // Reset feedback state when connecting\n currentEventIdRef.current = 1;\n lastFeedbackEventIdRef.current = 1;\n setCanSendFeedback(false);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: false });\n\n handleConnected();\n }, [handleConnected, callbacksRef]);\n\n // Enhanced disconnection handler to reset feedback state\n const handleDisconnectedWithFeedback = React.useCallback(() => {\n setCanSendFeedback(false);\n handleDisconnected();\n }, [handleDisconnected]);\n\n const { sendMessage } = useMessageSending(status, localParticipant, callbacksRef);\n\n const updateCanSendFeedback = React.useCallback(() => {\n const newCanSendFeedback = currentEventIdRef.current !== lastFeedbackEventIdRef.current;\n\n if (canSendFeedback !== newCanSendFeedback) {\n setCanSendFeedback(newCanSendFeedback);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: newCanSendFeedback });\n }\n }, [canSendFeedback, callbacksRef]);\n\n const sendFeedback = React.useCallback((like: boolean) => {\n if (!canSendFeedback) {\n console.warn(\n lastFeedbackEventIdRef.current === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n const feedbackMessage = {\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: currentEventIdRef.current,\n };\n\n sendMessage(feedbackMessage);\n lastFeedbackEventIdRef.current = currentEventIdRef.current;\n updateCanSendFeedback();\n }, [canSendFeedback, sendMessage, updateCanSendFeedback]);\n\n // setVolume placeholder (to be implemented when LiveKit supports it)\n const setVolume = React.useCallback((volume: number) => {\n console.warn('setVolume is not yet implemented in React Native SDK');\n }, []);\n\n const getId = () => conversationId;\n\n const setMicMuted = React.useCallback((muted: boolean) => {\n if (localParticipant) {\n localParticipant.setMicrophoneEnabled(!muted);\n }\n }, [localParticipant]);\n\n // Update current event ID for feedback tracking\n const updateCurrentEventId = React.useCallback((eventId: number) => {\n currentEventIdRef.current = eventId;\n updateCanSendFeedback();\n }, [updateCanSendFeedback]);\n\n // Handle participant ready with overrides\n const handleParticipantReadyWithOverrides = React.useCallback((participant: LocalParticipant) => {\n handleParticipantReady(participant);\n\n if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, userId, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl: setTokenFetchUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n onConnected={handleConnectedWithFeedback}\n onDisconnected={handleDisconnectedWithFeedback}\n onError={handleError}\n roomConnected={roomConnected}\n callbacks={callbacksRef.current}\n onParticipantReady={handleParticipantReadyWithOverrides}\n sendMessage={sendMessage}\n clientTools={clientToolsRef.current}\n updateCurrentEventId={updateCurrentEventId}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\n};","export const DEFAULT_SERVER_URL = \"wss://livekit.rtc.elevenlabs.io\";\n","import { useRef, useCallback } from \"react\";\nimport type { Callbacks } from \"../types\";\n\nexport const useConversationCallbacks = () => {\n const callbacksRef = useRef<Callbacks>({});\n\n const setCallbacks = useCallback((callbacks: Callbacks) => {\n callbacksRef.current = callbacks;\n }, []);\n\n return {\n callbacksRef,\n setCallbacks,\n };\n};\n","import { useState, useCallback } from \"react\";\nimport type {\n ConversationConfig,\n ConversationStatus,\n Callbacks,\n} from \"../types\";\nimport {\n getConversationToken,\n extractConversationIdFromToken,\n} from \"../utils/tokenUtils\";\n\nexport const useConversationSession = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n setConnect: (connect: boolean) => void,\n setToken: (token: string) => void,\n setConversationId: (conversationId: string) => void,\n tokenFetchUrl?: string\n) => {\n const [overrides, setOverrides] = useState<ConversationConfig[\"overrides\"]>(\n {}\n );\n const [customLlmExtraBody, setCustomLlmExtraBody] =\n useState<ConversationConfig[\"customLlmExtraBody\"]>(null);\n const [dynamicVariables, setDynamicVariables] = useState<\n ConversationConfig[\"dynamicVariables\"]\n >({});\n const [userId, setUserId] = useState<ConversationConfig[\"userId\"]>(undefined);\n\n const startSession = useCallback(\n async (config: ConversationConfig) => {\n try {\n setStatus(\"connecting\");\n callbacksRef.current.onStatusChange?.({ status: \"connecting\" });\n\n setOverrides(config.overrides || {});\n setCustomLlmExtraBody(config.customLlmExtraBody || null);\n setDynamicVariables(config.dynamicVariables || {});\n setUserId(config.userId);\n\n let conversationToken: string;\n\n if (config.conversationToken) {\n conversationToken = config.conversationToken;\n } else if (config.agentId) {\n console.info(\n \"Getting conversation token for agentId:\",\n config.agentId\n );\n // Use tokenFetchUrl from config first, then from hook parameter, then default\n const urlToUse = config.tokenFetchUrl || tokenFetchUrl;\n conversationToken = await getConversationToken(\n config.agentId,\n urlToUse\n );\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n const extractedConversationId =\n extractConversationIdFromToken(conversationToken);\n setConversationId(extractedConversationId);\n\n setToken(conversationToken);\n setConnect(true);\n } catch (error) {\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [\n callbacksRef,\n setStatus,\n setConnect,\n setToken,\n setConversationId,\n tokenFetchUrl,\n ]\n );\n\n const endSession = useCallback(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.(\"User ended conversation\");\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\n\n return {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractConversationIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n const roomId = tokenPayload.video?.room || \"\";\n\n return roomId.match(/(conv_[a-zA-Z0-9]+)/)?.[0] || \"\";\n } catch (error) {\n console.warn(\"Could not extract conversation ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string,\n tokenFetchUrl?: string\n): Promise<string> => {\n const baseUrl =\n tokenFetchUrl || \"https://api.elevenlabs.io/v1/convai/conversation/token\";\n const response = await fetch(\n `${baseUrl}?agent_id=${agentId}&source=react_native_sdk&version=${PACKAGE_VERSION}`\n );\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`Failed to get conversation token: ${data.detail.message}`);\n }\n\n if (!data.token) {\n throw new Error(\"No conversation token received from API\");\n }\n\n return data.token;\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport { AudioSession } from \"@livekit/react-native\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useLiveKitRoom = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n conversationId: string\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId });\n }, [conversationId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.(\"disconnected\");\n }, [callbacksRef, setStatus]);\n\n const handleError = useCallback(\n (error: Error) => {\n console.error(\"LiveKit error:\", error);\n callbacksRef.current.onError?.(error.message, undefined);\n },\n [callbacksRef]\n );\n\n return {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n };\n};\n","import { useCallback } from \"react\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useMessageSending = (\n status: ConversationStatus,\n localParticipant: LocalParticipant | null,\n callbacksRef: { current: Callbacks }\n) => {\n const sendMessage = useCallback(\n async (message: unknown) => {\n if (status !== \"connected\" || !localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send message via WebRTC:\", error);\n console.error(\"Error details:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n },\n [status, localParticipant, callbacksRef]\n );\n\n return { sendMessage };\n};\n","import type { ConversationConfig, InitiationClientDataEvent } from \"../types\";\nimport { PACKAGE_VERSION } from \"../version\";\n\nexport function constructOverrides(\n config: ConversationConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n source_info: {\n source: \"react_native_sdk\",\n version: config.overrides?.client?.version || PACKAGE_VERSION,\n },\n };\n }\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n if (config.userId) {\n overridesEvent.user_id = String(config.userId);\n }\n\n return overridesEvent;\n}\n"],"names":["PACKAGE_VERSION","MessageHandler","_ref","onReady","isConnected","callbacks","sendMessage","_ref$clientTools","clientTools","updateCurrentEventId","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from","_msg$from2","decoder","TextDecoder","message","JSON","parse","decode","payload","type","_msg$from3","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","client_tool_call","tool_name","_temp","parameters","then","result","formattedResult","stringify","String","tool_call_id","is_error","_catch","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","reject","handleClientToolCall","onDebug","LiveKitRoomWrapper","children","createElement","LiveKitRoom","serverUrl","token","connect","audio","video","options","adaptiveStream","pixelDensity","onConnected","onDisconnected","onParticipantReady","roomConnected","_excluded","ElevenLabsContext","createContext","registerGlobals","_useState","useState","setToken","_useState2","setConnect","_useState3","status","setStatus","_useState4","setServerUrl","_useState5","undefined","tokenFetchUrl","setTokenFetchUrl","_useState6","conversationId","setConversationId","_useState7","setIsSpeaking","_useState8","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","_useConversationCallb","callbacksRef","setCallbacks","useCallback","useConversationCallbacks","setCallbacksBase","wrappedCallbacks","_extends","event","_useConversationSessi","overrides","setOverrides","customLlmExtraBody","setCustomLlmExtraBody","dynamicVariables","setDynamicVariables","userId","setUserId","startSession","config","_temp2","_result2","extractedConversationId","_tokenPayload$video","_roomId$match","atob","split","room","match","error","console","warn","extractConversationIdFromToken","conversationToken","onStatusChange","agentId","info","fetch","response","json","data","ok","Error","detail","getConversationToken","_getConversationToken","endSession","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","setMicMuted","muted","setMicrophoneEnabled","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","source_info","version","client","custom_llm_extra_body","dynamic_variables","user_id","constructOverrides","getId","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
1
+ {"version":3,"file":"lib.umd.js","sources":["../src/version.ts","../src/components/MessageHandler.tsx","../src/components/LiveKitRoomWrapper.tsx","../src/ElevenLabsProvider.tsx","../src/utils/constants.ts","../src/hooks/useConversationCallbacks.ts","../src/hooks/useConversationSession.ts","../src/utils/tokenUtils.ts","../src/hooks/useLiveKitRoom.ts","../src/hooks/useMessageSending.ts","../src/utils/overrides.ts"],"sourcesContent":["// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.3.2\";\n","import { useEffect } from \"react\";\nimport { useLocalParticipant, useDataChannel } from \"@livekit/react-native\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type {\n Callbacks,\n ClientToolsConfig,\n ClientToolCallEvent,\n ConversationEvent,\n} from \"../types\";\nimport React from \"react\";\n\ninterface MessageHandlerProps {\n onReady: (participant: LocalParticipant) => void;\n isConnected: boolean;\n callbacks: Callbacks;\n sendMessage: (message: unknown) => void;\n clientTools?: ClientToolsConfig[\"clientTools\"];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: any): event is ConversationEvent {\n return !!event.type;\n}\n\nfunction extractMessageText(event: ConversationEvent): string | null {\n switch (event.type) {\n case \"user_transcript\":\n return event.user_transcription_event.user_transcript;\n case \"agent_response\":\n return event.agent_response_event.agent_response;\n default:\n return null;\n }\n}\n\nexport const MessageHandler = ({\n onReady,\n isConnected,\n callbacks,\n sendMessage,\n clientTools = {},\n updateCurrentEventId,\n}: MessageHandlerProps) => {\n const { localParticipant } = useLocalParticipant();\n\n // Track agent response count for synthetic event IDs (WebRTC mode)\n const agentResponseCountRef = React.useRef(1);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.client_tool_call.tool_name](\n clientToolCall.client_tool_call.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.client_tool_call.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (callbacks.onUnhandledClientToolCall) {\n callbacks.onUnhandledClientToolCall(clientToolCall.client_tool_call);\n return;\n }\n\n const errorMessage = `Client tool with name ${clientToolCall.client_tool_call.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.client_tool_call.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.client_tool_call.tool_call_id,\n result: errorMessage,\n is_error: true,\n });\n }\n };\n\n const _ = useDataChannel(msg => {\n const decoder = new TextDecoder();\n const message = JSON.parse(decoder.decode(msg.payload));\n\n if (!isValidEvent(message)) {\n callbacks.onDebug?.({\n type: \"invalid_event\",\n message,\n });\n return;\n }\n\n const messageText = extractMessageText(message);\n if (messageText !== null) {\n callbacks.onMessage?.({\n message: messageText,\n source: msg.from?.isAgent ? \"ai\" : \"user\",\n });\n }\n\n if (msg.from?.isAgent) {\n callbacks.onModeChange?.({\n mode: msg.from?.isSpeaking ? \"speaking\" : \"listening\",\n });\n\n // Track agent responses for feedback (WebRTC mode needs synthetic event IDs)\n if (message.type === \"agent_response\" && updateCurrentEventId) {\n const eventId = agentResponseCountRef.current++;\n updateCurrentEventId(eventId);\n }\n }\n\n switch (message.type) {\n case \"ping\":\n sendMessage({\n type: \"pong\",\n event_id: message.ping_event.event_id,\n });\n break;\n case \"client_tool_call\":\n handleClientToolCall(message);\n break;\n default:\n callbacks.onDebug?.(message);\n break;\n }\n });\n\n return null;\n};\n","// @ts-nocheck - pnpm hoisting causes duplicate React type definitions\nimport React from 'react';\nimport { LiveKitRoom } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig } from '../types';\nimport { MessageHandler } from './MessageHandler';\n\ninterface LiveKitRoomWrapperProps {\n children: React.ReactNode;\n serverUrl: string;\n token: string;\n connect: boolean;\n onConnected: () => void;\n onDisconnected: () => void;\n onError: (error: Error) => void;\n roomConnected: boolean;\n callbacks: Callbacks;\n onParticipantReady: (participant: LocalParticipant) => void;\n sendMessage: (message: unknown) => void;\n clientTools: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport const LiveKitRoomWrapper = ({\n children,\n serverUrl,\n token,\n connect,\n onConnected,\n onDisconnected,\n onError,\n roomConnected,\n callbacks,\n onParticipantReady,\n sendMessage,\n clientTools,\n updateCurrentEventId,\n}: LiveKitRoomWrapperProps) => {\n return (\n <LiveKitRoom\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n audio={true}\n video={false}\n options={{\n adaptiveStream: { pixelDensity: 'screen' },\n }}\n connectOptions={{\n rtcConfig: {\n iceTransportPolicy: 'relay',\n },\n }}\n onConnected={onConnected}\n onDisconnected={onDisconnected}\n onError={onError}\n >\n <MessageHandler\n onReady={onParticipantReady}\n isConnected={roomConnected}\n callbacks={callbacks}\n sendMessage={sendMessage}\n clientTools={clientTools}\n updateCurrentEventId={updateCurrentEventId}\n />\n {children as any}\n </LiveKitRoom>\n );\n};","import React from 'react';\nimport { createContext, useContext, useState } from 'react';\nimport { registerGlobals } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ConversationConfig, ConversationStatus, ClientToolsConfig } from './types';\nimport { constructOverrides } from './utils/overrides';\nimport { DEFAULT_SERVER_URL } from './utils/constants';\nimport { useConversationCallbacks } from './hooks/useConversationCallbacks';\nimport { useConversationSession } from './hooks/useConversationSession';\nimport { useLiveKitRoom } from './hooks/useLiveKitRoom';\nimport { useMessageSending } from './hooks/useMessageSending';\nimport { LiveKitRoomWrapper } from './components/LiveKitRoomWrapper';\n\ninterface ConversationOptions extends Callbacks, Partial<ClientToolsConfig> {\n serverUrl?: string;\n tokenFetchUrl?: string;\n}\n\nexport interface Conversation {\n startSession: (config: ConversationConfig) => Promise<void>;\n endSession: () => Promise<void>;\n status: ConversationStatus;\n isSpeaking: boolean;\n // TODO: Implement setVolume when LiveKit React Native supports it\n // setVolume: (volume: number) => void;\n canSendFeedback: boolean;\n getId: () => string;\n sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n setMicMuted: (muted: boolean) => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n tokenFetchUrl?: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (url: string) => void;\n setTokenFetchUrl: (url: string) => void;\n setClientTools: (tools: ClientToolsConfig['clientTools']) => void;\n}\n\nconst ElevenLabsContext = createContext<ElevenLabsContextType | null>(null);\n\nexport const useConversation = (options: ConversationOptions = {}): Conversation => {\n const context = useContext(ElevenLabsContext);\n if (!context) {\n throw new Error('useConversation must be used within ElevenLabsProvider');\n }\n\n const { serverUrl, tokenFetchUrl, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\n\n React.useEffect(() => {\n if (tokenFetchUrl) {\n context.setTokenFetchUrl(tokenFetchUrl);\n }\n }, [context, tokenFetchUrl]);\n\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n\n context.setCallbacks(callbacks);\n\n return context.conversation;\n};\n\ninterface ElevenLabsProviderProps {\n children: React.ReactNode;\n}\n\nexport const ElevenLabsProvider: React.FC<ElevenLabsProviderProps> = ({ children }) => {\n // Initialize globals on mount\n registerGlobals();\n\n // State management\n const [token, setToken] = useState('');\n const [connect, setConnect] = useState(false);\n const [status, setStatus] = useState<ConversationStatus>('disconnected');\n const [serverUrl, setServerUrl] = useState(DEFAULT_SERVER_URL);\n const [tokenFetchUrl, setTokenFetchUrl] = useState<string | undefined>(undefined);\n const [conversationId, setConversationId] = useState<string>('');\n const [isSpeaking, setIsSpeaking] = useState(false);\n const [canSendFeedback, setCanSendFeedback] = useState(false);\n\n // Feedback state tracking\n const currentEventIdRef = React.useRef(1);\n const lastFeedbackEventIdRef = React.useRef(1);\n\n // Use ref for clientTools to avoid re-renders (like callbacks)\n const clientToolsRef = React.useRef<ClientToolsConfig['clientTools']>({});\n\n // Custom hooks\n const { callbacksRef, setCallbacks: setCallbacksBase } = useConversationCallbacks();\n\n // Enhanced setCallbacks that wraps onModeChange to update isSpeaking state\n const setCallbacks = React.useCallback((callbacks: Callbacks) => {\n const wrappedCallbacks = {\n ...callbacks,\n onModeChange: (event: { mode: 'speaking' | 'listening' }) => {\n setIsSpeaking(event.mode === 'speaking');\n callbacks.onModeChange?.(event);\n }\n };\n setCallbacksBase(wrappedCallbacks);\n }, [setCallbacksBase]);\n\n const {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setConversationId, tokenFetchUrl);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, conversationId);\n\n // Enhanced connection handler to initialize feedback state\n const handleConnectedWithFeedback = React.useCallback(() => {\n // Reset feedback state when connecting\n currentEventIdRef.current = 1;\n lastFeedbackEventIdRef.current = 1;\n setCanSendFeedback(false);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: false });\n\n handleConnected();\n }, [handleConnected, callbacksRef]);\n\n // Enhanced disconnection handler to reset feedback state\n const handleDisconnectedWithFeedback = React.useCallback(() => {\n setCanSendFeedback(false);\n handleDisconnected();\n }, [handleDisconnected]);\n\n const { sendMessage } = useMessageSending(status, localParticipant, callbacksRef);\n\n const updateCanSendFeedback = React.useCallback(() => {\n const newCanSendFeedback = currentEventIdRef.current !== lastFeedbackEventIdRef.current;\n\n if (canSendFeedback !== newCanSendFeedback) {\n setCanSendFeedback(newCanSendFeedback);\n callbacksRef.current.onCanSendFeedbackChange?.({ canSendFeedback: newCanSendFeedback });\n }\n }, [canSendFeedback, callbacksRef]);\n\n const sendFeedback = React.useCallback((like: boolean) => {\n if (!canSendFeedback) {\n console.warn(\n lastFeedbackEventIdRef.current === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n const feedbackMessage = {\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: currentEventIdRef.current,\n };\n\n sendMessage(feedbackMessage);\n lastFeedbackEventIdRef.current = currentEventIdRef.current;\n updateCanSendFeedback();\n }, [canSendFeedback, sendMessage, updateCanSendFeedback]);\n\n // setVolume placeholder (to be implemented when LiveKit supports it)\n const setVolume = React.useCallback((volume: number) => {\n console.warn('setVolume is not yet implemented in React Native SDK');\n }, []);\n\n const getId = () => conversationId;\n\n const setMicMuted = React.useCallback((muted: boolean) => {\n if (localParticipant) {\n localParticipant.setMicrophoneEnabled(!muted);\n }\n }, [localParticipant]);\n\n // Update current event ID for feedback tracking\n const updateCurrentEventId = React.useCallback((eventId: number) => {\n currentEventIdRef.current = eventId;\n updateCanSendFeedback();\n }, [updateCanSendFeedback]);\n\n // Handle participant ready with overrides\n const handleParticipantReadyWithOverrides = React.useCallback((participant: LocalParticipant) => {\n handleParticipantReady(participant);\n\n if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, userId, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl: setTokenFetchUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n serverUrl={serverUrl}\n token={token}\n connect={connect}\n onConnected={handleConnectedWithFeedback}\n onDisconnected={handleDisconnectedWithFeedback}\n onError={handleError}\n roomConnected={roomConnected}\n callbacks={callbacksRef.current}\n onParticipantReady={handleParticipantReadyWithOverrides}\n sendMessage={sendMessage}\n clientTools={clientToolsRef.current}\n updateCurrentEventId={updateCurrentEventId}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\n};","export const DEFAULT_SERVER_URL = \"wss://livekit.rtc.elevenlabs.io\";\n","import { useRef, useCallback } from \"react\";\nimport type { Callbacks } from \"../types\";\n\nexport const useConversationCallbacks = () => {\n const callbacksRef = useRef<Callbacks>({});\n\n const setCallbacks = useCallback((callbacks: Callbacks) => {\n callbacksRef.current = callbacks;\n }, []);\n\n return {\n callbacksRef,\n setCallbacks,\n };\n};\n","import { useState, useCallback } from \"react\";\nimport type {\n ConversationConfig,\n ConversationStatus,\n Callbacks,\n} from \"../types\";\nimport {\n getConversationToken,\n extractConversationIdFromToken,\n} from \"../utils/tokenUtils\";\n\nexport const useConversationSession = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n setConnect: (connect: boolean) => void,\n setToken: (token: string) => void,\n setConversationId: (conversationId: string) => void,\n tokenFetchUrl?: string\n) => {\n const [overrides, setOverrides] = useState<ConversationConfig[\"overrides\"]>(\n {}\n );\n const [customLlmExtraBody, setCustomLlmExtraBody] =\n useState<ConversationConfig[\"customLlmExtraBody\"]>(null);\n const [dynamicVariables, setDynamicVariables] = useState<\n ConversationConfig[\"dynamicVariables\"]\n >({});\n const [userId, setUserId] = useState<ConversationConfig[\"userId\"]>(undefined);\n\n const startSession = useCallback(\n async (config: ConversationConfig) => {\n try {\n setStatus(\"connecting\");\n callbacksRef.current.onStatusChange?.({ status: \"connecting\" });\n\n setOverrides(config.overrides || {});\n setCustomLlmExtraBody(config.customLlmExtraBody || null);\n setDynamicVariables(config.dynamicVariables || {});\n setUserId(config.userId);\n\n let conversationToken: string;\n\n if (config.conversationToken) {\n conversationToken = config.conversationToken;\n } else if (config.agentId) {\n console.info(\n \"Getting conversation token for agentId:\",\n config.agentId\n );\n // Use tokenFetchUrl from config first, then from hook parameter, then default\n const urlToUse = config.tokenFetchUrl || tokenFetchUrl;\n conversationToken = await getConversationToken(\n config.agentId,\n urlToUse\n );\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n const extractedConversationId =\n extractConversationIdFromToken(conversationToken);\n setConversationId(extractedConversationId);\n\n setToken(conversationToken);\n setConnect(true);\n } catch (error) {\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [\n callbacksRef,\n setStatus,\n setConnect,\n setToken,\n setConversationId,\n tokenFetchUrl,\n ]\n );\n\n const endSession = useCallback(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\n\n return {\n startSession,\n endSession,\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractConversationIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n const roomId = tokenPayload.video?.room || \"\";\n\n return roomId.match(/(conv_[a-zA-Z0-9]+)/)?.[0] || \"\";\n } catch (error) {\n console.warn(\"Could not extract conversation ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string,\n tokenFetchUrl?: string\n): Promise<string> => {\n const baseUrl =\n tokenFetchUrl || \"https://api.elevenlabs.io/v1/convai/conversation/token\";\n const response = await fetch(\n `${baseUrl}?agent_id=${agentId}&source=react_native_sdk&version=${PACKAGE_VERSION}`\n );\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`Failed to get conversation token: ${data.detail.message}`);\n }\n\n if (!data.token) {\n throw new Error(\"No conversation token received from API\");\n }\n\n return data.token;\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport { AudioSession } from \"@livekit/react-native\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useLiveKitRoom = (\n callbacksRef: { current: Callbacks },\n setStatus: (status: ConversationStatus) => void,\n conversationId: string\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId });\n }, [conversationId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n }, [callbacksRef, setStatus]);\n\n const handleError = useCallback(\n (error: Error) => {\n console.error(\"LiveKit error:\", error);\n callbacksRef.current.onError?.(error.message, undefined);\n },\n [callbacksRef]\n );\n\n return {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n };\n};\n","import { useCallback } from \"react\";\nimport type { LocalParticipant } from \"livekit-client\";\nimport type { ConversationStatus, Callbacks } from \"../types\";\n\nexport const useMessageSending = (\n status: ConversationStatus,\n localParticipant: LocalParticipant | null,\n callbacksRef: { current: Callbacks }\n) => {\n const sendMessage = useCallback(\n async (message: unknown) => {\n if (status !== \"connected\" || !localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send message via WebRTC:\", error);\n console.error(\"Error details:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n },\n [status, localParticipant, callbacksRef]\n );\n\n return { sendMessage };\n};\n","import type { ConversationConfig, InitiationClientDataEvent } from \"../types\";\nimport { PACKAGE_VERSION } from \"../version\";\n\nexport function constructOverrides(\n config: ConversationConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n };\n }\n\n overridesEvent.source_info = {\n source: \"react_native_sdk\",\n version: config.overrides?.client?.version || PACKAGE_VERSION,\n };\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n if (config.userId) {\n overridesEvent.user_id = String(config.userId);\n }\n\n return overridesEvent;\n}\n"],"names":["PACKAGE_VERSION","MessageHandler","_ref","onReady","isConnected","callbacks","sendMessage","_ref$clientTools","clientTools","updateCurrentEventId","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from2","decoder","TextDecoder","message","JSON","parse","decode","payload","type","_msg$from","_msg$from3","messageText","event","user_transcription_event","user_transcript","agent_response_event","agent_response","extractMessageText","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","client_tool_call","tool_name","_temp","parameters","then","result","formattedResult","stringify","String","tool_call_id","is_error","_catch","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","reject","handleClientToolCall","onDebug","LiveKitRoomWrapper","children","createElement","LiveKitRoom","serverUrl","token","connect","audio","video","options","adaptiveStream","pixelDensity","connectOptions","rtcConfig","iceTransportPolicy","onConnected","onDisconnected","onParticipantReady","roomConnected","_excluded","ElevenLabsContext","createContext","registerGlobals","_useState","useState","setToken","_useState2","setConnect","_useState3","status","setStatus","_useState4","setServerUrl","_useState5","undefined","tokenFetchUrl","setTokenFetchUrl","_useState6","conversationId","setConversationId","_useState7","setIsSpeaking","_useState8","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","_useConversationCallb","callbacksRef","setCallbacks","useCallback","useConversationCallbacks","setCallbacksBase","wrappedCallbacks","_extends","_useConversationSessi","overrides","setOverrides","customLlmExtraBody","setCustomLlmExtraBody","dynamicVariables","setDynamicVariables","userId","setUserId","startSession","config","_temp2","_result2","extractedConversationId","_tokenPayload$video","_roomId$match","atob","split","room","match","error","console","warn","extractConversationIdFromToken","conversationToken","onStatusChange","agentId","info","fetch","response","json","data","ok","Error","detail","getConversationToken","_getConversationToken","endSession","onDisconnect","reason","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","setMicMuted","muted","setMicrophoneEnabled","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","source_info","version","client","custom_llm_extra_body","dynamic_variables","user_id","constructOverrides","getId","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,16 +1,19 @@
1
+ import type * as Types from "@elevenlabs/types";
2
+ import type { Incoming, Outgoing, Interruption, ConversationMetadata, Ping, Role as MessageRole, Mode as ConversationMode, Status, Callbacks } from "@elevenlabs/types";
3
+ export type { Callbacks } from "@elevenlabs/types";
1
4
  /**
2
5
  * Role in the conversation
3
6
  */
4
- export type Role = "user" | "ai";
7
+ export type Role = MessageRole;
5
8
  /**
6
9
  * Current mode of the conversation
7
10
  */
8
- export type Mode = "speaking" | "listening";
9
- export type ConversationStatus = "disconnected" | "connecting" | "connected";
11
+ export type Mode = ConversationMode;
12
+ export type ConversationStatus = Status;
10
13
  /**
11
14
  * Language support
12
15
  */
13
- export type Language = "en" | "ja" | "zh" | "de" | "hi" | "fr" | "ko" | "pt" | "pt-br" | "it" | "es" | "id" | "nl" | "tr" | "pl" | "sv" | "bg" | "ro" | "ar" | "cs" | "el" | "fi" | "ms" | "da" | "ta" | "uk" | "ru" | "hu" | "hr" | "sk" | "no" | "vi";
16
+ export type Language = Types.ConversationConfigOverrideAgentLanguage;
14
17
  /**
15
18
  * Client tools configuration
16
19
  */
@@ -25,31 +28,6 @@ export type ConversationOptions = {
25
28
  tokenFetchUrl?: string;
26
29
  clientTools?: Record<string, (parameters: unknown) => Promise<string | number | undefined> | string | number | undefined>;
27
30
  } & Partial<Callbacks>;
28
- /**
29
- * Callbacks configuration
30
- */
31
- export type Callbacks = {
32
- onConnect?: (props: {
33
- conversationId: string;
34
- }) => void;
35
- onDebug?: (props: unknown) => void;
36
- onDisconnect?: (details: string) => void;
37
- onError?: (message: string, context?: Record<string, unknown>) => void;
38
- onMessage?: (props: {
39
- message: ConversationEvent;
40
- source: Role;
41
- }) => void;
42
- onModeChange?: (prop: {
43
- mode: Mode;
44
- }) => void;
45
- onStatusChange?: (prop: {
46
- status: ConversationStatus;
47
- }) => void;
48
- onCanSendFeedbackChange?: (prop: {
49
- canSendFeedback: boolean;
50
- }) => void;
51
- onUnhandledClientToolCall?: (params: ClientToolCallEvent) => void;
52
- };
53
31
  export type ConversationConfig = {
54
32
  agentId?: string;
55
33
  conversationToken?: string;
@@ -77,125 +55,24 @@ export type ConversationConfig = {
77
55
  dynamicVariables?: Record<string, string | number | boolean>;
78
56
  userId?: string;
79
57
  };
80
- export type UserTranscriptionEvent = {
81
- type: "user_transcript";
82
- user_transcription_event: {
83
- user_transcript: string;
84
- };
85
- };
86
- export type AgentResponseEvent = {
87
- type: "agent_response";
88
- agent_response_event: {
89
- agent_response: string;
90
- };
91
- };
92
- export type AgentResponseCorrectionEvent = {
93
- type: "agent_response_correction";
94
- agent_response_correction_event: {
95
- original_agent_response: string;
96
- corrected_agent_response: string;
97
- };
98
- };
99
- export type AgentAudioEvent = {
100
- type: "audio";
101
- audio_event: {
102
- audio_base_64: string;
103
- event_id: number;
104
- };
105
- };
106
- export type InterruptionEvent = {
107
- type: "interruption";
108
- interruption_event: {
109
- event_id: number;
110
- };
111
- };
112
- export type InternalTentativeAgentResponseEvent = {
113
- type: "internal_tentative_agent_response";
114
- tentative_agent_response_internal_event: {
115
- tentative_agent_response: string;
116
- };
117
- };
118
- export type ConfigEvent = {
119
- type: "conversation_initiation_metadata";
120
- conversation_initiation_metadata_event: {
121
- conversation_id: string;
122
- agent_output_audio_format: string;
123
- user_input_audio_format?: string;
124
- };
125
- };
126
- export type PingEvent = {
127
- type: "ping";
128
- ping_event: {
129
- event_id: number;
130
- ping_ms?: number;
131
- };
132
- };
133
- export type ClientToolCallEvent = {
134
- type: "client_tool_call";
135
- client_tool_call: {
136
- tool_name: string;
137
- tool_call_id: string;
138
- parameters: any;
139
- expects_response: boolean;
140
- };
141
- };
142
- export type PongEvent = {
143
- type: "pong";
144
- event_id: number;
145
- };
146
- export type UserAudioEvent = {
147
- user_audio_chunk: string;
148
- };
149
- export type UserFeedbackEvent = {
150
- type: "feedback";
151
- score: "like" | "dislike";
152
- event_id: number;
153
- };
154
- export type ClientToolResultEvent = {
155
- type: "client_tool_result";
156
- tool_call_id: string;
157
- result: any;
158
- is_error: boolean;
159
- };
160
- export type ContextualUpdateEvent = {
161
- type: "contextual_update";
162
- text: string;
163
- };
164
- export type UserMessageEvent = {
165
- type: "user_message";
166
- text: string;
167
- };
168
- export type UserActivityEvent = {
169
- type: "user_activity";
170
- };
171
- export type MCPToolApprovalResultEvent = {
172
- type: "mcp_tool_approval_result";
173
- tool_call_id: string;
174
- is_approved: boolean;
175
- };
176
- export type InitiationClientDataEvent = {
177
- type: "conversation_initiation_client_data";
178
- conversation_config_override?: {
179
- agent?: {
180
- prompt?: {
181
- prompt?: string;
182
- };
183
- first_message?: string;
184
- language?: Language;
185
- };
186
- tts?: {
187
- voice_id?: string;
188
- };
189
- conversation?: {
190
- text_only?: boolean;
191
- };
192
- source_info?: {
193
- source?: string | null;
194
- version?: string | null;
195
- };
196
- };
197
- custom_llm_extra_body?: unknown;
198
- dynamic_variables?: Record<string, string | number | boolean>;
199
- user_id?: string;
200
- };
201
- export type ConversationEvent = UserTranscriptionEvent | AgentResponseEvent | AgentResponseCorrectionEvent | AgentAudioEvent | InterruptionEvent | InternalTentativeAgentResponseEvent | ConfigEvent | PingEvent | ClientToolCallEvent;
58
+ export type UserTranscriptionEvent = Incoming.UserTranscriptionClientEvent;
59
+ export type AgentResponseEvent = Incoming.AgentResponseClientEvent;
60
+ export type AgentResponseCorrectionEvent = Incoming.AgentResponseCorrectionClientEvent;
61
+ export type AgentAudioEvent = Incoming.AudioClientEvent;
62
+ export type InterruptionEvent = Interruption;
63
+ export type InternalTentativeAgentResponseEvent = Incoming.TentativeAgentResponseInternalClientEvent;
64
+ export type ConfigEvent = ConversationMetadata;
65
+ export type PingEvent = Ping;
66
+ export type ClientToolCallEvent = Incoming.ClientToolCallClientEvent;
67
+ export type VadScoreEvent = Incoming.VadScoreClientEvent;
68
+ export type MCPToolCallClientEvent = Incoming.McpToolCallClientEvent;
69
+ export type PongEvent = Outgoing.PongClientToOrchestratorEvent;
70
+ export type UserAudioEvent = Outgoing.UserAudio;
71
+ export type UserFeedbackEvent = Outgoing.UserFeedbackClientToOrchestratorEvent;
72
+ export type ClientToolResultEvent = Outgoing.ClientToolResultClientToOrchestratorEvent;
73
+ export type ContextualUpdateEvent = Outgoing.ContextualUpdateClientToOrchestratorEvent;
74
+ export type UserMessageEvent = Outgoing.UserMessageClientToOrchestratorEvent;
75
+ export type UserActivityEvent = Outgoing.UserActivityClientToOrchestratorEvent;
76
+ export type MCPToolApprovalResultEvent = Outgoing.McpToolApprovalResultClientToOrchestratorEvent;
77
+ export type InitiationClientDataEvent = Outgoing.ConversationInitiationClientToOrchestratorEvent;
78
+ export type ConversationEvent = UserTranscriptionEvent | AgentResponseEvent | AgentResponseCorrectionEvent | AgentAudioEvent | InterruptionEvent | InternalTentativeAgentResponseEvent | ConfigEvent | PingEvent | ClientToolCallEvent | VadScoreEvent | MCPToolCallClientEvent;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "0.3.0";
1
+ export declare const PACKAGE_VERSION = "0.3.2";
package/jest.config.cjs CHANGED
@@ -19,7 +19,6 @@ module.exports = {
19
19
  // TypeScript and JavaScript transformation
20
20
  transform: {
21
21
  '^.+\\.(ts|tsx)$': ['ts-jest', {
22
- isolatedModules: true,
23
22
  useESM: false,
24
23
  tsconfig: {
25
24
  target: 'ES2020',
@@ -31,6 +30,7 @@ module.exports = {
31
30
  skipLibCheck: true,
32
31
  strict: false, // Relaxed for testing
33
32
  resolveJsonModule: true,
33
+ isolatedModules: true,
34
34
  },
35
35
  }],
36
36
  '^.+\\.(js|jsx)$': 'babel-jest',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevenlabs/react-native",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "ElevenLabs React Native SDK for Conversational AI",
5
5
  "main": "./dist/lib.js",
6
6
  "module": "./dist/lib.module.js",
@@ -31,6 +31,9 @@
31
31
  "react": ">=17.0.0",
32
32
  "react-native": ">=0.70.0"
33
33
  },
34
+ "dependencies": {
35
+ "@elevenlabs/types": "0.0.1"
36
+ },
34
37
  "devDependencies": {
35
38
  "@testing-library/jest-native": "^5.4.3",
36
39
  "@testing-library/react-native": "^13.2.0",
@@ -49,15 +52,18 @@
49
52
  "url": "git+https://github.com/elevenlabs/packages.git",
50
53
  "directory": "packages/react-native"
51
54
  },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
52
58
  "scripts": {
53
59
  "generate-version": "printf \"// This file is auto-generated during build\\nexport const PACKAGE_VERSION = \\\"%s\\\";\\n\" \"$npm_package_version\" > src/version.ts",
54
- "prebuild": "npm run generate-version",
60
+ "prebuild": "pnpm run generate-version",
55
61
  "build": "BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts",
56
62
  "clean": "rm -rf ./dist",
57
- "dev": "npm run clean && npm run generate-version && BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts -w --no-compress",
58
- "lint": "npm run lint:ts && npm run lint:es && npm run lint:prettier",
59
- "lint:ts": "tsc --noEmit --skipLibCheck",
60
- "lint:es": "npx eslint .",
63
+ "dev": "pnpm run clean && pnpm run generate-version && BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts -w --no-compress",
64
+ "lint": "pnpm run check-types && pnpm run lint:es && pnpm run lint:prettier",
65
+ "check-types": "tsc --noEmit --skipLibCheck",
66
+ "lint:es": "pnpm exec eslint .",
61
67
  "lint:prettier": "prettier 'src/**/*.ts' --check",
62
68
  "test": "jest"
63
69
  }
@@ -132,6 +132,10 @@ describe('ElevenLabsProvider', () => {
132
132
  const TestComponent = () => {
133
133
  const conversation = useConversation();
134
134
 
135
+ // Suppress console.warn for sendFeedback test since canSendFeedback is false by default
136
+ const originalWarn = console.warn;
137
+ console.warn = jest.fn();
138
+
135
139
  // Test that all methods can be called safely
136
140
  expect(() => conversation.startSession({ agentId: 'test' })).not.toThrow();
137
141
  expect(() => conversation.endSession()).not.toThrow();
@@ -140,6 +144,9 @@ describe('ElevenLabsProvider', () => {
140
144
  expect(() => conversation.sendUserMessage('test message')).not.toThrow();
141
145
  expect(() => conversation.sendUserActivity()).not.toThrow();
142
146
 
147
+ // Restore console.warn
148
+ console.warn = originalWarn;
149
+
143
150
  return <TestText>Method tests passed</TestText>;
144
151
  };
145
152
 
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck - pnpm hoisting causes duplicate React type definitions
1
2
  import React from 'react';
2
3
  import { LiveKitRoom } from '@livekit/react-native';
3
4
  import type { LocalParticipant } from 'livekit-client';
@@ -45,6 +46,11 @@ export const LiveKitRoomWrapper = ({
45
46
  options={{
46
47
  adaptiveStream: { pixelDensity: 'screen' },
47
48
  }}
49
+ connectOptions={{
50
+ rtcConfig: {
51
+ iceTransportPolicy: 'relay',
52
+ },
53
+ }}
48
54
  onConnected={onConnected}
49
55
  onDisconnected={onDisconnected}
50
56
  onError={onError}
@@ -57,7 +63,7 @@ export const LiveKitRoomWrapper = ({
57
63
  clientTools={clientTools}
58
64
  updateCurrentEventId={updateCurrentEventId}
59
65
  />
60
- {children}
66
+ {children as any}
61
67
  </LiveKitRoom>
62
68
  );
63
69
  };
@@ -1,15 +1,20 @@
1
- import { useEffect } from 'react';
2
- import { useLocalParticipant, useDataChannel } from '@livekit/react-native';
3
- import type { LocalParticipant } from 'livekit-client';
4
- import type { Callbacks, ClientToolsConfig, ClientToolCallEvent, ConversationEvent } from '../types';
5
- import React from 'react';
1
+ import { useEffect } from "react";
2
+ import { useLocalParticipant, useDataChannel } from "@livekit/react-native";
3
+ import type { LocalParticipant } from "livekit-client";
4
+ import type {
5
+ Callbacks,
6
+ ClientToolsConfig,
7
+ ClientToolCallEvent,
8
+ ConversationEvent,
9
+ } from "../types";
10
+ import React from "react";
6
11
 
7
12
  interface MessageHandlerProps {
8
13
  onReady: (participant: LocalParticipant) => void;
9
14
  isConnected: boolean;
10
15
  callbacks: Callbacks;
11
16
  sendMessage: (message: unknown) => void;
12
- clientTools?: ClientToolsConfig['clientTools'];
17
+ clientTools?: ClientToolsConfig["clientTools"];
13
18
  updateCurrentEventId?: (eventId: number) => void;
14
19
  }
15
20
 
@@ -17,13 +22,24 @@ export function isValidEvent(event: any): event is ConversationEvent {
17
22
  return !!event.type;
18
23
  }
19
24
 
25
+ function extractMessageText(event: ConversationEvent): string | null {
26
+ switch (event.type) {
27
+ case "user_transcript":
28
+ return event.user_transcription_event.user_transcript;
29
+ case "agent_response":
30
+ return event.agent_response_event.agent_response;
31
+ default:
32
+ return null;
33
+ }
34
+ }
35
+
20
36
  export const MessageHandler = ({
21
37
  onReady,
22
38
  isConnected,
23
39
  callbacks,
24
40
  sendMessage,
25
41
  clientTools = {},
26
- updateCurrentEventId
42
+ updateCurrentEventId,
27
43
  }: MessageHandlerProps) => {
28
44
  const { localParticipant } = useLocalParticipant();
29
45
 
@@ -73,7 +89,7 @@ export const MessageHandler = ({
73
89
  }
74
90
  } else {
75
91
  if (callbacks.onUnhandledClientToolCall) {
76
- callbacks.onUnhandledClientToolCall(clientToolCall);
92
+ callbacks.onUnhandledClientToolCall(clientToolCall.client_tool_call);
77
93
  return;
78
94
  }
79
95
 
@@ -90,7 +106,7 @@ export const MessageHandler = ({
90
106
  }
91
107
  };
92
108
 
93
- const _ = useDataChannel((msg) => {
109
+ const _ = useDataChannel(msg => {
94
110
  const decoder = new TextDecoder();
95
111
  const message = JSON.parse(decoder.decode(msg.payload));
96
112
 
@@ -102,14 +118,17 @@ export const MessageHandler = ({
102
118
  return;
103
119
  }
104
120
 
105
- callbacks.onMessage?.({
106
- message,
107
- source: msg.from?.isAgent ? 'ai' : 'user',
108
- });
121
+ const messageText = extractMessageText(message);
122
+ if (messageText !== null) {
123
+ callbacks.onMessage?.({
124
+ message: messageText,
125
+ source: msg.from?.isAgent ? "ai" : "user",
126
+ });
127
+ }
109
128
 
110
129
  if (msg.from?.isAgent) {
111
130
  callbacks.onModeChange?.({
112
- mode: msg.from?.isSpeaking ? 'speaking' : 'listening'
131
+ mode: msg.from?.isSpeaking ? "speaking" : "listening",
113
132
  });
114
133
 
115
134
  // Track agent responses for feedback (WebRTC mode needs synthetic event IDs)
@@ -136,4 +155,4 @@ export const MessageHandler = ({
136
155
  });
137
156
 
138
157
  return null;
139
- };
158
+ };
@@ -86,7 +86,7 @@ export const useConversationSession = (
86
86
  setToken("");
87
87
  setStatus("disconnected");
88
88
  callbacksRef.current.onStatusChange?.({ status: "disconnected" });
89
- callbacksRef.current.onDisconnect?.("User ended conversation");
89
+ callbacksRef.current.onDisconnect?.({ reason: "user" });
90
90
  } catch (error) {
91
91
  callbacksRef.current.onError?.(error as string);
92
92
  throw error;
@@ -40,7 +40,7 @@ export const useLiveKitRoom = (
40
40
  setRoomConnected(false);
41
41
  setStatus("disconnected");
42
42
  setLocalParticipant(null);
43
- callbacksRef.current.onDisconnect?.("disconnected");
43
+ callbacksRef.current.onDisconnect?.({ reason: "user" });
44
44
  }, [callbacksRef, setStatus]);
45
45
 
46
46
  const handleError = useCallback(