@elevenlabs/react-native 0.5.3 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react"),require("@livekit/react-native")):"function"==typeof define&&define.amd?define(["exports","react","@livekit/react-native"],n):n((e||self).reactNative={},e.react,e.reactNative)}(this,function(e,n,t){function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=/*#__PURE__*/o(n);function a(){return a=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},a.apply(null,arguments)}var l="0.5.3",c=function(e){var o=e.onReady,a=e.isConnected,l=e.callbacks,c=e.sendMessage,s=e.clientTools,i=void 0===s?{}:s,u=e.updateCurrentEventId,d=e.onEndSession,f=t.useLocalParticipant().localParticipant,v=r.default.useRef(1);return n.useEffect(function(){a||(v.current=1)},[a]),n.useEffect(function(){a&&f&&o(f)},[a,f,o]),t.useDataChannel(function(e){var n,t=new TextDecoder,o=JSON.parse(t.decode(e.payload));if("object"==typeof(r=o)&&null!==r&&"type"in r){var r,a,s=function(e){switch(e.type){case"user_transcript":return e.user_transcription_event.user_transcript;case"agent_response":return e.agent_response_event.agent_response;default:return null}}(o);if(null!==s&&(null==l.onMessage||l.onMessage({message:s,source:"user_transcript"===o.type?"user":"ai"})),null!=(n=e.from)&&n.isAgent&&(null==l.onModeChange||l.onModeChange({mode:null!=(a=e.from)&&a.isSpeaking?"speaking":"listening"}),"agent_response"===o.type&&u)){var f=v.current++;u(f)}switch(o.type){case"ping":c({type:"pong",event_id:o.ping_event.event_id});break;case"client_tool_call":!function(e){try{return Promise.resolve(function(){if(e.client_tool_call.tool_name in i){var n=function(n,t){try{var o=Promise.resolve(i[e.client_tool_call.tool_name](e.client_tool_call.parameters)).then(function(n){var t="object"==typeof n?JSON.stringify(n):String(n);c({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:t,is_error:!1})})}catch(e){return t(e)}return o&&o.then?o.then(void 0,t):o}(0,function(n){null==l.onError||l.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.client_tool_call.tool_name}),c({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool execution failed: "+(null==n?void 0:n.message),is_error:!0})});if(n&&n.then)return n.then(function(){})}else{if(l.onUnhandledClientToolCall)return void l.onUnhandledClientToolCall(e.client_tool_call);var t="Client tool with name "+e.client_tool_call.tool_name+" is not defined on client";null==l.onError||l.onError(t,{clientToolName:e.client_tool_call.tool_name}),c({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:t,is_error:!0})}}())}catch(e){return Promise.reject(e)}}(o);break;case"audio":null==l.onAudio||l.onAudio(o.audio_event.audio_base_64);break;case"vad_score":null==l.onVadScore||l.onVadScore({vadScore:o.vad_score_event.vad_score});break;case"interruption":null==l.onInterruption||l.onInterruption(o.interruption_event);break;case"mcp_tool_call":null==l.onMCPToolCall||l.onMCPToolCall(o.mcp_tool_call);break;case"mcp_connection_status":null==l.onMCPConnectionStatus||l.onMCPConnectionStatus(o.mcp_connection_status);break;case"agent_tool_response":null==l.onAgentToolResponse||l.onAgentToolResponse(o.agent_tool_response),"end_call"===o.agent_tool_response.tool_name&&d("agent");break;case"conversation_initiation_metadata":null==l.onConversationMetadata||l.onConversationMetadata(o.conversation_initiation_metadata_event);break;case"asr_initiation_metadata":null==l.onAsrInitiationMetadata||l.onAsrInitiationMetadata(o.asr_initiation_metadata_event);break;case"agent_chat_response_part":null==l.onAgentChatResponsePart||l.onAgentChatResponsePart(o.text_response_part);break;default:null==l.onDebug||l.onDebug(o)}}else null==l.onDebug||l.onDebug({type:"invalid_event",message:o})}),null},s=function(e){var n=e.children;/*#__PURE__*/return r.default.createElement(t.LiveKitRoom,{serverUrl:e.serverUrl,token:e.token,connect:e.connect,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:e.onConnected,onDisconnected:e.onDisconnected,onError:e.onError},/*#__PURE__*/r.default.createElement(c,{onReady:e.onParticipantReady,isConnected:e.roomConnected,callbacks:e.callbacks,sendMessage:e.sendMessage,clientTools:e.clientTools,updateCurrentEventId:e.updateCurrentEventId,onEndSession:e.onEndSession}),n)},i=["serverUrl","tokenFetchUrl","clientTools"],u=/*#__PURE__*/n.createContext(null);e.ElevenLabsProvider=function(e){var o=e.children;t.registerGlobals();var c=n.useState(""),i=c[0],d=c[1],f=n.useState(!1),v=f[0],_=f[1],p=n.useState("disconnected"),h=p[0],m=p[1],C=n.useState("wss://livekit.rtc.elevenlabs.io"),g=C[0],b=C[1],k=n.useState(void 0),y=k[0],S=k[1],E=n.useState(""),P=E[0],M=E[1],T=n.useState(!1),x=T[0],w=T[1],I=n.useState(!1),R=I[0],D=I[1],U=r.default.useRef(1),F=r.default.useRef(1),A=r.default.useRef({}),j=function(){var e=n.useRef({}),t=n.useCallback(function(n){e.current=n},[]);return{callbacksRef:e,setCallbacks:t}}(),L=j.callbacksRef,N=j.setCallbacks,O=r.default.useCallback(function(e){var n=a({},e,{onModeChange:function(n){w("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});N(n)},[N]),V=function(e,t,o,r,a,c){var s=n.useState({}),i=s[0],u=s[1],d=n.useState(null),f=d[0],v=d[1],_=n.useState({}),p=_[0],h=_[1],m=n.useState(void 0),C=m[0],g=m[1];return{startSession:n.useCallback(function(n){try{return Promise.resolve(function(s,i){try{var d=function(){function s(e){var n=function(e){try{var n,t;return(null==(t=((null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||"").match(/(conv_[a-zA-Z0-9]+)/))?void 0:t[0])||""}catch(e){return console.warn("Could not extract conversation ID from token"),""}}(i);a(n),r(i),o(!0)}var i;t("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),u(n.overrides||{}),v(n.customLlmExtraBody||null),h(n.dynamicVariables||{}),g(n.userId);var d=function(){if(!n.conversationToken)return function(){if(n.agentId)return console.info("Getting conversation token for agentId:",n.agentId),Promise.resolve(function(e,n){try{return Promise.resolve(fetch((n||"https://api.elevenlabs.io/v1/convai/conversation/token")+"?agent_id="+e+"&source=react_native_sdk&version="+l)).then(function(e){return Promise.resolve(e.json()).then(function(n){if(!e.ok)throw new Error("Failed to get conversation token: "+n.detail.message);if(!n.token)throw new Error("No conversation token received from API");return n.token})})}catch(e){return Promise.reject(e)}}(n.agentId,n.tokenFetchUrl||c)).then(function(e){i=e});throw new Error("Either conversationToken or agentId is required")}();i=n.conversationToken}();return d&&d.then?d.then(s):s()}()}catch(e){return i(e)}return d&&d.then?d.then(void 0,i):d}(0,function(n){throw t("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(n),n}))}catch(e){return Promise.reject(e)}},[e,t,o,r,a,c]),endSession:n.useCallback(function(n){void 0===n&&(n="user");try{try{o(!1),r(""),t("disconnected"),u({}),v(null),h({}),g(void 0),a(""),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onDisconnect||e.current.onDisconnect({reason:n})}catch(n){throw null==e.current.onError||e.current.onError(n),n}return Promise.resolve()}catch(e){return Promise.reject(e)}},[e,o,r,t,a]),overrides:i,customLlmExtraBody:f,dynamicVariables:p,userId:C}}(L,m,_,d,M,y),B=V.startSession,J=V.endSession,q=V.overrides,K=V.customLlmExtraBody,G=V.dynamicVariables,z=V.userId,W=function(e,o,r,a){var l=n.useState(!1),c=l[0],s=l[1],i=n.useState(null),u=i[0],d=i[1],f=n.useRef(!1);n.useEffect(function(){r&&(s(!1),d(null),f.current=!1)},[r]),n.useEffect(function(){return function(){try{return Promise.resolve(t.AudioSession.startAudioSession()).then(function(){})}catch(e){return Promise.reject(e)}}(),function(){t.AudioSession.stopAudioSession()}},[]),n.useEffect(function(){u&&c&&!f.current&&(f.current=!0,null==e.current.onConnect||e.current.onConnect({conversationId:r}))},[u,c,r,e]);var v=n.useCallback(function(e){u||(d(e),o("connected"))},[u,o]),_=n.useCallback(function(){s(!0)},[]),p=n.useCallback(function(){"disconnected"!==a&&(s(!1),o("disconnected"),d(null),f.current=!1,null==e.current.onDisconnect||e.current.onDisconnect({reason:"user"}))},[e,o,a]),h=n.useCallback(function(n){console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e]);return{roomConnected:c,localParticipant:u,handleParticipantReady:v,handleConnected:_,handleDisconnected:p,handleError:h}}(L,m,P,h),Z=W.roomConnected,H=W.localParticipant,Q=W.handleParticipantReady,X=W.handleConnected,Y=W.handleDisconnected,$=W.handleError,ee=r.default.useCallback(function(){U.current=1,F.current=1,D(!1),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:!1}),X()},[X,L]),ne=r.default.useCallback(function(){D(!1),w(!1),Y()},[Y]),te=function(e,t,o){return{sendMessage:n.useCallback(function(n){try{if("connected"!==e||!t)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();var r=function(e,o){try{var r=(a=(new TextEncoder).encode(JSON.stringify(n)),Promise.resolve(t.publishData(a,{reliable:!0})).then(function(){}))}catch(e){return o(e)}var a;return r&&r.then?r.then(void 0,o):r}(0,function(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==o.current.onError||o.current.onError(e)});return Promise.resolve(r&&r.then?r.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},[e,t,o])}}(h,H,L),oe=te.sendMessage,re=r.default.useCallback(function(){var e=U.current!==F.current;R!==e&&(D(e),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:e}))},[R,L]),ae=r.default.useCallback(function(e){R?(oe({type:"feedback",score:e?"like":"dislike",event_id:U.current}),F.current=U.current,re()):console.warn(0===F.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[R,oe,re]);r.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var le=r.default.useCallback(function(){return P},[P]),ce=r.default.useCallback(function(e){H&&H.setMicrophoneEnabled(!e)},[H]),se=r.default.useCallback(function(e){U.current=e,re()},[re]),ie=r.default.useCallback(function(e){Q(e);var n=function(e){var n,t,o,r,a,c,s={type:"conversation_initiation_client_data"};return e.overrides&&(s.conversation_config_override={agent:{prompt:null==(t=e.overrides.agent)?void 0:t.prompt,first_message:null==(o=e.overrides.agent)?void 0:o.firstMessage,language:null==(r=e.overrides.agent)?void 0:r.language},tts:{voice_id:null==(a=e.overrides.tts)?void 0:a.voiceId},conversation:{text_only:null==(c=e.overrides.conversation)?void 0:c.textOnly}}),s.source_info={source:"react_native_sdk",version:(null==(n=e.overrides)||null==(n=n.client)?void 0:n.version)||l},e.customLlmExtraBody&&(s.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(s.dynamic_variables=e.dynamicVariables),e.userId&&(s.user_id=String(e.userId)),s}({overrides:q,customLlmExtraBody:K,dynamicVariables:G,userId:z});if(n)try{var t=(new TextEncoder).encode(JSON.stringify(n));e.publishData(t,{reliable:!0})}catch(e){console.error("Failed to send overrides:",e),null==L.current.onError||L.current.onError(e)}},[Q,q,K,G,z,L]),ue=r.default.useCallback(function(e){A.current=e},[]),de=r.default.useCallback(function(e){oe({type:"contextual_update",text:e})},[oe]),fe=r.default.useCallback(function(e){oe({type:"user_message",text:e})},[oe]),ve=r.default.useCallback(function(){oe({type:"user_activity"})},[oe]),_e=r.default.useMemo(function(){return{startSession:B,endSession:J,status:h,isSpeaking:x,canSendFeedback:R,getId:le,setMicMuted:ce,sendFeedback:ae,sendContextualUpdate:de,sendUserMessage:fe,sendUserActivity:ve}},[B,J,h,x,R,le,ce,ae,de,fe,ve]),pe=r.default.useMemo(function(){return{conversation:_e,callbacksRef:L,serverUrl:g,tokenFetchUrl:y,clientTools:A.current,setCallbacks:O,setServerUrl:b,setTokenFetchUrl:S,setClientTools:ue}},[_e,L,g,y,O,ue]);/*#__PURE__*/return r.default.createElement(u.Provider,{value:pe},/*#__PURE__*/r.default.createElement(s,{key:P||"disconnected",serverUrl:g,token:i,connect:v,onConnected:ee,onDisconnected:ne,onError:$,roomConnected:Z,callbacks:L.current,onParticipantReady:ie,sendMessage:oe,clientTools:A.current,updateCurrentEventId:se,onEndSession:J},o))},e.useConversation=function(e){void 0===e&&(e={});var t=n.useContext(u);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");var o=e.serverUrl,a=e.tokenFetchUrl,l=e.clientTools,c=function(e,n){if(null==e)return{};var t={};for(var o in e)if({}.hasOwnProperty.call(e,o)){if(-1!==n.indexOf(o))continue;t[o]=e[o]}return t}(e,i);return r.default.useEffect(function(){o&&t.setServerUrl(o)},[t,o]),r.default.useEffect(function(){a&&t.setTokenFetchUrl(a)},[t,a]),r.default.useEffect(function(){l&&t.setClientTools(l)},[t,l]),t.setCallbacks(c),t.conversation}});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react"),require("@livekit/react-native"),require("livekit-client")):"function"==typeof define&&define.amd?define(["exports","react","@livekit/react-native","livekit-client"],n):n((e||self).reactNative={},e.react,e.reactNative,e.livekitClient)}(this,function(e,n,t,r){function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=/*#__PURE__*/o(n);function c(){return c=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},c.apply(null,arguments)}var l="0.5.5",i=function(e){var o=e.onReady,c=e.isConnected,l=e.callbacks,i=e.sendMessage,s=e.clientTools,u=void 0===s?{}:s,d=e.updateCurrentEventId,f=e.onEndSession,v=t.useLocalParticipant().localParticipant,_=t.useRoomContext(),p=a.default.useRef(1),g=a.default.useRef(f);g.current=f;var m=a.default.useRef(o);m.current=o;var h=a.default.useRef(l);return h.current=l,n.useEffect(function(){var e=function(e){var n;null!=(n=e.identity)&&n.startsWith("agent")&&g.current("agent")};return _.on(r.RoomEvent.ParticipantDisconnected,e),function(){_.off(r.RoomEvent.ParticipantDisconnected,e)}},[_]),n.useEffect(function(){c||(p.current=1)},[c]),n.useEffect(function(){c&&v&&m.current(v)},[c,v]),t.useDataChannel(function(e){var n,t=new TextDecoder,r=JSON.parse(t.decode(e.payload));if("object"==typeof(o=r)&&null!==o&&"type"in o){var o,a,c=function(e){switch(e.type){case"user_transcript":return e.user_transcription_event.user_transcript;case"agent_response":return e.agent_response_event.agent_response;default:return null}}(r);if(null!==c&&(null==h.current.onMessage||h.current.onMessage({message:c,source:"user_transcript"===r.type?"user":"ai",role:"user_transcript"===r.type?"user":"agent"})),null!=(n=e.from)&&n.isAgent&&(null==h.current.onModeChange||h.current.onModeChange({mode:null!=(a=e.from)&&a.isSpeaking?"speaking":"listening"}),"agent_response"===r.type&&d)){var l=p.current++;d(l)}switch(r.type){case"ping":i({type:"pong",event_id:r.ping_event.event_id});break;case"client_tool_call":!function(e){try{return Promise.resolve(function(){if(e.client_tool_call.tool_name in u){var n=function(n,t){try{var r=Promise.resolve(u[e.client_tool_call.tool_name](e.client_tool_call.parameters)).then(function(n){var t="object"==typeof n?JSON.stringify(n):String(n);i({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:t,is_error:!1})})}catch(e){return t(e)}return r&&r.then?r.then(void 0,t):r}(0,function(n){null==h.current.onError||h.current.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.client_tool_call.tool_name}),i({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:"Client tool execution failed: "+(null==n?void 0:n.message),is_error:!0})});if(n&&n.then)return n.then(function(){})}else{if(h.current.onUnhandledClientToolCall)return void h.current.onUnhandledClientToolCall(e.client_tool_call);var t="Client tool with name "+e.client_tool_call.tool_name+" is not defined on client";null==h.current.onError||h.current.onError(t,{clientToolName:e.client_tool_call.tool_name}),i({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:t,is_error:!0})}}())}catch(e){return Promise.reject(e)}}(r);break;case"audio":null==h.current.onAudio||h.current.onAudio(r.audio_event.audio_base_64);break;case"vad_score":null==h.current.onVadScore||h.current.onVadScore({vadScore:r.vad_score_event.vad_score});break;case"interruption":null==h.current.onInterruption||h.current.onInterruption(r.interruption_event);break;case"mcp_tool_call":null==h.current.onMCPToolCall||h.current.onMCPToolCall(r.mcp_tool_call);break;case"mcp_connection_status":null==h.current.onMCPConnectionStatus||h.current.onMCPConnectionStatus(r.mcp_connection_status);break;case"agent_tool_request":null==h.current.onAgentToolRequest||h.current.onAgentToolRequest(r.agent_tool_request);break;case"agent_tool_response":null==h.current.onAgentToolResponse||h.current.onAgentToolResponse(r.agent_tool_response),"end_call"===r.agent_tool_response.tool_name&&g.current("agent");break;case"conversation_initiation_metadata":null==h.current.onConversationMetadata||h.current.onConversationMetadata(r.conversation_initiation_metadata_event);break;case"asr_initiation_metadata":null==h.current.onAsrInitiationMetadata||h.current.onAsrInitiationMetadata(r.asr_initiation_metadata_event);break;case"agent_chat_response_part":null==h.current.onAgentChatResponsePart||h.current.onAgentChatResponsePart(r.text_response_part);break;default:null==h.current.onDebug||h.current.onDebug(r)}}else null==h.current.onDebug||h.current.onDebug({type:"invalid_event",message:r})}),null},s=function(e){var n=e.children;/*#__PURE__*/return a.default.createElement(t.LiveKitRoom,{serverUrl:e.serverUrl,token:e.token,connect:e.connect,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:e.onConnected,onDisconnected:e.onDisconnected,onError:e.onError},/*#__PURE__*/a.default.createElement(i,{onReady:e.onParticipantReady,isConnected:e.roomConnected,callbacks:e.callbacks,sendMessage:e.sendMessage,clientTools:e.clientTools,updateCurrentEventId:e.updateCurrentEventId,onEndSession:e.onEndSession}),n)},u=["serverUrl","tokenFetchUrl","clientTools"],d=/*#__PURE__*/n.createContext(null);e.ElevenLabsProvider=function(e){var r=e.children;t.registerGlobals();var o=n.useState(""),i=o[0],u=o[1],f=n.useState(!1),v=f[0],_=f[1],p=n.useState("disconnected"),g=p[0],m=p[1],h=n.useState("wss://livekit.rtc.elevenlabs.io"),C=h[0],b=h[1],k=n.useState(void 0),y=k[0],E=k[1],S=n.useState(""),P=S[0],R=S[1],T=n.useState(!1),x=T[0],M=T[1],w=n.useState(!1),I=w[0],D=w[1],U=a.default.useRef(1),A=a.default.useRef(1),F=a.default.useRef({}),j=function(){var e=n.useRef({}),t=n.useCallback(function(n){e.current=n},[]);return{callbacksRef:e,setCallbacks:t}}(),L=j.callbacksRef,N=j.setCallbacks,O=a.default.useCallback(function(e){var n=c({},e,{onModeChange:function(n){M("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});N(n)},[N]),V=function(e,t,r,o,a,c){var i=n.useState({}),s=i[0],u=i[1],d=n.useState(null),f=d[0],v=d[1],_=n.useState({}),p=_[0],g=_[1],m=n.useState(void 0),h=m[0],C=m[1];return{startSession:n.useCallback(function(n){try{return Promise.resolve(function(i,s){try{var d=function(){function i(e){var n=function(e){try{var n,t;return(null==(t=((null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||"").match(/(conv_[a-zA-Z0-9]+)/))?void 0:t[0])||""}catch(e){return console.warn("Could not extract conversation ID from token"),""}}(s);a(n),o(s),r(!0)}var s;t("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),u(n.overrides||{}),v(n.customLlmExtraBody||null),g(n.dynamicVariables||{}),C(n.userId);var d=function(){if(!n.conversationToken)return function(){if(n.agentId)return console.info("Getting conversation token for agentId:",n.agentId),Promise.resolve(function(e,n){try{return Promise.resolve(fetch((n||"https://api.elevenlabs.io/v1/convai/conversation/token")+"?agent_id="+e+"&source=react_native_sdk&version="+l)).then(function(e){return Promise.resolve(e.json()).then(function(n){if(!e.ok)throw new Error("Failed to get conversation token: "+n.detail.message);if(!n.token)throw new Error("No conversation token received from API");return n.token})})}catch(e){return Promise.reject(e)}}(n.agentId,n.tokenFetchUrl||c)).then(function(e){s=e});throw new Error("Either conversationToken or agentId is required")}();s=n.conversationToken}();return d&&d.then?d.then(i):i()}()}catch(e){return s(e)}return d&&d.then?d.then(void 0,s):d}(0,function(n){throw t("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(n),n}))}catch(e){return Promise.reject(e)}},[e,t,r,o,a,c]),endSession:n.useCallback(function(n){void 0===n&&(n="user");try{try{r(!1),o(""),t("disconnected"),u({}),v(null),g({}),C(void 0),a(""),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onDisconnect||e.current.onDisconnect({reason:n})}catch(n){throw null==e.current.onError||e.current.onError(n),n}return Promise.resolve()}catch(e){return Promise.reject(e)}},[e,r,o,t,a]),overrides:s,customLlmExtraBody:f,dynamicVariables:p,userId:h}}(L,m,_,u,R,y),q=V.startSession,B=V.endSession,J=V.overrides,K=V.customLlmExtraBody,G=V.dynamicVariables,W=V.userId,z=function(e,r,o,a){var c=n.useState(!1),l=c[0],i=c[1],s=n.useState(null),u=s[0],d=s[1],f=n.useRef(!1);n.useEffect(function(){o&&(i(!1),d(null),f.current=!1)},[o]),n.useEffect(function(){return function(){try{return Promise.resolve(t.AudioSession.startAudioSession()).then(function(){})}catch(e){return Promise.reject(e)}}(),function(){t.AudioSession.stopAudioSession()}},[]),n.useEffect(function(){u&&l&&!f.current&&(f.current=!0,null==e.current.onConnect||e.current.onConnect({conversationId:o}))},[u,l,o,e]);var v=n.useCallback(function(e){u||(d(e),r("connected"))},[u,r]),_=n.useCallback(function(){i(!0)},[]),p=n.useCallback(function(){"disconnected"!==a&&(i(!1),r("disconnected"),d(null),f.current=!1,null==e.current.onDisconnect||e.current.onDisconnect({reason:"user"}))},[e,r,a]),g=n.useCallback(function(n){console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e]);return{roomConnected:l,localParticipant:u,handleParticipantReady:v,handleConnected:_,handleDisconnected:p,handleError:g}}(L,m,P,g),Z=z.roomConnected,H=z.localParticipant,Q=z.handleParticipantReady,X=z.handleConnected,Y=z.handleDisconnected,$=z.handleError,ee=a.default.useCallback(function(){U.current=1,A.current=1,D(!1),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:!1}),X()},[X,L]),ne=a.default.useCallback(function(){D(!1),M(!1),Y()},[Y]),te=function(e,t,r){return{sendMessage:n.useCallback(function(n){try{if("connected"!==e||!t)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();var o=function(e,r){try{var o=(a=(new TextEncoder).encode(JSON.stringify(n)),Promise.resolve(t.publishData(a,{reliable:!0})).then(function(){}))}catch(e){return r(e)}var a;return o&&o.then?o.then(void 0,r):o}(0,function(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==r.current.onError||r.current.onError(e)});return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},[e,t,r])}}(g,H,L),re=te.sendMessage,oe=a.default.useCallback(function(){var e=U.current!==A.current;I!==e&&(D(e),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:e}))},[I,L]),ae=a.default.useCallback(function(e){I?(re({type:"feedback",score:e?"like":"dislike",event_id:U.current}),A.current=U.current,oe()):console.warn(0===A.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[I,re,oe]);a.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var ce=a.default.useCallback(function(){return P},[P]),le=a.default.useCallback(function(e){H&&H.setMicrophoneEnabled(!e)},[H]),ie=a.default.useCallback(function(e){U.current=e,oe()},[oe]),se=a.default.useCallback(function(e){Q(e);var n=function(e){var n,t,r,o,a,c,i={type:"conversation_initiation_client_data"};return e.overrides&&(i.conversation_config_override={agent:{prompt:null==(t=e.overrides.agent)?void 0:t.prompt,first_message:null==(r=e.overrides.agent)?void 0:r.firstMessage,language:null==(o=e.overrides.agent)?void 0:o.language},tts:{voice_id:null==(a=e.overrides.tts)?void 0:a.voiceId},conversation:{text_only:null==(c=e.overrides.conversation)?void 0:c.textOnly}}),i.source_info={source:"react_native_sdk",version:(null==(n=e.overrides)||null==(n=n.client)?void 0:n.version)||l},e.customLlmExtraBody&&(i.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(i.dynamic_variables=e.dynamicVariables),e.userId&&(i.user_id=String(e.userId)),i}({overrides:J,customLlmExtraBody:K,dynamicVariables:G,userId:W});if(n)try{var t=(new TextEncoder).encode(JSON.stringify(n));e.publishData(t,{reliable:!0})}catch(e){console.error("Failed to send overrides:",e),null==L.current.onError||L.current.onError(e)}},[Q,J,K,G,W,L]),ue=a.default.useCallback(function(e){F.current=e},[]),de=a.default.useCallback(function(e){re({type:"contextual_update",text:e})},[re]),fe=a.default.useCallback(function(e){re({type:"user_message",text:e})},[re]),ve=a.default.useCallback(function(){re({type:"user_activity"})},[re]),_e=a.default.useMemo(function(){return{startSession:q,endSession:B,status:g,isSpeaking:x,canSendFeedback:I,getId:ce,setMicMuted:le,sendFeedback:ae,sendContextualUpdate:de,sendUserMessage:fe,sendUserActivity:ve}},[q,B,g,x,I,ce,le,ae,de,fe,ve]),pe=a.default.useMemo(function(){return{conversation:_e,callbacksRef:L,serverUrl:C,tokenFetchUrl:y,clientTools:F.current,setCallbacks:O,setServerUrl:b,setTokenFetchUrl:E,setClientTools:ue}},[_e,L,C,y,O,ue]);/*#__PURE__*/return a.default.createElement(d.Provider,{value:pe},/*#__PURE__*/a.default.createElement(s,{key:P||"disconnected",serverUrl:C,token:i,connect:v,onConnected:ee,onDisconnected:ne,onError:$,roomConnected:Z,callbacks:L.current,onParticipantReady:se,sendMessage:re,clientTools:F.current,updateCurrentEventId:ie,onEndSession:B},r))},e.useConversation=function(e){void 0===e&&(e={});var t=n.useContext(d);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");var r=e.serverUrl,o=e.tokenFetchUrl,c=e.clientTools,l=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,u);return a.default.useEffect(function(){r&&t.setServerUrl(r)},[t,r]),a.default.useEffect(function(){o&&t.setTokenFetchUrl(o)},[t,o]),a.default.useEffect(function(){c&&t.setClientTools(c)},[t,c]),t.setCallbacks(l),t.conversation}});
2
2
  //# sourceMappingURL=lib.umd.js.map
@@ -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.5.3\";\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 onEndSession: (reason: \"user\" | \"agent\") => void;\n clientTools?: ClientToolsConfig[\"clientTools\"];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: unknown): event is ConversationEvent {\n return typeof event === \"object\" && event !== null && \"type\" in event;\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 onEndSession,\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 // Reset agent response count when connection status changes\n useEffect(() => {\n if (!isConnected) {\n agentResponseCountRef.current = 1;\n }\n }, [isConnected]);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (clientToolCall.client_tool_call.tool_name in clientTools) {\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: message.type === \"user_transcript\" ? \"user\" : \"ai\",\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 case \"audio\":\n callbacks.onAudio?.(message.audio_event.audio_base_64);\n break;\n case \"vad_score\":\n callbacks.onVadScore?.({\n vadScore: message.vad_score_event.vad_score,\n });\n break;\n case \"interruption\":\n callbacks.onInterruption?.(message.interruption_event);\n break;\n case \"mcp_tool_call\":\n callbacks.onMCPToolCall?.(message.mcp_tool_call);\n break;\n case \"mcp_connection_status\":\n callbacks.onMCPConnectionStatus?.(message.mcp_connection_status);\n break;\n case \"agent_tool_response\":\n callbacks.onAgentToolResponse?.(message.agent_tool_response);\n\n if (message.agent_tool_response.tool_name === \"end_call\") {\n // End the call\n onEndSession(\"agent\");\n }\n break;\n case \"conversation_initiation_metadata\":\n callbacks.onConversationMetadata?.(\n message.conversation_initiation_metadata_event\n );\n break;\n case \"asr_initiation_metadata\":\n callbacks.onAsrInitiationMetadata?.(\n message.asr_initiation_metadata_event\n );\n break;\n case \"agent_chat_response_part\":\n callbacks.onAgentChatResponsePart?.(message.text_response_part);\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 onEndSession: (reason?: \"user\" | \"agent\") => void;\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 onEndSession,\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 onEndSession={onEndSession}\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: (reason?: \"user\" | \"agent\") => 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 React.useEffect(() => {\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n }, [context, clientTools]);\n\n // Update callbacks - since this only updates a ref, it's safe to call on every render\n // and doesn't cause re-renders of the provider or its consumers\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, status);\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 setIsSpeaking(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 = React.useCallback(() => conversationId, [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 const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n\n if (overridesEvent) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(overridesEvent));\n participant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send overrides:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n }\n }, [handleParticipantReady, overrides, customLlmExtraBody, dynamicVariables, userId, callbacksRef]);\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n // Memoize inline callback functions\n const sendContextualUpdate = React.useCallback((text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n }, [sendMessage]);\n\n const sendUserMessage = React.useCallback((text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n }, [sendMessage]);\n\n const sendUserActivity = React.useCallback(() => {\n sendMessage({\n type: \"user_activity\",\n });\n }, [sendMessage]);\n\n // Memoize the conversation object to prevent unnecessary re-renders\n const conversation = React.useMemo<Conversation>(() => ({\n startSession,\n endSession,\n status,\n isSpeaking,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate,\n sendUserMessage,\n sendUserActivity,\n }), [\n startSession,\n endSession,\n status,\n isSpeaking,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate,\n sendUserMessage,\n sendUserActivity,\n ]);\n\n // Memoize the context value to prevent unnecessary re-renders of consumers\n const contextValue = React.useMemo<ElevenLabsContextType>(() => ({\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl,\n setClientTools,\n }), [\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n setCallbacks,\n setClientTools,\n ]);\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n key={conversationId || 'disconnected'}\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 onEndSession={endSession}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\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(\n async (reason: \"user\" | \"agent\" = \"user\") => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n\n // Reset session configuration state\n setOverrides({});\n setCustomLlmExtraBody(null);\n setDynamicVariables({});\n setUserId(undefined);\n setConversationId(\"\");\n\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.({ reason });\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [callbacksRef, setConnect, setToken, setStatus, setConversationId]\n );\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, useRef } 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 status: ConversationStatus\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n const hasCalledOnConnectRef = useRef(false);\n\n // Reset room state when conversationId changes (new session starting)\n useEffect(() => {\n if (conversationId) {\n setRoomConnected(false);\n setLocalParticipant(null);\n hasCalledOnConnectRef.current = false;\n }\n }, [conversationId]);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n // Fire onConnect when both participant and room are fully ready\n useEffect(() => {\n if (localParticipant && roomConnected && !hasCalledOnConnectRef.current) {\n hasCalledOnConnectRef.current = true;\n callbacksRef.current.onConnect?.({ conversationId });\n }\n }, [localParticipant, roomConnected, conversationId, callbacksRef]);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n if (localParticipant) {\n return;\n }\n\n setLocalParticipant(participant);\n setStatus(\"connected\");\n },\n [localParticipant, setStatus]\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n }, []);\n\n const handleDisconnected = useCallback(() => {\n // If already disconnected, endSession already handled the disconnect callback\n if (status === \"disconnected\") {\n return;\n }\n\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n hasCalledOnConnectRef.current = false;\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n }, [callbacksRef, setStatus, status]);\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","onEndSession","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","current","useDataChannel","msg","_msg$from","decoder","TextDecoder","message","JSON","parse","decode","payload","event","_msg$from2","messageText","type","user_transcription_event","user_transcript","agent_response_event","agent_response","extractMessageText","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","eventId","event_id","ping_event","clientToolCall","Promise","resolve","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","onAudio","audio_event","audio_base_64","onVadScore","vadScore","vad_score_event","vad_score","onInterruption","interruption_event","onMCPToolCall","mcp_tool_call","onMCPConnectionStatus","mcp_connection_status","onAgentToolResponse","agent_tool_response","onConversationMetadata","conversation_initiation_metadata_event","onAsrInitiationMetadata","asr_initiation_metadata_event","onAgentChatResponsePart","text_response_part","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","_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","reason","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","hasCalledOnConnectRef","AudioSession","startAudioSession","start","stopAudioSession","onConnect","handleParticipantReady","participant","handleConnected","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","getId","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","setClientTools","tools","sendContextualUpdate","text","sendUserMessage","sendUserActivity","useMemo","contextValue","Provider","value","key","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.5.5\";\n","import { useEffect } from \"react\";\nimport { useLocalParticipant, useDataChannel, useRoomContext } from \"@livekit/react-native\";\nimport { RoomEvent } from \"livekit-client\";\nimport type { LocalParticipant, RemoteParticipant } 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 onEndSession: (reason: \"user\" | \"agent\") => void;\n clientTools?: ClientToolsConfig[\"clientTools\"];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: unknown): event is ConversationEvent {\n return typeof event === \"object\" && event !== null && \"type\" in event;\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 onEndSession,\n}: MessageHandlerProps) => {\n const { localParticipant } = useLocalParticipant();\n const room = useRoomContext();\n\n // Track agent response count for synthetic event IDs (WebRTC mode)\n const agentResponseCountRef = React.useRef(1);\n\n // Refs for callbacks to avoid unnecessary effect re-runs\n const onEndSessionRef = React.useRef(onEndSession);\n onEndSessionRef.current = onEndSession;\n const onReadyRef = React.useRef(onReady);\n onReadyRef.current = onReady;\n const callbacksRef = React.useRef(callbacks);\n callbacksRef.current = callbacks;\n\n // Detect agent disconnection\n useEffect(() => {\n const handleParticipantDisconnected = (participant: RemoteParticipant) => {\n if (participant.identity?.startsWith(\"agent\")) {\n onEndSessionRef.current(\"agent\");\n }\n };\n\n room.on(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);\n\n return () => {\n room.off(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);\n };\n }, [room]);\n\n // Reset agent response count when connection status changes\n useEffect(() => {\n if (!isConnected) {\n agentResponseCountRef.current = 1;\n }\n }, [isConnected]);\n\n useEffect(() => {\n if (isConnected && localParticipant) {\n onReadyRef.current(localParticipant);\n }\n }, [isConnected, localParticipant]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (clientToolCall.client_tool_call.tool_name in clientTools) {\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 callbacksRef.current.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 (callbacksRef.current.onUnhandledClientToolCall) {\n callbacksRef.current.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 callbacksRef.current.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 callbacksRef.current.onDebug?.({\n type: \"invalid_event\",\n message,\n });\n return;\n }\n\n const messageText = extractMessageText(message);\n if (messageText !== null) {\n callbacksRef.current.onMessage?.({\n message: messageText,\n source: message.type === \"user_transcript\" ? \"user\" : \"ai\",\n role: message.type === \"user_transcript\" ? \"user\" : \"agent\",\n });\n }\n\n if (msg.from?.isAgent) {\n callbacksRef.current.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 case \"audio\":\n callbacksRef.current.onAudio?.(message.audio_event.audio_base_64);\n break;\n case \"vad_score\":\n callbacksRef.current.onVadScore?.({\n vadScore: message.vad_score_event.vad_score,\n });\n break;\n case \"interruption\":\n callbacksRef.current.onInterruption?.(message.interruption_event);\n break;\n case \"mcp_tool_call\":\n callbacksRef.current.onMCPToolCall?.(message.mcp_tool_call);\n break;\n case \"mcp_connection_status\":\n callbacksRef.current.onMCPConnectionStatus?.(message.mcp_connection_status);\n break;\n case \"agent_tool_request\":\n callbacksRef.current.onAgentToolRequest?.(message.agent_tool_request);\n break;\n case \"agent_tool_response\":\n callbacksRef.current.onAgentToolResponse?.(message.agent_tool_response);\n\n if (message.agent_tool_response.tool_name === \"end_call\") {\n // End the call\n onEndSessionRef.current(\"agent\");\n }\n break;\n case \"conversation_initiation_metadata\":\n callbacksRef.current.onConversationMetadata?.(\n message.conversation_initiation_metadata_event\n );\n break;\n case \"asr_initiation_metadata\":\n callbacksRef.current.onAsrInitiationMetadata?.(\n message.asr_initiation_metadata_event\n );\n break;\n case \"agent_chat_response_part\":\n callbacksRef.current.onAgentChatResponsePart?.(message.text_response_part);\n break;\n default:\n callbacksRef.current.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 onEndSession: (reason?: \"user\" | \"agent\") => void;\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 onEndSession,\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 onEndSession={onEndSession}\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: (reason?: \"user\" | \"agent\") => 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 React.useEffect(() => {\n if (clientTools) {\n context.setClientTools(clientTools);\n }\n }, [context, clientTools]);\n\n // Update callbacks - since this only updates a ref, it's safe to call on every render\n // and doesn't cause re-renders of the provider or its consumers\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, status);\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 setIsSpeaking(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 = React.useCallback(() => conversationId, [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 const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n\n if (overridesEvent) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(overridesEvent));\n participant.publishData(data, { reliable: true });\n } catch (error) {\n console.error(\"Failed to send overrides:\", error);\n callbacksRef.current.onError?.(error as string);\n }\n }\n }, [handleParticipantReady, overrides, customLlmExtraBody, dynamicVariables, userId, callbacksRef]);\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n // Memoize inline callback functions\n const sendContextualUpdate = React.useCallback((text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n }, [sendMessage]);\n\n const sendUserMessage = React.useCallback((text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n }, [sendMessage]);\n\n const sendUserActivity = React.useCallback(() => {\n sendMessage({\n type: \"user_activity\",\n });\n }, [sendMessage]);\n\n // Memoize the conversation object to prevent unnecessary re-renders\n const conversation = React.useMemo<Conversation>(() => ({\n startSession,\n endSession,\n status,\n isSpeaking,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate,\n sendUserMessage,\n sendUserActivity,\n }), [\n startSession,\n endSession,\n status,\n isSpeaking,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate,\n sendUserMessage,\n sendUserActivity,\n ]);\n\n // Memoize the context value to prevent unnecessary re-renders of consumers\n const contextValue = React.useMemo<ElevenLabsContextType>(() => ({\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl,\n setClientTools,\n }), [\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n setCallbacks,\n setClientTools,\n ]);\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\n key={conversationId || 'disconnected'}\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 onEndSession={endSession}\n >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\n );\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(\n async (reason: \"user\" | \"agent\" = \"user\") => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n\n // Reset session configuration state\n setOverrides({});\n setCustomLlmExtraBody(null);\n setDynamicVariables({});\n setUserId(undefined);\n setConversationId(\"\");\n\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.({ reason });\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n },\n [callbacksRef, setConnect, setToken, setStatus, setConversationId]\n );\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, useRef } 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 status: ConversationStatus\n) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n const hasCalledOnConnectRef = useRef(false);\n\n // Reset room state when conversationId changes (new session starting)\n useEffect(() => {\n if (conversationId) {\n setRoomConnected(false);\n setLocalParticipant(null);\n hasCalledOnConnectRef.current = false;\n }\n }, [conversationId]);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n // Fire onConnect when both participant and room are fully ready\n useEffect(() => {\n if (localParticipant && roomConnected && !hasCalledOnConnectRef.current) {\n hasCalledOnConnectRef.current = true;\n callbacksRef.current.onConnect?.({ conversationId });\n }\n }, [localParticipant, roomConnected, conversationId, callbacksRef]);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n if (localParticipant) {\n return;\n }\n\n setLocalParticipant(participant);\n setStatus(\"connected\");\n },\n [localParticipant, setStatus]\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n }, []);\n\n const handleDisconnected = useCallback(() => {\n // If already disconnected, endSession already handled the disconnect callback\n if (status === \"disconnected\") {\n return;\n }\n\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n hasCalledOnConnectRef.current = false;\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n }, [callbacksRef, setStatus, status]);\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","onEndSession","localParticipant","useLocalParticipant","room","useRoomContext","agentResponseCountRef","React","useRef","onEndSessionRef","current","onReadyRef","callbacksRef","useEffect","handleParticipantDisconnected","participant","_participant$identity","identity","startsWith","on","RoomEvent","ParticipantDisconnected","off","useDataChannel","msg","_msg$from","decoder","TextDecoder","message","JSON","parse","decode","payload","event","_msg$from2","messageText","type","user_transcription_event","user_transcript","agent_response_event","agent_response","extractMessageText","onMessage","source","role","from","isAgent","onModeChange","mode","isSpeaking","eventId","event_id","ping_event","clientToolCall","Promise","resolve","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","onAudio","audio_event","audio_base_64","onVadScore","vadScore","vad_score_event","vad_score","onInterruption","interruption_event","onMCPToolCall","mcp_tool_call","onMCPConnectionStatus","mcp_connection_status","onAgentToolRequest","agent_tool_request","onAgentToolResponse","agent_tool_response","onConversationMetadata","conversation_initiation_metadata_event","onAsrInitiationMetadata","asr_initiation_metadata_event","onAgentChatResponsePart","text_response_part","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","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","match","error","console","warn","extractConversationIdFromToken","conversationToken","onStatusChange","agentId","info","fetch","response","json","data","ok","Error","detail","getConversationToken","_getConversationToken","endSession","reason","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","hasCalledOnConnectRef","AudioSession","startAudioSession","start","stopAudioSession","onConnect","handleParticipantReady","handleConnected","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","getId","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","setClientTools","tools","sendContextualUpdate","text","sendUserMessage","sendUserActivity","useMemo","contextValue","Provider","value","key","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -67,6 +67,7 @@ export type ClientToolCallEvent = Incoming.ClientToolCallClientEvent;
67
67
  export type VadScoreEvent = Incoming.VadScoreClientEvent;
68
68
  export type MCPToolCallClientEvent = Incoming.McpToolCallClientEvent;
69
69
  export type MCPConnectionStatusEvent = Incoming.McpConnectionStatusClientEvent;
70
+ export type AgentToolRequestEvent = Incoming.AgentToolRequestClientEvent;
70
71
  export type AgentToolResponseEvent = Incoming.AgentToolResponseClientEvent;
71
72
  export type ConversationMetadataEvent = ConversationMetadata;
72
73
  export type AsrInitiationMetadataEvent = AsrMetadataEvent;
@@ -80,4 +81,4 @@ export type UserMessageEvent = Outgoing.UserMessageClientToOrchestratorEvent;
80
81
  export type UserActivityEvent = Outgoing.UserActivityClientToOrchestratorEvent;
81
82
  export type MCPToolApprovalResultEvent = Outgoing.McpToolApprovalResultClientToOrchestratorEvent;
82
83
  export type InitiationClientDataEvent = Outgoing.ConversationInitiationClientToOrchestratorEvent;
83
- export type ConversationEvent = UserTranscriptionEvent | AgentResponseEvent | AgentResponseCorrectionEvent | AgentAudioEvent | InterruptionEvent | InternalTentativeAgentResponseEvent | ConfigEvent | PingEvent | ClientToolCallEvent | VadScoreEvent | MCPToolCallClientEvent | MCPConnectionStatusEvent | AgentToolResponseEvent | ConversationMetadataEvent | AsrInitiationMetadataEvent | AgentChatResponsePartEvent;
84
+ export type ConversationEvent = UserTranscriptionEvent | AgentResponseEvent | AgentResponseCorrectionEvent | AgentAudioEvent | InterruptionEvent | InternalTentativeAgentResponseEvent | ConfigEvent | PingEvent | ClientToolCallEvent | VadScoreEvent | MCPToolCallClientEvent | MCPConnectionStatusEvent | AgentToolRequestEvent | AgentToolResponseEvent | ConversationMetadataEvent | AsrInitiationMetadataEvent | AgentChatResponsePartEvent;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "0.5.3";
1
+ export declare const PACKAGE_VERSION = "0.5.5";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevenlabs/react-native",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "ElevenLabs React Native SDK for Conversational AI",
5
5
  "main": "./dist/lib.js",
6
6
  "module": "./dist/lib.module.js",
@@ -14,19 +14,6 @@
14
14
  "require": "./dist/lib.js"
15
15
  }
16
16
  },
17
- "scripts": {
18
- "generate-version": "printf \"// This file is auto-generated during build\\nexport const PACKAGE_VERSION = \\\"%s\\\";\\n\" \"$npm_package_version\" > src/version.ts",
19
- "prebuild": "npm run generate-version",
20
- "build": "BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts",
21
- "clean": "rm -rf ./dist",
22
- "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",
23
- "lint": "pnpm run check-types && pnpm run lint:es && pnpm run lint:prettier",
24
- "check-types": "tsc --noEmit --skipLibCheck",
25
- "lint:es": "pnpm exec eslint .",
26
- "lint:prettier": "prettier 'src/**/*.ts' --check",
27
- "prepublishOnly": "pnpm run build",
28
- "test": "jest"
29
- },
30
17
  "keywords": [
31
18
  "elevenlabs",
32
19
  "react-native",
@@ -45,7 +32,7 @@
45
32
  "react-native": ">=0.70.0"
46
33
  },
47
34
  "dependencies": {
48
- "@elevenlabs/types": "workspace:*"
35
+ "@elevenlabs/types": "0.4.0"
49
36
  },
50
37
  "devDependencies": {
51
38
  "@testing-library/jest-native": "^5.4.3",
@@ -67,5 +54,17 @@
67
54
  },
68
55
  "publishConfig": {
69
56
  "access": "public"
57
+ },
58
+ "scripts": {
59
+ "generate-version": "printf \"// This file is auto-generated during build\\nexport const PACKAGE_VERSION = \\\"%s\\\";\\n\" \"$npm_package_version\" > src/version.ts",
60
+ "prebuild": "npm run generate-version",
61
+ "build": "BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts",
62
+ "clean": "rm -rf ./dist",
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 .",
67
+ "lint:prettier": "prettier 'src/**/*.ts' --check",
68
+ "test": "jest"
70
69
  }
71
- }
70
+ }
@@ -1,6 +1,7 @@
1
1
  import { useEffect } from "react";
2
- import { useLocalParticipant, useDataChannel } from "@livekit/react-native";
3
- import type { LocalParticipant } from "livekit-client";
2
+ import { useLocalParticipant, useDataChannel, useRoomContext } from "@livekit/react-native";
3
+ import { RoomEvent } from "livekit-client";
4
+ import type { LocalParticipant, RemoteParticipant } from "livekit-client";
4
5
  import type {
5
6
  Callbacks,
6
7
  ClientToolsConfig,
@@ -44,10 +45,34 @@ export const MessageHandler = ({
44
45
  onEndSession,
45
46
  }: MessageHandlerProps) => {
46
47
  const { localParticipant } = useLocalParticipant();
48
+ const room = useRoomContext();
47
49
 
48
50
  // Track agent response count for synthetic event IDs (WebRTC mode)
49
51
  const agentResponseCountRef = React.useRef(1);
50
52
 
53
+ // Refs for callbacks to avoid unnecessary effect re-runs
54
+ const onEndSessionRef = React.useRef(onEndSession);
55
+ onEndSessionRef.current = onEndSession;
56
+ const onReadyRef = React.useRef(onReady);
57
+ onReadyRef.current = onReady;
58
+ const callbacksRef = React.useRef(callbacks);
59
+ callbacksRef.current = callbacks;
60
+
61
+ // Detect agent disconnection
62
+ useEffect(() => {
63
+ const handleParticipantDisconnected = (participant: RemoteParticipant) => {
64
+ if (participant.identity?.startsWith("agent")) {
65
+ onEndSessionRef.current("agent");
66
+ }
67
+ };
68
+
69
+ room.on(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);
70
+
71
+ return () => {
72
+ room.off(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);
73
+ };
74
+ }, [room]);
75
+
51
76
  // Reset agent response count when connection status changes
52
77
  useEffect(() => {
53
78
  if (!isConnected) {
@@ -57,9 +82,9 @@ export const MessageHandler = ({
57
82
 
58
83
  useEffect(() => {
59
84
  if (isConnected && localParticipant) {
60
- onReady(localParticipant);
85
+ onReadyRef.current(localParticipant);
61
86
  }
62
- }, [isConnected, localParticipant, onReady]);
87
+ }, [isConnected, localParticipant]);
63
88
 
64
89
  const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {
65
90
  if (clientToolCall.client_tool_call.tool_name in clientTools) {
@@ -81,7 +106,7 @@ export const MessageHandler = ({
81
106
  });
82
107
  } catch (e) {
83
108
  const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;
84
- callbacks.onError?.(errorMessage, {
109
+ callbacksRef.current.onError?.(errorMessage, {
85
110
  clientToolName: clientToolCall.client_tool_call.tool_name,
86
111
  });
87
112
  sendMessage({
@@ -92,13 +117,13 @@ export const MessageHandler = ({
92
117
  });
93
118
  }
94
119
  } else {
95
- if (callbacks.onUnhandledClientToolCall) {
96
- callbacks.onUnhandledClientToolCall(clientToolCall.client_tool_call);
120
+ if (callbacksRef.current.onUnhandledClientToolCall) {
121
+ callbacksRef.current.onUnhandledClientToolCall(clientToolCall.client_tool_call);
97
122
  return;
98
123
  }
99
124
 
100
125
  const errorMessage = `Client tool with name ${clientToolCall.client_tool_call.tool_name} is not defined on client`;
101
- callbacks.onError?.(errorMessage, {
126
+ callbacksRef.current.onError?.(errorMessage, {
102
127
  clientToolName: clientToolCall.client_tool_call.tool_name,
103
128
  });
104
129
  sendMessage({
@@ -115,7 +140,7 @@ export const MessageHandler = ({
115
140
  const message = JSON.parse(decoder.decode(msg.payload));
116
141
 
117
142
  if (!isValidEvent(message)) {
118
- callbacks.onDebug?.({
143
+ callbacksRef.current.onDebug?.({
119
144
  type: "invalid_event",
120
145
  message,
121
146
  });
@@ -124,14 +149,15 @@ export const MessageHandler = ({
124
149
 
125
150
  const messageText = extractMessageText(message);
126
151
  if (messageText !== null) {
127
- callbacks.onMessage?.({
152
+ callbacksRef.current.onMessage?.({
128
153
  message: messageText,
129
154
  source: message.type === "user_transcript" ? "user" : "ai",
155
+ role: message.type === "user_transcript" ? "user" : "agent",
130
156
  });
131
157
  }
132
158
 
133
159
  if (msg.from?.isAgent) {
134
- callbacks.onModeChange?.({
160
+ callbacksRef.current.onModeChange?.({
135
161
  mode: msg.from?.isSpeaking ? "speaking" : "listening",
136
162
  });
137
163
 
@@ -153,45 +179,48 @@ export const MessageHandler = ({
153
179
  handleClientToolCall(message);
154
180
  break;
155
181
  case "audio":
156
- callbacks.onAudio?.(message.audio_event.audio_base_64);
182
+ callbacksRef.current.onAudio?.(message.audio_event.audio_base_64);
157
183
  break;
158
184
  case "vad_score":
159
- callbacks.onVadScore?.({
185
+ callbacksRef.current.onVadScore?.({
160
186
  vadScore: message.vad_score_event.vad_score,
161
187
  });
162
188
  break;
163
189
  case "interruption":
164
- callbacks.onInterruption?.(message.interruption_event);
190
+ callbacksRef.current.onInterruption?.(message.interruption_event);
165
191
  break;
166
192
  case "mcp_tool_call":
167
- callbacks.onMCPToolCall?.(message.mcp_tool_call);
193
+ callbacksRef.current.onMCPToolCall?.(message.mcp_tool_call);
168
194
  break;
169
195
  case "mcp_connection_status":
170
- callbacks.onMCPConnectionStatus?.(message.mcp_connection_status);
196
+ callbacksRef.current.onMCPConnectionStatus?.(message.mcp_connection_status);
197
+ break;
198
+ case "agent_tool_request":
199
+ callbacksRef.current.onAgentToolRequest?.(message.agent_tool_request);
171
200
  break;
172
201
  case "agent_tool_response":
173
- callbacks.onAgentToolResponse?.(message.agent_tool_response);
202
+ callbacksRef.current.onAgentToolResponse?.(message.agent_tool_response);
174
203
 
175
204
  if (message.agent_tool_response.tool_name === "end_call") {
176
205
  // End the call
177
- onEndSession("agent");
206
+ onEndSessionRef.current("agent");
178
207
  }
179
208
  break;
180
209
  case "conversation_initiation_metadata":
181
- callbacks.onConversationMetadata?.(
210
+ callbacksRef.current.onConversationMetadata?.(
182
211
  message.conversation_initiation_metadata_event
183
212
  );
184
213
  break;
185
214
  case "asr_initiation_metadata":
186
- callbacks.onAsrInitiationMetadata?.(
215
+ callbacksRef.current.onAsrInitiationMetadata?.(
187
216
  message.asr_initiation_metadata_event
188
217
  );
189
218
  break;
190
219
  case "agent_chat_response_part":
191
- callbacks.onAgentChatResponsePart?.(message.text_response_part);
220
+ callbacksRef.current.onAgentChatResponsePart?.(message.text_response_part);
192
221
  break;
193
222
  default:
194
- callbacks.onDebug?.(message);
223
+ callbacksRef.current.onDebug?.(message);
195
224
  break;
196
225
  }
197
226
  });
package/src/types.ts CHANGED
@@ -99,6 +99,7 @@ export type ClientToolCallEvent = Incoming.ClientToolCallClientEvent;
99
99
  export type VadScoreEvent = Incoming.VadScoreClientEvent;
100
100
  export type MCPToolCallClientEvent = Incoming.McpToolCallClientEvent;
101
101
  export type MCPConnectionStatusEvent = Incoming.McpConnectionStatusClientEvent;
102
+ export type AgentToolRequestEvent = Incoming.AgentToolRequestClientEvent;
102
103
  export type AgentToolResponseEvent = Incoming.AgentToolResponseClientEvent;
103
104
  export type ConversationMetadataEvent = ConversationMetadata;
104
105
  export type AsrInitiationMetadataEvent = AsrMetadataEvent;
@@ -133,6 +134,7 @@ export type ConversationEvent =
133
134
  | VadScoreEvent
134
135
  | MCPToolCallClientEvent
135
136
  | MCPConnectionStatusEvent
137
+ | AgentToolRequestEvent
136
138
  | AgentToolResponseEvent
137
139
  | ConversationMetadataEvent
138
140
  | AsrInitiationMetadataEvent
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // This file is auto-generated during build
2
- export const PACKAGE_VERSION = "0.5.3";
2
+ export const PACKAGE_VERSION = "0.5.5";