ttp-agent-sdk 2.0.7 → 2.1.1

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.
@@ -0,0 +1,330 @@
1
+ # Enhanced AgentWidget - Complete Customization Guide
2
+
3
+ The `EnhancedAgentWidget` provides extensive customization options while maintaining sensible defaults. Users can customize icons, positioning, colors, animations, and much more.
4
+
5
+ ## Quick Start
6
+
7
+ ```javascript
8
+ import { EnhancedAgentWidget } from 'ttp-agent-sdk';
9
+
10
+ // Minimal configuration (uses all defaults)
11
+ new EnhancedAgentWidget({
12
+ agentId: 'your_agent_id',
13
+ getSessionUrl: async ({ agentId, variables }) => {
14
+ const response = await fetch('/api/get-session', {
15
+ method: 'POST',
16
+ headers: { 'Content-Type': 'application/json' },
17
+ body: JSON.stringify({ agentId, variables })
18
+ });
19
+ const data = await response.json();
20
+ return data.signedUrl;
21
+ }
22
+ });
23
+ ```
24
+
25
+ ## Complete Configuration Options
26
+
27
+ ### Required Configuration
28
+
29
+ ```javascript
30
+ {
31
+ agentId: 'your_agent_id', // Required: Your agent ID
32
+ getSessionUrl: async ({ agentId, variables }) => { ... } // Required: Function to get signed URL
33
+ }
34
+ ```
35
+
36
+ ### Icon/Image Configuration
37
+
38
+ ```javascript
39
+ {
40
+ icon: {
41
+ type: 'microphone', // 'microphone', 'custom', 'emoji', 'text'
42
+ customImage: 'https://example.com/icon.png', // URL for custom image
43
+ emoji: '🎤', // Emoji to display
44
+ text: 'AI', // Text to display
45
+ size: 'medium' // 'small', 'medium', 'large', 'xl'
46
+ }
47
+ }
48
+ ```
49
+
50
+ **Icon Examples:**
51
+ ```javascript
52
+ // Custom image
53
+ icon: { type: 'custom', customImage: 'https://example.com/my-logo.png' }
54
+
55
+ // Emoji
56
+ icon: { type: 'emoji', emoji: '🤖', size: 'large' }
57
+
58
+ // Text
59
+ icon: { type: 'text', text: 'HELP', size: 'small' }
60
+
61
+ // Default microphone
62
+ icon: { type: 'microphone' }
63
+ ```
64
+
65
+ ### Positioning Configuration
66
+
67
+ ```javascript
68
+ {
69
+ position: {
70
+ vertical: 'bottom', // 'top', 'bottom', 'center'
71
+ horizontal: 'right', // 'left', 'right', 'center'
72
+ offset: { x: 20, y: 20 } // Custom offset in pixels
73
+ }
74
+ }
75
+ ```
76
+
77
+ **Position Examples:**
78
+ ```javascript
79
+ // Top-left corner
80
+ position: { vertical: 'top', horizontal: 'left' }
81
+
82
+ // Center of screen
83
+ position: { vertical: 'center', horizontal: 'center' }
84
+
85
+ // Custom offset from bottom-right
86
+ position: {
87
+ vertical: 'bottom',
88
+ horizontal: 'right',
89
+ offset: { x: 50, y: 100 }
90
+ }
91
+ ```
92
+
93
+ ### Button Configuration
94
+
95
+ ```javascript
96
+ {
97
+ button: {
98
+ size: 'medium', // 'small', 'medium', 'large', 'xl'
99
+ shape: 'circle', // 'circle', 'square', 'rounded'
100
+ primaryColor: '#4F46E5', // Main button color
101
+ hoverColor: '#7C3AED', // Hover state color
102
+ activeColor: '#EF4444', // Active/recording color
103
+ shadow: true, // Enable shadow
104
+ shadowColor: 'rgba(0,0,0,0.15)' // Shadow color
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### Panel Configuration
110
+
111
+ ```javascript
112
+ {
113
+ panel: {
114
+ width: 350, // Panel width in pixels
115
+ height: 500, // Panel height in pixels
116
+ borderRadius: 12, // Border radius in pixels
117
+ backgroundColor: 'rgba(255,255,255,0.95)', // Panel background
118
+ backdropFilter: 'blur(10px)', // Backdrop filter effect
119
+ border: '1px solid rgba(0,0,0,0.1)' // Panel border
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### Header Configuration
125
+
126
+ ```javascript
127
+ {
128
+ header: {
129
+ title: 'Voice Assistant', // Header title
130
+ showTitle: true, // Show/hide title
131
+ backgroundColor: null, // null = uses button primaryColor
132
+ textColor: '#FFFFFF', // Header text color
133
+ showCloseButton: true // Show/hide close button
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Messages Configuration
139
+
140
+ ```javascript
141
+ {
142
+ messages: {
143
+ userBackgroundColor: '#E5E7EB', // User message background
144
+ agentBackgroundColor: '#F3F4F6', // Agent message background
145
+ systemBackgroundColor: '#DCFCE7', // System message background
146
+ errorBackgroundColor: '#FEE2E2', // Error message background
147
+ textColor: '#1F2937', // Text color
148
+ fontSize: '14px', // Font size
149
+ borderRadius: 8 // Message border radius
150
+ }
151
+ }
152
+ ```
153
+
154
+ ### Animation Configuration
155
+
156
+ ```javascript
157
+ {
158
+ animation: {
159
+ enableHover: true, // Enable hover animations
160
+ enablePulse: true, // Enable pulse animation when recording
161
+ enableSlide: true, // Enable slide animations
162
+ duration: 0.3 // Animation duration in seconds
163
+ }
164
+ }
165
+ ```
166
+
167
+ ### Behavior Configuration
168
+
169
+ ```javascript
170
+ {
171
+ behavior: {
172
+ autoOpen: false, // Auto-open panel on load
173
+ autoConnect: false, // Auto-connect on load
174
+ showWelcomeMessage: true, // Show welcome message
175
+ welcomeMessage: 'Hello! How can I help you today?' // Welcome message text
176
+ }
177
+ }
178
+ ```
179
+
180
+ ### Accessibility Configuration
181
+
182
+ ```javascript
183
+ {
184
+ accessibility: {
185
+ ariaLabel: 'Voice Assistant', // ARIA label for button
186
+ ariaDescription: 'Click to open voice assistant', // ARIA description
187
+ keyboardNavigation: true // Enable keyboard navigation (ESC to close)
188
+ }
189
+ }
190
+ ```
191
+
192
+ ### Custom CSS
193
+
194
+ ```javascript
195
+ {
196
+ customStyles: `
197
+ #enhanced-agent-widget {
198
+ /* Your custom CSS here */
199
+ }
200
+ `
201
+ }
202
+ ```
203
+
204
+ ## Complete Example
205
+
206
+ ```javascript
207
+ import { EnhancedAgentWidget } from 'ttp-agent-sdk';
208
+
209
+ const widget = new EnhancedAgentWidget({
210
+ // Required
211
+ agentId: 'my_agent_123',
212
+ getSessionUrl: async ({ agentId, variables }) => {
213
+ const response = await fetch('/api/get-session', {
214
+ method: 'POST',
215
+ headers: { 'Content-Type': 'application/json' },
216
+ body: JSON.stringify({ agentId, variables })
217
+ });
218
+ const data = await response.json();
219
+ return data.signedUrl;
220
+ },
221
+
222
+ // Custom icon (company logo)
223
+ icon: {
224
+ type: 'custom',
225
+ customImage: 'https://mycompany.com/logo.png',
226
+ size: 'large'
227
+ },
228
+
229
+ // Position in top-left
230
+ position: {
231
+ vertical: 'top',
232
+ horizontal: 'left',
233
+ offset: { x: 30, y: 30 }
234
+ },
235
+
236
+ // Brand colors
237
+ button: {
238
+ size: 'large',
239
+ shape: 'rounded',
240
+ primaryColor: '#FF6B35',
241
+ hoverColor: '#FF8C42',
242
+ activeColor: '#FF4444'
243
+ },
244
+
245
+ // Custom panel styling
246
+ panel: {
247
+ width: 400,
248
+ height: 600,
249
+ backgroundColor: 'rgba(255, 255, 255, 0.98)',
250
+ borderRadius: 20,
251
+ backdropFilter: 'blur(15px)'
252
+ },
253
+
254
+ // Custom header
255
+ header: {
256
+ title: 'My Company Assistant',
257
+ backgroundColor: '#FF6B35',
258
+ textColor: '#FFFFFF'
259
+ },
260
+
261
+ // Custom messages
262
+ messages: {
263
+ userBackgroundColor: '#FF6B35',
264
+ agentBackgroundColor: '#F0F0F0',
265
+ textColor: '#333333',
266
+ fontSize: '16px'
267
+ },
268
+
269
+ // Smooth animations
270
+ animation: {
271
+ enableHover: true,
272
+ enablePulse: true,
273
+ enableSlide: true,
274
+ duration: 0.4
275
+ },
276
+
277
+ // Auto-open for demo
278
+ behavior: {
279
+ autoOpen: true,
280
+ welcomeMessage: 'Welcome to My Company! How can I assist you?'
281
+ },
282
+
283
+ // Custom variables
284
+ variables: {
285
+ company: 'My Company',
286
+ page: 'homepage',
287
+ userType: 'visitor'
288
+ }
289
+ });
290
+ ```
291
+
292
+ ## Public API Methods
293
+
294
+ ```javascript
295
+ // Update configuration dynamically
296
+ widget.updateConfig({
297
+ button: { primaryColor: '#00FF00' },
298
+ position: { vertical: 'top' }
299
+ });
300
+
301
+ // Destroy the widget
302
+ widget.destroy();
303
+ ```
304
+
305
+ ## Migration from Original AgentWidget
306
+
307
+ The enhanced widget is fully backward compatible. Simply replace:
308
+
309
+ ```javascript
310
+ // Old
311
+ import { AgentWidget } from 'ttp-agent-sdk';
312
+ new AgentWidget({ ... });
313
+
314
+ // New
315
+ import { EnhancedAgentWidget } from 'ttp-agent-sdk';
316
+ new EnhancedAgentWidget({ ... });
317
+ ```
318
+
319
+ All existing configurations will work with sensible defaults applied.
320
+
321
+ ## Browser Support
322
+
323
+ - Chrome 66+
324
+ - Firefox 60+
325
+ - Safari 11.1+
326
+ - Edge 79+
327
+
328
+ ## License
329
+
330
+ MIT
@@ -0,0 +1,218 @@
1
+ # TTP Agent SDK - Signed Link Authentication Guide
2
+
3
+ ## 🔐 Understanding Signed Links
4
+
5
+ Signed links provide **secure, production-ready authentication** for your voice agents. Your **UI backend** generates secure, time-limited URLs that the widget uses to connect to the **conversation backend**.
6
+
7
+ ## 🏗️ Architecture Overview
8
+
9
+ ```
10
+ User's Frontend → User's Backend → TTP UI Backend → TTP Conversation Backend
11
+ ↓ ↓ ↓ ↓
12
+ Requests Requests Generates Handles
13
+ signed URL signed URL signed URL conversation
14
+ ↑ ↑ ↑ ↑
15
+ Receives Receives Returns Validates
16
+ signed URL signed URL signed URL signed token
17
+ ```
18
+
19
+ **The complete flow:**
20
+ 1. **User's Frontend** → requests signed URL from **User's Backend**
21
+ 2. **User's Backend** → requests signed URL from **TTP UI Backend** (`/api/public/agents`)
22
+ 3. **TTP UI Backend** → generates signed URL and returns to **User's Backend**
23
+ 4. **User's Backend** → returns signed URL to **User's Frontend**
24
+ 5. **User's Frontend** → connects directly to **TTP Conversation Backend** using signed URL
25
+
26
+ ## 🎯 Why Use Signed Links?
27
+
28
+ ### ❌ **Direct Agent ID (Insecure)**
29
+ ```javascript
30
+ // DON'T DO THIS IN PRODUCTION
31
+ new EnhancedAgentWidget({
32
+ agentId: 'agent_12345', // ❌ Visible in network traffic
33
+ websocketUrl: 'wss://speech.talktopc.com/ws/conv'
34
+ });
35
+ ```
36
+
37
+ **Problems:**
38
+ - Agent ID exposed in browser network tab
39
+ - No cost control
40
+ - No user-specific permissions
41
+ - Security risk
42
+
43
+ ### ✅ **Signed Link (Secure)**
44
+ ```javascript
45
+ // PRODUCTION-READY APPROACH
46
+ new EnhancedAgentWidget({
47
+ agentId: 'agent_12345',
48
+ getSessionUrl: async ({ agentId, variables }) => {
49
+ // User's Frontend calls User's Backend
50
+ const response = await fetch('/api/get-voice-session', {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ body: JSON.stringify({ agentId, variables })
54
+ });
55
+ const data = await response.json();
56
+ return data.signedUrl; // ✅ Secure, time-limited URL from TTP
57
+ }
58
+ });
59
+ ```
60
+
61
+ **Benefits:**
62
+ - ✅ Secure authentication
63
+ - ✅ Cost control per user
64
+ - ✅ User-specific permissions
65
+ - ✅ Time-limited access
66
+ - ✅ Production-ready
67
+
68
+ ## 🏗️ Implementation Guide
69
+
70
+ ### Step 1: User's Backend Implementation
71
+
72
+ Your user's backend should have an endpoint that requests signed URLs from TTP:
73
+
74
+ ```javascript
75
+ // User's Backend (Node.js example)
76
+ app.post('/api/get-voice-session', async (req, res) => {
77
+ try {
78
+ const { agentId, variables } = req.body;
79
+
80
+ // Validate user authentication
81
+ const user = await validateUser(req.headers.authorization);
82
+ if (!user) {
83
+ return res.status(401).json({ error: 'Unauthorized' });
84
+ }
85
+
86
+ // Request signed URL from TTP UI Backend
87
+ const ttpResponse = await fetch('https://backend.talktopc.com/api/public/agents', {
88
+ method: 'POST',
89
+ headers: {
90
+ 'Content-Type': 'application/json',
91
+ 'Authorization': `Bearer ${process.env.TTP_API_KEY}` // Your TTP API key
92
+ },
93
+ body: JSON.stringify({
94
+ agentId,
95
+ variables: {
96
+ ...variables,
97
+ userId: user.id,
98
+ userEmail: user.email
99
+ }
100
+ })
101
+ });
102
+
103
+ if (!ttpResponse.ok) {
104
+ throw new Error(`TTP API error: ${ttpResponse.status}`);
105
+ }
106
+
107
+ const ttpData = await ttpResponse.json();
108
+
109
+ // Return signed URL to user's frontend
110
+ res.json({
111
+ signedUrl: ttpData.signedUrl
112
+ });
113
+
114
+ } catch (error) {
115
+ console.error('Failed to get signed URL from TTP:', error);
116
+ res.status(500).json({ error: 'Failed to get voice session' });
117
+ }
118
+ });
119
+ ```
120
+
121
+ ### Step 2: User's Frontend Integration
122
+
123
+ ```javascript
124
+ import { EnhancedAgentWidget } from 'ttp-agent-sdk';
125
+
126
+ new EnhancedAgentWidget({
127
+ agentId: 'your_agent_id',
128
+
129
+ // User's Frontend calls User's Backend
130
+ getSessionUrl: async ({ agentId, variables }) => {
131
+ try {
132
+ const response = await fetch('/api/get-voice-session', {
133
+ method: 'POST',
134
+ headers: {
135
+ 'Content-Type': 'application/json',
136
+ 'Authorization': `Bearer ${getAuthToken()}` // User's auth token
137
+ },
138
+ body: JSON.stringify({
139
+ agentId,
140
+ variables: {
141
+ ...variables,
142
+ page: 'homepage',
143
+ userType: 'customer'
144
+ }
145
+ })
146
+ });
147
+
148
+ if (!response.ok) {
149
+ throw new Error(`Your backend responded with ${response.status}`);
150
+ }
151
+
152
+ const data = await response.json();
153
+ return data.signedUrl; // This connects directly to TTP Conversation Backend
154
+
155
+ } catch (error) {
156
+ console.error('Failed to get signed URL from your backend:', error);
157
+ throw error;
158
+ }
159
+ },
160
+
161
+ variables: {
162
+ page: 'homepage',
163
+ userType: 'customer',
164
+ language: 'en'
165
+ }
166
+ });
167
+ ```
168
+
169
+ ## 🔧 Your Current Implementation
170
+
171
+ Based on your setup, you're already using this pattern:
172
+
173
+ ```javascript
174
+ // Your current LandingPageWidget.jsx
175
+ getSessionUrl: async ({ agentId, variables }) => {
176
+ const response = await fetch(buildApiUrl('/api/landing/signed-url'), {
177
+ method: 'POST',
178
+ headers: { 'Content-Type': 'application/json' },
179
+ body: JSON.stringify({
180
+ agentId: agentId,
181
+ variables: variables,
182
+ page: 'landing',
183
+ userType: 'visitor'
184
+ })
185
+ });
186
+
187
+ const data = await response.json();
188
+ return data.signedUrl; // This connects to conversation backend
189
+ }
190
+ ```
191
+
192
+ ## 🎯 Key Points
193
+
194
+ 1. **UI Backend** (`/api/landing/signed-url`):
195
+ - Handles authentication
196
+ - Generates signed URLs
197
+ - Manages user permissions
198
+ - Controls costs
199
+
200
+ 2. **Conversation Backend** (`wss://speech.talktopc.com/ws/conv`):
201
+ - Validates signed tokens
202
+ - Handles voice conversations
203
+ - Processes audio streams
204
+
205
+ 3. **Frontend Widget**:
206
+ - Requests signed URL from UI backend
207
+ - Connects to conversation backend using signed URL
208
+ - Never exposes agent IDs directly
209
+
210
+ ## 🚀 Production Benefits
211
+
212
+ - **Security**: Agent IDs never exposed in frontend
213
+ - **Separation**: UI logic separate from conversation logic
214
+ - **Scalability**: Each backend can scale independently
215
+ - **Control**: UI backend controls access and permissions
216
+ - **Monitoring**: Track usage and costs at UI backend level
217
+
218
+ This architecture ensures your voice agents are secure, scalable, and production-ready! 🎤✨