@elevenlabs/react-native 0.1.0

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/ElevenLabsProvider.d.ts +22 -0
  4. package/dist/ElevenLabsProvider.test.d.ts +1 -0
  5. package/dist/components/LiveKitRoomWrapper.d.ts +20 -0
  6. package/dist/components/MessageHandler.d.ts +12 -0
  7. package/dist/hooks/useConversationCallbacks.d.ts +5 -0
  8. package/dist/hooks/useConversationSession.d.ts +28 -0
  9. package/dist/hooks/useLiveKitRoom.d.ts +12 -0
  10. package/dist/hooks/useMessageSending.d.ts +7 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/lib.js +2 -0
  13. package/dist/lib.js.map +1 -0
  14. package/dist/lib.modern.js +2 -0
  15. package/dist/lib.modern.js.map +1 -0
  16. package/dist/lib.module.js +2 -0
  17. package/dist/lib.module.js.map +1 -0
  18. package/dist/lib.umd.js +2 -0
  19. package/dist/lib.umd.js.map +1 -0
  20. package/dist/types.d.ts +109 -0
  21. package/dist/utils/constants.d.ts +1 -0
  22. package/dist/utils/overrides.d.ts +2 -0
  23. package/dist/utils/tokenUtils.d.ts +2 -0
  24. package/dist/version.d.ts +1 -0
  25. package/eslint.config.cjs +1 -0
  26. package/jest.config.cjs +263 -0
  27. package/jest.rn-mock.js +15 -0
  28. package/package.json +64 -0
  29. package/src/ElevenLabsProvider.test.tsx +187 -0
  30. package/src/ElevenLabsProvider.tsx +259 -0
  31. package/src/components/LiveKitRoomWrapper.tsx +63 -0
  32. package/src/components/MessageHandler.tsx +127 -0
  33. package/src/hooks/useConversationCallbacks.ts +15 -0
  34. package/src/hooks/useConversationSession.ts +88 -0
  35. package/src/hooks/useLiveKitRoom.ts +62 -0
  36. package/src/hooks/useMessageSending.ts +33 -0
  37. package/src/index.ts +9 -0
  38. package/src/types.ts +150 -0
  39. package/src/utils/constants.ts +1 -0
  40. package/src/utils/overrides.ts +40 -0
  41. package/src/utils/tokenUtils.ts +31 -0
  42. package/src/version.ts +2 -0
  43. package/tsconfig.json +18 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ElevenLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # ElevenLabs React Native SDK
2
+
3
+ A React Native SDK for ElevenLabs Conversational AI.
4
+
5
+ ## Features
6
+
7
+ - Real-time voice conversations with AI agents
8
+ - WebRTC communication through LiveKit
9
+ - Expo compatible (development builds only)
10
+
11
+ ## Notes
12
+
13
+ This SDK was designed and built for use with the Expo framework. Due to it requiring native code, Expo Go is not supported at this time.
14
+
15
+ ## Example app
16
+
17
+ There is an example app using this SDK located in the examples/react-native-expo directory. The readme there includes instructions on how to run the example app.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @elevenlabs/react-native @livekit/react-native @livekit/react-native-webrtc livekit-client
23
+ ```
24
+
25
+ **Required Dependencies:**
26
+ - `@livekit/react-native` - LiveKit React Native SDK (native modules)
27
+ - `@livekit/react-native-webrtc` - WebRTC implementation for React Native
28
+ - `livekit-client` - LiveKit JavaScript client
29
+
30
+ *Note: LiveKit dependencies are required due to React Native's native module architecture and must be installed in your app's root dependencies.*
31
+
32
+ > **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
+
34
+ ## Quick Start
35
+
36
+ ### Basic Usage
37
+
38
+ ```typescript
39
+ import React from 'react';
40
+ import { ElevenLabsProvider, useConversation } from '@elevenlabs/react-native';
41
+
42
+ function App() {
43
+ return (
44
+ <ElevenLabsProvider>
45
+ <ConversationComponent />
46
+ </ElevenLabsProvider>
47
+ );
48
+ }
49
+
50
+ function ConversationComponent() {
51
+ const conversation = useConversation({
52
+ onConnect: () => console.log('Connected'),
53
+ onDisconnect: () => console.log('Disconnected'),
54
+ onMessage: (message) => console.log('Message:', message),
55
+ onError: (error) => console.error('Error:', error),
56
+ });
57
+
58
+ const startSession = async () => {
59
+ await conversation.startSession({
60
+ agentId: 'your-agent-id'
61
+ });
62
+ };
63
+
64
+ const endSession = async () => {
65
+ await conversation.endSession();
66
+ };
67
+
68
+ const sendFeedback = (isPositive: boolean) => {
69
+ if (conversation.canSendFeedback) {
70
+ conversation.sendFeedback(isPositive);
71
+ }
72
+ };
73
+
74
+ const sendUserMessage = (text: string) => {
75
+ conversation.sendUserMessage(text);
76
+ };
77
+
78
+ return (
79
+ // Your UI components
80
+ // Use conversation.status, conversation.isSpeaking, conversation.canSendFeedback
81
+ );
82
+ }
83
+ ```
84
+
85
+ ## API Reference
86
+
87
+ ### useConversation Hook
88
+
89
+ Returns a conversation object with the following methods and properties:
90
+
91
+ #### `startSession(config: ConversationConfig): Promise<void>`
92
+
93
+ Starts a new conversation session.
94
+
95
+ **Parameters:**
96
+ - `config.agentId`: ElevenLabs agent ID, not needed if you provide a conversationToken.
97
+ - `config.conversationToken`: Optional pre-generated token, used for private agents that require authentication via your ElevenLabs API key.
98
+
99
+ ```typescript
100
+ await conversation.startSession({
101
+ agentId: 'your-agent-id'
102
+ });
103
+ ```
104
+
105
+ #### `endSession(): Promise<void>`
106
+
107
+ Ends the current conversation session.
108
+
109
+ ```typescript
110
+ await conversation.endSession();
111
+ ```
112
+
113
+ #### `sendFeedback(like: boolean): void`
114
+
115
+ Sends binary feedback for the most recent agent response.
116
+
117
+ **Parameters:**
118
+ - `like`: `true` for positive feedback, `false` for negative feedback
119
+
120
+ ```typescript
121
+ // Positive feedback
122
+ conversation.sendFeedback(true);
123
+
124
+ // Negative feedback
125
+ conversation.sendFeedback(false);
126
+ ```
127
+
128
+ #### `sendContextualUpdate(text: string): void`
129
+
130
+ Sends contextual information to the agent that won't trigger a response.
131
+
132
+ **Parameters:**
133
+ - `text`: Contextual information for the agent
134
+
135
+ ```typescript
136
+ conversation.sendContextualUpdate(
137
+ "User navigated to the profile page. Consider this for next response."
138
+ );
139
+ ```
140
+
141
+ #### `sendUserMessage(text: string): void`
142
+
143
+ Sends a text message to the agent as if the user spoke it.
144
+
145
+ **Parameters:**
146
+ - `text`: The message text to send
147
+
148
+ ```typescript
149
+ conversation.sendUserMessage("Hello, how are you today?");
150
+ ```
151
+
152
+ #### `sendUserActivity(): void`
153
+
154
+ Notifies the agent about user activity to prevent interruptions.
155
+
156
+ The agent will pause speaking for ~2 seconds after receiving this signal.
157
+
158
+ ```typescript
159
+ // Prevent interruption while user is typing
160
+ textInput.addEventListener('input', () => {
161
+ conversation.sendUserActivity();
162
+ });
163
+ ```
164
+
165
+ #### Properties
166
+
167
+ - `status: ConversationStatus` - Current conversation status ('connecting' | 'connected' | 'disconnected')
168
+ - `isSpeaking: boolean` - Whether the agent is currently speaking
169
+ - `canSendFeedback: boolean` - Whether feedback can be sent for the current response
170
+
171
+ ```typescript
172
+ console.log(conversation.status);
173
+ console.log(conversation.isSpeaking);
174
+ console.log(conversation.canSendFeedback);
175
+ ```
176
+
177
+ ### Callback Options
178
+
179
+ Pass to `useConversation` hook:
180
+
181
+ - `onConnect: () => void` - Called when connected
182
+ - `onDisconnect: (details?: unknown) => void` - Called when disconnected
183
+ - `onMessage: (message: unknown) => void` - Called when message received
184
+ - `onError: (error: unknown) => void` - Called on error
185
+
186
+ ## Requirements
187
+
188
+ This SDK requires:
189
+ - React Native with LiveKit dependencies installed and configured
190
+ - Microphone permissions
191
+
192
+ ## Development
193
+
194
+ Please, refer to the README.md file in the root of this repository.
195
+
196
+ ## Contributing
197
+
198
+ Please, create an issue first to discuss the proposed changes. Any contributions are welcome!
199
+
200
+ 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.
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { Callbacks, ConversationConfig, ConversationStatus, ClientToolsConfig } from './types';
3
+ interface ConversationOptions extends Callbacks, Partial<ClientToolsConfig> {
4
+ serverUrl?: string;
5
+ }
6
+ interface Conversation {
7
+ startSession: (config: ConversationConfig) => Promise<void>;
8
+ endSession: () => Promise<void>;
9
+ status: ConversationStatus;
10
+ isSpeaking: boolean;
11
+ canSendFeedback: boolean;
12
+ sendFeedback: (like: boolean) => void;
13
+ sendContextualUpdate: (text: string) => void;
14
+ sendUserMessage: (text: string) => void;
15
+ sendUserActivity: () => void;
16
+ }
17
+ export declare const useConversation: (options?: ConversationOptions) => Conversation;
18
+ interface ElevenLabsProviderProps {
19
+ children: React.ReactNode;
20
+ }
21
+ export declare const ElevenLabsProvider: React.FC<ElevenLabsProviderProps>;
22
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { LocalParticipant } from 'livekit-client';
3
+ import type { Callbacks, ClientToolsConfig } from '../types';
4
+ interface LiveKitRoomWrapperProps {
5
+ children: React.ReactNode;
6
+ serverUrl: string;
7
+ token: string;
8
+ connect: boolean;
9
+ onConnected: () => void;
10
+ onDisconnected: () => void;
11
+ onError: (error: Error) => void;
12
+ roomConnected: boolean;
13
+ callbacks: Callbacks;
14
+ onParticipantReady: (participant: LocalParticipant) => void;
15
+ sendMessage: (message: unknown) => void;
16
+ clientTools: ClientToolsConfig['clientTools'];
17
+ updateCurrentEventId?: (eventId: number) => void;
18
+ }
19
+ export declare const LiveKitRoomWrapper: ({ children, serverUrl, token, connect, onConnected, onDisconnected, onError, roomConnected, callbacks, onParticipantReady, sendMessage, clientTools, updateCurrentEventId, }: LiveKitRoomWrapperProps) => React.JSX.Element;
20
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { LocalParticipant } from 'livekit-client';
2
+ import type { Callbacks, ClientToolsConfig } from '../types';
3
+ interface MessageHandlerProps {
4
+ onReady: (participant: LocalParticipant) => void;
5
+ isConnected: boolean;
6
+ callbacks: Callbacks;
7
+ sendMessage: (message: unknown) => void;
8
+ clientTools?: ClientToolsConfig['clientTools'];
9
+ updateCurrentEventId?: (eventId: number) => void;
10
+ }
11
+ export declare const MessageHandler: ({ onReady, isConnected, callbacks, sendMessage, clientTools, updateCurrentEventId }: MessageHandlerProps) => null;
12
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { Callbacks } from "../types";
2
+ export declare const useConversationCallbacks: () => {
3
+ callbacksRef: import("react").RefObject<Callbacks>;
4
+ setCallbacks: (callbacks: Callbacks) => void;
5
+ };
@@ -0,0 +1,28 @@
1
+ import type { ConversationConfig, ConversationStatus, Callbacks } from "../types";
2
+ export declare const useConversationSession: (callbacksRef: {
3
+ current: Callbacks;
4
+ }, setStatus: (status: ConversationStatus) => void, setConnect: (connect: boolean) => void, setToken: (token: string) => void, setRoomId: (roomId: string) => void) => {
5
+ startSession: (config: ConversationConfig) => Promise<void>;
6
+ endSession: () => Promise<void>;
7
+ overrides: {
8
+ agent?: {
9
+ prompt?: {
10
+ prompt?: string;
11
+ };
12
+ firstMessage?: string;
13
+ language?: import("../types").Language;
14
+ };
15
+ tts?: {
16
+ voiceId?: string;
17
+ };
18
+ conversation?: {
19
+ textOnly?: boolean;
20
+ };
21
+ client?: {
22
+ source?: string;
23
+ version?: string;
24
+ };
25
+ } | undefined;
26
+ customLlmExtraBody: unknown;
27
+ dynamicVariables: Record<string, string | number | boolean> | undefined;
28
+ };
@@ -0,0 +1,12 @@
1
+ import type { LocalParticipant } from "livekit-client";
2
+ import type { ConversationStatus, Callbacks } from "../types";
3
+ export declare const useLiveKitRoom: (callbacksRef: {
4
+ current: Callbacks;
5
+ }, setStatus: (status: ConversationStatus) => void, roomId: string) => {
6
+ roomConnected: boolean;
7
+ localParticipant: LocalParticipant | null;
8
+ handleParticipantReady: (participant: LocalParticipant) => void;
9
+ handleConnected: () => void;
10
+ handleDisconnected: () => void;
11
+ handleError: (error: Error) => void;
12
+ };
@@ -0,0 +1,7 @@
1
+ import type { LocalParticipant } from "livekit-client";
2
+ import type { ConversationStatus, Callbacks } from "../types";
3
+ export declare const useMessageSending: (status: ConversationStatus, localParticipant: LocalParticipant | null, callbacksRef: {
4
+ current: Callbacks;
5
+ }) => {
6
+ sendMessage: (message: unknown) => Promise<void>;
7
+ };
@@ -0,0 +1,2 @@
1
+ export { ElevenLabsProvider, useConversation } from "./ElevenLabsProvider";
2
+ export type { ConversationStatus, Mode, Role, Callbacks, ConversationOptions, } from "./types";
package/dist/lib.js ADDED
@@ -0,0 +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.1.0",c=function(t){var o=t.onReady,a=t.isConnected,c=t.callbacks,l=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,o=new TextDecoder,a=JSON.parse(o.decode(e.payload));if(null==c.onMessage||c.onMessage({message:a,source:null!=(n=e.from)&&n.isAgent?"ai":"user"}),null!=(t=e.from)&&t.isAgent&&(null==c.onModeChange||c.onModeChange({mode:null!=(r=e.from)&&r.isSpeaking?"speaking":"listening"}),"agent_response"===a.type&&u)){var i=v.current++;u(i)}switch(a.type){case"ping":l({type:"pong",event_id:a.ping_event.event_id});break;case"client_tool_call":!function(e){try{return Promise.resolve(function(){if(Object.prototype.hasOwnProperty.call(s,e.tool_name)){var n=function(n,t){try{var r=Promise.resolve(s[e.tool_name](e.parameters)).then(function(n){var t="object"==typeof n?JSON.stringify(n):String(n);l({type:"client_tool_result",tool_call_id:e.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==c.onError||c.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.tool_name}),l({type:"client_tool_result",tool_call_id:e.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(c.onUnhandledClientToolCall)return void c.onUnhandledClientToolCall(e);var t="Client tool with name "+e.tool_name+" is not defined on client";null==c.onError||c.onError(t,{clientToolName:e.tool_name}),l({type:"client_tool_result",tool_call_id:e.tool_call_id,result:t,is_error:!0})}}())}catch(e){return Promise.reject(e)}}(a.client_tool_call);break;default:null==c.onDebug||c.onDebug(a)}}),null},l=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(c,{onReady:e.onParticipantReady,isConnected:e.roomConnected,callbacks:e.callbacks,sendMessage:e.sendMessage,clientTools:e.clientTools,updateCurrentEventId:e.updateCurrentEventId}),t)},i=["serverUrl","clientTools"],s=/*#__PURE__*/e.createContext(null);exports.ElevenLabsProvider=function(t){var c=t.children;n.registerGlobals();var i=e.useState(""),u=i[0],d=i[1],v=e.useState(!1),f=v[0],m=v[1],h=e.useState("disconnected"),C=h[0],g=h[1],b=e.useState("wss://livekit.rtc.elevenlabs.io"),k=b[0],p=b[1],y=e.useState(""),_=y[0],S=y[1],E=e.useState(!1),P=E[0],w=E[1],x=e.useState(!1),T=x[0],D=x[1],R=r.default.useRef(1),M=r.default.useRef(1),U=r.default.useRef({}),I=function(){var n=e.useRef({}),t=e.useCallback(function(e){n.current=e},[]);return{callbacksRef:n,setCallbacks:t}}(),j=I.callbacksRef,O=I.setCallbacks,L=r.default.useCallback(function(e){var n=o({},e,{onModeChange:function(n){w("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});O(n)},[O]),F=function(n,t,r,o,c){var l=e.useState({}),i=l[0],s=l[1],u=e.useState(null),d=u[0],v=u[1],f=e.useState({}),m=f[0],h=f[1];return{startSession:e.useCallback(function(e){try{return Promise.resolve(function(l,i){try{var u=function(){function l(e){var n=function(e){try{var n;return(null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||""}catch(e){return console.warn("Could not extract room ID from token"),""}}(i);c(n),o(i),r(!0)}var i;t("connecting"),null==n.current.onStatusChange||n.current.onStatusChange({status:"connecting"}),s(e.overrides||{}),v(e.customLlmExtraBody||null),h(e.dynamicVariables||{});var u=function(){if(!e.conversationToken)return function(){if(e.agentId)return console.info("Getting conversation token for agentId:",e.agentId),Promise.resolve(function(e){try{return Promise.resolve(fetch("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)).then(function(e){i=e});throw new Error("Either conversationToken or agentId is required")}();i=e.conversationToken}();return u&&u.then?u.then(l):l()}()}catch(e){return i(e)}return u&&u.then?u.then(void 0,i):u}(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,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:i,customLlmExtraBody:d,dynamicVariables:m}}(j,g,m,d,S),A=F.startSession,N=F.endSession,V=F.overrides,B=F.customLlmExtraBody,J=F.dynamicVariables,q=function(t,r,o){var a=e.useState(!1),c=a[0],l=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:c,localParticipant:s,handleParticipantReady:e.useCallback(function(e){u(e)},[]),handleConnected:e.useCallback(function(){l(!0),r("connected"),null==t.current.onConnect||t.current.onConnect({conversationId:o})},[o,t,r]),handleDisconnected:e.useCallback(function(){l(!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])}}(j,g,_),K=q.roomConnected,G=q.localParticipant,W=q.handleParticipantReady,z=q.handleConnected,H=q.handleDisconnected,Q=q.handleError,X=r.default.useCallback(function(){R.current=1,M.current=1,D(!1),null==j.current.onCanSendFeedbackChange||j.current.onCanSendFeedbackChange({canSendFeedback:!1}),z()},[z,j]),Y=r.default.useCallback(function(){D(!1),H()},[H]),Z=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])}}(C,G,j),$=Z.sendMessage,ee=r.default.useCallback(function(){var e=R.current!==M.current;T!==e&&(D(e),null==j.current.onCanSendFeedbackChange||j.current.onCanSendFeedbackChange({canSendFeedback:e}))},[T,j]),ne=r.default.useCallback(function(e){T?($({type:"feedback",score:e?"like":"dislike",event_id:R.current}),M.current=R.current,ee()):console.warn(0===M.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[T,$,ee]);r.default.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var te=r.default.useCallback(function(e){R.current=e,ee()},[ee]),re=r.default.useCallback(function(e){if(W(e),G){var n=function(e){var n,t,r,o,c,l,i,s={type:"conversation_initiation_client_data"};return e.overrides&&(s.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==(c=e.overrides.conversation)?void 0:c.textOnly},client:{source:(null==(l=e.overrides)||null==(l=l.client)?void 0:l.source)||"react_native_sdk",version:(null==(i=e.overrides)||null==(i=i.client)?void 0:i.version)||a}}),e.customLlmExtraBody&&(s.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(s.dynamic_variables=e.dynamicVariables),s}({overrides:V,customLlmExtraBody:B,dynamicVariables:J});$(n)}},[W,G,V,B,J,$]),oe={startSession:A,endSession:N,status:C,isSpeaking:P,canSendFeedback:T,sendFeedback:ne,sendContextualUpdate:function(e){$({type:"contextual_update",text:e})},sendUserMessage:function(e){$({type:"user_message",text:e})},sendUserActivity:function(){$({type:"user_activity"})}},ae=r.default.useCallback(function(e){U.current=e},[]);/*#__PURE__*/return r.default.createElement(s.Provider,{value:{conversation:oe,callbacksRef:j,serverUrl:k,clientTools:U.current,setCallbacks:L,setServerUrl:p,setClientTools:ae}},/*#__PURE__*/r.default.createElement(l,{serverUrl:k,token:u,connect:f,onConnected:X,onDisconnected:Y,onError:Q,roomConnected:K,callbacks:j.current,onParticipantReady:re,sendMessage:$,clientTools:U.current,updateCurrentEventId:te},c))},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.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]),a&&t.setClientTools(a),t.setCallbacks(c),t.conversation};
2
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +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.1.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent } 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 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.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.tool_name](\n clientToolCall.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.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.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.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.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.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 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.client_tool_call);\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}\n\ninterface 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 sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (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, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\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 [roomId, setRoomId] = 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 } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setRoomId);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, roomId);\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 // 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 });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\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 clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\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 extractRoomIdFromToken,\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 setRoomId: (roomId: string) => void\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\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\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 conversationToken = await getConversationToken(config.agentId);\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n // Extract room ID from token\n const extractedRoomId = extractRoomIdFromToken(conversationToken);\n setRoomId(extractedRoomId);\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 [callbacksRef, setStatus, setConnect, setToken, setRoomId]\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 };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractRoomIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n return tokenPayload.video?.room || \"\";\n } catch (error) {\n console.warn(\"Could not extract room ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string\n): Promise<string> => {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/convai/conversation/token?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 roomId: 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: roomId });\n }, [roomId, 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 client: {\n source: config.overrides?.client?.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 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","_msg$from3","decoder","TextDecoder","message","JSON","parse","decode","payload","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","type","eventId","current","event_id","ping_event","clientToolCall","Promise","resolve","Object","prototype","hasOwnProperty","call","tool_name","_temp","parameters","then","result","formattedResult","stringify","String","tool_call_id","is_error","_catch","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","reject","handleClientToolCall","client_tool_call","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","roomId","setRoomId","_useState6","setIsSpeaking","_useState7","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","_useConversationCallb","callbacksRef","setCallbacks","useCallback","useConversationCallbacks","setCallbacksBase","wrappedCallbacks","_extends","event","_useConversationSessi","overrides","setOverrides","customLlmExtraBody","setCustomLlmExtraBody","dynamicVariables","setDynamicVariables","startSession","config","_temp2","_result2","extractedRoomId","_tokenPayload$video","atob","split","room","error","console","warn","extractRoomIdFromToken","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","conversationId","handleDisconnected","handleError","undefined","useLiveKitRoom","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","_useMessageSending","TextEncoder","encode","publishData","reliable","useMessageSending","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","_config$overrides2","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","client","version","custom_llm_extra_body","dynamic_variables","constructOverrides","sendContextualUpdate","text","sendUserMessage","sendUserActivity","setClientTools","tools","Provider","value","context","useContext","_objectWithoutPropertiesLoose"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import e,{useRef as n,useCallback as t,useState as o,useEffect as r,useContext as a,createContext as s}from"react";import{AudioSession as l,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 g="0.1.0",m=({onReady:n,isConnected:t,callbacks:o,sendMessage:a,clientTools:s={},updateCurrentEventId:l})=>{const{localParticipant:d}=c(),u=e.useRef(1);return r(()=>{t&&d&&n(d)},[t,d,n]),i(e=>{var n,t;const r=new TextDecoder,c=JSON.parse(r.decode(e.payload));var i;if(null==o.onMessage||o.onMessage({message:c,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"===c.type&&l)){const e=u.current++;l(e)}switch(c.type){case"ping":a({type:"pong",event_id:c.ping_event.event_id});break;case"client_tool_call":(async e=>{if(Object.prototype.hasOwnProperty.call(s,e.tool_name))try{var n;const t=null!=(n=await s[e.tool_name](e.parameters))?n:"Client tool execution successful.",o="object"==typeof t?JSON.stringify(t):String(t);a({type:"client_tool_result",tool_call_id:e.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.tool_name}),a({type:"client_tool_result",tool_call_id:e.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.tool_name} is not defined on client`;null==o.onError||o.onError(n,{clientToolName:e.tool_name}),a({type:"client_tool_result",tool_call_id:e.tool_call_id,result:n,is_error:!0})}})(c.client_tool_call);break;default:null==o.onDebug||o.onDebug(c)}}),null},C=({children:n,serverUrl:t,token:o,connect:r,onConnected:a,onDisconnected:s,onError:l,roomConnected:c,callbacks:i,onParticipantReady:u,sendMessage:v,clientTools:g,updateCurrentEventId:C})=>/*#__PURE__*/e.createElement(d,{serverUrl:t,token:o,connect:r,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:a,onDisconnected:s,onError:l},/*#__PURE__*/e.createElement(m,{onReady:u,isConnected:c,callbacks:i,sendMessage:v,clientTools:g,updateCurrentEventId:C}),n),p=["serverUrl","clientTools"],y=/*#__PURE__*/s(null),b=(n={})=>{const t=a(y);if(!t)throw new Error("useConversation must be used within ElevenLabsProvider");const{serverUrl:o,clientTools:r}=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,p);return e.useEffect(()=>{o&&t.setServerUrl(o)},[t,o]),r&&t.setClientTools(r),t.setCallbacks(s),t.conversation},k=({children:a})=>{u();const[s,c]=o(""),[i,d]=o(!1),[m,p]=o("disconnected"),[b,k]=o("wss://livekit.rtc.elevenlabs.io"),[f,_]=o(""),[h,E]=o(!1),[S,w]=o(!1),x=e.useRef(1),T=e.useRef(1),D=e.useRef({}),{callbacksRef:M,setCallbacks:R}=(()=>{const e=n({}),o=t(n=>{e.current=n},[]);return{callbacksRef:e,setCallbacks:o}})(),U=e.useCallback(e=>{const n=v({},e,{onModeChange:n=>{E("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});R(n)},[R]),{startSession:I,endSession:P,overrides:O,customLlmExtraBody:F,dynamicVariables:L}=((e,n,r,a,s)=>{const[l,c]=o({}),[i,d]=o(null),[u,v]=o({});return{startSession:t(async t=>{try{let o;if(n("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),c(t.overrides||{}),d(t.customLlmExtraBody||null),v(t.dynamicVariables||{}),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),o=await(async e=>{const n=await fetch(`https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${e}&source=react_native_sdk&version=${g}`),t=await n.json();if(!n.ok)throw new Error(`Failed to get conversation token: ${t.detail.message}`);if(!t.token)throw new Error("No conversation token received from API");return t.token})(t.agentId)}const l=(e=>{try{var n;return(null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||""}catch(e){return console.warn("Could not extract room ID from token"),""}})(o);s(l),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,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("User ended conversation")}catch(n){throw null==e.current.onError||e.current.onError(n),n}},[e,r,a,n]),overrides:l,customLlmExtraBody:i,dynamicVariables:u}})(M,p,d,c,_),{roomConnected:N,localParticipant:V,handleParticipantReady:A,handleConnected:B,handleDisconnected:$,handleError:j}=((e,n,a)=>{const[s,c]=o(!1),[i,d]=o(null);return r(()=>((async()=>{await l.startAudioSession()})(),()=>{l.stopAudioSession()}),[]),{roomConnected:s,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("disconnected")},[e,n]),handleError:t(n=>{console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e])}})(M,p,f),J=e.useCallback(()=>{x.current=1,T.current=1,w(!1),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:!1}),B()},[B,M]),K=e.useCallback(()=>{w(!1),$()},[$]),{sendMessage:q}=((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])}))(m,V,M),G=e.useCallback(()=>{const e=x.current!==T.current;S!==e&&(w(e),null==M.current.onCanSendFeedbackChange||M.current.onCanSendFeedbackChange({canSendFeedback:e}))},[S,M]),W=e.useCallback(e=>{S?(q({type:"feedback",score:e?"like":"dislike",event_id:x.current}),T.current=x.current,G()):console.warn(0===T.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[S,q,G]);e.useCallback(e=>{console.warn("setVolume is not yet implemented in React Native SDK")},[]);const z=e.useCallback(e=>{x.current=e,G()},[G]),H=e.useCallback(e=>{if(A(e),V){const e=function(e){const n={type:"conversation_initiation_client_data"};var t,o,r,a,s,l,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==(a=e.overrides.tts)?void 0:a.voiceId},conversation:{text_only:null==(s=e.overrides.conversation)?void 0:s.textOnly},client:{source:(null==(l=e.overrides)||null==(l=l.client)?void 0:l.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),n}({overrides:O,customLlmExtraBody:F,dynamicVariables:L});q(e)}},[A,V,O,F,L,q]),Q={startSession:I,endSession:P,status:m,isSpeaking:h,canSendFeedback:S,sendFeedback:W,sendContextualUpdate:e=>{q({type:"contextual_update",text:e})},sendUserMessage:e=>{q({type:"user_message",text:e})},sendUserActivity:()=>{q({type:"user_activity"})}},X=e.useCallback(e=>{D.current=e},[]);/*#__PURE__*/return e.createElement(y.Provider,{value:{conversation:Q,callbacksRef:M,serverUrl:b,clientTools:D.current,setCallbacks:U,setServerUrl:k,setClientTools:X}},/*#__PURE__*/e.createElement(C,{serverUrl:b,token:s,connect:i,onConnected:J,onDisconnected:K,onError:j,roomConnected:N,callbacks:M.current,onParticipantReady:H,sendMessage:q,clientTools:D.current,updateCurrentEventId:z},a))};export{k as ElevenLabsProvider,b as useConversation};
2
+ //# sourceMappingURL=lib.modern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.modern.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.1.0\";\n","import { useEffect } from 'react';\nimport { useLocalParticipant, useDataChannel } from '@livekit/react-native';\nimport type { LocalParticipant } from 'livekit-client';\nimport type { Callbacks, ClientToolsConfig, ClientToolCallEvent } 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 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.tool_name\n )\n ) {\n try {\n const result =\n (await clientTools[clientToolCall.tool_name](\n clientToolCall.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.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.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.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.tool_name} is not defined on client`;\n callbacks.onError?.(errorMessage, {\n clientToolName: clientToolCall.tool_name,\n });\n sendMessage({\n type: \"client_tool_result\",\n tool_call_id: clientToolCall.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 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.client_tool_call);\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}\n\ninterface 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 sendFeedback: (like: boolean) => void;\n sendContextualUpdate: (text: string) => void;\n sendUserMessage: (text: string) => void;\n sendUserActivity: () => void;\n}\n\ninterface ElevenLabsContextType {\n conversation: Conversation;\n callbacksRef: { current: Callbacks };\n serverUrl: string;\n clientTools: ClientToolsConfig['clientTools'];\n setCallbacks: (callbacks: Callbacks) => void;\n setServerUrl: (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, clientTools, ...callbacks } = options;\n\n React.useEffect(() => {\n if (serverUrl) {\n context.setServerUrl(serverUrl);\n }\n }, [context, serverUrl]);\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 [roomId, setRoomId] = 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 } = useConversationSession(callbacksRef, setStatus, setConnect, setToken, setRoomId);\n\n const {\n roomConnected,\n localParticipant,\n handleParticipantReady,\n handleConnected,\n handleDisconnected,\n handleError,\n } = useLiveKitRoom(callbacksRef, setStatus, roomId);\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 // 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 });\n sendMessage(overridesEvent);\n }\n }, [handleParticipantReady, localParticipant, overrides, customLlmExtraBody, dynamicVariables, sendMessage]);\n\n const conversation: Conversation = {\n startSession,\n endSession,\n status,\n isSpeaking,\n // setVolume,\n canSendFeedback,\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 clientTools: clientToolsRef.current,\n setCallbacks,\n setServerUrl,\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 extractRoomIdFromToken,\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 setRoomId: (roomId: string) => void\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\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\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 conversationToken = await getConversationToken(config.agentId);\n } else {\n throw new Error(\"Either conversationToken or agentId is required\");\n }\n\n // Extract room ID from token\n const extractedRoomId = extractRoomIdFromToken(conversationToken);\n setRoomId(extractedRoomId);\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 [callbacksRef, setStatus, setConnect, setToken, setRoomId]\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 };\n};\n","import { PACKAGE_VERSION } from \"../version\";\n\nexport const extractRoomIdFromToken = (token: string): string => {\n try {\n const tokenPayload = JSON.parse(atob(token.split(\".\")[1]));\n return tokenPayload.video?.room || \"\";\n } catch (error) {\n console.warn(\"Could not extract room ID from token\");\n return \"\";\n }\n};\n\nexport const getConversationToken = async (\n agentId: string\n): Promise<string> => {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/convai/conversation/token?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 roomId: 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: roomId });\n }, [roomId, 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 client: {\n source: config.overrides?.client?.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 return overridesEvent;\n}\n"],"names":["PACKAGE_VERSION","MessageHandler","onReady","isConnected","callbacks","sendMessage","clientTools","updateCurrentEventId","localParticipant","useLocalParticipant","agentResponseCountRef","React","useRef","useEffect","useDataChannel","msg","_msg$from","_msg$from2","decoder","TextDecoder","message","JSON","parse","decode","payload","_msg$from3","onMessage","source","from","isAgent","onModeChange","mode","isSpeaking","type","eventId","current","event_id","ping_event","async","Object","prototype","hasOwnProperty","call","clientToolCall","tool_name","_await$_clientTools$c","result","parameters","formattedResult","stringify","String","tool_call_id","is_error","e","onError","clientToolName","onUnhandledClientToolCall","errorMessage","handleClientToolCall","client_tool_call","onDebug","LiveKitRoomWrapper","children","serverUrl","token","connect","onConnected","onDisconnected","roomConnected","onParticipantReady","createElement","LiveKitRoom","audio","video","options","adaptiveStream","pixelDensity","ElevenLabsContext","createContext","useConversation","context","useContext","Error","_objectWithoutPropertiesLoose","_excluded","setServerUrl","setClientTools","setCallbacks","conversation","ElevenLabsProvider","registerGlobals","setToken","useState","setConnect","status","setStatus","roomId","setRoomId","setIsSpeaking","canSendFeedback","setCanSendFeedback","currentEventIdRef","lastFeedbackEventIdRef","clientToolsRef","callbacksRef","setCallbacksBase","useConversationCallbacks","useCallback","wrappedCallbacks","_extends","event","startSession","endSession","overrides","customLlmExtraBody","dynamicVariables","useConversationSession","setOverrides","setCustomLlmExtraBody","setDynamicVariables","conversationToken","onStatusChange","config","agentId","console","info","response","fetch","data","json","ok","detail","getConversationToken","extractedRoomId","_tokenPayload$video","atob","split","room","error","warn","extractRoomIdFromToken","onDisconnect","handleParticipantReady","handleConnected","handleDisconnected","handleError","useLiveKitRoom","setRoomConnected","setLocalParticipant","AudioSession","startAudioSession","start","stopAudioSession","participant","onConnect","conversationId","undefined","handleConnectedWithFeedback","onCanSendFeedbackChange","handleDisconnectedWithFeedback","useMessageSending","TextEncoder","encode","publishData","reliable","updateCanSendFeedback","newCanSendFeedback","sendFeedback","like","score","volume","handleParticipantReadyWithOverrides","overridesEvent","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","_config$overrides","_config$overrides2","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","text_only","textOnly","client","version","custom_llm_extra_body","dynamic_variables","constructOverrides","sendContextualUpdate","text","sendUserMessage","sendUserActivity","tools","Provider","value"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import e,{useRef as n,useCallback as r,useState as t,useEffect as o,useContext as c,createContext as a}from"react";import{AudioSession as i,useLocalParticipant as l,useDataChannel as s,LiveKitRoom as u,registerGlobals as d}from"@livekit/react-native";function v(){return v=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var t in r)({}).hasOwnProperty.call(r,t)&&(e[t]=r[t])}return e},v.apply(null,arguments)}var f="0.1.0",m=function(n){var r=n.onReady,t=n.isConnected,c=n.callbacks,a=n.sendMessage,i=n.clientTools,u=void 0===i?{}:i,d=n.updateCurrentEventId,v=l().localParticipant,f=e.useRef(1);return o(function(){t&&v&&r(v)},[t,v,r]),s(function(e){var n,r,t,o=new TextDecoder,i=JSON.parse(o.decode(e.payload));if(null==c.onMessage||c.onMessage({message:i,source:null!=(n=e.from)&&n.isAgent?"ai":"user"}),null!=(r=e.from)&&r.isAgent&&(null==c.onModeChange||c.onModeChange({mode:null!=(t=e.from)&&t.isSpeaking?"speaking":"listening"}),"agent_response"===i.type&&d)){var l=f.current++;d(l)}switch(i.type){case"ping":a({type:"pong",event_id:i.ping_event.event_id});break;case"client_tool_call":!function(e){try{return Promise.resolve(function(){if(Object.prototype.hasOwnProperty.call(u,e.tool_name)){var n=function(n,r){try{var t=Promise.resolve(u[e.tool_name](e.parameters)).then(function(n){var r="object"==typeof n?JSON.stringify(n):String(n);a({type:"client_tool_result",tool_call_id:e.tool_call_id,result:r,is_error:!1})})}catch(e){return r(e)}return t&&t.then?t.then(void 0,r):t}(0,function(n){null==c.onError||c.onError("Client tool execution failed with following error: "+(null==n?void 0:n.message),{clientToolName:e.tool_name}),a({type:"client_tool_result",tool_call_id:e.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(c.onUnhandledClientToolCall)return void c.onUnhandledClientToolCall(e);var r="Client tool with name "+e.tool_name+" is not defined on client";null==c.onError||c.onError(r,{clientToolName:e.tool_name}),a({type:"client_tool_result",tool_call_id:e.tool_call_id,result:r,is_error:!0})}}())}catch(e){return Promise.reject(e)}}(i.client_tool_call);break;default:null==c.onDebug||c.onDebug(i)}}),null},h=function(n){var r=n.children;/*#__PURE__*/return e.createElement(u,{serverUrl:n.serverUrl,token:n.token,connect:n.connect,audio:!0,video:!1,options:{adaptiveStream:{pixelDensity:"screen"}},onConnected:n.onConnected,onDisconnected:n.onDisconnected,onError:n.onError},/*#__PURE__*/e.createElement(m,{onReady:n.onParticipantReady,isConnected:n.roomConnected,callbacks:n.callbacks,sendMessage:n.sendMessage,clientTools:n.clientTools,updateCurrentEventId:n.updateCurrentEventId}),r)},g=["serverUrl","clientTools"],C=/*#__PURE__*/a(null),p=function(n){void 0===n&&(n={});var r=c(C);if(!r)throw new Error("useConversation must be used within ElevenLabsProvider");var t=n.serverUrl,o=n.clientTools,a=function(e,n){if(null==e)return{};var r={};for(var t in e)if({}.hasOwnProperty.call(e,t)){if(-1!==n.indexOf(t))continue;r[t]=e[t]}return r}(n,g);return e.useEffect(function(){t&&r.setServerUrl(t)},[r,t]),o&&r.setClientTools(o),r.setCallbacks(a),r.conversation},y=function(c){var a=c.children;d();var l=t(""),s=l[0],u=l[1],m=t(!1),g=m[0],p=m[1],y=t("disconnected"),b=y[0],k=y[1],_=t("wss://livekit.rtc.elevenlabs.io"),E=_[0],S=_[1],P=t(""),w=P[0],x=P[1],T=t(!1),D=T[0],M=T[1],R=t(!1),U=R[0],I=R[1],O=e.useRef(1),j=e.useRef(1),F=e.useRef({}),L=function(){var e=n({}),t=r(function(n){e.current=n},[]);return{callbacksRef:e,setCallbacks:t}}(),N=L.callbacksRef,V=L.setCallbacks,A=e.useCallback(function(e){var n=v({},e,{onModeChange:function(n){M("speaking"===n.mode),null==e.onModeChange||e.onModeChange(n)}});V(n)},[V]),B=function(e,n,o,c,a){var i=t({}),l=i[0],s=i[1],u=t(null),d=u[0],v=u[1],m=t({}),h=m[0],g=m[1];return{startSession:r(function(r){try{return Promise.resolve(function(t,i){try{var l=function(){function t(e){var n=function(e){try{var n;return(null==(n=JSON.parse(atob(e.split(".")[1])).video)?void 0:n.room)||""}catch(e){return console.warn("Could not extract room ID from token"),""}}(i);a(n),c(i),o(!0)}var i;n("connecting"),null==e.current.onStatusChange||e.current.onStatusChange({status:"connecting"}),s(r.overrides||{}),v(r.customLlmExtraBody||null),g(r.dynamicVariables||{});var l=function(){if(!r.conversationToken)return function(){if(r.agentId)return console.info("Getting conversation token for agentId:",r.agentId),Promise.resolve(function(e){try{return Promise.resolve(fetch("https://api.elevenlabs.io/v1/convai/conversation/token?agent_id="+e+"&source=react_native_sdk&version="+f)).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)}}(r.agentId)).then(function(e){i=e});throw new Error("Either conversationToken or agentId is required")}();i=r.conversationToken}();return l&&l.then?l.then(t):t()}()}catch(e){return i(e)}return l&&l.then?l.then(void 0,i):l}(0,function(r){throw n("disconnected"),null==e.current.onStatusChange||e.current.onStatusChange({status:"disconnected"}),null==e.current.onError||e.current.onError(r),r}))}catch(e){return Promise.reject(e)}},[e,n,o,c,a]),endSession:r(function(){try{try{o(!1),c(""),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}return Promise.resolve()}catch(e){return Promise.reject(e)}},[e,o,c,n]),overrides:l,customLlmExtraBody:d,dynamicVariables:h}}(N,k,p,u,x),J=B.startSession,K=B.endSession,q=B.overrides,G=B.customLlmExtraBody,W=B.dynamicVariables,z=function(e,n,c){var a=t(!1),l=a[0],s=a[1],u=t(null),d=u[0],v=u[1];return o(function(){return function(){try{return Promise.resolve(i.startAudioSession()).then(function(){})}catch(e){return Promise.reject(e)}}(),function(){i.stopAudioSession()}},[]),{roomConnected:l,localParticipant:d,handleParticipantReady:r(function(e){v(e)},[]),handleConnected:r(function(){s(!0),n("connected"),null==e.current.onConnect||e.current.onConnect({conversationId:c})},[c,e,n]),handleDisconnected:r(function(){s(!1),n("disconnected"),v(null),null==e.current.onDisconnect||e.current.onDisconnect("disconnected")},[e,n]),handleError:r(function(n){console.error("LiveKit error:",n),null==e.current.onError||e.current.onError(n.message,void 0)},[e])}}(N,k,w),H=z.roomConnected,Q=z.localParticipant,X=z.handleParticipantReady,Y=z.handleConnected,Z=z.handleDisconnected,$=z.handleError,ee=e.useCallback(function(){O.current=1,j.current=1,I(!1),null==N.current.onCanSendFeedbackChange||N.current.onCanSendFeedbackChange({canSendFeedback:!1}),Y()},[Y,N]),ne=e.useCallback(function(){I(!1),Z()},[Z]),re=function(e,n,t){return{sendMessage:r(function(r){try{if("connected"!==e||!n)return console.warn("Cannot send message: room not connected or no local participant"),Promise.resolve();var o=function(e,t){try{var o=(c=(new TextEncoder).encode(JSON.stringify(r)),Promise.resolve(n.publishData(c,{reliable:!0})).then(function(){}))}catch(e){return t(e)}var c;return o&&o.then?o.then(void 0,t):o}(0,function(e){console.error("Failed to send message via WebRTC:",e),console.error("Error details:",e),null==t.current.onError||t.current.onError(e)});return Promise.resolve(o&&o.then?o.then(function(){}):void 0)}catch(e){return Promise.reject(e)}},[e,n,t])}}(b,Q,N),te=re.sendMessage,oe=e.useCallback(function(){var e=O.current!==j.current;U!==e&&(I(e),null==N.current.onCanSendFeedbackChange||N.current.onCanSendFeedbackChange({canSendFeedback:e}))},[U,N]),ce=e.useCallback(function(e){U?(te({type:"feedback",score:e?"like":"dislike",event_id:O.current}),j.current=O.current,oe()):console.warn(0===j.current?"Cannot send feedback: the conversation has not started yet.":"Cannot send feedback: feedback has already been sent for the current response.")},[U,te,oe]);e.useCallback(function(e){console.warn("setVolume is not yet implemented in React Native SDK")},[]);var ae=e.useCallback(function(e){O.current=e,oe()},[oe]),ie=e.useCallback(function(e){if(X(e),Q){var n=function(e){var n,r,t,o,c,a,i,l={type:"conversation_initiation_client_data"};return e.overrides&&(l.conversation_config_override={agent:{prompt:null==(n=e.overrides.agent)?void 0:n.prompt,first_message:null==(r=e.overrides.agent)?void 0:r.firstMessage,language:null==(t=e.overrides.agent)?void 0:t.language},tts:{voice_id:null==(o=e.overrides.tts)?void 0:o.voiceId},conversation:{text_only:null==(c=e.overrides.conversation)?void 0:c.textOnly},client:{source:(null==(a=e.overrides)||null==(a=a.client)?void 0:a.source)||"react_native_sdk",version:(null==(i=e.overrides)||null==(i=i.client)?void 0:i.version)||f}}),e.customLlmExtraBody&&(l.custom_llm_extra_body=e.customLlmExtraBody),e.dynamicVariables&&(l.dynamic_variables=e.dynamicVariables),l}({overrides:q,customLlmExtraBody:G,dynamicVariables:W});te(n)}},[X,Q,q,G,W,te]),le={startSession:J,endSession:K,status:b,isSpeaking:D,canSendFeedback:U,sendFeedback:ce,sendContextualUpdate:function(e){te({type:"contextual_update",text:e})},sendUserMessage:function(e){te({type:"user_message",text:e})},sendUserActivity:function(){te({type:"user_activity"})}},se=e.useCallback(function(e){F.current=e},[]);/*#__PURE__*/return e.createElement(C.Provider,{value:{conversation:le,callbacksRef:N,serverUrl:E,clientTools:F.current,setCallbacks:A,setServerUrl:S,setClientTools:se}},/*#__PURE__*/e.createElement(h,{serverUrl:E,token:s,connect:g,onConnected:ee,onDisconnected:ne,onError:$,roomConnected:H,callbacks:N.current,onParticipantReady:ie,sendMessage:te,clientTools:F.current,updateCurrentEventId:ae},a))};export{y as ElevenLabsProvider,p as useConversation};
2
+ //# sourceMappingURL=lib.module.js.map