A React + TypeScript + Vite frontend for real-time voice conversations using the Sayna JS SDK.
┌────────────────────────────────────────────────────────────────────────────┐
│ Browser │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Connection │ │ Chat Panel │ │ Audio │ │
│ │ Panel │ │ │ │ Playback │ │
│ │ │ │ Messages │ │ │ │
│ │ [Room Name] │ │ ┌──────────┐ │ │ <audio> │ │
│ │ [Your Name] │ │ │ User: Hi │ │ │ element │ │
│ │ │ │ │ AI: Hello│ │ │ │ │
│ │ [Call] [Hang Up]│ │ └──────────┘ │ │ │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ └───────────────────────┼───────────────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ Sayna JS SDK │ │
│ │ (SaynaClient) │ │
│ └─────────┬─────────┘ │
└────────────────────────────────────┼────────────────────────────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Backend │ │ LiveKit │ │ Sayna │
│ /start │ │ Server │ │ (via server)│
│ (token) │ │ (audio) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
User clicks "Call"
│
▼
┌─────────────────────────┐
│ 1. Fetch token from │
│ backend /start │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ 2. Connect to LiveKit │
│ with token │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ 3. Publish microphone │
│ (user grants access) │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ 4. User speaks │ ──────> │ Backend VoiceAgent │
│ (mic audio sent) │ │ processes speech │
└─────────────────────────┘ └───────────┬─────────────┘
│
┌───────────────────────────────────┘
│
▼
┌─────────────────────────┐
│ 5. AI response plays │
│ through audio element│
└─────────────────────────┘
- Node.js 18+
- A running backend server (see nestjs-ai-sdk-server)
# Install dependencies
npm install
# Copy environment template
cp .env.example .env
# Configure API_ENDPOINT (see below)
# Start development server
npm run devApp runs at http://localhost:5173.
| Variable | Required | Description |
|---|---|---|
API_ENDPOINT |
Yes | Backend URL for token generation |
API_ENDPOINT=http://localhost:4000/start┌─────────────────┐ ┌─────────────────┐
│ This App │ POST /start │ NestJS Server │
│ localhost:5173 │ ───────────────> │ localhost:4000 │
│ │ <─────────────── │ │
│ │ { token, url } │ │
└─────────────────┘ └─────────────────┘
Steps:
-
Start the backend first:
cd ../nestjs-ai-sdk-server npm run start:dev -
Configure this app's
.env:API_ENDPOINT=http://localhost:4000/start
-
Start this app:
npm run dev
-
Open http://localhost:5173 in your browser
┌─────────────────────────────────────────────────────────────┐
│ Voice Chat Features │
├─────────────────────────────────────────────────────────────┤
│ │
│ [x] Real-time voice communication via LiveKit │
│ [x] Live transcription display (interim + final) │
│ [x] AI response streaming with typing indicator │
│ [x] Audio playback with autoplay handling │
│ [x] Microphone toggle (mute/unmute) │
│ [x] Connection status indicators │
│ [x] Chat message history │
│ [x] Error handling with retry options │
│ │
└─────────────────────────────────────────────────────────────┘
src/
├── App.tsx # Main application
├── lib/
│ ├── saynaClient.ts # SDK wrapper with token handling
│ └── types.ts # TypeScript interfaces
└── components/
├── connection-panel.tsx # Room config & controls
└── chat-panel.tsx # Message list & input
┌─────────────────────────────────────────────────────────────────────────┐
│ Message Flow │
│ │
│ User speaks STT transcript AI response TTS audio │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ [Microphone] ──> [Data Channel] ──> [Data Channel] ──> [Audio Element]│
│ │ (user message) (AI message) │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌────────────────────────────┐ │
│ │ │ Chat Panel │ │
│ │ │ │ │
│ │ │ User: "Hello" │ │
│ │ │ AI: "Hi! How can I help?" │ │
│ │ └────────────────────────────┘ │
│ │ │
│ └──────────────────────────────────────────────────────────────> │
│ LiveKit audio stream │
└─────────────────────────────────────────────────────────────────────────┘
- NestJS AI Server - Backend for this UI
- Sayna JS SDK - Client SDK used here
- Sayna - Voice processing platform