@vapi-ai/web 2.5.1 → 2.5.2

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.
Files changed (6) hide show
  1. package/api.ts +380 -414
  2. package/dist/api.d.ts +2004 -2034
  3. package/dist/api.js +17 -28
  4. package/dist/vapi.js +101 -24
  5. package/package.json +1 -1
  6. package/vapi.ts +117 -24
package/dist/api.js CHANGED
@@ -72,15 +72,20 @@ class HttpClient {
72
72
  [ContentType.Text]: (input) => input !== null && typeof input !== "string"
73
73
  ? JSON.stringify(input)
74
74
  : input,
75
- [ContentType.FormData]: (input) => Object.keys(input || {}).reduce((formData, key) => {
76
- const property = input[key];
77
- formData.append(key, property instanceof Blob
78
- ? property
79
- : typeof property === "object" && property !== null
80
- ? JSON.stringify(property)
81
- : `${property}`);
82
- return formData;
83
- }, new FormData()),
75
+ [ContentType.FormData]: (input) => {
76
+ if (input instanceof FormData) {
77
+ return input;
78
+ }
79
+ return Object.keys(input || {}).reduce((formData, key) => {
80
+ const property = input[key];
81
+ formData.append(key, property instanceof Blob
82
+ ? property
83
+ : typeof property === "object" && property !== null
84
+ ? JSON.stringify(property)
85
+ : `${property}`);
86
+ return formData;
87
+ }, new FormData());
88
+ },
84
89
  [ContentType.UrlEncoded]: (input) => this.toQueryString(input),
85
90
  };
86
91
  mergeRequestParams(params1, params2) {
@@ -138,12 +143,13 @@ class HttpClient {
138
143
  ? null
139
144
  : payloadFormatter(body),
140
145
  }).then(async (response) => {
141
- const r = response.clone();
146
+ const r = response;
142
147
  r.data = null;
143
148
  r.error = null;
149
+ const responseToParse = responseFormat ? response.clone() : response;
144
150
  const data = !responseFormat
145
151
  ? r
146
- : await response[responseFormat]()
152
+ : await responseToParse[responseFormat]()
147
153
  .then((data) => {
148
154
  if (r.ok) {
149
155
  r.data = data;
@@ -1489,23 +1495,6 @@ class Api extends HttpClient {
1489
1495
  format: "json",
1490
1496
  ...params,
1491
1497
  }),
1492
- /**
1493
- * @description Analyzes assistant configuration and generates contextual structured output recommendations
1494
- *
1495
- * @tags Structured Outputs
1496
- * @name StructuredOutputControllerSuggest
1497
- * @summary Generate AI-Powered Structured Output Suggestions
1498
- * @request POST:/structured-output/suggest
1499
- * @secure
1500
- */
1501
- structuredOutputControllerSuggest: (data, params = {}) => this.request({
1502
- path: `/structured-output/suggest`,
1503
- method: "POST",
1504
- body: data,
1505
- secure: true,
1506
- type: ContentType.Json,
1507
- ...params,
1508
- }),
1509
1498
  };
1510
1499
  testSuite = {
1511
1500
  /**
package/dist/vapi.js CHANGED
@@ -7,6 +7,57 @@ const daily_js_1 = __importDefault(require("@daily-co/daily-js"));
7
7
  const events_1 = __importDefault(require("events"));
8
8
  const client_1 = require("./client");
9
9
  const daily_guards_1 = require("./daily-guards");
10
+ /**
11
+ * Extracts error details into a plain object that serializes properly to JSON.
12
+ * Error objects don't serialize well because their properties (message, stack, name)
13
+ * are not enumerable and get lost when using JSON.stringify().
14
+ */
15
+ function serializeError(error) {
16
+ if (error === null || error === undefined) {
17
+ return { message: 'Unknown error (null or undefined)' };
18
+ }
19
+ if (error instanceof Error) {
20
+ const serialized = {
21
+ message: error.message,
22
+ name: error.name,
23
+ stack: error.stack,
24
+ };
25
+ // Include any additional properties that might be on the error
26
+ const errorAsAny = error;
27
+ if (errorAsAny.code !== undefined) {
28
+ serialized.code = errorAsAny.code;
29
+ }
30
+ if (errorAsAny.cause !== undefined) {
31
+ serialized.cause = String(errorAsAny.cause);
32
+ }
33
+ if (errorAsAny.reason !== undefined) {
34
+ serialized.reason = errorAsAny.reason;
35
+ }
36
+ if (errorAsAny.details !== undefined) {
37
+ serialized.details = errorAsAny.details;
38
+ }
39
+ // Daily.co specific error properties
40
+ if (errorAsAny.errorMsg !== undefined) {
41
+ serialized.errorMsg = errorAsAny.errorMsg;
42
+ }
43
+ if (errorAsAny.error !== undefined && typeof errorAsAny.error === 'string') {
44
+ serialized.errorDetail = errorAsAny.error;
45
+ }
46
+ return serialized;
47
+ }
48
+ if (typeof error === 'string') {
49
+ return { message: error };
50
+ }
51
+ if (typeof error === 'object') {
52
+ // It's already a plain object, but let's ensure message exists
53
+ const errorObj = error;
54
+ return {
55
+ message: errorObj.message || errorObj.error || JSON.stringify(error),
56
+ ...errorObj
57
+ };
58
+ }
59
+ return { message: String(error) };
60
+ }
10
61
  async function startAudioPlayer(player, track) {
11
62
  player.muted = false;
12
63
  player.autoplay = true;
@@ -98,7 +149,7 @@ class Vapi extends VapiEventEmitter {
98
149
  this.emit('error', {
99
150
  type: 'validation-error',
100
151
  stage: 'input-validation',
101
- message: error.message,
152
+ error: serializeError(error),
102
153
  timestamp: new Date().toISOString()
103
154
  });
104
155
  throw error;
@@ -194,17 +245,18 @@ class Vapi extends VapiEventEmitter {
194
245
  }
195
246
  catch (error) {
196
247
  const dailyCallDuration = Date.now() - dailyCallStartTime;
248
+ const serializedError = serializeError(error);
197
249
  this.emit('call-start-progress', {
198
250
  stage: 'daily-call-object-creation',
199
251
  status: 'failed',
200
252
  duration: dailyCallDuration,
201
253
  timestamp: new Date().toISOString(),
202
- metadata: { error: error?.toString() }
254
+ metadata: { error: serializedError.message }
203
255
  });
204
256
  this.emit('error', {
205
257
  type: 'daily-call-object-creation-error',
206
258
  stage: 'daily-call-object-creation',
207
- error,
259
+ error: serializedError,
208
260
  timestamp: new Date().toISOString()
209
261
  });
210
262
  throw error;
@@ -226,13 +278,21 @@ class Vapi extends VapiEventEmitter {
226
278
  this.cleanup().catch(console.error);
227
279
  });
228
280
  this.call.on('error', (error) => {
229
- this.emit('error', error);
281
+ this.emit('error', {
282
+ type: 'daily-error',
283
+ error: serializeError(error),
284
+ timestamp: new Date().toISOString()
285
+ });
230
286
  if (isVideoRecordingEnabled) {
231
287
  this.call?.stopRecording();
232
288
  }
233
289
  });
234
290
  this.call.on('camera-error', (error) => {
235
- this.emit('camera-error', error);
291
+ this.emit('camera-error', {
292
+ type: 'camera-error',
293
+ error: serializeError(error),
294
+ timestamp: new Date().toISOString()
295
+ });
236
296
  });
237
297
  this.call.on('network-quality-change', (event) => {
238
298
  this.emit('network-quality-change', event);
@@ -326,17 +386,18 @@ class Vapi extends VapiEventEmitter {
326
386
  }
327
387
  catch (error) {
328
388
  const joinDuration = Date.now() - joinStartTime;
389
+ const serializedError = serializeError(error);
329
390
  this.emit('call-start-progress', {
330
391
  stage: 'daily-call-join',
331
392
  status: 'failed',
332
393
  duration: joinDuration,
333
394
  timestamp: new Date().toISOString(),
334
- metadata: { error: error?.toString() }
395
+ metadata: { error: serializedError.message }
335
396
  });
336
397
  this.emit('error', {
337
398
  type: 'daily-call-join-error',
338
399
  stage: 'daily-call-join',
339
- error,
400
+ error: serializedError,
340
401
  duration: joinDuration,
341
402
  timestamp: new Date().toISOString()
342
403
  });
@@ -384,17 +445,18 @@ class Vapi extends VapiEventEmitter {
384
445
  }
385
446
  catch (error) {
386
447
  const recordingSetupDuration = Date.now() - recordingStartTime;
448
+ const serializedError = serializeError(error);
387
449
  this.emit('call-start-progress', {
388
450
  stage: 'video-recording-setup',
389
451
  status: 'failed',
390
452
  duration: recordingSetupDuration,
391
453
  timestamp: new Date().toISOString(),
392
- metadata: { error: error?.toString() }
454
+ metadata: { error: serializedError.message }
393
455
  });
394
456
  this.emit('error', {
395
457
  type: 'video-recording-setup-error',
396
458
  stage: 'video-recording-setup',
397
- error,
459
+ error: serializedError,
398
460
  timestamp: new Date().toISOString()
399
461
  });
400
462
  // Don't throw here, video recording is optional
@@ -427,17 +489,18 @@ class Vapi extends VapiEventEmitter {
427
489
  }
428
490
  catch (error) {
429
491
  const audioObserverDuration = Date.now() - audioObserverStartTime;
492
+ const serializedError = serializeError(error);
430
493
  this.emit('call-start-progress', {
431
494
  stage: 'audio-observer-setup',
432
495
  status: 'failed',
433
496
  duration: audioObserverDuration,
434
497
  timestamp: new Date().toISOString(),
435
- metadata: { error: error?.toString() }
498
+ metadata: { error: serializedError.message }
436
499
  });
437
500
  this.emit('error', {
438
501
  type: 'audio-observer-setup-error',
439
502
  stage: 'audio-observer-setup',
440
- error,
503
+ error: serializedError,
441
504
  timestamp: new Date().toISOString()
442
505
  });
443
506
  // Don't throw here, this is non-critical
@@ -488,17 +551,18 @@ class Vapi extends VapiEventEmitter {
488
551
  }
489
552
  catch (error) {
490
553
  const audioProcessingDuration = Date.now() - audioProcessingStartTime;
554
+ const serializedError = serializeError(error);
491
555
  this.emit('call-start-progress', {
492
556
  stage: 'audio-processing-setup',
493
557
  status: 'failed',
494
558
  duration: audioProcessingDuration,
495
559
  timestamp: new Date().toISOString(),
496
- metadata: { error: error?.toString() }
560
+ metadata: { error: serializedError.message }
497
561
  });
498
562
  this.emit('error', {
499
563
  type: 'audio-processing-setup-error',
500
564
  stage: 'audio-processing-setup',
501
- error,
565
+ error: serializedError,
502
566
  timestamp: new Date().toISOString()
503
567
  });
504
568
  // Don't throw here, this is non-critical
@@ -513,11 +577,12 @@ class Vapi extends VapiEventEmitter {
513
577
  }
514
578
  catch (e) {
515
579
  const totalDuration = Date.now() - startTime;
580
+ const serializedError = serializeError(e);
516
581
  this.emit('call-start-failed', {
517
582
  stage: 'unknown',
518
583
  totalDuration,
519
- error: e?.toString() || 'Unknown error occurred',
520
- errorStack: e instanceof Error ? e.stack : 'No stack trace available',
584
+ error: serializedError.message,
585
+ errorStack: serializedError.stack || 'No stack trace available',
521
586
  timestamp: new Date().toISOString(),
522
587
  context: {
523
588
  hasAssistant: !!assistant,
@@ -530,7 +595,7 @@ class Vapi extends VapiEventEmitter {
530
595
  this.emit('error', {
531
596
  type: 'start-method-error',
532
597
  stage: 'unknown',
533
- error: e,
598
+ error: serializedError,
534
599
  totalDuration,
535
600
  timestamp: new Date().toISOString(),
536
601
  context: {
@@ -762,13 +827,21 @@ class Vapi extends VapiEventEmitter {
762
827
  this.cleanup().catch(console.error);
763
828
  });
764
829
  this.call.on('error', (error) => {
765
- this.emit('error', error);
830
+ this.emit('error', {
831
+ type: 'daily-error',
832
+ error: serializeError(error),
833
+ timestamp: new Date().toISOString()
834
+ });
766
835
  if (isVideoRecordingEnabled) {
767
836
  this.call?.stopRecording();
768
837
  }
769
838
  });
770
839
  this.call.on('camera-error', (error) => {
771
- this.emit('camera-error', error);
840
+ this.emit('camera-error', {
841
+ type: 'camera-error',
842
+ error: serializeError(error),
843
+ timestamp: new Date().toISOString()
844
+ });
772
845
  });
773
846
  this.call.on('network-quality-change', (event) => {
774
847
  this.emit('network-quality-change', event);
@@ -920,12 +993,13 @@ class Vapi extends VapiEventEmitter {
920
993
  }
921
994
  catch (error) {
922
995
  const recordingSetupDuration = Date.now() - recordingStartTime;
996
+ const serializedError = serializeError(error);
923
997
  this.emit('call-start-progress', {
924
998
  stage: 'video-recording-setup',
925
999
  status: 'failed',
926
1000
  duration: recordingSetupDuration,
927
1001
  timestamp: new Date().toISOString(),
928
- metadata: { error: error?.toString() }
1002
+ metadata: { error: serializedError.message }
929
1003
  });
930
1004
  // Don't throw here, video recording is optional
931
1005
  }
@@ -957,12 +1031,13 @@ class Vapi extends VapiEventEmitter {
957
1031
  }
958
1032
  catch (error) {
959
1033
  const audioObserverDuration = Date.now() - audioObserverStartTime;
1034
+ const serializedError = serializeError(error);
960
1035
  this.emit('call-start-progress', {
961
1036
  stage: 'audio-observer-setup',
962
1037
  status: 'failed',
963
1038
  duration: audioObserverDuration,
964
1039
  timestamp: new Date().toISOString(),
965
- metadata: { error: error?.toString() }
1040
+ metadata: { error: serializedError.message }
966
1041
  });
967
1042
  // Don't throw here, this is non-critical
968
1043
  }
@@ -991,12 +1066,13 @@ class Vapi extends VapiEventEmitter {
991
1066
  }
992
1067
  catch (error) {
993
1068
  const audioProcessingDuration = Date.now() - audioProcessingStartTime;
1069
+ const serializedError = serializeError(error);
994
1070
  this.emit('call-start-progress', {
995
1071
  stage: 'audio-processing-setup',
996
1072
  status: 'failed',
997
1073
  duration: audioProcessingDuration,
998
1074
  timestamp: new Date().toISOString(),
999
- metadata: { error: error?.toString() }
1075
+ metadata: { error: serializedError.message }
1000
1076
  });
1001
1077
  // Don't throw here, this is non-critical
1002
1078
  }
@@ -1010,11 +1086,12 @@ class Vapi extends VapiEventEmitter {
1010
1086
  }
1011
1087
  catch (e) {
1012
1088
  const totalDuration = Date.now() - startTime;
1089
+ const serializedError = serializeError(e);
1013
1090
  this.emit('call-start-failed', {
1014
1091
  stage: 'reconnect',
1015
1092
  totalDuration,
1016
- error: e?.toString() || 'Unknown error occurred',
1017
- errorStack: e instanceof Error ? e.stack : 'No stack trace available',
1093
+ error: serializedError.message,
1094
+ errorStack: serializedError.stack || 'No stack trace available',
1018
1095
  timestamp: new Date().toISOString(),
1019
1096
  context: {
1020
1097
  isReconnect: true,
@@ -1027,7 +1104,7 @@ class Vapi extends VapiEventEmitter {
1027
1104
  // Also emit the generic error event for backward compatibility
1028
1105
  this.emit('error', {
1029
1106
  type: 'reconnect-error',
1030
- error: e,
1107
+ error: serializedError,
1031
1108
  totalDuration,
1032
1109
  timestamp: new Date().toISOString(),
1033
1110
  context: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vapi-ai/web",
3
- "version": "2.5.1",
3
+ "version": "2.5.2",
4
4
  "description": "",
5
5
  "main": "dist/vapi.js",
6
6
  "types": "dist/vapi.d.ts",