Skip to main content

Examples & Demos

This page provides complete example implementations for both JavaScript and Unity SDKs.

GitHub Example Repositories

Complete Working Examples on GitHub

We maintain ready-to-run example projects with full source code on GitHub.

JavaScript Examples

Repository: uglabs/ug-js-sdk

The JavaScript SDK repository includes working examples demonstrating:

  • Basic text conversations
  • Voice-enabled chat
  • Image generation
  • Custom utilities (classify and extract)
  • React integration examples
  • Event handling patterns

View JavaScript Examples →

Unity Examples

Repository: uglabs/ug-demos-unity

Complete Unity demo projects showcasing:

  • Interactive NPC conversations
  • Voice-controlled game mechanics
  • Avatar integration
  • Event-driven gameplay
  • UI/UX best practices for Unity

View Unity Examples →


Basic Chat Example (JavaScript)

This example demonstrates a simple text-based conversation with the UG Labs API.

Overview

In this example, you'll learn how to:

  • Connect to the WebSocket API
  • Authenticate with an API key
  • Configure the conversation
  • Send and receive text messages
  • Handle streaming responses

Using the SDK

Installation

npm install ug-js-sdk

Complete Example

import { ConversationManager } from 'ug-js-sdk';

// Initialize conversation
const conversation = new ConversationManager({
apiKey: 'your-api-key',
federatedId: 'user-123' // Optional unique user identifier
});

// Set up event listeners
conversation.on('text-event', (event) => {
console.log('Assistant:', event.text);

if (event.done) {
console.log('Response complete');
}
});

conversation.on('error', (error) => {
console.error('Error:', error);
});

// Start conversation
async function startChat() {
try {
// Connect and authenticate
await conversation.start();

// Configure the assistant
await conversation.setConfiguration({
prompt: 'You are a friendly and helpful assistant.',
temperature: 0.7
});

// Send messages
await conversation.sendText('Hello! What can you help me with?');

// You can send follow-up messages
setTimeout(async () => {
await conversation.sendText('Tell me a fun fact about space.');
}, 5000);

} catch (error) {
console.error('Failed to start conversation:', error);
}
}

startChat();

Using the WebSocket API Directly

If you prefer to use the WebSocket API directly without the SDK:

// Step 1: Get access token
const authResponse = await fetch('https://pug.stg.uglabs.app/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
api_key: 'your-api-key',
federated_id: 'user-123'
})
});

const { access_token } = await authResponse.json();

// Step 2: Connect to WebSocket
const ws = new WebSocket('wss://pug.stg.uglabs.app/interact');

ws.onopen = () => {
console.log('WebSocket connected');

// Step 3: Authenticate
ws.send(JSON.stringify({
kind: 'authenticate',
uid: crypto.randomUUID(),
access_token: access_token
}));
};

// Step 4: Handle messages
let isAuthenticated = false;
let isConfigured = false;

ws.onmessage = (event) => {
const message = JSON.parse(event.data);

if (message.kind === 'authenticated') {
console.log('Authenticated successfully');
isAuthenticated = true;

// Step 5: Set configuration
ws.send(JSON.stringify({
kind: 'set_configuration',
uid: crypto.randomUUID(),
prompt: 'You are a friendly and helpful assistant.'
}));
}

if (message.kind === 'configured') {
console.log('Configuration set');
isConfigured = true;

// Step 6: Send first message
ws.send(JSON.stringify({
kind: 'interact',
uid: crypto.randomUUID(),
text: 'Hello! What can you help me with?',
audio_output: false
}));
}

if (message.kind === 'text') {
// Step 7: Receive response
console.log('Assistant:', message.text);

if (message.done) {
console.log('Response complete');
}
}

if (message.kind === 'error') {
console.error('Error:', message.error);
}
};

ws.onerror = (error) => {
console.error('WebSocket error:', error);
};

ws.onclose = () => {
console.log('WebSocket closed');
};

React Example

Here's how to build a simple chat interface in React:

import React, { useState, useEffect, useRef } from 'react';
import { ConversationManager } from 'ug-js-sdk';

function ChatInterface() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [isConnected, setIsConnected] = useState(false);
const conversationRef = useRef(null);
const messagesEndRef = useRef(null);

useEffect(() => {
// Initialize conversation
const conversation = new ConversationManager({
apiKey: 'your-api-key'
});

conversationRef.current = conversation;

// Set up event listeners
conversation.on('text-event', (event) => {
setMessages(prev => {
const last = prev[prev.length - 1];

if (last && last.role === 'assistant' && !last.complete) {
// Append to existing assistant message
return [
...prev.slice(0, -1),
{
...last,
content: last.content + event.text,
complete: event.done
}
];
} else {
// New assistant message
return [...prev, {
role: 'assistant',
content: event.text,
complete: event.done
}];
}
});
});

// Start conversation
conversation.start().then(() => {
return conversation.setConfiguration({
prompt: 'You are a helpful assistant.'
});
}).then(() => {
setIsConnected(true);
});

// Cleanup
return () => {
conversation.stop();
};
}, []);

// Auto-scroll to bottom
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);

const handleSend = async () => {
if (!input.trim() || !isConnected) return;

// Add user message
setMessages(prev => [...prev, {
role: 'user',
content: input,
complete: true
}]);

// Send to API
await conversationRef.current.sendText(input);

// Clear input
setInput('');
};

const handleKeyPress = (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSend();
}
};

return (
<div className="chat-container">
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className={`message ${msg.role}`}>
<strong>{msg.role === 'user' ? 'You' : 'Assistant'}:</strong>
<p>{msg.content}</p>
</div>
))}
<div ref={messagesEndRef} />
</div>

<div className="input-area">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Type your message..."
disabled={!isConnected}
/>
<button onClick={handleSend} disabled={!isConnected}>
Send
</button>
</div>

{!isConnected && <div className="status">Connecting...</div>}
</div>
);
}

export default ChatInterface;

Try It Yourself

Use the Interactive API Tester to:

  1. Connect with your API key
  2. Try the "Basic Chat" example scenario
  3. Experiment with different prompts and messages

Key Takeaways

  • Always authenticate before setting configuration
  • Configuration must be set before interaction
  • Text responses are streamed in chunks
  • Use the done field to know when a response is complete
  • Handle errors appropriately

Next Steps