UNPKG

@elevenlabs/react-native

Version:

ElevenLabs React Native SDK for Conversational AI

3 lines (2 loc) 15.2 kB
var e=require("react"),n=require("@livekit/react-native"),t=require("livekit-client");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=/*#__PURE__*/r(e);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 r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},a.apply(null,arguments)}var c="0.5.7",s=function(r){var a=r.onReady,c=r.isConnected,s=r.callbacks,u=r.sendMessage,l=r.clientTools,i=void 0===l?{}:l,d=r.updateCurrentEventId,f=r.onEndSession,v=n.useLocalParticipant().localParticipant,_=n.useRoomContext(),g=o.default.useRef(1),p=o.default.useRef(f);p.current=f;var C=o.default.useRef(a);C.current=a;var k=o.default.useRef(s);return k.current=s,e.useEffect(function(){var e=function(e){var n;null!=(n=e.identity)&&n.startsWith("agent")&&p.current("agent")};return _.on(t.RoomEvent.ParticipantDisconnected,e),function(){_.off(t.RoomEvent.ParticipantDisconnected,e)}},[_]),e.useEffect(function(){c||(g.current=1)},[c]),e.useEffect(function(){c&&v&&C.current(v)},[c,v]),n.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":u({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 i){var n=function(n,t){try{var r=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);u({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}),u({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}),u({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 t=e.children,r=e.serverUrl,a=e.token,c=e.connect,u=e.onConnected,l=e.onDisconnected,i=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=o.default.useMemo(function(){return!h&&(null==k||!k.allowMixingWithOthers||{audio:{noiseSuppression:!0,echoCancellation:!0},audioSessionConfiguration:{allowMixingWithOthers:!0}})},[k,h]);/*#__PURE__*/return o.default.createElement(n.LiveKitRoom,{serverUrl:r,token:a,connect:c,audio:m,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:u,onDisconnected:l,onError:i},/*#__PURE__*/o.default.createElement(s,{onReady:v,isConnected:d,callbacks:f,sendMessage:_,clientTools:g,updateCurrentEventId:p,onEndSession:C}),t)},l=["serverUrl","tokenFetchUrl","clientTools"],i=/*#__PURE__*/e.createContext(null);exports.ElevenLabsProvider=function(t){var r,s,l=t.children,d=t.audioSessionConfig;n.registerGlobals();var f=e.useState(""),v=f[0],_=f[1],g=e.useState(!1),p=g[0],C=g[1],k=e.useState("disconnected"),b=k[0],h=k[1],m=e.useState("wss://livekit.rtc.elevenlabs.io"),S=m[0],y=m[1],E=e.useState(void 0),M=E[0],P=E[1],x=e.useState(""),R=x[0],w=x[1],T=e.useState(!1),U=T[0],I=T[1],A=e.useState(!1),F=A[0],D=A[1],O=o.default.useRef(1),j=o.default.useRef(1),L=o.default.useRef({}),N=function(){var n=e.useRef({}),t=e.useCallback(function(e){n.current=e},[]);return{callbacksRef:n,setCallbacks:t}}(),V=N.callbacksRef,q=N.setCallbacks,B=o.default.useCallback(function(e){var n=a({},e,{onModeChange:function(n){I("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});q(n)},[q]),J=function(n,t,r,o,a,s){var u=e.useState({}),l=u[0],i=u[1],d=e.useState(null),f=d[0],v=d[1],_=e.useState({}),g=_[0],p=_[1],C=e.useState(void 0),k=C[0],b=C[1];return{startSession:e.useCallback(function(e){try{return Promise.resolve(function(u,l){try{var d=function(){function u(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"),""}}(l);a(n),o(l),r(!0)}var l;t("connecting"),null==n.current.onStatusChange||n.current.onStatusChange({status:"connecting"}),i(e.overrides||{}),v(e.customLlmExtraBody||null),p(e.dynamicVariables||{}),b(e.userId);var d=function(){if(!e.conversationToken)return function(){if(e.agentId)return console.info("Getting conversation token for agentId:",e.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="+c)).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)}}(e.agentId,e.tokenFetchUrl||s)).then(function(e){l=e});throw new Error("Either conversationToken or agentId is required")}();l=e.conversationToken}();return d&&d.then?d.then(u):u()}()}catch(e){return l(e)}return d&&d.then?d.then(void 0,l):d}(0,function(e){throw t("disconnected"),null==n.current.onStatusChange||n.current.onStatusChange({status:"disconnected"}),null==n.current.onError||n.current.onError(e),e}))}catch(e){return Promise.reject(e)}},[n,t,r,o,a,s]),endSession:e.useCallback(function(e){void 0===e&&(e="user");try{try{r(!1),o(""),t("disconnected"),i({}),v(null),p({}),b(void 0),a(""),null==n.current.onStatusChange||n.current.onStatusChange({status:"disconnected"}),null==n.current.onDisconnect||n.current.onDisconnect({reason:e})}catch(e){throw null==n.current.onError||n.current.onError(e),e}return Promise.resolve()}catch(e){return Promise.reject(e)}},[n,r,o,t,a]),overrides:l,customLlmExtraBody:f,dynamicVariables:g,userId:k}}(V,h,C,_,w,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==(s=G.conversation)?void 0:s.textOnly)&&r,X=function(t,r,o,a,c){void 0===c&&(c=!1);var s=e.useState(!1),u=s[0],l=s[1],i=e.useState(null),d=i[0],f=i[1],v=e.useRef(!1),_=e.useRef(!1);e.useEffect(function(){o&&(l(!1),f(null),v.current=!1)},[o]),e.useEffect(function(){var e=!c&&!!o;return e&&!_.current?(_.current=!0,n.AudioSession.startAudioSession()):!e&&_.current&&(_.current=!1,n.AudioSession.stopAudioSession()),function(){_.current&&(_.current=!1,n.AudioSession.stopAudioSession())}},[c,o]),e.useEffect(function(){d&&u&&!v.current&&(v.current=!0,null==t.current.onConnect||t.current.onConnect({conversationId:o}))},[d,u,o,t]);var g=e.useCallback(function(e){d||(f(e),r("connected"))},[d,r]),p=e.useCallback(function(){l(!0)},[]),C=e.useCallback(function(){"disconnected"!==a&&(l(!1),r("disconnected"),f(null),v.current=!1,null==t.current.onDisconnect||t.current.onDisconnect({reason:"user"}))},[t,r,a]),k=e.useCallback(function(e){console.error("LiveKit error:",e),null==t.current.onError||t.current.onError(e.message,void 0)},[t]);return{roomConnected:u,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=o.default.useCallback(function(){O.current=1,j.current=1,D(!1),null==V.current.onCanSendFeedbackChange||V.current.onCanSendFeedbackChange({canSendFeedback:!1}),ne()},[ne,V]),ae=o.default.useCallback(function(){D(!1),I(!1),te()},[te]),ce=function(n,t,r){return{sendMessage:e.useCallback(function(e){try{if("connected"!==n||!t)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();var o=function(n,r){try{var o=(a=(new TextEncoder).encode(JSON.stringify(e)),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)}},[n,t,r])}}(b,$,V),se=ce.sendMessage,ue=o.default.useCallback(function(){var e=O.current!==j.current;F!==e&&(D(e),null==V.current.onCanSendFeedbackChange||V.current.onCanSendFeedbackChange({canSendFeedback:e}))},[F,V]),le=o.default.useCallback(function(e){F?(se({type:"feedback",score:e?"like":"dislike",event_id:O.current}),j.current=O.current,ue()):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,ue]);o.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var ie=o.default.useCallback(function(){return R},[R]),de=o.default.useCallback(function(e){$&&$.setMicrophoneEnabled(!e)},[$]),fe=o.default.useCallback(function(e){O.current=e,ue()},[ue]),ve=o.default.useCallback(function(e){ee(e);var n=function(e){var n,t,r,o,a,s,u,l={type:"conversation_initiation_client_data"};return e.overrides&&(l.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==(s=e.overrides.tts)?void 0:s.speed},conversation:{text_only:null==(u=e.overrides.conversation)?void 0:u.textOnly}}),l.source_info={source:"react_native_sdk",version:(null==(n=e.overrides)||null==(n=n.client)?void 0:n.version)||c},e.customLlmExtraBody&&(l.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(l.dynamic_variables=e.dynamicVariables),e.userId&&(l.user_id=String(e.userId)),l}({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=o.default.useCallback(function(e){L.current=e},[]),ge=o.default.useCallback(function(e){se({type:"contextual_update",text:e})},[se]),pe=o.default.useCallback(function(e){se({type:"user_message",text:e})},[se]),Ce=o.default.useCallback(function(){se({type:"user_activity"})},[se]),ke=o.default.useRef({startSession:W,endSession:K,status:b,isSpeaking:U,canSendFeedback:F,getId:ie,setMicMuted:de,sendFeedback:le,sendContextualUpdate:ge,sendUserMessage:pe,sendUserActivity:Ce});ke.current={startSession:W,endSession:K,status:b,isSpeaking:U,canSendFeedback:F,getId:ie,setMicMuted:de,sendFeedback:le,sendContextualUpdate:ge,sendUserMessage:pe,sendUserActivity:Ce};var be=o.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=o.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 o.default.createElement(i.Provider,{value:he},/*#__PURE__*/o.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:d,textOnly:Q},l))},exports.useConversation=function(n){void 0===n&&(n={});var t=e.useContext(i);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");var r=n.serverUrl,a=n.tokenFetchUrl,c=n.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}(n,l);return o.default.useEffect(function(){r&&t.setServerUrl(r)},[t,r]),o.default.useEffect(function(){a&&t.setTokenFetchUrl(a)},[t,a]),o.default.useEffect(function(){c&&t.setClientTools(c)},[t,c]),t.setCallbacks(s),t.conversation}; //# sourceMappingURL=lib.js.map