@vapi-ai/web 1.0.252 → 1.0.255
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/README.md +2 -2
- package/dist/api.js +466 -326
- package/dist/client.js +2 -11
- package/dist/vapi.d.ts +1 -1
- package/dist/vapi.js +91 -109
- package/package.json +1 -1
- package/tsconfig.json +1 -1
- package/vapi.ts +4 -2
- package/dist/AtomicMediaSource.d.ts +0 -17
- package/dist/AtomicMediaSource.js +0 -78
- package/dist/player.d.ts +0 -10
- package/dist/player.js +0 -38
package/README.md
CHANGED
|
@@ -18,10 +18,10 @@ First, import the Vapi class from the package:
|
|
|
18
18
|
import Vapi from '@vapi-ai/web';
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Then, create a new instance of the Vapi class, passing your
|
|
21
|
+
Then, create a new instance of the Vapi class, passing your Public Key as a parameter to the constructor:
|
|
22
22
|
|
|
23
23
|
```javascript
|
|
24
|
-
const vapi = new Vapi('your-
|
|
24
|
+
const vapi = new Vapi('your-public-key');
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
You can start a new call by calling the `start` method and passing an `assistant` object or `assistantId`:
|
package/dist/api.js
CHANGED
|
@@ -9,26 +9,6 @@
|
|
|
9
9
|
* ## SOURCE: https://github.com/acacode/swagger-typescript-api ##
|
|
10
10
|
* ---------------------------------------------------------------
|
|
11
11
|
*/
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
22
|
-
var t = {};
|
|
23
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
24
|
-
t[p] = s[p];
|
|
25
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
26
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
27
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
28
|
-
t[p[i]] = s[p[i]];
|
|
29
|
-
}
|
|
30
|
-
return t;
|
|
31
|
-
};
|
|
32
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
13
|
exports.Api = exports.HttpClient = exports.ContentType = void 0;
|
|
34
14
|
var ContentType;
|
|
@@ -39,93 +19,23 @@ var ContentType;
|
|
|
39
19
|
ContentType["Text"] = "text/plain";
|
|
40
20
|
})(ContentType || (exports.ContentType = ContentType = {}));
|
|
41
21
|
class HttpClient {
|
|
22
|
+
baseUrl = "https://api.vapi.ai";
|
|
23
|
+
securityData = null;
|
|
24
|
+
securityWorker;
|
|
25
|
+
abortControllers = new Map();
|
|
26
|
+
customFetch = (...fetchParams) => fetch(...fetchParams);
|
|
27
|
+
baseApiParams = {
|
|
28
|
+
credentials: "same-origin",
|
|
29
|
+
headers: {},
|
|
30
|
+
redirect: "follow",
|
|
31
|
+
referrerPolicy: "no-referrer",
|
|
32
|
+
};
|
|
42
33
|
constructor(apiConfig = {}) {
|
|
43
|
-
this.baseUrl = "https://api.vapi.ai";
|
|
44
|
-
this.securityData = null;
|
|
45
|
-
this.abortControllers = new Map();
|
|
46
|
-
this.customFetch = (...fetchParams) => fetch(...fetchParams);
|
|
47
|
-
this.baseApiParams = {
|
|
48
|
-
credentials: "same-origin",
|
|
49
|
-
headers: {},
|
|
50
|
-
redirect: "follow",
|
|
51
|
-
referrerPolicy: "no-referrer",
|
|
52
|
-
};
|
|
53
|
-
this.setSecurityData = (data) => {
|
|
54
|
-
this.securityData = data;
|
|
55
|
-
};
|
|
56
|
-
this.contentFormatters = {
|
|
57
|
-
[ContentType.Json]: (input) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
|
|
58
|
-
[ContentType.Text]: (input) => (input !== null && typeof input !== "string" ? JSON.stringify(input) : input),
|
|
59
|
-
[ContentType.FormData]: (input) => Object.keys(input || {}).reduce((formData, key) => {
|
|
60
|
-
const property = input[key];
|
|
61
|
-
formData.append(key, property instanceof Blob
|
|
62
|
-
? property
|
|
63
|
-
: typeof property === "object" && property !== null
|
|
64
|
-
? JSON.stringify(property)
|
|
65
|
-
: `${property}`);
|
|
66
|
-
return formData;
|
|
67
|
-
}, new FormData()),
|
|
68
|
-
[ContentType.UrlEncoded]: (input) => this.toQueryString(input),
|
|
69
|
-
};
|
|
70
|
-
this.createAbortSignal = (cancelToken) => {
|
|
71
|
-
if (this.abortControllers.has(cancelToken)) {
|
|
72
|
-
const abortController = this.abortControllers.get(cancelToken);
|
|
73
|
-
if (abortController) {
|
|
74
|
-
return abortController.signal;
|
|
75
|
-
}
|
|
76
|
-
return void 0;
|
|
77
|
-
}
|
|
78
|
-
const abortController = new AbortController();
|
|
79
|
-
this.abortControllers.set(cancelToken, abortController);
|
|
80
|
-
return abortController.signal;
|
|
81
|
-
};
|
|
82
|
-
this.abortRequest = (cancelToken) => {
|
|
83
|
-
const abortController = this.abortControllers.get(cancelToken);
|
|
84
|
-
if (abortController) {
|
|
85
|
-
abortController.abort();
|
|
86
|
-
this.abortControllers.delete(cancelToken);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
this.request = (_a) => __awaiter(this, void 0, void 0, function* () {
|
|
90
|
-
var { body, secure, path, type, query, format, baseUrl, cancelToken } = _a, params = __rest(_a, ["body", "secure", "path", "type", "query", "format", "baseUrl", "cancelToken"]);
|
|
91
|
-
const secureParams = ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) &&
|
|
92
|
-
this.securityWorker &&
|
|
93
|
-
(yield this.securityWorker(this.securityData))) ||
|
|
94
|
-
{};
|
|
95
|
-
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
96
|
-
const queryString = query && this.toQueryString(query);
|
|
97
|
-
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
|
98
|
-
const responseFormat = format || requestParams.format;
|
|
99
|
-
return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, Object.assign(Object.assign({}, requestParams), { headers: Object.assign(Object.assign({}, (requestParams.headers || {})), (type && type !== ContentType.FormData ? { "Content-Type": type } : {})), signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null, body: typeof body === "undefined" || body === null ? null : payloadFormatter(body) })).then((response) => __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
const r = response;
|
|
101
|
-
r.data = null;
|
|
102
|
-
r.error = null;
|
|
103
|
-
const data = !responseFormat
|
|
104
|
-
? r
|
|
105
|
-
: yield response[responseFormat]()
|
|
106
|
-
.then((data) => {
|
|
107
|
-
if (r.ok) {
|
|
108
|
-
r.data = data;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
r.error = data;
|
|
112
|
-
}
|
|
113
|
-
return r;
|
|
114
|
-
})
|
|
115
|
-
.catch((e) => {
|
|
116
|
-
r.error = e;
|
|
117
|
-
return r;
|
|
118
|
-
});
|
|
119
|
-
if (cancelToken) {
|
|
120
|
-
this.abortControllers.delete(cancelToken);
|
|
121
|
-
}
|
|
122
|
-
if (!response.ok)
|
|
123
|
-
throw data;
|
|
124
|
-
return data;
|
|
125
|
-
}));
|
|
126
|
-
});
|
|
127
34
|
Object.assign(this, apiConfig);
|
|
128
35
|
}
|
|
36
|
+
setSecurityData = (data) => {
|
|
37
|
+
this.securityData = data;
|
|
38
|
+
};
|
|
129
39
|
encodeQueryParam(key, value) {
|
|
130
40
|
const encodedKey = encodeURIComponent(key);
|
|
131
41
|
return `${encodedKey}=${encodeURIComponent(typeof value === "number" ? value : `${value}`)}`;
|
|
@@ -148,9 +58,96 @@ class HttpClient {
|
|
|
148
58
|
const queryString = this.toQueryString(rawQuery);
|
|
149
59
|
return queryString ? `?${queryString}` : "";
|
|
150
60
|
}
|
|
61
|
+
contentFormatters = {
|
|
62
|
+
[ContentType.Json]: (input) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
|
|
63
|
+
[ContentType.Text]: (input) => (input !== null && typeof input !== "string" ? JSON.stringify(input) : input),
|
|
64
|
+
[ContentType.FormData]: (input) => Object.keys(input || {}).reduce((formData, key) => {
|
|
65
|
+
const property = input[key];
|
|
66
|
+
formData.append(key, property instanceof Blob
|
|
67
|
+
? property
|
|
68
|
+
: typeof property === "object" && property !== null
|
|
69
|
+
? JSON.stringify(property)
|
|
70
|
+
: `${property}`);
|
|
71
|
+
return formData;
|
|
72
|
+
}, new FormData()),
|
|
73
|
+
[ContentType.UrlEncoded]: (input) => this.toQueryString(input),
|
|
74
|
+
};
|
|
151
75
|
mergeRequestParams(params1, params2) {
|
|
152
|
-
return
|
|
76
|
+
return {
|
|
77
|
+
...this.baseApiParams,
|
|
78
|
+
...params1,
|
|
79
|
+
...(params2 || {}),
|
|
80
|
+
headers: {
|
|
81
|
+
...(this.baseApiParams.headers || {}),
|
|
82
|
+
...(params1.headers || {}),
|
|
83
|
+
...((params2 && params2.headers) || {}),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
153
86
|
}
|
|
87
|
+
createAbortSignal = (cancelToken) => {
|
|
88
|
+
if (this.abortControllers.has(cancelToken)) {
|
|
89
|
+
const abortController = this.abortControllers.get(cancelToken);
|
|
90
|
+
if (abortController) {
|
|
91
|
+
return abortController.signal;
|
|
92
|
+
}
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
const abortController = new AbortController();
|
|
96
|
+
this.abortControllers.set(cancelToken, abortController);
|
|
97
|
+
return abortController.signal;
|
|
98
|
+
};
|
|
99
|
+
abortRequest = (cancelToken) => {
|
|
100
|
+
const abortController = this.abortControllers.get(cancelToken);
|
|
101
|
+
if (abortController) {
|
|
102
|
+
abortController.abort();
|
|
103
|
+
this.abortControllers.delete(cancelToken);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
request = async ({ body, secure, path, type, query, format, baseUrl, cancelToken, ...params }) => {
|
|
107
|
+
const secureParams = ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) &&
|
|
108
|
+
this.securityWorker &&
|
|
109
|
+
(await this.securityWorker(this.securityData))) ||
|
|
110
|
+
{};
|
|
111
|
+
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
112
|
+
const queryString = query && this.toQueryString(query);
|
|
113
|
+
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
|
114
|
+
const responseFormat = format || requestParams.format;
|
|
115
|
+
return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, {
|
|
116
|
+
...requestParams,
|
|
117
|
+
headers: {
|
|
118
|
+
...(requestParams.headers || {}),
|
|
119
|
+
...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}),
|
|
120
|
+
},
|
|
121
|
+
signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
|
|
122
|
+
body: typeof body === "undefined" || body === null ? null : payloadFormatter(body),
|
|
123
|
+
}).then(async (response) => {
|
|
124
|
+
const r = response;
|
|
125
|
+
r.data = null;
|
|
126
|
+
r.error = null;
|
|
127
|
+
const data = !responseFormat
|
|
128
|
+
? r
|
|
129
|
+
: await response[responseFormat]()
|
|
130
|
+
.then((data) => {
|
|
131
|
+
if (r.ok) {
|
|
132
|
+
r.data = data;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
r.error = data;
|
|
136
|
+
}
|
|
137
|
+
return r;
|
|
138
|
+
})
|
|
139
|
+
.catch((e) => {
|
|
140
|
+
r.error = e;
|
|
141
|
+
return r;
|
|
142
|
+
});
|
|
143
|
+
if (cancelToken) {
|
|
144
|
+
this.abortControllers.delete(cancelToken);
|
|
145
|
+
}
|
|
146
|
+
if (!response.ok)
|
|
147
|
+
throw data;
|
|
148
|
+
return data;
|
|
149
|
+
});
|
|
150
|
+
};
|
|
154
151
|
}
|
|
155
152
|
exports.HttpClient = HttpClient;
|
|
156
153
|
/**
|
|
@@ -162,226 +159,369 @@ exports.HttpClient = HttpClient;
|
|
|
162
159
|
* API for building voice assistants
|
|
163
160
|
*/
|
|
164
161
|
class Api extends HttpClient {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
162
|
+
assistant = {
|
|
163
|
+
/**
|
|
164
|
+
* No description
|
|
165
|
+
*
|
|
166
|
+
* @tags Assistants
|
|
167
|
+
* @name AssistantControllerCreate
|
|
168
|
+
* @summary Create Assistant
|
|
169
|
+
* @request POST:/assistant
|
|
170
|
+
* @secure
|
|
171
|
+
*/
|
|
172
|
+
assistantControllerCreate: (data, params = {}) => this.request({
|
|
173
|
+
path: `/assistant`,
|
|
174
|
+
method: "POST",
|
|
175
|
+
body: data,
|
|
176
|
+
secure: true,
|
|
177
|
+
type: ContentType.Json,
|
|
178
|
+
format: "json",
|
|
179
|
+
...params,
|
|
180
|
+
}),
|
|
181
|
+
/**
|
|
182
|
+
* No description
|
|
183
|
+
*
|
|
184
|
+
* @tags Assistants
|
|
185
|
+
* @name AssistantControllerFindAll
|
|
186
|
+
* @summary List Assistants
|
|
187
|
+
* @request GET:/assistant
|
|
188
|
+
* @secure
|
|
189
|
+
*/
|
|
190
|
+
assistantControllerFindAll: (params = {}) => this.request({
|
|
191
|
+
path: `/assistant`,
|
|
192
|
+
method: "GET",
|
|
193
|
+
secure: true,
|
|
194
|
+
format: "json",
|
|
195
|
+
...params,
|
|
196
|
+
}),
|
|
197
|
+
/**
|
|
198
|
+
* No description
|
|
199
|
+
*
|
|
200
|
+
* @tags Assistants
|
|
201
|
+
* @name AssistantControllerFindOne
|
|
202
|
+
* @summary Get Assistant
|
|
203
|
+
* @request GET:/assistant/{id}
|
|
204
|
+
* @secure
|
|
205
|
+
*/
|
|
206
|
+
assistantControllerFindOne: (id, params = {}) => this.request({
|
|
207
|
+
path: `/assistant/${id}`,
|
|
208
|
+
method: "GET",
|
|
209
|
+
secure: true,
|
|
210
|
+
format: "json",
|
|
211
|
+
...params,
|
|
212
|
+
}),
|
|
213
|
+
/**
|
|
214
|
+
* No description
|
|
215
|
+
*
|
|
216
|
+
* @tags Assistants
|
|
217
|
+
* @name AssistantControllerUpdate
|
|
218
|
+
* @summary Update Assistant
|
|
219
|
+
* @request PATCH:/assistant/{id}
|
|
220
|
+
* @secure
|
|
221
|
+
*/
|
|
222
|
+
assistantControllerUpdate: (id, data, params = {}) => this.request({
|
|
223
|
+
path: `/assistant/${id}`,
|
|
224
|
+
method: "PATCH",
|
|
225
|
+
body: data,
|
|
226
|
+
secure: true,
|
|
227
|
+
type: ContentType.Json,
|
|
228
|
+
format: "json",
|
|
229
|
+
...params,
|
|
230
|
+
}),
|
|
231
|
+
/**
|
|
232
|
+
* No description
|
|
233
|
+
*
|
|
234
|
+
* @tags Assistants
|
|
235
|
+
* @name AssistantControllerReplace
|
|
236
|
+
* @summary Replace Assistant
|
|
237
|
+
* @request PUT:/assistant/{id}
|
|
238
|
+
* @secure
|
|
239
|
+
*/
|
|
240
|
+
assistantControllerReplace: (id, data, params = {}) => this.request({
|
|
241
|
+
path: `/assistant/${id}`,
|
|
242
|
+
method: "PUT",
|
|
243
|
+
body: data,
|
|
244
|
+
secure: true,
|
|
245
|
+
type: ContentType.Json,
|
|
246
|
+
format: "json",
|
|
247
|
+
...params,
|
|
248
|
+
}),
|
|
249
|
+
/**
|
|
250
|
+
* No description
|
|
251
|
+
*
|
|
252
|
+
* @tags Assistants
|
|
253
|
+
* @name AssistantControllerRemove
|
|
254
|
+
* @summary Delete Assistant
|
|
255
|
+
* @request DELETE:/assistant/{id}
|
|
256
|
+
* @secure
|
|
257
|
+
*/
|
|
258
|
+
assistantControllerRemove: (id, params = {}) => this.request({
|
|
259
|
+
path: `/assistant/${id}`,
|
|
260
|
+
method: "DELETE",
|
|
261
|
+
secure: true,
|
|
262
|
+
format: "json",
|
|
263
|
+
...params,
|
|
264
|
+
}),
|
|
265
|
+
};
|
|
266
|
+
call = {
|
|
267
|
+
/**
|
|
268
|
+
* No description
|
|
269
|
+
*
|
|
270
|
+
* @tags Calls
|
|
271
|
+
* @name CallControllerFindAll
|
|
272
|
+
* @summary List Calls
|
|
273
|
+
* @request GET:/call
|
|
274
|
+
* @secure
|
|
275
|
+
*/
|
|
276
|
+
callControllerFindAll: (params = {}) => this.request({
|
|
277
|
+
path: `/call`,
|
|
278
|
+
method: "GET",
|
|
279
|
+
secure: true,
|
|
280
|
+
format: "json",
|
|
281
|
+
...params,
|
|
282
|
+
}),
|
|
283
|
+
/**
|
|
284
|
+
* No description
|
|
285
|
+
*
|
|
286
|
+
* @tags Calls
|
|
287
|
+
* @name CallControllerFindOne
|
|
288
|
+
* @summary Get Call
|
|
289
|
+
* @request GET:/call/{id}
|
|
290
|
+
* @secure
|
|
291
|
+
*/
|
|
292
|
+
callControllerFindOne: (id, params = {}) => this.request({
|
|
293
|
+
path: `/call/${id}`,
|
|
294
|
+
method: "GET",
|
|
295
|
+
secure: true,
|
|
296
|
+
format: "json",
|
|
297
|
+
...params,
|
|
298
|
+
}),
|
|
299
|
+
/**
|
|
300
|
+
* No description
|
|
301
|
+
*
|
|
302
|
+
* @tags Calls
|
|
303
|
+
* @name CallControllerCreatePhoneCall
|
|
304
|
+
* @summary Create Phone Call
|
|
305
|
+
* @request POST:/call/phone
|
|
306
|
+
* @secure
|
|
307
|
+
*/
|
|
308
|
+
callControllerCreatePhoneCall: (data, params = {}) => this.request({
|
|
309
|
+
path: `/call/phone`,
|
|
310
|
+
method: "POST",
|
|
311
|
+
body: data,
|
|
312
|
+
secure: true,
|
|
313
|
+
type: ContentType.Json,
|
|
314
|
+
format: "json",
|
|
315
|
+
...params,
|
|
316
|
+
}),
|
|
317
|
+
/**
|
|
318
|
+
* No description
|
|
319
|
+
*
|
|
320
|
+
* @tags Calls
|
|
321
|
+
* @name CallControllerCreateWebCall
|
|
322
|
+
* @summary Create Web Call
|
|
323
|
+
* @request POST:/call/web
|
|
324
|
+
* @secure
|
|
325
|
+
*/
|
|
326
|
+
callControllerCreateWebCall: (data, params = {}) => this.request({
|
|
327
|
+
path: `/call/web`,
|
|
328
|
+
method: "POST",
|
|
329
|
+
body: data,
|
|
330
|
+
secure: true,
|
|
331
|
+
type: ContentType.Json,
|
|
332
|
+
format: "json",
|
|
333
|
+
...params,
|
|
334
|
+
}),
|
|
335
|
+
};
|
|
336
|
+
credential = {
|
|
337
|
+
/**
|
|
338
|
+
* No description
|
|
339
|
+
*
|
|
340
|
+
* @tags Credentials
|
|
341
|
+
* @name CredentialControllerCreate
|
|
342
|
+
* @summary Create Credential
|
|
343
|
+
* @request POST:/credential
|
|
344
|
+
* @secure
|
|
345
|
+
*/
|
|
346
|
+
credentialControllerCreate: (data, params = {}) => this.request({
|
|
347
|
+
path: `/credential`,
|
|
348
|
+
method: "POST",
|
|
349
|
+
body: data,
|
|
350
|
+
secure: true,
|
|
351
|
+
type: ContentType.Json,
|
|
352
|
+
format: "json",
|
|
353
|
+
...params,
|
|
354
|
+
}),
|
|
355
|
+
/**
|
|
356
|
+
* No description
|
|
357
|
+
*
|
|
358
|
+
* @tags Credentials
|
|
359
|
+
* @name CredentialControllerFindAll
|
|
360
|
+
* @summary List Credentials
|
|
361
|
+
* @request GET:/credential
|
|
362
|
+
* @secure
|
|
363
|
+
*/
|
|
364
|
+
credentialControllerFindAll: (params = {}) => this.request({
|
|
365
|
+
path: `/credential`,
|
|
366
|
+
method: "GET",
|
|
367
|
+
secure: true,
|
|
368
|
+
format: "json",
|
|
369
|
+
...params,
|
|
370
|
+
}),
|
|
371
|
+
/**
|
|
372
|
+
* No description
|
|
373
|
+
*
|
|
374
|
+
* @tags Credentials
|
|
375
|
+
* @name CredentialControllerFindOne
|
|
376
|
+
* @summary Get Credential
|
|
377
|
+
* @request GET:/credential/{id}
|
|
378
|
+
* @secure
|
|
379
|
+
*/
|
|
380
|
+
credentialControllerFindOne: (id, params = {}) => this.request({
|
|
381
|
+
path: `/credential/${id}`,
|
|
382
|
+
method: "GET",
|
|
383
|
+
secure: true,
|
|
384
|
+
format: "json",
|
|
385
|
+
...params,
|
|
386
|
+
}),
|
|
387
|
+
/**
|
|
388
|
+
* No description
|
|
389
|
+
*
|
|
390
|
+
* @tags Credentials
|
|
391
|
+
* @name CredentialControllerUpdate
|
|
392
|
+
* @summary Update Credential
|
|
393
|
+
* @request PUT:/credential/{id}
|
|
394
|
+
* @secure
|
|
395
|
+
*/
|
|
396
|
+
credentialControllerUpdate: (id, data, params = {}) => this.request({
|
|
397
|
+
path: `/credential/${id}`,
|
|
398
|
+
method: "PUT",
|
|
399
|
+
body: data,
|
|
400
|
+
secure: true,
|
|
401
|
+
type: ContentType.Json,
|
|
402
|
+
format: "json",
|
|
403
|
+
...params,
|
|
404
|
+
}),
|
|
405
|
+
/**
|
|
406
|
+
* No description
|
|
407
|
+
*
|
|
408
|
+
* @tags Credentials
|
|
409
|
+
* @name CredentialControllerRemove
|
|
410
|
+
* @summary Delete Credential
|
|
411
|
+
* @request DELETE:/credential/{id}
|
|
412
|
+
* @secure
|
|
413
|
+
*/
|
|
414
|
+
credentialControllerRemove: (id, params = {}) => this.request({
|
|
415
|
+
path: `/credential/${id}`,
|
|
416
|
+
method: "DELETE",
|
|
417
|
+
secure: true,
|
|
418
|
+
format: "json",
|
|
419
|
+
...params,
|
|
420
|
+
}),
|
|
421
|
+
};
|
|
422
|
+
phoneNumber = {
|
|
423
|
+
/**
|
|
424
|
+
* No description
|
|
425
|
+
*
|
|
426
|
+
* @tags Phone Numbers
|
|
427
|
+
* @name PhoneNumberControllerBuy
|
|
428
|
+
* @summary Buy Phone Number
|
|
429
|
+
* @request POST:/phone-number/buy
|
|
430
|
+
* @secure
|
|
431
|
+
*/
|
|
432
|
+
phoneNumberControllerBuy: (data, params = {}) => this.request({
|
|
433
|
+
path: `/phone-number/buy`,
|
|
434
|
+
method: "POST",
|
|
435
|
+
body: data,
|
|
436
|
+
secure: true,
|
|
437
|
+
type: ContentType.Json,
|
|
438
|
+
format: "json",
|
|
439
|
+
...params,
|
|
440
|
+
}),
|
|
441
|
+
/**
|
|
442
|
+
* No description
|
|
443
|
+
*
|
|
444
|
+
* @tags Phone Numbers
|
|
445
|
+
* @name PhoneNumberControllerImport
|
|
446
|
+
* @summary Import Twilio Number
|
|
447
|
+
* @request POST:/phone-number/import
|
|
448
|
+
* @secure
|
|
449
|
+
*/
|
|
450
|
+
phoneNumberControllerImport: (data, params = {}) => this.request({
|
|
451
|
+
path: `/phone-number/import`,
|
|
452
|
+
method: "POST",
|
|
453
|
+
body: data,
|
|
454
|
+
secure: true,
|
|
455
|
+
type: ContentType.Json,
|
|
456
|
+
format: "json",
|
|
457
|
+
...params,
|
|
458
|
+
}),
|
|
459
|
+
/**
|
|
460
|
+
* No description
|
|
461
|
+
*
|
|
462
|
+
* @tags Phone Numbers
|
|
463
|
+
* @name PhoneNumberControllerFindAll
|
|
464
|
+
* @summary List Phone Numbers
|
|
465
|
+
* @request GET:/phone-number
|
|
466
|
+
* @secure
|
|
467
|
+
*/
|
|
468
|
+
phoneNumberControllerFindAll: (params = {}) => this.request({
|
|
469
|
+
path: `/phone-number`,
|
|
470
|
+
method: "GET",
|
|
471
|
+
secure: true,
|
|
472
|
+
format: "json",
|
|
473
|
+
...params,
|
|
474
|
+
}),
|
|
475
|
+
/**
|
|
476
|
+
* No description
|
|
477
|
+
*
|
|
478
|
+
* @tags Phone Numbers
|
|
479
|
+
* @name PhoneNumberControllerFindOne
|
|
480
|
+
* @summary Get Phone Number
|
|
481
|
+
* @request GET:/phone-number/{id}
|
|
482
|
+
* @secure
|
|
483
|
+
*/
|
|
484
|
+
phoneNumberControllerFindOne: (id, params = {}) => this.request({
|
|
485
|
+
path: `/phone-number/${id}`,
|
|
486
|
+
method: "GET",
|
|
487
|
+
secure: true,
|
|
488
|
+
format: "json",
|
|
489
|
+
...params,
|
|
490
|
+
}),
|
|
491
|
+
/**
|
|
492
|
+
* No description
|
|
493
|
+
*
|
|
494
|
+
* @tags Phone Numbers
|
|
495
|
+
* @name PhoneNumberControllerUpdate
|
|
496
|
+
* @summary Update Phone Number
|
|
497
|
+
* @request PATCH:/phone-number/{id}
|
|
498
|
+
* @secure
|
|
499
|
+
*/
|
|
500
|
+
phoneNumberControllerUpdate: (id, data, params = {}) => this.request({
|
|
501
|
+
path: `/phone-number/${id}`,
|
|
502
|
+
method: "PATCH",
|
|
503
|
+
body: data,
|
|
504
|
+
secure: true,
|
|
505
|
+
type: ContentType.Json,
|
|
506
|
+
format: "json",
|
|
507
|
+
...params,
|
|
508
|
+
}),
|
|
509
|
+
/**
|
|
510
|
+
* No description
|
|
511
|
+
*
|
|
512
|
+
* @tags Phone Numbers
|
|
513
|
+
* @name PhoneNumberControllerRemove
|
|
514
|
+
* @summary Delete Phone Number
|
|
515
|
+
* @request DELETE:/phone-number/{id}
|
|
516
|
+
* @secure
|
|
517
|
+
*/
|
|
518
|
+
phoneNumberControllerRemove: (id, params = {}) => this.request({
|
|
519
|
+
path: `/phone-number/${id}`,
|
|
520
|
+
method: "DELETE",
|
|
521
|
+
secure: true,
|
|
522
|
+
format: "json",
|
|
523
|
+
...params,
|
|
524
|
+
}),
|
|
525
|
+
};
|
|
386
526
|
}
|
|
387
527
|
exports.Api = Api;
|
package/dist/client.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.client = void 0;
|
|
13
4
|
const api_1 = require("./api");
|
|
@@ -16,7 +7,7 @@ const api = new api_1.Api({
|
|
|
16
7
|
baseApiParams: {
|
|
17
8
|
secure: true,
|
|
18
9
|
},
|
|
19
|
-
securityWorker: (securityData) =>
|
|
10
|
+
securityWorker: async (securityData) => {
|
|
20
11
|
if (securityData) {
|
|
21
12
|
return {
|
|
22
13
|
headers: {
|
|
@@ -24,6 +15,6 @@ const api = new api_1.Api({
|
|
|
24
15
|
},
|
|
25
16
|
};
|
|
26
17
|
}
|
|
27
|
-
}
|
|
18
|
+
},
|
|
28
19
|
});
|
|
29
20
|
exports.client = api;
|
package/dist/vapi.d.ts
CHANGED
|
@@ -35,6 +35,6 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
35
35
|
private onAppMessage;
|
|
36
36
|
private handleRemoteParticipantsAudioLevel;
|
|
37
37
|
stop(): void;
|
|
38
|
-
|
|
38
|
+
send(message: VapiClientToServerMessage): void;
|
|
39
39
|
}
|
|
40
40
|
export {};
|
package/dist/vapi.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -17,26 +8,22 @@ const events_1 = __importDefault(require("events"));
|
|
|
17
8
|
const client_1 = require("./client");
|
|
18
9
|
function destroyAudioPlayer(participantId) {
|
|
19
10
|
const player = document.querySelector(`audio[data-participant-id="${participantId}"]`);
|
|
20
|
-
player
|
|
11
|
+
player?.remove();
|
|
21
12
|
}
|
|
22
|
-
function startPlayer(player, track) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
});
|
|
13
|
+
async function startPlayer(player, track) {
|
|
14
|
+
player.muted = false;
|
|
15
|
+
player.autoplay = true;
|
|
16
|
+
if (track != null) {
|
|
17
|
+
player.srcObject = new MediaStream([track]);
|
|
18
|
+
await player.play();
|
|
19
|
+
}
|
|
31
20
|
}
|
|
32
|
-
function buildAudioPlayer(track, participantId) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return player;
|
|
39
|
-
});
|
|
21
|
+
async function buildAudioPlayer(track, participantId) {
|
|
22
|
+
const player = document.createElement("audio");
|
|
23
|
+
player.dataset.participantId = participantId;
|
|
24
|
+
document.body.appendChild(player);
|
|
25
|
+
await startPlayer(player, track);
|
|
26
|
+
return player;
|
|
40
27
|
}
|
|
41
28
|
function subscribeToTracks(e, call) {
|
|
42
29
|
if (e.participant.local)
|
|
@@ -70,98 +57,95 @@ class VapiEventEmitter extends events_1.default {
|
|
|
70
57
|
}
|
|
71
58
|
}
|
|
72
59
|
class Vapi extends VapiEventEmitter {
|
|
60
|
+
started = false;
|
|
61
|
+
call = null;
|
|
62
|
+
speakingTimeout = null;
|
|
63
|
+
averageSpeechLevel = 0;
|
|
73
64
|
constructor(apiToken, apiBaseUrl) {
|
|
74
65
|
super();
|
|
75
|
-
|
|
76
|
-
this.call = null;
|
|
77
|
-
this.speakingTimeout = null;
|
|
78
|
-
this.averageSpeechLevel = 0;
|
|
79
|
-
client_1.client.baseUrl = apiBaseUrl !== null && apiBaseUrl !== void 0 ? apiBaseUrl : "https://api.vapi.ai";
|
|
66
|
+
client_1.client.baseUrl = apiBaseUrl ?? "https://api.vapi.ai";
|
|
80
67
|
client_1.client.setSecurityData(apiToken);
|
|
81
68
|
}
|
|
82
69
|
cleanup() {
|
|
83
|
-
var _a;
|
|
84
70
|
this.started = false;
|
|
85
|
-
|
|
71
|
+
this.call?.destroy();
|
|
86
72
|
this.call = null;
|
|
87
73
|
this.speakingTimeout = null;
|
|
88
74
|
}
|
|
89
|
-
start(assistant) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
this.call.on("left-meeting", () => {
|
|
107
|
-
this.emit("call-end");
|
|
108
|
-
this.cleanup();
|
|
109
|
-
});
|
|
110
|
-
this.call.on("participant-left", (e) => {
|
|
111
|
-
if (!e)
|
|
112
|
-
return;
|
|
113
|
-
destroyAudioPlayer(e.participant.session_id);
|
|
114
|
-
});
|
|
115
|
-
this.call.on("error", () => {
|
|
116
|
-
// Ignore error
|
|
117
|
-
});
|
|
118
|
-
this.call.on("track-started", (e) => __awaiter(this, void 0, void 0, function* () {
|
|
119
|
-
var _b, _c, _d;
|
|
120
|
-
if (!e || !e.participant)
|
|
121
|
-
return;
|
|
122
|
-
if ((_b = e.participant) === null || _b === void 0 ? void 0 : _b.local)
|
|
123
|
-
return;
|
|
124
|
-
if (e.track.kind !== "audio")
|
|
125
|
-
return;
|
|
126
|
-
yield buildAudioPlayer(e.track, e.participant.session_id);
|
|
127
|
-
if (((_c = e === null || e === void 0 ? void 0 : e.participant) === null || _c === void 0 ? void 0 : _c.user_name) !== "Vapi Speaker")
|
|
128
|
-
return;
|
|
129
|
-
(_d = this.call) === null || _d === void 0 ? void 0 : _d.sendAppMessage("playable");
|
|
130
|
-
this.emit("call-start");
|
|
131
|
-
}));
|
|
132
|
-
this.call.on("participant-joined", (e) => {
|
|
133
|
-
if (!e || !this.call)
|
|
134
|
-
return;
|
|
135
|
-
subscribeToTracks(e, this.call);
|
|
136
|
-
});
|
|
137
|
-
yield this.call.join({
|
|
138
|
-
url: webCall.webCallUrl,
|
|
139
|
-
subscribeToTracksAutomatically: false,
|
|
140
|
-
});
|
|
141
|
-
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
142
|
-
this.call.on("remote-participants-audio-level", (e) => this.handleRemoteParticipantsAudioLevel(e));
|
|
143
|
-
this.call.on("app-message", (e) => this.onAppMessage(e));
|
|
144
|
-
this.call.updateInputSettings({
|
|
145
|
-
audio: {
|
|
146
|
-
processor: {
|
|
147
|
-
type: "noise-cancellation",
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
});
|
|
151
|
-
return webCall;
|
|
152
|
-
}
|
|
153
|
-
catch (e) {
|
|
154
|
-
console.error(e);
|
|
155
|
-
this.emit("error", e);
|
|
75
|
+
async start(assistant) {
|
|
76
|
+
if (this.started) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
this.started = true;
|
|
80
|
+
try {
|
|
81
|
+
const webCall = (await client_1.client.call.callControllerCreateWebCall({
|
|
82
|
+
assistant: typeof assistant === "string" ? undefined : assistant,
|
|
83
|
+
assistantId: typeof assistant === "string" ? assistant : undefined,
|
|
84
|
+
})).data;
|
|
85
|
+
this.call = daily_js_1.default.createCallObject({
|
|
86
|
+
audioSource: true,
|
|
87
|
+
videoSource: false,
|
|
88
|
+
});
|
|
89
|
+
this.call.iframe()?.style.setProperty("display", "none");
|
|
90
|
+
this.call.on("left-meeting", () => {
|
|
91
|
+
this.emit("call-end");
|
|
156
92
|
this.cleanup();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
93
|
+
});
|
|
94
|
+
this.call.on("participant-left", (e) => {
|
|
95
|
+
if (!e)
|
|
96
|
+
return;
|
|
97
|
+
destroyAudioPlayer(e.participant.session_id);
|
|
98
|
+
});
|
|
99
|
+
this.call.on("error", () => {
|
|
100
|
+
// Ignore error
|
|
101
|
+
});
|
|
102
|
+
this.call.on("track-started", async (e) => {
|
|
103
|
+
if (!e || !e.participant)
|
|
104
|
+
return;
|
|
105
|
+
if (e.participant?.local)
|
|
106
|
+
return;
|
|
107
|
+
if (e.track.kind !== "audio")
|
|
108
|
+
return;
|
|
109
|
+
await buildAudioPlayer(e.track, e.participant.session_id);
|
|
110
|
+
if (e?.participant?.user_name !== "Vapi Speaker")
|
|
111
|
+
return;
|
|
112
|
+
this.call?.sendAppMessage("playable");
|
|
113
|
+
});
|
|
114
|
+
this.call.on("participant-joined", (e) => {
|
|
115
|
+
if (!e || !this.call)
|
|
116
|
+
return;
|
|
117
|
+
subscribeToTracks(e, this.call);
|
|
118
|
+
});
|
|
119
|
+
await this.call.join({
|
|
120
|
+
url: webCall.webCallUrl,
|
|
121
|
+
subscribeToTracksAutomatically: false,
|
|
122
|
+
});
|
|
123
|
+
this.call.startRemoteParticipantsAudioLevelObserver(100);
|
|
124
|
+
this.call.on("remote-participants-audio-level", (e) => this.handleRemoteParticipantsAudioLevel(e));
|
|
125
|
+
this.call.on("app-message", (e) => this.onAppMessage(e));
|
|
126
|
+
this.call.updateInputSettings({
|
|
127
|
+
audio: {
|
|
128
|
+
processor: {
|
|
129
|
+
type: "noise-cancellation",
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
return webCall;
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
console.error(e);
|
|
137
|
+
this.emit("error", e);
|
|
138
|
+
this.cleanup();
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
160
141
|
}
|
|
161
142
|
onAppMessage(e) {
|
|
162
143
|
if (!e)
|
|
163
144
|
return;
|
|
164
145
|
try {
|
|
146
|
+
if (e.data === "listening") {
|
|
147
|
+
return this.emit("call-start");
|
|
148
|
+
}
|
|
165
149
|
const parsedMessage = JSON.parse(e.data);
|
|
166
150
|
this.emit("message", parsedMessage);
|
|
167
151
|
}
|
|
@@ -188,14 +172,12 @@ class Vapi extends VapiEventEmitter {
|
|
|
188
172
|
}, 1000);
|
|
189
173
|
}
|
|
190
174
|
stop() {
|
|
191
|
-
var _a;
|
|
192
175
|
this.started = false;
|
|
193
|
-
|
|
176
|
+
this.call?.destroy();
|
|
194
177
|
this.call = null;
|
|
195
178
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendAppMessage(JSON.stringify(message));
|
|
179
|
+
send(message) {
|
|
180
|
+
this.call?.sendAppMessage(JSON.stringify(message));
|
|
199
181
|
}
|
|
200
182
|
}
|
|
201
183
|
exports.default = Vapi;
|
package/package.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
12
12
|
|
|
13
13
|
/* Language and Environment */
|
|
14
|
-
"target": "
|
|
14
|
+
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
15
15
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
16
16
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
17
17
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
package/vapi.ts
CHANGED
|
@@ -165,7 +165,6 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
165
165
|
|
|
166
166
|
if (e?.participant?.user_name !== "Vapi Speaker") return;
|
|
167
167
|
this.call?.sendAppMessage("playable");
|
|
168
|
-
this.emit("call-start");
|
|
169
168
|
});
|
|
170
169
|
|
|
171
170
|
this.call.on("participant-joined", (e) => {
|
|
@@ -204,6 +203,9 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
204
203
|
private onAppMessage(e?: DailyEventObjectAppMessage) {
|
|
205
204
|
if (!e) return;
|
|
206
205
|
try {
|
|
206
|
+
if (e.data === "listening") {
|
|
207
|
+
return this.emit("call-start");
|
|
208
|
+
}
|
|
207
209
|
const parsedMessage = JSON.parse(e.data);
|
|
208
210
|
this.emit("message", parsedMessage);
|
|
209
211
|
} catch (e) {
|
|
@@ -244,7 +246,7 @@ export default class Vapi extends VapiEventEmitter {
|
|
|
244
246
|
this.call = null;
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
|
|
249
|
+
send(message: VapiClientToServerMessage): void {
|
|
248
250
|
this.call?.sendAppMessage(JSON.stringify(message));
|
|
249
251
|
}
|
|
250
252
|
}
|
|
@@ -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;
|