> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate a Voice Agent with React

> Connect a Zero Runtime voice AI agent to a React app so users can talk to it in real time using the Google Gemini Live API.

Zero Runtime lets you integrate AI agents with real-time voice interaction into your React application within minutes.

In this quickstart, you'll create an AI agent that joins a meeting room and interacts with users through voice using the Google Gemini Live API.

## Prerequisites

Before proceeding, ensure that your development environment meets the following requirements:

* A Zero Runtime account (create one from the [Zero Runtime Dashboard](https://app.zeroruntime.ai/)).
* Node.js and Python 3.11+ installed on your device.
* A Google API key with Gemini Live API access.

<Note>
  You need a Zero Runtime account to generate a token and a Google API key for the Gemini Live API.
  Generate a token from the [Zero Runtime Dashboard](https://app.zeroruntime.ai/) and a Google API key from [Google AI Studio](https://aistudio.google.com/api-keys).
</Note>

## Project Structure

Your project structure should look like this:

<Tree>
  <Tree.Folder name="root" defaultOpen>
    <Tree.Folder name="node_modules" />

    <Tree.Folder name="public" />

    <Tree.Folder name="src" defaultOpen>
      <Tree.File name="config.js" />

      <Tree.File name="App.js" />

      <Tree.File name="index.js" />
    </Tree.Folder>

    <Tree.File name="agent-react.py" />

    <Tree.File name=".env" />
  </Tree.Folder>
</Tree>

You will be working on the following files:

* `App.js`: Creates a basic UI for joining the meeting.
* `config.js`: Stores the token and room ID.
* `index.js`: The entry point of your React application.
* `agent-react.py`: The Python AI agent backend using the Google Gemini Live API.
* `.env`: Environment variables for API keys.

## Part 1: React Frontend

<Steps>
  <Step title="Getting started with the code" icon="download">
    Create a new React app using the command below.

    ```bash theme={null}
    npx create-react-app zrt-ai-agent-react-app
    ```

    Install the Zero Runtime React SDK. Make sure you are in your React app directory before you run this command.

    ```bash theme={null}
    npm install "@videosdk.live/react-sdk"
    ```
  </Step>

  <Step title="Configure environment and credentials" icon="key">
    Create a meeting room using the Zero Runtime API:

    ```bash theme={null}
    curl -X POST https://api.videosdk.live/v2/rooms \
      -H "Authorization: YOUR_JWT_TOKEN_HERE" \
      -H "Content-Type: application/json"
    ```

    Copy the `roomId` from the response and configure it in `src/config.js`:

    ```js title="src/config.js" theme={null}
    export const TOKEN = "YOUR_ZRT_AUTH_TOKEN";
    export const ROOM_ID = "YOUR_MEETING_ID"; // Create using the Zero Runtime API (curl -X POST https://api.videosdk.live/v2/rooms)
    ```
  </Step>

  <Step title="Design the user interface" icon="window">
    Create the main App component with audio-only interaction in `src/App.js`:

    ```js title="src/App.js" theme={null}
    import React, { useEffect, useRef, useState } from "react";
    import { MeetingProvider, MeetingConsumer, useMeeting, useParticipant } from "@videosdk.live/react-sdk";
    import { TOKEN, ROOM_ID } from "./config";

    function ParticipantAudio({ participantId }) {
      const { micStream, micOn, isLocal, displayName } = useParticipant(participantId);
      const audioRef = useRef(null);

      useEffect(() => {
        if (!audioRef.current) return;
        if (micOn && micStream) {
          const mediaStream = new MediaStream();
          mediaStream.addTrack(micStream.track);
          audioRef.current.srcObject = mediaStream;
          audioRef.current.play().catch(() => {});
        } else {
          audioRef.current.srcObject = null;
        }
      }, [micStream, micOn]);

      return (
        <div>
          <p>Participant: {displayName} | Mic: {micOn ? "ON" : "OFF"}</p>
          <audio ref={audioRef} autoPlay muted={isLocal} />
        </div>
      );
    }

    function Controls() {
      const { leave, toggleMic } = useMeeting();
      return (
        <div>
          <button onClick={() => leave()}>Leave</button>
          <button onClick={() => toggleMic()}>Toggle Mic</button>
        </div>
      );
    }

    function MeetingView({ meetingId, onMeetingLeave }) {
      const [joined, setJoined] = useState(null);
      const { join, participants } = useMeeting({
        onMeetingJoined: () => setJoined("JOINED"),
        onMeetingLeft: onMeetingLeave,
      });

      const joinMeeting = () => {
        setJoined("JOINING");
        join();
      };

      return (
        <div>
          <h3>Meeting Id: {meetingId}</h3>
          {joined === "JOINED" ? (
            <div>
              <Controls />
              {[...participants.keys()].map((pid) => (
                <ParticipantAudio key={pid} participantId={pid} />
              ))}
            </div>
          ) : joined === "JOINING" ? (
            <p>Joining the meeting...</p>
          ) : (
            <button onClick={joinMeeting}>Join</button>
          )}
        </div>
      );
    }

    export default function App() {
      const [meetingId] = useState(ROOM_ID);

      const onMeetingLeave = () => {
        // no-op; simple sample
      };

      return (
        <MeetingProvider
          config={{
            meetingId,
            micEnabled: true,
            webcamEnabled: false,
            name: "Agent React User",
            multiStream: false,
          }}
          token={TOKEN}
        >
          <MeetingConsumer>
            {() => <MeetingView meetingId={meetingId} onMeetingLeave={onMeetingLeave} />}
          </MeetingConsumer>
        </MeetingProvider>
      );
    }
    ```
  </Step>
</Steps>

## Part 2: Python AI Agent

<Steps>
  <Step title="Setup the project" icon="download">
    Use Python 3.11 or higher, then install the Zero Runtime Agents SDK. Create and activate a virtual environment, then install `zrt` and `python-dotenv`. Every provider plugin ships with `zrt`.

    <CodeGroup>
      ```bash uv theme={null}
      uv venv --python 3.11
      source .venv/bin/activate     # macOS/Linux
      .\.venv\Scripts\activate      # Windows
      ```

      ```bash pip theme={null}
      python3.11 -m venv venv
      source venv/bin/activate      # macOS/Linux
      .\venv\Scripts\activate       # Windows
      ```
    </CodeGroup>

    <Tip>
      New to uv? See the [uv install guide](https://docs.astral.sh/uv/getting-started/installation/).
    </Tip>

    <CodeGroup>
      ```bash uv theme={null}
      uv pip install zrt python-dotenv
      ```

      ```bash pip theme={null}
      pip install zrt python-dotenv
      ```
    </CodeGroup>
  </Step>

  <Step title="Configure environment variables" icon="key">
    Create a `.env` file in your project root to store your keys and token securely for the Python agent:

    ```shell title=".env" theme={null}
    # Google API Key for the Gemini Live API
    GOOGLE_API_KEY=your_google_api_key_here

    # Option A: pre-generated ZRT auth token
    ZRT_AUTH_TOKEN=your_zrt_auth_token_here

    # Option B: SDK auto-generates the token (omit ZRT_AUTH_TOKEN)
    # ZRT_API_KEY=your_zrt_api_key
    # ZRT_SECRET_KEY=your_zrt_secret_key
    ```
  </Step>

  <Step title="Create the AI agent backend" icon="robot">
    Create the Python AI agent that joins the same meeting room and interacts with users through voice.

    ```python title="agent-react.py" theme={null}
    import os
    import zrt
    from zrt import Agent, Pipeline, Room
    from zrt.plugins import GeminiRealtime, GeminiLiveConfig
    from zrt.inference import AICousticsDenoise
    from dotenv import load_dotenv

    load_dotenv()

    AGENT_ID = "react-voice-agent"

    pipeline = Pipeline(
        llm=GeminiRealtime(
            api_key=os.getenv("GOOGLE_API_KEY"),  # optional when GOOGLE_API_KEY is in .env
            config=GeminiLiveConfig(model="gemini-3.1-flash-live-preview", voice="Leda", response_modalities=["AUDIO"]),
        ),
        denoise=AICousticsDenoise(model_id="quail-vf-2.2-l-16khz"),
    )


    class MyVoiceAgent(Agent):
        def __init__(self) -> None:
            super().__init__(
                name="MyVoiceAgent",
                agent_id=AGENT_ID,
                instructions="You are a high-energy game-show host guiding the caller to guess a secret number from 1 to 100 to win 1,000,000$.",
                pipeline=pipeline,
            )

        async def on_enter(self) -> None:
            await self.session.say(
                "Welcome to the Zero Runtime AI Agent game show! I'm your host, and we're about to play for 1,000,000$. Are you ready to play?"
            )

        async def on_exit(self) -> None:
            await self.session.say("Goodbye!")


    def invoke_agent() -> None:
        # Join the same room the frontend created (its meeting ID).
        zrt.invoke(AGENT_ID, room=Room(room_id="YOUR_MEETING_ID"))


    if __name__ == "__main__":
        zrt.serve(MyVoiceAgent, on_ready=invoke_agent)
    ```
  </Step>
</Steps>

## Part 3: Run the Application

<Steps>
  <Step title="Run the frontend" icon="play">
    Once you have completed all the steps above, start your React application:

    ```bash theme={null}
    # Install dependencies
    npm install

    # Start the development server
    npm start
    ```

    Open `http://localhost:3000` in your web browser.
  </Step>

  <Step title="Run the AI agent" icon="terminal">
    Open a new terminal, activate your virtual environment, and run the Python agent. It reads `GOOGLE_API_KEY` from the `.env` file.

    <CodeGroup>
      ```bash uv theme={null}
      uv run python agent-react.py
      ```

      ```bash pip theme={null}
      python agent-react.py
      ```
    </CodeGroup>
  </Step>

  <Step title="Connect and interact" icon="microphone">
    1. **Join the meeting from the React app:**
       * Click the **Join** button in your browser.
       * Allow microphone permissions when prompted.

    2. **Agent connection:**
       * Once you join, the Python backend detects your participation.
       * You should see "Participant joined" in the terminal.
       * The AI agent greets you and initiates the game.

    3. **Start playing:**
       * The agent guides you through a number guessing game (1–100).
       * Use your microphone to interact with the AI host.
       * The agent provides hints and encouragement throughout the game.
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="'Waiting for participant...' but no connection" icon="plug">
    * Ensure both the frontend and backend are running.
    * Check that the room ID matches in both `src/config.js` and `agent-react.py`.
    * Verify your Zero Runtime token is valid.
  </Accordion>

  <Accordion title="Audio not working" icon="volume-high">
    * Check browser permissions for microphone access.
    * Ensure your Google API key has Gemini Live API access enabled.
  </Accordion>

  <Accordion title="Agent not responding" icon="robot">
    * Verify your Google API key is correctly set in the environment.
    * Check that the Gemini Live API is enabled in your Google Cloud Console.
  </Accordion>

  <Accordion title="React build issues" icon="code">
    * Ensure your Node.js version is compatible.
    * Clear the npm cache: `npm cache clean --force`.
    * Delete `node_modules` and reinstall: `rm -rf node_modules && npm install`.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart Example" icon="github" href="https://github.com/ZeroRuntimeAI/zrt-python-sdk-examples">
    Complete working example with source code.
  </Card>

  <Card title="Build Your First Voice Agent" icon="microphone" href="/quickstarts/build-your-first-voice-agent">
    Learn the Cascade and Realtime pipelines in depth.
  </Card>
</CardGroup>
