@hamsa-ai/voice-agents-sdk 0.4.0-beta.9 → 0.4.1-beta.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.
- package/README.md +6 -9
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -2
- package/types/classes/livekit-analytics.d.ts +61 -3
- package/types/classes/livekit-manager.d.ts +5 -5
- package/types/classes/livekit-tool-registry.d.ts +1 -66
- package/types/classes/types.d.ts +11 -23
- package/types/main.d.ts +74 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hamsa-ai/voice-agents-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1-beta.1",
|
|
4
4
|
"description": "Hamsa AI - Voice Agents JavaScript SDK",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"build": "npm run clean && npm run build:types && npm run build:rollup",
|
|
27
27
|
"test": "jest",
|
|
28
28
|
"test:watch": "jest --watch",
|
|
29
|
-
"prepare": "npm run build"
|
|
29
|
+
"prepare": "npm run build",
|
|
30
|
+
"tag:push": "VERSION=$(node -p \"require('./package.json').version\") && TAG=v$VERSION && git fetch --tags -q && if git rev-parse -q --verify \"refs/tags/$TAG\" >/dev/null; then echo \"Tag $TAG already exists locally.\"; else git tag -a \"$TAG\" -m \"Release $TAG\"; fi && if git ls-remote --exit-code --tags origin \"$TAG\" >/dev/null 2>&1; then echo \"Tag $TAG already exists on origin.\"; else git push origin \"$TAG\"; fi && echo \"Done: $TAG\""
|
|
30
31
|
},
|
|
31
32
|
"author": "Hamsa AI Inc.",
|
|
32
33
|
"license": "MIT",
|
|
@@ -166,6 +166,22 @@ export declare class LiveKitAnalytics extends EventEmitter {
|
|
|
166
166
|
private room;
|
|
167
167
|
/** Current connection state flag for controlling analytics collection */
|
|
168
168
|
private isConnected;
|
|
169
|
+
/** Last recorded user audio level for dropout detection */
|
|
170
|
+
private lastUserAudioLevel;
|
|
171
|
+
/** Last recorded agent audio level for dropout detection */
|
|
172
|
+
private lastAgentAudioLevel;
|
|
173
|
+
/** Timestamp when user audio level dropped below threshold */
|
|
174
|
+
private userDropoutStartTime;
|
|
175
|
+
/** Timestamp when agent audio level dropped below threshold */
|
|
176
|
+
private agentDropoutStartTime;
|
|
177
|
+
/** Timestamp when user started speaking (VAD-based) */
|
|
178
|
+
private vadUserSpeakStart;
|
|
179
|
+
/** Timestamp when agent started speaking (VAD-based) */
|
|
180
|
+
private vadAgentSpeakStart;
|
|
181
|
+
/** Timestamp when user input was detected (for response time measurement) */
|
|
182
|
+
private lastUserInputTime;
|
|
183
|
+
/** Previous connection quality for jitter change detection (internal) */
|
|
184
|
+
private previousConnectionQuality;
|
|
169
185
|
/**
|
|
170
186
|
* Creates a new LiveKitAnalytics instance
|
|
171
187
|
*
|
|
@@ -346,7 +362,7 @@ export declare class LiveKitAnalytics extends EventEmitter {
|
|
|
346
362
|
*/
|
|
347
363
|
handleAudioPlaybackChanged(playing: boolean): void;
|
|
348
364
|
/**
|
|
349
|
-
* Gets current connection statistics
|
|
365
|
+
* Gets current connection statistics (customer-facing - verified data only)
|
|
350
366
|
*/
|
|
351
367
|
getConnectionStats(): ConnectionStatsResult;
|
|
352
368
|
/**
|
|
@@ -354,15 +370,57 @@ export declare class LiveKitAnalytics extends EventEmitter {
|
|
|
354
370
|
*/
|
|
355
371
|
getAudioLevels(): AudioLevelsResult;
|
|
356
372
|
/**
|
|
357
|
-
* Gets current performance metrics
|
|
373
|
+
* Gets current performance metrics (customer-facing - verified data only)
|
|
358
374
|
*/
|
|
359
375
|
getPerformanceMetrics(): PerformanceMetricsResult;
|
|
360
376
|
/**
|
|
361
|
-
*
|
|
377
|
+
* Manually records response time for agent interactions
|
|
378
|
+
*
|
|
379
|
+
* @param responseTime - Response time in milliseconds
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```typescript
|
|
383
|
+
* // Record custom response time measurement
|
|
384
|
+
* const startTime = Date.now();
|
|
385
|
+
* // ... agent processing ...
|
|
386
|
+
* const responseTime = Date.now() - startTime;
|
|
387
|
+
* analytics.recordResponseTime(responseTime);
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
recordResponseTime(responseTime: number): void;
|
|
391
|
+
/**
|
|
392
|
+
* Gets current voice activity detection thresholds
|
|
393
|
+
*/
|
|
394
|
+
getVADSettings(): {
|
|
395
|
+
audioThreshold: number;
|
|
396
|
+
minSpeakingDuration: number;
|
|
397
|
+
dropoutThreshold: number;
|
|
398
|
+
dropoutDetectionDuration: number;
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Gets comprehensive call analytics (customer-facing - verified data only)
|
|
362
402
|
*/
|
|
363
403
|
getCallAnalytics(participants: ParticipantData[], trackStats: TrackStatsResult, volume: number, isPaused: boolean): CallAnalyticsResult & {
|
|
364
404
|
callDuration: number;
|
|
365
405
|
};
|
|
406
|
+
/**
|
|
407
|
+
* Gets full connection statistics including estimated metrics (internal use only)
|
|
408
|
+
* @internal
|
|
409
|
+
*/
|
|
410
|
+
getInternalConnectionStats(): ConnectionMetrics & {
|
|
411
|
+
connectionAttempts: number;
|
|
412
|
+
reconnectionAttempts: number;
|
|
413
|
+
connectionEstablishedTime: number;
|
|
414
|
+
isConnected: boolean;
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Gets full performance metrics including estimated network latency (internal use only)
|
|
418
|
+
* @internal
|
|
419
|
+
*/
|
|
420
|
+
getInternalPerformanceMetrics(): PerformanceMetrics & {
|
|
421
|
+
callDuration: number;
|
|
422
|
+
averageResponseTime: number;
|
|
423
|
+
};
|
|
366
424
|
/**
|
|
367
425
|
* Cleans up analytics resources
|
|
368
426
|
*/
|
|
@@ -314,14 +314,14 @@ export default class LiveKitManager extends EventEmitter {
|
|
|
314
314
|
/**
|
|
315
315
|
* Retrieves current network connection statistics and quality metrics
|
|
316
316
|
*
|
|
317
|
-
* @returns Object containing
|
|
317
|
+
* @returns Object containing connection quality, connection counts, and timing data
|
|
318
318
|
*
|
|
319
319
|
* @example
|
|
320
320
|
* ```typescript
|
|
321
321
|
* const stats = manager.getConnectionStats();
|
|
322
|
-
* console.log(`Latency: ${stats.latency}ms`);
|
|
323
|
-
* console.log(`Packet loss: ${stats.packetLoss}%`);
|
|
324
322
|
* console.log(`Connection quality: ${stats.quality}`);
|
|
323
|
+
* console.log(`Connection attempts: ${stats.connectionAttempts}`);
|
|
324
|
+
* console.log(`Reconnections: ${stats.reconnectionAttempts}`);
|
|
325
325
|
*
|
|
326
326
|
* if (stats.quality === 'poor') {
|
|
327
327
|
* showNetworkWarning();
|
|
@@ -354,7 +354,7 @@ export default class LiveKitManager extends EventEmitter {
|
|
|
354
354
|
/**
|
|
355
355
|
* Retrieves current performance metrics including response times and call duration
|
|
356
356
|
*
|
|
357
|
-
* @returns Object containing response times,
|
|
357
|
+
* @returns Object containing response times, call duration, and connection timing
|
|
358
358
|
*
|
|
359
359
|
* @example
|
|
360
360
|
* ```typescript
|
|
@@ -442,7 +442,7 @@ export default class LiveKitManager extends EventEmitter {
|
|
|
442
442
|
* });
|
|
443
443
|
*
|
|
444
444
|
* // Check for quality issues
|
|
445
|
-
* if (analytics.connectionStats.
|
|
445
|
+
* if (analytics.connectionStats.quality === 'poor') {
|
|
446
446
|
* reportNetworkIssue(analytics.connectionStats);
|
|
447
447
|
* }
|
|
448
448
|
* ```
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
* - Includes automatic cleanup and resource management
|
|
179
179
|
*/
|
|
180
180
|
import { EventEmitter } from 'events';
|
|
181
|
-
import {
|
|
181
|
+
import type { Room } from 'livekit-client';
|
|
182
182
|
import type { Tool } from './types';
|
|
183
183
|
/**
|
|
184
184
|
* LiveKitToolRegistry class for client-side tool management and RPC handling
|
|
@@ -445,71 +445,6 @@ export declare class LiveKitToolRegistry extends EventEmitter {
|
|
|
445
445
|
text?: string;
|
|
446
446
|
final?: boolean;
|
|
447
447
|
}>): void;
|
|
448
|
-
/**
|
|
449
|
-
* Provides access to the local microphone audio stream for external processing
|
|
450
|
-
*
|
|
451
|
-
* Retrieves the local participant's microphone track and creates a MediaStream
|
|
452
|
-
* for external audio processing applications. This enables advanced integrations
|
|
453
|
-
* such as real-time audio analysis, recording, or additional audio effects
|
|
454
|
-
* processing outside of the LiveKit pipeline.
|
|
455
|
-
*
|
|
456
|
-
* @fires localAudioStreamAvailable When local audio stream is successfully extracted
|
|
457
|
-
*
|
|
458
|
-
* @example
|
|
459
|
-
* ```typescript
|
|
460
|
-
* // Listen for local audio stream availability
|
|
461
|
-
* registry.on('localAudioStreamAvailable', (stream) => {
|
|
462
|
-
* console.log('Local audio stream is available');
|
|
463
|
-
*
|
|
464
|
-
* // Set up real-time audio analysis
|
|
465
|
-
* const audioAnalyzer = new AudioAnalyzer(stream);
|
|
466
|
-
* audioAnalyzer.on('volumeLevel', (level) => {
|
|
467
|
-
* updateVolumeIndicator(level);
|
|
468
|
-
* });
|
|
469
|
-
*
|
|
470
|
-
* // Enable noise gate functionality
|
|
471
|
-
* const noiseGate = new NoiseGate(stream);
|
|
472
|
-
* noiseGate.threshold = -40; // dB
|
|
473
|
-
*
|
|
474
|
-
* // Record conversation for quality assurance
|
|
475
|
-
* if (recordingEnabled) {
|
|
476
|
-
* const mediaRecorder = new MediaRecorder(stream);
|
|
477
|
-
* mediaRecorder.start();
|
|
478
|
-
*
|
|
479
|
-
* mediaRecorder.ondataavailable = (event) => {
|
|
480
|
-
* saveAudioChunk(event.data);
|
|
481
|
-
* };
|
|
482
|
-
* }
|
|
483
|
-
* });
|
|
484
|
-
*
|
|
485
|
-
* // Call after connection is established
|
|
486
|
-
* registry.emitLocalAudioStream();
|
|
487
|
-
* ```
|
|
488
|
-
*
|
|
489
|
-
* @example Audio Processing Pipeline
|
|
490
|
-
* ```typescript
|
|
491
|
-
* registry.on('localAudioStreamAvailable', (stream) => {
|
|
492
|
-
* // Create audio context for advanced processing
|
|
493
|
-
* const audioContext = new AudioContext();
|
|
494
|
-
* const source = audioContext.createMediaStreamSource(stream);
|
|
495
|
-
*
|
|
496
|
-
* // Add audio effects
|
|
497
|
-
* const gainNode = audioContext.createGain();
|
|
498
|
-
* const filterNode = audioContext.createBiquadFilter();
|
|
499
|
-
*
|
|
500
|
-
* // Connect processing chain
|
|
501
|
-
* source.connect(gainNode);
|
|
502
|
-
* gainNode.connect(filterNode);
|
|
503
|
-
* filterNode.connect(audioContext.destination);
|
|
504
|
-
*
|
|
505
|
-
* // Configure effects
|
|
506
|
-
* gainNode.gain.value = 1.2;
|
|
507
|
-
* filterNode.type = 'highpass';
|
|
508
|
-
* filterNode.frequency.value = 80;
|
|
509
|
-
* });
|
|
510
|
-
* ```
|
|
511
|
-
*/
|
|
512
|
-
emitLocalAudioStream(): void;
|
|
513
448
|
/**
|
|
514
449
|
* Returns the count of currently registered tools
|
|
515
450
|
*
|
package/types/classes/types.d.ts
CHANGED
|
@@ -98,18 +98,18 @@ export type CallStats = {
|
|
|
98
98
|
};
|
|
99
99
|
/**
|
|
100
100
|
* Real-time network connection quality metrics.
|
|
101
|
-
*
|
|
101
|
+
* Internal structure includes estimated values for future use.
|
|
102
102
|
*/
|
|
103
103
|
export type ConnectionMetrics = {
|
|
104
|
-
/** Current network latency in milliseconds */
|
|
104
|
+
/** Current network latency in milliseconds (internal - estimated) */
|
|
105
105
|
latency: number;
|
|
106
|
-
/** Packet loss percentage (
|
|
106
|
+
/** Packet loss percentage (internal - estimated) */
|
|
107
107
|
packetLoss: number;
|
|
108
|
-
/** Current bandwidth usage in bytes per second */
|
|
108
|
+
/** Current bandwidth usage in bytes per second (internal - estimated) */
|
|
109
109
|
bandwidth: number;
|
|
110
110
|
/** Qualitative assessment of connection ('excellent', 'good', 'poor', 'lost') */
|
|
111
111
|
quality: string;
|
|
112
|
-
/** Network jitter measurement in milliseconds */
|
|
112
|
+
/** Network jitter measurement in milliseconds (internal - estimated) */
|
|
113
113
|
jitter: number;
|
|
114
114
|
};
|
|
115
115
|
/**
|
|
@@ -132,12 +132,12 @@ export type AudioMetrics = {
|
|
|
132
132
|
};
|
|
133
133
|
/**
|
|
134
134
|
* Performance metrics tracking response times and connection reliability.
|
|
135
|
-
*
|
|
135
|
+
* Internal structure includes estimated network latency for future use.
|
|
136
136
|
*/
|
|
137
137
|
export type PerformanceMetrics = {
|
|
138
138
|
/** Total response time for agent interactions in milliseconds */
|
|
139
139
|
responseTime: number;
|
|
140
|
-
/** Current network latency measurement in milliseconds */
|
|
140
|
+
/** Current network latency measurement in milliseconds (internal - estimated) */
|
|
141
141
|
networkLatency: number;
|
|
142
142
|
/** Time taken to establish the initial connection in milliseconds */
|
|
143
143
|
connectionEstablishedTime: number;
|
|
@@ -146,19 +146,11 @@ export type PerformanceMetrics = {
|
|
|
146
146
|
};
|
|
147
147
|
/**
|
|
148
148
|
* Complete connection statistics result returned by getConnectionStats().
|
|
149
|
-
*
|
|
149
|
+
* Only includes verified data - no estimated metrics exposed to customers.
|
|
150
150
|
*/
|
|
151
151
|
export type ConnectionStatsResult = {
|
|
152
|
-
/** Current
|
|
153
|
-
latency: number;
|
|
154
|
-
/** Current packet loss percentage */
|
|
155
|
-
packetLoss: number;
|
|
156
|
-
/** Current bandwidth usage in bytes per second */
|
|
157
|
-
bandwidth: number;
|
|
158
|
-
/** Current connection quality assessment */
|
|
152
|
+
/** Current connection quality assessment from LiveKit */
|
|
159
153
|
quality: string;
|
|
160
|
-
/** Current network jitter in milliseconds */
|
|
161
|
-
jitter: number;
|
|
162
154
|
/** Total connection attempts made */
|
|
163
155
|
connectionAttempts: number;
|
|
164
156
|
/** Total reconnection attempts made */
|
|
@@ -196,13 +188,11 @@ export type AudioLevelsResult = {
|
|
|
196
188
|
};
|
|
197
189
|
/**
|
|
198
190
|
* Complete performance metrics result returned by getPerformanceMetrics().
|
|
199
|
-
*
|
|
191
|
+
* Only includes verified performance data - no estimated metrics exposed.
|
|
200
192
|
*/
|
|
201
193
|
export type PerformanceMetricsResult = {
|
|
202
194
|
/** Total response time in milliseconds */
|
|
203
195
|
responseTime: number;
|
|
204
|
-
/** Current network latency in milliseconds */
|
|
205
|
-
networkLatency: number;
|
|
206
196
|
/** Connection establishment time in milliseconds */
|
|
207
197
|
connectionEstablishedTime: number;
|
|
208
198
|
/** Total reconnection count */
|
|
@@ -264,10 +254,8 @@ export type ConnectionQualityData = {
|
|
|
264
254
|
quality: ConnectionQuality;
|
|
265
255
|
/** Identity of the participant this quality measurement applies to */
|
|
266
256
|
participant: string;
|
|
267
|
-
/**
|
|
257
|
+
/** Connection quality string from LiveKit (estimated metrics available internally) */
|
|
268
258
|
metrics: {
|
|
269
|
-
latency: number;
|
|
270
|
-
packetLoss: number;
|
|
271
259
|
quality: string;
|
|
272
260
|
};
|
|
273
261
|
};
|
package/types/main.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
import type { Room } from 'livekit-client';
|
|
2
3
|
import LiveKitManager, { type AudioLevelsResult, type CallAnalyticsResult, type ConnectionStatsResult, type ParticipantData, type PerformanceMetricsResult, type TrackStatsResult } from './classes/livekit-manager';
|
|
3
4
|
import ScreenWakeLock from './classes/screen-wake-lock';
|
|
5
|
+
/**
|
|
6
|
+
* Custom error class that includes both human-readable message and machine-readable messageKey
|
|
7
|
+
* for internationalization and programmatic error handling
|
|
8
|
+
*/
|
|
9
|
+
declare class HamsaApiError extends Error {
|
|
10
|
+
/** Machine-readable error key for i18n or programmatic handling */
|
|
11
|
+
readonly messageKey?: string;
|
|
12
|
+
constructor(message: string, messageKey?: string);
|
|
13
|
+
}
|
|
4
14
|
/**
|
|
5
15
|
* Configuration options for the HamsaVoiceAgent constructor
|
|
6
16
|
* Allows customization of API endpoints and other global settings
|
|
@@ -164,6 +174,32 @@ type JobDetails = {
|
|
|
164
174
|
* // Get analytics snapshot anytime
|
|
165
175
|
* const analytics = agent.getCallAnalytics();
|
|
166
176
|
* ```
|
|
177
|
+
*
|
|
178
|
+
* @example Track-based Audio Processing
|
|
179
|
+
* ```typescript
|
|
180
|
+
* // Handle incoming audio tracks from voice agent
|
|
181
|
+
* agent.on('trackSubscribed', ({ track, publication, participant }) => {
|
|
182
|
+
* if (track.kind === 'audio') {
|
|
183
|
+
* // Option 1: Attach to DOM element (LiveKit way)
|
|
184
|
+
* track.attach(audioElement);
|
|
185
|
+
*
|
|
186
|
+
* // Option 2: Create MediaStream for custom processing
|
|
187
|
+
* const stream = new MediaStream([track.mediaStreamTrack]);
|
|
188
|
+
* const audioContext = new AudioContext();
|
|
189
|
+
* const source = audioContext.createMediaStreamSource(stream);
|
|
190
|
+
* // Add custom audio processing...
|
|
191
|
+
* }
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* // Handle local audio track availability
|
|
195
|
+
* agent.on('localTrackPublished', ({ track, publication }) => {
|
|
196
|
+
* if (track && track.source === 'microphone') {
|
|
197
|
+
* // Access local microphone track for recording/analysis
|
|
198
|
+
* const stream = new MediaStream([track.mediaStreamTrack]);
|
|
199
|
+
* setupVoiceAnalyzer(stream);
|
|
200
|
+
* }
|
|
201
|
+
* });
|
|
202
|
+
* ```
|
|
167
203
|
*/
|
|
168
204
|
declare class HamsaVoiceAgent extends EventEmitter {
|
|
169
205
|
#private;
|
|
@@ -181,6 +217,8 @@ declare class HamsaVoiceAgent extends EventEmitter {
|
|
|
181
217
|
jobId: string | null;
|
|
182
218
|
/** Screen wake lock manager to prevent device sleep during calls */
|
|
183
219
|
wakeLockManager: ScreenWakeLock;
|
|
220
|
+
/** Flag to track if the user initiated the call end */
|
|
221
|
+
private userInitiatedEnd;
|
|
184
222
|
/**
|
|
185
223
|
* Creates a new HamsaVoiceAgent instance
|
|
186
224
|
*
|
|
@@ -710,6 +748,41 @@ declare class HamsaVoiceAgent extends EventEmitter {
|
|
|
710
748
|
* ```
|
|
711
749
|
*/
|
|
712
750
|
getCallAnalytics(): CallAnalyticsResult | null;
|
|
751
|
+
/**
|
|
752
|
+
* Gets the LiveKit Room instance for React SDK integration
|
|
753
|
+
*
|
|
754
|
+
* Provides access to the underlying LiveKit Room object for use with
|
|
755
|
+
* LiveKit React components. This enables integration with the broader
|
|
756
|
+
* LiveKit React ecosystem while maintaining the benefits of the
|
|
757
|
+
* HamsaVoiceAgent abstraction.
|
|
758
|
+
*
|
|
759
|
+
* @internal - For use by @hamsa-ai/voice-agents-react only
|
|
760
|
+
* @returns LiveKit Room instance or null if not connected
|
|
761
|
+
*
|
|
762
|
+
* @example React SDK Integration
|
|
763
|
+
* ```typescript
|
|
764
|
+
* import { RoomContext } from '@livekit/components-react';
|
|
765
|
+
*
|
|
766
|
+
* function VoiceProvider({ agent, children }) {
|
|
767
|
+
* const [room, setRoom] = useState(null);
|
|
768
|
+
*
|
|
769
|
+
* useEffect(() => {
|
|
770
|
+
* agent.on('callStarted', () => {
|
|
771
|
+
* setRoom(agent.getRoom());
|
|
772
|
+
* });
|
|
773
|
+
* }, [agent]);
|
|
774
|
+
*
|
|
775
|
+
* if (!room) return children;
|
|
776
|
+
*
|
|
777
|
+
* return (
|
|
778
|
+
* <RoomContext.Provider value={room}>
|
|
779
|
+
* {children}
|
|
780
|
+
* </RoomContext.Provider>
|
|
781
|
+
* );
|
|
782
|
+
* }
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
785
|
+
getRoom(): Room | null;
|
|
713
786
|
}
|
|
714
|
-
export { HamsaVoiceAgent };
|
|
787
|
+
export { HamsaVoiceAgent, HamsaApiError };
|
|
715
788
|
export default HamsaVoiceAgent;
|