UNPKG

@elevenlabs/react-native

Version:

ElevenLabs React Native SDK for Conversational AI

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