@elevenlabs/react-native 0.3.0 → 0.3.2

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.
@@ -0,0 +1,22 @@
1
+
2
+ > @elevenlabs/react-native@0.3.2 prebuild /home/runner/work/packages/packages/packages/react-native
3
+ > pnpm run generate-version
4
+
5
+
6
+ > @elevenlabs/react-native@0.3.2 generate-version /home/runner/work/packages/packages/packages/react-native
7
+ > printf "// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"%s\";\n" "$npm_package_version" > src/version.ts
8
+
9
+
10
+ > @elevenlabs/react-native@0.3.2 build /home/runner/work/packages/packages/packages/react-native
11
+ > BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts
12
+
13
+ No name was provided for external module '@livekit/react-native' in output.globals – guessing 'reactNative'
14
+ Build "@elevenlabs/react-native" to dist:
15
+ 3.84 kB: lib.js.gz
16
+ 3.39 kB: lib.js.br
17
+ 3.49 kB: lib.modern.js.gz
18
+ 3.08 kB: lib.modern.js.br
19
+ 3.83 kB: lib.module.js.gz
20
+ 3.39 kB: lib.module.js.br
21
+ 3.92 kB: lib.umd.js.gz
22
+ 3.47 kB: lib.umd.js.br
@@ -0,0 +1,4 @@
1
+
2
+ > @elevenlabs/react-native@0.3.2 generate-version /home/runner/work/packages/packages/packages/react-native
3
+ > printf "// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"%s\";\n" "$npm_package_version" > src/version.ts
4
+
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 ElevenLabs
3
+ Copyright (c) 2025 ElevenLabs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
- # ElevenLabs React Native SDK
1
+ ![hero](../../assets/hero.png)
2
2
 
3
- A React Native SDK for ElevenLabs Conversational AI.
3
+ # ElevenLabs Agents React Native SDK
4
+
5
+ Build multimodal agents with the [ElevenLabs Agents platform](https://elevenlabs.io/docs/agents-platform/overview).
6
+
7
+ An SDK library for using ElevenLabs Agents. If you're looking for a Node.js library for other audio APIs, please refer to the [ElevenLabs Node.js Library](https://www.npmjs.com/package/@elevenlabs/elevenlabs-js).
4
8
 
5
9
  ## Features
6
10
 
@@ -23,11 +27,12 @@ npm install @elevenlabs/react-native @livekit/react-native @livekit/react-native
23
27
  ```
24
28
 
25
29
  **Required Dependencies:**
30
+
26
31
  - `@livekit/react-native` - LiveKit React Native SDK (native modules)
27
32
  - `@livekit/react-native-webrtc` - WebRTC implementation for React Native
28
33
  - `livekit-client` - LiveKit JavaScript client
29
34
 
30
- *Note: LiveKit dependencies are required due to React Native's native module architecture and must be installed in your app's root dependencies.*
35
+ _Note: LiveKit dependencies are required due to React Native's native module architecture and must be installed in your app's root dependencies._
31
36
 
32
37
  > **Installation Note:** You may see peer dependency warnings during installation. This is normal - the warnings ensure you have the required LiveKit packages installed for native module linking.
33
38
 
@@ -93,13 +98,14 @@ Returns a conversation object with the following methods and properties:
93
98
  Starts a new conversation session.
94
99
 
95
100
  **Parameters:**
101
+
96
102
  - `config.agentId`: ElevenLabs agent ID, not needed if you provide a conversationToken.
97
103
  - `config.conversationToken`: Optional pre-generated token, used for private agents that require authentication via your ElevenLabs API key.
98
104
  - `config.userId`: You can optionally pass a user ID to identify the user in the conversation. This can be your own customer identifier. This will be included in the conversation initiation data sent to the server.
99
105
 
100
106
  ```typescript
101
107
  await conversation.startSession({
102
- agentId: 'your-agent-id'
108
+ agentId: "your-agent-id",
103
109
  });
104
110
  ```
105
111
 
@@ -116,6 +122,7 @@ await conversation.endSession();
116
122
  Sends binary feedback for the most recent agent response.
117
123
 
118
124
  **Parameters:**
125
+
119
126
  - `like`: `true` for positive feedback, `false` for negative feedback
120
127
 
121
128
  ```typescript
@@ -131,6 +138,7 @@ conversation.sendFeedback(false);
131
138
  Sends contextual information to the agent that won't trigger a response.
132
139
 
133
140
  **Parameters:**
141
+
134
142
  - `text`: Contextual information for the agent
135
143
 
136
144
  ```typescript
@@ -144,6 +152,7 @@ conversation.sendContextualUpdate(
144
152
  Sends a text message to the agent as if the user spoke it.
145
153
 
146
154
  **Parameters:**
155
+
147
156
  - `text`: The message text to send
148
157
 
149
158
  ```typescript
@@ -158,7 +167,7 @@ The agent will pause speaking for ~2 seconds after receiving this signal.
158
167
 
159
168
  ```typescript
160
169
  // Prevent interruption while user is typing
161
- textInput.addEventListener('input', () => {
170
+ textInput.addEventListener("input", () => {
162
171
  conversation.sendUserActivity();
163
172
  });
164
173
  ```
@@ -178,11 +187,12 @@ console.log(id);
178
187
  Mutes/unmutes the microphone
179
188
 
180
189
  **Parameters:**
190
+
181
191
  - `muted`: Whether the mic should be muted or not
182
192
 
183
193
  ```typescript
184
194
  conversation.setMicMuted(true); // mute
185
- conversation.setMicMuted(false) // unmute
195
+ conversation.setMicMuted(false); // unmute
186
196
  ```
187
197
 
188
198
  #### Properties
@@ -207,7 +217,7 @@ Override the WebRTC server URL (defaults to ElevenLabs' LiveKit server):
207
217
 
208
218
  ```typescript
209
219
  const conversation = useConversation({
210
- serverUrl: 'wss://your-custom-livekit-server.com'
220
+ serverUrl: "wss://your-custom-livekit-server.com",
211
221
  });
212
222
  ```
213
223
 
@@ -217,7 +227,7 @@ Override the token fetch endpoint (defaults to ElevenLabs' token API):
217
227
 
218
228
  ```typescript
219
229
  const conversation = useConversation({
220
- tokenFetchUrl: 'https://your-api.com/v1/conversation/token'
230
+ tokenFetchUrl: "https://your-api.com/v1/conversation/token",
221
231
  });
222
232
  ```
223
233
 
@@ -225,8 +235,8 @@ You can also override the token fetch URL on a per-session basis:
225
235
 
226
236
  ```typescript
227
237
  await conversation.startSession({
228
- agentId: 'your-agent-id',
229
- tokenFetchUrl: 'https://your-api.com/v1/conversation/token'
238
+ agentId: "your-agent-id",
239
+ tokenFetchUrl: "https://your-api.com/v1/conversation/token",
230
240
  });
231
241
  ```
232
242
 
@@ -234,10 +244,10 @@ await conversation.startSession({
234
244
 
235
245
  ```typescript
236
246
  const conversation = useConversation({
237
- serverUrl: 'wss://your-custom-livekit-server.com',
238
- tokenFetchUrl: 'https://your-api.com/v1/conversation/token',
239
- onConnect: () => console.log('Connected!'),
240
- onError: (error) => console.error('Error:', error)
247
+ serverUrl: "wss://your-custom-livekit-server.com",
248
+ tokenFetchUrl: "https://your-api.com/v1/conversation/token",
249
+ onConnect: () => console.log("Connected!"),
250
+ onError: error => console.error("Error:", error),
241
251
  });
242
252
  ```
243
253
 
@@ -253,6 +263,7 @@ Pass to `useConversation` hook:
253
263
  ## Requirements
254
264
 
255
265
  This SDK requires:
266
+
256
267
  - React Native with LiveKit dependencies installed and configured
257
268
  - Microphone permissions
258
269
 
@@ -264,4 +275,4 @@ Please, refer to the README.md file in the root of this repository.
264
275
 
265
276
  Please, create an issue first to discuss the proposed changes. Any contributions are welcome!
266
277
 
267
- Remember, if merged, your code will be used as part of a MIT licensed project. By submitting a Pull Request, you are giving your consent for your code to be integrated into this library.
278
+ Remember, if merged, your code will be used as part of a MIT licensed project. By submitting a Pull Request, you are giving your consent for your code to be integrated into this library.
@@ -1,13 +1,13 @@
1
- import type { LocalParticipant } from 'livekit-client';
2
- import type { Callbacks, ClientToolsConfig, ConversationEvent } from '../types';
1
+ import type { LocalParticipant } from "livekit-client";
2
+ import type { Callbacks, ClientToolsConfig, ConversationEvent } from "../types";
3
3
  interface MessageHandlerProps {
4
4
  onReady: (participant: LocalParticipant) => void;
5
5
  isConnected: boolean;
6
6
  callbacks: Callbacks;
7
7
  sendMessage: (message: unknown) => void;
8
- clientTools?: ClientToolsConfig['clientTools'];
8
+ clientTools?: ClientToolsConfig["clientTools"];
9
9
  updateCurrentEventId?: (eventId: number) => void;
10
10
  }
11
11
  export declare function isValidEvent(event: any): event is ConversationEvent;
12
- export declare const MessageHandler: ({ onReady, isConnected, callbacks, sendMessage, clientTools, updateCurrentEventId }: MessageHandlerProps) => null;
12
+ export declare const MessageHandler: ({ onReady, isConnected, callbacks, sendMessage, clientTools, updateCurrentEventId, }: MessageHandlerProps) => null;
13
13
  export {};
package/dist/lib.js CHANGED
@@ -1,2 +1,2 @@
1
- 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.0",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};
1
+ 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.2",l=function(t){var o=t.onReady,a=t.isConnected,l=t.callbacks,c=t.sendMessage,s=t.clientTools,i=void 0===s?{}:s,u=t.updateCurrentEventId,d=n.useLocalParticipant().localParticipant,f=r.default.useRef(1);return e.useEffect(function(){a&&d&&o(d)},[a,d,o]),n.useDataChannel(function(e){var n,t=new TextDecoder,r=JSON.parse(t.decode(e.payload));if(r.type){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==l.onMessage||l.onMessage({message:s,source:null!=(o=e.from)&&o.isAgent?"ai":"user"})),null!=(n=e.from)&&n.isAgent&&(null==l.onModeChange||l.onModeChange({mode:null!=(a=e.from)&&a.isSpeaking?"speaking":"listening"}),"agent_response"===r.type&&u)){var d=f.current++;u(d)}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(Object.prototype.hasOwnProperty.call(i,e.client_tool_call.tool_name)){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);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.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)}}(r);break;default:null==l.onDebug||l.onDebug(r)}}else null==l.onDebug||l.onDebug({type:"invalid_event",message:r})}),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"}},connectOptions:{rtcConfig:{iceTransportPolicy:"relay"}},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)},s=["serverUrl","tokenFetchUrl","clientTools"],i=/*#__PURE__*/e.createContext(null);exports.ElevenLabsProvider=function(t){var l=t.children;n.registerGlobals();var s=e.useState(""),u=s[0],d=s[1],f=e.useState(!1),v=f[0],h=f[1],_=e.useState("disconnected"),g=_[0],m=_[1],C=e.useState("wss://livekit.rtc.elevenlabs.io"),p=C[0],b=C[1],k=e.useState(void 0),y=k[0],S=k[1],E=e.useState(""),P=E[0],w=E[1],x=e.useState(!1),T=x[0],I=x[1],D=e.useState(!1),U=D[0],M=D[1],R=r.default.useRef(1),F=r.default.useRef(1),O=r.default.useRef({}),j=function(){var n=e.useRef({}),t=e.useCallback(function(e){n.current=e},[]);return{callbacksRef:n,setCallbacks:t}}(),L=j.callbacksRef,A=j.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 s=e.useState({}),i=s[0],u=s[1],d=e.useState(null),f=d[0],v=d[1],h=e.useState({}),_=h[0],g=h[1],m=e.useState(void 0),C=m[0],p=m[1];return{startSession:e.useCallback(function(e){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);l(n),o(i),r(!0)}var i;t("connecting"),null==n.current.onStatusChange||n.current.onStatusChange({status:"connecting"}),u(e.overrides||{}),v(e.customLlmExtraBody||null),g(e.dynamicVariables||{}),p(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){i=e});throw new Error("Either conversationToken or agentId is required")}();i=e.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(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({reason:"user"})}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:i,customLlmExtraBody:f,dynamicVariables:_,userId:C}}(L,m,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],s=e.useState(null),i=s[0],u=s[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:i,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({reason:"user"})},[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,m,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;U!==e&&(M(e),null==L.current.onCanSendFeedbackChange||L.current.onCanSendFeedbackChange({canSendFeedback:e}))},[U,L]),ae=r.default.useCallback(function(e){U?(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.")},[U,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]),se=r.default.useCallback(function(e){if(Q(e),H){var n=function(e){var n,t,r,o,l,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==(r=e.overrides.agent)?void 0:r.firstMessage,language:null==(o=e.overrides.agent)?void 0:o.language},tts:{voice_id:null==(l=e.overrides.tts)?void 0:l.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)||a},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});re(n)}},[Q,H,q,K,G,z,re]),ie={startSession:B,endSession:J,status:g,isSpeaking:T,canSendFeedback:U,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){O.current=e},[]);/*#__PURE__*/return r.default.createElement(i.Provider,{value:{conversation:ie,callbacksRef:L,serverUrl:p,tokenFetchUrl:y,clientTools:O.current,setCallbacks:N,setServerUrl:b,setTokenFetchUrl:S,setClientTools:ue}},/*#__PURE__*/r.default.createElement(c,{serverUrl:p,token:u,connect:v,onConnected:ee,onDisconnected:ne,onError:$,roomConnected:Z,callbacks:L.current,onParticipantReady:se,sendMessage:re,clientTools:O.current,updateCurrentEventId:ce},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 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,s);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};
2
2
  //# sourceMappingURL=lib.js.map
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.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.3.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent, ConversationEvent } 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 clientTools?: ClientToolsConfig['clientTools'];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: any): event is ConversationEvent {\n return !!event.type;\n}\n\nexport const MessageHandler = ({\n onReady,\n isConnected,\n callbacks,\n sendMessage,\n clientTools = {},\n updateCurrentEventId\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 useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.client_tool_call.tool_name\n )\n ) {\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);\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 callbacks.onMessage?.({\n message,\n source: msg.from?.isAgent ? 'ai' : 'user',\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 default:\n callbacks.onDebug?.(message);\n break;\n }\n });\n\n return null;\n};","import 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 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}: 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 />\n {children}\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: () => 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 if (clientTools) {\n context.setClientTools(clientTools);\n }\n\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);\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 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 = () => 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 if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, userId, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl: setTokenFetchUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\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 >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\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(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.(\"User ended conversation\");\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\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 } 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) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId });\n }, [conversationId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.(\"disconnected\");\n }, [callbacksRef, setStatus]);\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 source_info: {\n source: \"react_native_sdk\",\n version: config.overrides?.client?.version || PACKAGE_VERSION,\n },\n };\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","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from","_msg$from2","decoder","TextDecoder","message","JSON","parse","decode","payload","type","_msg$from3","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","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","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","event","_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","onDisconnect","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","setMicMuted","muted","setMicrophoneEnabled","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","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","getId","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
1
+ {"version":3,"file":"lib.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.3.2\";\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 clientTools?: ClientToolsConfig[\"clientTools\"];\n updateCurrentEventId?: (eventId: number) => void;\n}\n\nexport function isValidEvent(event: any): event is ConversationEvent {\n return !!event.type;\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}: 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 useEffect(() => {\n if (isConnected && localParticipant) {\n onReady(localParticipant);\n }\n }, [isConnected, localParticipant, onReady]);\n\n const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {\n if (\n Object.prototype.hasOwnProperty.call(\n clientTools,\n clientToolCall.client_tool_call.tool_name\n )\n ) {\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: msg.from?.isAgent ? \"ai\" : \"user\",\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 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 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}: 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 connectOptions={{\n rtcConfig: {\n iceTransportPolicy: 'relay',\n },\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 />\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: () => 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 if (clientTools) {\n context.setClientTools(clientTools);\n }\n\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);\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 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 = () => 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 if (localParticipant) {\n const overridesEvent = constructOverrides({\n overrides,\n customLlmExtraBody,\n dynamicVariables,\n userId,\n });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, userId, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\n getId,\n setMicMuted,\n sendFeedback,\n sendContextualUpdate: (text: string) => {\n sendMessage({\n type: \"contextual_update\",\n text,\n });\n },\n sendUserMessage: (text: string) => {\n sendMessage({\n type: \"user_message\",\n text,\n });\n },\n sendUserActivity: () => {\n sendMessage({\n type: \"user_activity\",\n });\n },\n };\n\n // Create setClientTools function that only updates ref\n const setClientTools = React.useCallback((tools: ClientToolsConfig['clientTools']) => {\n clientToolsRef.current = tools;\n }, []);\n\n const contextValue: ElevenLabsContextType = {\n conversation,\n callbacksRef,\n serverUrl,\n tokenFetchUrl,\n clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\n setTokenFetchUrl: setTokenFetchUrl,\n setClientTools,\n };\n\n return (\n <ElevenLabsContext.Provider value={contextValue}>\n <LiveKitRoomWrapper\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 >\n {children}\n </LiveKitRoomWrapper>\n </ElevenLabsContext.Provider>\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(async () => {\n try {\n setConnect(false);\n setToken(\"\");\n setStatus(\"disconnected\");\n callbacksRef.current.onStatusChange?.({ status: \"disconnected\" });\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n } catch (error) {\n callbacksRef.current.onError?.(error as string);\n throw error;\n }\n }, [callbacksRef, setConnect, setToken, setStatus]);\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 } 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) => {\n const [roomConnected, setRoomConnected] = useState(false);\n const [localParticipant, setLocalParticipant] =\n useState<LocalParticipant | null>(null);\n\n useEffect(() => {\n const start = async () => {\n await AudioSession.startAudioSession();\n };\n\n start();\n return () => {\n AudioSession.stopAudioSession();\n };\n }, []);\n\n const handleParticipantReady = useCallback(\n (participant: LocalParticipant) => {\n setLocalParticipant(participant);\n },\n []\n );\n\n const handleConnected = useCallback(() => {\n setRoomConnected(true);\n setStatus(\"connected\");\n callbacksRef.current.onConnect?.({ conversationId });\n }, [conversationId, callbacksRef, setStatus]);\n\n const handleDisconnected = useCallback(() => {\n setRoomConnected(false);\n setStatus(\"disconnected\");\n setLocalParticipant(null);\n callbacksRef.current.onDisconnect?.({ reason: \"user\" });\n }, [callbacksRef, setStatus]);\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","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from2","decoder","TextDecoder","message","JSON","parse","decode","payload","type","_msg$from","_msg$from3","messageText","event","user_transcription_event","user_transcript","agent_response_event","agent_response","extractMessageText","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","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","onDebug","LiveKitRoomWrapper","children","createElement","LiveKitRoom","serverUrl","token","connect","audio","video","options","adaptiveStream","pixelDensity","connectOptions","rtcConfig","iceTransportPolicy","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","onDisconnect","reason","useConversationSession","_useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","handleParticipantReady","participant","handleConnected","onConnect","handleDisconnected","handleError","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","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","getId","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e,{useRef as n,useCallback as t,useState as o,useEffect as r,useContext as l,createContext as a}from"react";import{AudioSession as c,useLocalParticipant as s,useDataChannel as i,LiveKitRoom as d,registerGlobals as u}from"@livekit/react-native";function v(){return v=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},v.apply(null,arguments)}const g="0.3.0",_=({onReady:n,isConnected:t,callbacks:o,sendMessage:l,clientTools:a={},updateCurrentEventId:c})=>{const{localParticipant:d}=s(),u=e.useRef(1);return r(()=>{t&&d&&n(d)},[t,d,n]),i(e=>{var n,t;const r=new TextDecoder,s=JSON.parse(r.decode(e.payload));if(s.type){var i;if(null==o.onMessage||o.onMessage({message:s,source:null!=(n=e.from)&&n.isAgent?"ai":"user"}),null!=(t=e.from)&&t.isAgent&&(null==o.onModeChange||o.onModeChange({mode:null!=(i=e.from)&&i.isSpeaking?"speaking":"listening"}),"agent_response"===s.type&&c)){const e=u.current++;c(e)}switch(s.type){case"ping":l({type:"pong",event_id:s.ping_event.event_id});break;case"client_tool_call":(async e=>{if(Object.prototype.hasOwnProperty.call(a,e.client_tool_call.tool_name))try{var n;const t=null!=(n=await a[e.client_tool_call.tool_name](e.client_tool_call.parameters))?n:"Client tool execution successful.",o="object"==typeof t?JSON.stringify(t):String(t);l({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:o,is_error:!1})}catch(n){null==o.onError||o.onError(`Client tool execution failed with following error: ${null==n?void 0:n.message}`,{clientToolName:e.client_tool_call.tool_name}),l({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})}else{if(o.onUnhandledClientToolCall)return void o.onUnhandledClientToolCall(e);const n=`Client tool with name ${e.client_tool_call.tool_name} is not defined on client`;null==o.onError||o.onError(n,{clientToolName:e.client_tool_call.tool_name}),l({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:n,is_error:!0})}})(s);break;default:null==o.onDebug||o.onDebug(s)}}else null==o.onDebug||o.onDebug({type:"invalid_event",message:s})}),null},m=({children:n,serverUrl:t,token:o,connect:r,onConnected:l,onDisconnected:a,onError:c,roomConnected:s,callbacks:i,onParticipantReady:u,sendMessage:v,clientTools:g,updateCurrentEventId:m})=>/*#__PURE__*/e.createElement(d,{serverUrl:t,token:o,connect:r,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:l,onDisconnected:a,onError:c},/*#__PURE__*/e.createElement(_,{onReady:u,isConnected:s,callbacks:i,sendMessage:v,clientTools:g,updateCurrentEventId:m}),n),C=["serverUrl","tokenFetchUrl","clientTools"],p=/*#__PURE__*/a(null),k=(n={})=>{const t=l(p);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");const{serverUrl:o,tokenFetchUrl:r,clientTools:a}=n,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}(n,C);return e.useEffect(()=>{o&&t.setServerUrl(o)},[t,o]),e.useEffect(()=>{r&&t.setTokenFetchUrl(r)},[t,r]),a&&t.setClientTools(a),t.setCallbacks(c),t.conversation},b=({children:l})=>{u();const[a,s]=o(""),[i,d]=o(!1),[_,C]=o("disconnected"),[k,b]=o("wss://livekit.rtc.elevenlabs.io"),[h,f]=o(void 0),[y,E]=o(""),[S,w]=o(!1),[x,T]=o(!1),I=e.useRef(1),U=e.useRef(1),D=e.useRef({}),{callbacksRef:M,setCallbacks:F}=(()=>{const e=n({}),o=t(n=>{e.current=n},[]);return{callbacksRef:e,setCallbacks:o}})(),R=e.useCallback(e=>{const n=v({},e,{onModeChange:n=>{w("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});F(n)},[F]),{startSession:P,endSession:O,overrides:L,customLlmExtraBody:N,dynamicVariables:A,userId:V}=((e,n,r,l,a,c)=>{const[s,i]=o({}),[d,u]=o(null),[v,_]=o({}),[m,C]=o(void 0);return{startSession:t(async t=>{try{let o;if(n("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),i(t.overrides||{}),u(t.customLlmExtraBody||null),_(t.dynamicVariables||{}),C(t.userId),t.conversationToken)o=t.conversationToken;else{if(!t.agentId)throw new Error("Either conversationToken or agentId is required");{console.info("Getting conversation token for agentId:",t.agentId);const e=t.tokenFetchUrl||c;o=await(async(e,n)=>{const t=n||"https://api.elevenlabs.io/v1/convai/conversation/token",o=await fetch(`${t}?agent_id=${e}&source=react_native_sdk&version=${g}`),r=await o.json();if(!o.ok)throw new Error(`Failed to get conversation token: ${r.detail.message}`);if(!r.token)throw new Error("No conversation token received from API");return r.token})(t.agentId,e)}}const s=(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"),""}})(o);a(s),l(o),r(!0)}catch(t){throw n("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(t),t}},[e,n,r,l,a,c]),endSession:t(async()=>{try{r(!1),l(""),n("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onDisconnect||e.current.onDisconnect("User ended conversation")}catch(n){throw null==e.current.onError||e.current.onError(n),n}},[e,r,l,n]),overrides:s,customLlmExtraBody:d,dynamicVariables:v,userId:m}})(M,C,d,s,E,h),{roomConnected:$,localParticipant:B,handleParticipantReady:j,handleConnected:J,handleDisconnected:K,handleError:q}=((e,n,l)=>{const[a,s]=o(!1),[i,d]=o(null);return r(()=>((async()=>{await c.startAudioSession()})(),()=>{c.stopAudioSession()}),[]),{roomConnected:a,localParticipant:i,handleParticipantReady:t(e=>{d(e)},[]),handleConnected:t(()=>{s(!0),n("connected"),null==e.current.onConnect||e.current.onConnect({conversationId:l})},[l,e,n]),handleDisconnected:t(()=>{s(!1),n("disconnected"),d(null),null==e.current.onDisconnect||e.current.onDisconnect("disconnected")},[e,n]),handleError:t(n=>{console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e])}})(M,C,y),z=e.useCallback(()=>{I.current=1,U.current=1,T(!1),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:!1}),J()},[J,M]),G=e.useCallback(()=>{T(!1),K()},[K]),{sendMessage:W}=((e,n,o)=>({sendMessage:t(async t=>{if("connected"===e&&n)try{const e=(new TextEncoder).encode(JSON.stringify(t));await n.publishData(e,{reliable:!0})}catch(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==o.current.onError||o.current.onError(e)}else console.warn("Cannot send message: room not connected or no local participant")},[e,n,o])}))(_,B,M),Z=e.useCallback(()=>{const e=I.current!==U.current;x!==e&&(T(e),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:e}))},[x,M]),H=e.useCallback(e=>{x?(W({type:"feedback",score:e?"like":"dislike",event_id:I.current}),U.current=I.current,Z()):console.warn(0===U.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[x,W,Z]);e.useCallback(e=>{console.warn("setVolume is not yet implemented in React Native SDK")},[]);const Q=e.useCallback(e=>{B&&B.setMicrophoneEnabled(!e)},[B]),X=e.useCallback(e=>{I.current=e,Z()},[Z]),Y=e.useCallback(e=>{if(j(e),B){const e=function(e){const n={type:"conversation_initiation_client_data"};var t,o,r,l,a,c;return e.overrides&&(n.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==(l=e.overrides.tts)?void 0:l.voiceId},conversation:{text_only:null==(a=e.overrides.conversation)?void 0:a.textOnly},source_info:{source:"react_native_sdk",version:(null==(c=e.overrides)||null==(c=c.client)?void 0:c.version)||g}}),e.customLlmExtraBody&&(n.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(n.dynamic_variables=e.dynamicVariables),e.userId&&(n.user_id=String(e.userId)),n}({overrides:L,customLlmExtraBody:N,dynamicVariables:A,userId:V});W(e)}},[j,B,L,N,A,V,W]),ee={startSession:P,endSession:O,status:_,isSpeaking:S,canSendFeedback:x,getId:()=>y,setMicMuted:Q,sendFeedback:H,sendContextualUpdate:e=>{W({type:"contextual_update",text:e})},sendUserMessage:e=>{W({type:"user_message",text:e})},sendUserActivity:()=>{W({type:"user_activity"})}},ne=e.useCallback(e=>{D.current=e},[]);/*#__PURE__*/return e.createElement(p.Provider,{value:{conversation:ee,callbacksRef:M,serverUrl:k,tokenFetchUrl:h,clientTools:D.current,setCallbacks:R,setServerUrl:b,setTokenFetchUrl:f,setClientTools:ne}},/*#__PURE__*/e.createElement(m,{serverUrl:k,token:a,connect:i,onConnected:z,onDisconnected:G,onError:q,roomConnected:$,callbacks:M.current,onParticipantReady:Y,sendMessage:W,clientTools:D.current,updateCurrentEventId:X},l))};export{b as ElevenLabsProvider,k as useConversation};
1
+ import e,{useRef as n,useCallback as t,useState as o,useEffect as r,useContext as a,createContext as l}from"react";import{AudioSession as s,useLocalParticipant as c,useDataChannel as i,LiveKitRoom as d,registerGlobals as u}from"@livekit/react-native";function v(){return v=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},v.apply(null,arguments)}const _="0.3.2",g=({onReady:n,isConnected:t,callbacks:o,sendMessage:a,clientTools:l={},updateCurrentEventId:s})=>{const{localParticipant:d}=c(),u=e.useRef(1);return r(()=>{t&&d&&n(d)},[t,d,n]),i(e=>{var n;const t=new TextDecoder,r=JSON.parse(t.decode(e.payload));if(!r.type)return void(null==o.onDebug||o.onDebug({type:"invalid_event",message:r}));const 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);var i,d;if(null!==c&&(null==o.onMessage||o.onMessage({message:c,source:null!=(i=e.from)&&i.isAgent?"ai":"user"})),null!=(n=e.from)&&n.isAgent&&(null==o.onModeChange||o.onModeChange({mode:null!=(d=e.from)&&d.isSpeaking?"speaking":"listening"}),"agent_response"===r.type&&s)){const e=u.current++;s(e)}switch(r.type){case"ping":a({type:"pong",event_id:r.ping_event.event_id});break;case"client_tool_call":(async e=>{if(Object.prototype.hasOwnProperty.call(l,e.client_tool_call.tool_name))try{var n;const t=null!=(n=await l[e.client_tool_call.tool_name](e.client_tool_call.parameters))?n:"Client tool execution successful.",o="object"==typeof t?JSON.stringify(t):String(t);a({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:o,is_error:!1})}catch(n){null==o.onError||o.onError(`Client tool execution failed with following error: ${null==n?void 0:n.message}`,{clientToolName:e.client_tool_call.tool_name}),a({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})}else{if(o.onUnhandledClientToolCall)return void o.onUnhandledClientToolCall(e.client_tool_call);const n=`Client tool with name ${e.client_tool_call.tool_name} is not defined on client`;null==o.onError||o.onError(n,{clientToolName:e.client_tool_call.tool_name}),a({type:"client_tool_result",tool_call_id:e.client_tool_call.tool_call_id,result:n,is_error:!0})}})(r);break;default:null==o.onDebug||o.onDebug(r)}}),null},p=({children:n,serverUrl:t,token:o,connect:r,onConnected:a,onDisconnected:l,onError:s,roomConnected:c,callbacks:i,onParticipantReady:u,sendMessage:v,clientTools:_,updateCurrentEventId:p})=>/*#__PURE__*/e.createElement(d,{serverUrl:t,token:o,connect:r,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},connectOptions:{rtcConfig:{iceTransportPolicy:"relay"}},onConnected:a,onDisconnected:l,onError:s},/*#__PURE__*/e.createElement(g,{onReady:u,isConnected:c,callbacks:i,sendMessage:v,clientTools:_,updateCurrentEventId:p}),n),m=["serverUrl","tokenFetchUrl","clientTools"],C=/*#__PURE__*/l(null),k=(n={})=>{const t=a(C);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");const{serverUrl:o,tokenFetchUrl:r,clientTools:l}=n,s=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}(n,m);return e.useEffect(()=>{o&&t.setServerUrl(o)},[t,o]),e.useEffect(()=>{r&&t.setTokenFetchUrl(r)},[t,r]),l&&t.setClientTools(l),t.setCallbacks(s),t.conversation},f=({children:a})=>{u();const[l,c]=o(""),[i,d]=o(!1),[g,m]=o("disconnected"),[k,f]=o("wss://livekit.rtc.elevenlabs.io"),[y,h]=o(void 0),[b,E]=o(""),[S,w]=o(!1),[x,T]=o(!1),I=e.useRef(1),U=e.useRef(1),D=e.useRef({}),{callbacksRef:M,setCallbacks:F}=(()=>{const e=n({}),o=t(n=>{e.current=n},[]);return{callbacksRef:e,setCallbacks:o}})(),R=e.useCallback(e=>{const n=v({},e,{onModeChange:n=>{w("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});F(n)},[F]),{startSession:P,endSession:O,overrides:L,customLlmExtraBody:N,dynamicVariables:A,userId:V}=((e,n,r,a,l,s)=>{const[c,i]=o({}),[d,u]=o(null),[v,g]=o({}),[p,m]=o(void 0);return{startSession:t(async t=>{try{let o;if(n("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),i(t.overrides||{}),u(t.customLlmExtraBody||null),g(t.dynamicVariables||{}),m(t.userId),t.conversationToken)o=t.conversationToken;else{if(!t.agentId)throw new Error("Either conversationToken or agentId is required");{console.info("Getting conversation token for agentId:",t.agentId);const e=t.tokenFetchUrl||s;o=await(async(e,n)=>{const t=n||"https://api.elevenlabs.io/v1/convai/conversation/token",o=await fetch(`${t}?agent_id=${e}&source=react_native_sdk&version=${_}`),r=await o.json();if(!o.ok)throw new Error(`Failed to get conversation token: ${r.detail.message}`);if(!r.token)throw new Error("No conversation token received from API");return r.token})(t.agentId,e)}}const c=(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"),""}})(o);l(c),a(o),r(!0)}catch(t){throw n("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(t),t}},[e,n,r,a,l,s]),endSession:t(async()=>{try{r(!1),a(""),n("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onDisconnect||e.current.onDisconnect({reason:"user"})}catch(n){throw null==e.current.onError||e.current.onError(n),n}},[e,r,a,n]),overrides:c,customLlmExtraBody:d,dynamicVariables:v,userId:p}})(M,m,d,c,E,y),{roomConnected:$,localParticipant:B,handleParticipantReady:j,handleConnected:J,handleDisconnected:K,handleError:q}=((e,n,a)=>{const[l,c]=o(!1),[i,d]=o(null);return r(()=>((async()=>{await s.startAudioSession()})(),()=>{s.stopAudioSession()}),[]),{roomConnected:l,localParticipant:i,handleParticipantReady:t(e=>{d(e)},[]),handleConnected:t(()=>{c(!0),n("connected"),null==e.current.onConnect||e.current.onConnect({conversationId:a})},[a,e,n]),handleDisconnected:t(()=>{c(!1),n("disconnected"),d(null),null==e.current.onDisconnect||e.current.onDisconnect({reason:"user"})},[e,n]),handleError:t(n=>{console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e])}})(M,m,b),z=e.useCallback(()=>{I.current=1,U.current=1,T(!1),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:!1}),J()},[J,M]),G=e.useCallback(()=>{T(!1),K()},[K]),{sendMessage:W}=((e,n,o)=>({sendMessage:t(async t=>{if("connected"===e&&n)try{const e=(new TextEncoder).encode(JSON.stringify(t));await n.publishData(e,{reliable:!0})}catch(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==o.current.onError||o.current.onError(e)}else console.warn("Cannot send message: room not connected or no local participant")},[e,n,o])}))(g,B,M),Z=e.useCallback(()=>{const e=I.current!==U.current;x!==e&&(T(e),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:e}))},[x,M]),H=e.useCallback(e=>{x?(W({type:"feedback",score:e?"like":"dislike",event_id:I.current}),U.current=I.current,Z()):console.warn(0===U.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[x,W,Z]);e.useCallback(e=>{console.warn("setVolume is not yet implemented in React Native SDK")},[]);const Q=e.useCallback(e=>{B&&B.setMicrophoneEnabled(!e)},[B]),X=e.useCallback(e=>{I.current=e,Z()},[Z]),Y=e.useCallback(e=>{if(j(e),B){const e=function(e){var n;const t={type:"conversation_initiation_client_data"};var o,r,a,l,s;return e.overrides&&(t.conversation_config_override={agent:{prompt:null==(o=e.overrides.agent)?void 0:o.prompt,first_message:null==(r=e.overrides.agent)?void 0:r.firstMessage,language:null==(a=e.overrides.agent)?void 0:a.language},tts:{voice_id:null==(l=e.overrides.tts)?void 0:l.voiceId},conversation:{text_only:null==(s=e.overrides.conversation)?void 0:s.textOnly}}),t.source_info={source:"react_native_sdk",version:(null==(n=e.overrides)||null==(n=n.client)?void 0:n.version)||_},e.customLlmExtraBody&&(t.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(t.dynamic_variables=e.dynamicVariables),e.userId&&(t.user_id=String(e.userId)),t}({overrides:L,customLlmExtraBody:N,dynamicVariables:A,userId:V});W(e)}},[j,B,L,N,A,V,W]),ee={startSession:P,endSession:O,status:g,isSpeaking:S,canSendFeedback:x,getId:()=>b,setMicMuted:Q,sendFeedback:H,sendContextualUpdate:e=>{W({type:"contextual_update",text:e})},sendUserMessage:e=>{W({type:"user_message",text:e})},sendUserActivity:()=>{W({type:"user_activity"})}},ne=e.useCallback(e=>{D.current=e},[]);/*#__PURE__*/return e.createElement(C.Provider,{value:{conversation:ee,callbacksRef:M,serverUrl:k,tokenFetchUrl:y,clientTools:D.current,setCallbacks:R,setServerUrl:f,setTokenFetchUrl:h,setClientTools:ne}},/*#__PURE__*/e.createElement(p,{serverUrl:k,token:l,connect:i,onConnected:z,onDisconnected:G,onError:q,roomConnected:$,callbacks:M.current,onParticipantReady:Y,sendMessage:W,clientTools:D.current,updateCurrentEventId:X},a))};export{f as ElevenLabsProvider,k as useConversation};
2
2
  //# sourceMappingURL=lib.modern.js.map