ttp-agent-sdk 2.1.7 → 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-widget.js +1 -1
- package/dist/agent-widget.js.map +1 -1
- package/dist/audio-processor.js +1 -0
- package/{examples/test.html → dist/examples/test-agent-app.html} +109 -45
- package/dist/examples/test-signed-link.html +451 -0
- package/{dist/examples/test.html → examples/test-agent-app.html} +109 -45
- package/examples/test-signed-link.html +451 -0
- package/package.json +1 -1
- package/dist/examples/enhanced-widget-examples.html +0 -471
- package/dist/examples/multi-platform-examples.html +0 -1119
- package/dist/examples/react-example.html +0 -774
- package/dist/examples/react-example.jsx +0 -307
- package/dist/examples/vanilla-example.html +0 -464
- package/examples/enhanced-widget-examples.html +0 -471
- package/examples/multi-platform-examples.html +0 -1119
- package/examples/react-example.html +0 -774
- package/examples/react-example.jsx +0 -307
- package/examples/vanilla-example.html +0 -464
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Voice Agent Widget - Signed Link Test</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
10
|
+
max-width: 800px;
|
|
11
|
+
margin: 40px auto;
|
|
12
|
+
padding: 20px;
|
|
13
|
+
background: #F9FAFB;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.container {
|
|
17
|
+
background: white;
|
|
18
|
+
padding: 30px;
|
|
19
|
+
border-radius: 12px;
|
|
20
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
h1 {
|
|
24
|
+
color: #111827;
|
|
25
|
+
margin-top: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.info {
|
|
29
|
+
background: #EFF6FF;
|
|
30
|
+
border-left: 4px solid #3B82F6;
|
|
31
|
+
padding: 16px;
|
|
32
|
+
margin: 20px 0;
|
|
33
|
+
border-radius: 4px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.config-info {
|
|
37
|
+
background: #FEF3C7;
|
|
38
|
+
border-left: 4px solid #F59E0B;
|
|
39
|
+
padding: 16px;
|
|
40
|
+
margin: 20px 0;
|
|
41
|
+
border-radius: 4px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.status {
|
|
45
|
+
margin: 20px 0;
|
|
46
|
+
padding: 12px;
|
|
47
|
+
background: #F3F4F6;
|
|
48
|
+
border-radius: 6px;
|
|
49
|
+
font-family: monospace;
|
|
50
|
+
font-size: 14px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.status.success {
|
|
54
|
+
background: #D1FAE5;
|
|
55
|
+
color: #065F46;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.status.error {
|
|
59
|
+
background: #FEE2E2;
|
|
60
|
+
color: #991B1B;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
button {
|
|
64
|
+
background: #4F46E5;
|
|
65
|
+
color: white;
|
|
66
|
+
border: none;
|
|
67
|
+
padding: 12px 24px;
|
|
68
|
+
border-radius: 6px;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
font-size: 16px;
|
|
71
|
+
margin: 10px 10px 10px 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
button:hover {
|
|
75
|
+
background: #4338CA;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.code-block {
|
|
79
|
+
background: #1F2937;
|
|
80
|
+
color: #F9FAFB;
|
|
81
|
+
padding: 16px;
|
|
82
|
+
border-radius: 6px;
|
|
83
|
+
font-family: monospace;
|
|
84
|
+
font-size: 12px;
|
|
85
|
+
overflow-x: auto;
|
|
86
|
+
margin: 20px 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.api-info {
|
|
90
|
+
background: #F0FDF4;
|
|
91
|
+
border-left: 4px solid #10B981;
|
|
92
|
+
padding: 16px;
|
|
93
|
+
margin: 20px 0;
|
|
94
|
+
border-radius: 4px;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
97
|
+
</head>
|
|
98
|
+
<body>
|
|
99
|
+
<div class="container">
|
|
100
|
+
<h1>🎤 Voice Agent Widget - Signed Link Test</h1>
|
|
101
|
+
|
|
102
|
+
<div class="config-info">
|
|
103
|
+
<strong>📝 Configuration:</strong>
|
|
104
|
+
<ul style="margin: 10px 0 0 20px; line-height: 1.8;">
|
|
105
|
+
<li><strong>Agent ID:</strong> agent_87c4a55a1</li>
|
|
106
|
+
<li><strong>App ID:</strong> app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC</li>
|
|
107
|
+
<li><strong>Method:</strong> Signed link via backend API</li>
|
|
108
|
+
</ul>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div class="api-info">
|
|
112
|
+
<strong>🔗 Backend API:</strong>
|
|
113
|
+
<ul style="margin: 10px 0 0 20px; line-height: 1.8;">
|
|
114
|
+
<li><strong>Endpoint:</strong> https://backend.talktopc.com/api/public/agents/signed-url</li>
|
|
115
|
+
<li><strong>Method:</strong> POST</li>
|
|
116
|
+
<li><strong>Purpose:</strong> Generate signed WebSocket URL for secure connection</li>
|
|
117
|
+
</ul>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<div class="info">
|
|
121
|
+
<strong>📝 Testing Instructions:</strong>
|
|
122
|
+
<ol style="margin: 10px 0 0 20px; line-height: 1.8;">
|
|
123
|
+
<li>Look for the floating voice button in the bottom-right corner</li>
|
|
124
|
+
<li>Click the button to open the widget</li>
|
|
125
|
+
<li>Widget will request signed URL from backend API</li>
|
|
126
|
+
<li>Click the microphone to start (will request mic permission)</li>
|
|
127
|
+
<li>Widget will connect using the signed WebSocket URL</li>
|
|
128
|
+
<li>Check the status updates below</li>
|
|
129
|
+
</ol>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<h2>Widget Status:</h2>
|
|
133
|
+
<div id="status" class="status">
|
|
134
|
+
Waiting for widget to load...
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<h2>Console Log:</h2>
|
|
138
|
+
<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;">
|
|
139
|
+
Console messages will appear here...
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<h2>Implementation Code:</h2>
|
|
143
|
+
<div class="code-block">
|
|
144
|
+
const widget = new TTPAgentSDK.AgentWidget({
|
|
145
|
+
agentId: 'agent_87c4a55a1',
|
|
146
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
147
|
+
|
|
148
|
+
// Signed link via backend API
|
|
149
|
+
getSessionUrl: async ({ agentId, appId, variables }) => {
|
|
150
|
+
const response = await fetch('https://backend.talktopc.com/api/public/agents/signed-url', {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: {
|
|
153
|
+
'Content-Type': 'application/json',
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
agentId: agentId,
|
|
157
|
+
appId: appId,
|
|
158
|
+
variables: variables
|
|
159
|
+
})
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
throw new Error(`Backend API error: ${response.status}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const data = await response.json();
|
|
167
|
+
return data.signedUrl || data.url || data.websocketUrl || data.sessionUrl;
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
variables: {
|
|
171
|
+
testMode: true,
|
|
172
|
+
userName: 'Test User',
|
|
173
|
+
page: 'test-signed-link.html'
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
primaryColor: '#F59E0B',
|
|
177
|
+
position: 'bottom-right'
|
|
178
|
+
});
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<h2>Manual Tests:</h2>
|
|
182
|
+
<button onclick="testMicButton()">Test Mic Button Click</button>
|
|
183
|
+
<button onclick="testToggleVoice()">Test ToggleVoice Method</button>
|
|
184
|
+
<button onclick="checkWidgetState()">Check Widget State</button>
|
|
185
|
+
<button onclick="testMicrophone()">Test Microphone Access</button>
|
|
186
|
+
<button onclick="testBackendAPI()">Test Backend API</button>
|
|
187
|
+
<button onclick="testSignedUrlGeneration()">Test Signed URL Generation</button>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<!-- Load the widget -->
|
|
191
|
+
<script src="../dist/agent-widget.js" onload="console.log('SDK script loaded successfully')" onerror="console.error('Failed to load SDK script')"></script>
|
|
192
|
+
|
|
193
|
+
<script>
|
|
194
|
+
// Override console.log to show in page
|
|
195
|
+
const originalLog = console.log;
|
|
196
|
+
const originalError = console.error;
|
|
197
|
+
const logDiv = document.getElementById('log');
|
|
198
|
+
|
|
199
|
+
function addLog(message, type = 'log') {
|
|
200
|
+
const time = new Date().toLocaleTimeString();
|
|
201
|
+
const color = type === 'error' ? '#EF4444' : '#10B981';
|
|
202
|
+
logDiv.innerHTML += `<div style="color: ${color};">[${time}] ${message}</div>`;
|
|
203
|
+
logDiv.scrollTop = logDiv.scrollHeight;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
console.log = (...args) => {
|
|
207
|
+
originalLog(...args);
|
|
208
|
+
addLog(args.join(' '));
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
console.error = (...args) => {
|
|
212
|
+
originalError(...args);
|
|
213
|
+
addLog(args.join(' '), 'error');
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// Update status display
|
|
217
|
+
function updateStatus(message, type = 'info') {
|
|
218
|
+
const statusDiv = document.getElementById('status');
|
|
219
|
+
statusDiv.textContent = message;
|
|
220
|
+
statusDiv.className = 'status ' + type;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Initialize the widget
|
|
224
|
+
try {
|
|
225
|
+
console.log('Initializing widget with signed link...');
|
|
226
|
+
console.log('TTPAgentSDK available:', typeof TTPAgentSDK);
|
|
227
|
+
console.log('TTPAgentSDK.AgentWidget available:', typeof TTPAgentSDK?.AgentWidget);
|
|
228
|
+
|
|
229
|
+
if (typeof TTPAgentSDK === 'undefined') {
|
|
230
|
+
throw new Error('TTPAgentSDK is not defined. Check if the script loaded correctly.');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (typeof TTPAgentSDK.AgentWidget === 'undefined') {
|
|
234
|
+
throw new Error('TTPAgentSDK.AgentWidget is not defined. Check the SDK build.');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Create a new AgentWidget instance with signed link
|
|
238
|
+
const widget = new TTPAgentSDK.AgentWidget({
|
|
239
|
+
agentId: 'agent_87c4a55a1',
|
|
240
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
241
|
+
|
|
242
|
+
// Signed link via backend API
|
|
243
|
+
getSessionUrl: async ({ agentId, appId, variables }) => {
|
|
244
|
+
console.log('Requesting signed URL from backend API...');
|
|
245
|
+
console.log('Agent ID:', agentId);
|
|
246
|
+
console.log('App ID:', appId);
|
|
247
|
+
console.log('Variables:', variables);
|
|
248
|
+
|
|
249
|
+
updateStatus('Requesting signed URL from backend...', 'info');
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
const response = await fetch('https://backend.talktopc.com/api/public/agents/signed-url', {
|
|
253
|
+
method: 'POST',
|
|
254
|
+
headers: {
|
|
255
|
+
'Content-Type': 'application/json',
|
|
256
|
+
},
|
|
257
|
+
body: JSON.stringify({
|
|
258
|
+
agentId: agentId,
|
|
259
|
+
appId: appId,
|
|
260
|
+
variables: variables
|
|
261
|
+
})
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
console.log('Backend API response status:', response.status);
|
|
265
|
+
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
const errorText = await response.text();
|
|
268
|
+
throw new Error(`Backend API error: ${response.status} - ${errorText}`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const data = await response.json();
|
|
272
|
+
console.log('Backend API response data:', data);
|
|
273
|
+
|
|
274
|
+
// Handle different possible response formats
|
|
275
|
+
const signedUrl = data.signedUrl || data.url || data.websocketUrl || data.sessionUrl;
|
|
276
|
+
|
|
277
|
+
if (!signedUrl) {
|
|
278
|
+
throw new Error('No signed URL found in API response');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log('Generated signed URL:', signedUrl);
|
|
282
|
+
updateStatus('Signed URL received from backend ✓', 'success');
|
|
283
|
+
|
|
284
|
+
return signedUrl;
|
|
285
|
+
} catch (error) {
|
|
286
|
+
console.error('Failed to get signed URL from backend:', error);
|
|
287
|
+
updateStatus('Failed to get signed URL from backend ✗', 'error');
|
|
288
|
+
|
|
289
|
+
// Fallback to direct connection if backend fails
|
|
290
|
+
console.log('Falling back to direct connection...');
|
|
291
|
+
const fallbackUrl = `wss://speech.talktopc.com/ws/conv?agentId=${agentId}&appId=${appId}&demo=true`;
|
|
292
|
+
console.log('Using fallback URL:', fallbackUrl);
|
|
293
|
+
updateStatus('Using fallback direct connection', 'info');
|
|
294
|
+
|
|
295
|
+
return fallbackUrl;
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
// Pass some test variables
|
|
300
|
+
variables: {
|
|
301
|
+
testMode: true,
|
|
302
|
+
userName: 'Test User',
|
|
303
|
+
page: 'test-signed-link.html',
|
|
304
|
+
connectionType: 'signed-link'
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
// Customize appearance
|
|
308
|
+
primaryColor: '#F59E0B',
|
|
309
|
+
position: 'bottom-right'
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Store widget reference for testing (like the working implementation)
|
|
313
|
+
window.testWidget = widget;
|
|
314
|
+
|
|
315
|
+
console.log('Widget initialized successfully with signed link!');
|
|
316
|
+
console.log('Widget instance:', widget);
|
|
317
|
+
console.log('Test methods available at window.testWidget');
|
|
318
|
+
updateStatus('Widget loaded and ready ✓', 'success');
|
|
319
|
+
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error('Failed to initialize widget:', error);
|
|
322
|
+
updateStatus('Widget failed to load ✗', 'error');
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Test functions (matching the working implementation)
|
|
326
|
+
function testMicButton() {
|
|
327
|
+
console.log('🎤 Testing mic button manually...');
|
|
328
|
+
const micButton = document.getElementById('agent-mic-button');
|
|
329
|
+
if (micButton) {
|
|
330
|
+
console.log('🎤 Found mic button, clicking...');
|
|
331
|
+
micButton.click();
|
|
332
|
+
} else {
|
|
333
|
+
console.log('🎤 Mic button not found');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function testToggleVoice() {
|
|
338
|
+
console.log('🎤 Testing toggleVoice method...');
|
|
339
|
+
if (window.testWidget && window.testWidget.toggleVoice) {
|
|
340
|
+
window.testWidget.toggleVoice();
|
|
341
|
+
} else {
|
|
342
|
+
console.log('🎤 toggleVoice method not available');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function checkWidgetState() {
|
|
347
|
+
console.log('🎤 Widget state:', {
|
|
348
|
+
isActive: window.testWidget?.isActive,
|
|
349
|
+
isOpen: window.testWidget?.isOpen,
|
|
350
|
+
sdk: window.testWidget?.sdk
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function testMicrophone() {
|
|
355
|
+
console.log('Testing microphone access...');
|
|
356
|
+
try {
|
|
357
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
358
|
+
console.log('Microphone access granted ✓');
|
|
359
|
+
stream.getTracks().forEach(track => track.stop());
|
|
360
|
+
alert('Microphone access OK!');
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.error('Microphone access denied:', error);
|
|
363
|
+
alert('Microphone access DENIED! Please allow microphone in browser settings.');
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Manual test functions
|
|
368
|
+
async function testBackendAPI() {
|
|
369
|
+
console.log('Testing backend API connection...');
|
|
370
|
+
try {
|
|
371
|
+
const response = await fetch('https://backend.talktopc.com/api/public/agents/signed-url', {
|
|
372
|
+
method: 'POST',
|
|
373
|
+
headers: {
|
|
374
|
+
'Content-Type': 'application/json',
|
|
375
|
+
},
|
|
376
|
+
body: JSON.stringify({
|
|
377
|
+
agentId: 'agent_87c4a55a1',
|
|
378
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
379
|
+
variables: { testMode: true }
|
|
380
|
+
})
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
console.log('Backend API response status:', response.status);
|
|
384
|
+
|
|
385
|
+
if (response.ok) {
|
|
386
|
+
const data = await response.json();
|
|
387
|
+
console.log('Backend API response:', data);
|
|
388
|
+
alert('Backend API connection OK! Check console for response details.');
|
|
389
|
+
} else {
|
|
390
|
+
const errorText = await response.text();
|
|
391
|
+
throw new Error(`Backend returned error: ${response.status} - ${errorText}`);
|
|
392
|
+
}
|
|
393
|
+
} catch (error) {
|
|
394
|
+
console.error('Backend API test failed:', error);
|
|
395
|
+
alert('Backend API test FAILED! Check console for details.');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
async function testSignedUrlGeneration() {
|
|
400
|
+
console.log('Testing signed URL generation...');
|
|
401
|
+
try {
|
|
402
|
+
const response = await fetch('https://backend.talktopc.com/api/public/agents/signed-url', {
|
|
403
|
+
method: 'POST',
|
|
404
|
+
headers: {
|
|
405
|
+
'Content-Type': 'application/json',
|
|
406
|
+
},
|
|
407
|
+
body: JSON.stringify({
|
|
408
|
+
agentId: 'agent_87c4a55a1',
|
|
409
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
410
|
+
variables: {
|
|
411
|
+
testMode: true,
|
|
412
|
+
userName: 'Test User',
|
|
413
|
+
timestamp: new Date().toISOString()
|
|
414
|
+
}
|
|
415
|
+
})
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
if (response.ok) {
|
|
419
|
+
const data = await response.json();
|
|
420
|
+
const signedUrl = data.signedUrl || data.url || data.websocketUrl || data.sessionUrl;
|
|
421
|
+
|
|
422
|
+
if (signedUrl) {
|
|
423
|
+
console.log('Generated signed URL:', signedUrl);
|
|
424
|
+
alert(`Signed URL generated successfully!\n\nURL: ${signedUrl.substring(0, 100)}...`);
|
|
425
|
+
} else {
|
|
426
|
+
throw new Error('No signed URL in response');
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
throw new Error(`API error: ${response.status}`);
|
|
430
|
+
}
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error('Signed URL generation test failed:', error);
|
|
433
|
+
alert('Signed URL generation FAILED! Check console for details.');
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async function testMicrophone() {
|
|
438
|
+
console.log('Testing microphone access...');
|
|
439
|
+
try {
|
|
440
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
441
|
+
console.log('Microphone access granted ✓');
|
|
442
|
+
stream.getTracks().forEach(track => track.stop());
|
|
443
|
+
alert('Microphone access OK!');
|
|
444
|
+
} catch (error) {
|
|
445
|
+
console.error('Microphone access denied:', error);
|
|
446
|
+
alert('Microphone access DENIED! Please allow microphone in browser settings.');
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
</script>
|
|
450
|
+
</body>
|
|
451
|
+
</html>
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
============================================
|
|
3
|
-
FILE: examples/test.html
|
|
4
|
-
Test page for the widget
|
|
5
|
-
============================================
|
|
6
|
-
-->
|
|
7
1
|
<!DOCTYPE html>
|
|
8
2
|
<html lang="en">
|
|
9
3
|
<head>
|
|
10
4
|
<meta charset="UTF-8">
|
|
11
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
12
|
-
<title>Voice Agent Widget - Test
|
|
6
|
+
<title>Voice Agent Widget - Agent ID + App ID Test</title>
|
|
13
7
|
<style>
|
|
14
8
|
body {
|
|
15
9
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
@@ -39,6 +33,14 @@ Test page for the widget
|
|
|
39
33
|
border-radius: 4px;
|
|
40
34
|
}
|
|
41
35
|
|
|
36
|
+
.config-info {
|
|
37
|
+
background: #F0FDF4;
|
|
38
|
+
border-left: 4px solid #10B981;
|
|
39
|
+
padding: 16px;
|
|
40
|
+
margin: 20px 0;
|
|
41
|
+
border-radius: 4px;
|
|
42
|
+
}
|
|
43
|
+
|
|
42
44
|
.status {
|
|
43
45
|
margin: 20px 0;
|
|
44
46
|
padding: 12px;
|
|
@@ -72,20 +74,39 @@ Test page for the widget
|
|
|
72
74
|
button:hover {
|
|
73
75
|
background: #4338CA;
|
|
74
76
|
}
|
|
77
|
+
|
|
78
|
+
.code-block {
|
|
79
|
+
background: #1F2937;
|
|
80
|
+
color: #F9FAFB;
|
|
81
|
+
padding: 16px;
|
|
82
|
+
border-radius: 6px;
|
|
83
|
+
font-family: monospace;
|
|
84
|
+
font-size: 12px;
|
|
85
|
+
overflow-x: auto;
|
|
86
|
+
margin: 20px 0;
|
|
87
|
+
}
|
|
75
88
|
</style>
|
|
76
89
|
</head>
|
|
77
90
|
<body>
|
|
78
91
|
<div class="container">
|
|
79
|
-
<h1>🎤 Voice Agent Widget - Test
|
|
92
|
+
<h1>🎤 Voice Agent Widget - Agent ID + App ID Test</h1>
|
|
93
|
+
|
|
94
|
+
<div class="config-info">
|
|
95
|
+
<strong>📝 Configuration:</strong>
|
|
96
|
+
<ul style="margin: 10px 0 0 20px; line-height: 1.8;">
|
|
97
|
+
<li><strong>Agent ID:</strong> agent_87c4a55a1</li>
|
|
98
|
+
<li><strong>App ID:</strong> app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC</li>
|
|
99
|
+
<li><strong>Method:</strong> Direct connection (no signed link)</li>
|
|
100
|
+
</ul>
|
|
101
|
+
</div>
|
|
80
102
|
|
|
81
103
|
<div class="info">
|
|
82
104
|
<strong>📝 Testing Instructions:</strong>
|
|
83
105
|
<ol style="margin: 10px 0 0 20px; line-height: 1.8;">
|
|
84
|
-
<li><strong>No backend required!</strong> This demo uses a mock session URL</li>
|
|
85
106
|
<li>Look for the floating voice button in the bottom-right corner</li>
|
|
86
107
|
<li>Click the button to open the widget</li>
|
|
87
108
|
<li>Click the microphone to start (will request mic permission)</li>
|
|
88
|
-
<li>Widget will connect
|
|
109
|
+
<li>Widget will connect directly using agent ID + app ID</li>
|
|
89
110
|
<li>Check the status updates below</li>
|
|
90
111
|
</ol>
|
|
91
112
|
</div>
|
|
@@ -100,13 +121,39 @@ Test page for the widget
|
|
|
100
121
|
Console messages will appear here...
|
|
101
122
|
</div>
|
|
102
123
|
|
|
124
|
+
<h2>Implementation Code:</h2>
|
|
125
|
+
<div class="code-block">
|
|
126
|
+
const widget = new TTPAgentSDK.AgentWidget({
|
|
127
|
+
agentId: 'agent_87c4a55a1',
|
|
128
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
129
|
+
|
|
130
|
+
// Direct connection without signed link
|
|
131
|
+
getSessionUrl: async ({ agentId, appId, variables }) => {
|
|
132
|
+
// Direct WebSocket URL construction with demo flag
|
|
133
|
+
const wsUrl = `wss://speech.talktopc.com/ws/conv?agentId=${agentId}&appId=${appId}&demo=true`;
|
|
134
|
+
return wsUrl;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
variables: {
|
|
138
|
+
testMode: true,
|
|
139
|
+
userName: 'Test User',
|
|
140
|
+
page: 'test-agent-app.html'
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
primaryColor: '#10B981',
|
|
144
|
+
position: 'bottom-right'
|
|
145
|
+
});
|
|
146
|
+
</div>
|
|
147
|
+
|
|
103
148
|
<h2>Manual Tests:</h2>
|
|
104
|
-
<button onclick="
|
|
149
|
+
<button onclick="testMicButton()">Test Mic Button Click</button>
|
|
150
|
+
<button onclick="testToggleVoice()">Test ToggleVoice Method</button>
|
|
151
|
+
<button onclick="checkWidgetState()">Check Widget State</button>
|
|
105
152
|
<button onclick="testMicrophone()">Test Microphone Access</button>
|
|
106
153
|
</div>
|
|
107
154
|
|
|
108
155
|
<!-- Load the widget -->
|
|
109
|
-
<script src="../agent-widget.js" onload="console.log('SDK script loaded successfully')" onerror="console.error('Failed to load SDK script')"></script>
|
|
156
|
+
<script src="../agent-widget.js?v=24" onload="console.log('SDK script loaded successfully')" onerror="console.error('Failed to load SDK script')"></script>
|
|
110
157
|
|
|
111
158
|
<script>
|
|
112
159
|
// Override console.log to show in page
|
|
@@ -140,7 +187,7 @@ Test page for the widget
|
|
|
140
187
|
|
|
141
188
|
// Initialize the widget
|
|
142
189
|
try {
|
|
143
|
-
console.log('Initializing widget...');
|
|
190
|
+
console.log('Initializing widget with agent ID + app ID...');
|
|
144
191
|
console.log('TTPAgentSDK available:', typeof TTPAgentSDK);
|
|
145
192
|
console.log('TTPAgentSDK.AgentWidget available:', typeof TTPAgentSDK?.AgentWidget);
|
|
146
193
|
|
|
@@ -152,31 +199,30 @@ Test page for the widget
|
|
|
152
199
|
throw new Error('TTPAgentSDK.AgentWidget is not defined. Check the SDK build.');
|
|
153
200
|
}
|
|
154
201
|
|
|
155
|
-
// Create a new AgentWidget instance
|
|
202
|
+
// Create a new AgentWidget instance with agent ID + app ID
|
|
156
203
|
const widget = new TTPAgentSDK.AgentWidget({
|
|
157
|
-
agentId: '
|
|
204
|
+
agentId: 'agent_87c4a55a1',
|
|
205
|
+
appId: 'app_Bc01EqMQt2Euehl4qqZSi6l3FJP42Q9vJ0pC',
|
|
158
206
|
|
|
159
|
-
//
|
|
160
|
-
getSessionUrl: async ({ agentId, variables }) => {
|
|
161
|
-
console.log('
|
|
207
|
+
// Direct connection without signed link
|
|
208
|
+
getSessionUrl: async ({ agentId, appId, variables }) => {
|
|
209
|
+
console.log('Creating direct session URL for agent:', agentId);
|
|
210
|
+
console.log('App ID:', appId);
|
|
162
211
|
console.log('Variables:', variables);
|
|
163
212
|
|
|
164
|
-
updateStatus('Creating
|
|
213
|
+
updateStatus('Creating direct session URL...', 'info');
|
|
165
214
|
|
|
166
215
|
try {
|
|
167
|
-
//
|
|
168
|
-
|
|
216
|
+
// Direct WebSocket URL construction with demo flag
|
|
217
|
+
const wsUrl = `wss://speech.talktopc.com/ws/conv?agentId=${agentId}&appId=${appId}&demo=true`;
|
|
169
218
|
|
|
170
|
-
|
|
171
|
-
|
|
219
|
+
console.log('Generated direct session URL:', wsUrl);
|
|
220
|
+
updateStatus('Direct session URL created ✓', 'success');
|
|
172
221
|
|
|
173
|
-
|
|
174
|
-
updateStatus('Mock session URL created ✓', 'success');
|
|
175
|
-
|
|
176
|
-
return mockSignedUrl;
|
|
222
|
+
return wsUrl;
|
|
177
223
|
} catch (error) {
|
|
178
|
-
console.error('Failed to create
|
|
179
|
-
updateStatus('Failed to create
|
|
224
|
+
console.error('Failed to create direct session URL:', error);
|
|
225
|
+
updateStatus('Failed to create direct session URL ✗', 'error');
|
|
180
226
|
throw error;
|
|
181
227
|
}
|
|
182
228
|
},
|
|
@@ -185,7 +231,8 @@ Test page for the widget
|
|
|
185
231
|
variables: {
|
|
186
232
|
testMode: true,
|
|
187
233
|
userName: 'Test User',
|
|
188
|
-
page: 'test.html'
|
|
234
|
+
page: 'test-agent-app.html',
|
|
235
|
+
connectionType: 'direct'
|
|
189
236
|
},
|
|
190
237
|
|
|
191
238
|
// Customize appearance
|
|
@@ -193,7 +240,12 @@ Test page for the widget
|
|
|
193
240
|
position: 'bottom-right'
|
|
194
241
|
});
|
|
195
242
|
|
|
196
|
-
|
|
243
|
+
// Store widget reference for testing (like the working implementation)
|
|
244
|
+
window.testWidget = widget;
|
|
245
|
+
|
|
246
|
+
console.log('Widget initialized successfully with agent ID + app ID!');
|
|
247
|
+
console.log('Widget instance:', widget);
|
|
248
|
+
console.log('Test methods available at window.testWidget');
|
|
197
249
|
updateStatus('Widget loaded and ready ✓', 'success');
|
|
198
250
|
|
|
199
251
|
} catch (error) {
|
|
@@ -201,23 +253,35 @@ Test page for the widget
|
|
|
201
253
|
updateStatus('Widget failed to load ✗', 'error');
|
|
202
254
|
}
|
|
203
255
|
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
console.log('Testing
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
256
|
+
// Test functions (matching the working implementation)
|
|
257
|
+
function testMicButton() {
|
|
258
|
+
console.log('🎤 Testing mic button manually...');
|
|
259
|
+
const micButton = document.getElementById('agent-mic-button');
|
|
260
|
+
if (micButton) {
|
|
261
|
+
console.log('🎤 Found mic button, clicking...');
|
|
262
|
+
micButton.click();
|
|
263
|
+
} else {
|
|
264
|
+
console.log('🎤 Mic button not found');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function testToggleVoice() {
|
|
269
|
+
console.log('🎤 Testing toggleVoice method...');
|
|
270
|
+
if (window.testWidget && window.testWidget.toggleVoice) {
|
|
271
|
+
window.testWidget.toggleVoice();
|
|
272
|
+
} else {
|
|
273
|
+
console.log('🎤 toggleVoice method not available');
|
|
218
274
|
}
|
|
219
275
|
}
|
|
220
276
|
|
|
277
|
+
function checkWidgetState() {
|
|
278
|
+
console.log('🎤 Widget state:', {
|
|
279
|
+
isActive: window.testWidget?.isActive,
|
|
280
|
+
isOpen: window.testWidget?.isOpen,
|
|
281
|
+
sdk: window.testWidget?.sdk
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
221
285
|
async function testMicrophone() {
|
|
222
286
|
console.log('Testing microphone access...');
|
|
223
287
|
try {
|