UNPKG

@elevenlabs/react-native

Version:

ElevenLabs React Native SDK for Conversational AI

3 lines (2 loc) 15.5 kB
!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 s="0.5.7",i=function(e){var o=e.onReady,c=e.isConnected,s=e.callbacks,i=e.sendMessage,u=e.clientTools,l=void 0===u?{}:u,d=e.updateCurrentEventId,f=e.onEndSession,v=t.useLocalParticipant().localParticipant,_=t.useRoomContext(),g=a.default.useRef(1),p=a.default.useRef(f);p.current=f;var C=a.default.useRef(o);C.current=o;var k=a.default.useRef(s);return k.current=s,n.useEffect(function(){var e=function(e){var n;null!=(n=e.identity)&&n.startsWith("agent")&&p.current("agent")};return _.on(r.RoomEvent.ParticipantDisconnected,e),function(){_.off(r.RoomEvent.ParticipantDisconnected,e)}},[_]),n.useEffect(function(){c||(g.current=1)},[c]),n.useEffect(function(){c&&v&&C.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==k.current.onMessage||k.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==k.current.onModeChange||k.current.onModeChange({mode:null!=(a=e.from)&&a.isSpeaking?"speaking":"listening"}),"agent_response"===r.type&&d)){var s=g.current++;d(s)}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 l){var n=function(n,t){try{var r=Promise.resolve(l[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==k.current.onError||k.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(k.current.onUnhandledClientToolCall)return void k.current.onUnhandledClientToolCall(e.client_tool_call);var t="Client tool with name "+e.client_tool_call.tool_name+" is not defined on client";null==k.current.onError||k.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==k.current.onAudio||k.current.onAudio(r.audio_event.audio_base_64);break;case"vad_score":null==k.current.onVadScore||k.current.onVadScore({vadScore:r.vad_score_event.vad_score});break;case"interruption":null==k.current.onInterruption||k.current.onInterruption(r.interruption_event);break;case"mcp_tool_call":null==k.current.onMCPToolCall||k.current.onMCPToolCall(r.mcp_tool_call);break;case"mcp_connection_status":null==k.current.onMCPConnectionStatus||k.current.onMCPConnectionStatus(r.mcp_connection_status);break;case"agent_tool_request":null==k.current.onAgentToolRequest||k.current.onAgentToolRequest(r.agent_tool_request);break;case"agent_tool_response":null==k.current.onAgentToolResponse||k.current.onAgentToolResponse(r.agent_tool_response),"end_call"===r.agent_tool_response.tool_name&&p.current("agent");break;case"conversation_initiation_metadata":null==k.current.onConversationMetadata||k.current.onConversationMetadata(r.conversation_initiation_metadata_event);break;case"asr_initiation_metadata":null==k.current.onAsrInitiationMetadata||k.current.onAsrInitiationMetadata(r.asr_initiation_metadata_event);break;case"agent_chat_response_part":null==k.current.onAgentChatResponsePart||k.current.onAgentChatResponsePart(r.text_response_part);break;default:null==k.current.onDebug||k.current.onDebug(r)}}else null==k.current.onDebug||k.current.onDebug({type:"invalid_event",message:r})}),null},u=function(e){var n=e.children,r=e.serverUrl,o=e.token,c=e.connect,s=e.onConnected,u=e.onDisconnected,l=e.onError,d=e.roomConnected,f=e.callbacks,v=e.onParticipantReady,_=e.sendMessage,g=e.clientTools,p=e.updateCurrentEventId,C=e.onEndSession,k=e.audioSessionConfig,b=e.textOnly,h=void 0!==b&&b,m=a.default.useMemo(function(){return!h&&(null==k||!k.allowMixingWithOthers||{audio:{noiseSuppression:!0,echoCancellation:!0},audioSessionConfiguration:{allowMixingWithOthers:!0}})},[k,h]);/*#__PURE__*/return a.default.createElement(t.LiveKitRoom,{serverUrl:r,token:o,connect:c,audio:m,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:s,onDisconnected:u,onError:l},/*#__PURE__*/a.default.createElement(i,{onReady:v,isConnected:d,callbacks:f,sendMessage:_,clientTools:g,updateCurrentEventId:p,onEndSession:C}),n)},l=["serverUrl","tokenFetchUrl","clientTools"],d=/*#__PURE__*/n.createContext(null);e.ElevenLabsProvider=function(e){var r,o,i=e.children,l=e.audioSessionConfig;t.registerGlobals();var f=n.useState(""),v=f[0],_=f[1],g=n.useState(!1),p=g[0],C=g[1],k=n.useState("disconnected"),b=k[0],h=k[1],m=n.useState("wss://livekit.rtc.elevenlabs.io"),S=m[0],y=m[1],E=n.useState(void 0),M=E[0],P=E[1],x=n.useState(""),R=x[0],T=x[1],w=n.useState(!1),U=w[0],I=w[1],A=n.useState(!1),F=A[0],D=A[1],O=a.default.useRef(1),j=a.default.useRef(1),L=a.default.useRef({}),N=function(){var e=n.useRef({}),t=n.useCallback(function(n){e.current=n},[]);return{callbacksRef:e,setCallbacks:t}}(),V=N.callbacksRef,q=N.setCallbacks,B=a.default.useCallback(function(e){var n=c({},e,{onModeChange:function(n){I("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});q(n)},[q]),J=function(e,t,r,o,a,c){var i=n.useState({}),u=i[0],l=i[1],d=n.useState(null),f=d[0],v=d[1],_=n.useState({}),g=_[0],p=_[1],C=n.useState(void 0),k=C[0],b=C[1];return{startSession:n.useCallback(function(n){try{return Promise.resolve(function(i,u){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"),""}}(u);a(n),o(u),r(!0)}var u;t("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),l(n.overrides||{}),v(n.customLlmExtraBody||null),p(n.dynamicVariables||{}),b(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="+s)).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){u=e});throw new Error("Either conversationToken or agentId is required")}();u=n.conversationToken}();return d&&d.then?d.then(i):i()}()}catch(e){return u(e)}return d&&d.then?d.then(void 0,u):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"),l({}),v(null),p({}),b(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:u,customLlmExtraBody:f,dynamicVariables:g,userId:k}}(V,h,C,_,T,M),W=J.startSession,K=J.endSession,G=J.overrides,z=J.customLlmExtraBody,Z=J.dynamicVariables,H=J.userId,Q=null!=(r=null==G||null==(o=G.conversation)?void 0:o.textOnly)&&r,X=function(e,r,o,a,c){void 0===c&&(c=!1);var s=n.useState(!1),i=s[0],u=s[1],l=n.useState(null),d=l[0],f=l[1],v=n.useRef(!1),_=n.useRef(!1);n.useEffect(function(){o&&(u(!1),f(null),v.current=!1)},[o]),n.useEffect(function(){var e=!c&&!!o;return e&&!_.current?(_.current=!0,t.AudioSession.startAudioSession()):!e&&_.current&&(_.current=!1,t.AudioSession.stopAudioSession()),function(){_.current&&(_.current=!1,t.AudioSession.stopAudioSession())}},[c,o]),n.useEffect(function(){d&&i&&!v.current&&(v.current=!0,null==e.current.onConnect||e.current.onConnect({conversationId:o}))},[d,i,o,e]);var g=n.useCallback(function(e){d||(f(e),r("connected"))},[d,r]),p=n.useCallback(function(){u(!0)},[]),C=n.useCallback(function(){"disconnected"!==a&&(u(!1),r("disconnected"),f(null),v.current=!1,null==e.current.onDisconnect||e.current.onDisconnect({reason:"user"}))},[e,r,a]),k=n.useCallback(function(n){console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e]);return{roomConnected:i,localParticipant:d,handleParticipantReady:g,handleConnected:p,handleDisconnected:C,handleError:k}}(V,h,R,b,Q),Y=X.roomConnected,$=X.localParticipant,ee=X.handleParticipantReady,ne=X.handleConnected,te=X.handleDisconnected,re=X.handleError,oe=a.default.useCallback(function(){O.current=1,j.current=1,D(!1),null==V.current.onCanSendFeedbackChange||V.current.onCanSendFeedbackChange({canSendFeedback:!1}),ne()},[ne,V]),ae=a.default.useCallback(function(){D(!1),I(!1),te()},[te]),ce=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])}}(b,$,V),se=ce.sendMessage,ie=a.default.useCallback(function(){var e=O.current!==j.current;F!==e&&(D(e),null==V.current.onCanSendFeedbackChange||V.current.onCanSendFeedbackChange({canSendFeedback:e}))},[F,V]),ue=a.default.useCallback(function(e){F?(se({type:"feedback",score:e?"like":"dislike",event_id:O.current}),j.current=O.current,ie()):console.warn(0===j.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[F,se,ie]);a.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var le=a.default.useCallback(function(){return R},[R]),de=a.default.useCallback(function(e){$&&$.setMicrophoneEnabled(!e)},[$]),fe=a.default.useCallback(function(e){O.current=e,ie()},[ie]),ve=a.default.useCallback(function(e){ee(e);var n=function(e){var n,t,r,o,a,c,i,u={type:"conversation_initiation_client_data"};return e.overrides&&(u.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,speed:null==(c=e.overrides.tts)?void 0:c.speed},conversation:{text_only:null==(i=e.overrides.conversation)?void 0:i.textOnly}}),u.source_info={source:"react_native_sdk",version:(null==(n=e.overrides)||null==(n=n.client)?void 0:n.version)||s},e.customLlmExtraBody&&(u.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(u.dynamic_variables=e.dynamicVariables),e.userId&&(u.user_id=String(e.userId)),u}({overrides:G,customLlmExtraBody:z,dynamicVariables:Z,userId:H});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==V.current.onError||V.current.onError(e)}},[ee,G,z,Z,H,V]),_e=a.default.useCallback(function(e){L.current=e},[]),ge=a.default.useCallback(function(e){se({type:"contextual_update",text:e})},[se]),pe=a.default.useCallback(function(e){se({type:"user_message",text:e})},[se]),Ce=a.default.useCallback(function(){se({type:"user_activity"})},[se]),ke=a.default.useRef({startSession:W,endSession:K,status:b,isSpeaking:U,canSendFeedback:F,getId:le,setMicMuted:de,sendFeedback:ue,sendContextualUpdate:ge,sendUserMessage:pe,sendUserActivity:Ce});ke.current={startSession:W,endSession:K,status:b,isSpeaking:U,canSendFeedback:F,getId:le,setMicMuted:de,sendFeedback:ue,sendContextualUpdate:ge,sendUserMessage:pe,sendUserActivity:Ce};var be=a.default.useMemo(function(){return{get startSession(){return ke.current.startSession},get endSession(){return ke.current.endSession},get status(){return ke.current.status},get isSpeaking(){return ke.current.isSpeaking},get canSendFeedback(){return ke.current.canSendFeedback},get getId(){return ke.current.getId},get setMicMuted(){return ke.current.setMicMuted},get sendFeedback(){return ke.current.sendFeedback},get sendContextualUpdate(){return ke.current.sendContextualUpdate},get sendUserMessage(){return ke.current.sendUserMessage},get sendUserActivity(){return ke.current.sendUserActivity}}},[]),he=a.default.useMemo(function(){return{conversation:be,callbacksRef:V,serverUrl:S,tokenFetchUrl:M,clientTools:L.current,setCallbacks:B,setServerUrl:y,setTokenFetchUrl:P,setClientTools:_e}},[be,V,S,M,B,_e]);/*#__PURE__*/return a.default.createElement(d.Provider,{value:he},/*#__PURE__*/a.default.createElement(u,{serverUrl:S,token:v,connect:p,onConnected:oe,onDisconnected:ae,onError:re,roomConnected:Y,callbacks:V.current,onParticipantReady:ve,sendMessage:se,clientTools:L.current,updateCurrentEventId:fe,onEndSession:K,audioSessionConfig:l,textOnly:Q},i))},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,s=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,l);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(s),t.conversation}}); //# sourceMappingURL=lib.umd.js.map