Skip to main content

Web Client Overview

The web client (@llmrtc/llmrtc-web-client) is a browser library that handles WebRTC signaling, audio/video capture, and event emission for voice AI applications.


Architecture

The web client manages the browser-side connection:


Core Features

Connection Management

  • WebSocket signaling with automatic reconnection
  • WebRTC peer connection setup
  • ICE candidate handling
  • Session persistence across reconnects

Audio Handling

  • Microphone capture via getUserMedia
  • TTS playback through WebRTC tracks
  • Speech state events (start/end)
  • Barge-in support

Video & Vision

  • Camera capture with frame extraction
  • Screen sharing support
  • Automatic attachment queuing
  • FPS control for bandwidth management

Event System

  • Rich event API for UI integration
  • Transcript and LLM response events
  • Tool call notifications
  • Connection state changes

Basic Usage

import { LLMRTCWebClient } from '@llmrtc/llmrtc-web-client';

// Create client
const client = new LLMRTCWebClient({
signallingUrl: 'wss://your-server.com'
});

// Set up event handlers
client.on('stateChange', (state) => {
console.log('Connection state:', state);
});

client.on('transcript', (text) => {
console.log('User said:', text);
});

client.on('llmChunk', (chunk) => {
process.stdout.write(chunk);
});

client.on('ttsStart', () => {
console.log('Assistant speaking...');
});

client.on('ttsComplete', () => {
console.log('Assistant finished.');
});

// Start connection
await client.start();

// Share microphone
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const controller = client.shareAudio(stream);

// Later: cleanup
controller.stop();
await client.close();

Connection States

The client moves through defined states:

StateDescription
disconnectedInitial state, not connected
connectingEstablishing WebSocket and WebRTC
connectedFully connected and operational
reconnectingConnection lost, attempting recovery
failedConnection failed, no more retries
closedExplicitly closed by application

Events

The client emits events for UI integration:

Connection Events

EventPayloadDescription
stateChangeConnectionStateConnection state changed
reconnecting{ attempt, maxAttempts }Reconnection attempt
errorClientErrorError occurred

Speech Events

EventPayloadDescription
speechStart-User started speaking
speechEnd-User stopped speaking
transcriptstringFinal transcription

Response Events

EventPayloadDescription
llmstringComplete LLM response
llmChunkstringStreaming LLM chunk
ttsStart-TTS audio started
ttsComplete-TTS audio finished
ttsCancelled-TTS interrupted (barge-in)
ttsTrackMediaStreamWebRTC audio track

Playbook Events

EventPayloadDescription
stageChange{ from, to, reason }Stage transition
toolCallStart{ name, callId, arguments }Tool execution started
toolCallEnd{ callId, result, error, durationMs }Tool execution completed

Constructor Options

interface WebClientConfig {
// Required
signallingUrl: string; // WebSocket server URL

// WebRTC
iceServers?: RTCIceServer[]; // Custom ICE servers (optional)
useWebRTC?: boolean; // Force WebRTC transport

// Reconnection
reconnection?: {
enabled?: boolean; // Enable auto-reconnect (default: true)
maxRetries?: number; // Max retry attempts (default: 5)
baseDelayMs?: number; // Initial delay (default: 1000)
maxDelayMs?: number; // Max delay (default: 30000)
jitterFactor?: number; // Jitter (0-1) (default: 0.3)
};
}
Audio Playback

The client does not auto-play TTS audio. You must handle the ttsTrack or tts event and connect the audio to an <audio> element yourself. See Audio Handling for details.


Methods

Connection

MethodDescription
start()Establish connection to server
close()Close connection and cleanup

Audio

MethodDescription
shareAudio(stream)Share microphone audio, returns controller

Video & Vision

MethodDescription
shareVideo(stream, intervalMs?)Share camera with frame capture (intervalMs between frames)
shareScreen(stream, intervalMs?)Share screen with frame capture (intervalMs between frames)
sendAttachments()Send queued attachments to server

Framework Integration

React

import { useEffect, useState, useRef } from 'react';
import { LLMRTCWebClient } from '@llmrtc/llmrtc-web-client';

function useVoiceClient(url: string) {
const clientRef = useRef<LLMRTCWebClient | null>(null);
const [state, setState] = useState('disconnected');
const [transcript, setTranscript] = useState('');

useEffect(() => {
const client = new LLMRTCWebClient({ signallingUrl: url });
clientRef.current = client;

client.on('stateChange', setState);
client.on('transcript', setTranscript);

return () => {
client.close();
};
}, [url]);

return { client: clientRef.current, state, transcript };
}

Vue

import { ref, onMounted, onUnmounted } from 'vue';
import { LLMRTCWebClient } from '@llmrtc/llmrtc-web-client';

export function useVoiceClient(url: string) {
const client = ref<LLMRTCWebClient | null>(null);
const state = ref('disconnected');

onMounted(() => {
client.value = new LLMRTCWebClient({ signallingUrl: url });
client.value.on('stateChange', (s) => state.value = s);
});

onUnmounted(() => {
client.value?.close();
});

return { client, state };
}

Browser Requirements

BrowserMinimum Version
Chrome74+
Firefox78+
Safari14.1+
Edge79+

Required APIs:

  • WebSocket
  • WebRTC (RTCPeerConnection)
  • getUserMedia
  • MediaStream