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