@elevenlabs/react-native 0.5.4 → 0.5.6
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.
- package/.turbo/turbo-build.log +17 -11
- package/.turbo/turbo-generate-version.log +1 -1
- package/README.md +54 -1
- package/dist/ElevenLabsProvider.d.ts +2 -1
- package/dist/components/LiveKitRoomWrapper.d.ts +3 -2
- package/dist/hooks/useConversationSession.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.js +1 -1
- package/dist/lib.module.js.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/version.d.ts +1 -1
- package/package.json +3 -3
- package/src/ElevenLabsProvider.test.tsx +64 -1
- package/src/ElevenLabsProvider.tsx +27 -7
- package/src/components/LiveKitRoomWrapper.tsx +22 -2
- package/src/components/MessageHandler.tsx +49 -23
- package/src/index.ts +1 -0
- package/src/types.ts +24 -6
- package/src/utils/overrides.ts +1 -0
- package/src/version.ts +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
|
-
import { useLocalParticipant, useDataChannel } from "@livekit/react-native";
|
|
3
|
-
import
|
|
2
|
+
import { useLocalParticipant, useDataChannel, useRoomContext } from "@livekit/react-native";
|
|
3
|
+
import { RoomEvent } from "livekit-client";
|
|
4
|
+
import type { LocalParticipant, RemoteParticipant } from "livekit-client";
|
|
4
5
|
import type {
|
|
5
6
|
Callbacks,
|
|
6
7
|
ClientToolsConfig,
|
|
@@ -44,10 +45,34 @@ export const MessageHandler = ({
|
|
|
44
45
|
onEndSession,
|
|
45
46
|
}: MessageHandlerProps) => {
|
|
46
47
|
const { localParticipant } = useLocalParticipant();
|
|
48
|
+
const room = useRoomContext();
|
|
47
49
|
|
|
48
50
|
// Track agent response count for synthetic event IDs (WebRTC mode)
|
|
49
51
|
const agentResponseCountRef = React.useRef(1);
|
|
50
52
|
|
|
53
|
+
// Refs for callbacks to avoid unnecessary effect re-runs
|
|
54
|
+
const onEndSessionRef = React.useRef(onEndSession);
|
|
55
|
+
onEndSessionRef.current = onEndSession;
|
|
56
|
+
const onReadyRef = React.useRef(onReady);
|
|
57
|
+
onReadyRef.current = onReady;
|
|
58
|
+
const callbacksRef = React.useRef(callbacks);
|
|
59
|
+
callbacksRef.current = callbacks;
|
|
60
|
+
|
|
61
|
+
// Detect agent disconnection
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const handleParticipantDisconnected = (participant: RemoteParticipant) => {
|
|
64
|
+
if (participant.identity?.startsWith("agent")) {
|
|
65
|
+
onEndSessionRef.current("agent");
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
room.on(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);
|
|
70
|
+
|
|
71
|
+
return () => {
|
|
72
|
+
room.off(RoomEvent.ParticipantDisconnected, handleParticipantDisconnected);
|
|
73
|
+
};
|
|
74
|
+
}, [room]);
|
|
75
|
+
|
|
51
76
|
// Reset agent response count when connection status changes
|
|
52
77
|
useEffect(() => {
|
|
53
78
|
if (!isConnected) {
|
|
@@ -57,9 +82,9 @@ export const MessageHandler = ({
|
|
|
57
82
|
|
|
58
83
|
useEffect(() => {
|
|
59
84
|
if (isConnected && localParticipant) {
|
|
60
|
-
|
|
85
|
+
onReadyRef.current(localParticipant);
|
|
61
86
|
}
|
|
62
|
-
}, [isConnected, localParticipant
|
|
87
|
+
}, [isConnected, localParticipant]);
|
|
63
88
|
|
|
64
89
|
const handleClientToolCall = async (clientToolCall: ClientToolCallEvent) => {
|
|
65
90
|
if (clientToolCall.client_tool_call.tool_name in clientTools) {
|
|
@@ -81,7 +106,7 @@ export const MessageHandler = ({
|
|
|
81
106
|
});
|
|
82
107
|
} catch (e) {
|
|
83
108
|
const errorMessage = `Client tool execution failed with following error: ${(e as Error)?.message}`;
|
|
84
|
-
|
|
109
|
+
callbacksRef.current.onError?.(errorMessage, {
|
|
85
110
|
clientToolName: clientToolCall.client_tool_call.tool_name,
|
|
86
111
|
});
|
|
87
112
|
sendMessage({
|
|
@@ -92,13 +117,13 @@ export const MessageHandler = ({
|
|
|
92
117
|
});
|
|
93
118
|
}
|
|
94
119
|
} else {
|
|
95
|
-
if (
|
|
96
|
-
|
|
120
|
+
if (callbacksRef.current.onUnhandledClientToolCall) {
|
|
121
|
+
callbacksRef.current.onUnhandledClientToolCall(clientToolCall.client_tool_call);
|
|
97
122
|
return;
|
|
98
123
|
}
|
|
99
124
|
|
|
100
125
|
const errorMessage = `Client tool with name ${clientToolCall.client_tool_call.tool_name} is not defined on client`;
|
|
101
|
-
|
|
126
|
+
callbacksRef.current.onError?.(errorMessage, {
|
|
102
127
|
clientToolName: clientToolCall.client_tool_call.tool_name,
|
|
103
128
|
});
|
|
104
129
|
sendMessage({
|
|
@@ -115,7 +140,7 @@ export const MessageHandler = ({
|
|
|
115
140
|
const message = JSON.parse(decoder.decode(msg.payload));
|
|
116
141
|
|
|
117
142
|
if (!isValidEvent(message)) {
|
|
118
|
-
|
|
143
|
+
callbacksRef.current.onDebug?.({
|
|
119
144
|
type: "invalid_event",
|
|
120
145
|
message,
|
|
121
146
|
});
|
|
@@ -124,14 +149,15 @@ export const MessageHandler = ({
|
|
|
124
149
|
|
|
125
150
|
const messageText = extractMessageText(message);
|
|
126
151
|
if (messageText !== null) {
|
|
127
|
-
|
|
152
|
+
callbacksRef.current.onMessage?.({
|
|
128
153
|
message: messageText,
|
|
129
154
|
source: message.type === "user_transcript" ? "user" : "ai",
|
|
155
|
+
role: message.type === "user_transcript" ? "user" : "agent",
|
|
130
156
|
});
|
|
131
157
|
}
|
|
132
158
|
|
|
133
159
|
if (msg.from?.isAgent) {
|
|
134
|
-
|
|
160
|
+
callbacksRef.current.onModeChange?.({
|
|
135
161
|
mode: msg.from?.isSpeaking ? "speaking" : "listening",
|
|
136
162
|
});
|
|
137
163
|
|
|
@@ -153,48 +179,48 @@ export const MessageHandler = ({
|
|
|
153
179
|
handleClientToolCall(message);
|
|
154
180
|
break;
|
|
155
181
|
case "audio":
|
|
156
|
-
|
|
182
|
+
callbacksRef.current.onAudio?.(message.audio_event.audio_base_64);
|
|
157
183
|
break;
|
|
158
184
|
case "vad_score":
|
|
159
|
-
|
|
185
|
+
callbacksRef.current.onVadScore?.({
|
|
160
186
|
vadScore: message.vad_score_event.vad_score,
|
|
161
187
|
});
|
|
162
188
|
break;
|
|
163
189
|
case "interruption":
|
|
164
|
-
|
|
190
|
+
callbacksRef.current.onInterruption?.(message.interruption_event);
|
|
165
191
|
break;
|
|
166
192
|
case "mcp_tool_call":
|
|
167
|
-
|
|
193
|
+
callbacksRef.current.onMCPToolCall?.(message.mcp_tool_call);
|
|
168
194
|
break;
|
|
169
195
|
case "mcp_connection_status":
|
|
170
|
-
|
|
196
|
+
callbacksRef.current.onMCPConnectionStatus?.(message.mcp_connection_status);
|
|
171
197
|
break;
|
|
172
198
|
case "agent_tool_request":
|
|
173
|
-
|
|
199
|
+
callbacksRef.current.onAgentToolRequest?.(message.agent_tool_request);
|
|
174
200
|
break;
|
|
175
201
|
case "agent_tool_response":
|
|
176
|
-
|
|
202
|
+
callbacksRef.current.onAgentToolResponse?.(message.agent_tool_response);
|
|
177
203
|
|
|
178
204
|
if (message.agent_tool_response.tool_name === "end_call") {
|
|
179
205
|
// End the call
|
|
180
|
-
|
|
206
|
+
onEndSessionRef.current("agent");
|
|
181
207
|
}
|
|
182
208
|
break;
|
|
183
209
|
case "conversation_initiation_metadata":
|
|
184
|
-
|
|
210
|
+
callbacksRef.current.onConversationMetadata?.(
|
|
185
211
|
message.conversation_initiation_metadata_event
|
|
186
212
|
);
|
|
187
213
|
break;
|
|
188
214
|
case "asr_initiation_metadata":
|
|
189
|
-
|
|
215
|
+
callbacksRef.current.onAsrInitiationMetadata?.(
|
|
190
216
|
message.asr_initiation_metadata_event
|
|
191
217
|
);
|
|
192
218
|
break;
|
|
193
219
|
case "agent_chat_response_part":
|
|
194
|
-
|
|
220
|
+
callbacksRef.current.onAgentChatResponsePart?.(message.text_response_part);
|
|
195
221
|
break;
|
|
196
222
|
default:
|
|
197
|
-
|
|
223
|
+
callbacksRef.current.onDebug?.(message);
|
|
198
224
|
break;
|
|
199
225
|
}
|
|
200
226
|
});
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type * as Types from "@elevenlabs/types";
|
|
2
2
|
import type {
|
|
3
|
+
AsrInitiationMetadataEvent as AsrMetadataEvent,
|
|
4
|
+
Callbacks,
|
|
5
|
+
ConversationMetadata,
|
|
6
|
+
Mode as ConversationMode,
|
|
3
7
|
Incoming,
|
|
4
|
-
Outgoing,
|
|
5
8
|
Interruption,
|
|
6
|
-
ConversationMetadata,
|
|
7
|
-
Ping,
|
|
8
9
|
Role as MessageRole,
|
|
9
|
-
|
|
10
|
+
Outgoing,
|
|
11
|
+
Ping,
|
|
10
12
|
Status,
|
|
11
|
-
Callbacks,
|
|
12
|
-
AsrInitiationMetadataEvent as AsrMetadataEvent,
|
|
13
13
|
} from "@elevenlabs/types";
|
|
14
14
|
export type { Callbacks } from "@elevenlabs/types";
|
|
15
15
|
|
|
@@ -70,6 +70,7 @@ export type ConversationConfig = {
|
|
|
70
70
|
};
|
|
71
71
|
tts?: {
|
|
72
72
|
voiceId?: string;
|
|
73
|
+
speed?: number;
|
|
73
74
|
};
|
|
74
75
|
conversation?: {
|
|
75
76
|
textOnly?: boolean;
|
|
@@ -139,3 +140,20 @@ export type ConversationEvent =
|
|
|
139
140
|
| ConversationMetadataEvent
|
|
140
141
|
| AsrInitiationMetadataEvent
|
|
141
142
|
| AgentChatResponsePartEvent;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Audio session configuration for controlling how the SDK handles audio
|
|
146
|
+
*/
|
|
147
|
+
export interface AudioSessionConfig {
|
|
148
|
+
/**
|
|
149
|
+
* Whether audio should mix with other audio sources.
|
|
150
|
+
* When true, the SDK will configure the audio session to allow
|
|
151
|
+
* concurrent audio playback with other audio sources.
|
|
152
|
+
*
|
|
153
|
+
* iOS: Adds AVAudioSessionCategoryOptionMixWithOthers
|
|
154
|
+
* Android: Uses AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
|
|
155
|
+
*
|
|
156
|
+
* @default false (exclusive audio session)
|
|
157
|
+
*/
|
|
158
|
+
allowMixingWithOthers?: boolean;
|
|
159
|
+
}
|
package/src/utils/overrides.ts
CHANGED
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated during build
|
|
2
|
-
export const PACKAGE_VERSION = "0.5.
|
|
2
|
+
export const PACKAGE_VERSION = "0.5.6";
|