@wix/legends-platform-sdk
v1.23.0
Published
React SDK for building AI-powered voice, video, and text chat experiences on the Legends Platform.
Downloads
386
Maintainers
Keywords
Readme
@wix/legends-platform-sdk
React SDK for building AI-powered voice, video, and text chat experiences on the Legends Platform.
Installation
npm install @wix/legends-platform-sdk
# or
yarn add @wix/legends-platform-sdkEntry Points
The SDK exposes two entry points:
| Entry point | What's inside |
|---|---|
| @wix/legends-platform-sdk | Types and server-safe hooks (useTextChat, useConversationEvents, useMicrophone, useSpeaker, useCamera, etc.) — no LiveKit dependency |
| @wix/legends-platform-sdk/livekit/sdk | Everything above + LegendsPlatform, useConversation, useScreenShare, useParticipantTrack, useSpeechActivityDetector, useAudioLevel |
Use the main entry when you only need types or hooks without a LiveKit room (e.g. server-side code or Jest tests). Use livekit/sdk for React components and live conversation hooks.
Quick Start
Get a namespace API key from the Legends Platform team, then store it in .env.local:
LEGENDS_API_KEY=lp_your_raw_api_key
LEGENDS_CHAT_ID=your-chat-idWrap your app with LegendsPlatform. External apps use HEADLESS as the namespace value:
import { LegendsPlatform, useConversation, useMicrophone } from '@wix/legends-platform-sdk/livekit/sdk';
function VoiceButton() {
const { status, join, leave } = useConversation({ type: 'audio' });
const { enabled, setEnabled } = useMicrophone();
return (
<div>
<p>Status: {status}</p>
{status === 'pending' && <button onClick={join}>Start</button>}
{status === 'created' && (
<>
<button onClick={() => leave()}>End</button>
<button onClick={() => setEnabled(!enabled)}>
Mic: {enabled ? 'ON' : 'OFF'}
</button>
</>
)}
</div>
);
}
export default function App() {
return (
<LegendsPlatform
chatId="your-chat-id"
namespace="HEADLESS"
apiKey="lp_your_api_key"
>
<VoiceButton />
</LegendsPlatform>
);
}API
<LegendsPlatform />
The root context provider. Must wrap all SDK hooks and components.
| Prop | Type | Description |
|------|------|-------------|
| chatId | string | Required. The chat instance ID |
| namespace | string | Required. Your namespace |
| apiKey | string | Raw namespace API key — pass lp_... as-is, the SDK sends it as Authorization: Api-Key <token> |
| personaChatService | IPersonaChatService | Custom service for advanced use cases (see below) |
| tools | ToolsRegistry | Optional client-side tool handlers |
| queryClient | QueryClient | Optional TanStack Query client |
| children | ReactNode | Required |
Either apiKey or personaChatService must be provided.
Hooks
useConversation(options) — livekit/sdk
Manages a voice or video conversation session.
const { status, join, leave } = useConversation({
type: 'audio' | 'video', // default: 'audio'
autoJoin: false, // default: false
});| Return | Type | Description |
|--------|------|-------------|
| status | 'pending' \| 'created' \| 'destroying' \| 'destroyed' \| 'exceeded' \| 'inactivity-timeout' \| 'voice-not-found' \| 'initialization-error' \| 'error' | Current conversation state |
| join() | () => void | Start the conversation |
| leave() | (destroy?: boolean) => Promise<void> | End the conversation |
useMicrophone()
const { enabled, setEnabled } = useMicrophone();useCamera()
const { enabled, setEnabled } = useCamera();useSpeaker()
const { volume, setVolume } = useSpeaker();useTextChat()
Manages text-based chat messages.
const { messages, status, send, fetchNext } = useTextChat();
await send({ message: 'Hello' });useTextChatStream(options)
Streaming counterpart to useTextChat. Sends messages over SSE and drips the assistant reply into streamingText at a steady rate via requestAnimationFrame.
const { messages, status, send } = useTextChatStream({
onError: (err) => console.error(err),
revealMsPerChar: 16, // ms per character, default 16 (~62 chars/s)
});
// messages[n].streamStatus === 'streaming' while the reply is in-flight
const result = await send({ message: 'Hello' });
// result: { ok: boolean, producedContent: boolean, aborted: boolean }useConversationStatus()
const status = useConversationStatus();
// 'pending' | 'created' | 'destroying' | 'destroyed' | 'exceeded'
// | 'inactivity-timeout' | 'voice-not-found' | 'initialization-error' | 'error'useConversationTimer()
const { elapsed, remaining } = useConversationTimer();useTools()
Observe client-side tool calls executed by the SDK. Register tool handlers by passing a tools registry to LegendsPlatform.
import { LegendsPlatform, useTools, type ToolsRegistry } from '@wix/legends-platform-sdk/livekit/sdk';
const tools: ToolsRegistry = {
get_weather: async ({ city }) => {
const data = await fetchWeather(city as string);
return { temperature: data.temp };
},
};
function ToolLog() {
const calls = useTools(); // returns ToolCallSnapshot[]
return <pre>{JSON.stringify(calls, null, 2)}</pre>;
}
<LegendsPlatform
chatId="your-chat-id"
namespace="HEADLESS"
apiKey="lp_your_api_key"
tools={tools}
>
<ToolLog />
</LegendsPlatform>useSpeechActivityDetector(options)
Acoustic speech onset/offset detector driven by AudioWorkletNode. Useful for measuring end-to-end latency or building custom VAD UI.
useSpeechActivityDetector({
source: 'user',
thresholdRms: 0.015,
hangoverMs: 300,
onSpeechStart: (timestampMs) => console.log('started', timestampMs),
onSpeechEnd: (timestampMs) => console.log('ended', timestampMs),
});Advanced: Custom Service
For advanced integration, inject a custom IPersonaChatService instead of apiKey. Your implementation owns authentication and must forward valid credentials on every request.
import { LegendsPlatform } from '@wix/legends-platform-sdk/livekit/sdk';
import type { IPersonaChatService } from '@wix/legends-platform-sdk';
const myService: IPersonaChatService = {
async createVoiceConversation(params) { /* ... */ },
async createInteractiveConversation(params) { /* ... */ },
async endInteractiveConversation(params) { /* ... */ },
async sendChatMessage(params) { /* ... */ },
async queryChatMessages(params) { /* ... */ },
};
<LegendsPlatform
chatId="your-chat-id"
namespace="your-namespace"
personaChatService={myService}
>
...
</LegendsPlatform>Supported Conversation Vendors
- LiveKit — voice and video
- Daily — video
- Hume — voice with emotional intelligence
- ElevenLabs — voice
The vendor is determined automatically based on the conversation configuration.
