@vapi-ai/web 2.7.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vapi.d.ts +19 -0
- package/dist/vapi.js +55 -10
- package/package.json +3 -3
- package/vapi.ts +72 -22
package/dist/vapi.d.ts
CHANGED
|
@@ -154,6 +154,25 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
154
154
|
* consumers register. Audio processing is non-critical, so the call continues.
|
|
155
155
|
*/
|
|
156
156
|
private emitAudioProcessingError;
|
|
157
|
+
/**
|
|
158
|
+
* Starts Daily's local (microphone) audio level observer.
|
|
159
|
+
*
|
|
160
|
+
* Only runs when something is listening for 'local-volume-level'. The observer
|
|
161
|
+
* costs an AudioContext plus an AudioWorklet for the lifetime of the call and
|
|
162
|
+
* nothing else in the SDK reads the level, so starting it unconditionally
|
|
163
|
+
* charges every consumer for a feature almost none of them use. Listeners
|
|
164
|
+
* attached after the call is under way should call the public
|
|
165
|
+
* `startLocalAudioLevelObserver()`.
|
|
166
|
+
*
|
|
167
|
+
* Must run after the noise-cancellation processor has settled. Krisp replaces
|
|
168
|
+
* the microphone track, Daily reacts to any local track change by closing the
|
|
169
|
+
* AudioContext its in-flight `audioWorklet.addModule()` is still loading into,
|
|
170
|
+
* and Chrome and Firefox reject that load with "AbortError: Unable to load a
|
|
171
|
+
* worklet's module". Daily answers by stopping the observer for the rest of
|
|
172
|
+
* the call, so losing this race costs the feature, not just console noise.
|
|
173
|
+
* Tracked upstream at https://github.com/daily-co/daily-js/issues/317.
|
|
174
|
+
*/
|
|
175
|
+
private maybeStartLocalAudioLevelObserver;
|
|
157
176
|
start(assistant?: CreateAssistantDTO | string, assistantOverrides?: AssistantOverrides, squad?: CreateSquadDTO | string, workflow?: CreateWorkflowDTO | string, workflowOverrides?: WorkflowOverrides, options?: StartCallOptions): Promise<Call | null>;
|
|
158
177
|
private onAppMessage;
|
|
159
178
|
private handleRemoteParticipantsAudioLevel;
|
package/dist/vapi.js
CHANGED
|
@@ -181,6 +181,35 @@ class Vapi extends VapiEventEmitter {
|
|
|
181
181
|
timestamp: new Date().toISOString(),
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Starts Daily's local (microphone) audio level observer.
|
|
186
|
+
*
|
|
187
|
+
* Only runs when something is listening for 'local-volume-level'. The observer
|
|
188
|
+
* costs an AudioContext plus an AudioWorklet for the lifetime of the call and
|
|
189
|
+
* nothing else in the SDK reads the level, so starting it unconditionally
|
|
190
|
+
* charges every consumer for a feature almost none of them use. Listeners
|
|
191
|
+
* attached after the call is under way should call the public
|
|
192
|
+
* `startLocalAudioLevelObserver()`.
|
|
193
|
+
*
|
|
194
|
+
* Must run after the noise-cancellation processor has settled. Krisp replaces
|
|
195
|
+
* the microphone track, Daily reacts to any local track change by closing the
|
|
196
|
+
* AudioContext its in-flight `audioWorklet.addModule()` is still loading into,
|
|
197
|
+
* and Chrome and Firefox reject that load with "AbortError: Unable to load a
|
|
198
|
+
* worklet's module". Daily answers by stopping the observer for the rest of
|
|
199
|
+
* the call, so losing this race costs the feature, not just console noise.
|
|
200
|
+
* Tracked upstream at https://github.com/daily-co/daily-js/issues/317.
|
|
201
|
+
*/
|
|
202
|
+
async maybeStartLocalAudioLevelObserver() {
|
|
203
|
+
if (!this.call || this.listenerCount('local-volume-level') === 0) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
await this.call.startLocalAudioLevelObserver(100);
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.emit('local-audio-level-observer-error', serializeError(error));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
184
213
|
async start(assistant, assistantOverrides, squad, workflow, workflowOverrides, options) {
|
|
185
214
|
const startTime = Date.now();
|
|
186
215
|
// Input validation with detailed error messages
|
|
@@ -542,7 +571,6 @@ class Vapi extends VapiEventEmitter {
|
|
|
542
571
|
const audioObserverStartTime = Date.now();
|
|
543
572
|
try {
|
|
544
573
|
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
545
|
-
this.call.startLocalAudioLevelObserver(100);
|
|
546
574
|
const audioObserverDuration = Date.now() - audioObserverStartTime;
|
|
547
575
|
this.emit('call-start-progress', {
|
|
548
576
|
stage: 'audio-observer-setup',
|
|
@@ -608,17 +636,26 @@ class Vapi extends VapiEventEmitter {
|
|
|
608
636
|
});
|
|
609
637
|
const audioProcessingStartTime = Date.now();
|
|
610
638
|
try {
|
|
611
|
-
this.call
|
|
612
|
-
.updateInputSettings({
|
|
639
|
+
const audioProcessingUpdate = this.call.updateInputSettings({
|
|
613
640
|
audio: {
|
|
614
641
|
processor: {
|
|
615
642
|
type: 'noise-cancellation',
|
|
616
643
|
},
|
|
617
644
|
},
|
|
618
|
-
})
|
|
619
|
-
|
|
645
|
+
});
|
|
646
|
+
audioProcessingUpdate.catch((error) => {
|
|
620
647
|
this.emitAudioProcessingError('audio-processing-setup', error);
|
|
621
648
|
});
|
|
649
|
+
// The observer waits for this update rather than starting alongside the
|
|
650
|
+
// remote one above, so that Krisp has already swapped the microphone
|
|
651
|
+
// track. See maybeStartLocalAudioLevelObserver().
|
|
652
|
+
//
|
|
653
|
+
// A separate chain, not another link on the one above: EventEmitter
|
|
654
|
+
// rethrows out of emit('error') when a consumer registered no 'error'
|
|
655
|
+
// listener, and whether the observer starts must not hinge on that.
|
|
656
|
+
audioProcessingUpdate
|
|
657
|
+
.catch(() => { })
|
|
658
|
+
.then(() => this.maybeStartLocalAudioLevelObserver());
|
|
622
659
|
const audioProcessingDuration = Date.now() - audioProcessingStartTime;
|
|
623
660
|
this.emit('call-start-progress', {
|
|
624
661
|
stage: 'audio-processing-setup',
|
|
@@ -1361,7 +1398,6 @@ class Vapi extends VapiEventEmitter {
|
|
|
1361
1398
|
const audioObserverStartTime = Date.now();
|
|
1362
1399
|
try {
|
|
1363
1400
|
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
1364
|
-
this.call.startLocalAudioLevelObserver(100);
|
|
1365
1401
|
const audioObserverDuration = Date.now() - audioObserverStartTime;
|
|
1366
1402
|
this.emit('call-start-progress', {
|
|
1367
1403
|
stage: 'audio-observer-setup',
|
|
@@ -1390,17 +1426,26 @@ class Vapi extends VapiEventEmitter {
|
|
|
1390
1426
|
});
|
|
1391
1427
|
const audioProcessingStartTime = Date.now();
|
|
1392
1428
|
try {
|
|
1393
|
-
this.call
|
|
1394
|
-
.updateInputSettings({
|
|
1429
|
+
const audioProcessingUpdate = this.call.updateInputSettings({
|
|
1395
1430
|
audio: {
|
|
1396
1431
|
processor: {
|
|
1397
1432
|
type: 'noise-cancellation',
|
|
1398
1433
|
},
|
|
1399
1434
|
},
|
|
1400
|
-
})
|
|
1401
|
-
|
|
1435
|
+
});
|
|
1436
|
+
audioProcessingUpdate.catch((error) => {
|
|
1402
1437
|
this.emitAudioProcessingError('audio-processing-setup', error);
|
|
1403
1438
|
});
|
|
1439
|
+
// The observer waits for this update rather than starting alongside the
|
|
1440
|
+
// remote one above, so that Krisp has already swapped the microphone
|
|
1441
|
+
// track. See maybeStartLocalAudioLevelObserver().
|
|
1442
|
+
//
|
|
1443
|
+
// A separate chain, not another link on the one above: EventEmitter
|
|
1444
|
+
// rethrows out of emit('error') when a consumer registered no 'error'
|
|
1445
|
+
// listener, and whether the observer starts must not hinge on that.
|
|
1446
|
+
audioProcessingUpdate
|
|
1447
|
+
.catch(() => { })
|
|
1448
|
+
.then(() => this.maybeStartLocalAudioLevelObserver());
|
|
1404
1449
|
const audioProcessingDuration = Date.now() - audioProcessingStartTime;
|
|
1405
1450
|
this.emit('call-start-progress', {
|
|
1406
1451
|
stage: 'audio-processing-setup',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vapi-ai/web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/vapi.js",
|
|
6
6
|
"types": "dist/vapi.d.ts",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/VapiAI/client-sdk-web#readme",
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
31
|
+
"node": ">=22.14.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@daily-co/daily-js": "^0.
|
|
34
|
+
"@daily-co/daily-js": "^0.93.0",
|
|
35
35
|
"events": "^3.3.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
package/vapi.ts
CHANGED
|
@@ -423,6 +423,36 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Starts Daily's local (microphone) audio level observer.
|
|
428
|
+
*
|
|
429
|
+
* Only runs when something is listening for 'local-volume-level'. The observer
|
|
430
|
+
* costs an AudioContext plus an AudioWorklet for the lifetime of the call and
|
|
431
|
+
* nothing else in the SDK reads the level, so starting it unconditionally
|
|
432
|
+
* charges every consumer for a feature almost none of them use. Listeners
|
|
433
|
+
* attached after the call is under way should call the public
|
|
434
|
+
* `startLocalAudioLevelObserver()`.
|
|
435
|
+
*
|
|
436
|
+
* Must run after the noise-cancellation processor has settled. Krisp replaces
|
|
437
|
+
* the microphone track, Daily reacts to any local track change by closing the
|
|
438
|
+
* AudioContext its in-flight `audioWorklet.addModule()` is still loading into,
|
|
439
|
+
* and Chrome and Firefox reject that load with "AbortError: Unable to load a
|
|
440
|
+
* worklet's module". Daily answers by stopping the observer for the rest of
|
|
441
|
+
* the call, so losing this race costs the feature, not just console noise.
|
|
442
|
+
* Tracked upstream at https://github.com/daily-co/daily-js/issues/317.
|
|
443
|
+
*/
|
|
444
|
+
private async maybeStartLocalAudioLevelObserver(): Promise<void> {
|
|
445
|
+
if (!this.call || this.listenerCount('local-volume-level') === 0) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
await this.call.startLocalAudioLevelObserver(100);
|
|
451
|
+
} catch (error) {
|
|
452
|
+
this.emit('local-audio-level-observer-error', serializeError(error));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
426
456
|
async start(
|
|
427
457
|
assistant?: CreateAssistantDTO | string,
|
|
428
458
|
assistantOverrides?: AssistantOverrides,
|
|
@@ -835,7 +865,6 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
835
865
|
|
|
836
866
|
try {
|
|
837
867
|
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
838
|
-
this.call.startLocalAudioLevelObserver(100);
|
|
839
868
|
const audioObserverDuration = Date.now() - audioObserverStartTime;
|
|
840
869
|
this.emit('call-start-progress', {
|
|
841
870
|
stage: 'audio-observer-setup',
|
|
@@ -905,17 +934,28 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
905
934
|
const audioProcessingStartTime = Date.now();
|
|
906
935
|
|
|
907
936
|
try {
|
|
908
|
-
this.call
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
type: 'noise-cancellation',
|
|
913
|
-
},
|
|
937
|
+
const audioProcessingUpdate = this.call.updateInputSettings({
|
|
938
|
+
audio: {
|
|
939
|
+
processor: {
|
|
940
|
+
type: 'noise-cancellation',
|
|
914
941
|
},
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
942
|
+
},
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
audioProcessingUpdate.catch((error) => {
|
|
946
|
+
this.emitAudioProcessingError('audio-processing-setup', error);
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
// The observer waits for this update rather than starting alongside the
|
|
950
|
+
// remote one above, so that Krisp has already swapped the microphone
|
|
951
|
+
// track. See maybeStartLocalAudioLevelObserver().
|
|
952
|
+
//
|
|
953
|
+
// A separate chain, not another link on the one above: EventEmitter
|
|
954
|
+
// rethrows out of emit('error') when a consumer registered no 'error'
|
|
955
|
+
// listener, and whether the observer starts must not hinge on that.
|
|
956
|
+
audioProcessingUpdate
|
|
957
|
+
.catch(() => {})
|
|
958
|
+
.then(() => this.maybeStartLocalAudioLevelObserver());
|
|
919
959
|
|
|
920
960
|
const audioProcessingDuration = Date.now() - audioProcessingStartTime;
|
|
921
961
|
this.emit('call-start-progress', {
|
|
@@ -1758,7 +1798,6 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
1758
1798
|
|
|
1759
1799
|
try {
|
|
1760
1800
|
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
1761
|
-
this.call.startLocalAudioLevelObserver(100);
|
|
1762
1801
|
const audioObserverDuration = Date.now() - audioObserverStartTime;
|
|
1763
1802
|
this.emit('call-start-progress', {
|
|
1764
1803
|
stage: 'audio-observer-setup',
|
|
@@ -1789,17 +1828,28 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
1789
1828
|
const audioProcessingStartTime = Date.now();
|
|
1790
1829
|
|
|
1791
1830
|
try {
|
|
1792
|
-
this.call
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
type: 'noise-cancellation',
|
|
1797
|
-
},
|
|
1831
|
+
const audioProcessingUpdate = this.call.updateInputSettings({
|
|
1832
|
+
audio: {
|
|
1833
|
+
processor: {
|
|
1834
|
+
type: 'noise-cancellation',
|
|
1798
1835
|
},
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1836
|
+
},
|
|
1837
|
+
});
|
|
1838
|
+
|
|
1839
|
+
audioProcessingUpdate.catch((error) => {
|
|
1840
|
+
this.emitAudioProcessingError('audio-processing-setup', error);
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
// The observer waits for this update rather than starting alongside the
|
|
1844
|
+
// remote one above, so that Krisp has already swapped the microphone
|
|
1845
|
+
// track. See maybeStartLocalAudioLevelObserver().
|
|
1846
|
+
//
|
|
1847
|
+
// A separate chain, not another link on the one above: EventEmitter
|
|
1848
|
+
// rethrows out of emit('error') when a consumer registered no 'error'
|
|
1849
|
+
// listener, and whether the observer starts must not hinge on that.
|
|
1850
|
+
audioProcessingUpdate
|
|
1851
|
+
.catch(() => {})
|
|
1852
|
+
.then(() => this.maybeStartLocalAudioLevelObserver());
|
|
1803
1853
|
|
|
1804
1854
|
const audioProcessingDuration = Date.now() - audioProcessingStartTime;
|
|
1805
1855
|
this.emit('call-start-progress', {
|