@vapi-ai/web 1.1.7 → 1.2.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/api.js CHANGED
@@ -10,30 +10,7 @@
10
10
  * ---------------------------------------------------------------
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.Api = exports.HttpClient = exports.ContentType = exports.CreateWebCallDTO = void 0;
14
- class CreateWebCallDTO {
15
- /**
16
- * This is the assistant that will be used for the call. To use a transient assistant, use `assistant` instead.
17
- */
18
- assistantId;
19
- /**
20
- * Overrides for the assistant's settings and template variables.
21
- */
22
- assistantOverrides;
23
- /**
24
- * This is the assistant that will be used for the call. To use an existing assistant, use `assistantId` instead.
25
- */
26
- assistant;
27
- /**
28
- * This will expose SIP URI you can use to connect to the call. Disabled by default.
29
- */
30
- sipEnabled;
31
- /**
32
- * This is the metadata associated with the call.
33
- */
34
- metadata;
35
- }
36
- exports.CreateWebCallDTO = CreateWebCallDTO;
13
+ exports.Api = exports.HttpClient = exports.ContentType = void 0;
37
14
  var ContentType;
38
15
  (function (ContentType) {
39
16
  ContentType["Json"] = "application/json";
@@ -325,6 +302,40 @@ class Api extends HttpClient {
325
302
  format: 'json',
326
303
  ...params,
327
304
  }),
305
+ /**
306
+ * No description
307
+ *
308
+ * @tags Calls
309
+ * @name CallControllerDeleteCallData
310
+ * @summary Delete Call Data
311
+ * @request DELETE:/call/{id}
312
+ * @secure
313
+ */
314
+ callControllerDeleteCallData: (id, params = {}) => this.request({
315
+ path: `/call/${id}`,
316
+ method: 'DELETE',
317
+ secure: true,
318
+ format: 'json',
319
+ ...params,
320
+ }),
321
+ /**
322
+ * No description
323
+ *
324
+ * @tags Calls
325
+ * @name CallControllerUpdate
326
+ * @summary Update Call
327
+ * @request PATCH:/call/{id}
328
+ * @secure
329
+ */
330
+ callControllerUpdate: (id, data, params = {}) => this.request({
331
+ path: `/call/${id}`,
332
+ method: 'PATCH',
333
+ body: data,
334
+ secure: true,
335
+ type: ContentType.Json,
336
+ format: 'json',
337
+ ...params,
338
+ }),
328
339
  /**
329
340
  * No description
330
341
  *
@@ -591,58 +602,179 @@ class Api extends HttpClient {
591
602
  ...params,
592
603
  }),
593
604
  };
594
- voiceLibrary = {
605
+ log = {
595
606
  /**
596
607
  * No description
597
608
  *
598
- * @tags Voice Library
599
- * @name VoiceLibraryControllerVoiceGetByProvider
600
- * @summary Get voices in Voice Library by Providers
601
- * @request GET:/voice-library/{provider}
609
+ * @tags Logs
610
+ * @name LoggingControllerGetLogs
611
+ * @summary Get Call Logs
612
+ * @request GET:/log
602
613
  * @secure
603
614
  */
604
- voiceLibraryControllerVoiceGetByProvider: (provider, params = {}) => this.request({
605
- path: `/voice-library/${provider}`,
615
+ loggingControllerGetLogs: (query, params = {}) => this.request({
616
+ path: `/log`,
606
617
  method: 'GET',
618
+ query: query,
607
619
  secure: true,
608
620
  format: 'json',
609
621
  ...params,
610
622
  }),
623
+ };
624
+ tool = {
611
625
  /**
612
626
  * No description
613
627
  *
614
- * @tags Voice Library
615
- * @name VoiceLibraryControllerVoiceLibrarySyncByProvider
616
- * @summary Sync voices in Voice Library by Providers
617
- * @request POST:/voice-library/sync/{provider}
628
+ * @tags Tools
629
+ * @name ToolControllerCreate
630
+ * @summary Create Tool
631
+ * @request POST:/tool
618
632
  * @secure
619
633
  */
620
- voiceLibraryControllerVoiceLibrarySyncByProvider: (provider, params = {}) => this.request({
621
- path: `/voice-library/sync/${provider}`,
634
+ toolControllerCreate: (data, params = {}) => this.request({
635
+ path: `/tool`,
622
636
  method: 'POST',
637
+ body: data,
623
638
  secure: true,
639
+ type: ContentType.Json,
624
640
  format: 'json',
625
641
  ...params,
626
642
  }),
627
- };
628
- logging = {
629
643
  /**
630
644
  * No description
631
645
  *
632
- * @tags Logging
633
- * @name LoggingControllerGetLogs
634
- * @summary Get Logging Logs
635
- * @request GET:/logging
646
+ * @tags Tools
647
+ * @name ToolControllerFindAll
648
+ * @summary List Tools
649
+ * @request GET:/tool
636
650
  * @secure
637
651
  */
638
- loggingControllerGetLogs: (query, params = {}) => this.request({
639
- path: `/logging`,
652
+ toolControllerFindAll: (query, params = {}) => this.request({
653
+ path: `/tool`,
640
654
  method: 'GET',
641
655
  query: query,
642
656
  secure: true,
643
657
  format: 'json',
644
658
  ...params,
645
659
  }),
660
+ /**
661
+ * No description
662
+ *
663
+ * @tags Tools
664
+ * @name ToolControllerFindOne
665
+ * @summary Get Tool
666
+ * @request GET:/tool/{id}
667
+ * @secure
668
+ */
669
+ toolControllerFindOne: (id, params = {}) => this.request({
670
+ path: `/tool/${id}`,
671
+ method: 'GET',
672
+ secure: true,
673
+ format: 'json',
674
+ ...params,
675
+ }),
676
+ /**
677
+ * No description
678
+ *
679
+ * @tags Tools
680
+ * @name ToolControllerUpdate
681
+ * @summary Update Tool
682
+ * @request PATCH:/tool/{id}
683
+ * @secure
684
+ */
685
+ toolControllerUpdate: (id, data, params = {}) => this.request({
686
+ path: `/tool/${id}`,
687
+ method: 'PATCH',
688
+ body: data,
689
+ secure: true,
690
+ type: ContentType.Json,
691
+ format: 'json',
692
+ ...params,
693
+ }),
694
+ /**
695
+ * No description
696
+ *
697
+ * @tags Tools
698
+ * @name ToolControllerRemove
699
+ * @summary Delete Tool
700
+ * @request DELETE:/tool/{id}
701
+ * @secure
702
+ */
703
+ toolControllerRemove: (id, params = {}) => this.request({
704
+ path: `/tool/${id}`,
705
+ method: 'DELETE',
706
+ secure: true,
707
+ format: 'json',
708
+ ...params,
709
+ }),
710
+ };
711
+ file = {
712
+ /**
713
+ * No description
714
+ *
715
+ * @tags Files
716
+ * @name FileControllerCreate
717
+ * @summary Upload File
718
+ * @request POST:/file/upload
719
+ * @secure
720
+ */
721
+ fileControllerCreate: (data, params = {}) => this.request({
722
+ path: `/file/upload`,
723
+ method: 'POST',
724
+ body: data,
725
+ secure: true,
726
+ type: ContentType.FormData,
727
+ format: 'json',
728
+ ...params,
729
+ }),
730
+ /**
731
+ * No description
732
+ *
733
+ * @tags Files
734
+ * @name FileControllerFindAll
735
+ * @summary List Files
736
+ * @request GET:/file
737
+ * @secure
738
+ */
739
+ fileControllerFindAll: (params = {}) => this.request({
740
+ path: `/file`,
741
+ method: 'GET',
742
+ secure: true,
743
+ format: 'json',
744
+ ...params,
745
+ }),
746
+ /**
747
+ * No description
748
+ *
749
+ * @tags Files
750
+ * @name FileControllerFindOne
751
+ * @summary Get File
752
+ * @request GET:/file/{id}
753
+ * @secure
754
+ */
755
+ fileControllerFindOne: (id, params = {}) => this.request({
756
+ path: `/file/${id}`,
757
+ method: 'GET',
758
+ secure: true,
759
+ format: 'json',
760
+ ...params,
761
+ }),
762
+ /**
763
+ * No description
764
+ *
765
+ * @tags Files
766
+ * @name FileControllerRemove
767
+ * @summary Delete File
768
+ * @request DELETE:/file/{id}
769
+ * @secure
770
+ */
771
+ fileControllerRemove: (id, params = {}) => this.request({
772
+ path: `/file/${id}`,
773
+ method: 'DELETE',
774
+ secure: true,
775
+ format: 'json',
776
+ ...params,
777
+ }),
646
778
  };
647
779
  }
648
780
  exports.Api = Api;
package/dist/vapi.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
- import { Call, CreateAssistantDTO, OverrideAssistantDTO } from './api';
2
+ import { Call, CreateAssistantDTO, CreateSquadDTO, OverrideAssistantDTO } from './api';
3
+ import { DailyCall } from '@daily-co/daily-js';
3
4
  import type { ChatCompletionMessageParam } from 'openai/resources';
4
5
  import EventEmitter from 'events';
5
6
  export interface AddMessageMessage {
@@ -37,10 +38,9 @@ export default class Vapi extends VapiEventEmitter {
37
38
  private started;
38
39
  private call;
39
40
  private speakingTimeout;
40
- private averageSpeechLevel;
41
41
  constructor(apiToken: string, apiBaseUrl?: string);
42
42
  private cleanup;
43
- start(assistant: CreateAssistantDTO | string, assistantOverrides?: OverrideAssistantDTO): Promise<Call | null>;
43
+ start(assistant?: CreateAssistantDTO | string, assistantOverrides?: OverrideAssistantDTO, squad?: CreateSquadDTO | string): Promise<Call | null>;
44
44
  private onAppMessage;
45
45
  private handleRemoteParticipantsAudioLevel;
46
46
  stop(): void;
@@ -48,5 +48,7 @@ export default class Vapi extends VapiEventEmitter {
48
48
  setMuted(mute: boolean): void;
49
49
  isMuted(): boolean;
50
50
  say(message: string, endCallAfterSpoken?: boolean): void;
51
+ setInputDevicesAsync(options: Parameters<DailyCall['setInputDevicesAsync']>[0]): void;
52
+ setOutputDeviceAsync(options: Parameters<DailyCall['setOutputDeviceAsync']>[0]): void;
51
53
  }
52
54
  export {};
package/dist/vapi.js CHANGED
@@ -60,7 +60,6 @@ class Vapi extends VapiEventEmitter {
60
60
  started = false;
61
61
  call = null;
62
62
  speakingTimeout = null;
63
- averageSpeechLevel = 0;
64
63
  constructor(apiToken, apiBaseUrl) {
65
64
  super();
66
65
  client_1.client.baseUrl = apiBaseUrl ?? 'https://api.vapi.ai';
@@ -72,7 +71,10 @@ class Vapi extends VapiEventEmitter {
72
71
  this.call = null;
73
72
  this.speakingTimeout = null;
74
73
  }
75
- async start(assistant, assistantOverrides) {
74
+ async start(assistant, assistantOverrides, squad) {
75
+ if (!assistant && !squad) {
76
+ throw new Error('Assistant or Squad must be provided.');
77
+ }
76
78
  if (this.started) {
77
79
  return null;
78
80
  }
@@ -82,6 +84,8 @@ class Vapi extends VapiEventEmitter {
82
84
  assistant: typeof assistant === 'string' ? undefined : assistant,
83
85
  assistantId: typeof assistant === 'string' ? assistant : undefined,
84
86
  assistantOverrides,
87
+ squad: typeof squad === 'string' ? undefined : squad,
88
+ squadId: typeof squad === 'string' ? squad : undefined,
85
89
  })).data;
86
90
  if (this.call) {
87
91
  this.cleanup();
@@ -133,6 +137,22 @@ class Vapi extends VapiEventEmitter {
133
137
  this.handleRemoteParticipantsAudioLevel(e);
134
138
  });
135
139
  this.call.on('app-message', (e) => this.onAppMessage(e));
140
+ this.call.on('nonfatal-error', (e) => {
141
+ // https://docs.daily.co/reference/daily-js/events/meeting-events#type-audio-processor-error
142
+ if (e?.type === 'audio-processor-error') {
143
+ this.call
144
+ ?.updateInputSettings({
145
+ audio: {
146
+ processor: {
147
+ type: 'none',
148
+ },
149
+ },
150
+ })
151
+ .then(() => {
152
+ this.call?.setLocalAudio(true);
153
+ });
154
+ }
155
+ });
136
156
  this.call.updateInputSettings({
137
157
  audio: {
138
158
  processor: {
@@ -225,5 +245,11 @@ class Vapi extends VapiEventEmitter {
225
245
  endCallAfterSpoken
226
246
  });
227
247
  }
248
+ setInputDevicesAsync(options) {
249
+ this.call?.setInputDevicesAsync(options);
250
+ }
251
+ setOutputDeviceAsync(options) {
252
+ this.call?.setOutputDeviceAsync(options);
253
+ }
228
254
  }
229
255
  exports.default = Vapi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vapi-ai/web",
3
- "version": "1.1.7",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "dist/vapi.js",
6
6
  "types": "dist/vapi.d.ts",
package/update.sh CHANGED
@@ -1 +1 @@
1
- npm version patch && npm run build && npm publish && cd ../landing && npm install @vapi-ai/web@latest && cd -
1
+ npm version minor && npm run build && npm publish && cd ../landing && npm install @vapi-ai/web@latest && cd -
package/vapi.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Call, CreateAssistantDTO, OverrideAssistantDTO } from './api';
1
+ import { Call, CreateAssistantDTO, CreateSquadDTO, OverrideAssistantDTO } from './api';
2
2
  import DailyIframe, {
3
3
  DailyCall,
4
4
  DailyEventObjectAppMessage,
@@ -103,7 +103,6 @@ export default class Vapi extends VapiEventEmitter {
103
103
  private started: boolean = false;
104
104
  private call: DailyCall | null = null;
105
105
  private speakingTimeout: NodeJS.Timeout | null = null;
106
- private averageSpeechLevel: number = 0;
107
106
 
108
107
  constructor(apiToken: string, apiBaseUrl?: string) {
109
108
  super();
@@ -119,13 +118,17 @@ export default class Vapi extends VapiEventEmitter {
119
118
  }
120
119
 
121
120
  async start(
122
- assistant: CreateAssistantDTO | string,
121
+ assistant?: CreateAssistantDTO | string,
123
122
  assistantOverrides?: OverrideAssistantDTO,
123
+ squad?: CreateSquadDTO | string,
124
124
  ): Promise<Call | null> {
125
+ if (!assistant && !squad) {
126
+ throw new Error('Assistant or Squad must be provided.');
127
+ }
128
+
125
129
  if (this.started) {
126
130
  return null;
127
131
  }
128
-
129
132
  this.started = true;
130
133
 
131
134
  try {
@@ -134,6 +137,8 @@ export default class Vapi extends VapiEventEmitter {
134
137
  assistant: typeof assistant === 'string' ? undefined : assistant,
135
138
  assistantId: typeof assistant === 'string' ? assistant : undefined,
136
139
  assistantOverrides,
140
+ squad: typeof squad === 'string' ? undefined : squad,
141
+ squadId: typeof squad === 'string' ? squad : undefined,
137
142
  })
138
143
  ).data;
139
144
 
@@ -193,6 +198,23 @@ export default class Vapi extends VapiEventEmitter {
193
198
 
194
199
  this.call.on('app-message', (e) => this.onAppMessage(e));
195
200
 
201
+ this.call.on('nonfatal-error', (e) => {
202
+ // https://docs.daily.co/reference/daily-js/events/meeting-events#type-audio-processor-error
203
+ if (e?.type === 'audio-processor-error') {
204
+ this.call
205
+ ?.updateInputSettings({
206
+ audio: {
207
+ processor: {
208
+ type: 'none',
209
+ },
210
+ },
211
+ })
212
+ .then(() => {
213
+ this.call?.setLocalAudio(true);
214
+ });
215
+ }
216
+ });
217
+
196
218
  this.call.updateInputSettings({
197
219
  audio: {
198
220
  processor: {
@@ -289,4 +311,13 @@ export default class Vapi extends VapiEventEmitter {
289
311
  endCallAfterSpoken
290
312
  })
291
313
  }
314
+
315
+
316
+ public setInputDevicesAsync(options: Parameters<DailyCall['setInputDevicesAsync']>[0]) {
317
+ this.call?.setInputDevicesAsync(options)
318
+ }
319
+
320
+ public setOutputDeviceAsync(options: Parameters<DailyCall['setOutputDeviceAsync']>[0]) {
321
+ this.call?.setOutputDeviceAsync(options)
322
+ }
292
323
  }
@@ -1,17 +0,0 @@
1
- /// <reference types="node" />
2
- import EventEmitter from "events";
3
- declare global {
4
- interface Window {
5
- ManagedMediaSource: any;
6
- }
7
- }
8
- declare class AtomicMediaSource extends EventEmitter {
9
- mediaSource: any;
10
- sourceBuffer: SourceBuffer | null;
11
- private operationsQueue;
12
- constructor();
13
- appendBuffer(buffer: ArrayBuffer): void;
14
- clearBuffer(): void;
15
- private createOperationQueue;
16
- }
17
- export default AtomicMediaSource;
@@ -1,78 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const async_1 = __importDefault(require("async"));
7
- const events_1 = __importDefault(require("events"));
8
- // ManagedMediaSource needed for iOS Safari
9
- function getMediaSource() {
10
- if (window.ManagedMediaSource) {
11
- return new window.ManagedMediaSource();
12
- }
13
- if (window.MediaSource) {
14
- return new window.MediaSource();
15
- }
16
- return null;
17
- }
18
- class AtomicMediaSource extends events_1.default {
19
- constructor() {
20
- super();
21
- this.sourceBuffer = null;
22
- this.mediaSource = getMediaSource();
23
- this.operationsQueue = this.createOperationQueue();
24
- if (!this.mediaSource) {
25
- console.error("MediaSource is not supported in your browser.");
26
- // Display a message to the user, or handle this situation in another way
27
- return;
28
- }
29
- this.mediaSource.addEventListener("sourceopen", () => {
30
- this.mediaSource.duration = Number.POSITIVE_INFINITY;
31
- this.sourceBuffer = this.mediaSource.addSourceBuffer('audio/webm; codecs="opus"');
32
- if (this.sourceBuffer) {
33
- this.sourceBuffer.mode = "sequence";
34
- }
35
- });
36
- }
37
- appendBuffer(buffer) {
38
- this.operationsQueue.push(() => {
39
- return new Promise((resolve, reject) => {
40
- if (this.sourceBuffer) {
41
- this.sourceBuffer.addEventListener("updateend", () => {
42
- resolve();
43
- }, { once: true });
44
- this.sourceBuffer.appendBuffer(buffer);
45
- }
46
- else {
47
- reject();
48
- }
49
- });
50
- });
51
- }
52
- clearBuffer() {
53
- // this.operationsQueue.push(() => {
54
- // return new Promise((resolve, reject) => {
55
- // if (this.sourceBuffer) {
56
- // this.sourceBuffer.addEventListener(
57
- // "updateend",
58
- // () => {
59
- // resolve();
60
- // },
61
- // { once: true }
62
- // );
63
- // if (this.sourceBuffer.buffered.length > 0) {
64
- // this.sourceBuffer.remove(0, this.sourceBuffer.buffered.end(0));
65
- // }
66
- // } else {
67
- // reject();
68
- // }
69
- // });
70
- // });
71
- }
72
- createOperationQueue() {
73
- return async_1.default.queue((task, callback) => {
74
- task().then(() => callback());
75
- }, 1);
76
- }
77
- }
78
- exports.default = AtomicMediaSource;
package/dist/player.d.ts DELETED
@@ -1,10 +0,0 @@
1
- /// <reference types="node" />
2
- import EventEmitter from "events";
3
- export declare class ContinuousPlayer extends EventEmitter {
4
- private atomic;
5
- private audio;
6
- constructor();
7
- start(): void;
8
- playChunk(audioData: ArrayBuffer): void;
9
- clear(): void;
10
- }
package/dist/player.js DELETED
@@ -1,38 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ContinuousPlayer = void 0;
7
- const AtomicMediaSource_1 = __importDefault(require("./AtomicMediaSource"));
8
- const events_1 = __importDefault(require("events"));
9
- class ContinuousPlayer extends events_1.default {
10
- constructor() {
11
- super();
12
- this.audio = document.createElement("audio");
13
- this.audio.addEventListener("playing", () => this.emit("speech-start"));
14
- this.audio.addEventListener("play", () => this.emit("speech-start"));
15
- this.audio.addEventListener("canplay", () => {
16
- this.audio.play();
17
- });
18
- this.audio.addEventListener("waiting", () => this.emit("speech-end"));
19
- this.atomic = new AtomicMediaSource_1.default();
20
- this.audio.src = URL.createObjectURL(this.atomic.mediaSource);
21
- document.body.appendChild(this.audio);
22
- }
23
- start() {
24
- this.audio.play();
25
- }
26
- playChunk(audioData) {
27
- var _a;
28
- (_a = this.atomic.sourceBuffer) === null || _a === void 0 ? void 0 : _a.addEventListener("updateend", () => {
29
- this.audio.play().catch((error) => console.error("Play error:", error));
30
- }, { once: true });
31
- this.atomic.appendBuffer(audioData);
32
- }
33
- clear() {
34
- this.audio.pause();
35
- this.atomic.clearBuffer();
36
- }
37
- }
38
- exports.ContinuousPlayer = ContinuousPlayer;