diff --git a/README.md b/README.md index 80e9534..69e0927 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,24 @@ The app is configured to connect to the LiveKit homepage agent by default, which To switch from the default agent to your own, you first need a LiveKit agent to speak with. For a no-code setup, use the [Agent Builder](https://docs.livekit.io/agents/start/builder/). For more customization, try our starter agent for [Python](https://github.com/livekit-examples/agent-starter-python), [Node.js](https://github.com/livekit-examples/agent-starter-node), or [create your own from scratch](https://docs.livekit.io/agents/start/voice-ai/). -Second, you need a token server. For development, the easiest option is the [sandbox token server](https://docs.livekit.io/frontends/authentication/tokens/sandbox-token-server/): enable it from your project's **Options** on the [Settings](https://cloud.livekit.io/projects/p_/settings/project) page in LiveKit Cloud and copy the `sandboxId`. +Second, you need a token server. For development, the easiest option is the [development token server](https://docs.livekit.io/frontends/build/authentication/development-token-server/): turn on the **Development token server** switch on the [Settings](https://cloud.livekit.io/projects/p_/settings/project) page in LiveKit Cloud and copy the **Token server ID**. -Then edit `sandboxID` in `hooks/useConnection.tsx`: +Then edit `tokenServerId` in `hooks/useConnection.tsx`: ```ts -const sandboxID = 'your id here'; +const tokenServerId = ''; ``` +> [!NOTE] +> The development token server is for prototyping only: any client can request a token with any permissions. See [Token generation](#token-generation) before you ship. +> +> This setting was previously called the *sandbox token server*. + ## Token generation -In a production environment, you will be responsible for developing a solution to [generate tokens for your users](https://docs.livekit.io/home/server/generating-tokens/) which is integrated with your authentication solution. You should disable the token server and modify `hooks/useConnectionDetails.ts` to use your own token server. +In a production environment, you will be responsible for developing a solution to [generate tokens for your users](https://docs.livekit.io/home/server/generating-tokens/) that integrates with your authentication system. + +You should turn off the development token server and replace `TokenSource.developmentTokenServer` in `hooks/useConnection.tsx` with `TokenSource.endpoint` pointing at your own token server, or a `TokenSource.custom` implementation. ## Contributing diff --git a/hooks/useConnection.tsx b/hooks/useConnection.tsx index bad6eea..91cf41c 100644 --- a/hooks/useConnection.tsx +++ b/hooks/useConnection.tsx @@ -2,8 +2,11 @@ import { TokenSource, TokenSourceBase, TokenSourceResponseObject } from 'livekit import { createContext, useContext, useMemo, useState } from 'react'; import { SessionProvider, useSession } from '@livekit/components-react'; -// TODO: Add your Sandbox ID here -const sandboxID = ''; +// TODO: Add your development token server ID here. +// Find it on your LiveKit Cloud project's Settings page under "Development token server". +// See https://docs.livekit.io/frontends/build/authentication/development-token-server/ +// (This setting was previously called the sandbox token server.) +const tokenServerId = ''; // The name of the agent you wish to be dispatched. const agentName = undefined @@ -47,8 +50,8 @@ export function ConnectionProvider({ children }: ConnectionProviderProps) { const [isConnectionActive, setIsConnectionActive] = useState(false); const tokenSource = useMemo(() => { - if (sandboxID) { - return TokenSource.sandboxTokenServer(sandboxID) + if (tokenServerId) { + return TokenSource.developmentTokenServer(tokenServerId) } else if (hardcodedUrl && hardcodedToken) { return TokenSource.literal( { @@ -59,7 +62,7 @@ export function ConnectionProvider({ children }: ConnectionProviderProps) { } else { return TokenSource.endpoint(homepageAgentUrl) } - }, [sandboxID, hardcodedUrl, hardcodedToken]) + }, [tokenServerId, hardcodedUrl, hardcodedToken]) const session = useSession( tokenSource, diff --git a/package-lock.json b/package-lock.json index dfc22be..cac0b1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,9 @@ "@config-plugins/react-native-webrtc": "^15.0.2", "@expo/vector-icons": "^15.0.3", "@livekit/components-react": "2.9.21", - "@livekit/react-native": "^2.12.0", + "@livekit/react-native": "^3.0.0", "@livekit/react-native-expo-plugin": "^1.0.3", - "@livekit/react-native-webrtc": "^144.1.2", + "@livekit/react-native-webrtc": "^144.2.0", "@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/native": "^7.0.14", "expo": "^57.0.0", @@ -26,7 +26,7 @@ "expo-status-bar": "~57.0.1", "expo-symbols": "~57.0.3", "expo-system-ui": "~57.0.4", - "livekit-client": "^2.21.0", + "livekit-client": "^2.22.3", "react": "19.2.3", "react-dom": "19.2.3", "react-native": "0.86.3", @@ -3483,9 +3483,9 @@ } }, "node_modules/@livekit/react-native": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@livekit/react-native/-/react-native-2.12.0.tgz", - "integrity": "sha512-6n4PQr22vtbl6WL6QbLVCLzM5/bCdTt+hHUyMecL8AheEuypVwbhMe5Vj7UuxOeyNojqXdgi2yRWGhB9WH4Gxg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@livekit/react-native/-/react-native-3.0.0.tgz", + "integrity": "sha512-9x9Lv9gUUgw4Gl2BB3YO51FbruV5if+VXv4vx6KsHmVhfV98xYonZqTah/Ue2atyWAhsmLl2zA529fkbyNJuZQ==", "license": "Apache-2.0", "workspaces": [ ".", @@ -3508,7 +3508,7 @@ "node": ">=20" }, "peerDependencies": { - "@livekit/react-native-webrtc": "^144.1.2", + "@livekit/react-native-webrtc": "^144.2.0", "livekit-client": "^2.19.0", "react": "*", "react-native": "*" @@ -3527,9 +3527,9 @@ } }, "node_modules/@livekit/react-native-webrtc": { - "version": "144.1.2", - "resolved": "https://registry.npmjs.org/@livekit/react-native-webrtc/-/react-native-webrtc-144.1.2.tgz", - "integrity": "sha512-Ls8w3FGlf67SMNu6r8SUpbFHXMIkyEEGb25j6apZ7HrBSGqOFSRWAx7ms9z5d0D3e9Zs1AMNiziG1YWBLOtqiQ==", + "version": "144.2.0", + "resolved": "https://registry.npmjs.org/@livekit/react-native-webrtc/-/react-native-webrtc-144.2.0.tgz", + "integrity": "sha512-7HrXfvFiPlAzmxRFJ/lSPDMZ1d4NvqwUUn7k3N95V6Xgw7/ckVrc+GapOHnrIUwLASQNqnTEpOnYpbVoVPj3bw==", "license": "MIT", "dependencies": { "base64-js": "1.5.1", @@ -11772,9 +11772,9 @@ "license": "MIT" }, "node_modules/livekit-client": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.21.0.tgz", - "integrity": "sha512-RBUhPkV/sl1nzl8lokVlK5uATPwn0AlsudCBZXissw/kDl9yz8ac4pNJ43iPpMVoHOeBYH/BZ3vUC1adqa/zFQ==", + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/livekit-client/-/livekit-client-2.22.3.tgz", + "integrity": "sha512-jw9zBKXY5Gtr5MZ7vEON3QhMNccuDvYHck1PFSyG1aaateQPqgKZFBMgZkFZaXHIf9RV4MDW5xpTK2b/+qbwOg==", "license": "Apache-2.0", "dependencies": { "@livekit/mutex": "1.1.1", @@ -11782,6 +11782,7 @@ "events": "^3.3.0", "jose": "^6.1.0", "loglevel": "^1.9.2", + "machina": "^7.0.0", "sdp-transform": "^2.15.0", "tslib": "2.8.1", "typed-emitter": "^2.1.0", @@ -11950,6 +11951,15 @@ "yallist": "^3.0.2" } }, + "node_modules/machina": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/machina/-/machina-7.0.1.tgz", + "integrity": "sha512-0Xkgs8NeBvO2hW6bjJT8ewLWrMfh1haMPstaghpASWjXkLjRhtDiaJG1Kb7mslaOHxZYxpH7PIjpmirRVYbMMA==", + "license": "MIT", + "engines": { + "node": ">=22.22" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", diff --git a/package.json b/package.json index 085513e..b65c0e2 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "@config-plugins/react-native-webrtc": "^15.0.2", "@expo/vector-icons": "^15.0.3", "@livekit/components-react": "2.9.21", - "@livekit/react-native": "^2.12.0", + "@livekit/react-native": "^3.0.0", "@livekit/react-native-expo-plugin": "^1.0.3", - "@livekit/react-native-webrtc": "^144.1.2", + "@livekit/react-native-webrtc": "^144.2.0", "@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/native": "^7.0.14", "expo": "^57.0.0", @@ -35,7 +35,7 @@ "expo-status-bar": "~57.0.1", "expo-symbols": "~57.0.3", "expo-system-ui": "~57.0.4", - "livekit-client": "^2.21.0", + "livekit-client": "^2.22.3", "react": "19.2.3", "react-dom": "19.2.3", "react-native": "0.86.3", diff --git a/taskfile.yaml b/taskfile.yaml index 9c6d74e..70b8ae6 100644 --- a/taskfile.yaml +++ b/taskfile.yaml @@ -5,13 +5,13 @@ tasks: post_create: desc: "Runs after this template is instantiated as a Sandbox or Bootstrap" vars: - TOKEN_FILE: "hooks/useConnection.ts" + TOKEN_FILE: "hooks/useConnection.tsx" cmds: - - echo -e "Setting up sandbox..." + - echo -e "Setting up development token server..." - platforms: [darwin] - cmd: sed -i "" "s/sandboxID = ''/sandboxID = '{{.LIVEKIT_SANDBOX_ID}}'/g" "{{.ROOT_DIR}}/{{.TOKEN_FILE}}" + cmd: sed -i "" "s/tokenServerId = ''/tokenServerId = '{{.LIVEKIT_TOKEN_SERVER_ID | default .LIVEKIT_SANDBOX_ID}}'/g" "{{.ROOT_DIR}}/{{.TOKEN_FILE}}" - platforms: [linux, windows] - cmd: sed -i "s/sandboxID = ''/sandboxID = '{{.LIVEKIT_SANDBOX_ID}}'/g" "{{.ROOT_DIR}}/{{.TOKEN_FILE}}" + cmd: sed -i "s/tokenServerId = ''/tokenServerId = '{{.LIVEKIT_TOKEN_SERVER_ID | default .LIVEKIT_SANDBOX_ID}}'/g" "{{.ROOT_DIR}}/{{.TOKEN_FILE}}" - echo -e "\nYour React-Native voice assistant is ready to go!\n" - echo -e "Install the dependencies by running \"npm install\""