UNPKG

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
<!-- ============================================ FILE: examples/test.html Test page for the widget ============================================ --> <!DOCTYPE html> <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>