@anganyai/voice-sdk 0.0.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/CHANGELOG.md +33 -0
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/dist/index.cjs +17820 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1708 -0
- package/dist/index.d.ts +1708 -0
- package/dist/index.js +17802 -0
- package/dist/index.js.map +1 -0
- package/package.json +94 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for Angany Voice SDK
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* SDK configuration options
|
|
6
|
+
*/
|
|
7
|
+
interface VoiceConfig {
|
|
8
|
+
/**
|
|
9
|
+
* The base URL of the Angany API
|
|
10
|
+
* @default 'https://api.angany.ai'
|
|
11
|
+
*/
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
/**
|
|
14
|
+
* The OIDC issuer URL
|
|
15
|
+
* @default Same as apiUrl
|
|
16
|
+
*/
|
|
17
|
+
issuer?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Enable debug mode for detailed logging
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
debug?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Logging level
|
|
25
|
+
* @default 'warn'
|
|
26
|
+
*/
|
|
27
|
+
logLevel?: LogLevel;
|
|
28
|
+
/**
|
|
29
|
+
* Custom logger instance
|
|
30
|
+
*/
|
|
31
|
+
logger?: Logger;
|
|
32
|
+
/**
|
|
33
|
+
* Request timeout in milliseconds
|
|
34
|
+
* @default 30000
|
|
35
|
+
*/
|
|
36
|
+
timeout?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Retry configuration
|
|
39
|
+
*/
|
|
40
|
+
retry?: RetryConfig;
|
|
41
|
+
/**
|
|
42
|
+
* Custom headers to include in all requests
|
|
43
|
+
*/
|
|
44
|
+
headers?: Record<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* Platform-specific configuration
|
|
47
|
+
*/
|
|
48
|
+
platform?: PlatformConfig;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Log levels
|
|
52
|
+
*/
|
|
53
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
54
|
+
/**
|
|
55
|
+
* Logger interface
|
|
56
|
+
*/
|
|
57
|
+
interface Logger {
|
|
58
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
59
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
60
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
61
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Retry configuration
|
|
65
|
+
*/
|
|
66
|
+
interface RetryConfig {
|
|
67
|
+
/**
|
|
68
|
+
* Maximum number of retry attempts
|
|
69
|
+
* @default 3
|
|
70
|
+
*/
|
|
71
|
+
maxAttempts?: number;
|
|
72
|
+
/**
|
|
73
|
+
* Initial delay in milliseconds
|
|
74
|
+
* @default 1000
|
|
75
|
+
*/
|
|
76
|
+
initialDelay?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Maximum delay in milliseconds
|
|
79
|
+
* @default 30000
|
|
80
|
+
*/
|
|
81
|
+
maxDelay?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Backoff multiplier
|
|
84
|
+
* @default 2
|
|
85
|
+
*/
|
|
86
|
+
multiplier?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Jitter factor (0-1)
|
|
89
|
+
* @default 0.1
|
|
90
|
+
*/
|
|
91
|
+
jitter?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Platform-specific configuration
|
|
95
|
+
*/
|
|
96
|
+
interface PlatformConfig {
|
|
97
|
+
/**
|
|
98
|
+
* React Native specific config
|
|
99
|
+
*/
|
|
100
|
+
reactNative?: {
|
|
101
|
+
/**
|
|
102
|
+
* InCallManager configuration
|
|
103
|
+
*/
|
|
104
|
+
inCallManager?: Record<string, unknown>;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Node.js specific config
|
|
108
|
+
*/
|
|
109
|
+
node?: {
|
|
110
|
+
/**
|
|
111
|
+
* HTTP agent configuration
|
|
112
|
+
*/
|
|
113
|
+
agent?: unknown;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Web specific config
|
|
117
|
+
*/
|
|
118
|
+
web?: {
|
|
119
|
+
/**
|
|
120
|
+
* WebRTC constraints
|
|
121
|
+
*/
|
|
122
|
+
rtcConfiguration?: RTCConfiguration;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Voice resource information
|
|
127
|
+
*/
|
|
128
|
+
interface VoiceResource {
|
|
129
|
+
/**
|
|
130
|
+
* Unique identifier for the resource
|
|
131
|
+
*/
|
|
132
|
+
id: string;
|
|
133
|
+
/**
|
|
134
|
+
* Display name of the resource
|
|
135
|
+
*/
|
|
136
|
+
name: string;
|
|
137
|
+
/**
|
|
138
|
+
* Description of the resource
|
|
139
|
+
*/
|
|
140
|
+
description?: string;
|
|
141
|
+
/**
|
|
142
|
+
* Resource type
|
|
143
|
+
*/
|
|
144
|
+
type: 'agent' | 'assistant' | 'custom';
|
|
145
|
+
/**
|
|
146
|
+
* Resource capabilities
|
|
147
|
+
*/
|
|
148
|
+
capabilities?: string[];
|
|
149
|
+
/**
|
|
150
|
+
* Resource metadata
|
|
151
|
+
*/
|
|
152
|
+
metadata?: Record<string, unknown>;
|
|
153
|
+
/**
|
|
154
|
+
* Whether the resource is currently available
|
|
155
|
+
*/
|
|
156
|
+
available: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Resource configuration
|
|
159
|
+
*/
|
|
160
|
+
config?: ResourceConfig;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Resource configuration
|
|
164
|
+
*/
|
|
165
|
+
interface ResourceConfig {
|
|
166
|
+
/**
|
|
167
|
+
* SIP extension for this resource
|
|
168
|
+
*/
|
|
169
|
+
extension?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Supported languages
|
|
172
|
+
*/
|
|
173
|
+
languages?: string[];
|
|
174
|
+
/**
|
|
175
|
+
* Voice configuration
|
|
176
|
+
*/
|
|
177
|
+
voice?: {
|
|
178
|
+
/**
|
|
179
|
+
* Voice ID
|
|
180
|
+
*/
|
|
181
|
+
id?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Voice settings
|
|
184
|
+
*/
|
|
185
|
+
settings?: Record<string, unknown>;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Custom configuration
|
|
189
|
+
*/
|
|
190
|
+
custom?: Record<string, unknown>;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Simple event emitter implementation for the SDK
|
|
195
|
+
*
|
|
196
|
+
* Provides a lightweight event system without external dependencies.
|
|
197
|
+
* Supports typed events for better developer experience.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* interface MyEvents {
|
|
202
|
+
* data: [value: string];
|
|
203
|
+
* error: [error: Error];
|
|
204
|
+
* ready: [];
|
|
205
|
+
* }
|
|
206
|
+
*
|
|
207
|
+
* class MyClass extends EventEmitter<MyEvents> {
|
|
208
|
+
* doSomething() {
|
|
209
|
+
* this.emit('data', 'hello');
|
|
210
|
+
* this.emit('error', new Error('oops'));
|
|
211
|
+
* this.emit('ready');
|
|
212
|
+
* }
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
declare class EventEmitter<T extends Record<string, unknown[]>> {
|
|
217
|
+
private listeners;
|
|
218
|
+
/**
|
|
219
|
+
* Register an event listener
|
|
220
|
+
*
|
|
221
|
+
* @param event - Event name
|
|
222
|
+
* @param handler - Event handler function
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* emitter.on('data', (value) => {
|
|
227
|
+
* console.log('Received:', value);
|
|
228
|
+
* });
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
on<K extends keyof T>(event: K, handler: (...args: T[K]) => void): void;
|
|
232
|
+
/**
|
|
233
|
+
* Unregister an event listener
|
|
234
|
+
*
|
|
235
|
+
* @param event - Event name
|
|
236
|
+
* @param handler - Event handler function to remove
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const handler = (value) => console.log(value);
|
|
241
|
+
* emitter.on('data', handler);
|
|
242
|
+
* emitter.off('data', handler);
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
off<K extends keyof T>(event: K, handler: (...args: T[K]) => void): void;
|
|
246
|
+
/**
|
|
247
|
+
* Register a one-time event listener
|
|
248
|
+
*
|
|
249
|
+
* The handler will be automatically removed after the first call.
|
|
250
|
+
*
|
|
251
|
+
* @param event - Event name
|
|
252
|
+
* @param handler - Event handler function
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* emitter.once('ready', () => {
|
|
257
|
+
* console.log('Ready! This will only fire once');
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
once<K extends keyof T>(event: K, handler: (...args: T[K]) => void): void;
|
|
262
|
+
/**
|
|
263
|
+
* Emit an event
|
|
264
|
+
*
|
|
265
|
+
* Calls all registered handlers for the event in the order they were registered.
|
|
266
|
+
*
|
|
267
|
+
* @param event - Event name
|
|
268
|
+
* @param args - Arguments to pass to event handlers
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* emitter.emit('data', 'hello world');
|
|
273
|
+
* emitter.emit('error', new Error('Something went wrong'));
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
emit<K extends keyof T>(event: K, ...args: T[K]): void;
|
|
277
|
+
/**
|
|
278
|
+
* Remove all listeners for an event or all events
|
|
279
|
+
*
|
|
280
|
+
* @param event - Event name (optional). If not provided, removes all listeners.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* // Remove all listeners for 'data' event
|
|
285
|
+
* emitter.removeAllListeners('data');
|
|
286
|
+
*
|
|
287
|
+
* // Remove all listeners for all events
|
|
288
|
+
* emitter.removeAllListeners();
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
removeAllListeners(event?: keyof T): void;
|
|
292
|
+
/**
|
|
293
|
+
* Get the number of listeners for an event
|
|
294
|
+
*
|
|
295
|
+
* @param event - Event name
|
|
296
|
+
* @returns Number of registered listeners
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* const count = emitter.listenerCount('data');
|
|
301
|
+
* console.log(`There are ${count} data listeners`);
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
listenerCount(event: keyof T): number;
|
|
305
|
+
/**
|
|
306
|
+
* Get all event names that have listeners
|
|
307
|
+
*
|
|
308
|
+
* @returns Array of event names
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* const events = emitter.eventNames();
|
|
313
|
+
* console.log('Active events:', events);
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
eventNames(): (keyof T)[];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Authentication type definitions for Angany Voice SDK
|
|
321
|
+
*/
|
|
322
|
+
/**
|
|
323
|
+
* Base authentication options
|
|
324
|
+
*/
|
|
325
|
+
interface AuthOptions {
|
|
326
|
+
/**
|
|
327
|
+
* Authentication method
|
|
328
|
+
*/
|
|
329
|
+
method: 'frontend' | 'backend' | 'service-account';
|
|
330
|
+
/**
|
|
331
|
+
* Token refresh buffer in seconds
|
|
332
|
+
* @default 300 (5 minutes)
|
|
333
|
+
*/
|
|
334
|
+
refreshBufferSeconds?: number;
|
|
335
|
+
/**
|
|
336
|
+
* Enable automatic token refresh
|
|
337
|
+
* @default true
|
|
338
|
+
*/
|
|
339
|
+
autoRefresh?: boolean;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Frontend authentication options
|
|
343
|
+
*/
|
|
344
|
+
interface FrontendAuthOptions extends AuthOptions {
|
|
345
|
+
method: 'frontend';
|
|
346
|
+
/**
|
|
347
|
+
* OAuth redirect URI
|
|
348
|
+
* If not provided, will use popup flow (not supported by all providers)
|
|
349
|
+
*/
|
|
350
|
+
redirectUri?: string;
|
|
351
|
+
/**
|
|
352
|
+
* OAuth scopes to request
|
|
353
|
+
* @default ['openid', 'profile', 'offline_access']
|
|
354
|
+
*/
|
|
355
|
+
scopes?: string[];
|
|
356
|
+
/**
|
|
357
|
+
* Storage preference for credentials
|
|
358
|
+
* @default 'localStorage'
|
|
359
|
+
*/
|
|
360
|
+
storage?: 'localStorage' | 'sessionStorage' | 'memory';
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Backend authentication options
|
|
364
|
+
*/
|
|
365
|
+
interface BackendAuthOptions extends AuthOptions {
|
|
366
|
+
method: 'backend';
|
|
367
|
+
redirectUri?: string;
|
|
368
|
+
postLogoutRedirectUris?: string[];
|
|
369
|
+
branding?: BrandingOptions;
|
|
370
|
+
scopes?: string[];
|
|
371
|
+
autoRefresh?: boolean;
|
|
372
|
+
refreshBufferSeconds?: number;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Service account authentication options
|
|
376
|
+
*/
|
|
377
|
+
interface ServiceAccountAuthOptions extends AuthOptions {
|
|
378
|
+
method: 'service-account';
|
|
379
|
+
/**
|
|
380
|
+
* Service account credentials
|
|
381
|
+
*/
|
|
382
|
+
credentials: ServiceAccountCredentials;
|
|
383
|
+
/**
|
|
384
|
+
* OAuth scopes to request
|
|
385
|
+
* @default ['api:voice', 'api:conversation']
|
|
386
|
+
*/
|
|
387
|
+
scopes?: string[];
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Service account credentials
|
|
391
|
+
*/
|
|
392
|
+
interface ServiceAccountCredentials {
|
|
393
|
+
/**
|
|
394
|
+
* Service account ID
|
|
395
|
+
*/
|
|
396
|
+
clientId: string;
|
|
397
|
+
/**
|
|
398
|
+
* Service account secret
|
|
399
|
+
*/
|
|
400
|
+
clientSecret: string;
|
|
401
|
+
/**
|
|
402
|
+
* Optional key ID
|
|
403
|
+
*/
|
|
404
|
+
keyId?: string;
|
|
405
|
+
/**
|
|
406
|
+
* Optional private key for JWT assertion
|
|
407
|
+
*/
|
|
408
|
+
privateKey?: string;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* OAuth client credentials (for dynamic registration)
|
|
412
|
+
*/
|
|
413
|
+
interface ClientCredentials {
|
|
414
|
+
/**
|
|
415
|
+
* Client ID
|
|
416
|
+
*/
|
|
417
|
+
clientId: string;
|
|
418
|
+
/**
|
|
419
|
+
* Client secret (if applicable)
|
|
420
|
+
*/
|
|
421
|
+
clientSecret?: string;
|
|
422
|
+
/**
|
|
423
|
+
* Registration access token
|
|
424
|
+
*/
|
|
425
|
+
registrationAccessToken?: string;
|
|
426
|
+
/**
|
|
427
|
+
* Registration client URI
|
|
428
|
+
*/
|
|
429
|
+
registrationClientUri?: string;
|
|
430
|
+
/**
|
|
431
|
+
* When the credentials were created
|
|
432
|
+
*/
|
|
433
|
+
createdAt: Date;
|
|
434
|
+
/**
|
|
435
|
+
* When the credentials expire (if applicable)
|
|
436
|
+
*/
|
|
437
|
+
expiresAt?: Date;
|
|
438
|
+
/**
|
|
439
|
+
* Token endpoint authentication method
|
|
440
|
+
*/
|
|
441
|
+
tokenEndpointAuthMethod?: string;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Token set
|
|
445
|
+
*/
|
|
446
|
+
interface TokenSet {
|
|
447
|
+
/**
|
|
448
|
+
* Access token
|
|
449
|
+
*/
|
|
450
|
+
accessToken: string;
|
|
451
|
+
/**
|
|
452
|
+
* Refresh token (if available)
|
|
453
|
+
*/
|
|
454
|
+
refreshToken?: string;
|
|
455
|
+
/**
|
|
456
|
+
* ID token (if available)
|
|
457
|
+
*/
|
|
458
|
+
idToken?: string;
|
|
459
|
+
/**
|
|
460
|
+
* Token type
|
|
461
|
+
* @default 'Bearer'
|
|
462
|
+
*/
|
|
463
|
+
tokenType: string;
|
|
464
|
+
/**
|
|
465
|
+
* Token expiration time (seconds from now)
|
|
466
|
+
*/
|
|
467
|
+
expiresIn?: number;
|
|
468
|
+
/**
|
|
469
|
+
* Absolute expiration timestamp
|
|
470
|
+
*/
|
|
471
|
+
expiresAt?: Date;
|
|
472
|
+
/**
|
|
473
|
+
* Granted scopes
|
|
474
|
+
*/
|
|
475
|
+
scope?: string;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Authentication status
|
|
479
|
+
*/
|
|
480
|
+
interface AuthStatus {
|
|
481
|
+
/**
|
|
482
|
+
* Whether the user is authenticated
|
|
483
|
+
*/
|
|
484
|
+
authenticated: boolean;
|
|
485
|
+
/**
|
|
486
|
+
* Current authentication method
|
|
487
|
+
*/
|
|
488
|
+
method?: 'frontend' | 'backend' | 'service-account';
|
|
489
|
+
/**
|
|
490
|
+
* Current token set
|
|
491
|
+
*/
|
|
492
|
+
tokens?: TokenSet;
|
|
493
|
+
/**
|
|
494
|
+
* User information
|
|
495
|
+
*/
|
|
496
|
+
user?: UserInfo;
|
|
497
|
+
/**
|
|
498
|
+
* Authentication error (if any)
|
|
499
|
+
*/
|
|
500
|
+
error?: AuthError;
|
|
501
|
+
/**
|
|
502
|
+
* Authentication state
|
|
503
|
+
*/
|
|
504
|
+
state: AuthState;
|
|
505
|
+
/**
|
|
506
|
+
* When the auth status was last updated
|
|
507
|
+
*/
|
|
508
|
+
updatedAt: Date;
|
|
509
|
+
/**
|
|
510
|
+
* OAuth client credentials
|
|
511
|
+
*/
|
|
512
|
+
clientCredentials?: ClientCredentials;
|
|
513
|
+
/**
|
|
514
|
+
* When tokens expire
|
|
515
|
+
*/
|
|
516
|
+
expiresAt?: Date;
|
|
517
|
+
/**
|
|
518
|
+
* When tokens will be refreshed (if auto-refresh is enabled)
|
|
519
|
+
*/
|
|
520
|
+
refreshAt?: Date;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Authentication state
|
|
524
|
+
*/
|
|
525
|
+
type AuthState = 'unauthenticated' | 'authenticating' | 'authenticated' | 'refreshing' | 'error';
|
|
526
|
+
/**
|
|
527
|
+
* User information
|
|
528
|
+
*/
|
|
529
|
+
interface UserInfo {
|
|
530
|
+
/**
|
|
531
|
+
* User ID
|
|
532
|
+
*/
|
|
533
|
+
id: string;
|
|
534
|
+
/**
|
|
535
|
+
* Username
|
|
536
|
+
*/
|
|
537
|
+
username?: string;
|
|
538
|
+
/**
|
|
539
|
+
* Email address
|
|
540
|
+
*/
|
|
541
|
+
email?: string;
|
|
542
|
+
/**
|
|
543
|
+
* Display name
|
|
544
|
+
*/
|
|
545
|
+
name?: string;
|
|
546
|
+
/**
|
|
547
|
+
* User avatar URL
|
|
548
|
+
*/
|
|
549
|
+
picture?: string;
|
|
550
|
+
/**
|
|
551
|
+
* User roles
|
|
552
|
+
*/
|
|
553
|
+
roles?: string[];
|
|
554
|
+
/**
|
|
555
|
+
* User permissions
|
|
556
|
+
*/
|
|
557
|
+
permissions?: string[];
|
|
558
|
+
/**
|
|
559
|
+
* Additional user attributes
|
|
560
|
+
*/
|
|
561
|
+
attributes?: Record<string, unknown>;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Authentication error
|
|
565
|
+
*/
|
|
566
|
+
interface AuthError {
|
|
567
|
+
/**
|
|
568
|
+
* Error code
|
|
569
|
+
*/
|
|
570
|
+
code: string;
|
|
571
|
+
/**
|
|
572
|
+
* Error message
|
|
573
|
+
*/
|
|
574
|
+
message: string;
|
|
575
|
+
/**
|
|
576
|
+
* Error details
|
|
577
|
+
*/
|
|
578
|
+
details?: Record<string, unknown>;
|
|
579
|
+
/**
|
|
580
|
+
* When the error occurred
|
|
581
|
+
*/
|
|
582
|
+
timestamp: Date;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Credential rotation callback
|
|
586
|
+
*/
|
|
587
|
+
type CredentialRotationCallback = () => Promise<{
|
|
588
|
+
sip: {
|
|
589
|
+
username: string;
|
|
590
|
+
password: string;
|
|
591
|
+
realm?: string;
|
|
592
|
+
websocketUrl?: string;
|
|
593
|
+
uris?: string[];
|
|
594
|
+
};
|
|
595
|
+
apiToken?: string;
|
|
596
|
+
expiresAt: Date | string;
|
|
597
|
+
expiresIn: number;
|
|
598
|
+
}>;
|
|
599
|
+
/**
|
|
600
|
+
* Authentication event types
|
|
601
|
+
*/
|
|
602
|
+
interface AuthEvents extends Record<string, unknown[]> {
|
|
603
|
+
/**
|
|
604
|
+
* Emitted when authentication state changes
|
|
605
|
+
*/
|
|
606
|
+
stateChange: [state: AuthState, previousState: AuthState];
|
|
607
|
+
/**
|
|
608
|
+
* Emitted when tokens are refreshed
|
|
609
|
+
*/
|
|
610
|
+
tokenRefresh: [tokens: TokenSet];
|
|
611
|
+
/**
|
|
612
|
+
* Emitted when authentication fails
|
|
613
|
+
*/
|
|
614
|
+
error: [error: AuthError];
|
|
615
|
+
/**
|
|
616
|
+
* Emitted when user logs out
|
|
617
|
+
*/
|
|
618
|
+
logout: [];
|
|
619
|
+
/**
|
|
620
|
+
* Emitted when tokens are about to expire
|
|
621
|
+
*/
|
|
622
|
+
tokenExpiring: [expiresIn: number];
|
|
623
|
+
/**
|
|
624
|
+
* Emitted when ephemeral credentials are about to expire
|
|
625
|
+
*/
|
|
626
|
+
credentialsExpiring: [expiresIn: number];
|
|
627
|
+
/**
|
|
628
|
+
* Emitted when ephemeral credentials have been refreshed
|
|
629
|
+
*/
|
|
630
|
+
credentialsRefreshed: [
|
|
631
|
+
credentials: {
|
|
632
|
+
sip: {
|
|
633
|
+
username: string;
|
|
634
|
+
password: string;
|
|
635
|
+
realm?: string;
|
|
636
|
+
websocketUrl?: string;
|
|
637
|
+
uris?: string[];
|
|
638
|
+
};
|
|
639
|
+
apiToken?: string;
|
|
640
|
+
expiresAt: Date;
|
|
641
|
+
expiresIn: number;
|
|
642
|
+
}
|
|
643
|
+
];
|
|
644
|
+
/**
|
|
645
|
+
* Emitted when credential rotation fails
|
|
646
|
+
*/
|
|
647
|
+
credentialRotationFailed: [error: Error];
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Application branding options for OAuth consent page
|
|
651
|
+
*/
|
|
652
|
+
interface BrandingOptions {
|
|
653
|
+
/**
|
|
654
|
+
* Application name
|
|
655
|
+
*/
|
|
656
|
+
applicationName?: string;
|
|
657
|
+
/**
|
|
658
|
+
* URL to application icon (recommended: 512x512px)
|
|
659
|
+
*/
|
|
660
|
+
applicationIcon?: string;
|
|
661
|
+
/**
|
|
662
|
+
* Brief description of your application
|
|
663
|
+
*/
|
|
664
|
+
applicationDescription?: string;
|
|
665
|
+
/**
|
|
666
|
+
* Application homepage URL
|
|
667
|
+
*/
|
|
668
|
+
homepageUrl?: string;
|
|
669
|
+
/**
|
|
670
|
+
* Terms of service URL
|
|
671
|
+
*/
|
|
672
|
+
termsUrl?: string;
|
|
673
|
+
/**
|
|
674
|
+
* Privacy policy URL
|
|
675
|
+
*/
|
|
676
|
+
privacyUrl?: string;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Credential manager for the Angany Voice SDK
|
|
681
|
+
*
|
|
682
|
+
* Handles client credentials registration and ephemeral credentials for WebRTC connections.
|
|
683
|
+
*/
|
|
684
|
+
|
|
685
|
+
interface EphemeralCredentials {
|
|
686
|
+
sip: {
|
|
687
|
+
username: string;
|
|
688
|
+
password: string;
|
|
689
|
+
realm?: string;
|
|
690
|
+
websocketUrl?: string;
|
|
691
|
+
uris?: string[];
|
|
692
|
+
};
|
|
693
|
+
apiToken?: string | undefined;
|
|
694
|
+
expiresAt: Date;
|
|
695
|
+
expiresIn: number;
|
|
696
|
+
ice_servers?: RTCIceServer[];
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Authentication manager for the Angany Voice SDK
|
|
701
|
+
*
|
|
702
|
+
* Handles OAuth2 authentication flows, token management, and ephemeral credentials
|
|
703
|
+
* for WebRTC connections. Uses the certified openid-client library for all OAuth2/OIDC operations.
|
|
704
|
+
*
|
|
705
|
+
* Supports multiple authentication patterns:
|
|
706
|
+
* - Frontend (SPA) authentication with redirect or popup
|
|
707
|
+
* - Backend authentication with dynamic client registration
|
|
708
|
+
* - Service account authentication
|
|
709
|
+
*
|
|
710
|
+
* This class acts as a facade over specialized authentication components following SOLID principles.
|
|
711
|
+
*/
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Manages authentication for the Angany Voice SDK using openid-client
|
|
715
|
+
*
|
|
716
|
+
* @example Frontend Authentication
|
|
717
|
+
* ```typescript
|
|
718
|
+
* const auth = new AuthManager('https://api.angany.ai');
|
|
719
|
+
* await auth.authenticateFrontend({
|
|
720
|
+
* redirectUri: 'https://app.example.com/callback'
|
|
721
|
+
* });
|
|
722
|
+
* ```
|
|
723
|
+
*
|
|
724
|
+
* @example Backend Authentication with Dynamic Registration
|
|
725
|
+
* ```typescript
|
|
726
|
+
* const auth = new AuthManager('https://api.angany.ai');
|
|
727
|
+
* const result = await auth.authenticateBackend({
|
|
728
|
+
* branding: {
|
|
729
|
+
* applicationName: 'My App',
|
|
730
|
+
* applicationIcon: 'https://example.com/icon.png'
|
|
731
|
+
* }
|
|
732
|
+
* });
|
|
733
|
+
* // Save result.clientCredentials for reuse
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
declare class AuthManager extends EventEmitter<AuthEvents> {
|
|
737
|
+
private readonly logger;
|
|
738
|
+
private state;
|
|
739
|
+
private options;
|
|
740
|
+
private readonly issuer;
|
|
741
|
+
private readonly storageManager;
|
|
742
|
+
private readonly tokenManager;
|
|
743
|
+
private readonly credentialManager;
|
|
744
|
+
private readonly oauthClient;
|
|
745
|
+
private credentialRotationCallback?;
|
|
746
|
+
private credentialRotationTimeout?;
|
|
747
|
+
private credentialExpiryWarningThreshold;
|
|
748
|
+
constructor(apiUrl: string, issuer?: string);
|
|
749
|
+
/**
|
|
750
|
+
* Try to restore a previous session from localStorage
|
|
751
|
+
* This should be called on app startup to restore authentication state
|
|
752
|
+
*
|
|
753
|
+
* @returns true if session was restored successfully, false otherwise
|
|
754
|
+
*
|
|
755
|
+
* @example
|
|
756
|
+
* ```typescript
|
|
757
|
+
* const auth = new AuthManager('https://api.angany.ai');
|
|
758
|
+
* const restored = await auth.tryRestoreSession();
|
|
759
|
+
* if (restored) {
|
|
760
|
+
* console.log('Session restored, user is authenticated');
|
|
761
|
+
* } else {
|
|
762
|
+
* console.log('No session to restore, redirect to login');
|
|
763
|
+
* }
|
|
764
|
+
* ```
|
|
765
|
+
*/
|
|
766
|
+
tryRestoreSession(): Promise<boolean>;
|
|
767
|
+
/**
|
|
768
|
+
* Authenticate using frontend flow (SPA)
|
|
769
|
+
*/
|
|
770
|
+
authenticateFrontend(options?: Partial<FrontendAuthOptions>): Promise<void>;
|
|
771
|
+
/**
|
|
772
|
+
* Authenticate using backend flow
|
|
773
|
+
*/
|
|
774
|
+
authenticateBackend(options?: Partial<BackendAuthOptions>): Promise<{
|
|
775
|
+
clientCredentials: ClientCredentials;
|
|
776
|
+
authUrl?: string;
|
|
777
|
+
}>;
|
|
778
|
+
/**
|
|
779
|
+
* Authenticate using service account (client credentials)
|
|
780
|
+
*/
|
|
781
|
+
authenticateServiceAccount(options: ServiceAccountAuthOptions): Promise<void>;
|
|
782
|
+
/**
|
|
783
|
+
* Use existing client credentials
|
|
784
|
+
*/
|
|
785
|
+
useExistingCredentials(credentials: ClientCredentials, options?: {
|
|
786
|
+
redirectUri?: string;
|
|
787
|
+
scope?: string;
|
|
788
|
+
}): Promise<void>;
|
|
789
|
+
/**
|
|
790
|
+
* Get authorization URL for OAuth flow
|
|
791
|
+
*/
|
|
792
|
+
getAuthorizationUrl(): Promise<{
|
|
793
|
+
url: string;
|
|
794
|
+
codeVerifier: string;
|
|
795
|
+
state: string;
|
|
796
|
+
}>;
|
|
797
|
+
/**
|
|
798
|
+
* Set PKCE code verifier (for backend flows)
|
|
799
|
+
*/
|
|
800
|
+
setCodeVerifier(codeVerifier: string): void;
|
|
801
|
+
/**
|
|
802
|
+
* Handle OAuth callback
|
|
803
|
+
*/
|
|
804
|
+
handleCallback(code: string, state: string, codeVerifier?: string): Promise<{
|
|
805
|
+
success: boolean;
|
|
806
|
+
user?: UserInfo;
|
|
807
|
+
}>;
|
|
808
|
+
/**
|
|
809
|
+
* Check if ephemeral credentials are available and valid
|
|
810
|
+
*/
|
|
811
|
+
hasValidEphemeralCredentials(): boolean;
|
|
812
|
+
/**
|
|
813
|
+
* Get cached ephemeral credentials (if valid)
|
|
814
|
+
*/
|
|
815
|
+
getCachedEphemeralCredentials(): EphemeralCredentials | undefined;
|
|
816
|
+
/**
|
|
817
|
+
* Get current authentication status
|
|
818
|
+
*/
|
|
819
|
+
getAuthStatus(): AuthStatus;
|
|
820
|
+
/**
|
|
821
|
+
* Get current tokens
|
|
822
|
+
*/
|
|
823
|
+
getTokens(): TokenSet | undefined;
|
|
824
|
+
/**
|
|
825
|
+
* Get access token
|
|
826
|
+
*/
|
|
827
|
+
getAccessToken(): Promise<string | undefined>;
|
|
828
|
+
/**
|
|
829
|
+
* Refresh tokens
|
|
830
|
+
*/
|
|
831
|
+
refreshTokens(): Promise<TokenSet>;
|
|
832
|
+
/**
|
|
833
|
+
* Set ephemeral credentials for WebRTC connections
|
|
834
|
+
*/
|
|
835
|
+
setEphemeralCredentials(credentials: {
|
|
836
|
+
sip: {
|
|
837
|
+
username: string;
|
|
838
|
+
password: string;
|
|
839
|
+
realm?: string;
|
|
840
|
+
websocketUrl?: string;
|
|
841
|
+
uris?: string[];
|
|
842
|
+
};
|
|
843
|
+
apiToken?: string;
|
|
844
|
+
expiresAt: Date | string;
|
|
845
|
+
expiresIn: number;
|
|
846
|
+
}): void;
|
|
847
|
+
/**
|
|
848
|
+
* Set OAuth access token for API calls (hybrid approach)
|
|
849
|
+
*/
|
|
850
|
+
setOAuthAccessToken(accessToken: string): void;
|
|
851
|
+
/**
|
|
852
|
+
* Get ephemeral credentials for a specific user (admin function)
|
|
853
|
+
*/
|
|
854
|
+
getEphemeralCredentialsForUser(userAccessToken: string): Promise<EphemeralCredentials>;
|
|
855
|
+
/**
|
|
856
|
+
* Get ephemeral credentials for WebRTC connections
|
|
857
|
+
*/
|
|
858
|
+
getEphemeralCredentials(): Promise<EphemeralCredentials>;
|
|
859
|
+
/**
|
|
860
|
+
* Renew ephemeral credentials
|
|
861
|
+
*/
|
|
862
|
+
renewEphemeralCredentials(): Promise<void>;
|
|
863
|
+
/**
|
|
864
|
+
* Set credential rotation callback
|
|
865
|
+
* This callback will be called when credentials are about to expire
|
|
866
|
+
*/
|
|
867
|
+
setCredentialRotationCallback(callback: CredentialRotationCallback): void;
|
|
868
|
+
/**
|
|
869
|
+
* Clear credential rotation callback
|
|
870
|
+
*/
|
|
871
|
+
clearCredentialRotationCallback(): void;
|
|
872
|
+
/**
|
|
873
|
+
* Set credential expiry warning threshold (in seconds before expiry)
|
|
874
|
+
*/
|
|
875
|
+
setCredentialExpiryWarningThreshold(seconds: number): void;
|
|
876
|
+
/**
|
|
877
|
+
* Schedule credential rotation based on actual expiry time
|
|
878
|
+
*/
|
|
879
|
+
private scheduleCredentialRotation;
|
|
880
|
+
/**
|
|
881
|
+
* Clear credential rotation timeout
|
|
882
|
+
*/
|
|
883
|
+
private clearCredentialRotationTimeout;
|
|
884
|
+
/**
|
|
885
|
+
* Perform credential rotation
|
|
886
|
+
*/
|
|
887
|
+
private performCredentialRotation;
|
|
888
|
+
/**
|
|
889
|
+
* Logout user
|
|
890
|
+
*/
|
|
891
|
+
logout(options?: {
|
|
892
|
+
clearStoredClient?: boolean;
|
|
893
|
+
redirectToProvider?: boolean;
|
|
894
|
+
postLogoutRedirectUri?: string;
|
|
895
|
+
}): Promise<string | void>;
|
|
896
|
+
/**
|
|
897
|
+
* Initialize backend authentication (legacy method)
|
|
898
|
+
*/
|
|
899
|
+
initializeBackend(options: BackendAuthOptions & {
|
|
900
|
+
redirectUri?: string;
|
|
901
|
+
scope?: string;
|
|
902
|
+
}): Promise<{
|
|
903
|
+
clientId?: string;
|
|
904
|
+
}>;
|
|
905
|
+
/**
|
|
906
|
+
* Restore tokens from external source
|
|
907
|
+
*/
|
|
908
|
+
restoreTokens(tokens: TokenSet): void;
|
|
909
|
+
/**
|
|
910
|
+
* Set authentication state
|
|
911
|
+
*/
|
|
912
|
+
private setState;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Conversation type definitions for Angany Voice SDK
|
|
917
|
+
*/
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Conversation options
|
|
921
|
+
*/
|
|
922
|
+
interface ConversationOptions {
|
|
923
|
+
/**
|
|
924
|
+
* Voice resource ID or name
|
|
925
|
+
*/
|
|
926
|
+
resource: string;
|
|
927
|
+
/**
|
|
928
|
+
* Conversation metadata
|
|
929
|
+
*/
|
|
930
|
+
metadata?: Record<string, unknown>;
|
|
931
|
+
/**
|
|
932
|
+
* Audio configuration
|
|
933
|
+
*/
|
|
934
|
+
audio?: AudioConfig;
|
|
935
|
+
/**
|
|
936
|
+
* Enable automatic reconnection
|
|
937
|
+
* @default true
|
|
938
|
+
*/
|
|
939
|
+
autoReconnect?: boolean;
|
|
940
|
+
/**
|
|
941
|
+
* Maximum reconnection attempts
|
|
942
|
+
* @default 5
|
|
943
|
+
*/
|
|
944
|
+
maxReconnectAttempts?: number;
|
|
945
|
+
/**
|
|
946
|
+
* Reconnection delay in milliseconds
|
|
947
|
+
* @default 1000
|
|
948
|
+
*/
|
|
949
|
+
reconnectDelay?: number;
|
|
950
|
+
/**
|
|
951
|
+
* Enable echo cancellation
|
|
952
|
+
* @default true
|
|
953
|
+
*/
|
|
954
|
+
echoCancellation?: boolean;
|
|
955
|
+
/**
|
|
956
|
+
* Enable noise suppression
|
|
957
|
+
* @default true
|
|
958
|
+
*/
|
|
959
|
+
noiseSuppression?: boolean;
|
|
960
|
+
/**
|
|
961
|
+
* Enable automatic gain control
|
|
962
|
+
* @default true
|
|
963
|
+
*/
|
|
964
|
+
autoGainControl?: boolean;
|
|
965
|
+
/**
|
|
966
|
+
* Custom SIP headers
|
|
967
|
+
*/
|
|
968
|
+
sipHeaders?: Record<string, string>;
|
|
969
|
+
/**
|
|
970
|
+
* Conversation timeout in milliseconds
|
|
971
|
+
* @default 3600000 (1 hour)
|
|
972
|
+
*/
|
|
973
|
+
timeout?: number;
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Audio configuration
|
|
977
|
+
*/
|
|
978
|
+
interface AudioConfig {
|
|
979
|
+
/**
|
|
980
|
+
* Input device ID
|
|
981
|
+
*/
|
|
982
|
+
inputDeviceId?: string;
|
|
983
|
+
/**
|
|
984
|
+
* Output device ID
|
|
985
|
+
*/
|
|
986
|
+
outputDeviceId?: string;
|
|
987
|
+
/**
|
|
988
|
+
* Sample rate
|
|
989
|
+
* @default 48000
|
|
990
|
+
*/
|
|
991
|
+
sampleRate?: number;
|
|
992
|
+
/**
|
|
993
|
+
* Audio codec preferences
|
|
994
|
+
*/
|
|
995
|
+
codecs?: AudioCodec[];
|
|
996
|
+
/**
|
|
997
|
+
* Enable stereo
|
|
998
|
+
* @default false
|
|
999
|
+
*/
|
|
1000
|
+
stereo?: boolean;
|
|
1001
|
+
/**
|
|
1002
|
+
* Audio constraints
|
|
1003
|
+
*/
|
|
1004
|
+
constraints?: MediaTrackConstraints;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Audio codec
|
|
1008
|
+
*/
|
|
1009
|
+
type AudioCodec = 'opus' | 'PCMU' | 'PCMA' | 'G722' | 'iLBC' | 'VP8';
|
|
1010
|
+
/**
|
|
1011
|
+
* Conversation state
|
|
1012
|
+
*/
|
|
1013
|
+
type ConversationState = 'idle' | 'connecting' | 'connected' | 'active' | 'held' | 'muted' | 'disconnecting' | 'disconnected' | 'failed' | 'reconnecting' | 'error';
|
|
1014
|
+
/**
|
|
1015
|
+
* Conversation status
|
|
1016
|
+
*/
|
|
1017
|
+
interface ConversationStatus {
|
|
1018
|
+
/**
|
|
1019
|
+
* Current state
|
|
1020
|
+
*/
|
|
1021
|
+
state: ConversationState;
|
|
1022
|
+
/**
|
|
1023
|
+
* Conversation ID
|
|
1024
|
+
*/
|
|
1025
|
+
id?: string;
|
|
1026
|
+
/**
|
|
1027
|
+
* SIP call ID
|
|
1028
|
+
*/
|
|
1029
|
+
callId?: string;
|
|
1030
|
+
/**
|
|
1031
|
+
* Resource information
|
|
1032
|
+
*/
|
|
1033
|
+
resource?: VoiceResource;
|
|
1034
|
+
/**
|
|
1035
|
+
* Start time
|
|
1036
|
+
*/
|
|
1037
|
+
startTime?: Date;
|
|
1038
|
+
/**
|
|
1039
|
+
* End time
|
|
1040
|
+
*/
|
|
1041
|
+
endTime?: Date;
|
|
1042
|
+
/**
|
|
1043
|
+
* Duration in seconds
|
|
1044
|
+
*/
|
|
1045
|
+
duration?: number;
|
|
1046
|
+
/**
|
|
1047
|
+
* Whether the agent is muted
|
|
1048
|
+
*/
|
|
1049
|
+
agentMuted: boolean;
|
|
1050
|
+
/**
|
|
1051
|
+
* Whether the user is muted
|
|
1052
|
+
*/
|
|
1053
|
+
userMuted: boolean;
|
|
1054
|
+
/**
|
|
1055
|
+
* Connection quality
|
|
1056
|
+
*/
|
|
1057
|
+
quality?: ConnectionQuality;
|
|
1058
|
+
/**
|
|
1059
|
+
* Error information
|
|
1060
|
+
*/
|
|
1061
|
+
error?: ConversationError$1;
|
|
1062
|
+
/**
|
|
1063
|
+
* Conversation metadata
|
|
1064
|
+
*/
|
|
1065
|
+
metadata?: Record<string, unknown>;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Connection quality
|
|
1069
|
+
*/
|
|
1070
|
+
interface ConnectionQuality {
|
|
1071
|
+
/**
|
|
1072
|
+
* Overall quality score (0-100)
|
|
1073
|
+
*/
|
|
1074
|
+
score: number;
|
|
1075
|
+
/**
|
|
1076
|
+
* Quality level
|
|
1077
|
+
*/
|
|
1078
|
+
level: 'excellent' | 'good' | 'fair' | 'poor';
|
|
1079
|
+
/**
|
|
1080
|
+
* Network statistics
|
|
1081
|
+
*/
|
|
1082
|
+
stats?: NetworkStats;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Network statistics
|
|
1086
|
+
*/
|
|
1087
|
+
interface NetworkStats {
|
|
1088
|
+
/**
|
|
1089
|
+
* Round-trip time in milliseconds
|
|
1090
|
+
*/
|
|
1091
|
+
rtt?: number;
|
|
1092
|
+
/**
|
|
1093
|
+
* Packet loss percentage
|
|
1094
|
+
*/
|
|
1095
|
+
packetLoss?: number;
|
|
1096
|
+
/**
|
|
1097
|
+
* Jitter in milliseconds
|
|
1098
|
+
*/
|
|
1099
|
+
jitter?: number;
|
|
1100
|
+
/**
|
|
1101
|
+
* Bandwidth usage in kbps
|
|
1102
|
+
*/
|
|
1103
|
+
bandwidth?: {
|
|
1104
|
+
upload?: number;
|
|
1105
|
+
download?: number;
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Transcription event
|
|
1110
|
+
*/
|
|
1111
|
+
interface TranscriptionEvent {
|
|
1112
|
+
/**
|
|
1113
|
+
* Event ID
|
|
1114
|
+
*/
|
|
1115
|
+
id: string;
|
|
1116
|
+
/**
|
|
1117
|
+
* Event type
|
|
1118
|
+
*/
|
|
1119
|
+
type: 'partial' | 'final';
|
|
1120
|
+
/**
|
|
1121
|
+
* Speaker role
|
|
1122
|
+
*/
|
|
1123
|
+
role: 'user' | 'agent';
|
|
1124
|
+
/**
|
|
1125
|
+
* Transcribed text
|
|
1126
|
+
*/
|
|
1127
|
+
text: string;
|
|
1128
|
+
/**
|
|
1129
|
+
* Timestamp
|
|
1130
|
+
*/
|
|
1131
|
+
timestamp: Date;
|
|
1132
|
+
/**
|
|
1133
|
+
* Duration in seconds
|
|
1134
|
+
*/
|
|
1135
|
+
duration?: number;
|
|
1136
|
+
/**
|
|
1137
|
+
* Confidence score (0-1)
|
|
1138
|
+
*/
|
|
1139
|
+
confidence?: number;
|
|
1140
|
+
/**
|
|
1141
|
+
* Language code
|
|
1142
|
+
*/
|
|
1143
|
+
language?: string;
|
|
1144
|
+
/**
|
|
1145
|
+
* Alternative transcriptions
|
|
1146
|
+
*/
|
|
1147
|
+
alternatives?: TranscriptionAlternative[];
|
|
1148
|
+
/**
|
|
1149
|
+
* Additional metadata
|
|
1150
|
+
*/
|
|
1151
|
+
metadata?: Record<string, unknown>;
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Transcription alternative
|
|
1155
|
+
*/
|
|
1156
|
+
interface TranscriptionAlternative {
|
|
1157
|
+
/**
|
|
1158
|
+
* Alternative text
|
|
1159
|
+
*/
|
|
1160
|
+
text: string;
|
|
1161
|
+
/**
|
|
1162
|
+
* Confidence score (0-1)
|
|
1163
|
+
*/
|
|
1164
|
+
confidence: number;
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Speak options
|
|
1168
|
+
*/
|
|
1169
|
+
interface SpeakOptions {
|
|
1170
|
+
/**
|
|
1171
|
+
* Whether to interrupt current speech
|
|
1172
|
+
* @default false
|
|
1173
|
+
*/
|
|
1174
|
+
interrupt?: boolean;
|
|
1175
|
+
/**
|
|
1176
|
+
* Priority level
|
|
1177
|
+
* @default 'normal'
|
|
1178
|
+
*/
|
|
1179
|
+
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
1180
|
+
/**
|
|
1181
|
+
* Callback when speech starts
|
|
1182
|
+
*/
|
|
1183
|
+
onStart?: () => void;
|
|
1184
|
+
/**
|
|
1185
|
+
* Callback when speech ends
|
|
1186
|
+
*/
|
|
1187
|
+
onEnd?: () => void;
|
|
1188
|
+
/**
|
|
1189
|
+
* Callback on error
|
|
1190
|
+
*/
|
|
1191
|
+
onError?: (error: Error) => void;
|
|
1192
|
+
/**
|
|
1193
|
+
* Custom metadata
|
|
1194
|
+
*/
|
|
1195
|
+
metadata?: Record<string, unknown>;
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Conversation error
|
|
1199
|
+
*/
|
|
1200
|
+
interface ConversationError$1 {
|
|
1201
|
+
/**
|
|
1202
|
+
* Error code
|
|
1203
|
+
*/
|
|
1204
|
+
code: string;
|
|
1205
|
+
/**
|
|
1206
|
+
* Error message
|
|
1207
|
+
*/
|
|
1208
|
+
message: string;
|
|
1209
|
+
/**
|
|
1210
|
+
* Error type
|
|
1211
|
+
*/
|
|
1212
|
+
type: 'network' | 'permission' | 'resource' | 'timeout' | 'unknown';
|
|
1213
|
+
/**
|
|
1214
|
+
* Whether the error is recoverable
|
|
1215
|
+
*/
|
|
1216
|
+
recoverable: boolean;
|
|
1217
|
+
/**
|
|
1218
|
+
* Error details
|
|
1219
|
+
*/
|
|
1220
|
+
details?: Record<string, unknown>;
|
|
1221
|
+
/**
|
|
1222
|
+
* Original error
|
|
1223
|
+
*/
|
|
1224
|
+
cause?: Error;
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Conversation events
|
|
1228
|
+
*/
|
|
1229
|
+
interface ConversationEvents extends Record<string, unknown[]> {
|
|
1230
|
+
/**
|
|
1231
|
+
* Emitted when state changes
|
|
1232
|
+
*/
|
|
1233
|
+
stateChange: [state: ConversationState, previousState: ConversationState];
|
|
1234
|
+
/**
|
|
1235
|
+
* Emitted when connected
|
|
1236
|
+
*/
|
|
1237
|
+
connected: [];
|
|
1238
|
+
/**
|
|
1239
|
+
* Emitted when disconnected
|
|
1240
|
+
*/
|
|
1241
|
+
disconnected: [reason?: string];
|
|
1242
|
+
/**
|
|
1243
|
+
* Emitted on transcription
|
|
1244
|
+
*/
|
|
1245
|
+
transcription: [
|
|
1246
|
+
event: {
|
|
1247
|
+
speaker: 'user' | 'agent';
|
|
1248
|
+
text: string;
|
|
1249
|
+
timestamp: Date;
|
|
1250
|
+
isFinal: boolean;
|
|
1251
|
+
}
|
|
1252
|
+
];
|
|
1253
|
+
/**
|
|
1254
|
+
* Emitted on error
|
|
1255
|
+
*/
|
|
1256
|
+
error: [error: Error];
|
|
1257
|
+
/**
|
|
1258
|
+
* Emitted when agent is muted/unmuted
|
|
1259
|
+
*/
|
|
1260
|
+
agentMuted: [muted: boolean];
|
|
1261
|
+
/**
|
|
1262
|
+
* Emitted when user is muted/unmuted
|
|
1263
|
+
*/
|
|
1264
|
+
userMuted: [muted: boolean];
|
|
1265
|
+
/**
|
|
1266
|
+
* Emitted when connection quality changes
|
|
1267
|
+
*/
|
|
1268
|
+
qualityChange: [quality: ConnectionQuality];
|
|
1269
|
+
/**
|
|
1270
|
+
* Emitted when reconnecting
|
|
1271
|
+
*/
|
|
1272
|
+
reconnecting: [attempt: number];
|
|
1273
|
+
/**
|
|
1274
|
+
* Emitted when reconnected
|
|
1275
|
+
*/
|
|
1276
|
+
reconnected: [];
|
|
1277
|
+
/**
|
|
1278
|
+
* Emitted when conversation ends
|
|
1279
|
+
*/
|
|
1280
|
+
ended: [summary: {
|
|
1281
|
+
duration: number;
|
|
1282
|
+
}];
|
|
1283
|
+
/**
|
|
1284
|
+
* Emitted with audio level updates
|
|
1285
|
+
*/
|
|
1286
|
+
audioLevel: [level: number];
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
/**
|
|
1290
|
+
* Conversation management
|
|
1291
|
+
*/
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Represents an active voice conversation
|
|
1295
|
+
*/
|
|
1296
|
+
declare class Conversation extends EventEmitter<ConversationEvents> {
|
|
1297
|
+
private logger;
|
|
1298
|
+
private id;
|
|
1299
|
+
private state;
|
|
1300
|
+
private options;
|
|
1301
|
+
private agentMuted;
|
|
1302
|
+
private userMuted;
|
|
1303
|
+
private startTime?;
|
|
1304
|
+
private endTime?;
|
|
1305
|
+
private apiUrl;
|
|
1306
|
+
private authManager;
|
|
1307
|
+
private sipManager;
|
|
1308
|
+
private transcriptionService;
|
|
1309
|
+
private apiService;
|
|
1310
|
+
private callId?;
|
|
1311
|
+
private ephemeralCredentials?;
|
|
1312
|
+
private accessToken?;
|
|
1313
|
+
constructor(id: string, options: ConversationOptions, authManager: AuthManager, apiUrl: string);
|
|
1314
|
+
/**
|
|
1315
|
+
* Initialize and start the conversation
|
|
1316
|
+
*/
|
|
1317
|
+
initialize(): Promise<void>;
|
|
1318
|
+
/**
|
|
1319
|
+
* Send text to be spoken in the conversation
|
|
1320
|
+
*/
|
|
1321
|
+
speak(text: string, options?: {
|
|
1322
|
+
interrupt?: boolean;
|
|
1323
|
+
waitForResponse?: boolean;
|
|
1324
|
+
}): Promise<void>;
|
|
1325
|
+
/**
|
|
1326
|
+
* Mute or unmute the user's microphone
|
|
1327
|
+
*/
|
|
1328
|
+
mute(muted: boolean): void;
|
|
1329
|
+
/**
|
|
1330
|
+
* Mute the agent
|
|
1331
|
+
*/
|
|
1332
|
+
muteAgent(muted?: boolean): Promise<void>;
|
|
1333
|
+
/**
|
|
1334
|
+
* Unmute the agent (convenience method)
|
|
1335
|
+
*/
|
|
1336
|
+
unmuteAgent(): Promise<void>;
|
|
1337
|
+
/**
|
|
1338
|
+
* Check if agent is muted
|
|
1339
|
+
*/
|
|
1340
|
+
isAgentMuted(): boolean;
|
|
1341
|
+
/**
|
|
1342
|
+
* Get conversation status
|
|
1343
|
+
*/
|
|
1344
|
+
getStatus(): Promise<ConversationStatus>;
|
|
1345
|
+
/**
|
|
1346
|
+
* End the conversation
|
|
1347
|
+
*/
|
|
1348
|
+
end(): Promise<void>;
|
|
1349
|
+
/**
|
|
1350
|
+
* Get the conversation ID
|
|
1351
|
+
*/
|
|
1352
|
+
getId(): string;
|
|
1353
|
+
/**
|
|
1354
|
+
* Get the current state
|
|
1355
|
+
*/
|
|
1356
|
+
getState(): ConversationState;
|
|
1357
|
+
/**
|
|
1358
|
+
* Get the resource ID
|
|
1359
|
+
*/
|
|
1360
|
+
get resourceId(): string;
|
|
1361
|
+
/**
|
|
1362
|
+
* Get the conversation status (for compatibility)
|
|
1363
|
+
*/
|
|
1364
|
+
get status(): string;
|
|
1365
|
+
/**
|
|
1366
|
+
* Enable audio playback (call after user interaction to bypass autoplay restrictions)
|
|
1367
|
+
*/
|
|
1368
|
+
enableAudio(): Promise<void>;
|
|
1369
|
+
/**
|
|
1370
|
+
* Check if audio is playing
|
|
1371
|
+
*/
|
|
1372
|
+
isAudioPlaying(): boolean;
|
|
1373
|
+
/**
|
|
1374
|
+
* Set audio volume (0.0 to 1.0)
|
|
1375
|
+
*/
|
|
1376
|
+
setVolume(volume: number): void;
|
|
1377
|
+
/**
|
|
1378
|
+
* Mute or unmute the remote audio
|
|
1379
|
+
*/
|
|
1380
|
+
setAudioMuted(muted: boolean): void;
|
|
1381
|
+
/**
|
|
1382
|
+
* Get the audio element for external control
|
|
1383
|
+
*/
|
|
1384
|
+
getAudioElement(): HTMLAudioElement | undefined;
|
|
1385
|
+
private setState;
|
|
1386
|
+
private setupSipHandlers;
|
|
1387
|
+
private setupTranscriptionHandlers;
|
|
1388
|
+
private cleanup;
|
|
1389
|
+
private extractServerFromUris;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* Main entry point for the Angany Voice SDK
|
|
1394
|
+
*/
|
|
1395
|
+
|
|
1396
|
+
interface VoiceEvents extends Record<string, unknown[]> {
|
|
1397
|
+
/**
|
|
1398
|
+
* Emitted when a conversation is started
|
|
1399
|
+
*/
|
|
1400
|
+
conversationStarted: [conversation: Conversation];
|
|
1401
|
+
/**
|
|
1402
|
+
* Emitted when a conversation ends
|
|
1403
|
+
*/
|
|
1404
|
+
conversationEnded: [conversationId: string];
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Main SDK class for managing voice conversations
|
|
1408
|
+
*/
|
|
1409
|
+
declare class AnganyVoice extends EventEmitter<VoiceEvents> {
|
|
1410
|
+
private logger;
|
|
1411
|
+
private config;
|
|
1412
|
+
private conversations;
|
|
1413
|
+
/**
|
|
1414
|
+
* Authentication manager instance
|
|
1415
|
+
*/
|
|
1416
|
+
readonly auth: AuthManager;
|
|
1417
|
+
constructor(config: VoiceConfig);
|
|
1418
|
+
/**
|
|
1419
|
+
* Get the current configuration
|
|
1420
|
+
*/
|
|
1421
|
+
getConfig(): VoiceConfig;
|
|
1422
|
+
/**
|
|
1423
|
+
* Start a new conversation
|
|
1424
|
+
*/
|
|
1425
|
+
startConversation(resourceId: string, options?: Partial<ConversationOptions>): Promise<Conversation>;
|
|
1426
|
+
/**
|
|
1427
|
+
* Get an existing conversation by ID
|
|
1428
|
+
*/
|
|
1429
|
+
getConversation(id: string): Conversation | undefined;
|
|
1430
|
+
/**
|
|
1431
|
+
* Get all active conversations
|
|
1432
|
+
*/
|
|
1433
|
+
getConversations(): Conversation[];
|
|
1434
|
+
/**
|
|
1435
|
+
* End all conversations and cleanup
|
|
1436
|
+
*/
|
|
1437
|
+
cleanup(): Promise<void>;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
/**
|
|
1441
|
+
* Error classes for the Angany Voice SDK
|
|
1442
|
+
*
|
|
1443
|
+
* Provides a hierarchy of error types for different failure scenarios.
|
|
1444
|
+
* All SDK errors extend from AnganyError for easy error handling.
|
|
1445
|
+
*
|
|
1446
|
+
* @example Catching specific errors
|
|
1447
|
+
* ```typescript
|
|
1448
|
+
* try {
|
|
1449
|
+
* await voice.startConversation('agent');
|
|
1450
|
+
* } catch (error) {
|
|
1451
|
+
* if (error instanceof AuthenticationError) {
|
|
1452
|
+
* // Handle auth failure
|
|
1453
|
+
* } else if (error instanceof NetworkError) {
|
|
1454
|
+
* // Handle network issue
|
|
1455
|
+
* }
|
|
1456
|
+
* }
|
|
1457
|
+
* ```
|
|
1458
|
+
*/
|
|
1459
|
+
/**
|
|
1460
|
+
* Base error class for all SDK errors
|
|
1461
|
+
*
|
|
1462
|
+
* All SDK-specific errors extend from this class, making it easy
|
|
1463
|
+
* to catch any SDK error with a single catch block.
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* try {
|
|
1468
|
+
* // SDK operations
|
|
1469
|
+
* } catch (error) {
|
|
1470
|
+
* if (error instanceof AnganyError) {
|
|
1471
|
+
* console.log('SDK error:', error.code, error.message);
|
|
1472
|
+
* }
|
|
1473
|
+
* }
|
|
1474
|
+
* ```
|
|
1475
|
+
*/
|
|
1476
|
+
declare class AnganyError extends Error {
|
|
1477
|
+
/**
|
|
1478
|
+
* Machine-readable error code
|
|
1479
|
+
*
|
|
1480
|
+
* Use this for programmatic error handling instead of parsing messages.
|
|
1481
|
+
*/
|
|
1482
|
+
readonly code: string;
|
|
1483
|
+
/**
|
|
1484
|
+
* Additional error details
|
|
1485
|
+
*
|
|
1486
|
+
* May contain extra context, original errors, or debugging information.
|
|
1487
|
+
*/
|
|
1488
|
+
readonly details?: any;
|
|
1489
|
+
/**
|
|
1490
|
+
* Timestamp when the error occurred
|
|
1491
|
+
*/
|
|
1492
|
+
readonly timestamp: Date;
|
|
1493
|
+
constructor(message: string, code: string, details?: any);
|
|
1494
|
+
/**
|
|
1495
|
+
* Get a JSON representation of the error
|
|
1496
|
+
*
|
|
1497
|
+
* Useful for logging or sending error reports.
|
|
1498
|
+
*
|
|
1499
|
+
* @returns JSON-serializable error object
|
|
1500
|
+
*/
|
|
1501
|
+
toJSON(): Record<string, any>;
|
|
1502
|
+
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Authentication-related errors
|
|
1505
|
+
*
|
|
1506
|
+
* Thrown when authentication fails or tokens are invalid/expired.
|
|
1507
|
+
*
|
|
1508
|
+
* @example
|
|
1509
|
+
* ```typescript
|
|
1510
|
+
* throw new AuthenticationError('Invalid credentials', {
|
|
1511
|
+
* reason: 'wrong_password'
|
|
1512
|
+
* });
|
|
1513
|
+
* ```
|
|
1514
|
+
*/
|
|
1515
|
+
declare class AuthenticationError extends AnganyError {
|
|
1516
|
+
constructor(message: string, details?: any);
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Network-related errors
|
|
1520
|
+
*
|
|
1521
|
+
* Thrown when network requests fail or connections are lost.
|
|
1522
|
+
*
|
|
1523
|
+
* @example
|
|
1524
|
+
* ```typescript
|
|
1525
|
+
* throw new NetworkError('Connection timeout', {
|
|
1526
|
+
* url: 'https://api.angany.ai',
|
|
1527
|
+
* timeout: 30000
|
|
1528
|
+
* });
|
|
1529
|
+
* ```
|
|
1530
|
+
*/
|
|
1531
|
+
declare class NetworkError extends AnganyError {
|
|
1532
|
+
constructor(message: string, details?: any);
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* Permission-related errors
|
|
1536
|
+
*
|
|
1537
|
+
* Thrown when required permissions are denied (e.g., microphone access).
|
|
1538
|
+
*
|
|
1539
|
+
* @example
|
|
1540
|
+
* ```typescript
|
|
1541
|
+
* throw new PermissionError('Microphone access denied', {
|
|
1542
|
+
* permission: 'microphone',
|
|
1543
|
+
* state: 'denied'
|
|
1544
|
+
* });
|
|
1545
|
+
* ```
|
|
1546
|
+
*/
|
|
1547
|
+
declare class PermissionError extends AnganyError {
|
|
1548
|
+
constructor(message: string, details?: any);
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Conversation-related errors
|
|
1552
|
+
*
|
|
1553
|
+
* Thrown when conversation operations fail.
|
|
1554
|
+
*
|
|
1555
|
+
* @example
|
|
1556
|
+
* ```typescript
|
|
1557
|
+
* throw new ConversationError('Failed to start conversation', {
|
|
1558
|
+
* resource: 'support-agent',
|
|
1559
|
+
* reason: 'resource_not_found'
|
|
1560
|
+
* });
|
|
1561
|
+
* ```
|
|
1562
|
+
*/
|
|
1563
|
+
declare class ConversationError extends AnganyError {
|
|
1564
|
+
constructor(message: string, details?: any);
|
|
1565
|
+
}
|
|
1566
|
+
/**
|
|
1567
|
+
* Configuration errors
|
|
1568
|
+
*
|
|
1569
|
+
* Thrown when SDK is misconfigured or required options are missing.
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```typescript
|
|
1573
|
+
* throw new ConfigurationError('Missing required option: apiUrl', {
|
|
1574
|
+
* option: 'apiUrl',
|
|
1575
|
+
* provided: config
|
|
1576
|
+
* });
|
|
1577
|
+
* ```
|
|
1578
|
+
*/
|
|
1579
|
+
declare class ConfigurationError extends AnganyError {
|
|
1580
|
+
constructor(message: string, details?: any);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Resource errors
|
|
1584
|
+
*
|
|
1585
|
+
* Thrown when requested resources are not found or unavailable.
|
|
1586
|
+
*
|
|
1587
|
+
* @example
|
|
1588
|
+
* ```typescript
|
|
1589
|
+
* throw new ResourceError('Voice bot not found', {
|
|
1590
|
+
* resource: 'custom-agent',
|
|
1591
|
+
* availableResources: ['support', 'sales']
|
|
1592
|
+
* });
|
|
1593
|
+
* ```
|
|
1594
|
+
*/
|
|
1595
|
+
declare class ResourceError extends AnganyError {
|
|
1596
|
+
constructor(message: string, details?: any);
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Validation errors
|
|
1600
|
+
*
|
|
1601
|
+
* Thrown when input validation fails.
|
|
1602
|
+
*
|
|
1603
|
+
* @example
|
|
1604
|
+
* ```typescript
|
|
1605
|
+
* throw new ValidationError('Invalid phone number format', {
|
|
1606
|
+
* field: 'phoneNumber',
|
|
1607
|
+
* value: '123',
|
|
1608
|
+
* pattern: /^\+?[1-9]\d{1,14}$/
|
|
1609
|
+
* });
|
|
1610
|
+
* ```
|
|
1611
|
+
*/
|
|
1612
|
+
declare class ValidationError extends AnganyError {
|
|
1613
|
+
constructor(message: string, details?: any);
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Media errors
|
|
1617
|
+
*
|
|
1618
|
+
* Thrown when audio/video operations fail.
|
|
1619
|
+
*
|
|
1620
|
+
* @example
|
|
1621
|
+
* ```typescript
|
|
1622
|
+
* throw new MediaError('Failed to acquire microphone', {
|
|
1623
|
+
* constraints: { audio: true },
|
|
1624
|
+
* browserError: error
|
|
1625
|
+
* });
|
|
1626
|
+
* ```
|
|
1627
|
+
*/
|
|
1628
|
+
declare class MediaError extends AnganyError {
|
|
1629
|
+
constructor(message: string, details?: any);
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Common error codes used throughout the SDK
|
|
1633
|
+
*
|
|
1634
|
+
* Use these constants for consistent error handling.
|
|
1635
|
+
*
|
|
1636
|
+
* @example
|
|
1637
|
+
* ```typescript
|
|
1638
|
+
* if (error.code === ErrorCodes.TOKEN_EXPIRED) {
|
|
1639
|
+
* await auth.refreshTokens();
|
|
1640
|
+
* }
|
|
1641
|
+
* ```
|
|
1642
|
+
*/
|
|
1643
|
+
declare const ErrorCodes: {
|
|
1644
|
+
readonly AUTH_REQUIRED: "AUTH_REQUIRED";
|
|
1645
|
+
readonly TOKEN_EXPIRED: "TOKEN_EXPIRED";
|
|
1646
|
+
readonly TOKEN_INVALID: "TOKEN_INVALID";
|
|
1647
|
+
readonly REFRESH_FAILED: "REFRESH_FAILED";
|
|
1648
|
+
readonly LOGIN_REQUIRED: "LOGIN_REQUIRED";
|
|
1649
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
1650
|
+
readonly NETWORK_ERROR: "NETWORK_ERROR";
|
|
1651
|
+
readonly CONNECTION_LOST: "CONNECTION_LOST";
|
|
1652
|
+
readonly TIMEOUT: "TIMEOUT";
|
|
1653
|
+
readonly SERVER_ERROR: "SERVER_ERROR";
|
|
1654
|
+
readonly RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND";
|
|
1655
|
+
readonly RESOURCE_UNAVAILABLE: "RESOURCE_UNAVAILABLE";
|
|
1656
|
+
readonly QUOTA_EXCEEDED: "QUOTA_EXCEEDED";
|
|
1657
|
+
readonly MICROPHONE_DENIED: "MICROPHONE_DENIED";
|
|
1658
|
+
readonly MICROPHONE_NOT_FOUND: "MICROPHONE_NOT_FOUND";
|
|
1659
|
+
readonly MEDIA_ERROR: "MEDIA_ERROR";
|
|
1660
|
+
readonly SIP_REGISTRATION_FAILED: "SIP_REGISTRATION_FAILED";
|
|
1661
|
+
readonly CALL_FAILED: "CALL_FAILED";
|
|
1662
|
+
readonly CONVERSATION_ENDED: "CONVERSATION_ENDED";
|
|
1663
|
+
readonly INVALID_CONFIG: "INVALID_CONFIG";
|
|
1664
|
+
readonly MISSING_REQUIRED_OPTION: "MISSING_REQUIRED_OPTION";
|
|
1665
|
+
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
1666
|
+
readonly NOT_IMPLEMENTED: "NOT_IMPLEMENTED";
|
|
1667
|
+
};
|
|
1668
|
+
/**
|
|
1669
|
+
* Helper function to check if an error is an SDK error
|
|
1670
|
+
*
|
|
1671
|
+
* @param error - Error to check
|
|
1672
|
+
* @returns True if the error is an AnganyError
|
|
1673
|
+
*
|
|
1674
|
+
* @example
|
|
1675
|
+
* ```typescript
|
|
1676
|
+
* try {
|
|
1677
|
+
* // SDK operation
|
|
1678
|
+
* } catch (error) {
|
|
1679
|
+
* if (isAnganyError(error)) {
|
|
1680
|
+
* console.log('SDK error code:', error.code);
|
|
1681
|
+
* }
|
|
1682
|
+
* }
|
|
1683
|
+
* ```
|
|
1684
|
+
*/
|
|
1685
|
+
declare function isAnganyError(error: unknown): error is AnganyError;
|
|
1686
|
+
/**
|
|
1687
|
+
* Helper function to check if an error is a specific type
|
|
1688
|
+
*
|
|
1689
|
+
* @param error - Error to check
|
|
1690
|
+
* @param code - Error code to match
|
|
1691
|
+
* @returns True if the error has the specified code
|
|
1692
|
+
*
|
|
1693
|
+
* @example
|
|
1694
|
+
* ```typescript
|
|
1695
|
+
* if (hasErrorCode(error, ErrorCodes.TOKEN_EXPIRED)) {
|
|
1696
|
+
* // Handle token expiration
|
|
1697
|
+
* }
|
|
1698
|
+
* ```
|
|
1699
|
+
*/
|
|
1700
|
+
declare function hasErrorCode(error: unknown, code: string): boolean;
|
|
1701
|
+
|
|
1702
|
+
/**
|
|
1703
|
+
* SDK version
|
|
1704
|
+
* This is automatically updated during the release process
|
|
1705
|
+
*/
|
|
1706
|
+
declare const VERSION = "0.0.1";
|
|
1707
|
+
|
|
1708
|
+
export { AnganyError, AnganyVoice, type AuthError, type AuthEvents, AuthManager, type AuthOptions, type AuthState, type AuthStatus, AuthenticationError, type BackendAuthOptions, type ClientCredentials, ConfigurationError, Conversation, ConversationError, type ConversationOptions, type ConversationState, type ConversationStatus, ErrorCodes, EventEmitter, type FrontendAuthOptions, type LogLevel, MediaError, NetworkError, PermissionError, ResourceError, type ServiceAccountAuthOptions, type ServiceAccountCredentials, type SpeakOptions, type TokenSet, type TranscriptionEvent, type UserInfo, VERSION, ValidationError, type VoiceConfig, type VoiceResource, hasErrorCode, isAnganyError };
|