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

# React SDK Reference

> Complete reference for @upliftai/assistants-react

<Note>
  **Beta**: The SDK is in beta and actively being improved. Check npm for latest version.
</Note>

## Installation

```bash theme={null}
npm install @upliftai/assistants-react @livekit/components-react livekit-client
```

## Core Components

### `<UpliftAIRoom>`

The main wrapper component that establishes connection to the assistant.

```jsx theme={null}
import { UpliftAIRoom } from '@upliftai/assistants-react';

<UpliftAIRoom
  token={sessionToken}
  serverUrl={wsUrl}
  connect={true}
  audio={true}
  video={false}
  tools={toolsArray}
  onConnectionChange={(connected, agentIdentity) => {}}
  onToolsChange={(tools) => {}}
>
  <YourComponents />
</UpliftAIRoom>
```

#### Props

| Prop                 | Type           | Required | Description                           |
| -------------------- | -------------- | -------- | ------------------------------------- |
| `token`              | `string`       | Yes      | JWT session token from createSession  |
| `serverUrl`          | `string`       | Yes      | WebSocket URL for LiveKit server      |
| `connect`            | `boolean`      | No       | Auto-connect on mount (default: true) |
| `audio`              | `boolean`      | No       | Enable audio (default: true)          |
| `video`              | `boolean`      | No       | Enable video (default: false)         |
| `tools`              | `ToolConfig[]` | No       | Array of tool configurations          |
| `onConnectionChange` | `function`     | No       | Connection status callback            |
| `onToolsChange`      | `function`     | No       | Tools change callback                 |

## Hooks

### `useUpliftAIRoom()`

Access room functionality and state.

```javascript theme={null}
const {
  // Methods
  addTool,
  updateTool,
  removeTool,
  upsertTools,
  updateInstruction,
  
  // State
  isConnected,
  agentParticipant,
  room
} = useUpliftAIRoom();
```

#### Methods

##### `addTool(config: ToolConfig): Promise<void>`

Add a new tool to the assistant.

```javascript theme={null}
await addTool({
  name: 'calculator',
  description: 'Perform calculations',
  parameters: { /* ... */ },
  handler: async (data) => { /* ... */ }
});
```

##### `updateTool(config: ToolConfig): Promise<void>`

Update an existing tool configuration.

```javascript theme={null}
await updateTool({
  name: 'calculator',
  description: 'Updated description',
  // ... new configuration
});
```

##### `removeTool(name: string): Promise<void>`

Remove a tool by name.

```javascript theme={null}
await removeTool('calculator');
```

##### `upsertTools(configs: ToolConfig[]): Promise<void>`

Replace all tools with new set.

```javascript theme={null}
await upsertTools([tool1, tool2, tool3]);
```

##### `updateInstruction(instruction: string): Promise<void>`

Update assistant's system instructions.

```javascript theme={null}
await updateInstruction('You are now a pirate. Speak accordingly.');
```

### `useVoiceAssistant()`

Get voice assistant state.

```javascript theme={null}
const { state, participant } = useVoiceAssistant();

// state: 'listening' | 'thinking' | 'speaking'
```

### `useTracks()`

Access audio/video tracks.

```javascript theme={null}
import { useTracks } from '@upliftai/assistants-react';
import { Track } from 'livekit-client';

const tracks = useTracks([Track.Source.Microphone], {
  onlySubscribed: true,
});

const agentTrack = tracks.find(t => !t.participant.isLocal);
```

### `useConnectionState()`

Monitor connection status.

```javascript theme={null}
const { state, error } = useConnectionState();

// state: 'disconnected' | 'connecting' | 'connected' | 'reconnecting'
```

## UI Components

### Audio Components

#### `<AudioTrack>`

Renders audio output for a track.

```jsx theme={null}
<AudioTrack trackRef={agentTrack} />
```

#### `<BarVisualizer>`

Animated audio visualization bars.

```jsx theme={null}
<BarVisualizer
  state={agentState}
  trackRef={agentTrack}
  barCount={20}
  className="visualizer"
/>
```

Props:

* `state`: Voice assistant state
* `trackRef`: Audio track reference
* `barCount`: Number of bars (default: 7)
* `className`: CSS class name

### Control Components

#### `<TrackToggle>`

Toggle microphone or camera.

```jsx theme={null}
<TrackToggle source={Track.Source.Microphone}>
  Microphone
</TrackToggle>
```

#### `<DisconnectButton>`

End the session.

```jsx theme={null}
<DisconnectButton>
  End Call
</DisconnectButton>
```

#### `<ControlBar>`

Full control bar with all controls.

```jsx theme={null}
<ControlBar />
```

## Type Definitions

### ToolConfig

```typescript theme={null}
interface ToolConfig {
  name: string;
  description: string;
  parameters: {
    type: 'object';
    properties: Record<string, ParameterConfig>;
    required?: string[];
  };
  timeout: number;
  handler: (data: ToolInvocationData) => Promise<string>;
}
```

### ParameterConfig

```typescript theme={null}
interface ParameterConfig {
  type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
  description?: string;
  enum?: any[];
  items?: ParameterConfig;
  properties?: Record<string, ParameterConfig>;
  required?: string[];
}
```

### ToolInvocationData

```typescript theme={null}
interface ToolInvocationData {
  requestId: string;
  callerIdentity: string;
  payload: string; // JSON string to parse
  responseTimeout: number;
}
```

## Complete Examples

### Basic Voice Assistant

```jsx theme={null}
import React from 'react';
import {
  UpliftAIRoom,
  useUpliftAIRoom,
  useVoiceAssistant,
  BarVisualizer,
  TrackToggle,
  DisconnectButton,
  AudioTrack,
  useTracks
} from '@upliftai/assistants-react';
import { Track } from 'livekit-client';

function VoiceAssistant({ token, wsUrl }) {
  return (
    <UpliftAIRoom
      token={token}
      serverUrl={wsUrl}
      connect={true}
      audio={true}
    >
      <AssistantUI />
    </UpliftAIRoom>
  );
}

function AssistantUI() {
  const { isConnected, agentParticipant } = useUpliftAIRoom();
  const { state } = useVoiceAssistant();
  const tracks = useTracks([Track.Source.Microphone], {
    onlySubscribed: true
  });
  
  const agentTrack = tracks.find(t => !t.participant.isLocal);
  
  return (
    <div>
      <h2>Status: {isConnected ? 'Connected' : 'Disconnected'}</h2>
      
      {agentTrack && (
        <>
          <AudioTrack trackRef={agentTrack} />
          <BarVisualizer
            state={state}
            trackRef={agentTrack}
          />
        </>
      )}
      
      <p>
        {state === 'listening' && 'Listening...'}
        {state === 'thinking' && 'Thinking...'}
        {state === 'speaking' && 'Speaking...'}
      </p>
      
      <TrackToggle source={Track.Source.Microphone} />
      <DisconnectButton>End</DisconnectButton>
    </div>
  );
}
```

### Assistant with Tools

```jsx theme={null}
function AssistantWithTools({ token, wsUrl }) {
  const tools = [
    {
      name: 'search',
      description: 'Search for information',
      parameters: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query'
          }
        },
        required: ['query']
      },
      timeout: 10,
      handler: async (data) => {
        const { query } = JSON.parse(data.payload).arguments.raw_arguments;
        const results = await searchAPI(query);
        return JSON.stringify({
          result: results,
          presentationInstructions: `Found ${results.length} results`
        });
      }
    }
  ];
  
  return (
    <UpliftAIRoom
      token={token}
      serverUrl={wsUrl}
      tools={tools}
    >
      <AssistantUI />
    </UpliftAIRoom>
  );
}
```

### Dynamic Tool Management

```jsx theme={null}
function DynamicToolManager() {
  const { addTool, removeTool, isConnected } = useUpliftAIRoom();
  const [activeTools, setActiveTools] = useState([]);
  
  const handleAddTool = async (toolConfig) => {
    try {
      await addTool(toolConfig);
      setActiveTools([...activeTools, toolConfig.name]);
    } catch (error) {
      console.error('Failed to add tool:', error);
    }
  };
  
  const handleRemoveTool = async (toolName) => {
    try {
      await removeTool(toolName);
      setActiveTools(activeTools.filter(name => name !== toolName));
    } catch (error) {
      console.error('Failed to remove tool:', error);
    }
  };
  
  return (
    <div>
      <h3>Active Tools: {activeTools.join(', ')}</h3>
      <button 
        onClick={() => handleAddTool(weatherTool)}
        disabled={!isConnected}
      >
        Add Weather Tool
      </button>
      <button 
        onClick={() => handleRemoveTool('weather')}
        disabled={!isConnected}
      >
        Remove Weather Tool
      </button>
    </div>
  );
}
```

## Error Handling

```jsx theme={null}
function RobustAssistant({ token, wsUrl }) {
  const [error, setError] = useState(null);
  
  return (
    <UpliftAIRoom
      token={token}
      serverUrl={wsUrl}
      onConnectionChange={(connected, agentIdentity) => {
        if (!connected && agentIdentity) {
          setError('Connection lost');
        }
      }}
    >
      {error ? (
        <ErrorView error={error} onRetry={() => setError(null)} />
      ) : (
        <AssistantUI />
      )}
    </UpliftAIRoom>
  );
}
```

## LiveKit Components

The SDK re-exports all LiveKit components for convenience:

```jsx theme={null}
import {
  // Audio/Video
  AudioTrack,
  VideoTrack,
  
  // Controls
  ControlBar,
  TrackToggle,
  DisconnectButton,
  
  // Chat
  Chat,
  ChatEntry,
  
  // Layout
  GridLayout,
  FocusLayout,
  
  // Utilities
  RoomAudioRenderer,
  ConnectionStateToast,
  
  // ... and more
} from '@upliftai/assistants-react';
```

## Performance Tips

1. **Memoize tool handlers** to prevent recreating on each render
2. **Use React.memo** for components that don't need frequent updates
3. **Batch tool operations** when adding/removing multiple tools
4. **Lazy load** tool implementations for better initial load time
