Skip to content

Commit 68d4846

Browse files
committed
Update to use the agents SDK api
1 parent 47d519c commit 68d4846

File tree

6 files changed

+58
-91
lines changed

6 files changed

+58
-91
lines changed

app/(start)/index.tsx

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ConnectionDetails, fetchToken } from '@/hooks/useConnectionDetails';
1+
import { useConnection } from '@/hooks/useConnection';
22
import { useRouter } from 'expo-router';
33
import { useEffect, useState } from 'react';
44
import {
@@ -12,37 +12,18 @@ import {
1212

1313
export default function StartScreen() {
1414
const router = useRouter();
15-
16-
let [isConnecting, setConnecting] = useState(false);
17-
let [connectionDetails, setConnectionDetails] = useState<
18-
ConnectionDetails | undefined
19-
>(undefined);
20-
21-
// Fetch token when we're connecting.
22-
useEffect(() => {
23-
if (isConnecting) {
24-
fetchToken().then((details) => {
25-
console.log(details);
26-
setConnectionDetails(details);
27-
if (!details) {
28-
setConnecting(false);
29-
}
30-
});
31-
}
32-
}, [isConnecting]);
15+
const { isConnectionActive, connect } = useConnection();
3316

3417
// Navigate to Assistant screen when we have the connection details.
3518
useEffect(() => {
36-
if (isConnecting && connectionDetails) {
37-
setConnecting(false);
38-
setConnectionDetails(undefined);
19+
if (isConnectionActive) {
3920
router.navigate('../assistant');
4021
}
41-
}, [isConnecting, router, connectionDetails]);
22+
}, [isConnectionActive, router]);
4223

4324
let connectText: string;
4425

45-
if (isConnecting) {
26+
if (isConnectionActive) {
4627
connectText = 'Connecting';
4728
} else {
4829
connectText = 'Start Voice Assistant';
@@ -58,13 +39,13 @@ export default function StartScreen() {
5839

5940
<TouchableOpacity
6041
onPress={() => {
61-
setConnecting(true);
42+
connect();
6243
}}
6344
style={styles.button}
6445
activeOpacity={0.7}
65-
disabled={isConnecting} // Disable button while loading
46+
disabled={isConnectionActive} // Disable button while loading
6647
>
67-
{isConnecting ? (
48+
{isConnectionActive ? (
6849
<ActivityIndicator
6950
size="small"
7051
color="#ffffff"

app/_layout.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'react-native-reanimated';
99

1010
import { useColorScheme } from '@/hooks/useColorScheme';
1111
import { registerGlobals } from '@livekit/react-native';
12+
import { ConnectionProvider } from '@/hooks/useConnection';
1213

1314
// Do required setup for LiveKit React-Native
1415
registerGlobals();
@@ -17,12 +18,14 @@ export default function RootLayout() {
1718
const colorScheme = useColorScheme();
1819

1920
return (
20-
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
21-
<Stack>
22-
<Stack.Screen name="(start)" options={{ headerShown: false }} />
23-
<Stack.Screen name="assistant" options={{ headerShown: false }} />
24-
</Stack>
25-
<StatusBar style="auto" />
26-
</ThemeProvider>
21+
<ConnectionProvider>
22+
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
23+
<Stack>
24+
<Stack.Screen name="(start)" options={{ headerShown: false }} />
25+
<Stack.Screen name="assistant" options={{ headerShown: false }} />
26+
</Stack>
27+
<StatusBar style="auto" />
28+
</ThemeProvider>
29+
</ConnectionProvider>
2730
);
2831
}

app/assistant/index.tsx

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,21 @@ import {
1010
import React, { useCallback, useEffect, useState } from 'react';
1111
import {
1212
AudioSession,
13-
LiveKitRoom,
1413
useIOSAudioManagement,
1514
useLocalParticipant,
1615
useParticipantTracks,
1716
useRoomContext,
1817
VideoTrack,
1918
} from '@livekit/react-native';
20-
import { useConnectionDetails } from '@/hooks/useConnectionDetails';
2119
import { SafeAreaView } from 'react-native-safe-area-context';
2220
import { useRouter } from 'expo-router';
2321
import ControlBar from './ui/ControlBar';
2422
import ChatBar from './ui/ChatBar';
2523
import ChatLog from './ui/ChatLog';
2624
import AgentVisualization from './ui/AgentVisualization';
27-
import useDataStreamTranscriptions from '@/hooks/useDataStreamTranscriptions';
2825
import { Track } from 'livekit-client';
26+
import { TrackReference, useSessionContext, useSessionMessages, useTrackToggle } from '@livekit/components-react';
27+
import { useConnection } from '@/hooks/useConnection';
2928

3029
export default function AssistantScreen() {
3130
// Start the audio session first.
@@ -40,27 +39,19 @@ export default function AssistantScreen() {
4039
};
4140
}, []);
4241

43-
const connectionDetails = useConnectionDetails();
44-
4542
return (
4643
<SafeAreaView>
47-
<LiveKitRoom
48-
serverUrl={connectionDetails?.url}
49-
token={connectionDetails?.token}
50-
connect={true}
51-
audio={true}
52-
video={false}
53-
>
54-
<RoomView />
55-
</LiveKitRoom>
44+
<RoomView />
5645
</SafeAreaView>
5746
);
5847
}
5948

6049
const RoomView = () => {
6150
const router = useRouter();
62-
51+
const connection = useConnection();
52+
const session = useSessionContext();
6353
const room = useRoomContext();
54+
6455
useIOSAudioManagement(room, true);
6556

6657
const {
@@ -83,39 +74,34 @@ const RoomView = () => {
8374
participant: localParticipant,
8475
publication: localCameraTrack,
8576
source: Track.Source.Camera,
86-
}
77+
} satisfies TrackReference
8778
: localScreenShareTrack.length > 0 && isScreenShareEnabled
8879
? localScreenShareTrack[0]
8980
: null;
9081

91-
// Transcriptions
92-
const transcriptionState = useDataStreamTranscriptions();
93-
const addTranscription = transcriptionState.addTranscription;
82+
// Messages
83+
const { messages, send } = useSessionMessages()
9484
const [isChatEnabled, setChatEnabled] = useState(false);
9585
const [chatMessage, setChatMessage] = useState('');
9686

9787
const onChatSend = useCallback(
9888
(message: string) => {
99-
addTranscription(localParticipantIdentity, message);
89+
send(message)
10090
setChatMessage('');
10191
},
102-
[localParticipantIdentity, addTranscription, setChatMessage]
92+
[localParticipantIdentity, setChatMessage]
10393
);
10494

10595
// Control callbacks
106-
const onMicClick = useCallback(() => {
107-
localParticipant.setMicrophoneEnabled(!isMicrophoneEnabled);
108-
}, [isMicrophoneEnabled, localParticipant]);
109-
const onCameraClick = useCallback(() => {
110-
localParticipant.setCameraEnabled(!isCameraEnabled);
111-
}, [isCameraEnabled, localParticipant]);
112-
const onScreenShareClick = useCallback(() => {
113-
localParticipant.setScreenShareEnabled(!isScreenShareEnabled);
114-
}, [isScreenShareEnabled, localParticipant]);
96+
const micToggle = useTrackToggle({ source: Track.Source.Microphone });
97+
const cameraToggle = useTrackToggle({ source: Track.Source.Camera });
98+
const screenShareToggle = useTrackToggle({ source: Track.Source.ScreenShare });
11599
const onChatClick = useCallback(() => {
116100
setChatEnabled(!isChatEnabled);
117101
}, [isChatEnabled, setChatEnabled]);
118102
const onExitClick = useCallback(() => {
103+
connection.startDisconnectTransition();
104+
connection.onDisconnectTransitionComplete();
119105
router.back();
120106
}, [router]);
121107

@@ -161,7 +147,7 @@ const RoomView = () => {
161147
<View style={styles.spacer} />
162148
<ChatLog
163149
style={styles.logContainer}
164-
transcriptions={transcriptionState.transcriptions}
150+
messages={messages}
165151
/>
166152
<ChatBar
167153
style={styles.chatBar}
@@ -194,10 +180,10 @@ const RoomView = () => {
194180
isCameraEnabled,
195181
isScreenShareEnabled,
196182
isChatEnabled,
197-
onMicClick,
198-
onCameraClick,
183+
onMicClick: micToggle.toggle,
184+
onCameraClick: cameraToggle.toggle,
199185
onChatClick,
200-
onScreenShareClick,
186+
onScreenShareClick: screenShareToggle.toggle,
201187
onExitClick,
202188
}}
203189
/>

app/assistant/ui/AgentVisualization.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useVoiceAssistant } from '@livekit/components-react';
1+
import { useAgent, useVoiceAssistant } from '@livekit/components-react';
22
import { BarVisualizer, VideoTrack } from '@livekit/react-native';
33
import React, { useCallback, useState } from 'react';
44
import {
@@ -16,17 +16,19 @@ type AgentVisualizationProps = {
1616
const barSize = 0.2;
1717

1818
export default function AgentVisualization({ style }: AgentVisualizationProps) {
19-
const { state, audioTrack, videoTrack } = useVoiceAssistant();
19+
const { state, microphoneTrack, cameraTrack } = useAgent();
2020
const [barWidth, setBarWidth] = useState(0);
2121
const [barBorderRadius, setBarBorderRadius] = useState(0);
22+
2223
const layoutCallback = useCallback((event: LayoutChangeEvent) => {
2324
const { x, y, width, height } = event.nativeEvent.layout;
2425
console.log(x, y, width, height);
2526
setBarWidth(barSize * height);
2627
setBarBorderRadius(barSize * height);
2728
}, []);
28-
let videoView = videoTrack ? (
29-
<VideoTrack trackRef={videoTrack} style={styles.videoTrack} />
29+
30+
let videoView = cameraTrack ? (
31+
<VideoTrack trackRef={cameraTrack} style={styles.videoTrack} />
3032
) : null;
3133
return (
3234
<View style={[style, styles.container]}>
@@ -40,7 +42,7 @@ export default function AgentVisualization({ style }: AgentVisualizationProps) {
4042
barColor: '#FFFFFF',
4143
barBorderRadius: barBorderRadius,
4244
}}
43-
trackRef={audioTrack}
45+
trackRef={microphoneTrack}
4446
style={styles.barVisualizer}
4547
/>
4648
</View>

app/assistant/ui/ChatLog.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Transcription } from '@/hooks/useDataStreamTranscriptions';
2-
import { useLocalParticipant } from '@livekit/components-react';
1+
import { ReceivedMessage, useLocalParticipant } from '@livekit/components-react';
32
import { useCallback } from 'react';
43
import {
54
ListRenderItemInfo,
@@ -14,28 +13,27 @@ import Animated, { LinearTransition } from 'react-native-reanimated';
1413

1514
export type ChatLogProps = {
1615
style: StyleProp<ViewStyle>;
17-
transcriptions: Transcription[];
16+
messages: ReceivedMessage[];
1817
};
19-
export default function ChatLog({ style, transcriptions }: ChatLogProps) {
18+
export default function ChatLog({ style, messages: transcriptions }: ChatLogProps) {
2019
const { localParticipant } = useLocalParticipant();
21-
const localParticipantIdentity = localParticipant.identity;
2220

2321
const renderItem = useCallback(
24-
({ item }: ListRenderItemInfo<Transcription>) => {
25-
const isLocalUser = item.identity === localParticipantIdentity;
22+
({ item }: ListRenderItemInfo<ReceivedMessage>) => {
23+
const isLocalUser = item.from === localParticipant;
2624
if (isLocalUser) {
27-
return <UserTranscriptionText text={item.segment.text} />;
25+
return <UserTranscriptionText text={item.message} />;
2826
} else {
29-
return <AgentTranscriptionText text={item.segment.text} />;
27+
return <AgentTranscriptionText text={item.message} />;
3028
}
3129
},
32-
[localParticipantIdentity]
30+
[localParticipant]
3331
);
3432

3533
return (
3634
<Animated.FlatList
3735
renderItem={renderItem}
38-
data={transcriptions}
36+
data={transcriptions.toReversed()}
3937
style={style}
4038
inverted={true}
4139
itemLayoutAnimation={LinearTransition}

package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,22 @@
1919
"dependencies": {
2020
"@config-plugins/react-native-webrtc": "13.0.0",
2121
"@expo/vector-icons": "^15.0.3",
22-
"@livekit/components-react": "^2.8.1",
23-
"@livekit/react-native": "^2.9.0",
22+
"@livekit/components-react": "^2.9.15",
23+
"@livekit/react-native": "^2.9.5",
2424
"@livekit/react-native-expo-plugin": "^1.0.1",
2525
"@livekit/react-native-webrtc": "^137.0.0",
2626
"@react-navigation/bottom-tabs": "^7.2.0",
2727
"@react-navigation/native": "^7.0.14",
2828
"expo": "^54.0.22",
29-
"expo-blur": "~15.0.7",
3029
"expo-constants": "~18.0.10",
3130
"expo-dev-client": "~6.0.16",
3231
"expo-font": "~14.0.9",
33-
"expo-haptics": "~15.0.7",
34-
"expo-linking": "~8.0.8",
3532
"expo-router": "~6.0.14",
3633
"expo-splash-screen": "~31.0.10",
3734
"expo-status-bar": "~3.0.8",
3835
"expo-symbols": "~1.0.7",
3936
"expo-system-ui": "~6.0.8",
40-
"expo-web-browser": "~15.0.9",
41-
"livekit-client": "^2.11.2",
37+
"livekit-client": "^2.15.16",
4238
"react": "19.1.0",
4339
"react-dom": "19.1.0",
4440
"react-native": "0.81.5",
@@ -48,6 +44,7 @@
4844
"react-native-screens": "~4.16.0",
4945
"react-native-web": "^0.21.0",
5046
"react-native-webview": "13.15.0",
47+
"react-native-worklets": "0.5.1",
5148
"typescript": "5.0.4"
5249
},
5350
"devDependencies": {

0 commit comments

Comments
 (0)