@elevenlabs/react-native
Version:
ElevenLabs React Native SDK for Conversational AI
3 lines (2 loc) • 11 kB
JavaScript
var e=require("react"),n=require("@livekit/react-native");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=/*#__PURE__*/t(e);function o(){return o=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},o.apply(null,arguments)}var a="0.3.1",l=function(t){var o=t.onReady,a=t.isConnected,l=t.callbacks,c=t.sendMessage,i=t.clientTools,s=void 0===i?{}:i,u=t.updateCurrentEventId,d=n.useLocalParticipant().localParticipant,v=r.default.useRef(1);return e.useEffect(function(){a&&d&&o(d)},[a,d,o]),n.useDataChannel(function(e){var n,t,r=new TextDecoder,o=JSON.parse(r.decode(e.payload));if(o.type){var a;if(null==l.onMessage||l.onMessage({message:o,source:null!=(n=e.from)&&n.isAgent?"ai":"user"}),null!=(t=e.from)&&t.isAgent&&(null==l.onModeChange||l.onModeChange({mode:null!=(a=e.from)&&a.isSpeaking?"speaking":"listening"}),"agent_response"===o.type&&u)){var i=v.current++;u(i)}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(Object.prototype.hasOwnProperty.call(s,e.client_tool_call.tool_name)){var n=function(n,t){try{var r=Promise.resolve(s[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==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);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;default:null==l.onDebug||l.onDebug(o)}}else null==l.onDebug||l.onDebug({type:"invalid_event",message:o})}),null},c=function(e){var t=e.children;/*#__PURE__*/return r.default.createElement(n.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(l,{onReady:e.onParticipantReady,isConnected:e.roomConnected,callbacks:e.callbacks,sendMessage:e.sendMessage,clientTools:e.clientTools,updateCurrentEventId:e.updateCurrentEventId}),t)},i=["serverUrl","tokenFetchUrl","clientTools"],s=/*#__PURE__*/e.createContext(null);exports.ElevenLabsProvider=function(t){var l=t.children;n.registerGlobals();var i=e.useState(""),u=i[0],d=i[1],v=e.useState(!1),f=v[0],h=v[1],m=e.useState("disconnected"),g=m[0],C=m[1],_=e.useState("wss://livekit.rtc.elevenlabs.io"),b=_[0],k=_[1],p=e.useState(void 0),y=p[0],S=p[1],E=e.useState(""),P=E[0],w=E[1],x=e.useState(!1),T=x[0],I=x[1],U=e.useState(!1),D=U[0],M=U[1],R=r.default.useRef(1),F=r.default.useRef(1),j=r.default.useRef({}),O=function(){var n=e.useRef({}),t=e.useCallback(function(e){n.current=e},[]);return{callbacksRef:n,setCallbacks:t}}(),L=O.callbacksRef,A=O.setCallbacks,N=r.default.useCallback(function(e){var n=o({},e,{onModeChange:function(n){I("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});A(n)},[A]),V=function(n,t,r,o,l,c){var i=e.useState({}),s=i[0],u=i[1],d=e.useState(null),v=d[0],f=d[1],h=e.useState({}),m=h[0],g=h[1],C=e.useState(void 0),_=C[0],b=C[1];return{startSession:e.useCallback(function(e){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);l(n),o(s),r(!0)}var s;t("connecting"),null==n.current.onStatusChange||n.current.onStatusChange({status:"connecting"}),u(e.overrides||{}),f(e.customLlmExtraBody||null),g(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="+a)).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||c)).then(function(e){s=e});throw new Error("Either conversationToken or agentId is required")}();s=e.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(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,l,c]),endSession:e.useCallback(function(){try{try{r(!1),o(""),t("disconnected"),null==n.current.onStatusChange||n.current.onStatusChange({status:"disconnected"}),null==n.current.onDisconnect||n.current.onDisconnect("User ended conversation")}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]),overrides:s,customLlmExtraBody:v,dynamicVariables:m,userId:_}}(L,C,h,d,w,y),B=V.startSession,J=V.endSession,q=V.overrides,K=V.customLlmExtraBody,G=V.dynamicVariables,z=V.userId,W=function(t,r,o){var a=e.useState(!1),l=a[0],c=a[1],i=e.useState(null),s=i[0],u=i[1];return e.useEffect(function(){return function(){try{return Promise.resolve(n.AudioSession.startAudioSession()).then(function(){})}catch(e){return Promise.reject(e)}}(),function(){n.AudioSession.stopAudioSession()}},[]),{roomConnected:l,localParticipant:s,handleParticipantReady:e.useCallback(function(e){u(e)},[]),handleConnected:e.useCallback(function(){c(!0),r("connected"),null==t.current.onConnect||t.current.onConnect({conversationId:o})},[o,t,r]),handleDisconnected:e.useCallback(function(){c(!1),r("disconnected"),u(null),null==t.current.onDisconnect||t.current.onDisconnect("disconnected")},[t,r]),handleError:e.useCallback(function(e){console.error("LiveKit error:",e),null==t.current.onError||t.current.onError(e.message,void 0)},[t])}}(L,C,P),Z=W.roomConnected,H=W.localParticipant,Q=W.handleParticipantReady,X=W.handleConnected,Y=W.handleDisconnected,$=W.handleError,ee=r.default.useCallback(function(){R.current=1,F.current=1,M(!1),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:!1}),X()},[X,L]),ne=r.default.useCallback(function(){M(!1),Y()},[Y]),te=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])}}(g,H,L),re=te.sendMessage,oe=r.default.useCallback(function(){var e=R.current!==F.current;D!==e&&(M(e),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:e}))},[D,L]),ae=r.default.useCallback(function(e){D?(re({type:"feedback",score:e?"like":"dislike",event_id:R.current}),F.current=R.current,oe()):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.")},[D,re,oe]);r.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var le=r.default.useCallback(function(e){H&&H.setMicrophoneEnabled(!e)},[H]),ce=r.default.useCallback(function(e){R.current=e,oe()},[oe]),ie=r.default.useCallback(function(e){if(Q(e),H){var n=function(e){var n,t,r,o,l,c,i={type:"conversation_initiation_client_data"};return e.overrides&&(i.conversation_config_override={agent:{prompt:null==(n=e.overrides.agent)?void 0:n.prompt,first_message:null==(t=e.overrides.agent)?void 0:t.firstMessage,language:null==(r=e.overrides.agent)?void 0:r.language},tts:{voice_id:null==(o=e.overrides.tts)?void 0:o.voiceId},conversation:{text_only:null==(l=e.overrides.conversation)?void 0:l.textOnly},source_info:{source:"react_native_sdk",version:(null==(c=e.overrides)||null==(c=c.client)?void 0:c.version)||a}}),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:K,dynamicVariables:G,userId:z});re(n)}},[Q,H,q,K,G,z,re]),se={startSession:B,endSession:J,status:g,isSpeaking:T,canSendFeedback:D,getId:function(){return P},setMicMuted:le,sendFeedback:ae,sendContextualUpdate:function(e){re({type:"contextual_update",text:e})},sendUserMessage:function(e){re({type:"user_message",text:e})},sendUserActivity:function(){re({type:"user_activity"})}},ue=r.default.useCallback(function(e){j.current=e},[]);/*#__PURE__*/return r.default.createElement(s.Provider,{value:{conversation:se,callbacksRef:L,serverUrl:b,tokenFetchUrl:y,clientTools:j.current,setCallbacks:N,setServerUrl:k,setTokenFetchUrl:S,setClientTools:ue}},/*#__PURE__*/r.default.createElement(c,{serverUrl:b,token:u,connect:f,onConnected:ee,onDisconnected:ne,onError:$,roomConnected:Z,callbacks:L.current,onParticipantReady:ie,sendMessage:re,clientTools:j.current,updateCurrentEventId:ce},l))},exports.useConversation=function(n){void 0===n&&(n={});var t=e.useContext(s);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");var o=n.serverUrl,a=n.tokenFetchUrl,l=n.clientTools,c=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,i);return r.default.useEffect(function(){o&&t.setServerUrl(o)},[t,o]),r.default.useEffect(function(){a&&t.setTokenFetchUrl(a)},[t,a]),l&&t.setClientTools(l),t.setCallbacks(c),t.conversation};
//# sourceMappingURL=lib.js.map