ttp-agent-sdk
Version:
Comprehensive Voice Agent SDK for web integration with real-time audio, WebSocket communication, and React components
236 lines (201 loc) • 7.34 kB
HTML
<!--
============================================
FILE: examples/test.html
Test page for the widget
============================================
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Voice Agent Widget - Test Page</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
background: #F9FAFB;
}
.container {
background: white;
padding: 30px;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
h1 {
color: #111827;
margin-top: 0;
}
.info {
background: #EFF6FF;
border-left: 4px solid #3B82F6;
padding: 16px;
margin: 20px 0;
border-radius: 4px;
}
.status {
margin: 20px 0;
padding: 12px;
background: #F3F4F6;
border-radius: 6px;
font-family: monospace;
font-size: 14px;
}
.status.success {
background: #D1FAE5;
color: #065F46;
}
.status.error {
background: #FEE2E2;
color: #991B1B;
}
button {
background: #4F46E5;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
margin: 10px 10px 10px 0;
}
button:hover {
background: #4338CA;
}
</style>
</head>
<body>
<div class="container">
<h1>🎤 Voice Agent Widget - Test Page</h1>
<div class="info">
<strong>📝 Testing Instructions:</strong>
<ol style="margin: 10px 0 0 20px; line-height: 1.8;">
<li><strong>No backend required!</strong> This demo uses a mock session URL</li>
<li>Look for the floating voice button in the bottom-right corner</li>
<li>Click the button to open the widget</li>
<li>Click the microphone to start (will request mic permission)</li>
<li>Widget will connect to production backend at speech.talktopc.com</li>
<li>Check the status updates below</li>
</ol>
</div>
<h2>Widget Status:</h2>
<div id="status" class="status">
Waiting for widget to load...
</div>
<h2>Console Log:</h2>
<div id="log" style="background: #1F2937; color: #F9FAFB; padding: 16px; border-radius: 6px; font-family: monospace; font-size: 12px; max-height: 300px; overflow-y: auto;">
Console messages will appear here...
</div>
<h2>Manual Tests:</h2>
<button onclick="testConnection()">Test Backend Connection</button>
<button onclick="testMicrophone()">Test Microphone Access</button>
</div>
<!-- Load the widget -->
<script src="../agent-widget.js" onload="console.log('SDK script loaded successfully')" onerror="console.error('Failed to load SDK script')"></script>
<script>
// Override console.log to show in page
const originalLog = console.log;
const originalError = console.error;
const logDiv = document.getElementById('log');
function addLog(message, type = 'log') {
const time = new Date().toLocaleTimeString();
const color = type === 'error' ? '#EF4444' : '#10B981';
logDiv.innerHTML += `<div style="color: ${color};">[${time}] ${message}</div>`;
logDiv.scrollTop = logDiv.scrollHeight;
}
console.log = (...args) => {
originalLog(...args);
addLog(args.join(' '));
};
console.error = (...args) => {
originalError(...args);
addLog(args.join(' '), 'error');
};
// Update status display
function updateStatus(message, type = 'info') {
const statusDiv = document.getElementById('status');
statusDiv.textContent = message;
statusDiv.className = 'status ' + type;
}
// Initialize the widget
try {
console.log('Initializing widget...');
console.log('TTPAgentSDK available:', typeof TTPAgentSDK);
console.log('TTPAgentSDK.AgentWidget available:', typeof TTPAgentSDK?.AgentWidget);
if (typeof TTPAgentSDK === 'undefined') {
throw new Error('TTPAgentSDK is not defined. Check if the script loaded correctly.');
}
if (typeof TTPAgentSDK.AgentWidget === 'undefined') {
throw new Error('TTPAgentSDK.AgentWidget is not defined. Check the SDK build.');
}
// Create a new AgentWidget instance
const widget = new TTPAgentSDK.AgentWidget({
agentId: 'agent_test_123',
// Mock backend for local testing (no real backend needed!)
getSessionUrl: async ({ agentId, variables }) => {
console.log('Requesting session URL for agent:', agentId);
console.log('Variables:', variables);
updateStatus('Creating mock session URL...', 'info');
try {
// Simulate a small delay like a real backend
await new Promise(resolve => setTimeout(resolve, 500));
// Create a mock WebSocket URL for testing
const mockSignedUrl = `wss://speech.talktopc.com/ws/conv?agentId=${agentId}&appId=test_app_123`;
console.log('Generated mock session URL:', mockSignedUrl);
updateStatus('Mock session URL created ✓', 'success');
return mockSignedUrl;
} catch (error) {
console.error('Failed to create mock session URL:', error);
updateStatus('Failed to create mock session URL ✗', 'error');
throw error;
}
},
// Pass some test variables
variables: {
testMode: true,
userName: 'Test User',
page: 'test.html'
},
// Customize appearance
primaryColor: '#10B981',
position: 'bottom-right'
});
console.log('Widget initialized successfully!');
updateStatus('Widget loaded and ready ✓', 'success');
} catch (error) {
console.error('Failed to initialize widget:', error);
updateStatus('Widget failed to load ✗', 'error');
}
// Manual test functions
async function testConnection() {
console.log('Testing backend connection...');
try {
const response = await fetch('http://localhost:3000/health');
if (response.ok) {
console.log('Backend is reachable ✓');
alert('Backend connection OK!');
} else {
throw new Error('Backend returned error');
}
} catch (error) {
console.error('Cannot reach backend:', error);
alert('Widget initialization FAILED! Check console for details.');
}
}
async function testMicrophone() {
console.log('Testing microphone access...');
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
console.log('Microphone access granted ✓');
stream.getTracks().forEach(track => track.stop());
alert('Microphone access OK!');
} catch (error) {
console.error('Microphone access denied:', error);
alert('Microphone access DENIED! Please allow microphone in browser settings.');
}
}
</script>
</body>
</html>