@d-id/client-sdk 1.1.0-beta.3 → 1.1.0-beta.4
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/index.js +919 -1418
- package/dist/index.umd.cjs +1 -1789
- package/dist/src/types/entities/agents/manager.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.umd.cjs
CHANGED
|
@@ -1,1789 +1 @@
|
|
|
1
|
-
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.index = {}));
|
|
3
|
-
})(this, function(exports2) {
|
|
4
|
-
"use strict";var __defProp = Object.defineProperty;
|
|
5
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
-
var __publicField = (obj, key, value) => {
|
|
7
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
|
-
return value;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
class BaseError extends Error {
|
|
12
|
-
constructor({
|
|
13
|
-
kind,
|
|
14
|
-
description,
|
|
15
|
-
error
|
|
16
|
-
}) {
|
|
17
|
-
super(JSON.stringify({
|
|
18
|
-
kind,
|
|
19
|
-
description
|
|
20
|
-
}));
|
|
21
|
-
__publicField(this, "kind");
|
|
22
|
-
__publicField(this, "description");
|
|
23
|
-
__publicField(this, "error");
|
|
24
|
-
this.kind = kind;
|
|
25
|
-
this.description = description;
|
|
26
|
-
this.error = error;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
class ChatCreationFailed extends BaseError {
|
|
30
|
-
constructor(mode, persistent) {
|
|
31
|
-
super({
|
|
32
|
-
kind: "ChatCreationFailed",
|
|
33
|
-
description: `Failed to create ${persistent ? "persistent" : ""} chat, mode: ${mode}`
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
class ChatModeDowngraded extends BaseError {
|
|
38
|
-
constructor(mode) {
|
|
39
|
-
super({
|
|
40
|
-
kind: "ChatModeDowngraded",
|
|
41
|
-
description: `Chat mode downgraded to ${mode}`
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
class ValidationError extends BaseError {
|
|
46
|
-
constructor(message, key) {
|
|
47
|
-
super({
|
|
48
|
-
kind: "ValidationError",
|
|
49
|
-
description: message
|
|
50
|
-
});
|
|
51
|
-
__publicField(this, "key");
|
|
52
|
-
this.key = key;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
class WsError extends BaseError {
|
|
56
|
-
constructor(message) {
|
|
57
|
-
super({
|
|
58
|
-
kind: "WSError",
|
|
59
|
-
description: message
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
var UserPlan = /* @__PURE__ */ ((UserPlan2) => {
|
|
64
|
-
UserPlan2["TRIAL"] = "trial";
|
|
65
|
-
UserPlan2["BASIC"] = "basic";
|
|
66
|
-
UserPlan2["ENTERPRISE"] = "enterprise";
|
|
67
|
-
UserPlan2["LITE"] = "lite";
|
|
68
|
-
UserPlan2["ADVANCED"] = "advanced";
|
|
69
|
-
return UserPlan2;
|
|
70
|
-
})(UserPlan || {});
|
|
71
|
-
var PlanGroup = /* @__PURE__ */ ((PlanGroup2) => {
|
|
72
|
-
PlanGroup2["TRIAL"] = "deid-trial";
|
|
73
|
-
PlanGroup2["PRO"] = "deid-pro";
|
|
74
|
-
PlanGroup2["ENTERPRISE"] = "deid-enterprise";
|
|
75
|
-
PlanGroup2["LITE"] = "deid-lite";
|
|
76
|
-
PlanGroup2["ADVANCED"] = "deid-advanced";
|
|
77
|
-
PlanGroup2["BUILD"] = "deid-api-build";
|
|
78
|
-
PlanGroup2["LAUNCH"] = "deid-api-launch";
|
|
79
|
-
PlanGroup2["SCALE"] = "deid-api-scale";
|
|
80
|
-
return PlanGroup2;
|
|
81
|
-
})(PlanGroup || {});
|
|
82
|
-
var AgentStatus = /* @__PURE__ */ ((AgentStatus2) => {
|
|
83
|
-
AgentStatus2["Created"] = "created";
|
|
84
|
-
AgentStatus2["Started"] = "started";
|
|
85
|
-
AgentStatus2["Done"] = "done";
|
|
86
|
-
AgentStatus2["Error"] = "error";
|
|
87
|
-
AgentStatus2["Rejected"] = "rejected";
|
|
88
|
-
AgentStatus2["Ready"] = "ready";
|
|
89
|
-
return AgentStatus2;
|
|
90
|
-
})(AgentStatus || {});
|
|
91
|
-
var RateState = /* @__PURE__ */ ((RateState2) => {
|
|
92
|
-
RateState2["Unrated"] = "Unrated";
|
|
93
|
-
RateState2["Positive"] = "Positive";
|
|
94
|
-
RateState2["Negative"] = "Negative";
|
|
95
|
-
return RateState2;
|
|
96
|
-
})(RateState || {});
|
|
97
|
-
var ChatMode = /* @__PURE__ */ ((ChatMode2) => {
|
|
98
|
-
ChatMode2["Functional"] = "Functional";
|
|
99
|
-
ChatMode2["TextOnly"] = "TextOnly";
|
|
100
|
-
ChatMode2["Maintenance"] = "Maintenance";
|
|
101
|
-
ChatMode2["Playground"] = "Playground";
|
|
102
|
-
ChatMode2["DirectPlayback"] = "DirectPlayback";
|
|
103
|
-
return ChatMode2;
|
|
104
|
-
})(ChatMode || {});
|
|
105
|
-
var ChatProgress = /* @__PURE__ */ ((ChatProgress2) => {
|
|
106
|
-
ChatProgress2["Embed"] = "embed";
|
|
107
|
-
ChatProgress2["Query"] = "query";
|
|
108
|
-
ChatProgress2["Partial"] = "partial";
|
|
109
|
-
ChatProgress2["Answer"] = "answer";
|
|
110
|
-
ChatProgress2["Complete"] = "done";
|
|
111
|
-
return ChatProgress2;
|
|
112
|
-
})(ChatProgress || {});
|
|
113
|
-
var Subject = /* @__PURE__ */ ((Subject2) => {
|
|
114
|
-
Subject2["KnowledgeProcessing"] = "knowledge/processing";
|
|
115
|
-
Subject2["KnowledgeIndexing"] = "knowledge/indexing";
|
|
116
|
-
Subject2["KnowledgeFailed"] = "knowledge/error";
|
|
117
|
-
Subject2["KnowledgeDone"] = "knowledge/done";
|
|
118
|
-
return Subject2;
|
|
119
|
-
})(Subject || {});
|
|
120
|
-
var KnowledgeType = /* @__PURE__ */ ((KnowledgeType2) => {
|
|
121
|
-
KnowledgeType2["Knowledge"] = "knowledge";
|
|
122
|
-
KnowledgeType2["Document"] = "document";
|
|
123
|
-
KnowledgeType2["Record"] = "record";
|
|
124
|
-
return KnowledgeType2;
|
|
125
|
-
})(KnowledgeType || {});
|
|
126
|
-
var DocumentType = /* @__PURE__ */ ((DocumentType2) => {
|
|
127
|
-
DocumentType2["Pdf"] = "pdf";
|
|
128
|
-
DocumentType2["Text"] = "text";
|
|
129
|
-
DocumentType2["Html"] = "html";
|
|
130
|
-
DocumentType2["Word"] = "word";
|
|
131
|
-
DocumentType2["Json"] = "json";
|
|
132
|
-
DocumentType2["Markdown"] = "markdown";
|
|
133
|
-
DocumentType2["Csv"] = "csv";
|
|
134
|
-
DocumentType2["Excel"] = "excel";
|
|
135
|
-
DocumentType2["Powerpoint"] = "powerpoint";
|
|
136
|
-
DocumentType2["Archive"] = "archive";
|
|
137
|
-
DocumentType2["Image"] = "image";
|
|
138
|
-
DocumentType2["Audio"] = "audio";
|
|
139
|
-
DocumentType2["Video"] = "video";
|
|
140
|
-
return DocumentType2;
|
|
141
|
-
})(DocumentType || {});
|
|
142
|
-
var VideoType = /* @__PURE__ */ ((VideoType2) => {
|
|
143
|
-
VideoType2["Clip"] = "clip";
|
|
144
|
-
VideoType2["Talk"] = "talk";
|
|
145
|
-
return VideoType2;
|
|
146
|
-
})(VideoType || {});
|
|
147
|
-
const mapVideoType = (type) => {
|
|
148
|
-
switch (type) {
|
|
149
|
-
case "clip":
|
|
150
|
-
return "clip";
|
|
151
|
-
case "talk":
|
|
152
|
-
return "talk";
|
|
153
|
-
default:
|
|
154
|
-
throw new Error(`Unknown video type: ${type}`);
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
var StreamingState = /* @__PURE__ */ ((StreamingState2) => {
|
|
158
|
-
StreamingState2["Start"] = "START";
|
|
159
|
-
StreamingState2["Stop"] = "STOP";
|
|
160
|
-
return StreamingState2;
|
|
161
|
-
})(StreamingState || {});
|
|
162
|
-
var ConnectivityState = /* @__PURE__ */ ((ConnectivityState2) => {
|
|
163
|
-
ConnectivityState2["Strong"] = "STRONG";
|
|
164
|
-
ConnectivityState2["Weak"] = "WEAK";
|
|
165
|
-
ConnectivityState2["Unknown"] = "UNKNOWN";
|
|
166
|
-
return ConnectivityState2;
|
|
167
|
-
})(ConnectivityState || {});
|
|
168
|
-
var AgentActivityState = /* @__PURE__ */ ((AgentActivityState2) => {
|
|
169
|
-
AgentActivityState2["Idle"] = "IDLE";
|
|
170
|
-
AgentActivityState2["Talking"] = "TALKING";
|
|
171
|
-
return AgentActivityState2;
|
|
172
|
-
})(AgentActivityState || {});
|
|
173
|
-
const DataChannelSignalMap = {
|
|
174
|
-
"stream/started": "START",
|
|
175
|
-
"stream/done": "STOP"
|
|
176
|
-
/* Stop */
|
|
177
|
-
};
|
|
178
|
-
var StreamEvents = /* @__PURE__ */ ((StreamEvents2) => {
|
|
179
|
-
StreamEvents2["ChatAnswer"] = "chat/answer";
|
|
180
|
-
StreamEvents2["ChatPartial"] = "chat/partial";
|
|
181
|
-
StreamEvents2["StreamDone"] = "stream/done";
|
|
182
|
-
StreamEvents2["StreamStarted"] = "stream/started";
|
|
183
|
-
StreamEvents2["StreamFailed"] = "stream/error";
|
|
184
|
-
StreamEvents2["StreamReady"] = "stream/ready";
|
|
185
|
-
StreamEvents2["StreamCreated"] = "stream/created";
|
|
186
|
-
StreamEvents2["StreamVideoCreated"] = "stream-video/started";
|
|
187
|
-
StreamEvents2["StreamVideoDone"] = "stream-video/done";
|
|
188
|
-
StreamEvents2["StreamVideoError"] = "stream-video/error";
|
|
189
|
-
StreamEvents2["StreamVideoRejected"] = "stream-video/rejected";
|
|
190
|
-
return StreamEvents2;
|
|
191
|
-
})(StreamEvents || {});
|
|
192
|
-
var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
|
|
193
|
-
ConnectionState2["New"] = "new";
|
|
194
|
-
ConnectionState2["Fail"] = "fail";
|
|
195
|
-
ConnectionState2["Connected"] = "connected";
|
|
196
|
-
ConnectionState2["Connecting"] = "connecting";
|
|
197
|
-
ConnectionState2["Closed"] = "closed";
|
|
198
|
-
ConnectionState2["Completed"] = "completed";
|
|
199
|
-
ConnectionState2["Disconnected"] = "disconnected";
|
|
200
|
-
return ConnectionState2;
|
|
201
|
-
})(ConnectionState || {});
|
|
202
|
-
var StreamType = /* @__PURE__ */ ((StreamType2) => {
|
|
203
|
-
StreamType2["Legacy"] = "legacy";
|
|
204
|
-
StreamType2["Fluent"] = "fluent";
|
|
205
|
-
return StreamType2;
|
|
206
|
-
})(StreamType || {});
|
|
207
|
-
var Providers = /* @__PURE__ */ ((Providers2) => {
|
|
208
|
-
Providers2["Amazon"] = "amazon";
|
|
209
|
-
Providers2["Microsoft"] = "microsoft";
|
|
210
|
-
Providers2["Afflorithmics"] = "afflorithmics";
|
|
211
|
-
Providers2["Elevenlabs"] = "elevenlabs";
|
|
212
|
-
return Providers2;
|
|
213
|
-
})(Providers || {});
|
|
214
|
-
var VoiceAccess = /* @__PURE__ */ ((VoiceAccess2) => {
|
|
215
|
-
VoiceAccess2["Public"] = "public";
|
|
216
|
-
VoiceAccess2["Premium"] = "premium";
|
|
217
|
-
VoiceAccess2["Private"] = "private";
|
|
218
|
-
return VoiceAccess2;
|
|
219
|
-
})(VoiceAccess || {});
|
|
220
|
-
const CONNECTION_RETRY_TIMEOUT_MS = 45 * 1e3;
|
|
221
|
-
const PLAYGROUND_HEADER = "X-Playground-Chat";
|
|
222
|
-
const didApiUrl = "https://api-dev.d-id.com";
|
|
223
|
-
const didSocketApiUrl = "wss://notifications-dev.d-id.com";
|
|
224
|
-
const mixpanelKey = "79f81a83a67430be2bc0fd61042b8faa";
|
|
225
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
226
|
-
const getRandom = () => Math.random().toString(16).slice(2);
|
|
227
|
-
function createRacePromise(timeout, timeoutErrorMessage) {
|
|
228
|
-
let timeId;
|
|
229
|
-
const promise = new Promise((_, reject) => {
|
|
230
|
-
timeId = setTimeout(() => reject(new Error(timeoutErrorMessage)), timeout);
|
|
231
|
-
});
|
|
232
|
-
return {
|
|
233
|
-
promise,
|
|
234
|
-
clear: () => clearTimeout(timeId)
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
async function retryOperation(operation, userOptions) {
|
|
238
|
-
const options = {
|
|
239
|
-
limit: (userOptions == null ? void 0 : userOptions.limit) ?? 3,
|
|
240
|
-
delayMs: (userOptions == null ? void 0 : userOptions.delayMs) ?? 0,
|
|
241
|
-
timeout: (userOptions == null ? void 0 : userOptions.timeout) ?? 3e4,
|
|
242
|
-
timeoutErrorMessage: (userOptions == null ? void 0 : userOptions.timeoutErrorMessage) || "Timeout error",
|
|
243
|
-
shouldRetryFn: (userOptions == null ? void 0 : userOptions.shouldRetryFn) ?? (() => true),
|
|
244
|
-
onRetry: (userOptions == null ? void 0 : userOptions.onRetry) ?? (() => {
|
|
245
|
-
})
|
|
246
|
-
};
|
|
247
|
-
let lastError;
|
|
248
|
-
for (let attempt = 1; attempt <= options.limit; attempt++) {
|
|
249
|
-
try {
|
|
250
|
-
if (!options.timeout) {
|
|
251
|
-
return await operation();
|
|
252
|
-
}
|
|
253
|
-
const {
|
|
254
|
-
promise,
|
|
255
|
-
clear
|
|
256
|
-
} = createRacePromise(options.timeout, options.timeoutErrorMessage);
|
|
257
|
-
const operationPromise = operation().finally(clear);
|
|
258
|
-
return await Promise.race([operationPromise, promise]);
|
|
259
|
-
} catch (error) {
|
|
260
|
-
lastError = error;
|
|
261
|
-
if (!options.shouldRetryFn(error) || attempt >= options.limit) {
|
|
262
|
-
throw error;
|
|
263
|
-
}
|
|
264
|
-
await sleep(options.delayMs);
|
|
265
|
-
options.onRetry(error);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
throw lastError;
|
|
269
|
-
}
|
|
270
|
-
function getExternalId() {
|
|
271
|
-
let key = window.localStorage.getItem("did_external_key_id");
|
|
272
|
-
if (!key) {
|
|
273
|
-
key = Math.random().toString(16).slice(2);
|
|
274
|
-
window.localStorage.setItem("did_external_key_id", key);
|
|
275
|
-
}
|
|
276
|
-
return key;
|
|
277
|
-
}
|
|
278
|
-
let sessionKey = getRandom();
|
|
279
|
-
function getAuthHeader(auth) {
|
|
280
|
-
if (auth.type === "bearer") {
|
|
281
|
-
return `Bearer ${auth.token}`;
|
|
282
|
-
} else if (auth.type === "basic") {
|
|
283
|
-
return `Basic ${btoa(`${auth.username}:${auth.password}`)}`;
|
|
284
|
-
} else if (auth.type === "key") {
|
|
285
|
-
return `Client-Key ${auth.clientKey}.${getExternalId()}_${sessionKey}`;
|
|
286
|
-
} else {
|
|
287
|
-
throw new Error(`Unknown auth type: ${auth}`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
const retryHttpTooManyRequests = (operation) => retryOperation(operation, {
|
|
291
|
-
limit: 3,
|
|
292
|
-
delayMs: 1e3,
|
|
293
|
-
timeout: 0,
|
|
294
|
-
shouldRetryFn: (error) => error.status === 429
|
|
295
|
-
});
|
|
296
|
-
function createClient(auth, host = didApiUrl, onError) {
|
|
297
|
-
const client = async (url, options) => {
|
|
298
|
-
const {
|
|
299
|
-
skipErrorHandler,
|
|
300
|
-
...fetchOptions
|
|
301
|
-
} = options || {};
|
|
302
|
-
const request = await retryHttpTooManyRequests(() => fetch(host + ((url == null ? void 0 : url.startsWith("/")) ? url : `/${url}`), {
|
|
303
|
-
...fetchOptions,
|
|
304
|
-
headers: {
|
|
305
|
-
...fetchOptions.headers,
|
|
306
|
-
Authorization: getAuthHeader(auth),
|
|
307
|
-
"Content-Type": "application/json"
|
|
308
|
-
}
|
|
309
|
-
}));
|
|
310
|
-
if (!request.ok) {
|
|
311
|
-
let errorText = await request.text().catch(() => `Failed to fetch with status ${request.status}`);
|
|
312
|
-
const error = new Error(errorText);
|
|
313
|
-
if (onError && !skipErrorHandler) {
|
|
314
|
-
onError(error, {
|
|
315
|
-
url,
|
|
316
|
-
options: fetchOptions,
|
|
317
|
-
headers: request.headers
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
throw error;
|
|
321
|
-
}
|
|
322
|
-
return request.json();
|
|
323
|
-
};
|
|
324
|
-
return {
|
|
325
|
-
get(url, options) {
|
|
326
|
-
return client(url, {
|
|
327
|
-
...options,
|
|
328
|
-
method: "GET"
|
|
329
|
-
});
|
|
330
|
-
},
|
|
331
|
-
post(url, body, options) {
|
|
332
|
-
return client(url, {
|
|
333
|
-
...options,
|
|
334
|
-
body: JSON.stringify(body),
|
|
335
|
-
method: "POST"
|
|
336
|
-
});
|
|
337
|
-
},
|
|
338
|
-
delete(url, body, options) {
|
|
339
|
-
return client(url, {
|
|
340
|
-
...options,
|
|
341
|
-
body: JSON.stringify(body),
|
|
342
|
-
method: "DELETE"
|
|
343
|
-
});
|
|
344
|
-
},
|
|
345
|
-
patch(url, body, options) {
|
|
346
|
-
return client(url, {
|
|
347
|
-
...options,
|
|
348
|
-
body: JSON.stringify(body),
|
|
349
|
-
method: "PATCH"
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
function createAgentsApi(auth, host = didApiUrl, onError) {
|
|
355
|
-
const client = createClient(auth, `${host}/agents`, onError);
|
|
356
|
-
return {
|
|
357
|
-
create(payload, options) {
|
|
358
|
-
return client.post(`/`, payload, options);
|
|
359
|
-
},
|
|
360
|
-
getAgents(tag, options) {
|
|
361
|
-
return client.get(`/${tag ? `?tag=${tag}` : ""}`, options).then((agents) => agents ?? []);
|
|
362
|
-
},
|
|
363
|
-
getById(id, options) {
|
|
364
|
-
return client.get(`/${id}`, options);
|
|
365
|
-
},
|
|
366
|
-
delete(id, options) {
|
|
367
|
-
return client.delete(`/${id}`, void 0, options);
|
|
368
|
-
},
|
|
369
|
-
update(id, payload, options) {
|
|
370
|
-
return client.patch(`/${id}`, payload, options);
|
|
371
|
-
},
|
|
372
|
-
newChat(agentId, payload, options) {
|
|
373
|
-
return client.post(`/${agentId}/chat`, payload, options);
|
|
374
|
-
},
|
|
375
|
-
chat(agentId, chatId, payload, options) {
|
|
376
|
-
return client.post(`/${agentId}/chat/${chatId}`, payload, options);
|
|
377
|
-
},
|
|
378
|
-
createRating(agentId, chatId, payload, options) {
|
|
379
|
-
return client.post(`/${agentId}/chat/${chatId}/ratings`, payload, options);
|
|
380
|
-
},
|
|
381
|
-
updateRating(agentId, chatId, ratingId, payload, options) {
|
|
382
|
-
return client.patch(`/${agentId}/chat/${chatId}/ratings/${ratingId}`, payload, options);
|
|
383
|
-
},
|
|
384
|
-
deleteRating(agentId, chatId, ratingId, options) {
|
|
385
|
-
return client.delete(`/${agentId}/chat/${chatId}/ratings/${ratingId}`, options);
|
|
386
|
-
},
|
|
387
|
-
getSTTToken(agentId, options) {
|
|
388
|
-
return client.get(`/${agentId}/stt-token`, options);
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
const getAgentType = (presenter) => presenter.type === "clip" && presenter.presenter_id.startsWith("v2_") ? "clip_v2" : presenter.type;
|
|
393
|
-
function getAnalyticsInfo(agent) {
|
|
394
|
-
var _a, _b, _c, _d;
|
|
395
|
-
const mobileOrDesktop = () => {
|
|
396
|
-
return /Mobi|Android/i.test(navigator.userAgent) ? "Mobile" : "Desktop";
|
|
397
|
-
};
|
|
398
|
-
const getUserOS = () => {
|
|
399
|
-
const platform = navigator.platform;
|
|
400
|
-
if (platform.toLowerCase().includes("win")) {
|
|
401
|
-
return "Windows";
|
|
402
|
-
} else if (platform.toLowerCase().includes("mac")) {
|
|
403
|
-
return "Mac OS X";
|
|
404
|
-
} else if (platform.toLowerCase().includes("linux")) {
|
|
405
|
-
return "Linux";
|
|
406
|
-
} else {
|
|
407
|
-
return "Unknown";
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
const presenter = agent.presenter;
|
|
411
|
-
return {
|
|
412
|
-
$os: `${getUserOS()}`,
|
|
413
|
-
isMobile: `${mobileOrDesktop() == "Mobile"}`,
|
|
414
|
-
browser: navigator.userAgent,
|
|
415
|
-
origin: window.location.origin,
|
|
416
|
-
agentType: getAgentType(presenter),
|
|
417
|
-
agentVoice: {
|
|
418
|
-
voiceId: (_b = (_a = agent.presenter) == null ? void 0 : _a.voice) == null ? void 0 : _b.voice_id,
|
|
419
|
-
provider: (_d = (_c = agent.presenter) == null ? void 0 : _c.voice) == null ? void 0 : _d.type
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
const sumFunc = (numbers) => numbers.reduce((total, aNumber) => total + aNumber, 0);
|
|
424
|
-
const average = (numbers) => sumFunc(numbers) / numbers.length;
|
|
425
|
-
function getStreamAnalyticsProps(data, agent, additionalProps) {
|
|
426
|
-
var _a, _b, _c;
|
|
427
|
-
const {
|
|
428
|
-
event,
|
|
429
|
-
...baseProps
|
|
430
|
-
} = data;
|
|
431
|
-
const {
|
|
432
|
-
template
|
|
433
|
-
} = (agent == null ? void 0 : agent.llm) || {};
|
|
434
|
-
const {
|
|
435
|
-
language
|
|
436
|
-
} = ((_a = agent == null ? void 0 : agent.presenter) == null ? void 0 : _a.voice) || {};
|
|
437
|
-
const props = {
|
|
438
|
-
...baseProps,
|
|
439
|
-
llm: {
|
|
440
|
-
...baseProps.llm,
|
|
441
|
-
template
|
|
442
|
-
},
|
|
443
|
-
script: {
|
|
444
|
-
...baseProps.script,
|
|
445
|
-
provider: {
|
|
446
|
-
...(_b = baseProps == null ? void 0 : baseProps.script) == null ? void 0 : _b.provider,
|
|
447
|
-
language
|
|
448
|
-
}
|
|
449
|
-
},
|
|
450
|
-
stitch: (agent == null ? void 0 : agent.presenter.type) === "talk" ? (_c = agent == null ? void 0 : agent.presenter) == null ? void 0 : _c.stitch : void 0,
|
|
451
|
-
...additionalProps
|
|
452
|
-
};
|
|
453
|
-
return props;
|
|
454
|
-
}
|
|
455
|
-
let mixpanelEvents = {};
|
|
456
|
-
const mixpanelUrl = "https://api-js.mixpanel.com/track/?verbose=1&ip=1";
|
|
457
|
-
function initializeAnalytics(config) {
|
|
458
|
-
var _a, _b, _c, _d, _e, _f;
|
|
459
|
-
const source = (window == null ? void 0 : window.hasOwnProperty("DID_AGENTS_API")) ? "agents-ui" : "agents-sdk";
|
|
460
|
-
const presenter = config.agent.presenter;
|
|
461
|
-
const promptCustomization = (_a = config.agent.llm) == null ? void 0 : _a.prompt_customization;
|
|
462
|
-
const analyticProps = {
|
|
463
|
-
token: config.token || "testKey",
|
|
464
|
-
distinct_id: config.distinctId || getExternalId(),
|
|
465
|
-
agentId: config.agent.id,
|
|
466
|
-
agentType: getAgentType(presenter),
|
|
467
|
-
owner_id: config.agent.owner_id ?? "",
|
|
468
|
-
promptVersion: (_b = config.agent.llm) == null ? void 0 : _b.prompt_version,
|
|
469
|
-
behavior: {
|
|
470
|
-
role: promptCustomization == null ? void 0 : promptCustomization.role,
|
|
471
|
-
personality: promptCustomization == null ? void 0 : promptCustomization.personality,
|
|
472
|
-
instructions: (_c = config.agent.llm) == null ? void 0 : _c.instructions
|
|
473
|
-
},
|
|
474
|
-
temperature: (_d = config.agent.llm) == null ? void 0 : _d.temperature,
|
|
475
|
-
knowledgeSource: promptCustomization == null ? void 0 : promptCustomization.knowledge_source,
|
|
476
|
-
starterQuestionsCount: (_f = (_e = config.agent.knowledge) == null ? void 0 : _e.starter_message) == null ? void 0 : _f.length,
|
|
477
|
-
topicsToAvoid: promptCustomization == null ? void 0 : promptCustomization.topics_to_avoid,
|
|
478
|
-
maxResponseLength: promptCustomization == null ? void 0 : promptCustomization.max_response_length
|
|
479
|
-
};
|
|
480
|
-
return {
|
|
481
|
-
...analyticProps,
|
|
482
|
-
additionalProperties: {},
|
|
483
|
-
isEnabled: config.isEnabled ?? true,
|
|
484
|
-
getRandom: () => Math.random().toString(16).slice(2),
|
|
485
|
-
enrich(properties) {
|
|
486
|
-
const props = {};
|
|
487
|
-
if (properties && typeof properties !== "object") {
|
|
488
|
-
throw new Error("properties must be a flat json object");
|
|
489
|
-
}
|
|
490
|
-
for (let prop in properties) {
|
|
491
|
-
if (typeof properties[prop] === "string" || typeof properties[prop] === "number") {
|
|
492
|
-
props[prop] = properties[prop];
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
this.additionalProperties = {
|
|
496
|
-
...this.additionalProperties,
|
|
497
|
-
...props
|
|
498
|
-
};
|
|
499
|
-
},
|
|
500
|
-
async track(event, props) {
|
|
501
|
-
if (!this.isEnabled) {
|
|
502
|
-
return Promise.resolve();
|
|
503
|
-
}
|
|
504
|
-
const {
|
|
505
|
-
audioPath,
|
|
506
|
-
...sendProps
|
|
507
|
-
} = props || {};
|
|
508
|
-
const options = {
|
|
509
|
-
method: "POST",
|
|
510
|
-
headers: {
|
|
511
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
512
|
-
},
|
|
513
|
-
body: new URLSearchParams({
|
|
514
|
-
data: JSON.stringify([{
|
|
515
|
-
event,
|
|
516
|
-
properties: {
|
|
517
|
-
...this.additionalProperties,
|
|
518
|
-
...sendProps,
|
|
519
|
-
...analyticProps,
|
|
520
|
-
source,
|
|
521
|
-
time: Date.now(),
|
|
522
|
-
$insert_id: this.getRandom(),
|
|
523
|
-
origin: window.location.href,
|
|
524
|
-
"Screen Height": window.screen.height || window.innerWidth,
|
|
525
|
-
"Screen Width": window.screen.width || window.innerHeight,
|
|
526
|
-
"User Agent": navigator.userAgent
|
|
527
|
-
}
|
|
528
|
-
}])
|
|
529
|
-
})
|
|
530
|
-
};
|
|
531
|
-
try {
|
|
532
|
-
return await fetch(mixpanelUrl, options).then((res) => res.json());
|
|
533
|
-
} catch (err) {
|
|
534
|
-
return console.error(err);
|
|
535
|
-
}
|
|
536
|
-
},
|
|
537
|
-
linkTrack(mixpanelEvent, props, event, dependencies) {
|
|
538
|
-
if (!mixpanelEvents[mixpanelEvent]) {
|
|
539
|
-
mixpanelEvents[mixpanelEvent] = {
|
|
540
|
-
events: {},
|
|
541
|
-
resolvedDependencies: []
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
if (!dependencies.includes(event)) {
|
|
545
|
-
dependencies.push(event);
|
|
546
|
-
}
|
|
547
|
-
const linkedEvent = mixpanelEvents[mixpanelEvent];
|
|
548
|
-
linkedEvent.events[event] = {
|
|
549
|
-
props
|
|
550
|
-
};
|
|
551
|
-
linkedEvent.resolvedDependencies.push(event);
|
|
552
|
-
const allDependenciesResolved = dependencies.every((value) => linkedEvent.resolvedDependencies.includes(value));
|
|
553
|
-
if (allDependenciesResolved) {
|
|
554
|
-
const aggregatedProps = dependencies.reduce((acc, curr) => {
|
|
555
|
-
if (linkedEvent.events[curr]) {
|
|
556
|
-
return {
|
|
557
|
-
...acc,
|
|
558
|
-
...linkedEvent.events[curr].props
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
return acc;
|
|
562
|
-
}, {});
|
|
563
|
-
this.track(mixpanelEvent, aggregatedProps);
|
|
564
|
-
linkedEvent.resolvedDependencies = linkedEvent.resolvedDependencies.filter((event2) => !dependencies.includes(event2));
|
|
565
|
-
dependencies.forEach((event2) => {
|
|
566
|
-
delete linkedEvent.events[event2];
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
function createTimestampTracker() {
|
|
573
|
-
let timestamp = 0;
|
|
574
|
-
return {
|
|
575
|
-
reset: () => timestamp = 0,
|
|
576
|
-
update: () => timestamp = Date.now(),
|
|
577
|
-
get: (delta = false) => delta ? Date.now() - timestamp : timestamp
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
const timestampTracker = createTimestampTracker();
|
|
581
|
-
function getRequestHeaders(chatMode) {
|
|
582
|
-
return chatMode === ChatMode.Playground ? {
|
|
583
|
-
headers: {
|
|
584
|
-
[PLAYGROUND_HEADER]: "true"
|
|
585
|
-
}
|
|
586
|
-
} : {};
|
|
587
|
-
}
|
|
588
|
-
async function createChat(agent, agentsApi, analytics, chatMode, persist = false, chat) {
|
|
589
|
-
try {
|
|
590
|
-
if (!chat && chatMode !== ChatMode.DirectPlayback) {
|
|
591
|
-
chat = await agentsApi.newChat(agent.id, {
|
|
592
|
-
persist
|
|
593
|
-
}, getRequestHeaders(chatMode));
|
|
594
|
-
analytics.track("agent-chat", {
|
|
595
|
-
event: "created",
|
|
596
|
-
chat_id: chat.id,
|
|
597
|
-
agent_id: agent.id,
|
|
598
|
-
mode: chatMode
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
return {
|
|
602
|
-
chat,
|
|
603
|
-
chatMode: (chat == null ? void 0 : chat.chat_mode) ?? chatMode
|
|
604
|
-
};
|
|
605
|
-
} catch (error) {
|
|
606
|
-
try {
|
|
607
|
-
const parsedError = JSON.parse(error.message);
|
|
608
|
-
if ((parsedError == null ? void 0 : parsedError.kind) === "InsufficientCreditsError") {
|
|
609
|
-
throw new Error("InsufficientCreditsError");
|
|
610
|
-
}
|
|
611
|
-
} catch (e) {
|
|
612
|
-
console.error("Error parsing the error message:", e);
|
|
613
|
-
}
|
|
614
|
-
throw new Error("Cannot create new chat");
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
function getGreetings(agent) {
|
|
618
|
-
var _a;
|
|
619
|
-
const greetings = ((_a = agent.greetings) == null ? void 0 : _a.filter((greeting) => greeting.length > 0)) ?? [];
|
|
620
|
-
if (greetings.length > 0) {
|
|
621
|
-
return greetings[Math.floor(Math.random() * greetings.length)];
|
|
622
|
-
}
|
|
623
|
-
return `Hi! I'm ${agent.preview_name || "My Agent"}. How can I help you?`;
|
|
624
|
-
}
|
|
625
|
-
function getInitialMessages(content, initialMessages) {
|
|
626
|
-
if (initialMessages && initialMessages.length > 0) {
|
|
627
|
-
return initialMessages;
|
|
628
|
-
}
|
|
629
|
-
return [{
|
|
630
|
-
content,
|
|
631
|
-
id: getRandom(),
|
|
632
|
-
role: "assistant",
|
|
633
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
634
|
-
}];
|
|
635
|
-
}
|
|
636
|
-
function connect(options) {
|
|
637
|
-
return new Promise((resolve, reject) => {
|
|
638
|
-
const {
|
|
639
|
-
callbacks,
|
|
640
|
-
host,
|
|
641
|
-
auth
|
|
642
|
-
} = options;
|
|
643
|
-
const {
|
|
644
|
-
onMessage = null,
|
|
645
|
-
onOpen = null,
|
|
646
|
-
onClose = null,
|
|
647
|
-
onError = null
|
|
648
|
-
} = callbacks || {};
|
|
649
|
-
const socket = new WebSocket(`${host}?authorization=${getAuthHeader(auth)}`);
|
|
650
|
-
socket.onmessage = onMessage;
|
|
651
|
-
socket.onclose = onClose;
|
|
652
|
-
socket.onerror = (e) => {
|
|
653
|
-
console.error(e);
|
|
654
|
-
onError == null ? void 0 : onError("Websocket failed to connect", e);
|
|
655
|
-
reject(e);
|
|
656
|
-
};
|
|
657
|
-
socket.onopen = (e) => {
|
|
658
|
-
onOpen == null ? void 0 : onOpen(e);
|
|
659
|
-
resolve(socket);
|
|
660
|
-
};
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
async function connectWithRetries(options) {
|
|
664
|
-
const {
|
|
665
|
-
retries = 1
|
|
666
|
-
} = options;
|
|
667
|
-
let socket = null;
|
|
668
|
-
for (let attempt = 0; (socket == null ? void 0 : socket.readyState) !== WebSocket.OPEN; attempt++) {
|
|
669
|
-
try {
|
|
670
|
-
socket = await connect(options);
|
|
671
|
-
} catch (e) {
|
|
672
|
-
if (attempt === retries) {
|
|
673
|
-
throw e;
|
|
674
|
-
}
|
|
675
|
-
await sleep(attempt * 500);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
return socket;
|
|
679
|
-
}
|
|
680
|
-
async function createSocketManager(auth, host, callbacks) {
|
|
681
|
-
const messageCallbacks = (callbacks == null ? void 0 : callbacks.onMessage) ? [callbacks.onMessage] : [];
|
|
682
|
-
const socket = await connectWithRetries({
|
|
683
|
-
auth,
|
|
684
|
-
host,
|
|
685
|
-
callbacks: {
|
|
686
|
-
onError: (error) => {
|
|
687
|
-
var _a;
|
|
688
|
-
return (_a = callbacks.onError) == null ? void 0 : _a.call(callbacks, new WsError(error));
|
|
689
|
-
},
|
|
690
|
-
onMessage(event) {
|
|
691
|
-
const parsedData = JSON.parse(event.data);
|
|
692
|
-
messageCallbacks.forEach((callback) => callback(parsedData.event, parsedData));
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
return {
|
|
697
|
-
socket,
|
|
698
|
-
disconnect: () => socket.close(),
|
|
699
|
-
subscribeToEvents: (callback) => messageCallbacks.push(callback)
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
function getMessageContent(chatEventQueue) {
|
|
703
|
-
if (chatEventQueue["answer"] !== void 0) {
|
|
704
|
-
return chatEventQueue["answer"];
|
|
705
|
-
}
|
|
706
|
-
let currentSequence = 0;
|
|
707
|
-
let content = "";
|
|
708
|
-
while (currentSequence in chatEventQueue) {
|
|
709
|
-
content += chatEventQueue[currentSequence++];
|
|
710
|
-
}
|
|
711
|
-
return content;
|
|
712
|
-
}
|
|
713
|
-
function processChatEvent(event, data, chatEventQueue, items, onNewMessage) {
|
|
714
|
-
const lastMessage = items.messages[items.messages.length - 1];
|
|
715
|
-
if (!(event === ChatProgress.Partial || event === ChatProgress.Answer) || (lastMessage == null ? void 0 : lastMessage.role) !== "assistant") {
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
718
|
-
const {
|
|
719
|
-
content,
|
|
720
|
-
sequence
|
|
721
|
-
} = data;
|
|
722
|
-
if (event === ChatProgress.Partial) {
|
|
723
|
-
chatEventQueue[sequence] = content;
|
|
724
|
-
} else {
|
|
725
|
-
chatEventQueue["answer"] = content;
|
|
726
|
-
}
|
|
727
|
-
const messageContent = getMessageContent(chatEventQueue);
|
|
728
|
-
if (lastMessage.content !== messageContent || event === ChatProgress.Answer) {
|
|
729
|
-
lastMessage.content = messageContent;
|
|
730
|
-
onNewMessage == null ? void 0 : onNewMessage([...items.messages], event);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
function createMessageEventQueue(analytics, items, options, agentEntity, onStreamDone) {
|
|
734
|
-
let chatEventQueue = {};
|
|
735
|
-
return {
|
|
736
|
-
clearQueue: () => chatEventQueue = {},
|
|
737
|
-
onMessage: (event, data) => {
|
|
738
|
-
var _a, _b;
|
|
739
|
-
if ("content" in data) {
|
|
740
|
-
processChatEvent(event, data, chatEventQueue, items, options.callbacks.onNewMessage);
|
|
741
|
-
if (event === ChatProgress.Answer) {
|
|
742
|
-
analytics.track("agent-message-received", {
|
|
743
|
-
messages: items.messages.length,
|
|
744
|
-
mode: items.chatMode
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
} else {
|
|
748
|
-
const SEvent = StreamEvents;
|
|
749
|
-
const completedEvents = [SEvent.StreamVideoDone, SEvent.StreamVideoError, SEvent.StreamVideoRejected];
|
|
750
|
-
const failedEvents = [SEvent.StreamFailed, SEvent.StreamVideoError, SEvent.StreamVideoRejected];
|
|
751
|
-
const props = getStreamAnalyticsProps(data, agentEntity, {
|
|
752
|
-
mode: items.chatMode
|
|
753
|
-
});
|
|
754
|
-
event = event;
|
|
755
|
-
if (event === SEvent.StreamVideoCreated) {
|
|
756
|
-
analytics.linkTrack("agent-video", props, SEvent.StreamVideoCreated, ["start"]);
|
|
757
|
-
} else if (completedEvents.includes(event)) {
|
|
758
|
-
const streamEvent = event.split("/")[1];
|
|
759
|
-
if (failedEvents.includes(event)) {
|
|
760
|
-
analytics.track("agent-video", {
|
|
761
|
-
...props,
|
|
762
|
-
event: streamEvent
|
|
763
|
-
});
|
|
764
|
-
} else {
|
|
765
|
-
analytics.linkTrack("agent-video", {
|
|
766
|
-
...props,
|
|
767
|
-
event: streamEvent
|
|
768
|
-
}, event, ["done"]);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
if (failedEvents.includes(event)) {
|
|
772
|
-
(_b = (_a = options.callbacks).onError) == null ? void 0 : _b.call(_a, new Error(`Stream failed with event ${event}`), {
|
|
773
|
-
data
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
if (data.event === SEvent.StreamDone) {
|
|
777
|
-
onStreamDone();
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
};
|
|
782
|
-
}
|
|
783
|
-
function createClipApi(auth, host, agentId, onError) {
|
|
784
|
-
const client = createClient(auth, `${host}/agents/${agentId}`, onError);
|
|
785
|
-
return {
|
|
786
|
-
createStream(options) {
|
|
787
|
-
return client.post("/streams", {
|
|
788
|
-
output_resolution: options.output_resolution,
|
|
789
|
-
compatibility_mode: options.compatibility_mode,
|
|
790
|
-
stream_warmup: options.stream_warmup,
|
|
791
|
-
session_timeout: options.session_timeout,
|
|
792
|
-
stream_greeting: options.stream_greeting
|
|
793
|
-
});
|
|
794
|
-
},
|
|
795
|
-
startConnection(streamId, answer, sessionId) {
|
|
796
|
-
return client.post(`/streams/${streamId}/sdp`, {
|
|
797
|
-
session_id: sessionId,
|
|
798
|
-
answer
|
|
799
|
-
});
|
|
800
|
-
},
|
|
801
|
-
addIceCandidate(streamId, candidate, sessionId) {
|
|
802
|
-
return client.post(`/streams/${streamId}/ice`, {
|
|
803
|
-
session_id: sessionId,
|
|
804
|
-
...candidate
|
|
805
|
-
});
|
|
806
|
-
},
|
|
807
|
-
sendStreamRequest(streamId, sessionId, payload) {
|
|
808
|
-
return client.post(`/streams/${streamId}`, {
|
|
809
|
-
session_id: sessionId,
|
|
810
|
-
...payload
|
|
811
|
-
});
|
|
812
|
-
},
|
|
813
|
-
close(streamId, sessionId) {
|
|
814
|
-
return client.delete(`/streams/${streamId}`, {
|
|
815
|
-
session_id: sessionId
|
|
816
|
-
});
|
|
817
|
-
}
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
function createTalkApi(auth, host, agentId, onError) {
|
|
821
|
-
const client = createClient(auth, `${host}/agents/${agentId}`, onError);
|
|
822
|
-
return {
|
|
823
|
-
createStream(streamOptions, options) {
|
|
824
|
-
return client.post("/streams", {
|
|
825
|
-
driver_url: streamOptions.driver_url,
|
|
826
|
-
face: streamOptions.face,
|
|
827
|
-
config: streamOptions.config,
|
|
828
|
-
output_resolution: streamOptions.output_resolution,
|
|
829
|
-
compatibility_mode: streamOptions.compatibility_mode,
|
|
830
|
-
stream_warmup: streamOptions.stream_warmup,
|
|
831
|
-
session_timeout: streamOptions.session_timeout,
|
|
832
|
-
stream_greeting: streamOptions.stream_greeting
|
|
833
|
-
}, options);
|
|
834
|
-
},
|
|
835
|
-
startConnection(streamId, answer, sessionId, options) {
|
|
836
|
-
return client.post(`/streams/${streamId}/sdp`, {
|
|
837
|
-
session_id: sessionId,
|
|
838
|
-
answer
|
|
839
|
-
}, options);
|
|
840
|
-
},
|
|
841
|
-
addIceCandidate(streamId, candidate, sessionId, options) {
|
|
842
|
-
return client.post(`/streams/${streamId}/ice`, {
|
|
843
|
-
session_id: sessionId,
|
|
844
|
-
...candidate
|
|
845
|
-
}, options);
|
|
846
|
-
},
|
|
847
|
-
sendStreamRequest(streamId, sessionId, payload, options) {
|
|
848
|
-
return client.post(`/streams/${streamId}`, {
|
|
849
|
-
session_id: sessionId,
|
|
850
|
-
...payload
|
|
851
|
-
}, options);
|
|
852
|
-
},
|
|
853
|
-
close(streamId, sessionId, options) {
|
|
854
|
-
return client.delete(`/streams/${streamId}`, {
|
|
855
|
-
session_id: sessionId
|
|
856
|
-
}, options);
|
|
857
|
-
}
|
|
858
|
-
};
|
|
859
|
-
}
|
|
860
|
-
function createAggregateReport(start, end, lowFpsCount) {
|
|
861
|
-
const duration = (end.timestamp - start.timestamp) / 1e3;
|
|
862
|
-
return {
|
|
863
|
-
duration,
|
|
864
|
-
bytesReceived: end.bytesReceived - start.bytesReceived,
|
|
865
|
-
bitrate: Math.round((end.bytesReceived - start.bytesReceived) * 8 / duration),
|
|
866
|
-
packetsReceived: end.packetsReceived - start.packetsReceived,
|
|
867
|
-
packetsLost: end.packetsLost - start.packetsLost,
|
|
868
|
-
framesDropped: end.framesDropped - start.framesDropped,
|
|
869
|
-
framesDecoded: end.framesDecoded - start.framesDecoded,
|
|
870
|
-
jitter: end.jitter,
|
|
871
|
-
avgJitterDelayInInterval: (end.jitterBufferDelay - start.jitterBufferDelay) / (end.jitterBufferEmittedCount - start.jitterBufferEmittedCount),
|
|
872
|
-
jitterBufferEmittedCount: end.jitterBufferEmittedCount - start.jitterBufferEmittedCount,
|
|
873
|
-
jitterBufferDelay: (end.jitterBufferDelay - start.jitterBufferDelay) / duration,
|
|
874
|
-
framesPerSecond: end.framesPerSecond,
|
|
875
|
-
freezeCount: end.freezeCount - start.freezeCount,
|
|
876
|
-
freezeDuration: end.freezeDuration - start.freezeDuration,
|
|
877
|
-
lowFpsCount
|
|
878
|
-
};
|
|
879
|
-
}
|
|
880
|
-
function extractAnomalies(stats) {
|
|
881
|
-
return stats.filter((report) => report.freezeCount > 0 || report.framesPerSecond < 21 || report.framesDropped > 0 || report.packetsLost > 0).map((report) => {
|
|
882
|
-
const {
|
|
883
|
-
timestamp,
|
|
884
|
-
...updatedReport
|
|
885
|
-
} = report;
|
|
886
|
-
const causes = [];
|
|
887
|
-
if (report.freezeCount > 0) {
|
|
888
|
-
causes.push("freeze");
|
|
889
|
-
}
|
|
890
|
-
if (report.framesPerSecond < 21) {
|
|
891
|
-
causes.push("low fps");
|
|
892
|
-
}
|
|
893
|
-
if (report.framesDropped > 0) {
|
|
894
|
-
causes.push("frames dropped");
|
|
895
|
-
}
|
|
896
|
-
if (report.packetsLost > 0) {
|
|
897
|
-
causes.push("packet loss");
|
|
898
|
-
}
|
|
899
|
-
return {
|
|
900
|
-
...updatedReport,
|
|
901
|
-
causes
|
|
902
|
-
};
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
function formatStats(stats) {
|
|
906
|
-
let codec = "";
|
|
907
|
-
for (const report of stats.values()) {
|
|
908
|
-
if (report && report.type === "codec" && report.mimeType.startsWith("video")) {
|
|
909
|
-
codec = report.mimeType.split("/")[1];
|
|
910
|
-
}
|
|
911
|
-
if (report && report.type === "inbound-rtp" && report.kind === "video") {
|
|
912
|
-
return {
|
|
913
|
-
codec,
|
|
914
|
-
timestamp: report.timestamp,
|
|
915
|
-
bytesReceived: report.bytesReceived,
|
|
916
|
-
packetsReceived: report.packetsReceived,
|
|
917
|
-
packetsLost: report.packetsLost,
|
|
918
|
-
framesDropped: report.framesDropped,
|
|
919
|
-
framesDecoded: report.framesDecoded,
|
|
920
|
-
jitter: report.jitter,
|
|
921
|
-
jitterBufferDelay: report.jitterBufferDelay,
|
|
922
|
-
jitterBufferEmittedCount: report.jitterBufferEmittedCount,
|
|
923
|
-
avgJitterDelayInInterval: report.jitterBufferDelay / report.jitterBufferEmittedCount,
|
|
924
|
-
frameWidth: report.frameWidth,
|
|
925
|
-
frameHeight: report.frameHeight,
|
|
926
|
-
framesPerSecond: report.framesPerSecond,
|
|
927
|
-
freezeCount: report.freezeCount,
|
|
928
|
-
freezeDuration: report.totalFreezesDuration
|
|
929
|
-
};
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
return {};
|
|
933
|
-
}
|
|
934
|
-
function createVideoStatsReport(stats, interval2, previousStats) {
|
|
935
|
-
const differentialReport = stats.map((report, index) => {
|
|
936
|
-
if (index === 0) {
|
|
937
|
-
if (!previousStats) {
|
|
938
|
-
return {
|
|
939
|
-
timestamp: report.timestamp,
|
|
940
|
-
duration: 0,
|
|
941
|
-
bytesReceived: report.bytesReceived,
|
|
942
|
-
bitrate: report.bytesReceived * 8 / (interval2 / 1e3),
|
|
943
|
-
packetsReceived: report.packetsReceived,
|
|
944
|
-
packetsLost: report.packetsLost,
|
|
945
|
-
framesDropped: report.framesDropped,
|
|
946
|
-
framesDecoded: report.framesDecoded,
|
|
947
|
-
jitter: report.jitter,
|
|
948
|
-
jitterBufferDelay: report.jitterBufferDelay,
|
|
949
|
-
jitterBufferEmittedCount: report.jitterBufferEmittedCount,
|
|
950
|
-
avgJitterDelayInInterval: report.jitterBufferDelay / report.jitterBufferEmittedCount,
|
|
951
|
-
framesPerSecond: report.framesPerSecond,
|
|
952
|
-
freezeCount: report.freezeCount,
|
|
953
|
-
freezeDuration: report.freezeDuration
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
return {
|
|
957
|
-
timestamp: report.timestamp,
|
|
958
|
-
duration: 0,
|
|
959
|
-
bytesReceived: report.bytesReceived - previousStats.bytesReceived,
|
|
960
|
-
bitrate: (report.bytesReceived - previousStats.bytesReceived) * 8 / (interval2 / 1e3),
|
|
961
|
-
packetsReceived: report.packetsReceived - previousStats.packetsReceived,
|
|
962
|
-
packetsLost: report.packetsLost - previousStats.packetsLost,
|
|
963
|
-
framesDropped: report.framesDropped - previousStats.framesDropped,
|
|
964
|
-
framesDecoded: report.framesDecoded - previousStats.framesDecoded,
|
|
965
|
-
jitter: report.jitter,
|
|
966
|
-
jitterBufferDelay: report.jitterBufferDelay - previousStats.jitterBufferDelay,
|
|
967
|
-
jitterBufferEmittedCount: report.jitterBufferEmittedCount - previousStats.jitterBufferEmittedCount,
|
|
968
|
-
avgJitterDelayInInterval: (report.jitterBufferDelay - previousStats.jitterBufferDelay) / (report.jitterBufferEmittedCount - previousStats.jitterBufferEmittedCount),
|
|
969
|
-
framesPerSecond: report.framesPerSecond,
|
|
970
|
-
freezeCount: report.freezeCount - previousStats.freezeCount,
|
|
971
|
-
freezeDuration: report.freezeDuration - previousStats.freezeDuration
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
return {
|
|
975
|
-
timestamp: report.timestamp,
|
|
976
|
-
duration: interval2 * index / 1e3,
|
|
977
|
-
bytesReceived: report.bytesReceived - stats[index - 1].bytesReceived,
|
|
978
|
-
bitrate: (report.bytesReceived - stats[index - 1].bytesReceived) * 8 / (interval2 / 1e3),
|
|
979
|
-
packetsReceived: report.packetsReceived - stats[index - 1].packetsReceived,
|
|
980
|
-
packetsLost: report.packetsLost - stats[index - 1].packetsLost,
|
|
981
|
-
framesDropped: report.framesDropped - stats[index - 1].framesDropped,
|
|
982
|
-
framesDecoded: report.framesDecoded - stats[index - 1].framesDecoded,
|
|
983
|
-
jitter: report.jitter,
|
|
984
|
-
jitterBufferDelay: report.jitterBufferDelay - stats[index - 1].jitterBufferDelay,
|
|
985
|
-
jitterBufferEmittedCount: report.jitterBufferEmittedCount - stats[index - 1].jitterBufferEmittedCount,
|
|
986
|
-
avgJitterDelayInInterval: (report.jitterBufferDelay - stats[index - 1].jitterBufferDelay) / (report.jitterBufferEmittedCount - stats[index - 1].jitterBufferEmittedCount),
|
|
987
|
-
framesPerSecond: report.framesPerSecond,
|
|
988
|
-
freezeCount: report.freezeCount - stats[index - 1].freezeCount,
|
|
989
|
-
freezeDuration: report.freezeDuration - stats[index - 1].freezeDuration
|
|
990
|
-
};
|
|
991
|
-
});
|
|
992
|
-
const anomalies = extractAnomalies(differentialReport);
|
|
993
|
-
const lowFpsCount = anomalies.reduce((acc, report) => acc + (report.causes.includes("low fps") ? 1 : 0), 0);
|
|
994
|
-
const avgJittersSamples = differentialReport.map((stat) => stat.avgJitterDelayInInterval);
|
|
995
|
-
return {
|
|
996
|
-
webRTCStats: {
|
|
997
|
-
anomalies,
|
|
998
|
-
aggregateReport: createAggregateReport(stats[0], stats[stats.length - 1], lowFpsCount),
|
|
999
|
-
minJitterDelayInInterval: Math.min(...avgJittersSamples),
|
|
1000
|
-
maxJitterDelayInInterval: Math.max(...avgJittersSamples),
|
|
1001
|
-
avgJitterDelayInInterval: average(avgJittersSamples)
|
|
1002
|
-
},
|
|
1003
|
-
codec: stats[0].codec,
|
|
1004
|
-
resolution: `${stats[0].frameWidth}x${stats[0].frameHeight}`
|
|
1005
|
-
};
|
|
1006
|
-
}
|
|
1007
|
-
const interval = 100;
|
|
1008
|
-
const notReceivingIntervalsThreshold = Math.max(Math.ceil(400 / interval), 1);
|
|
1009
|
-
const LOW_JITTER_TRESHOLD = 0.25;
|
|
1010
|
-
const HIGH_JITTER_TRESHOLD = 0.28;
|
|
1011
|
-
function createVideoStatsAnalyzer() {
|
|
1012
|
-
let lastFramesReceived = 0;
|
|
1013
|
-
let prevDelay;
|
|
1014
|
-
let prevCount;
|
|
1015
|
-
let avgJitterDelayInInterval = 0;
|
|
1016
|
-
return (stats) => {
|
|
1017
|
-
for (const report of stats.values()) {
|
|
1018
|
-
if (report && report.type === "inbound-rtp" && report.kind === "video") {
|
|
1019
|
-
const delay = report.jitterBufferDelay;
|
|
1020
|
-
const count = report.jitterBufferEmittedCount;
|
|
1021
|
-
if (prevCount && count > prevCount) {
|
|
1022
|
-
const deltaDelay = delay - prevDelay;
|
|
1023
|
-
const deltaCount = count - prevCount;
|
|
1024
|
-
avgJitterDelayInInterval = deltaDelay / deltaCount;
|
|
1025
|
-
}
|
|
1026
|
-
prevDelay = delay;
|
|
1027
|
-
prevCount = count;
|
|
1028
|
-
const currFramesReceived = report.framesDecoded;
|
|
1029
|
-
const isReceiving = currFramesReceived - lastFramesReceived > 0;
|
|
1030
|
-
lastFramesReceived = currFramesReceived;
|
|
1031
|
-
return {
|
|
1032
|
-
isReceiving,
|
|
1033
|
-
avgJitterDelayInInterval,
|
|
1034
|
-
freezeCount: report.freezeCount
|
|
1035
|
-
};
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
return {
|
|
1039
|
-
isReceiving: false,
|
|
1040
|
-
avgJitterDelayInInterval
|
|
1041
|
-
};
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
function pollStats(peerConnection, getIsConnected, onConnected, onVideoStateChange, onConnectivityStateChange, warmup = false, shouldWaitForGreeting = false) {
|
|
1045
|
-
const streamsBeforeReady = warmup ? 1 : 0;
|
|
1046
|
-
let allStats = [];
|
|
1047
|
-
let previousStats;
|
|
1048
|
-
let notReceivingNumIntervals = 0;
|
|
1049
|
-
let isStreaming = false;
|
|
1050
|
-
let streamsCount = 0;
|
|
1051
|
-
let prevLowConnState = ConnectivityState.Unknown;
|
|
1052
|
-
let currLowConnState = ConnectivityState.Unknown;
|
|
1053
|
-
let currFreezeCount = 0;
|
|
1054
|
-
let prevFreezeCount = 0;
|
|
1055
|
-
const isReceivingVideoBytes = createVideoStatsAnalyzer();
|
|
1056
|
-
return setInterval(async () => {
|
|
1057
|
-
const stats = await peerConnection.getStats();
|
|
1058
|
-
const {
|
|
1059
|
-
isReceiving,
|
|
1060
|
-
avgJitterDelayInInterval,
|
|
1061
|
-
freezeCount
|
|
1062
|
-
} = isReceivingVideoBytes(stats);
|
|
1063
|
-
const slimStats = formatStats(stats);
|
|
1064
|
-
if (isReceiving) {
|
|
1065
|
-
notReceivingNumIntervals = 0;
|
|
1066
|
-
currFreezeCount = freezeCount - prevFreezeCount;
|
|
1067
|
-
currLowConnState = avgJitterDelayInInterval < LOW_JITTER_TRESHOLD ? ConnectivityState.Strong : avgJitterDelayInInterval > HIGH_JITTER_TRESHOLD && currFreezeCount > 1 ? ConnectivityState.Weak : prevLowConnState;
|
|
1068
|
-
if (currLowConnState !== prevLowConnState) {
|
|
1069
|
-
onConnectivityStateChange == null ? void 0 : onConnectivityStateChange(currLowConnState);
|
|
1070
|
-
prevLowConnState = currLowConnState;
|
|
1071
|
-
prevFreezeCount += currFreezeCount;
|
|
1072
|
-
currFreezeCount = 0;
|
|
1073
|
-
}
|
|
1074
|
-
if (!isStreaming) {
|
|
1075
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Start);
|
|
1076
|
-
if (shouldWaitForGreeting && streamsCount >= streamsBeforeReady && !getIsConnected()) {
|
|
1077
|
-
onConnected();
|
|
1078
|
-
}
|
|
1079
|
-
previousStats = allStats[allStats.length - 1];
|
|
1080
|
-
allStats = [];
|
|
1081
|
-
streamsCount++;
|
|
1082
|
-
isStreaming = true;
|
|
1083
|
-
}
|
|
1084
|
-
allStats.push(slimStats);
|
|
1085
|
-
} else if (isStreaming) {
|
|
1086
|
-
notReceivingNumIntervals++;
|
|
1087
|
-
if (notReceivingNumIntervals >= notReceivingIntervalsThreshold) {
|
|
1088
|
-
const statsReport = createVideoStatsReport(allStats, interval, previousStats);
|
|
1089
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Stop, statsReport);
|
|
1090
|
-
if (!shouldWaitForGreeting && !getIsConnected()) {
|
|
1091
|
-
onConnected();
|
|
1092
|
-
}
|
|
1093
|
-
isStreaming = false;
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
}, interval);
|
|
1097
|
-
}
|
|
1098
|
-
let _debug = false;
|
|
1099
|
-
const log = (message, extra) => _debug && console.log(message, extra);
|
|
1100
|
-
const actualRTCPC = (window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection).bind(window);
|
|
1101
|
-
function mapConnectionState(state) {
|
|
1102
|
-
switch (state) {
|
|
1103
|
-
case "connected":
|
|
1104
|
-
return ConnectionState.Connected;
|
|
1105
|
-
case "checking":
|
|
1106
|
-
return ConnectionState.Connecting;
|
|
1107
|
-
case "failed":
|
|
1108
|
-
return ConnectionState.Fail;
|
|
1109
|
-
case "new":
|
|
1110
|
-
return ConnectionState.New;
|
|
1111
|
-
case "closed":
|
|
1112
|
-
return ConnectionState.Closed;
|
|
1113
|
-
case "disconnected":
|
|
1114
|
-
return ConnectionState.Disconnected;
|
|
1115
|
-
case "completed":
|
|
1116
|
-
return ConnectionState.Completed;
|
|
1117
|
-
default:
|
|
1118
|
-
return ConnectionState.New;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
function handleLegacyStreamState({
|
|
1122
|
-
statsSignal,
|
|
1123
|
-
dataChannelSignal,
|
|
1124
|
-
onVideoStateChange,
|
|
1125
|
-
report
|
|
1126
|
-
}) {
|
|
1127
|
-
if (statsSignal === StreamingState.Start && dataChannelSignal === StreamingState.Start) {
|
|
1128
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Start);
|
|
1129
|
-
} else if (statsSignal === StreamingState.Stop && dataChannelSignal === StreamingState.Stop) {
|
|
1130
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Stop, report);
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
function handleFluentStreamState({
|
|
1134
|
-
statsSignal,
|
|
1135
|
-
dataChannelSignal,
|
|
1136
|
-
onVideoStateChange,
|
|
1137
|
-
onAgentActivityStateChange,
|
|
1138
|
-
report
|
|
1139
|
-
}) {
|
|
1140
|
-
if (statsSignal === StreamingState.Start) {
|
|
1141
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Start);
|
|
1142
|
-
} else if (statsSignal === StreamingState.Stop) {
|
|
1143
|
-
onVideoStateChange == null ? void 0 : onVideoStateChange(StreamingState.Stop, report);
|
|
1144
|
-
}
|
|
1145
|
-
if (dataChannelSignal === StreamingState.Start) {
|
|
1146
|
-
onAgentActivityStateChange == null ? void 0 : onAgentActivityStateChange(AgentActivityState.Talking);
|
|
1147
|
-
} else if (dataChannelSignal === StreamingState.Stop) {
|
|
1148
|
-
onAgentActivityStateChange == null ? void 0 : onAgentActivityStateChange(AgentActivityState.Idle);
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
function handleStreamState({
|
|
1152
|
-
statsSignal,
|
|
1153
|
-
dataChannelSignal,
|
|
1154
|
-
onVideoStateChange,
|
|
1155
|
-
onAgentActivityStateChange,
|
|
1156
|
-
streamType,
|
|
1157
|
-
report
|
|
1158
|
-
}) {
|
|
1159
|
-
if (streamType === StreamType.Legacy) {
|
|
1160
|
-
handleLegacyStreamState({
|
|
1161
|
-
statsSignal,
|
|
1162
|
-
dataChannelSignal,
|
|
1163
|
-
onVideoStateChange,
|
|
1164
|
-
report
|
|
1165
|
-
});
|
|
1166
|
-
} else if (streamType === StreamType.Fluent) {
|
|
1167
|
-
handleFluentStreamState({
|
|
1168
|
-
statsSignal,
|
|
1169
|
-
dataChannelSignal,
|
|
1170
|
-
onVideoStateChange,
|
|
1171
|
-
onAgentActivityStateChange,
|
|
1172
|
-
report
|
|
1173
|
-
});
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
async function createStreamingManager(agentId, agent, {
|
|
1177
|
-
debug = false,
|
|
1178
|
-
callbacks,
|
|
1179
|
-
auth,
|
|
1180
|
-
baseURL = didApiUrl
|
|
1181
|
-
}) {
|
|
1182
|
-
_debug = debug;
|
|
1183
|
-
let isConnected = false;
|
|
1184
|
-
let isDatachannelOpen = false;
|
|
1185
|
-
let dataChannelSignal = StreamingState.Stop;
|
|
1186
|
-
let statsSignal = StreamingState.Stop;
|
|
1187
|
-
let connectivityState = ConnectivityState.Unknown;
|
|
1188
|
-
const {
|
|
1189
|
-
startConnection,
|
|
1190
|
-
sendStreamRequest,
|
|
1191
|
-
close,
|
|
1192
|
-
createStream,
|
|
1193
|
-
addIceCandidate
|
|
1194
|
-
} = agent.videoType === VideoType.Clip ? createClipApi(auth, baseURL, agentId, callbacks.onError) : createTalkApi(auth, baseURL, agentId, callbacks.onError);
|
|
1195
|
-
const {
|
|
1196
|
-
id: streamIdFromServer,
|
|
1197
|
-
offer,
|
|
1198
|
-
ice_servers,
|
|
1199
|
-
session_id,
|
|
1200
|
-
fluent
|
|
1201
|
-
} = await createStream(agent);
|
|
1202
|
-
const peerConnection = new actualRTCPC({
|
|
1203
|
-
iceServers: ice_servers
|
|
1204
|
-
});
|
|
1205
|
-
const pcDataChannel = peerConnection.createDataChannel("JanusDataChannel");
|
|
1206
|
-
if (!session_id) {
|
|
1207
|
-
throw new Error("Could not create session_id");
|
|
1208
|
-
}
|
|
1209
|
-
const streamType = fluent ? StreamType.Fluent : StreamType.Legacy;
|
|
1210
|
-
const warmup = agent.stream_warmup && !fluent;
|
|
1211
|
-
const getIsConnected = () => isConnected;
|
|
1212
|
-
const onConnected = () => {
|
|
1213
|
-
var _a;
|
|
1214
|
-
isConnected = true;
|
|
1215
|
-
if (isDatachannelOpen) {
|
|
1216
|
-
(_a = callbacks.onConnectionStateChange) == null ? void 0 : _a.call(callbacks, ConnectionState.Connected);
|
|
1217
|
-
}
|
|
1218
|
-
};
|
|
1219
|
-
const videoStatsInterval = pollStats(peerConnection, getIsConnected, onConnected, (state, report) => handleStreamState({
|
|
1220
|
-
statsSignal: state,
|
|
1221
|
-
dataChannelSignal: streamType === StreamType.Legacy ? dataChannelSignal : void 0,
|
|
1222
|
-
onVideoStateChange: callbacks.onVideoStateChange,
|
|
1223
|
-
onAgentActivityStateChange: callbacks.onAgentActivityStateChange,
|
|
1224
|
-
report,
|
|
1225
|
-
streamType
|
|
1226
|
-
}), (state) => {
|
|
1227
|
-
var _a;
|
|
1228
|
-
return (_a = callbacks.onConnectivityStateChange) == null ? void 0 : _a.call(callbacks, connectivityState);
|
|
1229
|
-
}, warmup, !!agent.stream_greeting);
|
|
1230
|
-
peerConnection.onicecandidate = (event) => {
|
|
1231
|
-
var _a;
|
|
1232
|
-
log("peerConnection.onicecandidate", event);
|
|
1233
|
-
try {
|
|
1234
|
-
if (event.candidate && event.candidate.sdpMid && event.candidate.sdpMLineIndex !== null) {
|
|
1235
|
-
addIceCandidate(streamIdFromServer, {
|
|
1236
|
-
candidate: event.candidate.candidate,
|
|
1237
|
-
sdpMid: event.candidate.sdpMid,
|
|
1238
|
-
sdpMLineIndex: event.candidate.sdpMLineIndex
|
|
1239
|
-
}, session_id);
|
|
1240
|
-
} else {
|
|
1241
|
-
addIceCandidate(streamIdFromServer, {
|
|
1242
|
-
candidate: null
|
|
1243
|
-
}, session_id);
|
|
1244
|
-
}
|
|
1245
|
-
} catch (e) {
|
|
1246
|
-
(_a = callbacks.onError) == null ? void 0 : _a.call(callbacks, e, {
|
|
1247
|
-
streamId: streamIdFromServer
|
|
1248
|
-
});
|
|
1249
|
-
}
|
|
1250
|
-
};
|
|
1251
|
-
pcDataChannel.onopen = () => {
|
|
1252
|
-
isDatachannelOpen = true;
|
|
1253
|
-
if (!warmup && !agent.stream_greeting || isConnected) {
|
|
1254
|
-
onConnected();
|
|
1255
|
-
}
|
|
1256
|
-
};
|
|
1257
|
-
pcDataChannel.onmessage = (event) => {
|
|
1258
|
-
if (event.data in DataChannelSignalMap) {
|
|
1259
|
-
dataChannelSignal = DataChannelSignalMap[event.data];
|
|
1260
|
-
handleStreamState({
|
|
1261
|
-
statsSignal: streamType === StreamType.Legacy ? statsSignal : void 0,
|
|
1262
|
-
dataChannelSignal,
|
|
1263
|
-
onVideoStateChange: callbacks.onVideoStateChange,
|
|
1264
|
-
onAgentActivityStateChange: callbacks.onAgentActivityStateChange,
|
|
1265
|
-
streamType
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
};
|
|
1269
|
-
peerConnection.oniceconnectionstatechange = () => {
|
|
1270
|
-
var _a;
|
|
1271
|
-
log("peerConnection.oniceconnectionstatechange => " + peerConnection.iceConnectionState);
|
|
1272
|
-
const newState = mapConnectionState(peerConnection.iceConnectionState);
|
|
1273
|
-
if (newState !== ConnectionState.Connected) {
|
|
1274
|
-
(_a = callbacks.onConnectionStateChange) == null ? void 0 : _a.call(callbacks, newState);
|
|
1275
|
-
}
|
|
1276
|
-
};
|
|
1277
|
-
peerConnection.ontrack = (event) => {
|
|
1278
|
-
var _a;
|
|
1279
|
-
log("peerConnection.ontrack", event);
|
|
1280
|
-
(_a = callbacks.onSrcObjectReady) == null ? void 0 : _a.call(callbacks, event.streams[0]);
|
|
1281
|
-
};
|
|
1282
|
-
await peerConnection.setRemoteDescription(offer);
|
|
1283
|
-
log("set remote description OK");
|
|
1284
|
-
const sessionClientAnswer = await peerConnection.createAnswer();
|
|
1285
|
-
log("create answer OK");
|
|
1286
|
-
await peerConnection.setLocalDescription(sessionClientAnswer);
|
|
1287
|
-
log("set local description OK");
|
|
1288
|
-
await startConnection(streamIdFromServer, sessionClientAnswer, session_id);
|
|
1289
|
-
log("start connection OK");
|
|
1290
|
-
return {
|
|
1291
|
-
/**
|
|
1292
|
-
* Method to send request to server to get clip or talk depend on you payload
|
|
1293
|
-
* @param payload
|
|
1294
|
-
*/
|
|
1295
|
-
speak(payload) {
|
|
1296
|
-
return sendStreamRequest(streamIdFromServer, session_id, payload);
|
|
1297
|
-
},
|
|
1298
|
-
/**
|
|
1299
|
-
* Method to close RTC connection
|
|
1300
|
-
*/
|
|
1301
|
-
async disconnect() {
|
|
1302
|
-
var _a, _b, _c;
|
|
1303
|
-
if (streamIdFromServer) {
|
|
1304
|
-
const state = mapConnectionState(peerConnection.iceConnectionState);
|
|
1305
|
-
if (peerConnection) {
|
|
1306
|
-
if (state === ConnectionState.New) {
|
|
1307
|
-
(_a = callbacks.onVideoStateChange) == null ? void 0 : _a.call(callbacks, StreamingState.Stop);
|
|
1308
|
-
clearInterval(videoStatsInterval);
|
|
1309
|
-
return;
|
|
1310
|
-
}
|
|
1311
|
-
peerConnection.close();
|
|
1312
|
-
peerConnection.oniceconnectionstatechange = null;
|
|
1313
|
-
peerConnection.onnegotiationneeded = null;
|
|
1314
|
-
peerConnection.onicecandidate = null;
|
|
1315
|
-
peerConnection.ontrack = null;
|
|
1316
|
-
}
|
|
1317
|
-
try {
|
|
1318
|
-
if (state === ConnectionState.Connected) {
|
|
1319
|
-
await close(streamIdFromServer, session_id).catch((_) => {
|
|
1320
|
-
});
|
|
1321
|
-
}
|
|
1322
|
-
} catch (e) {
|
|
1323
|
-
log("Error on close stream connection", e);
|
|
1324
|
-
}
|
|
1325
|
-
(_b = callbacks.onVideoStateChange) == null ? void 0 : _b.call(callbacks, StreamingState.Stop);
|
|
1326
|
-
(_c = callbacks.onAgentActivityStateChange) == null ? void 0 : _c.call(callbacks, AgentActivityState.Idle);
|
|
1327
|
-
clearInterval(videoStatsInterval);
|
|
1328
|
-
}
|
|
1329
|
-
},
|
|
1330
|
-
/**
|
|
1331
|
-
* Session identifier information, should be returned in the body of all streaming requests
|
|
1332
|
-
*/
|
|
1333
|
-
sessionId: session_id,
|
|
1334
|
-
/**
|
|
1335
|
-
* Id of current RTC stream
|
|
1336
|
-
*/
|
|
1337
|
-
streamId: streamIdFromServer,
|
|
1338
|
-
streamType
|
|
1339
|
-
};
|
|
1340
|
-
}
|
|
1341
|
-
function getAgentStreamArgs(agent, options, greeting) {
|
|
1342
|
-
var _a;
|
|
1343
|
-
const {
|
|
1344
|
-
streamOptions
|
|
1345
|
-
} = options ?? {};
|
|
1346
|
-
return {
|
|
1347
|
-
videoType: mapVideoType(agent.presenter.type),
|
|
1348
|
-
output_resolution: streamOptions == null ? void 0 : streamOptions.outputResolution,
|
|
1349
|
-
session_timeout: streamOptions == null ? void 0 : streamOptions.sessionTimeout,
|
|
1350
|
-
stream_warmup: streamOptions == null ? void 0 : streamOptions.streamWarmup,
|
|
1351
|
-
compatibility_mode: streamOptions == null ? void 0 : streamOptions.compatibilityMode,
|
|
1352
|
-
stream_greeting: getAgentType(agent.presenter) !== "clip" && ((_a = options == null ? void 0 : options.streamOptions) == null ? void 0 : _a.streamGreeting) ? greeting : void 0
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
function handleStateChange(state, agent, statsReport, analytics) {
|
|
1356
|
-
if (timestampTracker.get() > 0) {
|
|
1357
|
-
if (state === StreamingState.Start) {
|
|
1358
|
-
analytics.linkTrack("agent-video", {
|
|
1359
|
-
event: "start",
|
|
1360
|
-
latency: timestampTracker.get(true)
|
|
1361
|
-
}, "start", [StreamEvents.StreamVideoCreated]);
|
|
1362
|
-
} else if (state === StreamingState.Stop) {
|
|
1363
|
-
analytics.linkTrack("agent-video", {
|
|
1364
|
-
event: "stop",
|
|
1365
|
-
is_greenscreen: agent.presenter.type === "clip" && agent.presenter.is_greenscreen,
|
|
1366
|
-
background: agent.presenter.type === "clip" && agent.presenter.background,
|
|
1367
|
-
...statsReport
|
|
1368
|
-
}, "done", [StreamEvents.StreamVideoDone]);
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
function connectToManager(agent, options, analytics, greeting) {
|
|
1373
|
-
timestampTracker.reset();
|
|
1374
|
-
return new Promise(async (resolve, reject) => {
|
|
1375
|
-
try {
|
|
1376
|
-
const streamingManager = await createStreamingManager(agent.id, getAgentStreamArgs(agent, options, greeting), {
|
|
1377
|
-
...options,
|
|
1378
|
-
analytics,
|
|
1379
|
-
callbacks: {
|
|
1380
|
-
...options.callbacks,
|
|
1381
|
-
onConnectionStateChange: (state) => {
|
|
1382
|
-
var _a, _b;
|
|
1383
|
-
(_b = (_a = options.callbacks).onConnectionStateChange) == null ? void 0 : _b.call(_a, state);
|
|
1384
|
-
if (state === ConnectionState.Connected) {
|
|
1385
|
-
resolve(streamingManager);
|
|
1386
|
-
}
|
|
1387
|
-
},
|
|
1388
|
-
onVideoStateChange: (state, statsReport) => {
|
|
1389
|
-
var _a, _b;
|
|
1390
|
-
(_b = (_a = options.callbacks).onVideoStateChange) == null ? void 0 : _b.call(_a, state);
|
|
1391
|
-
handleStateChange(state, agent, statsReport, analytics);
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
});
|
|
1395
|
-
} catch (error) {
|
|
1396
|
-
reject(error);
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
}
|
|
1400
|
-
async function initializeStreamAndChat(agent, options, agentsApi, analytics, chat, greeting) {
|
|
1401
|
-
var _a, _b, _c, _d;
|
|
1402
|
-
const {
|
|
1403
|
-
chat: newChat,
|
|
1404
|
-
chatMode
|
|
1405
|
-
} = await createChat(agent, agentsApi, analytics, options.mode, options.persistentChat, chat);
|
|
1406
|
-
if (chatMode && chatMode !== options.mode) {
|
|
1407
|
-
options.mode = chatMode;
|
|
1408
|
-
(_b = (_a = options.callbacks).onModeChange) == null ? void 0 : _b.call(_a, chatMode);
|
|
1409
|
-
if (chatMode === ChatMode.TextOnly) {
|
|
1410
|
-
(_d = (_c = options.callbacks).onError) == null ? void 0 : _d.call(_c, new ChatModeDowngraded(chatMode));
|
|
1411
|
-
return {
|
|
1412
|
-
chat: newChat
|
|
1413
|
-
};
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
const streamingManager = await connectToManager(agent, options, analytics, greeting);
|
|
1417
|
-
return {
|
|
1418
|
-
chat: newChat,
|
|
1419
|
-
streamingManager
|
|
1420
|
-
};
|
|
1421
|
-
}
|
|
1422
|
-
async function createAgentManager(agent, options) {
|
|
1423
|
-
var _a, _b, _c;
|
|
1424
|
-
let firstConnection = true;
|
|
1425
|
-
const mxKey = options.mixpanelKey || mixpanelKey;
|
|
1426
|
-
const wsURL = options.wsURL || didSocketApiUrl;
|
|
1427
|
-
const baseURL = options.baseURL || didApiUrl;
|
|
1428
|
-
const items = {
|
|
1429
|
-
messages: [],
|
|
1430
|
-
chatMode: options.mode || ChatMode.Functional
|
|
1431
|
-
};
|
|
1432
|
-
const agentsApi = createAgentsApi(options.auth, baseURL, options.callbacks.onError);
|
|
1433
|
-
const agentEntity = await agentsApi.getById(agent);
|
|
1434
|
-
const greeting = getGreetings(agentEntity);
|
|
1435
|
-
const analytics = initializeAnalytics({
|
|
1436
|
-
token: mxKey,
|
|
1437
|
-
agent: agentEntity,
|
|
1438
|
-
isEnabled: options.enableAnalitics,
|
|
1439
|
-
distinctId: options.distinctId
|
|
1440
|
-
});
|
|
1441
|
-
const {
|
|
1442
|
-
onMessage,
|
|
1443
|
-
clearQueue
|
|
1444
|
-
} = createMessageEventQueue(analytics, items, options, agentEntity, () => {
|
|
1445
|
-
var _a2;
|
|
1446
|
-
return (_a2 = items.socketManager) == null ? void 0 : _a2.disconnect();
|
|
1447
|
-
});
|
|
1448
|
-
items.messages = getInitialMessages(greeting, options.initialMessages);
|
|
1449
|
-
(_b = (_a = options.callbacks).onNewMessage) == null ? void 0 : _b.call(_a, [...items.messages], "answer");
|
|
1450
|
-
analytics.track("agent-sdk", {
|
|
1451
|
-
event: "loaded",
|
|
1452
|
-
...getAnalyticsInfo(agentEntity)
|
|
1453
|
-
});
|
|
1454
|
-
async function connect2(newChat) {
|
|
1455
|
-
var _a2, _b2, _c2, _d, _e, _f, _g;
|
|
1456
|
-
(_b2 = (_a2 = options.callbacks).onConnectionStateChange) == null ? void 0 : _b2.call(_a2, ConnectionState.Connecting);
|
|
1457
|
-
timestampTracker.reset();
|
|
1458
|
-
if (newChat && !firstConnection) {
|
|
1459
|
-
delete items.chat;
|
|
1460
|
-
items.messages = getInitialMessages(greeting);
|
|
1461
|
-
(_d = (_c2 = options.callbacks).onNewMessage) == null ? void 0 : _d.call(_c2, [...items.messages], "answer");
|
|
1462
|
-
}
|
|
1463
|
-
const websocketPromise = options.mode === ChatMode.DirectPlayback ? Promise.resolve(void 0) : createSocketManager(options.auth, wsURL, {
|
|
1464
|
-
onMessage,
|
|
1465
|
-
onError: options.callbacks.onError
|
|
1466
|
-
});
|
|
1467
|
-
const initPromise = retryOperation(() => {
|
|
1468
|
-
return initializeStreamAndChat(agentEntity, options, agentsApi, analytics, items.chat, newChat ? greeting : void 0);
|
|
1469
|
-
}, {
|
|
1470
|
-
limit: 3,
|
|
1471
|
-
timeout: CONNECTION_RETRY_TIMEOUT_MS,
|
|
1472
|
-
timeoutErrorMessage: "Timeout initializing the stream",
|
|
1473
|
-
// Retry on all errors except for connection errors and rate limit errors, these are already handled in client level.
|
|
1474
|
-
shouldRetryFn: (error) => (error == null ? void 0 : error.message) !== "Could not connect" && error.status !== 429,
|
|
1475
|
-
delayMs: 1e3
|
|
1476
|
-
}).catch((e) => {
|
|
1477
|
-
var _a3, _b3;
|
|
1478
|
-
changeMode(ChatMode.Maintenance);
|
|
1479
|
-
(_b3 = (_a3 = options.callbacks).onConnectionStateChange) == null ? void 0 : _b3.call(_a3, ConnectionState.Fail);
|
|
1480
|
-
throw e;
|
|
1481
|
-
});
|
|
1482
|
-
const [socketManager, {
|
|
1483
|
-
streamingManager,
|
|
1484
|
-
chat
|
|
1485
|
-
}] = await Promise.all([websocketPromise, initPromise]);
|
|
1486
|
-
if (chat && chat.id !== ((_e = items.chat) == null ? void 0 : _e.id)) {
|
|
1487
|
-
(_g = (_f = options.callbacks).onNewChat) == null ? void 0 : _g.call(_f, chat.id);
|
|
1488
|
-
}
|
|
1489
|
-
items.streamingManager = streamingManager;
|
|
1490
|
-
items.socketManager = socketManager;
|
|
1491
|
-
items.chat = chat;
|
|
1492
|
-
firstConnection = false;
|
|
1493
|
-
changeMode((chat == null ? void 0 : chat.chat_mode) ?? options.mode ?? ChatMode.Functional);
|
|
1494
|
-
}
|
|
1495
|
-
async function disconnect() {
|
|
1496
|
-
var _a2, _b2, _c2, _d;
|
|
1497
|
-
(_a2 = items.socketManager) == null ? void 0 : _a2.disconnect();
|
|
1498
|
-
await ((_b2 = items.streamingManager) == null ? void 0 : _b2.disconnect());
|
|
1499
|
-
delete items.streamingManager;
|
|
1500
|
-
delete items.socketManager;
|
|
1501
|
-
(_d = (_c2 = options.callbacks).onConnectionStateChange) == null ? void 0 : _d.call(_c2, ConnectionState.Disconnected);
|
|
1502
|
-
}
|
|
1503
|
-
async function changeMode(mode) {
|
|
1504
|
-
var _a2, _b2;
|
|
1505
|
-
if (mode !== items.chatMode) {
|
|
1506
|
-
analytics.track("agent-mode-change", {
|
|
1507
|
-
mode
|
|
1508
|
-
});
|
|
1509
|
-
items.chatMode = mode;
|
|
1510
|
-
if (items.chatMode !== ChatMode.Functional) {
|
|
1511
|
-
await disconnect();
|
|
1512
|
-
}
|
|
1513
|
-
(_b2 = (_a2 = options.callbacks).onModeChange) == null ? void 0 : _b2.call(_a2, mode);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
return {
|
|
1517
|
-
agent: agentEntity,
|
|
1518
|
-
getStreamType: () => {
|
|
1519
|
-
var _a2;
|
|
1520
|
-
return ((_a2 = items.streamingManager) == null ? void 0 : _a2.streamType) || StreamType.Legacy;
|
|
1521
|
-
},
|
|
1522
|
-
starterMessages: ((_c = agentEntity.knowledge) == null ? void 0 : _c.starter_message) || [],
|
|
1523
|
-
getSTTToken: () => agentsApi.getSTTToken(agentEntity.id),
|
|
1524
|
-
changeMode,
|
|
1525
|
-
enrichAnalytics: analytics.enrich,
|
|
1526
|
-
async connect() {
|
|
1527
|
-
var _a2;
|
|
1528
|
-
await connect2(true);
|
|
1529
|
-
analytics.track("agent-chat", {
|
|
1530
|
-
event: "connect",
|
|
1531
|
-
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1532
|
-
agentId: agentEntity.id,
|
|
1533
|
-
mode: items.chatMode
|
|
1534
|
-
});
|
|
1535
|
-
},
|
|
1536
|
-
async reconnect() {
|
|
1537
|
-
var _a2;
|
|
1538
|
-
await disconnect();
|
|
1539
|
-
await connect2(false);
|
|
1540
|
-
analytics.track("agent-chat", {
|
|
1541
|
-
event: "reconnect",
|
|
1542
|
-
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1543
|
-
agentId: agentEntity.id,
|
|
1544
|
-
mode: items.chatMode
|
|
1545
|
-
});
|
|
1546
|
-
},
|
|
1547
|
-
async disconnect() {
|
|
1548
|
-
var _a2;
|
|
1549
|
-
await disconnect();
|
|
1550
|
-
analytics.track("agent-chat", {
|
|
1551
|
-
event: "disconnect",
|
|
1552
|
-
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1553
|
-
agentId: agentEntity.id,
|
|
1554
|
-
mode: items.chatMode
|
|
1555
|
-
});
|
|
1556
|
-
},
|
|
1557
|
-
async chat(userMessage) {
|
|
1558
|
-
var _a2, _b2, _c2, _d, _e;
|
|
1559
|
-
const validateChatRequest = () => {
|
|
1560
|
-
if (options.mode === ChatMode.DirectPlayback) {
|
|
1561
|
-
throw new ValidationError("Direct playback is enabled, chat is disabled");
|
|
1562
|
-
} else if (userMessage.length >= 800) {
|
|
1563
|
-
throw new ValidationError("Message cannot be more than 800 characters");
|
|
1564
|
-
} else if (userMessage.length === 0) {
|
|
1565
|
-
throw new ValidationError("Message cannot be empty");
|
|
1566
|
-
} else if (items.chatMode === ChatMode.Maintenance) {
|
|
1567
|
-
throw new ValidationError("Chat is in maintenance mode");
|
|
1568
|
-
} else if (![ChatMode.TextOnly, ChatMode.Playground].includes(items.chatMode)) {
|
|
1569
|
-
if (!items.streamingManager) {
|
|
1570
|
-
throw new ValidationError("Streaming manager is not initialized");
|
|
1571
|
-
}
|
|
1572
|
-
if (!items.chat) {
|
|
1573
|
-
throw new ValidationError("Chat is not initialized");
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
};
|
|
1577
|
-
const initializeChat = async () => {
|
|
1578
|
-
var _a3, _b3;
|
|
1579
|
-
if (!items.chat) {
|
|
1580
|
-
const newChat = await createChat(agentEntity, agentsApi, analytics, items.chatMode, options.persistentChat);
|
|
1581
|
-
if (!newChat.chat) {
|
|
1582
|
-
throw new ChatCreationFailed(items.chatMode, !!options.persistentChat);
|
|
1583
|
-
}
|
|
1584
|
-
items.chat = newChat.chat;
|
|
1585
|
-
(_b3 = (_a3 = options.callbacks).onNewChat) == null ? void 0 : _b3.call(_a3, items.chat.id);
|
|
1586
|
-
}
|
|
1587
|
-
return items.chat.id;
|
|
1588
|
-
};
|
|
1589
|
-
const sendChatRequest = async (messages, chatId) => {
|
|
1590
|
-
return retryOperation(() => {
|
|
1591
|
-
var _a3, _b3;
|
|
1592
|
-
return agentsApi.chat(agentEntity.id, chatId, {
|
|
1593
|
-
chatMode: items.chatMode,
|
|
1594
|
-
streamId: (_a3 = items.streamingManager) == null ? void 0 : _a3.streamId,
|
|
1595
|
-
sessionId: (_b3 = items.streamingManager) == null ? void 0 : _b3.sessionId,
|
|
1596
|
-
messages: messages.map(({
|
|
1597
|
-
matches,
|
|
1598
|
-
...message
|
|
1599
|
-
}) => message)
|
|
1600
|
-
}, {
|
|
1601
|
-
...getRequestHeaders(items.chatMode),
|
|
1602
|
-
skipErrorHandler: true
|
|
1603
|
-
});
|
|
1604
|
-
}, {
|
|
1605
|
-
limit: 2,
|
|
1606
|
-
shouldRetryFn: (error) => {
|
|
1607
|
-
var _a3, _b3, _c3, _d2;
|
|
1608
|
-
const isInvalidSessionId = (_a3 = error == null ? void 0 : error.message) == null ? void 0 : _a3.includes("missing or invalid session_id");
|
|
1609
|
-
const isStreamError = (_b3 = error == null ? void 0 : error.message) == null ? void 0 : _b3.includes("Stream Error");
|
|
1610
|
-
if (!isStreamError && !isInvalidSessionId) {
|
|
1611
|
-
(_d2 = (_c3 = options.callbacks).onError) == null ? void 0 : _d2.call(_c3, error);
|
|
1612
|
-
return false;
|
|
1613
|
-
}
|
|
1614
|
-
return true;
|
|
1615
|
-
},
|
|
1616
|
-
onRetry: async () => {
|
|
1617
|
-
await disconnect();
|
|
1618
|
-
await connect2(false);
|
|
1619
|
-
}
|
|
1620
|
-
});
|
|
1621
|
-
};
|
|
1622
|
-
try {
|
|
1623
|
-
clearQueue();
|
|
1624
|
-
validateChatRequest();
|
|
1625
|
-
items.messages.push({
|
|
1626
|
-
id: getRandom(),
|
|
1627
|
-
role: "user",
|
|
1628
|
-
content: userMessage,
|
|
1629
|
-
created_at: new Date(timestampTracker.update()).toISOString()
|
|
1630
|
-
});
|
|
1631
|
-
(_b2 = (_a2 = options.callbacks).onNewMessage) == null ? void 0 : _b2.call(_a2, [...items.messages], "user");
|
|
1632
|
-
const chatId = await initializeChat();
|
|
1633
|
-
const response = await sendChatRequest([...items.messages], chatId);
|
|
1634
|
-
items.messages.push({
|
|
1635
|
-
id: getRandom(),
|
|
1636
|
-
role: "assistant",
|
|
1637
|
-
content: response.result || "",
|
|
1638
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1639
|
-
context: response.context,
|
|
1640
|
-
matches: response.matches
|
|
1641
|
-
});
|
|
1642
|
-
analytics.track("agent-message-send", {
|
|
1643
|
-
event: "success",
|
|
1644
|
-
mode: items.chatMode,
|
|
1645
|
-
messages: items.messages.length + 1
|
|
1646
|
-
});
|
|
1647
|
-
if (response.result) {
|
|
1648
|
-
(_d = (_c2 = options.callbacks).onNewMessage) == null ? void 0 : _d.call(_c2, [...items.messages], "answer");
|
|
1649
|
-
analytics.track("agent-message-received", {
|
|
1650
|
-
latency: timestampTracker.get(true),
|
|
1651
|
-
mode: items.chatMode,
|
|
1652
|
-
messages: items.messages.length
|
|
1653
|
-
});
|
|
1654
|
-
}
|
|
1655
|
-
return response;
|
|
1656
|
-
} catch (e) {
|
|
1657
|
-
if (((_e = items.messages[items.messages.length - 1]) == null ? void 0 : _e.role) === "assistant") {
|
|
1658
|
-
items.messages.pop();
|
|
1659
|
-
}
|
|
1660
|
-
analytics.track("agent-message-send", {
|
|
1661
|
-
event: "error",
|
|
1662
|
-
mode: items.chatMode,
|
|
1663
|
-
messages: items.messages.length
|
|
1664
|
-
});
|
|
1665
|
-
throw e;
|
|
1666
|
-
}
|
|
1667
|
-
},
|
|
1668
|
-
rate(messageId, score, rateId) {
|
|
1669
|
-
var _a2, _b2, _c2, _d;
|
|
1670
|
-
const message = items.messages.find((message2) => message2.id === messageId);
|
|
1671
|
-
if (!items.chat) {
|
|
1672
|
-
throw new Error("Chat is not initialized");
|
|
1673
|
-
} else if (!message) {
|
|
1674
|
-
throw new Error("Message not found");
|
|
1675
|
-
}
|
|
1676
|
-
const matches = ((_a2 = message.matches) == null ? void 0 : _a2.map((match) => [match.document_id, match.id])) ?? [];
|
|
1677
|
-
analytics.track("agent-rate", {
|
|
1678
|
-
event: rateId ? "update" : "create",
|
|
1679
|
-
thumb: score === 1 ? "up" : "down",
|
|
1680
|
-
knowledge_id: ((_b2 = agentEntity.knowledge) == null ? void 0 : _b2.id) ?? "",
|
|
1681
|
-
mode: items.chatMode,
|
|
1682
|
-
matches,
|
|
1683
|
-
score
|
|
1684
|
-
});
|
|
1685
|
-
if (rateId) {
|
|
1686
|
-
return agentsApi.updateRating(agentEntity.id, items.chat.id, rateId, {
|
|
1687
|
-
knowledge_id: ((_c2 = agentEntity.knowledge) == null ? void 0 : _c2.id) ?? "",
|
|
1688
|
-
message_id: messageId,
|
|
1689
|
-
matches,
|
|
1690
|
-
score
|
|
1691
|
-
});
|
|
1692
|
-
}
|
|
1693
|
-
return agentsApi.createRating(agentEntity.id, items.chat.id, {
|
|
1694
|
-
knowledge_id: ((_d = agentEntity.knowledge) == null ? void 0 : _d.id) ?? "",
|
|
1695
|
-
message_id: messageId,
|
|
1696
|
-
matches,
|
|
1697
|
-
score
|
|
1698
|
-
});
|
|
1699
|
-
},
|
|
1700
|
-
deleteRate(id) {
|
|
1701
|
-
var _a2;
|
|
1702
|
-
if (!items.chat) {
|
|
1703
|
-
throw new Error("Chat is not initialized");
|
|
1704
|
-
}
|
|
1705
|
-
analytics.track("agent-rate-delete", {
|
|
1706
|
-
type: "text",
|
|
1707
|
-
chat_id: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1708
|
-
id,
|
|
1709
|
-
mode: items.chatMode
|
|
1710
|
-
});
|
|
1711
|
-
return agentsApi.deleteRating(agentEntity.id, items.chat.id, id);
|
|
1712
|
-
},
|
|
1713
|
-
speak(payload) {
|
|
1714
|
-
var _a2;
|
|
1715
|
-
if (!items.streamingManager) {
|
|
1716
|
-
throw new Error("Please connect to the agent first");
|
|
1717
|
-
}
|
|
1718
|
-
function getScript() {
|
|
1719
|
-
if (typeof payload === "string") {
|
|
1720
|
-
if (!agentEntity.presenter.voice) {
|
|
1721
|
-
throw new Error("Presenter voice is not initialized");
|
|
1722
|
-
}
|
|
1723
|
-
return {
|
|
1724
|
-
type: "text",
|
|
1725
|
-
provider: agentEntity.presenter.voice,
|
|
1726
|
-
input: payload,
|
|
1727
|
-
ssml: false
|
|
1728
|
-
};
|
|
1729
|
-
}
|
|
1730
|
-
if (payload.type === "text" && !payload.provider) {
|
|
1731
|
-
if (!agentEntity.presenter.voice) {
|
|
1732
|
-
throw new Error("Presenter voice is not initialized");
|
|
1733
|
-
}
|
|
1734
|
-
return {
|
|
1735
|
-
type: "text",
|
|
1736
|
-
provider: agentEntity.presenter.voice,
|
|
1737
|
-
input: payload.input,
|
|
1738
|
-
ssml: payload.ssml
|
|
1739
|
-
};
|
|
1740
|
-
}
|
|
1741
|
-
return payload;
|
|
1742
|
-
}
|
|
1743
|
-
const script = getScript();
|
|
1744
|
-
analytics.track("agent-speak", script);
|
|
1745
|
-
timestampTracker.update();
|
|
1746
|
-
return items.streamingManager.speak({
|
|
1747
|
-
script,
|
|
1748
|
-
metadata: {
|
|
1749
|
-
chat_id: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1750
|
-
agent_id: agentEntity.id
|
|
1751
|
-
}
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
};
|
|
1755
|
-
}
|
|
1756
|
-
function getAgent(agentId, auth, baseURL) {
|
|
1757
|
-
const {
|
|
1758
|
-
getById
|
|
1759
|
-
} = createAgentsApi(auth, baseURL || didApiUrl);
|
|
1760
|
-
return getById(agentId);
|
|
1761
|
-
}
|
|
1762
|
-
exports2.AgentActivityState = AgentActivityState;
|
|
1763
|
-
exports2.AgentStatus = AgentStatus;
|
|
1764
|
-
exports2.ChatCreationFailed = ChatCreationFailed;
|
|
1765
|
-
exports2.ChatMode = ChatMode;
|
|
1766
|
-
exports2.ChatModeDowngraded = ChatModeDowngraded;
|
|
1767
|
-
exports2.ChatProgress = ChatProgress;
|
|
1768
|
-
exports2.ConnectionState = ConnectionState;
|
|
1769
|
-
exports2.ConnectivityState = ConnectivityState;
|
|
1770
|
-
exports2.DataChannelSignalMap = DataChannelSignalMap;
|
|
1771
|
-
exports2.DocumentType = DocumentType;
|
|
1772
|
-
exports2.KnowledgeType = KnowledgeType;
|
|
1773
|
-
exports2.PlanGroup = PlanGroup;
|
|
1774
|
-
exports2.Providers = Providers;
|
|
1775
|
-
exports2.RateState = RateState;
|
|
1776
|
-
exports2.StreamEvents = StreamEvents;
|
|
1777
|
-
exports2.StreamType = StreamType;
|
|
1778
|
-
exports2.StreamingState = StreamingState;
|
|
1779
|
-
exports2.Subject = Subject;
|
|
1780
|
-
exports2.UserPlan = UserPlan;
|
|
1781
|
-
exports2.ValidationError = ValidationError;
|
|
1782
|
-
exports2.VideoType = VideoType;
|
|
1783
|
-
exports2.VoiceAccess = VoiceAccess;
|
|
1784
|
-
exports2.WsError = WsError;
|
|
1785
|
-
exports2.createAgentManager = createAgentManager;
|
|
1786
|
-
exports2.getAgent = getAgent;
|
|
1787
|
-
exports2.mapVideoType = mapVideoType;
|
|
1788
|
-
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
1789
|
-
});
|
|
1
|
+
(function(f,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(f=typeof globalThis<"u"?globalThis:f||self,_(f.index={}))})(this,function(f){"use strict";var yt=Object.defineProperty;var pt=(f,_,N)=>_ in f?yt(f,_,{enumerable:!0,configurable:!0,writable:!0,value:N}):f[_]=N;var G=(f,_,N)=>(pt(f,typeof _!="symbol"?_+"":_,N),N);class _ extends Error{constructor({kind:a,description:n,error:o}){super(JSON.stringify({kind:a,description:n}));G(this,"kind");G(this,"description");G(this,"error");this.kind=a,this.description=n,this.error=o}}class N extends _{constructor(t,a){super({kind:"ChatCreationFailed",description:`Failed to create ${a?"persistent":""} chat, mode: ${t}`})}}class ie extends _{constructor(t){super({kind:"ChatModeDowngraded",description:`Chat mode downgraded to ${t}`})}}class H extends _{constructor(a,n){super({kind:"ValidationError",description:a});G(this,"key");this.key=n}}class se extends _{constructor(t){super({kind:"WSError",description:t})}}var oe=(e=>(e.TRIAL="trial",e.BASIC="basic",e.ENTERPRISE="enterprise",e.LITE="lite",e.ADVANCED="advanced",e))(oe||{}),ce=(e=>(e.TRIAL="deid-trial",e.PRO="deid-pro",e.ENTERPRISE="deid-enterprise",e.LITE="deid-lite",e.ADVANCED="deid-advanced",e.BUILD="deid-api-build",e.LAUNCH="deid-api-launch",e.SCALE="deid-api-scale",e))(ce||{}),de=(e=>(e.Created="created",e.Started="started",e.Done="done",e.Error="error",e.Rejected="rejected",e.Ready="ready",e))(de||{}),le=(e=>(e.Unrated="Unrated",e.Positive="Positive",e.Negative="Negative",e))(le||{}),j=(e=>(e.Functional="Functional",e.TextOnly="TextOnly",e.Maintenance="Maintenance",e.Playground="Playground",e.DirectPlayback="DirectPlayback",e))(j||{}),U=(e=>(e.Embed="embed",e.Query="query",e.Partial="partial",e.Answer="answer",e.Complete="done",e))(U||{}),ue=(e=>(e.KnowledgeProcessing="knowledge/processing",e.KnowledgeIndexing="knowledge/indexing",e.KnowledgeFailed="knowledge/error",e.KnowledgeDone="knowledge/done",e))(ue||{}),fe=(e=>(e.Knowledge="knowledge",e.Document="document",e.Record="record",e))(fe||{}),me=(e=>(e.Pdf="pdf",e.Text="text",e.Html="html",e.Word="word",e.Json="json",e.Markdown="markdown",e.Csv="csv",e.Excel="excel",e.Powerpoint="powerpoint",e.Archive="archive",e.Image="image",e.Audio="audio",e.Video="video",e))(me||{}),Z=(e=>(e.Clip="clip",e.Talk="talk",e))(Z||{});const ge=e=>{switch(e){case"clip":return"clip";case"talk":return"talk";default:throw new Error(`Unknown video type: ${e}`)}};var C=(e=>(e.Start="START",e.Stop="STOP",e))(C||{}),K=(e=>(e.Strong="STRONG",e.Weak="WEAK",e.Unknown="UNKNOWN",e))(K||{}),x=(e=>(e.Idle="IDLE",e.Talking="TALKING",e))(x||{});const O={"stream/started":"START","stream/done":"STOP"};var V=(e=>(e.ChatAnswer="chat/answer",e.ChatPartial="chat/partial",e.StreamDone="stream/done",e.StreamStarted="stream/started",e.StreamFailed="stream/error",e.StreamReady="stream/ready",e.StreamCreated="stream/created",e.StreamVideoCreated="stream-video/started",e.StreamVideoDone="stream-video/done",e.StreamVideoError="stream-video/error",e.StreamVideoRejected="stream-video/rejected",e))(V||{}),E=(e=>(e.New="new",e.Fail="fail",e.Connected="connected",e.Connecting="connecting",e.Closed="closed",e.Completed="completed",e.Disconnected="disconnected",e))(E||{}),J=(e=>(e.Legacy="legacy",e.Fluent="fluent",e))(J||{}),he=(e=>(e.Amazon="amazon",e.Microsoft="microsoft",e.Afflorithmics="afflorithmics",e.Elevenlabs="elevenlabs",e))(he||{}),we=(e=>(e.Public="public",e.Premium="premium",e.Private="private",e))(we||{});const Te=45*1e3,je="X-Playground-Chat",X="https://api.d-id.com",Pe="wss://notifications.d-id.com",be="79f81a83a67430be2bc0fd61042b8faa",ye=e=>new Promise(t=>setTimeout(t,e)),Q=()=>Math.random().toString(16).slice(2);function Be(e,t){let a;return{promise:new Promise((o,s)=>{a=setTimeout(()=>s(new Error(t)),e)}),clear:()=>clearTimeout(a)}}async function ee(e,t){const a={limit:(t==null?void 0:t.limit)??3,delayMs:(t==null?void 0:t.delayMs)??0,timeout:(t==null?void 0:t.timeout)??3e4,timeoutErrorMessage:(t==null?void 0:t.timeoutErrorMessage)||"Timeout error",shouldRetryFn:(t==null?void 0:t.shouldRetryFn)??(()=>!0),onRetry:(t==null?void 0:t.onRetry)??(()=>{})};let n;for(let o=1;o<=a.limit;o++)try{if(!a.timeout)return await e();const{promise:s,clear:r}=Be(a.timeout,a.timeoutErrorMessage),i=e().finally(r);return await Promise.race([i,s])}catch(s){if(n=s,!a.shouldRetryFn(s)||o>=a.limit)throw s;await ye(a.delayMs),a.onRetry(s)}throw n}function pe(){let e=window.localStorage.getItem("did_external_key_id");return e||(e=Math.random().toString(16).slice(2),window.localStorage.setItem("did_external_key_id",e)),e}let $e=Q();function ve(e){if(e.type==="bearer")return`Bearer ${e.token}`;if(e.type==="basic")return`Basic ${btoa(`${e.username}:${e.password}`)}`;if(e.type==="key")return`Client-Key ${e.clientKey}.${pe()}_${$e}`;throw new Error(`Unknown auth type: ${e}`)}const Le=e=>ee(e,{limit:3,delayMs:1e3,timeout:0,shouldRetryFn:t=>t.status===429});function te(e,t=X,a){const n=async(o,s)=>{const{skipErrorHandler:r,...i}=s||{},c=await Le(()=>fetch(t+(o!=null&&o.startsWith("/")?o:`/${o}`),{...i,headers:{...i.headers,Authorization:ve(e),"Content-Type":"application/json"}}));if(!c.ok){let g=await c.text().catch(()=>`Failed to fetch with status ${c.status}`);const l=new Error(g);throw a&&!r&&a(l,{url:o,options:i,headers:c.headers}),l}return c.json()};return{get(o,s){return n(o,{...s,method:"GET"})},post(o,s,r){return n(o,{...r,body:JSON.stringify(s),method:"POST"})},delete(o,s,r){return n(o,{...r,body:JSON.stringify(s),method:"DELETE"})},patch(o,s,r){return n(o,{...r,body:JSON.stringify(s),method:"PATCH"})}}}function Ce(e,t=X,a){const n=te(e,`${t}/agents`,a);return{create(o,s){return n.post("/",o,s)},getAgents(o,s){return n.get(`/${o?`?tag=${o}`:""}`,s).then(r=>r??[])},getById(o,s){return n.get(`/${o}`,s)},delete(o,s){return n.delete(`/${o}`,void 0,s)},update(o,s,r){return n.patch(`/${o}`,s,r)},newChat(o,s,r){return n.post(`/${o}/chat`,s,r)},chat(o,s,r,i){return n.post(`/${o}/chat/${s}`,r,i)},createRating(o,s,r,i){return n.post(`/${o}/chat/${s}/ratings`,r,i)},updateRating(o,s,r,i,c){return n.patch(`/${o}/chat/${s}/ratings/${r}`,i,c)},deleteRating(o,s,r,i){return n.delete(`/${o}/chat/${s}/ratings/${r}`,i)},getSTTToken(o,s){return n.get(`/${o}/stt-token`,s)}}}const re=e=>e.type==="clip"&&e.presenter_id.startsWith("v2_")?"clip_v2":e.type;function Ae(e){var o,s,r,i;const t=()=>/Mobi|Android/i.test(navigator.userAgent)?"Mobile":"Desktop",a=()=>{const c=navigator.platform;return c.toLowerCase().includes("win")?"Windows":c.toLowerCase().includes("mac")?"Mac OS X":c.toLowerCase().includes("linux")?"Linux":"Unknown"},n=e.presenter;return{$os:`${a()}`,isMobile:`${t()=="Mobile"}`,browser:navigator.userAgent,origin:window.location.origin,agentType:re(n),agentVoice:{voiceId:(s=(o=e.presenter)==null?void 0:o.voice)==null?void 0:s.voice_id,provider:(i=(r=e.presenter)==null?void 0:r.voice)==null?void 0:i.type}}}const ze=e=>e.reduce((t,a)=>t+a,0),Fe=e=>ze(e)/e.length;function Ne(e,t,a){var c,g,l;const{event:n,...o}=e,{template:s}=(t==null?void 0:t.llm)||{},{language:r}=((c=t==null?void 0:t.presenter)==null?void 0:c.voice)||{};return{...o,llm:{...o.llm,template:s},script:{...o.script,provider:{...(g=o==null?void 0:o.script)==null?void 0:g.provider,language:r}},stitch:(t==null?void 0:t.presenter.type)==="talk"?(l=t==null?void 0:t.presenter)==null?void 0:l.stitch:void 0,...a}}let ne={};const Je="https://api-js.mixpanel.com/track/?verbose=1&ip=1";function We(e){var s,r,i,c,g,l;const t=window!=null&&window.hasOwnProperty("DID_AGENTS_API")?"agents-ui":"agents-sdk",a=e.agent.presenter,n=(s=e.agent.llm)==null?void 0:s.prompt_customization,o={token:e.token||"testKey",distinct_id:e.distinctId||pe(),agentId:e.agent.id,agentType:re(a),owner_id:e.agent.owner_id??"",promptVersion:(r=e.agent.llm)==null?void 0:r.prompt_version,behavior:{role:n==null?void 0:n.role,personality:n==null?void 0:n.personality,instructions:(i=e.agent.llm)==null?void 0:i.instructions},temperature:(c=e.agent.llm)==null?void 0:c.temperature,knowledgeSource:n==null?void 0:n.knowledge_source,starterQuestionsCount:(l=(g=e.agent.knowledge)==null?void 0:g.starter_message)==null?void 0:l.length,topicsToAvoid:n==null?void 0:n.topics_to_avoid,maxResponseLength:n==null?void 0:n.max_response_length};return{...o,additionalProperties:{},isEnabled:e.isEnabled??!0,getRandom:()=>Math.random().toString(16).slice(2),enrich(h){const k={};if(h&&typeof h!="object")throw new Error("properties must be a flat json object");for(let p in h)(typeof h[p]=="string"||typeof h[p]=="number")&&(k[p]=h[p]);this.additionalProperties={...this.additionalProperties,...k}},async track(h,k){if(!this.isEnabled)return Promise.resolve();const{audioPath:p,...v}=k||{},D={method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({data:JSON.stringify([{event:h,properties:{...this.additionalProperties,...v,...o,source:t,time:Date.now(),$insert_id:this.getRandom(),origin:window.location.href,"Screen Height":window.screen.height||window.innerWidth,"Screen Width":window.screen.width||window.innerHeight,"User Agent":navigator.userAgent}}])})};try{return await fetch(Je,D).then(R=>R.json())}catch(R){return console.error(R)}},linkTrack(h,k,p,v){ne[h]||(ne[h]={events:{},resolvedDependencies:[]}),v.includes(p)||v.push(p);const D=ne[h];if(D.events[p]={props:k},D.resolvedDependencies.push(p),v.every(A=>D.resolvedDependencies.includes(A))){const A=v.reduce((P,d)=>D.events[d]?{...P,...D.events[d].props}:P,{});this.track(h,A),D.resolvedDependencies=D.resolvedDependencies.filter(P=>!v.includes(P)),v.forEach(P=>{delete D.events[P]})}}}}function He(){let e=0;return{reset:()=>e=0,update:()=>e=Date.now(),get:(t=!1)=>t?Date.now()-e:e}}const q=He();function De(e){return e===j.Playground?{headers:{[je]:"true"}}:{}}async function ke(e,t,a,n,o=!1,s){try{return!s&&n!==j.DirectPlayback&&(s=await t.newChat(e.id,{persist:o},De(n)),a.track("agent-chat",{event:"created",chat_id:s.id,agent_id:e.id,mode:n})),{chat:s,chatMode:(s==null?void 0:s.chat_mode)??n}}catch(r){try{const i=JSON.parse(r.message);if((i==null?void 0:i.kind)==="InsufficientCreditsError")throw new Error("InsufficientCreditsError")}catch(i){console.error("Error parsing the error message:",i)}throw new Error("Cannot create new chat")}}function Ue(e){var a;const t=((a=e.greetings)==null?void 0:a.filter(n=>n.length>0))??[];return t.length>0?t[Math.floor(Math.random()*t.length)]:`Hi! I'm ${e.preview_name||"My Agent"}. How can I help you?`}function Re(e,t){return t&&t.length>0?t:[{content:e,id:Q(),role:"assistant",created_at:new Date().toISOString()}]}function Ke(e){return new Promise((t,a)=>{const{callbacks:n,host:o,auth:s}=e,{onMessage:r=null,onOpen:i=null,onClose:c=null,onError:g=null}=n||{},l=new WebSocket(`${o}?authorization=${ve(s)}`);l.onmessage=r,l.onclose=c,l.onerror=h=>{console.error(h),g==null||g("Websocket failed to connect",h),a(h)},l.onopen=h=>{i==null||i(h),t(l)}})}async function qe(e){const{retries:t=1}=e;let a=null;for(let n=0;(a==null?void 0:a.readyState)!==WebSocket.OPEN;n++)try{a=await Ke(e)}catch(o){if(n===t)throw o;await ye(n*500)}return a}async function xe(e,t,a){const n=a!=null&&a.onMessage?[a.onMessage]:[],o=await qe({auth:e,host:t,callbacks:{onError:s=>{var r;return(r=a.onError)==null?void 0:r.call(a,new se(s))},onMessage(s){const r=JSON.parse(s.data);n.forEach(i=>i(r.event,r))}}});return{socket:o,disconnect:()=>o.close(),subscribeToEvents:s=>n.push(s)}}function Ve(e){if(e.answer!==void 0)return e.answer;let t=0,a="";for(;t in e;)a+=e[t++];return a}function Xe(e,t,a,n,o){const s=n.messages[n.messages.length-1];if(!(e===U.Partial||e===U.Answer)||(s==null?void 0:s.role)!=="assistant")return;const{content:r,sequence:i}=t;e===U.Partial?a[i]=r:a.answer=r;const c=Ve(a);(s.content!==c||e===U.Answer)&&(s.content=c,o==null||o([...n.messages],e))}function Ye(e,t,a,n,o){let s={};return{clearQueue:()=>s={},onMessage:(r,i)=>{var c,g;if("content"in i)Xe(r,i,s,t,a.callbacks.onNewMessage),r===U.Answer&&e.track("agent-message-received",{messages:t.messages.length,mode:t.chatMode});else{const l=V,h=[l.StreamVideoDone,l.StreamVideoError,l.StreamVideoRejected],k=[l.StreamFailed,l.StreamVideoError,l.StreamVideoRejected],p=Ne(i,n,{mode:t.chatMode});if(r=r,r===l.StreamVideoCreated)e.linkTrack("agent-video",p,l.StreamVideoCreated,["start"]);else if(h.includes(r)){const v=r.split("/")[1];k.includes(r)?e.track("agent-video",{...p,event:v}):e.linkTrack("agent-video",{...p,event:v},r,["done"])}k.includes(r)&&((g=(c=a.callbacks).onError)==null||g.call(c,new Error(`Stream failed with event ${r}`),{data:i})),i.event===l.StreamDone&&o()}}}}function Ge(e,t,a,n){const o=te(e,`${t}/agents/${a}`,n);return{createStream(s){return o.post("/streams",{output_resolution:s.output_resolution,compatibility_mode:s.compatibility_mode,stream_warmup:s.stream_warmup,session_timeout:s.session_timeout,stream_greeting:s.stream_greeting})},startConnection(s,r,i){return o.post(`/streams/${s}/sdp`,{session_id:i,answer:r})},addIceCandidate(s,r,i){return o.post(`/streams/${s}/ice`,{session_id:i,...r})},sendStreamRequest(s,r,i){return o.post(`/streams/${s}`,{session_id:r,...i})},close(s,r){return o.delete(`/streams/${s}`,{session_id:r})}}}function Qe(e,t,a,n){const o=te(e,`${t}/agents/${a}`,n);return{createStream(s,r){return o.post("/streams",{driver_url:s.driver_url,face:s.face,config:s.config,output_resolution:s.output_resolution,compatibility_mode:s.compatibility_mode,stream_warmup:s.stream_warmup,session_timeout:s.session_timeout,stream_greeting:s.stream_greeting},r)},startConnection(s,r,i,c){return o.post(`/streams/${s}/sdp`,{session_id:i,answer:r},c)},addIceCandidate(s,r,i,c){return o.post(`/streams/${s}/ice`,{session_id:i,...r},c)},sendStreamRequest(s,r,i,c){return o.post(`/streams/${s}`,{session_id:r,...i},c)},close(s,r,i){return o.delete(`/streams/${s}`,{session_id:r},i)}}}function Ze(e,t,a){const n=(t.timestamp-e.timestamp)/1e3;return{duration:n,bytesReceived:t.bytesReceived-e.bytesReceived,bitrate:Math.round((t.bytesReceived-e.bytesReceived)*8/n),packetsReceived:t.packetsReceived-e.packetsReceived,packetsLost:t.packetsLost-e.packetsLost,framesDropped:t.framesDropped-e.framesDropped,framesDecoded:t.framesDecoded-e.framesDecoded,jitter:t.jitter,avgJitterDelayInInterval:(t.jitterBufferDelay-e.jitterBufferDelay)/(t.jitterBufferEmittedCount-e.jitterBufferEmittedCount),jitterBufferEmittedCount:t.jitterBufferEmittedCount-e.jitterBufferEmittedCount,jitterBufferDelay:(t.jitterBufferDelay-e.jitterBufferDelay)/n,framesPerSecond:t.framesPerSecond,freezeCount:t.freezeCount-e.freezeCount,freezeDuration:t.freezeDuration-e.freezeDuration,lowFpsCount:a}}function Oe(e){return e.filter(t=>t.freezeCount>0||t.framesPerSecond<21||t.framesDropped>0||t.packetsLost>0).map(t=>{const{timestamp:a,...n}=t,o=[];return t.freezeCount>0&&o.push("freeze"),t.framesPerSecond<21&&o.push("low fps"),t.framesDropped>0&&o.push("frames dropped"),t.packetsLost>0&&o.push("packet loss"),{...n,causes:o}})}function et(e){let t="";for(const a of e.values())if(a&&a.type==="codec"&&a.mimeType.startsWith("video")&&(t=a.mimeType.split("/")[1]),a&&a.type==="inbound-rtp"&&a.kind==="video")return{codec:t,timestamp:a.timestamp,bytesReceived:a.bytesReceived,packetsReceived:a.packetsReceived,packetsLost:a.packetsLost,framesDropped:a.framesDropped,framesDecoded:a.framesDecoded,jitter:a.jitter,jitterBufferDelay:a.jitterBufferDelay,jitterBufferEmittedCount:a.jitterBufferEmittedCount,avgJitterDelayInInterval:a.jitterBufferDelay/a.jitterBufferEmittedCount,frameWidth:a.frameWidth,frameHeight:a.frameHeight,framesPerSecond:a.framesPerSecond,freezeCount:a.freezeCount,freezeDuration:a.totalFreezesDuration};return{}}function tt(e,t,a){const n=e.map((i,c)=>c===0?a?{timestamp:i.timestamp,duration:0,bytesReceived:i.bytesReceived-a.bytesReceived,bitrate:(i.bytesReceived-a.bytesReceived)*8/(t/1e3),packetsReceived:i.packetsReceived-a.packetsReceived,packetsLost:i.packetsLost-a.packetsLost,framesDropped:i.framesDropped-a.framesDropped,framesDecoded:i.framesDecoded-a.framesDecoded,jitter:i.jitter,jitterBufferDelay:i.jitterBufferDelay-a.jitterBufferDelay,jitterBufferEmittedCount:i.jitterBufferEmittedCount-a.jitterBufferEmittedCount,avgJitterDelayInInterval:(i.jitterBufferDelay-a.jitterBufferDelay)/(i.jitterBufferEmittedCount-a.jitterBufferEmittedCount),framesPerSecond:i.framesPerSecond,freezeCount:i.freezeCount-a.freezeCount,freezeDuration:i.freezeDuration-a.freezeDuration}:{timestamp:i.timestamp,duration:0,bytesReceived:i.bytesReceived,bitrate:i.bytesReceived*8/(t/1e3),packetsReceived:i.packetsReceived,packetsLost:i.packetsLost,framesDropped:i.framesDropped,framesDecoded:i.framesDecoded,jitter:i.jitter,jitterBufferDelay:i.jitterBufferDelay,jitterBufferEmittedCount:i.jitterBufferEmittedCount,avgJitterDelayInInterval:i.jitterBufferDelay/i.jitterBufferEmittedCount,framesPerSecond:i.framesPerSecond,freezeCount:i.freezeCount,freezeDuration:i.freezeDuration}:{timestamp:i.timestamp,duration:t*c/1e3,bytesReceived:i.bytesReceived-e[c-1].bytesReceived,bitrate:(i.bytesReceived-e[c-1].bytesReceived)*8/(t/1e3),packetsReceived:i.packetsReceived-e[c-1].packetsReceived,packetsLost:i.packetsLost-e[c-1].packetsLost,framesDropped:i.framesDropped-e[c-1].framesDropped,framesDecoded:i.framesDecoded-e[c-1].framesDecoded,jitter:i.jitter,jitterBufferDelay:i.jitterBufferDelay-e[c-1].jitterBufferDelay,jitterBufferEmittedCount:i.jitterBufferEmittedCount-e[c-1].jitterBufferEmittedCount,avgJitterDelayInInterval:(i.jitterBufferDelay-e[c-1].jitterBufferDelay)/(i.jitterBufferEmittedCount-e[c-1].jitterBufferEmittedCount),framesPerSecond:i.framesPerSecond,freezeCount:i.freezeCount-e[c-1].freezeCount,freezeDuration:i.freezeDuration-e[c-1].freezeDuration}),o=Oe(n),s=o.reduce((i,c)=>i+(c.causes.includes("low fps")?1:0),0),r=n.map(i=>i.avgJitterDelayInInterval);return{webRTCStats:{anomalies:o,aggregateReport:Ze(e[0],e[e.length-1],s),minJitterDelayInInterval:Math.min(...r),maxJitterDelayInInterval:Math.max(...r),avgJitterDelayInInterval:Fe(r)},codec:e[0].codec,resolution:`${e[0].frameWidth}x${e[0].frameHeight}`}}const ae=100,rt=Math.max(Math.ceil(400/ae),1),nt=.25,at=.28;function it(){let e=0,t,a,n=0;return o=>{for(const s of o.values())if(s&&s.type==="inbound-rtp"&&s.kind==="video"){const r=s.jitterBufferDelay,i=s.jitterBufferEmittedCount;if(a&&i>a){const l=r-t,h=i-a;n=l/h}t=r,a=i;const c=s.framesDecoded,g=c-e>0;return e=c,{isReceiving:g,avgJitterDelayInInterval:n,freezeCount:s.freezeCount}}return{isReceiving:!1,avgJitterDelayInInterval:n}}}function st(e,t,a,n,o,s=!1,r=!1){const i=s?1:0;let c=[],g,l=0,h=!1,k=0,p=K.Unknown,v=K.Unknown,D=0,R=0;const A=it();return setInterval(async()=>{const P=await e.getStats(),{isReceiving:d,avgJitterDelayInInterval:y,freezeCount:m}=A(P),M=et(P);if(d)l=0,D=m-R,v=y<nt?K.Strong:y>at&&D>1?K.Weak:p,v!==p&&(o==null||o(v),p=v,R+=D,D=0),h||(n==null||n(C.Start),r&&k>=i&&!t()&&a(),g=c[c.length-1],c=[],k++,h=!0),c.push(M);else if(h&&(l++,l>=rt)){const I=tt(c,ae,g);n==null||n(C.Stop,I),!r&&!t()&&a(),h=!1}},ae)}let Se=!1;const W=(e,t)=>Se&&console.log(e,t),ot=(window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection).bind(window);function Ee(e){switch(e){case"connected":return E.Connected;case"checking":return E.Connecting;case"failed":return E.Fail;case"new":return E.New;case"closed":return E.Closed;case"disconnected":return E.Disconnected;case"completed":return E.Completed;default:return E.New}}function ct({statsSignal:e,dataChannelSignal:t,onVideoStateChange:a,report:n}){e===C.Start&&t===C.Start?a==null||a(C.Start):e===C.Stop&&t===C.Stop&&(a==null||a(C.Stop,n))}function dt({statsSignal:e,dataChannelSignal:t,onVideoStateChange:a,onAgentActivityStateChange:n,report:o}){e===C.Start?a==null||a(C.Start):e===C.Stop&&(a==null||a(C.Stop,o)),t===C.Start?n==null||n(x.Talking):t===C.Stop&&(n==null||n(x.Idle))}function Me({statsSignal:e,dataChannelSignal:t,onVideoStateChange:a,onAgentActivityStateChange:n,streamType:o,report:s}){o===J.Legacy?ct({statsSignal:e,dataChannelSignal:t,onVideoStateChange:a,report:s}):o===J.Fluent&&dt({statsSignal:e,dataChannelSignal:t,onVideoStateChange:a,onAgentActivityStateChange:n,report:s})}async function lt(e,t,{debug:a=!1,callbacks:n,auth:o,baseURL:s=X}){Se=a;let r=!1,i=!1,c=C.Stop,g=C.Stop,l=K.Unknown;const{startConnection:h,sendStreamRequest:k,close:p,createStream:v,addIceCandidate:D}=t.videoType===Z.Clip?Ge(o,s,e,n.onError):Qe(o,s,e,n.onError),{id:R,offer:A,ice_servers:P,session_id:d,fluent:y}=await v(t),m=new ot({iceServers:P}),M=m.createDataChannel("JanusDataChannel");if(!d)throw new Error("Could not create session_id");const I=y?J.Fluent:J.Legacy,T=t.stream_warmup&&!y,z=()=>r,B=()=>{var u;r=!0,i&&((u=n.onConnectionStateChange)==null||u.call(n,E.Connected))},$=st(m,z,B,(u,w)=>Me({statsSignal:g=u,dataChannelSignal:I===J.Legacy?c:void 0,onVideoStateChange:n.onVideoStateChange,onAgentActivityStateChange:n.onAgentActivityStateChange,report:w,streamType:I}),u=>{var w;return(w=n.onConnectivityStateChange)==null?void 0:w.call(n,l)},T,!!t.stream_greeting);m.onicecandidate=u=>{var w;W("peerConnection.onicecandidate",u);try{u.candidate&&u.candidate.sdpMid&&u.candidate.sdpMLineIndex!==null?D(R,{candidate:u.candidate.candidate,sdpMid:u.candidate.sdpMid,sdpMLineIndex:u.candidate.sdpMLineIndex},d):D(R,{candidate:null},d)}catch(b){(w=n.onError)==null||w.call(n,b,{streamId:R})}},M.onopen=()=>{i=!0,(!T&&!t.stream_greeting||r)&&B()},M.onmessage=u=>{u.data in O&&(c=O[u.data],Me({statsSignal:I===J.Legacy?g:void 0,dataChannelSignal:c,onVideoStateChange:n.onVideoStateChange,onAgentActivityStateChange:n.onAgentActivityStateChange,streamType:I}))},m.oniceconnectionstatechange=()=>{var w;W("peerConnection.oniceconnectionstatechange => "+m.iceConnectionState);const u=Ee(m.iceConnectionState);u!==E.Connected&&((w=n.onConnectionStateChange)==null||w.call(n,u))},m.ontrack=u=>{var w;W("peerConnection.ontrack",u),(w=n.onSrcObjectReady)==null||w.call(n,u.streams[0])},await m.setRemoteDescription(A),W("set remote description OK");const S=await m.createAnswer();return W("create answer OK"),await m.setLocalDescription(S),W("set local description OK"),await h(R,S,d),W("start connection OK"),{speak(u){return k(R,d,u)},async disconnect(){var u,w,b;if(R){const L=Ee(m.iceConnectionState);if(m){if(L===E.New){(u=n.onVideoStateChange)==null||u.call(n,C.Stop),clearInterval($);return}m.close(),m.oniceconnectionstatechange=null,m.onnegotiationneeded=null,m.onicecandidate=null,m.ontrack=null}try{L===E.Connected&&await p(R,d).catch(F=>{})}catch(F){W("Error on close stream connection",F)}(w=n.onVideoStateChange)==null||w.call(n,C.Stop),(b=n.onAgentActivityStateChange)==null||b.call(n,x.Idle),clearInterval($)}},sessionId:d,streamId:R,streamType:I}}function ut(e,t,a){var o;const{streamOptions:n}=t??{};return{videoType:ge(e.presenter.type),output_resolution:n==null?void 0:n.outputResolution,session_timeout:n==null?void 0:n.sessionTimeout,stream_warmup:n==null?void 0:n.streamWarmup,compatibility_mode:n==null?void 0:n.compatibilityMode,stream_greeting:re(e.presenter)!=="clip"&&((o=t==null?void 0:t.streamOptions)!=null&&o.streamGreeting)?a:void 0}}function ft(e,t,a,n){q.get()>0&&(e===C.Start?n.linkTrack("agent-video",{event:"start",latency:q.get(!0)},"start",[V.StreamVideoCreated]):e===C.Stop&&n.linkTrack("agent-video",{event:"stop",is_greenscreen:t.presenter.type==="clip"&&t.presenter.is_greenscreen,background:t.presenter.type==="clip"&&t.presenter.background,...a},"done",[V.StreamVideoDone]))}function mt(e,t,a,n){return q.reset(),new Promise(async(o,s)=>{try{const r=await lt(e.id,ut(e,t,n),{...t,analytics:a,callbacks:{...t.callbacks,onConnectionStateChange:i=>{var c,g;(g=(c=t.callbacks).onConnectionStateChange)==null||g.call(c,i),i===E.Connected&&o(r)},onVideoStateChange:(i,c)=>{var g,l;(l=(g=t.callbacks).onVideoStateChange)==null||l.call(g,i),ft(i,e,c,a)}}})}catch(r){s(r)}})}async function gt(e,t,a,n,o,s){var g,l,h,k;const{chat:r,chatMode:i}=await ke(e,a,n,t.mode,t.persistentChat,o);if(i&&i!==t.mode&&(t.mode=i,(l=(g=t.callbacks).onModeChange)==null||l.call(g,i),i===j.TextOnly))return(k=(h=t.callbacks).onError)==null||k.call(h,new ie(i)),{chat:r};const c=await mt(e,t,n,s);return{chat:r,streamingManager:c}}async function ht(e,t){var R,A,P;let a=!0;const n=t.mixpanelKey||be,o=t.wsURL||Pe,s=t.baseURL||X,r={messages:[],chatMode:t.mode||j.Functional},i=Ce(t.auth,s,t.callbacks.onError),c=await i.getById(e),g=Ue(c),l=We({token:n,agent:c,isEnabled:t.enableAnalitics,distinctId:t.distinctId}),{onMessage:h,clearQueue:k}=Ye(l,r,t,c,()=>{var d;return(d=r.socketManager)==null?void 0:d.disconnect()});r.messages=Re(g,t.initialMessages),(A=(R=t.callbacks).onNewMessage)==null||A.call(R,[...r.messages],"answer"),l.track("agent-sdk",{event:"loaded",...Ae(c)});async function p(d){var z,B,$,S,u,w,b;(B=(z=t.callbacks).onConnectionStateChange)==null||B.call(z,E.Connecting),q.reset(),d&&!a&&(delete r.chat,r.messages=Re(g),(S=($=t.callbacks).onNewMessage)==null||S.call($,[...r.messages],"answer"));const y=t.mode===j.DirectPlayback?Promise.resolve(void 0):xe(t.auth,o,{onMessage:h,onError:t.callbacks.onError}),m=ee(()=>gt(c,t,i,l,r.chat,d?g:void 0),{limit:3,timeout:Te,timeoutErrorMessage:"Timeout initializing the stream",shouldRetryFn:L=>(L==null?void 0:L.message)!=="Could not connect"&&L.status!==429,delayMs:1e3}).catch(L=>{var F,Y;throw D(j.Maintenance),(Y=(F=t.callbacks).onConnectionStateChange)==null||Y.call(F,E.Fail),L}),[M,{streamingManager:I,chat:T}]=await Promise.all([y,m]);T&&T.id!==((u=r.chat)==null?void 0:u.id)&&((b=(w=t.callbacks).onNewChat)==null||b.call(w,T.id)),r.streamingManager=I,r.socketManager=M,r.chat=T,a=!1,D((T==null?void 0:T.chat_mode)??t.mode??j.Functional)}async function v(){var d,y,m,M;(d=r.socketManager)==null||d.disconnect(),await((y=r.streamingManager)==null?void 0:y.disconnect()),delete r.streamingManager,delete r.socketManager,(M=(m=t.callbacks).onConnectionStateChange)==null||M.call(m,E.Disconnected)}async function D(d){var y,m;d!==r.chatMode&&(l.track("agent-mode-change",{mode:d}),r.chatMode=d,r.chatMode!==j.Functional&&await v(),(m=(y=t.callbacks).onModeChange)==null||m.call(y,d))}return{agent:c,getStreamType:()=>{var d;return(d=r.streamingManager)==null?void 0:d.streamType},starterMessages:((P=c.knowledge)==null?void 0:P.starter_message)||[],getSTTToken:()=>i.getSTTToken(c.id),changeMode:D,enrichAnalytics:l.enrich,async connect(){var d;await p(!0),l.track("agent-chat",{event:"connect",chatId:(d=r.chat)==null?void 0:d.id,agentId:c.id,mode:r.chatMode})},async reconnect(){var d;await v(),await p(!1),l.track("agent-chat",{event:"reconnect",chatId:(d=r.chat)==null?void 0:d.id,agentId:c.id,mode:r.chatMode})},async disconnect(){var d;await v(),l.track("agent-chat",{event:"disconnect",chatId:(d=r.chat)==null?void 0:d.id,agentId:c.id,mode:r.chatMode})},async chat(d){var I,T,z,B,$;const y=()=>{if(t.mode===j.DirectPlayback)throw new H("Direct playback is enabled, chat is disabled");if(d.length>=800)throw new H("Message cannot be more than 800 characters");if(d.length===0)throw new H("Message cannot be empty");if(r.chatMode===j.Maintenance)throw new H("Chat is in maintenance mode");if(![j.TextOnly,j.Playground].includes(r.chatMode)){if(!r.streamingManager)throw new H("Streaming manager is not initialized");if(!r.chat)throw new H("Chat is not initialized")}},m=async()=>{var S,u;if(!r.chat){const w=await ke(c,i,l,r.chatMode,t.persistentChat);if(!w.chat)throw new N(r.chatMode,!!t.persistentChat);r.chat=w.chat,(u=(S=t.callbacks).onNewChat)==null||u.call(S,r.chat.id)}return r.chat.id},M=async(S,u)=>ee(()=>{var w,b;return i.chat(c.id,u,{chatMode:r.chatMode,streamId:(w=r.streamingManager)==null?void 0:w.streamId,sessionId:(b=r.streamingManager)==null?void 0:b.sessionId,messages:S.map(({matches:L,...F})=>F)},{...De(r.chatMode),skipErrorHandler:!0})},{limit:2,shouldRetryFn:w=>{var F,Y,_e,Ie;const b=(F=w==null?void 0:w.message)==null?void 0:F.includes("missing or invalid session_id");return!((Y=w==null?void 0:w.message)==null?void 0:Y.includes("Stream Error"))&&!b?((Ie=(_e=t.callbacks).onError)==null||Ie.call(_e,w),!1):!0},onRetry:async()=>{await v(),await p(!1)}});try{k(),y(),r.messages.push({id:Q(),role:"user",content:d,created_at:new Date(q.update()).toISOString()}),(T=(I=t.callbacks).onNewMessage)==null||T.call(I,[...r.messages],"user");const S=await m(),u=await M([...r.messages],S);return r.messages.push({id:Q(),role:"assistant",content:u.result||"",created_at:new Date().toISOString(),context:u.context,matches:u.matches}),l.track("agent-message-send",{event:"success",mode:r.chatMode,messages:r.messages.length+1}),u.result&&((B=(z=t.callbacks).onNewMessage)==null||B.call(z,[...r.messages],"answer"),l.track("agent-message-received",{latency:q.get(!0),mode:r.chatMode,messages:r.messages.length})),u}catch(S){throw(($=r.messages[r.messages.length-1])==null?void 0:$.role)==="assistant"&&r.messages.pop(),l.track("agent-message-send",{event:"error",mode:r.chatMode,messages:r.messages.length}),S}},rate(d,y,m){var T,z,B,$;const M=r.messages.find(S=>S.id===d);if(r.chat){if(!M)throw new Error("Message not found")}else throw new Error("Chat is not initialized");const I=((T=M.matches)==null?void 0:T.map(S=>[S.document_id,S.id]))??[];return l.track("agent-rate",{event:m?"update":"create",thumb:y===1?"up":"down",knowledge_id:((z=c.knowledge)==null?void 0:z.id)??"",mode:r.chatMode,matches:I,score:y}),m?i.updateRating(c.id,r.chat.id,m,{knowledge_id:((B=c.knowledge)==null?void 0:B.id)??"",message_id:d,matches:I,score:y}):i.createRating(c.id,r.chat.id,{knowledge_id:(($=c.knowledge)==null?void 0:$.id)??"",message_id:d,matches:I,score:y})},deleteRate(d){var y;if(!r.chat)throw new Error("Chat is not initialized");return l.track("agent-rate-delete",{type:"text",chat_id:(y=r.chat)==null?void 0:y.id,id:d,mode:r.chatMode}),i.deleteRating(c.id,r.chat.id,d)},speak(d){var M;if(!r.streamingManager)throw new Error("Please connect to the agent first");function y(){if(typeof d=="string"){if(!c.presenter.voice)throw new Error("Presenter voice is not initialized");return{type:"text",provider:c.presenter.voice,input:d,ssml:!1}}if(d.type==="text"&&!d.provider){if(!c.presenter.voice)throw new Error("Presenter voice is not initialized");return{type:"text",provider:c.presenter.voice,input:d.input,ssml:d.ssml}}return d}const m=y();return l.track("agent-speak",m),q.update(),r.streamingManager.speak({script:m,metadata:{chat_id:(M=r.chat)==null?void 0:M.id,agent_id:c.id}})}}}function wt(e,t,a){const{getById:n}=Ce(t,a||X);return n(e)}f.AgentActivityState=x,f.AgentStatus=de,f.ChatCreationFailed=N,f.ChatMode=j,f.ChatModeDowngraded=ie,f.ChatProgress=U,f.ConnectionState=E,f.ConnectivityState=K,f.DataChannelSignalMap=O,f.DocumentType=me,f.KnowledgeType=fe,f.PlanGroup=ce,f.Providers=he,f.RateState=le,f.StreamEvents=V,f.StreamType=J,f.StreamingState=C,f.Subject=ue,f.UserPlan=oe,f.ValidationError=H,f.VideoType=Z,f.VoiceAccess=we,f.WsError=se,f.createAgentManager=ht,f.getAgent=wt,f.mapVideoType=ge,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
|