ttp-agent-sdk 2.2.22 → 2.3.0

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/index.html CHANGED
@@ -1,224 +1,2439 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>TTP Agent SDK - Voice AI Integration</title>
7
- <style>
8
- body {
9
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
10
- max-width: 1200px;
11
- margin: 0 auto;
12
- padding: 20px;
13
- background: #f8fafc;
14
- color: #1e293b;
15
- }
16
- .header {
17
- text-align: center;
18
- margin-bottom: 40px;
19
- padding: 40px 20px;
20
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
21
- color: white;
22
- border-radius: 12px;
23
- }
24
- .header h1 {
25
- margin: 0 0 10px 0;
26
- font-size: 2.5rem;
27
- }
28
- .header p {
29
- margin: 0;
30
- font-size: 1.2rem;
31
- opacity: 0.9;
32
- }
33
- .content {
34
- display: grid;
35
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
36
- gap: 30px;
37
- margin-bottom: 40px;
38
- }
39
- .card {
40
- background: white;
41
- padding: 30px;
42
- border-radius: 12px;
43
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
44
- border: 1px solid #e2e8f0;
45
- }
46
- .card h2 {
47
- margin-top: 0;
48
- color: #4f46e5;
49
- display: flex;
50
- align-items: center;
51
- gap: 10px;
52
- }
53
- .card p {
54
- line-height: 1.6;
55
- color: #64748b;
56
- }
57
- .demo-button {
58
- display: inline-block;
59
- background: #4f46e5;
60
- color: white;
61
- padding: 12px 24px;
62
- text-decoration: none;
63
- border-radius: 8px;
64
- font-weight: 600;
65
- transition: background-color 0.2s;
66
- margin-top: 15px;
67
- }
68
- .demo-button:hover {
69
- background: #4338ca;
70
- }
71
- .code-block {
72
- background: #1e293b;
73
- color: #e2e8f0;
74
- padding: 20px;
75
- border-radius: 8px;
76
- font-family: 'Monaco', 'Menlo', monospace;
77
- font-size: 14px;
78
- overflow-x: auto;
79
- margin: 20px 0;
80
- }
81
- .features {
82
- background: white;
83
- padding: 30px;
84
- border-radius: 12px;
85
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
86
- margin-bottom: 30px;
87
- }
88
- .features h2 {
89
- margin-top: 0;
90
- color: #4f46e5;
91
- }
92
- .feature-grid {
93
- display: grid;
94
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
95
- gap: 20px;
96
- margin-top: 20px;
97
- }
98
- .feature {
99
- padding: 20px;
100
- background: #f8fafc;
101
- border-radius: 8px;
102
- border-left: 4px solid #4f46e5;
103
- }
104
- .feature h3 {
105
- margin: 0 0 10px 0;
106
- color: #1e293b;
107
- }
108
- .feature p {
109
- margin: 0;
110
- color: #64748b;
111
- font-size: 14px;
112
- }
113
- .footer {
114
- text-align: center;
115
- padding: 30px;
116
- color: #64748b;
117
- border-top: 1px solid #e2e8f0;
118
- }
119
- </style>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>TTP Agent SDK - Documentation</title>
7
+ <link rel="stylesheet" href="/styles.css">
120
8
  </head>
121
9
  <body>
122
- <div class="header">
123
- <h1>🎤 TTP Agent SDK</h1>
124
- <p>Comprehensive Voice AI Integration for Web Applications</p>
10
+ <!-- Mobile Header (only visible on mobile) -->
11
+ <header class="mobile-header">
12
+ <div class="mobile-header-logo">
13
+ <img src="https://talktopc.com/logo192.png" alt="TTP Logo">
14
+ <h1 class="mobile-header-title">TTP Agent SDK</h1>
125
15
  </div>
16
+ </header>
126
17
 
127
- <div class="features">
128
- <h2>✨ Key Features</h2>
129
- <div class="feature-grid">
130
- <div class="feature">
131
- <h3>🎤 Real-time Audio</h3>
132
- <p>High-quality audio recording and playback with AudioWorklet</p>
18
+ <div class="documentation">
19
+ <!-- Sidebar Navigation -->
20
+ <aside class="sidebar">
21
+ <div class="sidebar-header">
22
+ <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 10px;">
23
+ <img src="https://talktopc.com/logo192.png" alt="TTP Logo" style="width: 40px; height: 40px; border-radius: 8px;">
24
+ <div>
25
+ <h1 style="margin: 0; font-size: 1.4rem;">TTP Agent SDK</h1>
26
+ <p class="version" style="margin: 0;">v2.3.0</p>
27
+ </div>
28
+ </div>
29
+ </div>
30
+
31
+ <nav class="sidebar-nav">
32
+ <div class="nav-section">
33
+ <h3>Getting Started</h3>
34
+ <ul>
35
+ <li><a href="#introduction" class="nav-link active">Introduction</a></li>
36
+ <li><a href="#installation" class="nav-link">Installation</a></li>
37
+ <li><a href="#quick-start" class="nav-link">Quick Start</a></li>
38
+ </ul>
39
+ </div>
40
+
41
+ <div class="nav-section">
42
+ <h3>Core Concepts</h3>
43
+ <ul>
44
+ <li><a href="#authentication" class="nav-link">Authentication</a></li>
45
+ <li><a href="#agent-override" class="nav-link">Agent Override</a></li>
46
+ <li><a href="#events" class="nav-link">Events & Callbacks</a></li>
47
+ </ul>
48
+ </div>
49
+
50
+ <div class="nav-section">
51
+ <h3>Guides</h3>
52
+ <ul>
53
+ <li><a href="#text-chat-widget" class="nav-link">Voice & Chat Widget</a></li>
54
+ <li><a href="#vanilla-js" class="nav-link">Vanilla JavaScript</a></li>
55
+ <li><a href="#react" class="nav-link">React Integration</a></li>
56
+ <li><a href="#voice-button" class="nav-link">VoiceButton Component</a></li>
57
+ </ul>
58
+ </div>
59
+
60
+ <div class="nav-section">
61
+ <h3>API Reference</h3>
62
+ <ul>
63
+ <li><a href="#voicesdk" class="nav-link">VoiceSDK Class</a></li>
64
+ <li><a href="#methods" class="nav-link">Methods</a></li>
65
+ <li><a href="#events-api" class="nav-link">Events</a></li>
66
+ <li><a href="#configuration" class="nav-link">Configuration</a></li>
67
+ </ul>
68
+ </div>
69
+
70
+ <div class="nav-section">
71
+ <h3>Examples</h3>
72
+ <ul>
73
+ <li><a href="../examples/test-text-chat.html" target="_blank">Live Widget Demo 🚀</a></li>
74
+ </ul>
75
+ </div>
76
+ </nav>
77
+ </aside>
78
+
79
+ <!-- Main Content -->
80
+ <main class="content">
81
+ <div class="content-wrapper">
82
+ <!-- Introduction -->
83
+ <section id="introduction" class="doc-section">
84
+ <h1>Introduction</h1>
85
+ <p class="lead">TTP Agent SDK is a powerful JavaScript library for building AI-powered voice and chat interactions in your web applications.</p>
86
+
87
+ <!-- Quick Links Menu -->
88
+ <div class="quick-links-container">
89
+ <h2 style="text-align: center; margin-bottom: 25px; color: var(--text-primary);">What We Offer</h2>
90
+ <div class="quick-links-grid">
91
+ <a href="#text-chat-widget" class="quick-link-card">
92
+ <div class="quick-link-icon">🎙️💬</div>
93
+ <h3>Voice & Chat Widget</h3>
94
+ <p>Drop-in widget with voice & text for any website</p>
95
+ <span class="quick-link-arrow">→</span>
96
+ </a>
97
+
98
+ <a href="#vanilla-js" class="quick-link-card">
99
+ <div class="quick-link-icon">🎤</div>
100
+ <h3>Voice SDK</h3>
101
+ <p>Real-time voice AI integration</p>
102
+ <span class="quick-link-arrow">→</span>
103
+ </a>
104
+
105
+ <a href="#react" class="quick-link-card">
106
+ <div class="quick-link-icon">⚛️</div>
107
+ <h3>React Components</h3>
108
+ <p>Pre-built React components</p>
109
+ <span class="quick-link-arrow">→</span>
110
+ </a>
111
+
112
+ <a href="#agent-override" class="quick-link-card">
113
+ <div class="quick-link-icon">⚙️</div>
114
+ <h3>Agent Override</h3>
115
+ <p>Dynamic AI customization</p>
116
+ <span class="quick-link-arrow">→</span>
117
+ </a>
133
118
  </div>
134
- <div class="feature">
135
- <h3>🔄 WebSocket Communication</h3>
136
- <p>Real-time bidirectional communication with authentication</p>
119
+ </div>
120
+
121
+ <!-- Key Features -->
122
+ <div style="margin-top: 50px;">
123
+ <h2 style="margin-bottom: 20px;">Key Features</h2>
124
+ <div class="features-compact">
125
+ <div class="feature-compact-item">
126
+ <span class="feature-compact-icon">🔒</span>
127
+ <div>
128
+ <strong>Secure Authentication</strong>
129
+ <p>Backend-to-backend signed link authentication with one-time use tokens</p>
130
+ </div>
131
+ </div>
132
+ <div class="feature-compact-item">
133
+ <span class="feature-compact-icon">🎨</span>
134
+ <div>
135
+ <strong>Fully Customizable</strong>
136
+ <p>Colors, branding, languages, RTL support, and custom agent settings</p>
137
+ </div>
138
+ </div>
139
+ <div class="feature-compact-item">
140
+ <span class="feature-compact-icon">📱</span>
141
+ <div>
142
+ <strong>Mobile Optimized</strong>
143
+ <p>Works seamlessly on desktop, tablet, and mobile devices</p>
144
+ </div>
145
+ </div>
146
+ <div class="feature-compact-item">
147
+ <span class="feature-compact-icon">🌍</span>
148
+ <div>
149
+ <strong>Multi-language</strong>
150
+ <p>Built-in support for multiple languages and custom translations</p>
151
+ </div>
152
+ </div>
153
+ <div class="feature-compact-item">
154
+ <span class="feature-compact-icon">⚡</span>
155
+ <div>
156
+ <strong>Real-time Streaming</strong>
157
+ <p>WebSocket-based audio streaming with low latency</p>
158
+ </div>
159
+ </div>
160
+ <div class="feature-compact-item">
161
+ <span class="feature-compact-icon">🔧</span>
162
+ <div>
163
+ <strong>Easy Integration</strong>
164
+ <p>Simple CDN setup or NPM package with comprehensive API</p>
165
+ </div>
166
+ </div>
137
167
  </div>
168
+ </div>
169
+ </section>
170
+
171
+ <!-- Installation -->
172
+ <section id="installation" class="doc-section">
173
+ <h1>Installation</h1>
174
+
175
+ <h2>NPM</h2>
176
+ <pre><code>npm install ttp-agent-sdk</code></pre>
177
+
178
+ <h2>CDN</h2>
179
+ <pre><code>&lt;script src="https://unpkg.com/ttp-agent-sdk/dist/agent-widget.js"&gt;&lt;/script&gt;</code></pre>
180
+
181
+ <h2>Import</h2>
182
+ <pre><code>// ES6 Import
183
+ import { VoiceSDK } from 'ttp-agent-sdk';
184
+
185
+ // CommonJS
186
+ const { VoiceSDK } = require('ttp-agent-sdk');
187
+
188
+ // Browser Global
189
+ const sdk = new window.TTPAgentSDK.VoiceSDK(config);</code></pre>
190
+ </section>
191
+
192
+ <!-- Quick Start -->
193
+ <section id="quick-start" class="doc-section">
194
+ <h1>Quick Start</h1>
195
+ <p>Get up and running in 5 minutes with this simple example.</p>
196
+
197
+ <div class="step-card">
198
+ <div class="step-number">1</div>
199
+ <div class="step-content">
200
+ <h3>Get a Signed URL</h3>
201
+ <div class="warning-box">
202
+ <strong>🔒 Backend-to-Backend:</strong> Your frontend requests from YOUR backend, which then communicates with TTP backend. Never expose your API key to the frontend!
203
+ </div>
204
+ <p><strong>Frontend → Your Backend:</strong></p>
205
+ <pre><code>const response = await fetch('/api/get-voice-session', {
206
+ method: 'POST',
207
+ headers: {
208
+ 'Content-Type': 'application/json'
209
+ },
210
+ body: JSON.stringify({
211
+ agentId: 'agent_123'
212
+ })
213
+ });
214
+
215
+ const { signedUrl } = await response.json();</code></pre>
216
+ <p><strong>Your Backend → TTP Backend:</strong> (See Authentication section for details)</p>
217
+ </div>
218
+ </div>
219
+
220
+ <div class="step-card">
221
+ <div class="step-number">2</div>
222
+ <div class="step-content">
223
+ <h3>Initialize the SDK</h3>
224
+ <p>Create a VoiceSDK instance with the signed URL:</p>
225
+ <pre><code>import { VoiceSDK } from 'ttp-agent-sdk';
226
+
227
+ const voiceSDK = new VoiceSDK({
228
+ websocketUrl: signedUrl, // Signed URL from step 1
229
+ appId: 'your_app_id', // Your application ID
230
+ agentId: 'agent_123' // The AI agent to connect to
231
+ });
232
+
233
+ // Listen to events
234
+ voiceSDK.on('connected', () => {
235
+ console.log('✅ Connected to agent');
236
+ });
237
+
238
+ voiceSDK.on('message', (msg) => {
239
+ if (msg.type === 'agent_response') {
240
+ console.log('Agent:', msg.agent_response);
241
+ }
242
+ });</code></pre>
243
+ </div>
244
+ </div>
245
+
246
+ <div class="step-card">
247
+ <div class="step-number">3</div>
248
+ <div class="step-content">
249
+ <h3>Connect & Start Recording</h3>
250
+ <p>Connect to the agent and start capturing audio:</p>
251
+ <pre><code>// Connect
252
+ await voiceSDK.connect();
253
+
254
+ // Start recording
255
+ await voiceSDK.startRecording();
256
+
257
+ // Stop recording
258
+ await voiceSDK.stopRecording();</code></pre>
259
+ </div>
260
+ </div>
261
+ </section>
262
+
263
+ <!-- Authentication -->
264
+ <section id="authentication" class="doc-section">
265
+ <h1>Authentication</h1>
266
+ <p>TTP Agent SDK uses signed WebSocket URLs for secure authentication.</p>
267
+
268
+ <div class="info-box">
269
+ <strong>🔒 Security First:</strong> All connections require signed URLs obtained from your backend, which authenticates with the TTP backend using an API key.
270
+ </div>
271
+
272
+ <h2>Authentication Flow</h2>
273
+ <div class="warning-box">
274
+ <strong>🔐 Critical Security Note:</strong> The signed URL generation happens <strong>Backend-to-Backend</strong>. Your frontend NEVER directly contacts TTP backend. This protects your API key!
275
+ </div>
276
+ <div class="flow-diagram">
277
+ <div class="flow-step">
278
+ <div class="flow-box" style="background: linear-gradient(135deg, #e0f2fe 0%, #bfdbfe 100%);">
279
+ <strong>1. 🖥️ Your Frontend</strong>
280
+ <p>User clicks "Start Voice Chat"</p>
281
+ </div>
282
+ <div class="flow-arrow">↓</div>
283
+ <div class="flow-box" style="background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);">
284
+ <strong>2. 🔧 Your Backend</strong>
285
+ <p>Receives: POST /api/get-voice-session</p>
286
+ </div>
287
+ <div class="flow-arrow">↓ 🔒 Backend-to-Backend (API Key)</div>
288
+ <div class="flow-box" style="background: linear-gradient(135deg, #e9d5ff 0%, #d8b4fe 100%);">
289
+ <strong>3. 🏢 TTP Backend</strong>
290
+ <p>Validates API key & generates signed JWT</p>
291
+ </div>
292
+ <div class="flow-arrow">↑ Returns signed URL</div>
293
+ <div class="flow-box" style="background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);">
294
+ <strong>4. 🔧 Your Backend</strong>
295
+ <p>Forwards signed URL to frontend</p>
296
+ </div>
297
+ <div class="flow-arrow">↓</div>
298
+ <div class="flow-box" style="background: linear-gradient(135deg, #e0f2fe 0%, #bfdbfe 100%);">
299
+ <strong>5. 🖥️ Your Frontend</strong>
300
+ <p>Uses SDK with signed URL (WebSocket)</p>
301
+ </div>
302
+ </div>
303
+ </div>
304
+
305
+ <h2>Backend Implementation (Backend-to-Backend)</h2>
306
+ <p><strong>Your backend acts as a secure proxy between your frontend and TTP backend:</strong></p>
307
+
308
+ <div class="info-box">
309
+ <strong>💡 Architecture:</strong> Frontend → Your Backend → TTP Backend → Your Backend → Frontend
310
+ </div>
311
+
312
+ <div class="success-box">
313
+ <strong>⏱️ Configurable TTL:</strong> You can specify <code>expirationMs</code> (in milliseconds) to control how long the signed URL is valid. Default is 1 hour (3600000ms) if not specified.
314
+ <br><br>
315
+ <strong>Examples:</strong>
316
+ <ul style="margin-top: 10px; margin-left: 20px;">
317
+ <li>5 minutes: <code>300000</code></li>
318
+ <li>1 hour (default): <code>3600000</code></li>
319
+ <li>24 hours: <code>86400000</code></li>
320
+ </ul>
321
+ </div>
322
+
323
+ <pre><code>// Example: Node.js/Express
324
+ // This endpoint is called by YOUR FRONTEND
325
+ app.post('/api/get-voice-session', async (req, res) => {
326
+ const { agentId } = req.body;
327
+
328
+ // 1️⃣ Authenticate YOUR user (your auth logic)
329
+ if (!req.user) {
330
+ return res.status(401).json({ error: 'Unauthorized' });
331
+ }
332
+
333
+ // 2️⃣ Backend-to-Backend: Call TTP Backend with YOUR API Key
334
+ // ⚠️ This happens SERVER-SIDE only - API key never exposed to frontend
335
+ const response = await fetch('https://backend.talktopc.com/api/public/agents/signed-url', {
336
+ method: 'POST',
337
+ headers: {
338
+ 'Content-Type': 'application/json',
339
+ 'X-API-Key': process.env.TTP_API_KEY // 🔒 Secret - never in frontend!
340
+ },
341
+ body: JSON.stringify({
342
+ agentId: agentId,
343
+ appId: process.env.TTP_APP_ID,
344
+ expirationMs: 3600000 // Optional: Token TTL in milliseconds (default: 1 hour)
345
+ })
346
+ });
347
+
348
+ const { signedUrl } = await response.json();
349
+
350
+ // 3️⃣ Return signed URL to YOUR frontend
351
+ res.json({ signedUrl });
352
+ });</code></pre>
353
+
354
+ <div class="warning-box">
355
+ <strong>⚠️ Never expose your API key:</strong> The API key should only be used on your backend server, never in frontend code.
356
+ </div>
357
+
358
+ <h2>Token Properties</h2>
359
+ <table class="properties-table">
360
+ <thead>
361
+ <tr>
362
+ <th>Property</th>
363
+ <th>Description</th>
364
+ </tr>
365
+ </thead>
366
+ <tbody>
367
+ <tr>
368
+ <td><code>jti</code></td>
369
+ <td>Unique token ID for one-time use enforcement</td>
370
+ </tr>
371
+ <tr>
372
+ <td><code>agentId</code></td>
373
+ <td>The AI agent identifier</td>
374
+ </tr>
375
+ <tr>
376
+ <td><code>userId</code></td>
377
+ <td>Your user's identifier</td>
378
+ </tr>
379
+ <tr>
380
+ <td><code>allowOverride</code></td>
381
+ <td>Permission flag for agent settings override</td>
382
+ </tr>
383
+ <tr>
384
+ <td><code>exp</code></td>
385
+ <td>Expiration time (configurable via <code>expirationMs</code>, defaults to 1 hour)</td>
386
+ </tr>
387
+ </tbody>
388
+ </table>
389
+
390
+ <h2>Request Parameters</h2>
391
+ <table class="properties-table">
392
+ <thead>
393
+ <tr>
394
+ <th>Parameter</th>
395
+ <th>Type</th>
396
+ <th>Required</th>
397
+ <th>Description</th>
398
+ </tr>
399
+ </thead>
400
+ <tbody>
401
+ <tr>
402
+ <td><code>agentId</code></td>
403
+ <td>string</td>
404
+ <td>Yes</td>
405
+ <td>The AI agent identifier</td>
406
+ </tr>
407
+ <tr>
408
+ <td><code>appId</code></td>
409
+ <td>string</td>
410
+ <td>Yes</td>
411
+ <td>Your application identifier</td>
412
+ </tr>
413
+ <tr>
414
+ <td><code>expirationMs</code></td>
415
+ <td>number</td>
416
+ <td>No</td>
417
+ <td>Token TTL in milliseconds (default: 3600000 = 1 hour)</td>
418
+ </tr>
419
+ <tr>
420
+ <td><code>variables</code></td>
421
+ <td>object</td>
422
+ <td>No</td>
423
+ <td>Custom variables to pass to the agent</td>
424
+ </tr>
425
+ </tbody>
426
+ </table>
427
+ </section>
428
+
429
+ <!-- Agent Override -->
430
+ <section id="agent-override" class="doc-section">
431
+ <h1>Agent Settings Override</h1>
432
+ <p class="badge-new">NEW FEATURE</p>
433
+ <p>Dynamically customize agent behavior, voice, and personality on a per-session basis.</p>
434
+
435
+ <div class="info-box">
436
+ <strong>🔒 Security:</strong> Agent overrides are only available with signed link authentication where <code>allowOverride: true</code> is granted by your backend.
437
+ </div>
438
+
439
+ <h2>How It Works</h2>
440
+ <div class="info-box">
441
+ <strong>🔐 Backend-to-Backend First:</strong> The signed URL with override permission is obtained via backend-to-backend communication before your frontend can use it.
442
+ </div>
443
+ <ol class="numbered-list">
444
+ <li><strong>Backend-to-Backend:</strong> Your backend requests a signed URL from TTP backend with <code>allowOverride: true</code></li>
445
+ <li><strong>Backend → Frontend:</strong> Your backend returns the signed URL to your frontend</li>
446
+ <li><strong>Frontend:</strong> Your frontend uses the SDK with the signed URL + custom agent settings</li>
447
+ <li><strong>TTP Backend:</strong> Validates the JWT signature and applies your overrides if permission granted</li>
448
+ </ol>
449
+
450
+ <h2>Example</h2>
451
+ <pre><code>const voiceSDK = new VoiceSDK({
452
+ websocketUrl: signedUrl, // Signed URL from your backend
453
+ appId: 'your_app_id', // Your application ID
454
+ agentId: 'agent_123', // The AI agent to connect to
455
+
456
+ // Override agent settings
457
+ agentSettingsOverride: {
458
+ // Core settings
459
+ prompt: "You are a friendly Spanish-speaking travel assistant",
460
+ language: "es",
461
+ temperature: 0.9,
462
+ maxTokens: 200,
463
+
464
+ // Voice settings
465
+ voiceSpeed: 1.2,
466
+ selectedVoice: "nova",
467
+
468
+ // Behavior
469
+ firstMessage: "¡Hola! ¿Cómo puedo ayudarte hoy?",
470
+ disableInterruptions: false,
471
+ autoDetectLanguage: true
472
+ }
473
+ });</code></pre>
474
+
475
+ <h2>Available Override Settings</h2>
476
+ <div class="settings-grid">
477
+ <div class="settings-category">
478
+ <h3>📝 Core Settings</h3>
479
+ <ul>
480
+ <li><code>prompt</code> - System prompt/instructions</li>
481
+ <li><code>temperature</code> - LLM temperature (0-2)</li>
482
+ <li><code>maxTokens</code> - Maximum response tokens</li>
483
+ <li><code>model</code> - LLM model selection</li>
484
+ <li><code>language</code> - Response language code</li>
485
+ </ul>
486
+ </div>
487
+ <div class="settings-category">
488
+ <h3>🔊 Voice Settings</h3>
489
+ <ul>
490
+ <li><code>selectedVoice</code> - Voice preset name</li>
491
+ <li><code>voiceId</code> - Specific voice ID</li>
492
+ <li><code>voiceSpeed</code> - Speed multiplier (0.5-2)</li>
493
+ </ul>
494
+ </div>
495
+ <div class="settings-category">
496
+ <h3>⚙️ Behavior</h3>
497
+ <ul>
498
+ <li><code>firstMessage</code> - Initial greeting</li>
499
+ <li><code>disableInterruptions</code> - Allow/prevent barge-in</li>
500
+ <li><code>autoDetectLanguage</code> - Auto language detection</li>
501
+ <li><code>maxCallDuration</code> - Max session duration (seconds)</li>
502
+ </ul>
503
+ </div>
504
+ <div class="settings-category">
505
+ <h3>🛠️ Advanced</h3>
506
+ <ul>
507
+ <li><code>selectedTools</code> - Array of enabled tools</li>
508
+ <li><code>timezone</code> - User timezone</li>
509
+ </ul>
510
+ </div>
511
+ </div>
512
+
513
+ <div class="warning-box">
514
+ <strong>⚠️ Validation:</strong> All overrides are validated and sanitized on the server. Invalid values will be rejected or clamped to safe ranges.
515
+ </div>
516
+ </section>
517
+
518
+ <!-- Events -->
519
+ <section id="events" class="doc-section">
520
+ <h1>Events & Callbacks</h1>
521
+ <p>The SDK emits events for all important state changes and interactions.</p>
522
+
523
+ <h2>Event Categories</h2>
524
+
525
+ <h3>Connection Events</h3>
526
+ <pre><code>voiceSDK.on('connected', () => {
527
+ console.log('✅ Connected to agent');
528
+ });
529
+
530
+ voiceSDK.on('disconnected', (event) => {
531
+ console.log('❌ Disconnected:', event.reason);
532
+ console.log('Close code:', event.code);
533
+ });
534
+
535
+ voiceSDK.on('error', (error) => {
536
+ console.error('Error:', error);
537
+ });</code></pre>
538
+
539
+ <h3>Recording Events</h3>
540
+ <pre><code>voiceSDK.on('recordingStarted', () => {
541
+ console.log('🎤 Recording started');
542
+ });
543
+
544
+ voiceSDK.on('recordingStopped', () => {
545
+ console.log('⏹️ Recording stopped');
546
+ });</code></pre>
547
+
548
+ <h3>Message Events</h3>
549
+ <pre><code>voiceSDK.on('message', (msg) => {
550
+ switch(msg.type) {
551
+ case 'agent_response':
552
+ console.log('Agent:', msg.agent_response);
553
+ break;
554
+ case 'transcription':
555
+ console.log('You said:', msg.text);
556
+ break;
557
+ // ... other message types
558
+ }
559
+ });</code></pre>
560
+
561
+ <h3>Audio Events</h3>
562
+ <pre><code>voiceSDK.on('playbackStarted', () => {
563
+ console.log('🔊 Audio playback started');
564
+ });
565
+
566
+ voiceSDK.on('playbackStopped', () => {
567
+ console.log('🔇 Audio playback stopped');
568
+ });
569
+
570
+ voiceSDK.on('audioData', (audioData) => {
571
+ // Raw audio data (Uint8Array)
572
+ });</code></pre>
573
+
574
+ <h3>Special Events</h3>
575
+ <pre><code>// Barge-in (user interrupts agent)
576
+ voiceSDK.on('bargeIn', (message) => {
577
+ console.log('User interrupted the agent');
578
+ });
579
+
580
+ // Greeting audio
581
+ voiceSDK.on('greetingStarted', () => {
582
+ console.log('Playing greeting message');
583
+ });
584
+
585
+ // Domain whitelist error
586
+ voiceSDK.on('domainError', (error) => {
587
+ console.error('Domain not whitelisted:', error.reason);
588
+ });</code></pre>
589
+ </section>
590
+
591
+ <!-- Voice & Chat Widget -->
592
+ <section id="text-chat-widget" class="doc-section">
593
+ <h1>Voice & Chat Widget</h1>
594
+ <p>Pre-built, customizable widget with voice and text chat - perfect for adding AI conversation to any website.</p>
595
+
596
+ <div class="feature-grid">
597
+ <div class="feature-card">
598
+ <div class="feature-icon">💬</div>
599
+ <h3>Voice & Text Chat</h3>
600
+ <p>Beautiful interface with voice recording, text chat, and message history</p>
601
+ </div>
602
+ <div class="feature-card">
603
+ <div class="feature-icon">🎨</div>
604
+ <h3>Fully Customizable</h3>
605
+ <p>Colors, position, size, RTL support, and custom branding</p>
606
+ </div>
607
+ <div class="feature-card">
608
+ <div class="feature-icon">📱</div>
609
+ <h3>Mobile Optimized</h3>
610
+ <p>Responsive design that works perfectly on all devices</p>
611
+ </div>
612
+ <div class="feature-card">
613
+ <div class="feature-icon">🌍</div>
614
+ <h3>Multi-language</h3>
615
+ <p>Built-in support for multiple languages with custom translations</p>
616
+ </div>
617
+ </div>
618
+
619
+ <h2>Installation</h2>
620
+ <pre><code>&lt;!-- Add the SDK script to your page --&gt;
621
+ &lt;script src="https://unpkg.com/ttp-agent-sdk/dist/agent-widget.js"&gt;&lt;/script&gt;
622
+
623
+ &lt;!-- Initialize the widget --&gt;
624
+ &lt;script&gt;
625
+ const widget = new TTPAgentSDK.TTPChatWidget({
626
+ agentId: 'agent_123',
627
+ appId: 'your_app_id'
628
+ });
629
+ &lt;/script&gt;</code></pre>
630
+
631
+ <h2>Basic Configuration</h2>
632
+ <pre><code>const widget = new TTPAgentSDK.TTPChatWidget({
633
+ // Required
634
+ agentId: 'agent_123', // Your AI agent ID
635
+ appId: 'your_app_id', // Your application ID
636
+
637
+ // Optional - Appearance
638
+ primaryColor: '#7C3AED', // Widget theme color
639
+ position: 'bottom-right', // 'bottom-right', 'bottom-left'
640
+ language: 'en', // 'en', 'es', 'fr', 'de', 'he', etc.
641
+ direction: 'ltr', // 'ltr' or 'rtl' for right-to-left languages
642
+
643
+ // Optional - Variables
644
+ variables: {
645
+ userName: 'John Doe',
646
+ page: 'homepage',
647
+ customData: 'value'
648
+ }
649
+ });</code></pre>
650
+
651
+ <h2>Advanced Customization</h2>
652
+
653
+ <h3>Icon Customization</h3>
654
+ <pre><code>const widget = new TTPAgentSDK.TTPChatWidget({
655
+ agentId: 'agent_123',
656
+ appId: 'your_app_id',
657
+
658
+ icon: {
659
+ type: 'custom', // 'default', 'emoji', or 'custom'
660
+ customImage: 'https://your-site.com/logo.png', // Custom image URL
661
+ size: 60, // Icon size in pixels
662
+ backgroundColor: '#FFFFFF', // Background color
663
+ borderRadius: '50%' // Border radius (50% for circle)
664
+ }
665
+ });</code></pre>
666
+
667
+ <h3>Chat Window Customization</h3>
668
+ <pre><code>const widget = new TTPAgentSDK.TTPChatWidget({
669
+ agentId: 'agent_123',
670
+ appId: 'your_app_id',
671
+
672
+ chatWindow: {
673
+ width: 400, // Width in pixels
674
+ height: 600, // Height in pixels
675
+ title: 'Chat with us!', // Custom title
676
+ subtitle: 'We reply instantly', // Custom subtitle
677
+ placeholder: 'Type here...', // Input placeholder
678
+ borderRadius: 12 // Window border radius
679
+ }
680
+ });</code></pre>
681
+
682
+ <h3>Branding</h3>
683
+ <pre><code>const widget = new TTPAgentSDK.TTPChatWidget({
684
+ agentId: 'agent_123',
685
+ appId: 'your_app_id',
686
+
687
+ branding: {
688
+ companyName: 'Your Company',
689
+ logo: 'https://your-site.com/logo.png',
690
+ showPoweredBy: false // Hide "Powered by TTP" footer
691
+ }
692
+ });</code></pre>
693
+
694
+ <h3>RTL (Right-to-Left) Support</h3>
695
+ <pre><code>// For Hebrew, Arabic, etc.
696
+ const widget = new TTPAgentSDK.TTPChatWidget({
697
+ agentId: 'agent_123',
698
+ appId: 'your_app_id',
699
+ direction: 'rtl',
700
+ language: 'he', // Hebrew
701
+ position: 'bottom-left' // Better for RTL
702
+ });</code></pre>
703
+
704
+ <h2>Widget Methods</h2>
705
+
706
+ <div class="method-card">
707
+ <h3><code>widget.open()</code></h3>
708
+ <p>Programmatically open the chat window.</p>
709
+ <pre><code>// Open chat from your own button
710
+ document.getElementById('myButton').onclick = () => {
711
+ widget.open();
712
+ };</code></pre>
713
+ </div>
714
+
715
+ <div class="method-card">
716
+ <h3><code>widget.close()</code></h3>
717
+ <p>Close the chat window.</p>
718
+ <pre><code>widget.close();</code></pre>
719
+ </div>
720
+
721
+ <div class="method-card">
722
+ <h3><code>widget.toggle()</code></h3>
723
+ <p>Toggle chat window open/closed.</p>
724
+ <pre><code>widget.toggle();</code></pre>
725
+ </div>
726
+
727
+ <div class="method-card">
728
+ <h3><code>widget.destroy()</code></h3>
729
+ <p>Remove the widget from the page.</p>
730
+ <pre><code>widget.destroy();</code></pre>
731
+ </div>
732
+
733
+ <div class="method-card">
734
+ <h3><code>widget.updateConfig(config)</code></h3>
735
+ <p>Update widget configuration dynamically.</p>
736
+ <pre><code>widget.updateConfig({
737
+ primaryColor: '#FF5733',
738
+ language: 'es'
739
+ });</code></pre>
740
+ </div>
741
+
742
+ <h2>Widget Events</h2>
743
+ <pre><code>const widget = new TTPAgentSDK.TTPChatWidget({
744
+ agentId: 'agent_123',
745
+ appId: 'your_app_id',
746
+
747
+ // Event callbacks
748
+ onOpen: () => {
749
+ console.log('Chat opened');
750
+ },
751
+
752
+ onClose: () => {
753
+ console.log('Chat closed');
754
+ },
755
+
756
+ onMessage: (message) => {
757
+ console.log('New message:', message);
758
+ },
759
+
760
+ onError: (error) => {
761
+ console.error('Widget error:', error);
762
+ },
763
+
764
+ onReady: () => {
765
+ console.log('Widget initialized');
766
+ }
767
+ });</code></pre>
768
+
769
+ <h2>Complete Example</h2>
770
+ <pre><code>&lt;!DOCTYPE html&gt;
771
+ &lt;html lang="en"&gt;
772
+ &lt;head&gt;
773
+ &lt;meta charset="UTF-8"&gt;
774
+ &lt;title&gt;My Website with AI Chat&lt;/title&gt;
775
+ &lt;/head&gt;
776
+ &lt;body&gt;
777
+ &lt;h1&gt;Welcome to my website!&lt;/h1&gt;
778
+
779
+ &lt;!-- Load the SDK --&gt;
780
+ &lt;script src="https://unpkg.com/ttp-agent-sdk/dist/agent-widget.js"&gt;&lt;/script&gt;
781
+
782
+ &lt;!-- Initialize widget --&gt;
783
+ &lt;script&gt;
784
+ const widget = new TTPAgentSDK.TTPChatWidget({
785
+ agentId: 'agent_123',
786
+ appId: 'your_app_id',
787
+
788
+ // Customize appearance
789
+ primaryColor: '#7C3AED',
790
+ position: 'bottom-right',
791
+ language: 'en',
792
+
793
+ // Custom branding
794
+ chatWindow: {
795
+ title: 'Chat with us!',
796
+ subtitle: 'We typically reply instantly'
797
+ },
798
+
799
+ // Pass context variables
800
+ variables: {
801
+ userName: 'Visitor',
802
+ page: window.location.pathname,
803
+ referrer: document.referrer
804
+ },
805
+
806
+ // Event handlers
807
+ onReady: () => {
808
+ console.log('Chat widget ready!');
809
+ },
810
+
811
+ onMessage: (message) => {
812
+ // Track messages in analytics
813
+ console.log('Message:', message);
814
+ }
815
+ });
816
+
817
+ // Optional: Open chat programmatically
818
+ // widget.open();
819
+ &lt;/script&gt;
820
+ &lt;/body&gt;
821
+ &lt;/html&gt;</code></pre>
822
+
823
+ <h2>Configuration Reference</h2>
824
+ <div class="info-box">
825
+ <p><strong>🎨 Extensive Customization</strong></p>
826
+ <p>The Voice & Chat Widget can be customized in almost every aspect - colors, text, icons, sizes, behaviors, and more!</p>
827
+ </div>
828
+
829
+ <p>See the <a href="../examples/test-text-chat.html" target="_blank">live demo</a> to experiment with all customization options interactively.</p>
830
+
831
+ <details open>
832
+ <summary><strong>Required Configuration</strong></summary>
833
+ <table class="properties-table">
834
+ <thead>
835
+ <tr>
836
+ <th>Property</th>
837
+ <th>Type</th>
838
+ <th>Description</th>
839
+ </tr>
840
+ </thead>
841
+ <tbody>
842
+ <tr>
843
+ <td><code>agentId</code></td>
844
+ <td>string</td>
845
+ <td>Your AI agent identifier</td>
846
+ </tr>
847
+ <tr>
848
+ <td><code>appId</code></td>
849
+ <td>string</td>
850
+ <td>Your application identifier</td>
851
+ </tr>
852
+ </tbody>
853
+ </table>
854
+ </details>
855
+
856
+ <details open>
857
+ <summary><strong>General Configuration</strong></summary>
858
+ <table class="properties-table">
859
+ <thead>
860
+ <tr>
861
+ <th>Property</th>
862
+ <th>Type</th>
863
+ <th>Default</th>
864
+ <th>Description</th>
865
+ </tr>
866
+ </thead>
867
+ <tbody>
868
+ <tr>
869
+ <td><code>primaryColor</code></td>
870
+ <td>string</td>
871
+ <td>'#7C3AED'</td>
872
+ <td>Main theme color (hex)</td>
873
+ </tr>
874
+ <tr>
875
+ <td><code>direction</code></td>
876
+ <td>string</td>
877
+ <td>'ltr'</td>
878
+ <td>'ltr' or 'rtl'</td>
879
+ </tr>
880
+ <tr>
881
+ <td><code>language</code></td>
882
+ <td>string</td>
883
+ <td>'en'</td>
884
+ <td>Language code (en, es, fr, de, he, ar, etc.)</td>
885
+ </tr>
886
+ <tr>
887
+ <td><code>variables</code></td>
888
+ <td>object</td>
889
+ <td>{}</td>
890
+ <td>Custom variables to pass to agent</td>
891
+ </tr>
892
+ <tr>
893
+ <td><code>customStyles</code></td>
894
+ <td>string</td>
895
+ <td>''</td>
896
+ <td>Custom CSS to inject</td>
897
+ </tr>
898
+ </tbody>
899
+ </table>
900
+ </details>
901
+
902
+ <details>
903
+ <summary><strong>Positioning</strong></summary>
904
+ <table class="properties-table">
905
+ <thead>
906
+ <tr>
907
+ <th>Property</th>
908
+ <th>Type</th>
909
+ <th>Default</th>
910
+ <th>Description</th>
911
+ </tr>
912
+ </thead>
913
+ <tbody>
914
+ <tr>
915
+ <td><code>position</code></td>
916
+ <td>string | object</td>
917
+ <td>'bottom-right'</td>
918
+ <td>String: 'bottom-right', 'bottom-left'. Object: { vertical, horizontal, offset }</td>
919
+ </tr>
920
+ <tr>
921
+ <td><code>position.vertical</code></td>
922
+ <td>string</td>
923
+ <td>'bottom'</td>
924
+ <td>'top' or 'bottom'</td>
925
+ </tr>
926
+ <tr>
927
+ <td><code>position.horizontal</code></td>
928
+ <td>string</td>
929
+ <td>'right'</td>
930
+ <td>'left' or 'right'</td>
931
+ </tr>
932
+ <tr>
933
+ <td><code>position.offset</code></td>
934
+ <td>object</td>
935
+ <td>{ x: 20, y: 20 }</td>
936
+ <td>Offset from edges (pixels)</td>
937
+ </tr>
938
+ </tbody>
939
+ </table>
940
+ </details>
941
+
942
+ <details>
943
+ <summary><strong>Icon & Button</strong></summary>
944
+ <table class="properties-table">
945
+ <thead>
946
+ <tr>
947
+ <th>Property</th>
948
+ <th>Type</th>
949
+ <th>Default</th>
950
+ <th>Description</th>
951
+ </tr>
952
+ </thead>
953
+ <tbody>
954
+ <tr>
955
+ <td><code>icon.type</code></td>
956
+ <td>string</td>
957
+ <td>'custom'</td>
958
+ <td>'microphone', 'custom', 'emoji', 'text'</td>
959
+ </tr>
960
+ <tr>
961
+ <td><code>icon.customImage</code></td>
962
+ <td>string</td>
963
+ <td>TTP logo</td>
964
+ <td>URL to custom icon image</td>
965
+ </tr>
966
+ <tr>
967
+ <td><code>icon.size</code></td>
968
+ <td>string</td>
969
+ <td>'medium'</td>
970
+ <td>'small', 'medium', 'large', 'xl'</td>
971
+ </tr>
972
+ <tr>
973
+ <td><code>icon.backgroundColor</code></td>
974
+ <td>string</td>
975
+ <td>'#FFFFFF'</td>
976
+ <td>Icon background color</td>
977
+ </tr>
978
+ <tr>
979
+ <td><code>button.size</code></td>
980
+ <td>string</td>
981
+ <td>'medium'</td>
982
+ <td>'small', 'medium', 'large'</td>
983
+ </tr>
984
+ <tr>
985
+ <td><code>button.shape</code></td>
986
+ <td>string</td>
987
+ <td>'circle'</td>
988
+ <td>'circle', 'rounded', 'square'</td>
989
+ </tr>
990
+ <tr>
991
+ <td><code>button.backgroundColor</code></td>
992
+ <td>string</td>
993
+ <td>primaryColor</td>
994
+ <td>Button background color</td>
995
+ </tr>
996
+ <tr>
997
+ <td><code>button.hoverColor</code></td>
998
+ <td>string</td>
999
+ <td>'#7C3AED'</td>
1000
+ <td>Button hover color</td>
1001
+ </tr>
1002
+ <tr>
1003
+ <td><code>button.shadow</code></td>
1004
+ <td>boolean</td>
1005
+ <td>true</td>
1006
+ <td>Enable button shadow</td>
1007
+ </tr>
1008
+ </tbody>
1009
+ </table>
1010
+ </details>
1011
+
1012
+ <details>
1013
+ <summary><strong>Panel & Header</strong></summary>
1014
+ <table class="properties-table">
1015
+ <thead>
1016
+ <tr>
1017
+ <th>Property</th>
1018
+ <th>Type</th>
1019
+ <th>Default</th>
1020
+ <th>Description</th>
1021
+ </tr>
1022
+ </thead>
1023
+ <tbody>
1024
+ <tr>
1025
+ <td><code>panel.width</code></td>
1026
+ <td>number</td>
1027
+ <td>350</td>
1028
+ <td>Panel width (pixels)</td>
1029
+ </tr>
1030
+ <tr>
1031
+ <td><code>panel.height</code></td>
1032
+ <td>number</td>
1033
+ <td>500</td>
1034
+ <td>Panel height (pixels)</td>
1035
+ </tr>
1036
+ <tr>
1037
+ <td><code>panel.borderRadius</code></td>
1038
+ <td>number</td>
1039
+ <td>12</td>
1040
+ <td>Border radius (pixels)</td>
1041
+ </tr>
1042
+ <tr>
1043
+ <td><code>panel.backgroundColor</code></td>
1044
+ <td>string</td>
1045
+ <td>'#FFFFFF'</td>
1046
+ <td>Panel background color</td>
1047
+ </tr>
1048
+ <tr>
1049
+ <td><code>header.title</code></td>
1050
+ <td>string</td>
1051
+ <td>'Chat Assistant'</td>
1052
+ <td>Header title text</td>
1053
+ </tr>
1054
+ <tr>
1055
+ <td><code>header.showTitle</code></td>
1056
+ <td>boolean</td>
1057
+ <td>true</td>
1058
+ <td>Show/hide header title</td>
1059
+ </tr>
1060
+ <tr>
1061
+ <td><code>header.backgroundColor</code></td>
1062
+ <td>string</td>
1063
+ <td>'#7C3AED'</td>
1064
+ <td>Header background color</td>
1065
+ </tr>
1066
+ <tr>
1067
+ <td><code>header.textColor</code></td>
1068
+ <td>string</td>
1069
+ <td>'#FFFFFF'</td>
1070
+ <td>Header text color</td>
1071
+ </tr>
1072
+ </tbody>
1073
+ </table>
1074
+ </details>
1075
+
1076
+ <details>
1077
+ <summary><strong>Messages & Chat</strong></summary>
1078
+ <table class="properties-table">
1079
+ <thead>
1080
+ <tr>
1081
+ <th>Property</th>
1082
+ <th>Type</th>
1083
+ <th>Default</th>
1084
+ <th>Description</th>
1085
+ </tr>
1086
+ </thead>
1087
+ <tbody>
1088
+ <tr>
1089
+ <td><code>messages.userBackgroundColor</code></td>
1090
+ <td>string</td>
1091
+ <td>'#E5E7EB'</td>
1092
+ <td>User message background</td>
1093
+ </tr>
1094
+ <tr>
1095
+ <td><code>messages.agentBackgroundColor</code></td>
1096
+ <td>string</td>
1097
+ <td>'#F3F4F6'</td>
1098
+ <td>Agent message background</td>
1099
+ </tr>
1100
+ <tr>
1101
+ <td><code>messages.systemBackgroundColor</code></td>
1102
+ <td>string</td>
1103
+ <td>'#DCFCE7'</td>
1104
+ <td>System message background</td>
1105
+ </tr>
1106
+ <tr>
1107
+ <td><code>messages.errorBackgroundColor</code></td>
1108
+ <td>string</td>
1109
+ <td>'#FEE2E2'</td>
1110
+ <td>Error message background</td>
1111
+ </tr>
1112
+ <tr>
1113
+ <td><code>messages.textColor</code></td>
1114
+ <td>string</td>
1115
+ <td>'#1F2937'</td>
1116
+ <td>Message text color</td>
1117
+ </tr>
1118
+ <tr>
1119
+ <td><code>messages.fontSize</code></td>
1120
+ <td>string</td>
1121
+ <td>'14px'</td>
1122
+ <td>Message font size</td>
1123
+ </tr>
1124
+ <tr>
1125
+ <td><code>messages.borderRadius</code></td>
1126
+ <td>number</td>
1127
+ <td>8</td>
1128
+ <td>Message bubble radius</td>
1129
+ </tr>
1130
+ <tr>
1131
+ <td><code>text.sendButtonColor</code></td>
1132
+ <td>string</td>
1133
+ <td>'#7C3AED'</td>
1134
+ <td>Send button color</td>
1135
+ </tr>
1136
+ <tr>
1137
+ <td><code>text.sendButtonHoverColor</code></td>
1138
+ <td>string</td>
1139
+ <td>'#6D28D9'</td>
1140
+ <td>Send button hover color</td>
1141
+ </tr>
1142
+ <tr>
1143
+ <td><code>text.sendButtonActiveColor</code></td>
1144
+ <td>string</td>
1145
+ <td>'#6D28D9'</td>
1146
+ <td>Send button active color</td>
1147
+ </tr>
1148
+ <tr>
1149
+ <td><code>text.sendButtonText</code></td>
1150
+ <td>string</td>
1151
+ <td>'➤'</td>
1152
+ <td>Send button text/icon</td>
1153
+ </tr>
1154
+ <tr>
1155
+ <td><code>text.sendButtonTextColor</code></td>
1156
+ <td>string</td>
1157
+ <td>'#FFFFFF'</td>
1158
+ <td>Send button text color</td>
1159
+ </tr>
1160
+ <tr>
1161
+ <td><code>text.sendButtonFontSize</code></td>
1162
+ <td>string</td>
1163
+ <td>'18px'</td>
1164
+ <td>Send button font size</td>
1165
+ </tr>
1166
+ <tr>
1167
+ <td><code>text.sendButtonFontWeight</code></td>
1168
+ <td>string</td>
1169
+ <td>'500'</td>
1170
+ <td>Send button font weight</td>
1171
+ </tr>
1172
+ <tr>
1173
+ <td><code>text.inputPlaceholder</code></td>
1174
+ <td>string</td>
1175
+ <td>'Type your message...'</td>
1176
+ <td>Input placeholder text</td>
1177
+ </tr>
1178
+ <tr>
1179
+ <td><code>text.inputBorderColor</code></td>
1180
+ <td>string</td>
1181
+ <td>'#E5E7EB'</td>
1182
+ <td>Input border color</td>
1183
+ </tr>
1184
+ <tr>
1185
+ <td><code>text.inputFocusColor</code></td>
1186
+ <td>string</td>
1187
+ <td>'#7C3AED'</td>
1188
+ <td>Input focus color</td>
1189
+ </tr>
1190
+ <tr>
1191
+ <td><code>text.inputBackgroundColor</code></td>
1192
+ <td>string</td>
1193
+ <td>'#FFFFFF'</td>
1194
+ <td>Input background color</td>
1195
+ </tr>
1196
+ <tr>
1197
+ <td><code>text.inputTextColor</code></td>
1198
+ <td>string</td>
1199
+ <td>'#1F2937'</td>
1200
+ <td>Input text color</td>
1201
+ </tr>
1202
+ <tr>
1203
+ <td><code>text.inputFontSize</code></td>
1204
+ <td>string</td>
1205
+ <td>'14px'</td>
1206
+ <td>Input font size</td>
1207
+ </tr>
1208
+ <tr>
1209
+ <td><code>text.inputBorderRadius</code></td>
1210
+ <td>number</td>
1211
+ <td>20</td>
1212
+ <td>Input border radius (pixels)</td>
1213
+ </tr>
1214
+ <tr>
1215
+ <td><code>text.inputPadding</code></td>
1216
+ <td>string</td>
1217
+ <td>'6px 14px'</td>
1218
+ <td>Input padding</td>
1219
+ </tr>
1220
+ </tbody>
1221
+ </table>
1222
+ </details>
1223
+
1224
+ <details>
1225
+ <summary><strong>Voice Configuration</strong></summary>
1226
+ <table class="properties-table">
1227
+ <thead>
1228
+ <tr>
1229
+ <th>Property</th>
1230
+ <th>Type</th>
1231
+ <th>Default</th>
1232
+ <th>Description</th>
1233
+ </tr>
1234
+ </thead>
1235
+ <tbody>
1236
+ <tr>
1237
+ <td><code>voice.micButtonColor</code></td>
1238
+ <td>string</td>
1239
+ <td>primaryColor</td>
1240
+ <td>Microphone button color (inside panel)</td>
1241
+ </tr>
1242
+ <tr>
1243
+ <td><code>voice.micButtonActiveColor</code></td>
1244
+ <td>string</td>
1245
+ <td>'#EF4444'</td>
1246
+ <td>Microphone button color when active</td>
1247
+ </tr>
1248
+ <tr>
1249
+ <td><code>voice.micButtonHint.text</code></td>
1250
+ <td>string</td>
1251
+ <td>'Click the button to start...'</td>
1252
+ <td>Hint text below mic button</td>
1253
+ </tr>
1254
+ <tr>
1255
+ <td><code>voice.micButtonHint.color</code></td>
1256
+ <td>string</td>
1257
+ <td>'#6B7280'</td>
1258
+ <td>Hint text color</td>
1259
+ </tr>
1260
+ <tr>
1261
+ <td><code>voice.avatarBackgroundColor</code></td>
1262
+ <td>string</td>
1263
+ <td>'#667eea'</td>
1264
+ <td>Voice avatar background</td>
1265
+ </tr>
1266
+ <tr>
1267
+ <td><code>voice.avatarActiveBackgroundColor</code></td>
1268
+ <td>string</td>
1269
+ <td>'#667eea'</td>
1270
+ <td>Avatar background when active</td>
1271
+ </tr>
1272
+ <tr>
1273
+ <td><code>voice.statusTitleColor</code></td>
1274
+ <td>string</td>
1275
+ <td>'#1e293b'</td>
1276
+ <td>Status title text color</td>
1277
+ </tr>
1278
+ <tr>
1279
+ <td><code>voice.statusSubtitleColor</code></td>
1280
+ <td>string</td>
1281
+ <td>'#64748b'</td>
1282
+ <td>Status subtitle text color</td>
1283
+ </tr>
1284
+ <tr>
1285
+ <td><code>voice.startCallButtonColor</code></td>
1286
+ <td>string</td>
1287
+ <td>'#667eea'</td>
1288
+ <td>Start call button color</td>
1289
+ </tr>
1290
+ <tr>
1291
+ <td><code>voice.startCallButtonTextColor</code></td>
1292
+ <td>string</td>
1293
+ <td>'#FFFFFF'</td>
1294
+ <td>Start call button text color</td>
1295
+ </tr>
1296
+ <tr>
1297
+ <td><code>voice.endCallButtonColor</code></td>
1298
+ <td>string</td>
1299
+ <td>'#ef4444'</td>
1300
+ <td>End call button color</td>
1301
+ </tr>
1302
+ <tr>
1303
+ <td><code>voice.transcriptBackgroundColor</code></td>
1304
+ <td>string</td>
1305
+ <td>'#FFFFFF'</td>
1306
+ <td>Transcript background</td>
1307
+ </tr>
1308
+ <tr>
1309
+ <td><code>voice.transcriptTextColor</code></td>
1310
+ <td>string</td>
1311
+ <td>'#1e293b'</td>
1312
+ <td>Transcript text color</td>
1313
+ </tr>
1314
+ <tr>
1315
+ <td><code>voice.transcriptLabelColor</code></td>
1316
+ <td>string</td>
1317
+ <td>'#94a3b8'</td>
1318
+ <td>Transcript label color</td>
1319
+ </tr>
1320
+ <tr>
1321
+ <td><code>voice.controlButtonColor</code></td>
1322
+ <td>string</td>
1323
+ <td>'#FFFFFF'</td>
1324
+ <td>Control button color</td>
1325
+ </tr>
1326
+ <tr>
1327
+ <td><code>voice.controlButtonSecondaryColor</code></td>
1328
+ <td>string</td>
1329
+ <td>'#64748b'</td>
1330
+ <td>Secondary control button color</td>
1331
+ </tr>
1332
+ <tr>
1333
+ <td><code>voice.language</code></td>
1334
+ <td>string</td>
1335
+ <td>'en'</td>
1336
+ <td>Voice language (overrides global)</td>
1337
+ </tr>
1338
+ </tbody>
1339
+ </table>
1340
+ </details>
1341
+
1342
+ <details>
1343
+ <summary><strong>Behavior</strong></summary>
1344
+ <table class="properties-table">
1345
+ <thead>
1346
+ <tr>
1347
+ <th>Property</th>
1348
+ <th>Type</th>
1349
+ <th>Default</th>
1350
+ <th>Description</th>
1351
+ </tr>
1352
+ </thead>
1353
+ <tbody>
1354
+ <tr>
1355
+ <td><code>behavior.mode</code></td>
1356
+ <td>string</td>
1357
+ <td>'unified'</td>
1358
+ <td>'unified' (both), 'voice-only', 'text-only'</td>
1359
+ </tr>
1360
+ <tr>
1361
+ <td><code>behavior.autoOpen</code></td>
1362
+ <td>boolean</td>
1363
+ <td>false</td>
1364
+ <td>Auto-open widget on page load</td>
1365
+ </tr>
1366
+ <tr>
1367
+ <td><code>behavior.startOpen</code></td>
1368
+ <td>boolean</td>
1369
+ <td>false</td>
1370
+ <td>Start with widget open</td>
1371
+ </tr>
1372
+ <tr>
1373
+ <td><code>behavior.hidden</code></td>
1374
+ <td>boolean</td>
1375
+ <td>false</td>
1376
+ <td>Hide the widget completely</td>
1377
+ </tr>
1378
+ <tr>
1379
+ <td><code>behavior.autoConnect</code></td>
1380
+ <td>boolean</td>
1381
+ <td>false</td>
1382
+ <td>Auto-connect on widget open</td>
1383
+ </tr>
1384
+ <tr>
1385
+ <td><code>behavior.showWelcomeMessage</code></td>
1386
+ <td>boolean</td>
1387
+ <td>true</td>
1388
+ <td>Show welcome message</td>
1389
+ </tr>
1390
+ <tr>
1391
+ <td><code>behavior.welcomeMessage</code></td>
1392
+ <td>string</td>
1393
+ <td>'Hello! How can I help...'</td>
1394
+ <td>Welcome message text</td>
1395
+ </tr>
1396
+ <tr>
1397
+ <td><code>behavior.enableVoiceMode</code></td>
1398
+ <td>boolean</td>
1399
+ <td>true</td>
1400
+ <td>Enable voice mode option (in unified mode)</td>
1401
+ </tr>
1402
+ </tbody>
1403
+ </table>
1404
+ </details>
1405
+
1406
+ <details>
1407
+ <summary><strong>Animation & Tooltips</strong></summary>
1408
+ <table class="properties-table">
1409
+ <thead>
1410
+ <tr>
1411
+ <th>Property</th>
1412
+ <th>Type</th>
1413
+ <th>Default</th>
1414
+ <th>Description</th>
1415
+ </tr>
1416
+ </thead>
1417
+ <tbody>
1418
+ <tr>
1419
+ <td><code>animation.enableHover</code></td>
1420
+ <td>boolean</td>
1421
+ <td>true</td>
1422
+ <td>Enable hover animations</td>
1423
+ </tr>
1424
+ <tr>
1425
+ <td><code>animation.enablePulse</code></td>
1426
+ <td>boolean</td>
1427
+ <td>true</td>
1428
+ <td>Enable pulse animations</td>
1429
+ </tr>
1430
+ <tr>
1431
+ <td><code>animation.enableSlide</code></td>
1432
+ <td>boolean</td>
1433
+ <td>true</td>
1434
+ <td>Enable slide animations</td>
1435
+ </tr>
1436
+ <tr>
1437
+ <td><code>animation.duration</code></td>
1438
+ <td>number</td>
1439
+ <td>0.3</td>
1440
+ <td>Animation duration (seconds)</td>
1441
+ </tr>
1442
+ <tr>
1443
+ <td><code>tooltips.newChat</code></td>
1444
+ <td>string</td>
1445
+ <td>Auto</td>
1446
+ <td>New chat button tooltip</td>
1447
+ </tr>
1448
+ <tr>
1449
+ <td><code>tooltips.back</code></td>
1450
+ <td>string</td>
1451
+ <td>Auto</td>
1452
+ <td>Back button tooltip</td>
1453
+ </tr>
1454
+ <tr>
1455
+ <td><code>tooltips.close</code></td>
1456
+ <td>string</td>
1457
+ <td>Auto</td>
1458
+ <td>Close button tooltip</td>
1459
+ </tr>
1460
+ <tr>
1461
+ <td><code>tooltips.mute</code></td>
1462
+ <td>string</td>
1463
+ <td>Auto</td>
1464
+ <td>Mute button tooltip</td>
1465
+ </tr>
1466
+ <tr>
1467
+ <td><code>tooltips.speaker</code></td>
1468
+ <td>string</td>
1469
+ <td>Auto</td>
1470
+ <td>Speaker button tooltip</td>
1471
+ </tr>
1472
+ <tr>
1473
+ <td><code>tooltips.endCall</code></td>
1474
+ <td>string</td>
1475
+ <td>Auto</td>
1476
+ <td>End call button tooltip</td>
1477
+ </tr>
1478
+ </tbody>
1479
+ </table>
1480
+ </details>
1481
+
1482
+ <details>
1483
+ <summary><strong>Landing Screen (Unified Mode)</strong></summary>
1484
+ <table class="properties-table">
1485
+ <thead>
1486
+ <tr>
1487
+ <th>Property</th>
1488
+ <th>Type</th>
1489
+ <th>Default</th>
1490
+ <th>Description</th>
1491
+ </tr>
1492
+ </thead>
1493
+ <tbody>
1494
+ <tr>
1495
+ <td><code>landing.backgroundColor</code></td>
1496
+ <td>string</td>
1497
+ <td>Gradient</td>
1498
+ <td>Landing screen background (color or gradient)</td>
1499
+ </tr>
1500
+ <tr>
1501
+ <td><code>landing.logo</code></td>
1502
+ <td>string</td>
1503
+ <td>'🤖'</td>
1504
+ <td>Landing screen logo (emoji or text)</td>
1505
+ </tr>
1506
+ <tr>
1507
+ <td><code>landing.title</code></td>
1508
+ <td>string</td>
1509
+ <td>null</td>
1510
+ <td>Landing screen title (null uses translation)</td>
1511
+ </tr>
1512
+ <tr>
1513
+ <td><code>landing.titleColor</code></td>
1514
+ <td>string</td>
1515
+ <td>'#1e293b'</td>
1516
+ <td>Landing title text color</td>
1517
+ </tr>
1518
+ <tr>
1519
+ <td><code>landing.modeCardBackgroundColor</code></td>
1520
+ <td>string</td>
1521
+ <td>'#FFFFFF'</td>
1522
+ <td>Mode selection card background</td>
1523
+ </tr>
1524
+ <tr>
1525
+ <td><code>landing.modeCardBorderColor</code></td>
1526
+ <td>string</td>
1527
+ <td>'#E2E8F0'</td>
1528
+ <td>Mode card border color</td>
1529
+ </tr>
1530
+ <tr>
1531
+ <td><code>landing.modeCardHoverBorderColor</code></td>
1532
+ <td>string</td>
1533
+ <td>header.backgroundColor</td>
1534
+ <td>Mode card border color on hover</td>
1535
+ </tr>
1536
+ <tr>
1537
+ <td><code>landing.modeCardIconBackgroundColor</code></td>
1538
+ <td>string</td>
1539
+ <td>header.backgroundColor</td>
1540
+ <td>Mode card icon background</td>
1541
+ </tr>
1542
+ <tr>
1543
+ <td><code>landing.modeCardTitleColor</code></td>
1544
+ <td>string</td>
1545
+ <td>'#111827'</td>
1546
+ <td>Mode card title text color</td>
1547
+ </tr>
1548
+ <tr>
1549
+ <td><code>landing.voiceCardIcon</code></td>
1550
+ <td>string</td>
1551
+ <td>'🎤'</td>
1552
+ <td>Voice mode card icon</td>
1553
+ </tr>
1554
+ <tr>
1555
+ <td><code>landing.textCardIcon</code></td>
1556
+ <td>string</td>
1557
+ <td>'💬'</td>
1558
+ <td>Text mode card icon</td>
1559
+ </tr>
1560
+ </tbody>
1561
+ </table>
1562
+ </details>
1563
+
1564
+ <details>
1565
+ <summary><strong>Advanced Configuration</strong></summary>
1566
+ <table class="properties-table">
1567
+ <thead>
1568
+ <tr>
1569
+ <th>Property</th>
1570
+ <th>Type</th>
1571
+ <th>Default</th>
1572
+ <th>Description</th>
1573
+ </tr>
1574
+ </thead>
1575
+ <tbody>
1576
+ <tr>
1577
+ <td><code>websocketUrl</code></td>
1578
+ <td>string</td>
1579
+ <td>Auto-detected</td>
1580
+ <td>Custom WebSocket URL for text chat</td>
1581
+ </tr>
1582
+ <tr>
1583
+ <td><code>voice.websocketUrl</code></td>
1584
+ <td>string</td>
1585
+ <td>Auto-detected</td>
1586
+ <td>Custom WebSocket URL for voice chat</td>
1587
+ </tr>
1588
+ <tr>
1589
+ <td><code>demo</code></td>
1590
+ <td>boolean</td>
1591
+ <td>true</td>
1592
+ <td>Enable demo mode</td>
1593
+ </tr>
1594
+ <tr>
1595
+ <td><code>panel.backdropFilter</code></td>
1596
+ <td>string</td>
1597
+ <td>null</td>
1598
+ <td>CSS backdrop filter (e.g., 'blur(10px)')</td>
1599
+ </tr>
1600
+ <tr>
1601
+ <td><code>panel.border</code></td>
1602
+ <td>string</td>
1603
+ <td>'1px solid rgba(0,0,0,0.1)'</td>
1604
+ <td>Panel border style</td>
1605
+ </tr>
1606
+ <tr>
1607
+ <td><code>button.shadowColor</code></td>
1608
+ <td>string</td>
1609
+ <td>'rgba(0,0,0,0.15)'</td>
1610
+ <td>Button shadow color</td>
1611
+ </tr>
1612
+ <tr>
1613
+ <td><code>icon.emoji</code></td>
1614
+ <td>string</td>
1615
+ <td>'🎤'</td>
1616
+ <td>Emoji when icon.type = 'emoji'</td>
1617
+ </tr>
1618
+ <tr>
1619
+ <td><code>icon.text</code></td>
1620
+ <td>string</td>
1621
+ <td>'AI'</td>
1622
+ <td>Text when icon.type = 'text'</td>
1623
+ </tr>
1624
+ <tr>
1625
+ <td><code>accessibility.ariaLabel</code></td>
1626
+ <td>string</td>
1627
+ <td>'Chat Assistant'</td>
1628
+ <td>ARIA label for the widget</td>
1629
+ </tr>
1630
+ <tr>
1631
+ <td><code>accessibility.ariaDescription</code></td>
1632
+ <td>string</td>
1633
+ <td>'Click to open chat assistant'</td>
1634
+ <td>ARIA description</td>
1635
+ </tr>
1636
+ <tr>
1637
+ <td><code>accessibility.keyboardNavigation</code></td>
1638
+ <td>boolean</td>
1639
+ <td>true</td>
1640
+ <td>Enable keyboard navigation</td>
1641
+ </tr>
1642
+ </tbody>
1643
+ </table>
1644
+ </details>
1645
+
1646
+ <div class="info-box" style="margin: 20px 0;">
1647
+ <p><strong>✅ Configuration Verified:</strong></p>
1648
+ <p>All configuration options listed above have been verified against the source code and are fully supported. The widget has 80+ customization options across 13 categories:</p>
1649
+ <ul style="margin: 10px 0 0 20px; columns: 2; column-gap: 20px;">
1650
+ <li>General (5 options)</li>
1651
+ <li>Positioning (4 options)</li>
1652
+ <li>Icon & Button (9 options)</li>
1653
+ <li>Panel & Header (8 options)</li>
1654
+ <li>Messages (7 options)</li>
1655
+ <li>Text Chat (13 options)</li>
1656
+ <li>Voice Interface (17 options)</li>
1657
+ <li>Landing Screen (11 options)</li>
1658
+ <li>Tooltips (6 options)</li>
1659
+ <li>Animations (4 options)</li>
1660
+ <li>Behavior (8 options)</li>
1661
+ <li>Accessibility (3 options)</li>
1662
+ <li>Advanced (11 options)</li>
1663
+ </ul>
1664
+ <p style="margin-top: 10px;">Experiment with all options interactively in the <a href="../examples/test-text-chat.html" target="_blank" style="color: inherit; text-decoration: underline;">live demo</a>.</p>
1665
+ </div>
1666
+
1667
+ <p style="margin-top: 20px;"><strong>📖 Tip:</strong> All configuration options support the spread operator (...), so you can pass additional custom properties that will be merged with defaults.</p>
1668
+
1669
+ <div class="info-box">
1670
+ <strong>🎮 Live Demo:</strong> Try the fully functional widget with customization options at <a href="../examples/test-text-chat.html" target="_blank">test-text-chat.html</a>
1671
+ </div>
1672
+
1673
+ <h2>Use Cases</h2>
1674
+ <div class="features">
138
1675
  <div class="feature">
139
- <h3>⚛️ React Components</h3>
140
- <p>Ready-to-use React components for modern applications</p>
1676
+ <h4>💼 Customer Support</h4>
1677
+ <p>Add 24/7 AI-powered support to your website</p>
141
1678
  </div>
142
1679
  <div class="feature">
143
- <h3>🌐 Vanilla JavaScript</h3>
144
- <p>Works with any JavaScript framework or vanilla JS</p>
1680
+ <h4>🛒 E-commerce</h4>
1681
+ <p>Help customers find products and answer questions</p>
145
1682
  </div>
146
1683
  <div class="feature">
147
- <h3>🔒 Multiple Auth Methods</h3>
148
- <p>Support for signed links and direct agent access</p>
1684
+ <h4>📚 Documentation</h4>
1685
+ <p>Provide interactive help for your docs</p>
149
1686
  </div>
150
1687
  <div class="feature">
151
- <h3>📱 Responsive Widget</h3>
152
- <p>Pre-built UI widget for quick integration</p>
1688
+ <h4>🎓 Education</h4>
1689
+ <p>Create AI tutors and learning assistants</p>
153
1690
  </div>
154
- </div>
155
- </div>
1691
+ </div>
1692
+ </section>
156
1693
 
157
- <div class="content">
158
- <div class="card">
159
- <h2>🚀 Quick Start</h2>
160
- <p>Get started with the pre-built widget in just a few lines of code.</p>
161
- <div class="code-block">
162
- &lt;script src="https://cdn.talktopc.com/agent-widget.js"&gt;&lt;/script&gt;
163
- &lt;script&gt;
164
- TTPAgentSDK.AgentWidget.init({
165
- agentId: 'your_agent_id',
166
- getSessionUrl: 'https://your-backend.com/api/get-session'
167
- });
168
- &lt;/script&gt;
169
- </div>
170
- <a href="examples/test-text-chat.html" class="demo-button">Try Widget Demo</a>
171
- </div>
1694
+ <!-- Vanilla JS Guide -->
1695
+ <section id="vanilla-js" class="doc-section">
1696
+ <h1>Vanilla JavaScript Guide</h1>
1697
+ <p>Use the SDK in any JavaScript application without frameworks.</p>
172
1698
 
173
- <div class="card">
174
- <h2>⚛️ React Integration</h2>
175
- <p>Use the VoiceButton component in your React applications.</p>
176
- <div class="code-block">
177
- import { VoiceButton } from 'ttp-agent-sdk';
1699
+ <h2>Complete Example</h2>
1700
+ <pre><code>import { VoiceSDK } from 'ttp-agent-sdk';
178
1701
 
179
- &lt;VoiceButton
180
- websocketUrl="wss://speech.talktopc.com/ws/conv"
181
- agentId="your_agent_id"
182
- appId="your_app_id"
183
- /&gt;
184
- </div>
185
- <a href="examples/react-example.html" class="demo-button">View React Example</a>
186
- </div>
1702
+ class VoiceAssistant {
1703
+ constructor() {
1704
+ this.sdk = null;
1705
+ this.isConnected = false;
1706
+ this.isRecording = false;
1707
+ }
1708
+
1709
+ async initialize(agentId, overrides = {}) {
1710
+ // Step 1: Get signed URL
1711
+ const signedUrl = await this.getSignedUrl(agentId);
1712
+
1713
+ // Step 2: Create SDK
1714
+ this.sdk = new VoiceSDK({
1715
+ websocketUrl: signedUrl,
1716
+ appId: 'your_app_id',
1717
+ agentId: agentId,
1718
+ agentSettingsOverride: overrides
1719
+ });
1720
+
1721
+ // Setup event listeners
1722
+ this.setupEventListeners();
1723
+
1724
+ // Connect
1725
+ await this.sdk.connect();
1726
+ }
1727
+
1728
+ setupEventListeners() {
1729
+ this.sdk.on('connected', () => {
1730
+ this.isConnected = true;
1731
+ this.updateUI('connected');
1732
+ });
1733
+
1734
+ this.sdk.on('disconnected', () => {
1735
+ this.isConnected = false;
1736
+ this.isRecording = false;
1737
+ this.updateUI('disconnected');
1738
+ });
1739
+
1740
+ this.sdk.on('recordingStarted', () => {
1741
+ this.isRecording = true;
1742
+ this.updateUI('recording');
1743
+ });
1744
+
1745
+ this.sdk.on('recordingStopped', () => {
1746
+ this.isRecording = false;
1747
+ this.updateUI('connected');
1748
+ });
1749
+
1750
+ this.sdk.on('message', (msg) => {
1751
+ if (msg.type === 'agent_response') {
1752
+ this.displayMessage('agent', msg.agent_response);
1753
+ }
1754
+ });
1755
+
1756
+ this.sdk.on('error', (error) => {
1757
+ this.handleError(error);
1758
+ });
1759
+ }
1760
+
1761
+ async getSignedUrl(agentId) {
1762
+ const response = await fetch('/api/get-voice-session', {
1763
+ method: 'POST',
1764
+ headers: {
1765
+ 'Content-Type': 'application/json'
1766
+ },
1767
+ body: JSON.stringify({
1768
+ agentId: agentId
1769
+ })
1770
+ });
1771
+
1772
+ const { signedUrl } = await response.json();
1773
+ return signedUrl;
1774
+ }
1775
+
1776
+ async toggleRecording() {
1777
+ if (!this.isConnected) return;
1778
+
1779
+ if (this.isRecording) {
1780
+ await this.sdk.stopRecording();
1781
+ } else {
1782
+ await this.sdk.startRecording();
1783
+ }
1784
+ }
1785
+
1786
+ disconnect() {
1787
+ if (this.sdk) {
1788
+ this.sdk.disconnect();
1789
+ this.sdk = null;
1790
+ }
1791
+ }
1792
+
1793
+ updateUI(state) {
1794
+ // Update your UI based on state
1795
+ }
1796
+
1797
+ displayMessage(role, text) {
1798
+ // Display message in your UI
1799
+ }
1800
+
1801
+ handleError(error) {
1802
+ // Handle errors
1803
+ }
1804
+ }
187
1805
 
188
- <div class="card">
189
- <h2>🌐 Vanilla JavaScript</h2>
190
- <p>Integrate with any JavaScript framework or vanilla JS.</p>
191
- <div class="code-block">
1806
+ // Usage
1807
+ const assistant = new VoiceAssistant();
1808
+
1809
+ await assistant.initialize('agent_123', {
1810
+ language: 'es',
1811
+ temperature: 0.9
1812
+ });</code></pre>
1813
+ </section>
1814
+
1815
+ <!-- React Guide -->
1816
+ <section id="react" class="doc-section">
1817
+ <h1>React Integration</h1>
1818
+ <p>Use the SDK in React applications with hooks and components.</p>
1819
+
1820
+ <h2>Using Hooks</h2>
1821
+ <pre><code>import React, { useState, useEffect, useRef } from 'react';
192
1822
  import { VoiceSDK } from 'ttp-agent-sdk';
193
1823
 
194
- const voiceSDK = new VoiceSDK({
195
- websocketUrl: 'wss://speech.talktopc.com/ws/conv',
196
- agentId: 'your_agent_id',
197
- appId: 'your_app_id'
198
- });
1824
+ function VoiceChat() {
1825
+ const [status, setStatus] = useState('disconnected');
1826
+ const [isRecording, setIsRecording] = useState(false);
1827
+ const [messages, setMessages] = useState([]);
1828
+ const sdkRef = useRef(null);
199
1829
 
200
- await voiceSDK.connect();
201
- </div>
202
- <a href="examples/vanilla-example.html" class="demo-button">Try Vanilla Demo</a>
203
- </div>
1830
+ // Initialize SDK
1831
+ useEffect(() => {
1832
+ async function initSDK() {
1833
+ // Get signed URL
1834
+ const response = await fetch('/api/get-voice-session', {
1835
+ method: 'POST',
1836
+ headers: {
1837
+ 'Content-Type': 'application/json'
1838
+ },
1839
+ body: JSON.stringify({
1840
+ agentId: 'agent_123'
1841
+ })
1842
+ });
1843
+
1844
+ const { signedUrl } = await response.json();
1845
+
1846
+ // Create SDK
1847
+ const sdk = new VoiceSDK({
1848
+ websocketUrl: signedUrl,
1849
+ appId: 'your_app_id',
1850
+ agentId: 'agent_123',
1851
+ agentSettingsOverride: {
1852
+ language: 'es',
1853
+ temperature: 0.9
1854
+ }
1855
+ });
1856
+
1857
+ // Event listeners
1858
+ sdk.on('connected', () => setStatus('connected'));
1859
+ sdk.on('disconnected', () => {
1860
+ setStatus('disconnected');
1861
+ setIsRecording(false);
1862
+ });
1863
+ sdk.on('recordingStarted', () => setIsRecording(true));
1864
+ sdk.on('recordingStopped', () => setIsRecording(false));
1865
+ sdk.on('message', (msg) => {
1866
+ if (msg.type === 'agent_response') {
1867
+ setMessages(prev => [
1868
+ ...prev,
1869
+ { role: 'agent', text: msg.agent_response }
1870
+ ]);
1871
+ }
1872
+ });
1873
+
1874
+ await sdk.connect();
1875
+ sdkRef.current = sdk;
1876
+ }
1877
+
1878
+ initSDK();
1879
+
1880
+ // Cleanup
1881
+ return () => {
1882
+ if (sdkRef.current) {
1883
+ sdkRef.current.disconnect();
1884
+ }
1885
+ };
1886
+ }, []);
1887
+
1888
+ const toggleRecording = async () => {
1889
+ if (sdkRef.current) {
1890
+ await sdkRef.current.toggleRecording();
1891
+ }
1892
+ };
1893
+
1894
+ return (
1895
+ &lt;div&gt;
1896
+ &lt;div&gt;Status: {status}&lt;/div&gt;
1897
+ &lt;button onClick={toggleRecording} disabled={status !== 'connected'}&gt;
1898
+ {isRecording ? 'Stop' : 'Start'} Recording
1899
+ &lt;/button&gt;
1900
+ &lt;div&gt;
1901
+ {messages.map((msg, i) => (
1902
+ &lt;div key={i}&gt;{msg.role}: {msg.text}&lt;/div&gt;
1903
+ ))}
1904
+ &lt;/div&gt;
1905
+ &lt;/div&gt;
1906
+ );
1907
+ }
1908
+
1909
+ export default VoiceChat;</code></pre>
1910
+ </section>
1911
+
1912
+ <!-- VoiceButton Component -->
1913
+ <section id="voice-button" class="doc-section">
1914
+ <h1>VoiceButton Component</h1>
1915
+ <p>Pre-built React component for quick integration.</p>
1916
+
1917
+ <h2>Installation</h2>
1918
+ <pre><code>import { VoiceButton } from 'ttp-agent-sdk/react';</code></pre>
1919
+
1920
+ <h2>Basic Usage</h2>
1921
+ <pre><code>import React, { useState, useEffect } from 'react';
1922
+ import { VoiceButton } from 'ttp-agent-sdk/react';
1923
+
1924
+ function App() {
1925
+ const [signedUrl, setSignedUrl] = useState(null);
1926
+
1927
+ useEffect(() => {
1928
+ async function fetchSignedUrl() {
1929
+ const response = await fetch('/api/get-voice-session', {
1930
+ method: 'POST',
1931
+ headers: {
1932
+ 'Content-Type': 'application/json'
1933
+ },
1934
+ body: JSON.stringify({
1935
+ agentId: 'agent_123'
1936
+ })
1937
+ });
1938
+
1939
+ const { signedUrl } = await response.json();
1940
+ setSignedUrl(signedUrl);
1941
+ }
1942
+
1943
+ fetchSignedUrl();
1944
+ }, []);
1945
+
1946
+ if (!signedUrl) return &lt;div&gt;Loading...&lt;/div&gt;;
1947
+
1948
+ return (
1949
+ &lt;VoiceButton
1950
+ websocketUrl={signedUrl}
1951
+ appId="your_app_id"
1952
+ agentId="agent_123"
1953
+ agentSettingsOverride={{
1954
+ language: 'es',
1955
+ temperature: 0.9
1956
+ }}
1957
+ onConnected={() => console.log('Connected')}
1958
+ onMessage={(msg) => console.log('Message:', msg)}
1959
+ onError={(error) => console.error('Error:', error)}
1960
+ /&gt;
1961
+ );
1962
+ }</code></pre>
1963
+
1964
+ <h2>Props</h2>
1965
+ <table class="properties-table">
1966
+ <thead>
1967
+ <tr>
1968
+ <th>Prop</th>
1969
+ <th>Type</th>
1970
+ <th>Required</th>
1971
+ <th>Description</th>
1972
+ </tr>
1973
+ </thead>
1974
+ <tbody>
1975
+ <tr>
1976
+ <td><code>websocketUrl</code></td>
1977
+ <td>string</td>
1978
+ <td>Yes</td>
1979
+ <td>Signed WebSocket URL</td>
1980
+ </tr>
1981
+ <tr>
1982
+ <td><code>appId</code></td>
1983
+ <td>string</td>
1984
+ <td>Yes</td>
1985
+ <td>Your application ID</td>
1986
+ </tr>
1987
+ <tr>
1988
+ <td><code>agentId</code></td>
1989
+ <td>string</td>
1990
+ <td>Yes</td>
1991
+ <td>The AI agent identifier</td>
1992
+ </tr>
1993
+ <tr>
1994
+ <td><code>agentSettingsOverride</code></td>
1995
+ <td>object</td>
1996
+ <td>No</td>
1997
+ <td>Custom agent settings</td>
1998
+ </tr>
1999
+ <tr>
2000
+ <td><code>voice</code></td>
2001
+ <td>string</td>
2002
+ <td>No</td>
2003
+ <td>Voice preset (default: 'default')</td>
2004
+ </tr>
2005
+ <tr>
2006
+ <td><code>language</code></td>
2007
+ <td>string</td>
2008
+ <td>No</td>
2009
+ <td>Language code (default: 'en')</td>
2010
+ </tr>
2011
+ <tr>
2012
+ <td><code>onConnected</code></td>
2013
+ <td>function</td>
2014
+ <td>No</td>
2015
+ <td>Connected callback</td>
2016
+ </tr>
2017
+ <tr>
2018
+ <td><code>onDisconnected</code></td>
2019
+ <td>function</td>
2020
+ <td>No</td>
2021
+ <td>Disconnected callback</td>
2022
+ </tr>
2023
+ <tr>
2024
+ <td><code>onMessage</code></td>
2025
+ <td>function</td>
2026
+ <td>No</td>
2027
+ <td>Message callback</td>
2028
+ </tr>
2029
+ <tr>
2030
+ <td><code>onError</code></td>
2031
+ <td>function</td>
2032
+ <td>No</td>
2033
+ <td>Error callback</td>
2034
+ </tr>
2035
+ </tbody>
2036
+ </table>
2037
+ </section>
2038
+
2039
+ <!-- VoiceSDK API -->
2040
+ <section id="voicesdk" class="doc-section">
2041
+ <h1>VoiceSDK Class</h1>
2042
+ <p>Core class for voice interaction functionality.</p>
204
2043
 
205
- <div class="card">
206
- <h2>📚 Documentation</h2>
207
- <p>Complete documentation and API reference for all features.</p>
208
- <ul style="color: #64748b; line-height: 1.8;">
209
- <li>Installation & Setup</li>
210
- <li>Authentication Methods</li>
211
- <li>Event Handling</li>
212
- <li>API Reference</li>
213
- <li>Examples & Tutorials</li>
2044
+ <h2>Constructor</h2>
2045
+ <pre><code>new VoiceSDK(config)</code></pre>
2046
+
2047
+ <h3>Configuration Object</h3>
2048
+ <table class="properties-table">
2049
+ <thead>
2050
+ <tr>
2051
+ <th>Property</th>
2052
+ <th>Type</th>
2053
+ <th>Required</th>
2054
+ <th>Description</th>
2055
+ </tr>
2056
+ </thead>
2057
+ <tbody>
2058
+ <tr>
2059
+ <td><code>websocketUrl</code></td>
2060
+ <td>string</td>
2061
+ <td>Yes</td>
2062
+ <td>Signed WebSocket URL from your backend</td>
2063
+ </tr>
2064
+ <tr>
2065
+ <td><code>appId</code></td>
2066
+ <td>string</td>
2067
+ <td>Yes</td>
2068
+ <td>Your application identifier</td>
2069
+ </tr>
2070
+ <tr>
2071
+ <td><code>agentId</code></td>
2072
+ <td>string</td>
2073
+ <td>Yes</td>
2074
+ <td>The AI agent identifier to connect to</td>
2075
+ </tr>
2076
+ <tr>
2077
+ <td><code>agentSettingsOverride</code></td>
2078
+ <td>object</td>
2079
+ <td>No</td>
2080
+ <td>Custom agent configuration</td>
2081
+ </tr>
2082
+ <tr>
2083
+ <td><code>voice</code></td>
2084
+ <td>string</td>
2085
+ <td>No</td>
2086
+ <td>Voice preset name (default: 'default')</td>
2087
+ </tr>
2088
+ <tr>
2089
+ <td><code>language</code></td>
2090
+ <td>string</td>
2091
+ <td>No</td>
2092
+ <td>Language code (default: 'en')</td>
2093
+ </tr>
2094
+ <tr>
2095
+ <td><code>sampleRate</code></td>
2096
+ <td>number</td>
2097
+ <td>No</td>
2098
+ <td>Audio sample rate (default: 16000)</td>
2099
+ </tr>
2100
+ <tr>
2101
+ <td><code>autoReconnect</code></td>
2102
+ <td>boolean</td>
2103
+ <td>No</td>
2104
+ <td>Auto-reconnect on disconnect (default: true)</td>
2105
+ </tr>
2106
+ </tbody>
2107
+ </table>
2108
+ </section>
2109
+
2110
+ <!-- Methods -->
2111
+ <section id="methods" class="doc-section">
2112
+ <h1>Methods</h1>
2113
+
2114
+ <div class="method-card">
2115
+ <h3><code>connect()</code></h3>
2116
+ <p>Connect to the voice agent.</p>
2117
+ <p><strong>Returns:</strong> <code>Promise&lt;boolean&gt;</code></p>
2118
+ <pre><code>await voiceSDK.connect();</code></pre>
2119
+ </div>
2120
+
2121
+ <div class="method-card">
2122
+ <h3><code>disconnect()</code></h3>
2123
+ <p>Disconnect from the voice agent.</p>
2124
+ <p><strong>Returns:</strong> <code>void</code></p>
2125
+ <pre><code>voiceSDK.disconnect();</code></pre>
2126
+ </div>
2127
+
2128
+ <div class="method-card">
2129
+ <h3><code>startRecording()</code></h3>
2130
+ <p>Start capturing and streaming audio.</p>
2131
+ <p><strong>Returns:</strong> <code>Promise&lt;boolean&gt;</code></p>
2132
+ <pre><code>await voiceSDK.startRecording();</code></pre>
2133
+ </div>
2134
+
2135
+ <div class="method-card">
2136
+ <h3><code>stopRecording()</code></h3>
2137
+ <p>Stop capturing audio.</p>
2138
+ <p><strong>Returns:</strong> <code>Promise&lt;boolean&gt;</code></p>
2139
+ <pre><code>await voiceSDK.stopRecording();</code></pre>
2140
+ </div>
2141
+
2142
+ <div class="method-card">
2143
+ <h3><code>toggleRecording()</code></h3>
2144
+ <p>Toggle recording state (start/stop).</p>
2145
+ <p><strong>Returns:</strong> <code>Promise&lt;boolean&gt;</code></p>
2146
+ <pre><code>await voiceSDK.toggleRecording();</code></pre>
2147
+ </div>
2148
+
2149
+ <div class="method-card">
2150
+ <h3><code>getStatus()</code></h3>
2151
+ <p>Get current connection and recording status.</p>
2152
+ <p><strong>Returns:</strong> <code>Object</code></p>
2153
+ <pre><code>const status = voiceSDK.getStatus();
2154
+ // Returns: { isConnected, isRecording, isPlaying }</code></pre>
2155
+ </div>
2156
+
2157
+ <div class="method-card">
2158
+ <h3><code>reconnect()</code></h3>
2159
+ <p>Manually reconnect to the agent.</p>
2160
+ <p><strong>Returns:</strong> <code>Promise&lt;boolean&gt;</code></p>
2161
+ <pre><code>await voiceSDK.reconnect();</code></pre>
2162
+ </div>
2163
+
2164
+ <div class="method-card">
2165
+ <h3><code>stopAudioPlayback()</code></h3>
2166
+ <p>Immediately stop audio playback (for barge-in).</p>
2167
+ <p><strong>Returns:</strong> <code>void</code></p>
2168
+ <pre><code>voiceSDK.stopAudioPlayback();</code></pre>
2169
+ </div>
2170
+
2171
+ <div class="method-card">
2172
+ <h3><code>on(event, callback)</code></h3>
2173
+ <p>Register an event listener.</p>
2174
+ <p><strong>Parameters:</strong></p>
2175
+ <ul>
2176
+ <li><code>event</code> (string) - Event name</li>
2177
+ <li><code>callback</code> (function) - Event handler</li>
214
2178
  </ul>
215
- <a href="README.md" class="demo-button">View Documentation</a>
216
- </div>
217
- </div>
2179
+ <pre><code>voiceSDK.on('connected', () => {
2180
+ console.log('Connected!');
2181
+ });</code></pre>
2182
+ </div>
218
2183
 
219
- <div class="footer">
220
- <p>Built with ❤️ by the TTP Agent Team</p>
221
- <p>Version 2.0.0 | <a href="https://github.com/yinon11/ttp-sdk-front" style="color: #4f46e5;">GitHub Repository</a></p>
222
- </div>
2184
+ <div class="method-card">
2185
+ <h3><code>destroy()</code></h3>
2186
+ <p>Cleanup all resources and disconnect.</p>
2187
+ <p><strong>Returns:</strong> <code>void</code></p>
2188
+ <pre><code>voiceSDK.destroy();</code></pre>
2189
+ </div>
2190
+ </section>
2191
+
2192
+ <!-- Events API -->
2193
+ <section id="events-api" class="doc-section">
2194
+ <h1>Events Reference</h1>
2195
+
2196
+ <table class="properties-table">
2197
+ <thead>
2198
+ <tr>
2199
+ <th>Event</th>
2200
+ <th>Parameters</th>
2201
+ <th>Description</th>
2202
+ </tr>
2203
+ </thead>
2204
+ <tbody>
2205
+ <tr>
2206
+ <td><code>connected</code></td>
2207
+ <td>-</td>
2208
+ <td>Emitted when successfully connected</td>
2209
+ </tr>
2210
+ <tr>
2211
+ <td><code>disconnected</code></td>
2212
+ <td><code>event</code></td>
2213
+ <td>Emitted when disconnected (includes reason)</td>
2214
+ </tr>
2215
+ <tr>
2216
+ <td><code>error</code></td>
2217
+ <td><code>error</code></td>
2218
+ <td>Emitted on errors</td>
2219
+ </tr>
2220
+ <tr>
2221
+ <td><code>recordingStarted</code></td>
2222
+ <td>-</td>
2223
+ <td>Emitted when recording starts</td>
2224
+ </tr>
2225
+ <tr>
2226
+ <td><code>recordingStopped</code></td>
2227
+ <td>-</td>
2228
+ <td>Emitted when recording stops</td>
2229
+ </tr>
2230
+ <tr>
2231
+ <td><code>message</code></td>
2232
+ <td><code>message</code></td>
2233
+ <td>Emitted for all WebSocket messages</td>
2234
+ </tr>
2235
+ <tr>
2236
+ <td><code>playbackStarted</code></td>
2237
+ <td>-</td>
2238
+ <td>Emitted when audio playback starts</td>
2239
+ </tr>
2240
+ <tr>
2241
+ <td><code>playbackStopped</code></td>
2242
+ <td>-</td>
2243
+ <td>Emitted when audio playback stops</td>
2244
+ </tr>
2245
+ <tr>
2246
+ <td><code>playbackError</code></td>
2247
+ <td><code>error</code></td>
2248
+ <td>Emitted on audio playback errors</td>
2249
+ </tr>
2250
+ <tr>
2251
+ <td><code>bargeIn</code></td>
2252
+ <td><code>message</code></td>
2253
+ <td>Emitted when user interrupts agent</td>
2254
+ </tr>
2255
+ <tr>
2256
+ <td><code>stopPlaying</code></td>
2257
+ <td><code>message</code></td>
2258
+ <td>Emitted when server requests to stop audio</td>
2259
+ </tr>
2260
+ <tr>
2261
+ <td><code>greetingStarted</code></td>
2262
+ <td>-</td>
2263
+ <td>Emitted when greeting audio starts</td>
2264
+ </tr>
2265
+ <tr>
2266
+ <td><code>domainError</code></td>
2267
+ <td><code>error</code></td>
2268
+ <td>Emitted when domain is not whitelisted</td>
2269
+ </tr>
2270
+ </tbody>
2271
+ </table>
2272
+ </section>
2273
+
2274
+ <!-- Configuration -->
2275
+ <section id="configuration" class="doc-section">
2276
+ <h1>Configuration Options</h1>
2277
+
2278
+ <h2>Agent Settings Override</h2>
2279
+ <p>Complete reference for all overridable settings:</p>
2280
+
2281
+ <h3>Core Settings</h3>
2282
+ <table class="properties-table">
2283
+ <thead>
2284
+ <tr>
2285
+ <th>Setting</th>
2286
+ <th>Type</th>
2287
+ <th>Range/Values</th>
2288
+ <th>Description</th>
2289
+ </tr>
2290
+ </thead>
2291
+ <tbody>
2292
+ <tr>
2293
+ <td><code>prompt</code></td>
2294
+ <td>string</td>
2295
+ <td>Any text</td>
2296
+ <td>System prompt/instructions for the agent</td>
2297
+ </tr>
2298
+ <tr>
2299
+ <td><code>temperature</code></td>
2300
+ <td>number</td>
2301
+ <td>0.0 - 2.0</td>
2302
+ <td>LLM creativity level</td>
2303
+ </tr>
2304
+ <tr>
2305
+ <td><code>maxTokens</code></td>
2306
+ <td>number</td>
2307
+ <td>1 - 4096</td>
2308
+ <td>Maximum tokens per response</td>
2309
+ </tr>
2310
+ <tr>
2311
+ <td><code>model</code></td>
2312
+ <td>string</td>
2313
+ <td>Model names</td>
2314
+ <td>LLM model to use</td>
2315
+ </tr>
2316
+ <tr>
2317
+ <td><code>language</code></td>
2318
+ <td>string</td>
2319
+ <td>ISO codes</td>
2320
+ <td>Response language (e.g., 'en', 'es', 'fr')</td>
2321
+ </tr>
2322
+ </tbody>
2323
+ </table>
2324
+
2325
+ <h3>Voice Settings</h3>
2326
+ <table class="properties-table">
2327
+ <thead>
2328
+ <tr>
2329
+ <th>Setting</th>
2330
+ <th>Type</th>
2331
+ <th>Range/Values</th>
2332
+ <th>Description</th>
2333
+ </tr>
2334
+ </thead>
2335
+ <tbody>
2336
+ <tr>
2337
+ <td><code>selectedVoice</code></td>
2338
+ <td>string</td>
2339
+ <td>Voice names</td>
2340
+ <td>Voice preset name</td>
2341
+ </tr>
2342
+ <tr>
2343
+ <td><code>voiceId</code></td>
2344
+ <td>string</td>
2345
+ <td>Voice IDs</td>
2346
+ <td>Specific voice identifier</td>
2347
+ </tr>
2348
+ <tr>
2349
+ <td><code>voiceSpeed</code></td>
2350
+ <td>number</td>
2351
+ <td>0.5 - 2.0</td>
2352
+ <td>Voice speed multiplier</td>
2353
+ </tr>
2354
+ </tbody>
2355
+ </table>
2356
+
2357
+ <h3>Behavior Settings</h3>
2358
+ <table class="properties-table">
2359
+ <thead>
2360
+ <tr>
2361
+ <th>Setting</th>
2362
+ <th>Type</th>
2363
+ <th>Range/Values</th>
2364
+ <th>Description</th>
2365
+ </tr>
2366
+ </thead>
2367
+ <tbody>
2368
+ <tr>
2369
+ <td><code>firstMessage</code></td>
2370
+ <td>string</td>
2371
+ <td>Any text</td>
2372
+ <td>Initial greeting message</td>
2373
+ </tr>
2374
+ <tr>
2375
+ <td><code>disableInterruptions</code></td>
2376
+ <td>boolean</td>
2377
+ <td>true/false</td>
2378
+ <td>Prevent user from interrupting agent</td>
2379
+ </tr>
2380
+ <tr>
2381
+ <td><code>autoDetectLanguage</code></td>
2382
+ <td>boolean</td>
2383
+ <td>true/false</td>
2384
+ <td>Automatically detect user's language</td>
2385
+ </tr>
2386
+ <tr>
2387
+ <td><code>maxCallDuration</code></td>
2388
+ <td>number</td>
2389
+ <td>Seconds</td>
2390
+ <td>Maximum session duration</td>
2391
+ </tr>
2392
+ </tbody>
2393
+ </table>
2394
+
2395
+ <h3>Advanced Settings</h3>
2396
+ <table class="properties-table">
2397
+ <thead>
2398
+ <tr>
2399
+ <th>Setting</th>
2400
+ <th>Type</th>
2401
+ <th>Range/Values</th>
2402
+ <th>Description</th>
2403
+ </tr>
2404
+ </thead>
2405
+ <tbody>
2406
+ <tr>
2407
+ <td><code>selectedTools</code></td>
2408
+ <td>array</td>
2409
+ <td>Tool names</td>
2410
+ <td>Array of enabled tool identifiers</td>
2411
+ </tr>
2412
+ <tr>
2413
+ <td><code>timezone</code></td>
2414
+ <td>string</td>
2415
+ <td>TZ names</td>
2416
+ <td>User timezone (e.g., 'America/New_York')</td>
2417
+ </tr>
2418
+ </tbody>
2419
+ </table>
2420
+ </section>
2421
+ </div>
2422
+
2423
+ <!-- Footer -->
2424
+ <footer class="doc-footer">
2425
+ <p>© 2024 TTP Agent SDK. Built with ❤️ for developers.</p>
2426
+ <p>
2427
+ <a href="https://github.com/your-org/ttp-agent-sdk" target="_blank">GitHub</a> ·
2428
+ <a href="../examples/test-text-chat.html" target="_blank">Live Demo</a> ·
2429
+ <a href="mailto:support@talktopc.com">Support</a>
2430
+ </p>
2431
+ </footer>
2432
+ </main>
2433
+ </div>
2434
+
2435
+ <script src="/script.js"></script>
223
2436
  </body>
224
2437
  </html>
2438
+
2439
+