@vapi-ai/web 1.0.256 → 1.0.258

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.
@@ -0,0 +1,53 @@
1
+ import Vapi from '../vapi'; // Adjust the import path based on your project structure
2
+
3
+ describe('Vapi', () => {
4
+ let vapi: Vapi;
5
+ let mockCall: any;
6
+
7
+ beforeEach(() => {
8
+ // Mock the DailyCall object
9
+ mockCall = {
10
+ setLocalAudio: jest.fn(),
11
+ localAudio: jest.fn(),
12
+ };
13
+ // Initialize Vapi instance and inject the mock
14
+ vapi = new Vapi('dummy_token');
15
+ vapi['call'] = mockCall; // Assuming you have a way to set this for testing
16
+ });
17
+
18
+ describe('setMuted', () => {
19
+ it('should mute the audio', () => {
20
+ vapi['setMuted'](true);
21
+ expect(mockCall.setLocalAudio).toHaveBeenCalledWith(false);
22
+ });
23
+
24
+ it('should unmute the audio', () => {
25
+ vapi['setMuted'](false);
26
+ expect(mockCall.setLocalAudio).toHaveBeenCalledWith(true);
27
+ });
28
+
29
+ it('should handle errors when call object is not available', () => {
30
+ vapi['call'] = null; // Simulate call object not being available
31
+ expect(() => vapi['setMuted'](true)).toThrow('Call object is not available.');
32
+ });
33
+ });
34
+
35
+ describe('toggleMute', () => {
36
+ it('should toggle audio from unmuted to muted', () => {
37
+ mockCall.localAudio.mockReturnValue(true); // Initially not muted
38
+ vapi.toggleMute();
39
+ expect(mockCall.setLocalAudio).toHaveBeenCalledWith(false); // Should mute
40
+ });
41
+
42
+ it('should toggle audio from muted to unmuted', () => {
43
+ mockCall.localAudio.mockReturnValue(false); // Initially muted
44
+ vapi.toggleMute();
45
+ expect(mockCall.setLocalAudio).toHaveBeenCalledWith(true); // Should unmute
46
+ });
47
+
48
+ it('should handle errors when call object is not available', () => {
49
+ vapi['call'] = null; // Simulate call object not being available
50
+ expect(() => vapi.toggleMute()).toThrow('Call object is not available.');
51
+ });
52
+ });
53
+ });
package/api.ts CHANGED
@@ -16,6 +16,13 @@ export interface DeepgramVoice {
16
16
  voiceId: "asteria" | "luna" | "hera" | "athena" | "varun" | "leo" | "perseus" | "helios" | "angus" | string;
17
17
  }
18
18
 
19
+ export interface OpenAIMessage {
20
+ content: string | null;
21
+ role: object;
22
+ function_call?: object;
23
+ tool_calls?: object[];
24
+ }
25
+
19
26
  export interface JsonSchema {
20
27
  type: "string" | "number" | "integer" | "boolean" | "array" | "object";
21
28
  /** This is of type JsonSchema. However, Swagger doesn't support circular references. */
@@ -124,17 +131,17 @@ export interface OpenAIFunction {
124
131
  }
125
132
 
126
133
  export interface TogetherAIModel {
134
+ /** This is the starting state for the conversation. */
135
+ messages?: OpenAIMessage[];
127
136
  provider: "together-ai";
128
137
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
129
138
  model: string;
130
139
  /**
131
- * This is the temperature that will be used for calls. Default is 1.
140
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
132
141
  * @min 0
133
142
  * @max 2
134
143
  */
135
144
  temperature?: number;
136
- /** This is the starting state for the conversation. */
137
- messages: object[];
138
145
  /** These are the functions that the assistant can execute during the call. */
139
146
  functions?: OpenAIFunction[];
140
147
  /**
@@ -146,17 +153,17 @@ export interface TogetherAIModel {
146
153
  }
147
154
 
148
155
  export interface AnyscaleModel {
156
+ /** This is the starting state for the conversation. */
157
+ messages?: OpenAIMessage[];
149
158
  provider: "anyscale";
150
159
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
151
160
  model: string;
152
161
  /**
153
- * This is the temperature that will be used for calls. Default is 1.
162
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
154
163
  * @min 0
155
164
  * @max 2
156
165
  */
157
166
  temperature?: number;
158
- /** This is the starting state for the conversation. */
159
- messages: object[];
160
167
  /** These are the functions that the assistant can execute during the call. */
161
168
  functions?: OpenAIFunction[];
162
169
  /**
@@ -168,17 +175,17 @@ export interface AnyscaleModel {
168
175
  }
169
176
 
170
177
  export interface OpenRouterModel {
178
+ /** This is the starting state for the conversation. */
179
+ messages?: OpenAIMessage[];
171
180
  provider: "openrouter";
172
181
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
173
182
  model: string;
174
183
  /**
175
- * This is the temperature that will be used for calls. Default is 1.
184
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
176
185
  * @min 0
177
186
  * @max 2
178
187
  */
179
188
  temperature?: number;
180
- /** This is the starting state for the conversation. */
181
- messages: object[];
182
189
  /** These are the functions that the assistant can execute during the call. */
183
190
  functions?: OpenAIFunction[];
184
191
  /**
@@ -190,17 +197,17 @@ export interface OpenRouterModel {
190
197
  }
191
198
 
192
199
  export interface PerplexityAIModel {
200
+ /** This is the starting state for the conversation. */
201
+ messages?: OpenAIMessage[];
193
202
  provider: "perplexity-ai";
194
203
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
195
204
  model: string;
196
205
  /**
197
- * This is the temperature that will be used for calls. Default is 1.
206
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
198
207
  * @min 0
199
208
  * @max 2
200
209
  */
201
210
  temperature?: number;
202
- /** This is the starting state for the conversation. */
203
- messages: object[];
204
211
  /** These are the functions that the assistant can execute during the call. */
205
212
  functions?: OpenAIFunction[];
206
213
  /**
@@ -212,17 +219,17 @@ export interface PerplexityAIModel {
212
219
  }
213
220
 
214
221
  export interface DeepInfraModel {
222
+ /** This is the starting state for the conversation. */
223
+ messages?: OpenAIMessage[];
215
224
  provider: "deepinfra";
216
225
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
217
226
  model: string;
218
227
  /**
219
- * This is the temperature that will be used for calls. Default is 1.
228
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
220
229
  * @min 0
221
230
  * @max 2
222
231
  */
223
232
  temperature?: number;
224
- /** This is the starting state for the conversation. */
225
- messages: object[];
226
233
  /** These are the functions that the assistant can execute during the call. */
227
234
  functions?: OpenAIFunction[];
228
235
  /**
@@ -234,6 +241,8 @@ export interface DeepInfraModel {
234
241
  }
235
242
 
236
243
  export interface CustomLLMModel {
244
+ /** This is the starting state for the conversation. */
245
+ messages?: OpenAIMessage[];
237
246
  /** This is the provider that will be used for the model. Any service, including your own server, that is compatible with the OpenAI API can be used. */
238
247
  provider: "custom-llm";
239
248
  /** These is the URL we'll use for the OpenAI client's `baseURL`. Ex. https://openrouter.ai/api/v1 */
@@ -241,13 +250,11 @@ export interface CustomLLMModel {
241
250
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
242
251
  model: string;
243
252
  /**
244
- * This is the temperature that will be used for calls. Default is 1.
253
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
245
254
  * @min 0
246
255
  * @max 2
247
256
  */
248
257
  temperature?: number;
249
- /** This is the starting state for the conversation. */
250
- messages: object[];
251
258
  /** These are the functions that the assistant can execute during the call. */
252
259
  functions?: OpenAIFunction[];
253
260
  /**
@@ -259,17 +266,17 @@ export interface CustomLLMModel {
259
266
  }
260
267
 
261
268
  export interface GroqModel {
269
+ /** This is the starting state for the conversation. */
270
+ messages?: OpenAIMessage[];
262
271
  /** The key of the model from the custom provider. Ex. cognitivecomputations/dolphin-mixtral-8x7b */
263
272
  model: "mixtral-8x7b-32768";
264
273
  provider: "groq";
265
274
  /**
266
- * This is the temperature that will be used for calls. Default is 1.
275
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
267
276
  * @min 0
268
277
  * @max 2
269
278
  */
270
279
  temperature?: number;
271
- /** This is the starting state for the conversation. */
272
- messages: object[];
273
280
  /** These are the functions that the assistant can execute during the call. */
274
281
  functions?: OpenAIFunction[];
275
282
  /**
@@ -310,6 +317,7 @@ export interface ElevenLabsVoice {
310
317
  | "burt"
311
318
  | "marissa"
312
319
  | "andrea"
320
+ | "sarah"
313
321
  | "phillip"
314
322
  | "steve"
315
323
  | "joseph"
@@ -348,21 +356,28 @@ export interface ElevenLabsVoice {
348
356
  * @example false
349
357
  */
350
358
  useSpeakerBoost?: boolean;
359
+ /**
360
+ * Defines the optimize streaming latency for voice settings.
361
+ * @min 1
362
+ * @max 4
363
+ * @example 4
364
+ */
365
+ optimizeStreamingLatency?: number;
351
366
  }
352
367
 
353
368
  export interface OpenAIModel {
369
+ /** This is the starting state for the conversation. */
370
+ messages?: OpenAIMessage[];
354
371
  /** This is the provider that will be used for the model. */
355
372
  provider: "openai";
356
373
  /** This is the OpenAI model that will be used. */
357
374
  model: "gpt-4" | "gpt-3.5-turbo";
358
375
  /**
359
- * This is the temperature that will be used for calls. Default is 1.
376
+ * This is the temperature that will be used for calls. Default is 0 to leverage caching for lower latency.
360
377
  * @min 0
361
378
  * @max 2
362
379
  */
363
380
  temperature?: number;
364
- /** This is the starting state for the conversation. */
365
- messages: object[];
366
381
  /** These are the functions that the assistant can execute during the call. */
367
382
  functions?: OpenAIFunction[];
368
383
  /**
@@ -517,11 +532,6 @@ export interface CreateAssistantDTO {
517
532
  * @example null
518
533
  */
519
534
  forwardingPhoneNumber?: string;
520
- /**
521
- * This sets whether the user can interrupt the assistant while it's speaking. Defaults to true.
522
- * @example true
523
- */
524
- interruptionsEnabled?: boolean;
525
535
  /**
526
536
  * This sets whether the assistant's calls are recorded. Defaults to true.
527
537
  * @example true
@@ -537,6 +547,11 @@ export interface CreateAssistantDTO {
537
547
  * @default null
538
548
  */
539
549
  dialKeypadFunctionEnabled?: boolean;
550
+ /**
551
+ * When this is enabled, no logs, recordings, or transcriptions will be stored. At the end of the call, you will still receive an end-of-call-report message to store on your server. Defaults to false.
552
+ * @example false
553
+ */
554
+ hipaaEnabled?: boolean;
540
555
  /**
541
556
  * These are the messages that will be sent to the Client SDKs. Default is ['transcript', 'hang', 'function-call', 'speech-update', 'metadata', 'conversation-update']
542
557
  * @example ["transcript","hang","function-call","speech-update","metadata","conversation-update"]
@@ -661,11 +676,6 @@ export interface Assistant {
661
676
  * @example null
662
677
  */
663
678
  forwardingPhoneNumber?: string;
664
- /**
665
- * This sets whether the user can interrupt the assistant while it's speaking. Defaults to true.
666
- * @example true
667
- */
668
- interruptionsEnabled?: boolean;
669
679
  /**
670
680
  * This sets whether the assistant's calls are recorded. Defaults to true.
671
681
  * @example true
@@ -681,6 +691,11 @@ export interface Assistant {
681
691
  * @default null
682
692
  */
683
693
  dialKeypadFunctionEnabled?: boolean;
694
+ /**
695
+ * When this is enabled, no logs, recordings, or transcriptions will be stored. At the end of the call, you will still receive an end-of-call-report message to store on your server. Defaults to false.
696
+ * @example false
697
+ */
698
+ hipaaEnabled?: boolean;
684
699
  /**
685
700
  * These are the messages that will be sent to the Client SDKs. Default is ['transcript', 'hang', 'function-call', 'speech-update', 'metadata', 'conversation-update']
686
701
  * @example ["transcript","hang","function-call","speech-update","metadata","conversation-update"]
@@ -819,11 +834,6 @@ export interface UpdateAssistantDTO {
819
834
  * @example null
820
835
  */
821
836
  forwardingPhoneNumber?: string;
822
- /**
823
- * This sets whether the user can interrupt the assistant while it's speaking. Defaults to true.
824
- * @example true
825
- */
826
- interruptionsEnabled?: boolean;
827
837
  /**
828
838
  * This sets whether the assistant's calls are recorded. Defaults to true.
829
839
  * @example true
@@ -839,6 +849,11 @@ export interface UpdateAssistantDTO {
839
849
  * @default null
840
850
  */
841
851
  dialKeypadFunctionEnabled?: boolean;
852
+ /**
853
+ * When this is enabled, no logs, recordings, or transcriptions will be stored. At the end of the call, you will still receive an end-of-call-report message to store on your server. Defaults to false.
854
+ * @example false
855
+ */
856
+ hipaaEnabled?: boolean;
842
857
  /**
843
858
  * These are the messages that will be sent to the Client SDKs. Default is ['transcript', 'hang', 'function-call', 'speech-update', 'metadata', 'conversation-update']
844
859
  * @example ["transcript","hang","function-call","speech-update","metadata","conversation-update"]
@@ -1652,6 +1667,23 @@ export interface UpdatePhoneNumberDTO {
1652
1667
  assistantId?: string;
1653
1668
  }
1654
1669
 
1670
+ export interface Metrics {
1671
+ orgId: string;
1672
+ rangeStart: string;
1673
+ rangeEnd: string;
1674
+ bill: number;
1675
+ billWithinBillingLimit: boolean;
1676
+ billDailyBreakdown: object;
1677
+ callActive: string;
1678
+ callActiveWithinConcurrencyLimit: boolean;
1679
+ callMinutes: string;
1680
+ callMinutesDailyBreakdown: object;
1681
+ callMinutesAverage: string;
1682
+ callMinutesAverageDailyBreakdown: object;
1683
+ callCount: string;
1684
+ callCountDailyBreakdown: object;
1685
+ }
1686
+
1655
1687
  export type QueryParamsType = Record<string | number, any>;
1656
1688
  export type ResponseFormat = keyof Omit<Body, "body" | "bodyUsed">;
1657
1689
 
@@ -1698,7 +1730,7 @@ export enum ContentType {
1698
1730
  }
1699
1731
 
1700
1732
  export class HttpClient<SecurityDataType = unknown> {
1701
- public baseUrl: string = "https://api.vapi.ai";
1733
+ public baseUrl: string = "https://west-api.vapi.ai";
1702
1734
  private securityData: SecurityDataType | null = null;
1703
1735
  private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"];
1704
1736
  private abortControllers = new Map<CancelToken, AbortController>();
@@ -1865,7 +1897,7 @@ export class HttpClient<SecurityDataType = unknown> {
1865
1897
  /**
1866
1898
  * @title Vapi API
1867
1899
  * @version 1.0
1868
- * @baseUrl https://api.vapi.ai
1900
+ * @baseUrl https://west-api.vapi.ai
1869
1901
  * @contact
1870
1902
  *
1871
1903
  * API for building voice assistants
@@ -2049,6 +2081,8 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
2049
2081
  */
2050
2082
  callControllerFindAll: (
2051
2083
  query?: {
2084
+ /** This will return calls with the specified assistantId. */
2085
+ assistantId?: string;
2052
2086
  /**
2053
2087
  * This is the maximum number of items to return. Defaults to 100.
2054
2088
  * @min 0
@@ -2769,4 +2803,42 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
2769
2803
  ...params,
2770
2804
  }),
2771
2805
  };
2806
+ metrics = {
2807
+ /**
2808
+ * No description
2809
+ *
2810
+ * @tags Metrics
2811
+ * @name MetricsControllerFindAll
2812
+ * @summary List Metrics
2813
+ * @request GET:/metrics
2814
+ * @secure
2815
+ */
2816
+ metricsControllerFindAll: (
2817
+ query?: {
2818
+ /**
2819
+ * This will include calls with a createdAt timestamp greater than or equal to the specified value.
2820
+ *
2821
+ * If not provided, defaults to the org's current period start.
2822
+ * @format date-time
2823
+ */
2824
+ rangeStart?: string;
2825
+ /**
2826
+ * This will include calls with a createdAt timestamp less than the specified value.
2827
+ *
2828
+ * If not provided, the default value will be the current timestamp.
2829
+ * @format date-time
2830
+ */
2831
+ rangeEnd?: string;
2832
+ },
2833
+ params: RequestParams = {},
2834
+ ) =>
2835
+ this.request<Metrics[], any>({
2836
+ path: `/metrics`,
2837
+ method: "GET",
2838
+ query: query,
2839
+ secure: true,
2840
+ format: "json",
2841
+ ...params,
2842
+ }),
2843
+ };
2772
2844
  }
package/jest.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Config } from '@jest/types';
2
+
3
+ const config: Config.InitialOptions = {
4
+ preset: 'ts-jest',
5
+ testEnvironment: 'node',
6
+ // Your Jest configuration options here
7
+ // For example, to match test files:
8
+ testMatch: ['**/__tests__/**/*.ts?(x)', '**/?(*.)+(spec|test).ts?(x)'],
9
+ };
10
+
11
+ export default config;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@vapi-ai/web",
3
- "version": "1.0.256",
3
+ "version": "1.0.258",
4
4
  "description": "",
5
5
  "main": "dist/vapi.js",
6
6
  "types": "dist/vapi.d.ts",
7
7
  "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1",
8
+ "test": "jest",
9
9
  "build": "tsc && tsc --declaration",
10
10
  "start": "npm run generate-api && npm run build && node dist/vapi.js",
11
11
  "generate-api": "npx swagger-typescript-api -p https://api.vapi.ai/api-json -o . -n api.ts",
@@ -26,8 +26,12 @@
26
26
  "events": "^3.3.0"
27
27
  },
28
28
  "devDependencies": {
29
+ "@types/jest": "^29.5.12",
29
30
  "@types/node": "^20.6.0",
31
+ "jest": "^29.7.0",
30
32
  "openai": "^4.24.1",
31
- "swagger-typescript-api": "^13.0.3"
33
+ "swagger-typescript-api": "^13.0.3",
34
+ "ts-jest": "^29.1.2",
35
+ "ts-node": "^10.9.2"
32
36
  }
33
37
  }
package/vapi.ts CHANGED
@@ -178,9 +178,11 @@ export default class Vapi extends VapiEventEmitter {
178
178
  });
179
179
 
180
180
  this.call.startRemoteParticipantsAudioLevelObserver(100);
181
- this.call.on("remote-participants-audio-level", (e) =>
182
- this.handleRemoteParticipantsAudioLevel(e)
183
- );
181
+
182
+ this.call.on("remote-participants-audio-level", (e) => {
183
+ if (e) this.handleRemoteParticipantsAudioLevel(e);
184
+ });
185
+
184
186
  this.call.on("app-message", (e) => this.onAppMessage(e));
185
187
 
186
188
  this.call.updateInputSettings({
@@ -205,9 +207,14 @@ export default class Vapi extends VapiEventEmitter {
205
207
  try {
206
208
  if (e.data === "listening") {
207
209
  return this.emit("call-start");
210
+ } else {
211
+ try {
212
+ const parsedMessage = JSON.parse(e.data);
213
+ this.emit("message", parsedMessage);
214
+ } catch (parseError) {
215
+ console.log("Error parsing message data: ", parseError);
216
+ }
208
217
  }
209
- const parsedMessage = JSON.parse(e.data);
210
- this.emit("message", parsedMessage);
211
218
  } catch (e) {
212
219
  console.error(e);
213
220
  }
@@ -249,4 +256,29 @@ export default class Vapi extends VapiEventEmitter {
249
256
  send(message: VapiClientToServerMessage): void {
250
257
  this.call?.sendAppMessage(JSON.stringify(message));
251
258
  }
259
+
260
+ private setMuted(mute: boolean) {
261
+ try {
262
+ if (!this.call) {
263
+ throw new Error('Call object is not available.');
264
+ }
265
+ this.call.setLocalAudio(!mute);
266
+ } catch (error) {
267
+ console.error("Error in setMuted:", error);
268
+ throw error;
269
+ }
270
+ }
271
+
272
+ public toggleMute() {
273
+ try {
274
+ if (!this.call) {
275
+ throw new Error('Call object is not available.');
276
+ }
277
+ const isCurrentlyMuted = this.call.localAudio() === false;
278
+ this.setMuted(!isCurrentlyMuted);
279
+ } catch (error) {
280
+ console.error("Error in toggleMute:", error);
281
+ throw error;
282
+ }
283
+ }
252
284
  }