LiveKit Agents Playground

repository·main·Indexed 18 days ago

https://github.com/livekit/agents-playground

A toolkit for building and testing LiveKit AI agents, featuring UI components for debugging, monitoring, and visualizing agent interactions. Includes tools such as AudioWaveform for real-time audio visualization, DebugPanel for session state inspection, EventLog for monitoring session events, and the Playground component for agent dispatch and configuration.

Tokens
9.5K
Snippets
30
Records
40
Agent score
62%

What's inside agents-playground

  1. Set Participant Attributes and Metadata

    main

    The Playground allows users to dynamically set participant attributes and metadata before or during a session. These values are passed to the tokenSource via TokenSourceFetchOptions and are used when requesting a token.

    Attributes

    Attributes are key-value pairs that can be edited in the 'User' section of the Settings panel. These are sent as participantAttributes in the token fetch request.

    Metadata

    Metadata is a string that can be updated via the AttributesInspector in the settings panel. This is sent as participantMetadata in the token fetch request.

  2. How settings are persisted via URL and Cookies

    main

    The playground uses a multi-layered approach to persist and synchronize user settings:

    1. URL Hash: Settings are encoded in the URL hash (e.g., /#cam=1&mic=0&theme_color=cyan). This allows users to share specific configurations via a link.
    2. Cookies: Settings are also stored in a cookie named lk_settings as a JSON string.
    3. Synchronization Logic:
      • If settings exist in the URL but not in cookies, the URL settings are saved to the cookie.
      • If settings exist in cookies but not in the URL, the cookie settings are applied to the URL.
      • The ConfigProvider resolves these layers on mount to ensure a consistent state.
  3. Configure Agent Dispatch via agentOptions

    main

    When using the Playground component, you can influence which agent is dispatched by providing agentOptions. This uses the RoomAgentDispatch structure. Specifically, setting agentName allows for explicit dispatch, where the playground requests a specific agent by name rather than letting the server pick any available agent.

    Supported keys in agentOptions (via PartialMessage<RoomAgentDispatch>):

    • agentName: The name of the agent to dispatch.
    • metadata: Metadata to pass to the agent.
    const agentOptions = {
      agentName: 'my-special-agent',
      metadata: 'some-metadata-string'
    };
    
    <Playground 
      tokenSource={tokenSource} 
      themeColors={['blue']} 
      agentOptions={agentOptions} 
    />
  4. Configure TokenSource for Playground connection

    main

    The playground requires a TokenSource to connect to LiveKit. You can configure this using the TokenSource class from livekit-client.

    If a NEXT_PUBLIC_LIVEKIT_URL environment variable is present, the application defaults to using an endpoint at /api/token via TokenSource.endpoint("/api/token").

    In the HomeInner component, the tokenSource state determines whether to show the PlaygroundConnect UI (to select a source) or the Playground UI (to start the session).

    import { TokenSourceConfigurable, TokenSource } from "livekit-client";
    
    // Example of setting a token source via an endpoint
    const tokenSource = TokenSource.endpoint("/api/token");
  5. Analyze OverlappingSpeechEvent timing

    main

    The overlappingSpeechEvents array provides enriched data for overlappingSpeech events, which is useful for calculating latency or aligning UI state with agent actions.

    Each OverlappingSpeechEvent contains:

    • speech: The raw AgentSessionEvent_OverlappingSpeech object.
    • createdAt: The server-side timestamp when the event was created.
    • createdAtSeconds: The createdAt timestamp converted to seconds.
    • detectedAtSeconds: The timestamp when the overlap was detected (falls back to createdAtSeconds if unavailable).
    • receivedAt: The wall-clock epoch time (in seconds) when the client actually received the event.
  6. Configure the application via NEXT_PUBLIC_APP_CONFIG

    main

    The application's global behavior and appearance can be configured using the NEXT_PUBLIC_APP_CONFIG environment variable. This variable expects a YAML-formatted string that is parsed into an AppConfig object. If this variable is not set, the application falls back to a default configuration.

    AppConfig Schema

    KeyTypeDescription
    titlestringThe application title
    descriptionstringA description of the playground
    github_linkstring (optional)Link to the GitHub repository
    video_fit'cover' | 'contain'How the video should fit the container
    show_qrboolean (optional)Whether to show a QR code
    agent_dispatchPartialMessage<RoomAgentDispatch> (optional)Configuration to support a specific agent
    settingsUserSettingsUser-facing settings (see UserSettings)
    title: "My Custom Playground"
    description: "Testing my custom agent"
    video_fit: "cover"
    settings:
      editable: true
      theme_color: "blue"
      chat: true
      inputs:
        camera: true
        screen: true
        mic: true
      outputs:
        audio: true
        video: true
  7. Use useStreamingWaveform to capture audio amplitude

    main

    The useStreamingWaveform hook extracts amplitude data from a LiveKit Track and stores it in a buffer synchronized with a WaveformClock.

    Important: The getData() method returns a WaveformSnapshot. The buffer property is a live reference to the internal Uint8Array. Its contents are mutated in-place by the sampling interval. You must consume this data synchronously (e.g., inside a requestAnimationFrame callback). If you need to persist the data for later use, you must copy it using buffer.slice(0, count).

    Parameters:

    • track: The LiveKit Track to analyze. If undefined, the buffer is cleared.
    • clock: An instance of WaveformClock to synchronize the sampling with a timeline.

    Returns:

    • An object containing getData(), which returns the current WaveformSnapshot.
    import { useStreamingWaveform } from './useStreamingWaveform';
    import type { Track } from 'livekit-client';
    
    // Assuming 'clock' is provided by useWaveformClock()
    const { getData } = useStreamingWaveform(track, clock);
    
    // Inside a render loop or requestAnimationFrame
    const frame = () => {
      const { buffer, count } = getData();
      // Use buffer and count to draw the waveform
      // Note: buffer is mutated in-place!
      requestAnimationFrame(frame);
    };
    requestAnimationFrame(frame);
  8. Use the DebugPanel component

    main

    The DebugPanel component is used to inspect real-time session state, including audio waveforms, event logs, performance metrics, and session usage. It provides a visual interface for debugging agent-user interactions, latency, and state transitions.

    Key Props

    PropTypeDescription
    userTrackTrack | undefinedThe audio track for the user.
    agentTrackTrack | undefinedThe audio track for the agent.
    eventsAgentSession.AgentSessionEvent[]An array of session events (e.g., state changes).
    overlappingSpeechEventsOverlappingSpeechEvent[]Events representing speech overlap (interruptions or backchannels).
    sessionUsageAgentSession.AgentSessionUsage | nullData regarding session resource usage.
    onClearEvents() => voidCallback to clear the event log.
    networkLatencynumberOne-way server-to-client transit time in seconds.
    uplinkLatencyUplinkLatency | undefinedDetailed client-to-agent pipeline latency.
    trackLabelsDebugPanelTrackLabels | undefinedCustom labels for the user and agent tracks.
    trackColorsDebugPanelTrackColors | undefinedCustom colors for the user and agent waveforms.
    highlightConfigDebugPanelHighlightConfig | undefinedCustom labels and colors for interruption/backchannel highlights.

    Customization Types

    DebugPanelTrackLabels

    type DebugPanelTrackLabels = {
      user?: string;
      agent?: string;
    };

    DebugPanelTrackColors

    type DebugPanelTrackColors = {
      agent?: string;
      user?: string;
    };

    DebugPanelHighlightConfig

    type DebugPanelHighlightConfig = {
      /** Label for interruption highlights. @default "Interruption" */
      interruptionLabel?: string;
      /** Label for backchannel highlights. @default "Backchannel" */
      backchannelLabel?: string;
      /** Color for interruption highlights. @default "#FA4C39" */
      interruptionColor?: string;
      /** Color for backchannel highlights. @default "#23DE6B" */
      backchannelColor?: string;
    };
    import { DebugPanel } from "./debug-panel";
    
    // Example usage:
    <DebugPanel
      userTrack={userTrack}
      agentTrack={agentTrack}
      events={events}
      overlappingSpeechEvents={overlappingSpeechEvents}
      sessionUsage={sessionUsage}
      onClearEvents={handleClearEvents}
      networkLatency={networkLatency}
      uplinkLatency={uplinkLatency}
      trackLabels={{ user: "Customer", agent: "AI Assistant" }}
      trackColors={{ agent: "#BA1FF9", user: "#666666" }}
      highlightConfig={{
        interruptionLabel: "User Interrupted",
        interruptionColor: "#FF0000",
      }}
    />
  9. Configure EventLogProps

    main

    The EventLog component accepts the following props:

    • events: An array of AgentSession.AgentSessionEvent objects to display.
    • enabledTypes: A Set<SessionEventType> representing the currently active event types to show in the log.
    • onEnabledTypesChange: A callback function (types: Set<SessionEventType>) => void triggered when the user toggles event type filters.
    • onClear (optional): A callback function triggered when the user clicks the 'Clear' button.
    • className (optional): A string for additional CSS classes.
  10. Use the useRemoteSession hook to manage agent sessions

    main

    The useRemoteSession hook provides a React interface for interacting with a remote LiveKit agent session via a Room instance. It handles the low-level byte stream communication, event tracking, and RPC (Remote Procedure Call) requests.

    Use this hook to:

    • Monitor real-time agent events.
    • Track network latency based on speech overlap events.
    • Access session usage statistics.
    • Send requests to a specific agent identity.
    • Clear the event history.
    import { Room } from 'livekit-client';
    import { useRemoteSession } from './hooks/useRemoteSession';
    
    function MyComponent({ room }: { room: Room }) {
      const {
        events,
        overlappingSpeechEvents,
        sessionUsage,
        networkLatency,
        clearEvents,
        sendRequest
      } = useRemoteSession(room);
    
      const handleAgentRequest = async () => {
        try {
          const response = await sendRequest('agent-identity-here', { /* request payload */ });
          console.log('Agent response:', response);
        } catch (error) {
          console.error('Request failed:', error);
        }
      };
    
      return (
        // Render UI using session data
      );
    }
  11. Configure the Playground component

    main

    The Playground component is the main entry point for the agents-playground UI. It requires a tokenSource for authentication and themeColors for styling. You can optionally provide agentOptions to pre-configure the agent being connected to (e.g., setting its name or metadata) and autoConnect to start the session immediately upon mounting.

    Props

    • themeColors: An array of strings representing available theme colors.
    • tokenSource: A TokenSourceConfigurable object used to fetch LiveKit tokens.
    • agentOptions (optional): A PartialMessage<RoomAgentDispatch> used to pass initial configuration to the agent (like agentName or metadata).
    • autoConnect (optional): A boolean that, if true, triggers session.start() automatically.
    • logo (optional): A React node to display in the header.
    import Playground from './components/playground/Playground';
    
    // Example usage
    <Playground 
      themeColors={['blue', 'red', 'green']} 
      tokenSource={myTokenSource} 
      agentOptions={{ agentName: 'my-agent' }}
      autoConnect={true}
    />
  12. Display toast notifications using useToast

    main

    To display toast notifications in the playground, use the useToast hook (imported from ./ToasterProvider). This hook provides setToastMessage, which allows you to trigger a notification with a specific message and type. The PlaygroundToast component handles the visual rendering of these messages.

    Supported ToastType values:

    • "error": Renders with red styling.
    • "success": Renders with green styling.
    • "info": Renders with amber styling.
    import { useToast } from "./ToasterProvider";
    
    // Inside your component:
    const { setToastMessage } = useToast();
    
    const triggerError = () => {
      setToastMessage({
        message: "An error occurred!",
        type: "error"
      });
    };