@vapi-ai/web 1.1.5 → 1.1.7

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/api.ts CHANGED
@@ -772,6 +772,8 @@ export interface OpenAIModel {
772
772
  provider: 'openai';
773
773
  /** This is the OpenAI model that will be used. */
774
774
  model:
775
+ | 'gpt-4o'
776
+ | 'gpt-4o-2024-05-13'
775
777
  | 'gpt-4-turbo'
776
778
  | 'gpt-4-turbo-2024-04-09'
777
779
  | 'gpt-4-turbo-preview'
@@ -789,6 +791,8 @@ export interface OpenAIModel {
789
791
  * @example ["gpt-4-0125-preview","gpt-4-0613"]
790
792
  */
791
793
  fallbackModels?:
794
+ | 'gpt-4o'
795
+ | 'gpt-4o-2024-05-13'
792
796
  | 'gpt-4-turbo'
793
797
  | 'gpt-4-turbo-2024-04-09'
794
798
  | 'gpt-4-turbo-preview'
@@ -0,0 +1,17 @@
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;
@@ -0,0 +1,78 @@
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/api.d.ts CHANGED
@@ -503,12 +503,12 @@ export interface OpenAIModel {
503
503
  /** This is the provider that will be used for the model. */
504
504
  provider: 'openai';
505
505
  /** This is the OpenAI model that will be used. */
506
- model: 'gpt-4-turbo' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo-preview' | 'gpt-4-0125-preview' | 'gpt-4-1106-preview' | 'gpt-4' | 'gpt-4-0613' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-0613';
506
+ model: 'gpt-4o' | 'gpt-4o-2024-05-13' | 'gpt-4-turbo' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo-preview' | 'gpt-4-0125-preview' | 'gpt-4-1106-preview' | 'gpt-4' | 'gpt-4-0613' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-0613';
507
507
  /**
508
508
  * These are the fallback models that will be used if the primary model fails. This shouldn't be specified unless you have a specific reason to do so. Vapi will automatically find the fastest fallbacks that make sense.
509
509
  * @example ["gpt-4-0125-preview","gpt-4-0613"]
510
510
  */
511
- fallbackModels?: 'gpt-4-turbo' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo-preview' | 'gpt-4-0125-preview' | 'gpt-4-1106-preview' | 'gpt-4' | 'gpt-4-0613' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-0613';
511
+ fallbackModels?: 'gpt-4o' | 'gpt-4o-2024-05-13' | 'gpt-4-turbo' | 'gpt-4-turbo-2024-04-09' | 'gpt-4-turbo-preview' | 'gpt-4-0125-preview' | 'gpt-4-1106-preview' | 'gpt-4' | 'gpt-4-0613' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-0613';
512
512
  /** @example true */
513
513
  semanticCachingEnabled?: boolean;
514
514
  /**
@@ -0,0 +1,10 @@
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 ADDED
@@ -0,0 +1,38 @@
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;
package/dist/vapi.d.ts CHANGED
@@ -10,7 +10,12 @@ export interface ControlMessages {
10
10
  type: 'control';
11
11
  control: 'mute-assistant' | 'unmute-assistant';
12
12
  }
13
- type VapiClientToServerMessage = AddMessageMessage | ControlMessages;
13
+ export interface SayMessage {
14
+ type: 'say';
15
+ message: string;
16
+ endCallAfterSpoken?: boolean;
17
+ }
18
+ type VapiClientToServerMessage = AddMessageMessage | ControlMessages | SayMessage;
14
19
  type VapiEventNames = 'call-end' | 'call-start' | 'volume-level' | 'speech-start' | 'speech-end' | 'message' | 'error';
15
20
  type VapiEventListeners = {
16
21
  'call-end': () => void;
@@ -42,5 +47,6 @@ export default class Vapi extends VapiEventEmitter {
42
47
  send(message: VapiClientToServerMessage): void;
43
48
  setMuted(mute: boolean): void;
44
49
  isMuted(): boolean;
50
+ say(message: string, endCallAfterSpoken?: boolean): void;
45
51
  }
46
52
  export {};
package/dist/vapi.js CHANGED
@@ -218,5 +218,12 @@ class Vapi extends VapiEventEmitter {
218
218
  throw error;
219
219
  }
220
220
  }
221
+ say(message, endCallAfterSpoken) {
222
+ this.send({
223
+ type: 'say',
224
+ message,
225
+ endCallAfterSpoken
226
+ });
227
+ }
221
228
  }
222
229
  exports.default = Vapi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vapi-ai/web",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "",
5
5
  "main": "dist/vapi.js",
6
6
  "types": "dist/vapi.d.ts",
package/vapi.ts CHANGED
@@ -50,7 +50,13 @@ export interface ControlMessages {
50
50
  control: 'mute-assistant' | 'unmute-assistant';
51
51
  }
52
52
 
53
- type VapiClientToServerMessage = AddMessageMessage | ControlMessages;
53
+ export interface SayMessage {
54
+ type: 'say';
55
+ message: string;
56
+ endCallAfterSpoken?: boolean;
57
+ }
58
+
59
+ type VapiClientToServerMessage = AddMessageMessage | ControlMessages | SayMessage;
54
60
 
55
61
  type VapiEventNames =
56
62
  | 'call-end'
@@ -275,4 +281,12 @@ export default class Vapi extends VapiEventEmitter {
275
281
  throw error;
276
282
  }
277
283
  }
284
+
285
+ public say(message: string, endCallAfterSpoken?: boolean) {
286
+ this.send({
287
+ type:'say',
288
+ message,
289
+ endCallAfterSpoken
290
+ })
291
+ }
278
292
  }