Quickstart Guide
Get up and running with UG Labs SDK in minutes. This guide will walk you through creating a simple conversational AI application.
Prerequisites
Install the SDK
npm install ug-js-sdk
Or using yarn:
yarn add ug-js-sdk
Get Your API Key
Get your API key from the UG Labs Console
Basic Example
Here's a simple example that creates a conversation and sends a text message:
import { ConversationManager, ConversationConfig } from 'ug-js-sdk';
// Initialize the conversation manager
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123',
prompt: 'You are a helpful assistant.',
hooks: {
onStateChange: (state) => console.log('State:', state),
onTextMessage: (event) => console.log('Assistant:', event.text),
onError: (error) => console.error('Error:', error.message),
},
};
const conversation = new ConversationManager(config);
// Start the conversation
async function start() {
try {
// Initialize connection (establishes WebSocket, requests mic if needed)
await conversation.initialize();
// Send a text message
await conversation.sendText('Hello! How are you?');
} catch (error) {
console.error('Failed to start conversation:', error);
}
}
start();
Step-by-Step Explanation
1. Import and Configure
import { ConversationManager, ConversationConfig } from 'ug-js-sdk';
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123', // Unique user ID for conversation continuity
prompt: 'You are a friendly assistant.',
hooks: {
onTextMessage: (event) => console.log('Assistant:', event.text),
},
};
The ConversationManager is the main class that handles all interactions with the UG Labs API. Configuration is passed directly to the constructor.
2. Set Up Event Hooks
hooks: {
onStateChange: (state) => console.log('State:', state),
onTextMessage: (event) => console.log('Assistant:', event.text),
onDataMessage: (event) => console.log('Data:', event.data),
onError: (error) => console.error('Error:', error.message),
}
Event hooks receive real-time updates from the conversation:
onTextMessage: Streaming text chunks from the assistantonDataMessage: Structured data from utilities (classifiers, extractors)onStateChange: Conversation state transitionsonError: Error notifications
3. Initialize and Interact
const conversation = new ConversationManager(config);
// Connect to the API
await conversation.initialize();
// Send text messages
await conversation.sendText('Hello! How are you?');
First, create the manager with your config, then call initialize() to establish the WebSocket connection.
Adding Voice Interaction
To enable voice input and output:
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123',
prompt: 'You are a helpful voice assistant.',
// Enable audio capabilities
inputCapabilities: { audio: true, text: true },
capabilities: { audio: true, subtitles: true },
// Optional: Configure voice
voiceProfile: {
provider: 'elevenlabs',
voice_id: 'your-voice-id',
speed: 1.0,
},
hooks: {
onStateChange: (state) => console.log('State:', state),
onTextMessage: (event) => console.log('Assistant:', event.text),
},
};
const conversation = new ConversationManager(config);
await conversation.initialize();
// Start listening for voice input (requires user gesture in browser)
await conversation.startListening();
// Later, stop listening
await conversation.stopListening();
Using Utilities
Add structured outputs with classification or extraction utilities:
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123',
prompt: 'You are a sentiment analysis assistant.',
// Step 1: Define utilities
utilities: {
sentiment: {
type: 'classify',
classification_question: 'What is the sentiment: {{user_input}}',
answers: ['positive', 'negative', 'neutral'],
},
},
// Step 2: Activate utilities (REQUIRED!)
onOutputUtilities: ['sentiment'],
hooks: {
// Step 3: Handle utility results
onDataMessage: (event) => {
console.log('Sentiment:', event.data.sentiment);
},
},
};
Important: Utilities must be both defined in utilities AND activated in one of:
onOutputUtilities- Run after assistant response (recommended, lowest latency)onInputUtilities- Run before prompt (blocking, adds latency)onInputNonBlockingUtilities- Run in parallel with LLM
Complete React Example
Here's a complete example using React:
import React, { useEffect, useState, useRef } from 'react';
import { ConversationManager, ConversationConfig, ConversationState } from 'ug-js-sdk';
function ChatApp() {
const [messages, setMessages] = useState<{ role: string; content: string }[]>([]);
const [input, setInput] = useState('');
const [state, setState] = useState<ConversationState>('uninitialized');
const managerRef = useRef<ConversationManager | null>(null);
useEffect(() => {
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123',
prompt: 'You are a helpful assistant.',
// Text-only mode
inputCapabilities: { audio: false, text: true },
capabilities: { audio: false },
hooks: {
onStateChange: (newState) => setState(newState),
onTextMessage: (event) => {
setMessages(prev => {
// Append to last assistant message or create new one
const last = prev[prev.length - 1];
if (last?.role === 'assistant') {
return [
...prev.slice(0, -1),
{ role: 'assistant', content: last.content + event.text }
];
}
return [...prev, { role: 'assistant', content: event.text }];
});
},
onError: (error) => console.error('Error:', error.message),
},
};
const manager = new ConversationManager(config);
managerRef.current = manager;
manager.initialize();
// Cleanup on unmount
return () => {
manager.dispose();
};
}, []);
const sendMessage = async () => {
if (!input.trim() || !managerRef.current) return;
setMessages(prev => [...prev, { role: 'user', content: input }]);
await managerRef.current.sendText(input);
setInput('');
};
return (
<div>
<div>Status: {state}</div>
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className={msg.role}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
</div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
disabled={state !== 'idle' && state !== 'listening'}
/>
<button onClick={sendMessage} disabled={state !== 'idle' && state !== 'listening'}>
Send
</button>
</div>
);
}
export default ChatApp;
Using configRef (Load Config from Backend)
Instead of defining prompt and utilities in code, you can load them from a deployed configuration:
const config: ConversationConfig = {
apiUrl: 'wss://pug.stg.uglabs.app',
apiKey: 'your-api-key',
federatedId: 'user-123',
// Load configuration from backend
// Created via console.stg.uglabs.app/playground → Deploy
configRef: 'char_abc123_v2',
hooks: {
onTextMessage: (event) => console.log(event.text),
},
};
When configRef is set, prompt, utilities, and voiceProfile are loaded from the backend.
Next Steps
- Configuration Reference - All configuration options
- WASM Setup Guide - Voice input setup for different bundlers
- Explore the WebSocket Protocol
- Learn about Utilities
- See More Examples
Troubleshooting
Connection Issues
If you're having trouble connecting:
- Verify your API key is correct
- Check your network connection
- Ensure you're using HTTPS for voice features (WebSocket + mic require secure context)
- Check browser console for detailed error messages
Audio Not Working
If audio input/output isn't working:
- Grant microphone permissions when prompted
- Ensure your browser supports Web Audio API and MediaRecorder
- Try using headphones to avoid echo
- Check that
inputCapabilities.audiois set totrue - Call
startListening()after a user gesture (button click)
Utilities Not Returning Data
If utilities don't produce results:
- Verify utility is defined in
utilitiesobject - Verify utility name is in
onOutputUtilitiesarray (most common issue!) - Implement
onDataMessagehook to receive results
WASM/ONNX Issues
For issues with voice activity detection (VAD) or ONNX model loading, see the WASM Setup Troubleshooting guide.