@hamsa-ai/voice-agents-sdk 0.4.0-beta.1 → 0.4.0-beta.2

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/README.md CHANGED
@@ -40,7 +40,7 @@ Then, you can initialize the agent like this:
40
40
  const agent = new HamsaVoiceAgent("YOUR_API_KEY");
41
41
 
42
42
  agent.on("callStarted", () => {
43
- console.log("Conversation has started!");
43
+ console.log("Conversation has started!");
44
44
  });
45
45
 
46
46
  // Example: Start a call
@@ -55,11 +55,19 @@ Start a conversation with an existing agent by calling the "start" function. You
55
55
 
56
56
  ```javascript
57
57
  agent.start({
58
- agentId: YOUR_AGENT_ID,
59
- params: {
60
- param1: "NAME",
61
- param2: "NAME2",
62
- },
58
+ agentId: YOUR_AGENT_ID,
59
+ params: {
60
+ param1: "NAME",
61
+ param2: "NAME2",
62
+ },
63
+ voiceEnablement: true,
64
+ userId: "user-123", // Optional user tracking
65
+ preferHeadphonesForIosDevices: true, // iOS audio optimization
66
+ connectionDelay: {
67
+ android: 3000, // 3 second delay for Android
68
+ ios: 0,
69
+ default: 0,
70
+ },
63
71
  });
64
72
  ```
65
73
 
@@ -87,6 +95,135 @@ To end a conversation, simply call the "end" function:
87
95
  agent.end();
88
96
  ```
89
97
 
98
+ ## Advanced Audio Controls
99
+
100
+ The SDK provides comprehensive audio control features for professional voice applications:
101
+
102
+ ### Volume Management
103
+
104
+ ```javascript
105
+ // Set agent voice volume (0.0 to 1.0)
106
+ agent.setVolume(0.8);
107
+
108
+ // Get current output volume
109
+ const currentVolume = agent.getOutputVolume();
110
+ console.log(`Volume: ${Math.round(currentVolume * 100)}%`);
111
+
112
+ // Get user microphone input level
113
+ const inputLevel = agent.getInputVolume();
114
+ if (inputLevel > 0.1) {
115
+ showUserSpeakingIndicator();
116
+ }
117
+ ```
118
+
119
+ ### Microphone Control
120
+
121
+ ```javascript
122
+ // Mute/unmute microphone
123
+ agent.setMicMuted(true); // Mute
124
+ agent.setMicMuted(false); // Unmute
125
+
126
+ // Check mute status
127
+ if (agent.isMicMuted()) {
128
+ showUnmutePrompt();
129
+ }
130
+
131
+ // Toggle microphone
132
+ const currentMuted = agent.isMicMuted();
133
+ agent.setMicMuted(!currentMuted);
134
+
135
+ // Listen for microphone events
136
+ agent.on('micMuted', () => {
137
+ document.getElementById('micButton').classList.add('muted');
138
+ });
139
+
140
+ agent.on('micUnmuted', () => {
141
+ document.getElementById('micButton').classList.remove('muted');
142
+ });
143
+ ```
144
+
145
+ ### Audio Visualization
146
+
147
+ Create real-time audio visualizers using frequency data:
148
+
149
+ ```javascript
150
+ // Input visualizer (user's microphone)
151
+ function createInputVisualizer() {
152
+ const canvas = document.getElementById('inputVisualizer');
153
+ const ctx = canvas.getContext('2d');
154
+
155
+ function draw() {
156
+ const frequencyData = agent.getInputByteFrequencyData();
157
+
158
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
159
+ const barWidth = canvas.width / frequencyData.length;
160
+
161
+ for (let i = 0; i < frequencyData.length; i++) {
162
+ const barHeight = (frequencyData[i] / 255) * canvas.height;
163
+ ctx.fillStyle = `hsl(${i * 2}, 70%, 60%)`;
164
+ ctx.fillRect(i * barWidth, canvas.height - barHeight, barWidth, barHeight);
165
+ }
166
+
167
+ requestAnimationFrame(draw);
168
+ }
169
+
170
+ draw();
171
+ }
172
+
173
+ // Output visualizer (agent's voice)
174
+ function createOutputVisualizer() {
175
+ const canvas = document.getElementById('outputVisualizer');
176
+ const ctx = canvas.getContext('2d');
177
+
178
+ agent.on('speaking', () => {
179
+ function draw() {
180
+ const frequencyData = agent.getOutputByteFrequencyData();
181
+
182
+ if (frequencyData.length > 0) {
183
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
184
+
185
+ // Draw voice characteristics
186
+ for (let i = 0; i < frequencyData.length; i++) {
187
+ const barHeight = (frequencyData[i] / 255) * canvas.height;
188
+ ctx.fillStyle = `hsl(${240 + i}, 70%, 60%)`;
189
+ ctx.fillRect(i * 2, canvas.height - barHeight, 2, barHeight);
190
+ }
191
+
192
+ requestAnimationFrame(draw);
193
+ }
194
+ }
195
+ draw();
196
+ });
197
+ }
198
+ ```
199
+
200
+
201
+ ## Advanced Configuration Options
202
+
203
+ ### Platform-Specific Optimizations
204
+
205
+ ```javascript
206
+ agent.start({
207
+ agentId: "your-agent-id",
208
+
209
+ // Optimize audio for iOS devices
210
+ preferHeadphonesForIosDevices: true,
211
+
212
+ // Platform-specific delays to prevent audio cutoff
213
+ connectionDelay: {
214
+ android: 3000, // Android needs longer delay for audio mode switching
215
+ ios: 500, // Shorter delay for iOS
216
+ default: 1000 // Default for other platforms
217
+ },
218
+
219
+ // Disable wake lock for battery optimization
220
+ disableWakeLock: false,
221
+
222
+ // User tracking
223
+ userId: "customer-12345"
224
+ });
225
+ ```
226
+
90
227
  ## Events
91
228
 
92
229
  During the conversation, the SDK emits events to update your application about the conversation status.
@@ -95,16 +232,16 @@ During the conversation, the SDK emits events to update your application about t
95
232
 
96
233
  ```javascript
97
234
  agent.on("callStarted", () => {
98
- console.log("Conversation has started!");
235
+ console.log("Conversation has started!");
99
236
  });
100
237
  agent.on("callEnded", () => {
101
- console.log("Conversation has ended!");
238
+ console.log("Conversation has ended!");
102
239
  });
103
240
  agent.on("callPaused", () => {
104
- console.log("The conversation is paused");
241
+ console.log("The conversation is paused");
105
242
  });
106
243
  agent.on("callResumed", () => {
107
- console.log("Conversation has resumed");
244
+ console.log("Conversation has resumed");
108
245
  });
109
246
  ```
110
247
 
@@ -112,10 +249,10 @@ agent.on("callResumed", () => {
112
249
 
113
250
  ```javascript
114
251
  agent.on("speaking", () => {
115
- console.log("The agent is speaking");
252
+ console.log("The agent is speaking");
116
253
  });
117
254
  agent.on("listening", () => {
118
- console.log("The agent is listening");
255
+ console.log("The agent is listening");
119
256
  });
120
257
  ```
121
258
 
@@ -123,10 +260,10 @@ agent.on("listening", () => {
123
260
 
124
261
  ```javascript
125
262
  agent.on("transcriptionReceived", (text) => {
126
- console.log("User speech transcription received", text);
263
+ console.log("User speech transcription received", text);
127
264
  });
128
265
  agent.on("answerReceived", (text) => {
129
- console.log("Agent answer received", text);
266
+ console.log("Agent answer received", text);
130
267
  });
131
268
  ```
132
269
 
@@ -134,10 +271,10 @@ agent.on("answerReceived", (text) => {
134
271
 
135
272
  ```javascript
136
273
  agent.on("closed", () => {
137
- console.log("Conversation was closed");
274
+ console.log("Conversation was closed");
138
275
  });
139
276
  agent.on("error", (e) => {
140
- console.log("Error was received", e);
277
+ console.log("Error was received", e);
141
278
  });
142
279
  ```
143
280
 
@@ -148,46 +285,46 @@ The SDK provides comprehensive analytics for monitoring call quality, performanc
148
285
  ```javascript
149
286
  // Real-time connection quality updates
150
287
  agent.on("connectionQualityChanged", ({ quality, participant, metrics }) => {
151
- console.log(`Connection quality: ${quality}`, metrics);
288
+ console.log(`Connection quality: ${quality}`, metrics);
152
289
  });
153
290
 
154
291
  // Periodic analytics updates (every second during calls)
155
292
  agent.on("analyticsUpdated", (analytics) => {
156
- console.log("Call analytics:", analytics);
157
- // Contains: connectionStats, audioMetrics, performanceMetrics, etc.
293
+ console.log("Call analytics:", analytics);
294
+ // Contains: connectionStats, audioMetrics, performanceMetrics, etc.
158
295
  });
159
296
 
160
297
  // Participant events
161
298
  agent.on("participantConnected", (participant) => {
162
- console.log("Participant joined:", participant.identity);
299
+ console.log("Participant joined:", participant.identity);
163
300
  });
164
301
 
165
302
  agent.on("participantDisconnected", (participant) => {
166
- console.log("Participant left:", participant.identity);
303
+ console.log("Participant left:", participant.identity);
167
304
  });
168
305
 
169
306
  // Track subscription events (audio/video streams)
170
307
  agent.on("trackSubscribed", ({ track, participant, trackStats }) => {
171
- console.log("New track:", track.kind, "from", participant);
308
+ console.log("New track:", track.kind, "from", participant);
172
309
  });
173
310
 
174
311
  agent.on("trackUnsubscribed", ({ track, participant }) => {
175
- console.log("Track ended:", track.kind, "from", participant);
312
+ console.log("Track ended:", track.kind, "from", participant);
176
313
  });
177
314
 
178
315
  // Connection state changes
179
316
  agent.on("reconnecting", () => {
180
- console.log("Attempting to reconnect...");
317
+ console.log("Attempting to reconnect...");
181
318
  });
182
319
 
183
320
  agent.on("reconnected", () => {
184
- console.log("Successfully reconnected");
321
+ console.log("Successfully reconnected");
185
322
  });
186
323
 
187
324
  // Custom events from agents
188
325
  agent.on("customEvent", (eventType, eventData, metadata) => {
189
- console.log(`Custom event: ${eventType}`, eventData);
190
- // Examples: flow_navigation, tool_execution, agent_state_change
326
+ console.log(`Custom event: ${eventType}`, eventData);
327
+ // Examples: flow_navigation, tool_execution, agent_state_change
191
328
  });
192
329
  ```
193
330
 
@@ -195,6 +332,17 @@ agent.on("customEvent", (eventType, eventData, metadata) => {
195
332
 
196
333
  The SDK provides comprehensive real-time analytics for monitoring call quality, performance metrics, and custom agent events. Access analytics data through both synchronous methods and event-driven updates.
197
334
 
335
+ ### Analytics Architecture
336
+
337
+ The SDK uses a clean modular design with four specialized components:
338
+
339
+ - **Connection Management**: Handles room connections, participants, and network state
340
+ - **Analytics Engine**: Processes WebRTC statistics and performance metrics
341
+ - **Audio Management**: Manages audio tracks, volume control, and quality monitoring
342
+ - **Tool Registry**: Handles RPC method registration and client-side tool execution
343
+
344
+ Access analytics data through both synchronous methods and event-driven updates.
345
+
198
346
  ### Synchronous Analytics Methods
199
347
 
200
348
  Get real-time analytics data instantly for dashboards and monitoring:
@@ -278,16 +426,18 @@ const analytics = agent.getCallAnalytics();
278
426
  console.log(analytics);
279
427
  /*
280
428
  {
281
- callDuration: 60000,
282
- callStartTime: 1638360000000,
283
- isConnected: true,
284
- isPaused: false,
285
- connectionStats: { ... },
286
- audioMetrics: { ... },
287
- performanceMetrics: { ... },
288
- participants: [ ... ],
289
- trackStats: { ... },
290
- callStats: { ... }
429
+ connectionStats: { latency: 45, packetLoss: 0.1, quality: 'good', ... },
430
+ audioMetrics: { userAudioLevel: 0.8, agentAudioLevel: 0.3, ... },
431
+ performanceMetrics: { callDuration: 60000, responseTime: 1200, ... },
432
+ participants: [{ identity: 'agent', sid: 'participant-sid', ... }],
433
+ trackStats: { totalTracks: 2, activeTracks: 2, ... },
434
+ callStats: { connectionAttempts: 1, packetsLost: 0, ... },
435
+ metadata: {
436
+ callStartTime: 1638360000000,
437
+ isConnected: true,
438
+ isPaused: false,
439
+ volume: 1.0
440
+ }
291
441
  }
292
442
  */
293
443
  ```
@@ -299,25 +449,31 @@ Build live monitoring dashboards using the analytics data:
299
449
  ```javascript
300
450
  // Update dashboard every second
301
451
  const updateDashboard = () => {
302
- const stats = agent.getConnectionStats();
303
- const audio = agent.getAudioLevels();
304
- const performance = agent.getPerformanceMetrics();
305
-
306
- // Update UI elements
307
- document.getElementById('latency').textContent = `${stats.latency}ms`;
308
- document.getElementById('quality').textContent = stats.quality;
309
- document.getElementById('duration').textContent = `${Math.floor(performance.callDuration / 1000)}s`;
310
- document.getElementById('user-audio').style.width = `${audio.userAudioLevel * 100}%`;
311
- document.getElementById('agent-audio').style.width = `${audio.agentAudioLevel * 100}%`;
452
+ const stats = agent.getConnectionStats();
453
+ const audio = agent.getAudioLevels();
454
+ const performance = agent.getPerformanceMetrics();
455
+
456
+ // Update UI elements
457
+ document.getElementById("latency").textContent = `${stats.latency}ms`;
458
+ document.getElementById("quality").textContent = stats.quality;
459
+ document.getElementById("duration").textContent = `${Math.floor(
460
+ performance.callDuration / 1000
461
+ )}s`;
462
+ document.getElementById("user-audio").style.width = `${
463
+ audio.userAudioLevel * 100
464
+ }%`;
465
+ document.getElementById("agent-audio").style.width = `${
466
+ audio.agentAudioLevel * 100
467
+ }%`;
312
468
  };
313
469
 
314
470
  // Start dashboard updates when call begins
315
- agent.on('callStarted', () => {
316
- const dashboardInterval = setInterval(updateDashboard, 1000);
317
-
318
- agent.on('callEnded', () => {
319
- clearInterval(dashboardInterval);
320
- });
471
+ agent.on("callStarted", () => {
472
+ const dashboardInterval = setInterval(updateDashboard, 1000);
473
+
474
+ agent.on("callEnded", () => {
475
+ clearInterval(dashboardInterval);
476
+ });
321
477
  });
322
478
  ```
323
479
 
@@ -327,30 +483,40 @@ Track custom events from your voice agents:
327
483
 
328
484
  ```javascript
329
485
  agent.on("customEvent", (eventType, eventData, metadata) => {
330
- switch(eventType) {
331
- case "flow_navigation":
332
- console.log("Agent navigated:", eventData.from, "->", eventData.to);
333
- // Track conversation flow
334
- break;
335
-
336
- case "tool_execution":
337
- console.log("Tool called:", eventData.toolName, "Result:", eventData.success);
338
- // Monitor tool usage
339
- break;
340
-
341
- case "agent_state_change":
342
- console.log("Agent state:", eventData.state);
343
- // Track agent behavior
344
- break;
345
-
346
- case "user_intent_detected":
347
- console.log("User intent:", eventData.intent, "Confidence:", eventData.confidence);
348
- // Analyze user intent
349
- break;
350
-
351
- default:
352
- console.log("Custom event:", eventType, eventData);
353
- }
486
+ switch (eventType) {
487
+ case "flow_navigation":
488
+ console.log("Agent navigated:", eventData.from, "->", eventData.to);
489
+ // Track conversation flow
490
+ break;
491
+
492
+ case "tool_execution":
493
+ console.log(
494
+ "Tool called:",
495
+ eventData.toolName,
496
+ "Result:",
497
+ eventData.success
498
+ );
499
+ // Monitor tool usage
500
+ break;
501
+
502
+ case "agent_state_change":
503
+ console.log("Agent state:", eventData.state);
504
+ // Track agent behavior
505
+ break;
506
+
507
+ case "user_intent_detected":
508
+ console.log(
509
+ "User intent:",
510
+ eventData.intent,
511
+ "Confidence:",
512
+ eventData.confidence
513
+ );
514
+ // Analyze user intent
515
+ break;
516
+
517
+ default:
518
+ console.log("Custom event:", eventType, eventData);
519
+ }
354
520
  });
355
521
  ```
356
522
 
@@ -360,7 +526,7 @@ The SDK accepts optional configuration parameters:
360
526
 
361
527
  ```javascript
362
528
  const agent = new HamsaVoiceAgent("YOUR_API_KEY", {
363
- API_URL: "https://api.tryhamsa.com", // API endpoint (default)
529
+ API_URL: "https://api.tryhamsa.com", // API endpoint (default)
364
530
  });
365
531
  ```
366
532
 
@@ -370,29 +536,29 @@ You can register client-side tools that the agent can call during conversations:
370
536
 
371
537
  ```javascript
372
538
  const tools = [
373
- {
374
- function_name: "getUserInfo",
375
- description: "Get user information",
376
- parameters: [
377
- {
378
- name: "userId",
379
- type: "string",
380
- description: "User ID to look up",
381
- },
382
- ],
383
- required: ["userId"],
384
- fn: async (userId) => {
385
- // Your tool implementation
386
- const userInfo = await fetchUserInfo(userId);
387
- return userInfo;
388
- },
389
- },
539
+ {
540
+ function_name: "getUserInfo",
541
+ description: "Get user information",
542
+ parameters: [
543
+ {
544
+ name: "userId",
545
+ type: "string",
546
+ description: "User ID to look up",
547
+ },
548
+ ],
549
+ required: ["userId"],
550
+ fn: async (userId) => {
551
+ // Your tool implementation
552
+ const userInfo = await fetchUserInfo(userId);
553
+ return userInfo;
554
+ },
555
+ },
390
556
  ];
391
557
 
392
558
  agent.start({
393
- agentId: "YOUR_AGENT_ID",
394
- tools: tools,
395
- voiceEnablement: true,
559
+ agentId: "YOUR_AGENT_ID",
560
+ tools: tools,
561
+ voiceEnablement: true,
396
562
  });
397
563
  ```
398
564
 
@@ -404,69 +570,131 @@ If you're upgrading from a previous version, see the [Migration Guide](./MIGRATI
404
570
 
405
571
  This SDK supports modern browsers with WebRTC capabilities:
406
572
 
407
- - Chrome 60+
408
- - Firefox 60+
409
- - Safari 12+
410
- - Edge 79+
573
+ - Chrome 60+
574
+ - Firefox 60+
575
+ - Safari 12+
576
+ - Edge 79+
411
577
 
412
578
  ## TypeScript Support
413
579
 
414
580
  The SDK includes comprehensive TypeScript definitions with detailed analytics interfaces:
415
581
 
416
582
  ```typescript
417
- import { HamsaVoiceAgent } from "@hamsa-ai/voice-agents-sdk";
583
+ import {
584
+ HamsaVoiceAgent,
585
+ CallAnalyticsResult,
586
+ ParticipantData,
587
+ CustomEventMetadata,
588
+ } from "@hamsa-ai/voice-agents-sdk";
418
589
 
419
590
  // All analytics methods return strongly typed data
420
591
  const agent = new HamsaVoiceAgent("API_KEY");
421
592
 
422
- // TypeScript will provide autocomplete and type checking
423
- agent.on("analyticsUpdated", (analytics: CallAnalytics) => {
424
- console.log(analytics.connectionStats.latency); // number
425
- console.log(analytics.audioMetrics.userAudioLevel); // number
426
- console.log(analytics.performanceMetrics.callDuration); // number
593
+ // TypeScript will provide full autocomplete and type checking for all methods
594
+ const connectionStats = agent.getConnectionStats(); // ConnectionStatsResult | null
595
+ const audioLevels = agent.getAudioLevels(); // AudioLevelsResult | null
596
+ const performance = agent.getPerformanceMetrics(); // PerformanceMetricsResult | null
597
+ const participants = agent.getParticipants(); // ParticipantData[]
598
+ const trackStats = agent.getTrackStats(); // TrackStatsResult | null
599
+ const analytics = agent.getCallAnalytics(); // CallAnalyticsResult | null
600
+
601
+ // Advanced audio control methods
602
+ const outputVolume = agent.getOutputVolume(); // number
603
+ const inputVolume = agent.getInputVolume(); // number
604
+ const isMuted = agent.isMicMuted(); // boolean
605
+ const inputFreqData = agent.getInputByteFrequencyData(); // Uint8Array
606
+ const outputFreqData = agent.getOutputByteFrequencyData(); // Uint8Array
607
+
608
+ // Strongly typed start options with all advanced features
609
+ await agent.start({
610
+ agentId: "agent-id",
611
+ voiceEnablement: true,
612
+ userId: "user-123",
613
+ params: {
614
+ userName: "John Doe",
615
+ sessionId: "session-456"
616
+ },
617
+ preferHeadphonesForIosDevices: true,
618
+ connectionDelay: {
619
+ android: 3000,
620
+ ios: 500,
621
+ default: 1000
622
+ },
623
+ disableWakeLock: false
624
+ });
625
+
626
+ // Strongly typed event handlers
627
+ agent.on("analyticsUpdated", (analytics: CallAnalyticsResult) => {
628
+ console.log(analytics.connectionStats.latency); // number
629
+ console.log(analytics.audioMetrics.userAudioLevel); // number
630
+ console.log(analytics.performanceMetrics.callDuration); // number
631
+ console.log(analytics.participants.length); // number
632
+ });
633
+
634
+ // Audio control events
635
+ agent.on("micMuted", () => {
636
+ console.log("Microphone was muted");
637
+ });
638
+
639
+ agent.on("micUnmuted", () => {
640
+ console.log("Microphone was unmuted");
427
641
  });
428
642
 
429
643
  // Strongly typed custom events
430
- agent.on("customEvent", (eventType: string, eventData: any, metadata: CustomEventMetadata) => {
644
+ agent.on(
645
+ "customEvent",
646
+ (eventType: string, eventData: any, metadata: CustomEventMetadata) => {
431
647
  console.log(metadata.timestamp); // number
432
648
  console.log(metadata.participant); // string
649
+ }
650
+ );
651
+
652
+ // Strongly typed participant events
653
+ agent.on("participantConnected", (participant: ParticipantData) => {
654
+ console.log(participant.identity); // string
655
+ console.log(participant.connectionTime); // number
433
656
  });
434
657
  ```
435
658
 
436
659
  ## Use Cases
437
660
 
438
661
  ### Real-time Call Quality Monitoring
662
+
439
663
  ```javascript
440
664
  agent.on("connectionQualityChanged", ({ quality, metrics }) => {
441
- if (quality === 'poor') {
442
- showNetworkWarning();
443
- logQualityIssue(metrics);
444
- }
665
+ if (quality === "poor") {
666
+ showNetworkWarning();
667
+ logQualityIssue(metrics);
668
+ }
445
669
  });
446
670
  ```
447
671
 
448
672
  ### Analytics Dashboard
673
+
449
674
  ```javascript
450
675
  const analytics = agent.getCallAnalytics();
451
676
  sendToAnalytics({
452
- callDuration: analytics.callDuration,
453
- audioQuality: analytics.audioMetrics,
454
- participantCount: analytics.participants.length,
455
- performance: analytics.performanceMetrics
677
+ callDuration: analytics.callDuration,
678
+ audioQuality: analytics.audioMetrics,
679
+ participantCount: analytics.participants.length,
680
+ performance: analytics.performanceMetrics,
456
681
  });
457
682
  ```
458
683
 
459
684
  ### Conversation Flow Analysis
685
+
460
686
  ```javascript
461
687
  agent.on("customEvent", (eventType, data) => {
462
- if (eventType === "flow_navigation") {
463
- trackConversationFlow(data.from, data.to);
464
- optimizeAgentResponses(data);
465
- }
688
+ if (eventType === "flow_navigation") {
689
+ trackConversationFlow(data.from, data.to);
690
+ optimizeAgentResponses(data);
691
+ }
466
692
  });
467
693
  ```
468
694
 
469
695
  ## Dependencies
470
696
 
471
- - **livekit-client**: Real-time communication infrastructure
472
- - **events**: EventEmitter for browser compatibility
697
+ - **livekit-client v2.15.4**: Real-time communication infrastructure
698
+ - **events v3.3.0**: EventEmitter for browser compatibility
699
+
700
+ The SDK uses LiveKit's native WebRTC capabilities for high-quality real-time audio communication and comprehensive analytics.