@d-id/client-sdk 1.0.29-beta.55 → 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/README.md +287 -5
- package/dist/index.js +1725 -414
- package/dist/index.umd.cjs +1851 -1
- package/dist/src/api/agents.d.ts +16 -9
- package/dist/src/api/apiClient.d.ts +10 -0
- package/dist/src/api/knowledge.d.ts +1 -1
- package/dist/src/api/streams/clipStream.d.ts +2 -0
- package/dist/src/api/streams/index.d.ts +2 -0
- package/dist/src/api/streams/talkStream.d.ts +2 -0
- package/dist/src/auth/{getAuthHeader.d.ts → get-auth-header.d.ts} +1 -0
- package/dist/src/config/consts.d.ts +2 -0
- package/dist/src/{environment.d.ts → config/environment.d.ts} +0 -1
- package/dist/src/errors/base-error.d.ts +12 -0
- package/dist/src/errors/chat/chat-creation-failed.d.ts +5 -0
- package/dist/src/errors/chat/chat-mode-downgraded.d.ts +5 -0
- package/dist/src/errors/index.d.ts +4 -0
- package/dist/src/errors/validation-error.d.ts +5 -0
- package/dist/src/errors/ws-error.d.ts +4 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/services/agent-manager/connect-to-manager.d.ts +7 -0
- package/dist/src/{createAgentManager.d.ts → services/agent-manager/index.d.ts} +12 -4
- package/dist/src/services/analytics/mixpanel.d.ts +21 -0
- package/dist/src/services/analytics/timestamp-tracker.d.ts +5 -0
- package/dist/src/services/chat/index.d.ts +7 -0
- package/dist/src/services/chat/intial-messages.d.ts +2 -0
- package/dist/src/services/socket-manager/index.d.ts +11 -0
- package/dist/src/services/socket-manager/message-queue.d.ts +11 -0
- package/dist/src/{createStreamingManager.d.ts → services/streaming-manager/index.d.ts} +4 -3
- package/dist/src/services/streaming-manager/stats/poll.d.ts +4 -0
- package/dist/src/services/streaming-manager/stats/report.d.ts +17 -0
- package/dist/src/types/entities/agents/agent.d.ts +14 -2
- package/dist/src/types/entities/agents/chat.d.ts +12 -4
- package/dist/src/types/entities/agents/knowledge.d.ts +2 -0
- package/dist/src/types/entities/agents/llm.d.ts +20 -17
- package/dist/src/types/entities/agents/manager.d.ts +106 -23
- package/dist/src/types/entities/agents/presenter.d.ts +8 -2
- package/dist/src/types/entities/video.d.ts +1 -0
- package/dist/src/types/face-rect.d.ts +6 -0
- package/dist/src/types/index.d.ts +4 -4
- package/dist/src/types/stream/api/clip.d.ts +21 -9
- package/dist/src/types/stream/api/talk.d.ts +31 -1
- package/dist/src/types/stream/rtc.d.ts +4 -3
- package/dist/src/types/stream/stream.d.ts +70 -4
- package/dist/src/types/{StreamScript.d.ts → stream-script.d.ts} +2 -2
- package/dist/src/types/voice/stt.d.ts +4 -0
- package/dist/src/utils/agent.d.ts +4 -0
- package/dist/src/utils/analytics.d.ts +15 -0
- package/dist/src/utils/chat.d.ts +2 -0
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/retry-operation.d.ts +38 -0
- package/package.json +3 -2
- package/dist/src/api/clipStream.d.ts +0 -2
- package/dist/src/api/getClient.d.ts +0 -7
- package/dist/src/api/ratings.d.ts +0 -7
- package/dist/src/api/talkStream.d.ts +0 -2
- package/dist/src/connectToSocket.d.ts +0 -9
- package/dist/src/utils/webrtc.d.ts +0 -2
- /package/dist/src/types/{tts.d.ts → voice/tts.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,536 +1,1847 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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 {
|
|
8
|
+
constructor({
|
|
9
|
+
kind,
|
|
10
|
+
description,
|
|
11
|
+
error
|
|
12
|
+
}) {
|
|
13
|
+
super(JSON.stringify({
|
|
14
|
+
kind,
|
|
15
|
+
description
|
|
16
|
+
}));
|
|
17
|
+
__publicField(this, "kind");
|
|
18
|
+
__publicField(this, "description");
|
|
19
|
+
__publicField(this, "error");
|
|
20
|
+
this.kind = kind;
|
|
21
|
+
this.description = description;
|
|
22
|
+
this.error = error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
class ChatCreationFailed extends BaseError {
|
|
26
|
+
constructor(mode, persistent) {
|
|
27
|
+
super({
|
|
28
|
+
kind: "ChatCreationFailed",
|
|
29
|
+
description: `Failed to create ${persistent ? "persistent" : ""} chat, mode: ${mode}`
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class ChatModeDowngraded extends BaseError {
|
|
34
|
+
constructor(mode) {
|
|
35
|
+
super({
|
|
36
|
+
kind: "ChatModeDowngraded",
|
|
37
|
+
description: `Chat mode downgraded to ${mode}`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class ValidationError extends BaseError {
|
|
42
|
+
constructor(message, key) {
|
|
43
|
+
super({
|
|
44
|
+
kind: "ValidationError",
|
|
45
|
+
description: message
|
|
46
|
+
});
|
|
47
|
+
__publicField(this, "key");
|
|
48
|
+
this.key = key;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class WsError extends BaseError {
|
|
52
|
+
constructor(message) {
|
|
53
|
+
super({
|
|
54
|
+
kind: "WSError",
|
|
55
|
+
description: message
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
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) {
|
|
145
|
+
case "clip":
|
|
146
|
+
return "clip";
|
|
147
|
+
case "talk":
|
|
148
|
+
return "talk";
|
|
149
|
+
default:
|
|
150
|
+
throw new Error(`Unknown video type: ${type}`);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
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
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
promise,
|
|
235
|
+
clear: () => clearTimeout(timeId)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
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) ?? (() => {
|
|
246
|
+
})
|
|
247
|
+
};
|
|
248
|
+
let lastError;
|
|
249
|
+
for (let attempt = 1; attempt <= options.limit; attempt++) {
|
|
250
|
+
try {
|
|
251
|
+
if (!options.timeout) {
|
|
252
|
+
return await operation();
|
|
253
|
+
}
|
|
254
|
+
const {
|
|
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);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
throw lastError;
|
|
270
|
+
}
|
|
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;
|
|
279
|
+
}
|
|
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
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const retryHttpTooManyRequests = (operation) => retryOperation(operation, {
|
|
293
|
+
limit: 3,
|
|
294
|
+
delayMs: 1e3,
|
|
295
|
+
timeout: 0,
|
|
296
|
+
shouldRetryFn: (error) => error.status === 429
|
|
297
|
+
});
|
|
298
|
+
function createClient(auth, host = didApiUrl, onError) {
|
|
299
|
+
const client = async (url, options) => {
|
|
300
|
+
const {
|
|
301
|
+
skipErrorHandler,
|
|
302
|
+
...fetchOptions
|
|
303
|
+
} = options || {};
|
|
304
|
+
const request = await retryHttpTooManyRequests(() => fetch(host + ((url == null ? void 0 : url.startsWith("/")) ? url : `/${url}`), {
|
|
305
|
+
...fetchOptions,
|
|
21
306
|
headers: {
|
|
22
|
-
...
|
|
23
|
-
Authorization:
|
|
307
|
+
...fetchOptions.headers,
|
|
308
|
+
Authorization: getAuthHeader(auth),
|
|
24
309
|
"Content-Type": "application/json"
|
|
25
310
|
}
|
|
26
|
-
});
|
|
27
|
-
if (!
|
|
28
|
-
let
|
|
29
|
-
|
|
311
|
+
}));
|
|
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;
|
|
30
323
|
}
|
|
31
|
-
return
|
|
324
|
+
return request.json();
|
|
32
325
|
};
|
|
33
326
|
return {
|
|
34
|
-
get(
|
|
35
|
-
return
|
|
36
|
-
...
|
|
327
|
+
get(url, options) {
|
|
328
|
+
return client(url, {
|
|
329
|
+
...options,
|
|
37
330
|
method: "GET"
|
|
38
331
|
});
|
|
39
332
|
},
|
|
40
|
-
post(
|
|
41
|
-
return
|
|
42
|
-
...
|
|
43
|
-
body: JSON.stringify(
|
|
333
|
+
post(url, body, options) {
|
|
334
|
+
return client(url, {
|
|
335
|
+
...options,
|
|
336
|
+
body: JSON.stringify(body),
|
|
44
337
|
method: "POST"
|
|
45
338
|
});
|
|
46
339
|
},
|
|
47
|
-
delete(
|
|
48
|
-
return
|
|
49
|
-
...
|
|
50
|
-
body: JSON.stringify(
|
|
340
|
+
delete(url, body, options) {
|
|
341
|
+
return client(url, {
|
|
342
|
+
...options,
|
|
343
|
+
body: JSON.stringify(body),
|
|
51
344
|
method: "DELETE"
|
|
52
345
|
});
|
|
53
346
|
},
|
|
54
|
-
patch(
|
|
55
|
-
return
|
|
56
|
-
...
|
|
57
|
-
body: JSON.stringify(
|
|
347
|
+
patch(url, body, options) {
|
|
348
|
+
return client(url, {
|
|
349
|
+
...options,
|
|
350
|
+
body: JSON.stringify(body),
|
|
58
351
|
method: "PATCH"
|
|
59
352
|
});
|
|
60
353
|
}
|
|
61
354
|
};
|
|
62
355
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
356
|
+
function createAgentsApi(auth, host = didApiUrl, onError) {
|
|
357
|
+
const client = createClient(auth, `${host}/agents`, onError);
|
|
65
358
|
return {
|
|
66
|
-
create(
|
|
67
|
-
return
|
|
359
|
+
create(payload, options) {
|
|
360
|
+
return client.post(`/`, payload, options);
|
|
68
361
|
},
|
|
69
|
-
getAgents(
|
|
70
|
-
return
|
|
362
|
+
getAgents(tag, options) {
|
|
363
|
+
return client.get(`/${tag ? `?tag=${tag}` : ""}`, options).then((agents) => agents ?? []);
|
|
71
364
|
},
|
|
72
|
-
getById(
|
|
73
|
-
return
|
|
365
|
+
getById(id, options) {
|
|
366
|
+
return client.get(`/${id}`, options);
|
|
74
367
|
},
|
|
75
|
-
delete(
|
|
76
|
-
return
|
|
368
|
+
delete(id, options) {
|
|
369
|
+
return client.delete(`/${id}`, void 0, options);
|
|
77
370
|
},
|
|
78
|
-
update(
|
|
79
|
-
return
|
|
371
|
+
update(id, payload, options) {
|
|
372
|
+
return client.patch(`/${id}`, payload, options);
|
|
80
373
|
},
|
|
81
|
-
newChat(
|
|
82
|
-
return
|
|
374
|
+
newChat(agentId, payload, options) {
|
|
375
|
+
return client.post(`/${agentId}/chat`, payload, options);
|
|
83
376
|
},
|
|
84
|
-
chat(
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function J(e, a = y) {
|
|
90
|
-
const n = k(e, `${a}/knowledge`);
|
|
91
|
-
return {
|
|
92
|
-
createKnowledge(t, r) {
|
|
93
|
-
return n.post("/", t, r);
|
|
377
|
+
chat(agentId, chatId, payload, options) {
|
|
378
|
+
return client.post(`/${agentId}/chat/${chatId}`, payload, options);
|
|
94
379
|
},
|
|
95
|
-
|
|
96
|
-
return
|
|
380
|
+
createRating(agentId, chatId, payload, options) {
|
|
381
|
+
return client.post(`/${agentId}/chat/${chatId}/ratings`, payload, options);
|
|
97
382
|
},
|
|
98
|
-
|
|
99
|
-
return
|
|
383
|
+
updateRating(agentId, chatId, ratingId, payload, options) {
|
|
384
|
+
return client.patch(`/${agentId}/chat/${chatId}/ratings/${ratingId}`, payload, options);
|
|
100
385
|
},
|
|
101
|
-
|
|
102
|
-
return
|
|
386
|
+
deleteRating(agentId, chatId, ratingId, options) {
|
|
387
|
+
return client.delete(`/${agentId}/chat/${chatId}/ratings/${ratingId}`, options);
|
|
103
388
|
},
|
|
104
|
-
|
|
105
|
-
return
|
|
389
|
+
getSTTToken(agentId, options) {
|
|
390
|
+
return client.get(`/${agentId}/stt-token`, options);
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
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;
|
|
413
|
+
return {
|
|
414
|
+
$os: `${getUserOS()}`,
|
|
415
|
+
isMobile: `${mobileOrDesktop() == "Mobile"}`,
|
|
416
|
+
browser: navigator.userAgent,
|
|
417
|
+
origin: window.location.origin,
|
|
418
|
+
agentType: getAgentType(presenter),
|
|
419
|
+
agentVoice: {
|
|
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
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
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;
|
|
429
|
+
const {
|
|
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,
|
|
441
|
+
llm: {
|
|
442
|
+
...baseProps.llm,
|
|
443
|
+
template
|
|
106
444
|
},
|
|
107
|
-
|
|
108
|
-
|
|
445
|
+
script: {
|
|
446
|
+
...baseProps.script,
|
|
447
|
+
provider: {
|
|
448
|
+
...(_b = baseProps == null ? void 0 : baseProps.script) == null ? void 0 : _b.provider,
|
|
449
|
+
language
|
|
450
|
+
}
|
|
109
451
|
},
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
454
|
+
};
|
|
455
|
+
return props;
|
|
456
|
+
}
|
|
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,
|
|
471
|
+
behavior: {
|
|
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
|
|
112
475
|
},
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
481
|
+
};
|
|
482
|
+
return {
|
|
483
|
+
...analyticProps,
|
|
484
|
+
additionalProperties: {},
|
|
485
|
+
isEnabled: config.isEnabled ?? true,
|
|
486
|
+
getRandom,
|
|
487
|
+
enrich(properties) {
|
|
488
|
+
const props = {};
|
|
489
|
+
if (properties && typeof properties !== "object") {
|
|
490
|
+
throw new Error("properties must be a flat json object");
|
|
491
|
+
}
|
|
492
|
+
for (let prop in properties) {
|
|
493
|
+
if (typeof properties[prop] === "string" || typeof properties[prop] === "number") {
|
|
494
|
+
props[prop] = properties[prop];
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
this.additionalProperties = {
|
|
498
|
+
...this.additionalProperties,
|
|
499
|
+
...props
|
|
500
|
+
};
|
|
115
501
|
},
|
|
116
|
-
|
|
117
|
-
|
|
502
|
+
async track(event, props) {
|
|
503
|
+
if (!this.isEnabled) {
|
|
504
|
+
return Promise.resolve();
|
|
505
|
+
}
|
|
506
|
+
const {
|
|
507
|
+
audioPath,
|
|
508
|
+
...sendProps
|
|
509
|
+
} = props || {};
|
|
510
|
+
const options = {
|
|
511
|
+
method: "POST",
|
|
512
|
+
headers: {
|
|
513
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
514
|
+
},
|
|
515
|
+
body: new URLSearchParams({
|
|
516
|
+
data: JSON.stringify([{
|
|
517
|
+
event,
|
|
518
|
+
properties: {
|
|
519
|
+
...this.additionalProperties,
|
|
520
|
+
...sendProps,
|
|
521
|
+
...analyticProps,
|
|
522
|
+
source,
|
|
523
|
+
time: Date.now(),
|
|
524
|
+
$insert_id: this.getRandom(),
|
|
525
|
+
origin: window.location.href,
|
|
526
|
+
"Screen Height": window.screen.height || window.innerWidth,
|
|
527
|
+
"Screen Width": window.screen.width || window.innerHeight,
|
|
528
|
+
"User Agent": navigator.userAgent
|
|
529
|
+
}
|
|
530
|
+
}])
|
|
531
|
+
})
|
|
532
|
+
};
|
|
533
|
+
try {
|
|
534
|
+
return await fetch(mixpanelUrl, options).then((res) => res.json());
|
|
535
|
+
} catch (err) {
|
|
536
|
+
return console.error(err);
|
|
537
|
+
}
|
|
118
538
|
},
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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];
|
|
569
|
+
});
|
|
570
|
+
}
|
|
123
571
|
}
|
|
124
572
|
};
|
|
125
573
|
}
|
|
126
|
-
function
|
|
127
|
-
|
|
574
|
+
function createTimestampTracker() {
|
|
575
|
+
let timestamp = 0;
|
|
128
576
|
return {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
getByKnowledge(t, r) {
|
|
133
|
-
return n.get(`/${t}`, r).then((i) => i ?? []);
|
|
134
|
-
},
|
|
135
|
-
update(t, r, i) {
|
|
136
|
-
return n.patch(`/${t}`, r, i);
|
|
137
|
-
},
|
|
138
|
-
delete(t, r) {
|
|
139
|
-
return n.delete(`/${t}`, r);
|
|
140
|
-
}
|
|
577
|
+
reset: () => timestamp = 0,
|
|
578
|
+
update: () => timestamp = Date.now(),
|
|
579
|
+
get: (delta = false) => delta ? Date.now() - timestamp : timestamp
|
|
141
580
|
};
|
|
142
581
|
}
|
|
143
|
-
const
|
|
144
|
-
function
|
|
145
|
-
return
|
|
582
|
+
const timestampTracker = createTimestampTracker();
|
|
583
|
+
function getRequestHeaders(chatMode) {
|
|
584
|
+
return chatMode === ChatMode.Playground ? {
|
|
585
|
+
headers: {
|
|
586
|
+
[PLAYGROUND_HEADER]: "true"
|
|
587
|
+
}
|
|
588
|
+
} : {};
|
|
589
|
+
}
|
|
590
|
+
async function createChat(agent, agentsApi, analytics, chatMode, persist = false, chat) {
|
|
591
|
+
try {
|
|
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
|
|
606
|
+
};
|
|
607
|
+
} catch (error) {
|
|
608
|
+
try {
|
|
609
|
+
const parsedError = JSON.parse(error.message);
|
|
610
|
+
if ((parsedError == null ? void 0 : parsedError.kind) === "InsufficientCreditsError") {
|
|
611
|
+
throw new Error("InsufficientCreditsError");
|
|
612
|
+
}
|
|
613
|
+
} catch (e) {
|
|
614
|
+
console.error("Error parsing the error message:", e);
|
|
615
|
+
}
|
|
616
|
+
throw new Error("Cannot create new chat");
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
function getInitialMessages(initialMessages) {
|
|
620
|
+
if (initialMessages && initialMessages.length > 0) {
|
|
621
|
+
return initialMessages;
|
|
622
|
+
}
|
|
623
|
+
return [];
|
|
624
|
+
}
|
|
625
|
+
function connect(options) {
|
|
626
|
+
return new Promise((resolve, reject) => {
|
|
627
|
+
const {
|
|
628
|
+
callbacks,
|
|
629
|
+
host,
|
|
630
|
+
auth
|
|
631
|
+
} = options;
|
|
146
632
|
const {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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);
|
|
160
649
|
};
|
|
161
650
|
});
|
|
162
651
|
}
|
|
163
|
-
async function
|
|
652
|
+
async function connectWithRetries(options) {
|
|
164
653
|
const {
|
|
165
|
-
retries
|
|
166
|
-
} =
|
|
167
|
-
let
|
|
168
|
-
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++) {
|
|
169
658
|
try {
|
|
170
|
-
|
|
171
|
-
} catch (
|
|
172
|
-
if (
|
|
173
|
-
throw
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
659
|
+
socket = await connect(options);
|
|
660
|
+
} catch (e) {
|
|
661
|
+
if (attempt === retries) {
|
|
662
|
+
throw e;
|
|
663
|
+
}
|
|
664
|
+
await sleep(attempt * 500);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return socket;
|
|
668
|
+
}
|
|
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,
|
|
182
674
|
callbacks: {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
675
|
+
onError: (error) => {
|
|
676
|
+
var _a;
|
|
677
|
+
return (_a = callbacks.onError) == null ? void 0 : _a.call(callbacks, new WsError(error));
|
|
678
|
+
},
|
|
679
|
+
onMessage(event) {
|
|
680
|
+
const parsedData = JSON.parse(event.data);
|
|
681
|
+
messageCallbacks.forEach((callback) => callback(parsedData.event, parsedData));
|
|
186
682
|
}
|
|
187
683
|
}
|
|
188
684
|
});
|
|
189
685
|
return {
|
|
190
|
-
socket
|
|
191
|
-
disconnect: () =>
|
|
192
|
-
subscribeToEvents: (
|
|
686
|
+
socket,
|
|
687
|
+
disconnect: () => socket.close(),
|
|
688
|
+
subscribeToEvents: (callback) => messageCallbacks.push(callback)
|
|
689
|
+
};
|
|
690
|
+
}
|
|
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;
|
|
701
|
+
}
|
|
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") {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const {
|
|
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
|
+
}
|
|
721
|
+
}
|
|
722
|
+
function createMessageEventQueue(analytics, items, options, agentEntity, onStreamDone) {
|
|
723
|
+
let chatEventQueue = {};
|
|
724
|
+
return {
|
|
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
|
|
742
|
+
});
|
|
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();
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
193
770
|
};
|
|
194
771
|
}
|
|
195
|
-
function
|
|
196
|
-
const
|
|
772
|
+
function createClipApi(auth, host, agentId, onError) {
|
|
773
|
+
const client = createClient(auth, `${host}/agents/${agentId}`, onError);
|
|
197
774
|
return {
|
|
198
|
-
createStream(
|
|
199
|
-
return
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
|
204
782
|
});
|
|
205
783
|
},
|
|
206
|
-
startConnection(
|
|
207
|
-
return
|
|
208
|
-
session_id:
|
|
209
|
-
answer
|
|
784
|
+
startConnection(streamId, answer, sessionId) {
|
|
785
|
+
return client.post(`/streams/${streamId}/sdp`, {
|
|
786
|
+
session_id: sessionId,
|
|
787
|
+
answer
|
|
210
788
|
});
|
|
211
789
|
},
|
|
212
|
-
addIceCandidate(
|
|
213
|
-
return
|
|
214
|
-
session_id:
|
|
215
|
-
...
|
|
790
|
+
addIceCandidate(streamId, candidate, sessionId) {
|
|
791
|
+
return client.post(`/streams/${streamId}/ice`, {
|
|
792
|
+
session_id: sessionId,
|
|
793
|
+
...candidate
|
|
216
794
|
});
|
|
217
795
|
},
|
|
218
|
-
sendStreamRequest(
|
|
219
|
-
return
|
|
220
|
-
session_id:
|
|
221
|
-
...
|
|
796
|
+
sendStreamRequest(streamId, sessionId, payload) {
|
|
797
|
+
return client.post(`/streams/${streamId}`, {
|
|
798
|
+
session_id: sessionId,
|
|
799
|
+
...payload
|
|
222
800
|
});
|
|
223
801
|
},
|
|
224
|
-
close(
|
|
225
|
-
return
|
|
226
|
-
session_id:
|
|
802
|
+
close(streamId, sessionId) {
|
|
803
|
+
return client.delete(`/streams/${streamId}`, {
|
|
804
|
+
session_id: sessionId
|
|
227
805
|
});
|
|
228
806
|
}
|
|
229
807
|
};
|
|
230
808
|
}
|
|
231
|
-
function
|
|
232
|
-
const
|
|
809
|
+
function createTalkApi(auth, host, agentId, onError) {
|
|
810
|
+
const client = createClient(auth, `${host}/agents/${agentId}`, onError);
|
|
233
811
|
return {
|
|
234
|
-
createStream(
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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);
|
|
823
|
+
},
|
|
824
|
+
startConnection(streamId, answer, sessionId, options) {
|
|
825
|
+
return client.post(`/streams/${streamId}/sdp`, {
|
|
826
|
+
session_id: sessionId,
|
|
827
|
+
answer
|
|
828
|
+
}, options);
|
|
829
|
+
},
|
|
830
|
+
addIceCandidate(streamId, candidate, sessionId, options) {
|
|
831
|
+
return client.post(`/streams/${streamId}/ice`, {
|
|
832
|
+
session_id: sessionId,
|
|
833
|
+
...candidate
|
|
834
|
+
}, options);
|
|
835
|
+
},
|
|
836
|
+
sendStreamRequest(streamId, sessionId, payload, options) {
|
|
837
|
+
return client.post(`/streams/${streamId}`, {
|
|
838
|
+
session_id: sessionId,
|
|
839
|
+
...payload
|
|
840
|
+
}, options);
|
|
841
|
+
},
|
|
842
|
+
close(streamId, sessionId, options) {
|
|
843
|
+
return client.delete(`/streams/${streamId}`, {
|
|
844
|
+
session_id: sessionId
|
|
845
|
+
}, options);
|
|
264
846
|
}
|
|
265
847
|
};
|
|
266
848
|
}
|
|
267
|
-
function
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
bytesReceived:
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
849
|
+
function createAggregateReport(start, end, lowFpsCount) {
|
|
850
|
+
const duration = (end.timestamp - start.timestamp) / 1e3;
|
|
851
|
+
return {
|
|
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
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function extractAnomalies(stats) {
|
|
870
|
+
return stats.filter((report) => report.freezeCount > 0 || report.framesPerSecond < 21 || report.framesDropped > 0 || report.packetsLost > 0).map((report) => {
|
|
871
|
+
const {
|
|
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
|
|
891
|
+
};
|
|
298
892
|
});
|
|
299
893
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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") {
|
|
905
|
+
return {
|
|
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
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
return {};
|
|
927
|
+
}
|
|
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);
|
|
993
|
+
return {
|
|
994
|
+
webRTCStats: {
|
|
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)
|
|
1003
|
+
},
|
|
1004
|
+
codec: stats[0].codec,
|
|
1005
|
+
resolution: `${stats[0].frameWidth}x${stats[0].frameHeight}`
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
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;
|
|
324
1026
|
}
|
|
325
|
-
|
|
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
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return {
|
|
1040
|
+
isReceiving: false,
|
|
1041
|
+
avgJitterDelayInInterval
|
|
1042
|
+
};
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
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();
|
|
1055
|
+
return setInterval(async () => {
|
|
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
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}, interval);
|
|
1093
|
+
}
|
|
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) {
|
|
1099
|
+
case "connected":
|
|
1100
|
+
return ConnectionState.Connected;
|
|
1101
|
+
case "checking":
|
|
1102
|
+
return ConnectionState.Connecting;
|
|
1103
|
+
case "failed":
|
|
1104
|
+
return ConnectionState.Fail;
|
|
1105
|
+
case "new":
|
|
1106
|
+
return ConnectionState.New;
|
|
1107
|
+
case "closed":
|
|
1108
|
+
return ConnectionState.Closed;
|
|
1109
|
+
case "disconnected":
|
|
1110
|
+
return ConnectionState.Disconnected;
|
|
1111
|
+
case "completed":
|
|
1112
|
+
return ConnectionState.Completed;
|
|
1113
|
+
default:
|
|
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);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
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
|
|
326
1161
|
});
|
|
327
|
-
}
|
|
1162
|
+
} else if (streamType === StreamType.Fluent) {
|
|
1163
|
+
handleFluentStreamState({
|
|
1164
|
+
statsSignal,
|
|
1165
|
+
dataChannelSignal,
|
|
1166
|
+
onVideoStateChange,
|
|
1167
|
+
onAgentActivityStateChange,
|
|
1168
|
+
report
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
328
1171
|
}
|
|
329
|
-
async function
|
|
330
|
-
debug
|
|
331
|
-
callbacks
|
|
332
|
-
auth
|
|
333
|
-
baseURL
|
|
1172
|
+
async function createStreamingManager(agentId, agent, {
|
|
1173
|
+
debug = false,
|
|
1174
|
+
callbacks,
|
|
1175
|
+
auth,
|
|
1176
|
+
baseURL = didApiUrl,
|
|
1177
|
+
analytics
|
|
334
1178
|
}) {
|
|
335
|
-
|
|
1179
|
+
_debug = debug;
|
|
1180
|
+
let isConnected = false;
|
|
1181
|
+
let isDatachannelOpen = false;
|
|
1182
|
+
let dataChannelSignal = StreamingState.Stop;
|
|
1183
|
+
let statsSignal = StreamingState.Stop;
|
|
1184
|
+
const {
|
|
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);
|
|
336
1191
|
const {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
} =
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
iceServers: v
|
|
349
|
-
}), s = u.createDataChannel("JanusDataChannel");
|
|
350
|
-
if (!f)
|
|
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) {
|
|
351
1203
|
throw new Error("Could not create session_id");
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
var
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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);
|
|
1232
|
+
try {
|
|
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
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
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 {
|
|
377
1290
|
/**
|
|
378
1291
|
* Method to send request to server to get clip or talk depend on you payload
|
|
379
1292
|
* @param payload
|
|
380
1293
|
*/
|
|
381
|
-
speak(
|
|
382
|
-
return
|
|
1294
|
+
speak(payload) {
|
|
1295
|
+
return sendStreamRequest(streamIdFromServer, session_id, payload);
|
|
383
1296
|
},
|
|
384
1297
|
/**
|
|
385
1298
|
* Method to close RTC connection
|
|
386
1299
|
*/
|
|
387
1300
|
async disconnect() {
|
|
388
|
-
var
|
|
389
|
-
|
|
390
|
-
|
|
1301
|
+
var _a;
|
|
1302
|
+
if (streamIdFromServer) {
|
|
1303
|
+
const state = mapConnectionState(peerConnection.iceConnectionState);
|
|
1304
|
+
if (peerConnection) {
|
|
1305
|
+
if (state === ConnectionState.New) {
|
|
1306
|
+
clearInterval(videoStatsInterval);
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
peerConnection.close();
|
|
1310
|
+
peerConnection.oniceconnectionstatechange = null;
|
|
1311
|
+
peerConnection.onnegotiationneeded = null;
|
|
1312
|
+
peerConnection.onicecandidate = null;
|
|
1313
|
+
peerConnection.ontrack = null;
|
|
1314
|
+
}
|
|
1315
|
+
try {
|
|
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);
|
|
1322
|
+
}
|
|
1323
|
+
(_a = callbacks.onAgentActivityStateChange) == null ? void 0 : _a.call(callbacks, AgentActivityState.Idle);
|
|
1324
|
+
clearInterval(videoStatsInterval);
|
|
1325
|
+
}
|
|
391
1326
|
},
|
|
392
1327
|
/**
|
|
393
1328
|
* Session identifier information, should be returned in the body of all streaming requests
|
|
394
1329
|
*/
|
|
395
|
-
sessionId:
|
|
1330
|
+
sessionId: session_id,
|
|
396
1331
|
/**
|
|
397
1332
|
* Id of current RTC stream
|
|
398
1333
|
*/
|
|
399
|
-
streamId:
|
|
1334
|
+
streamId: streamIdFromServer,
|
|
1335
|
+
streamType
|
|
400
1336
|
};
|
|
401
1337
|
}
|
|
402
|
-
function
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
} : {
|
|
414
|
-
videoType: I.Talk,
|
|
415
|
-
source_url: e.presenter.source_url
|
|
1338
|
+
function getAgentStreamArgs(agent, options) {
|
|
1339
|
+
const {
|
|
1340
|
+
streamOptions
|
|
1341
|
+
} = options ?? {};
|
|
1342
|
+
return {
|
|
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
|
|
416
1349
|
};
|
|
417
1350
|
}
|
|
418
|
-
function
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
function connectToManager(agent, options, analytics) {
|
|
1412
|
+
timestampTracker.reset();
|
|
1413
|
+
return new Promise(async (resolve, reject) => {
|
|
1414
|
+
try {
|
|
1415
|
+
const streamingManager = await createStreamingManager(agent.id, getAgentStreamArgs(agent, options), {
|
|
1416
|
+
...options,
|
|
1417
|
+
analytics,
|
|
1418
|
+
callbacks: {
|
|
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);
|
|
434
1425
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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);
|
|
1431
|
+
},
|
|
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);
|
|
1436
|
+
}
|
|
438
1437
|
}
|
|
439
|
-
}
|
|
440
|
-
})
|
|
1438
|
+
});
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
reject(error);
|
|
1441
|
+
}
|
|
441
1442
|
});
|
|
442
1443
|
}
|
|
443
|
-
function
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
1444
|
+
async function initializeStreamAndChat(agent, options, agentsApi, analytics, chat) {
|
|
1445
|
+
var _a, _b, _c, _d;
|
|
1446
|
+
const {
|
|
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);
|
|
456
1461
|
return {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
1462
|
+
chat: newChat,
|
|
1463
|
+
streamingManager
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
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 = {
|
|
1473
|
+
messages: [],
|
|
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();
|
|
1490
|
+
});
|
|
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", {
|
|
1494
|
+
event: "loaded",
|
|
1495
|
+
...getAnalyticsInfo(agentEntity)
|
|
1496
|
+
});
|
|
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
|
+
}, {
|
|
1512
|
+
limit: 3,
|
|
1513
|
+
timeout: CONNECTION_RETRY_TIMEOUT_MS,
|
|
1514
|
+
timeoutErrorMessage: "Timeout initializing the stream",
|
|
1515
|
+
// Retry on all errors except for connection errors and rate limit errors, these are already handled in client level.
|
|
1516
|
+
shouldRetryFn: (error) => (error == null ? void 0 : error.message) !== "Could not connect" && error.status !== 429,
|
|
1517
|
+
delayMs: 1e3
|
|
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);
|
|
1536
|
+
}
|
|
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);
|
|
1544
|
+
}
|
|
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
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
return {
|
|
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,
|
|
1568
|
+
async connect() {
|
|
1569
|
+
var _a2;
|
|
1570
|
+
await connect2(true);
|
|
1571
|
+
analytics.track("agent-chat", {
|
|
1572
|
+
event: "connect",
|
|
1573
|
+
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1574
|
+
agentId: agentEntity.id,
|
|
1575
|
+
mode: items.chatMode
|
|
1576
|
+
});
|
|
1577
|
+
},
|
|
460
1578
|
async reconnect() {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
chat(s) {
|
|
470
|
-
if (s.length === 0)
|
|
471
|
-
throw new Error("Messages cannot be empty");
|
|
472
|
-
return s[s.length - 1].created_at = (/* @__PURE__ */ new Date()).toISOString(), s[s.length - 1].role || (s[s.length - 1].role = "user"), i.chat(o.id, l.id, {
|
|
473
|
-
sessionId: m.sessionId,
|
|
474
|
-
streamId: m.streamId,
|
|
475
|
-
messages: s
|
|
476
|
-
}, {
|
|
477
|
-
signal: r.signal
|
|
1579
|
+
var _a2;
|
|
1580
|
+
await disconnect();
|
|
1581
|
+
await connect2(false);
|
|
1582
|
+
analytics.track("agent-chat", {
|
|
1583
|
+
event: "reconnect",
|
|
1584
|
+
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1585
|
+
agentId: agentEntity.id,
|
|
1586
|
+
mode: items.chatMode
|
|
478
1587
|
});
|
|
479
1588
|
},
|
|
480
|
-
|
|
481
|
-
var
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
matches: c
|
|
489
|
-
}) : d.create({
|
|
490
|
-
agent_id: o.id,
|
|
491
|
-
knowledge_id: ((h = o.knowledge) == null ? void 0 : h.id) ?? "",
|
|
492
|
-
chat_id: l.id,
|
|
493
|
-
score: s,
|
|
494
|
-
matches: c
|
|
1589
|
+
async disconnect() {
|
|
1590
|
+
var _a2;
|
|
1591
|
+
await disconnect();
|
|
1592
|
+
analytics.track("agent-chat", {
|
|
1593
|
+
event: "disconnect",
|
|
1594
|
+
chatId: (_a2 = items.chat) == null ? void 0 : _a2.id,
|
|
1595
|
+
agentId: agentEntity.id,
|
|
1596
|
+
mode: items.chatMode
|
|
495
1597
|
});
|
|
496
1598
|
},
|
|
497
|
-
|
|
498
|
-
|
|
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
|
+
}
|
|
1617
|
+
}
|
|
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);
|
|
1628
|
+
}
|
|
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
|
+
});
|
|
1646
|
+
}, {
|
|
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
|
+
}
|
|
1662
|
+
});
|
|
1663
|
+
};
|
|
1664
|
+
try {
|
|
1665
|
+
clearQueue();
|
|
1666
|
+
validateChatRequest();
|
|
1667
|
+
items.messages.push({
|
|
1668
|
+
id: getRandom(),
|
|
1669
|
+
role: "user",
|
|
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(),
|
|
1678
|
+
role: "assistant",
|
|
1679
|
+
content: response.result || "",
|
|
1680
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1681
|
+
context: response.context,
|
|
1682
|
+
matches: response.matches
|
|
1683
|
+
});
|
|
1684
|
+
analytics.track("agent-message-send", {
|
|
1685
|
+
event: "success",
|
|
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", {
|
|
1703
|
+
event: "error",
|
|
1704
|
+
mode: items.chatMode,
|
|
1705
|
+
messages: items.messages.length
|
|
1706
|
+
});
|
|
1707
|
+
throw e;
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
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) {
|
|
1714
|
+
throw new Error("Chat is not initialized");
|
|
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
|
|
1740
|
+
});
|
|
1741
|
+
},
|
|
1742
|
+
deleteRate(id) {
|
|
1743
|
+
var _a2;
|
|
1744
|
+
if (!items.chat) {
|
|
1745
|
+
throw new Error("Chat is not initialized");
|
|
1746
|
+
}
|
|
1747
|
+
analytics.track("agent-rate-delete", {
|
|
1748
|
+
type: "text",
|
|
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);
|
|
499
1754
|
},
|
|
500
|
-
speak(
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
1755
|
+
async speak(payload) {
|
|
1756
|
+
var _a2, _b2, _c2, _d;
|
|
1757
|
+
if (!items.streamingManager) {
|
|
1758
|
+
throw new Error("Please connect to the agent first");
|
|
1759
|
+
}
|
|
1760
|
+
function getScript() {
|
|
1761
|
+
if (typeof payload === "string") {
|
|
1762
|
+
if (!agentEntity.presenter.voice) {
|
|
1763
|
+
throw new Error("Presenter voice is not initialized");
|
|
1764
|
+
}
|
|
1765
|
+
return {
|
|
505
1766
|
type: "text",
|
|
506
|
-
provider:
|
|
507
|
-
input:
|
|
508
|
-
ssml:
|
|
1767
|
+
provider: agentEntity.presenter.voice,
|
|
1768
|
+
input: payload,
|
|
1769
|
+
ssml: false
|
|
509
1770
|
};
|
|
510
|
-
}
|
|
1771
|
+
}
|
|
1772
|
+
if (payload.type === "text" && !payload.provider) {
|
|
1773
|
+
if (!agentEntity.presenter.voice) {
|
|
1774
|
+
throw new Error("Presenter voice is not initialized");
|
|
1775
|
+
}
|
|
511
1776
|
return {
|
|
512
|
-
type: "
|
|
513
|
-
|
|
1777
|
+
type: "text",
|
|
1778
|
+
provider: agentEntity.presenter.voice,
|
|
1779
|
+
input: payload.input,
|
|
1780
|
+
ssml: payload.ssml
|
|
514
1781
|
};
|
|
515
|
-
|
|
1782
|
+
}
|
|
1783
|
+
return payload;
|
|
1784
|
+
}
|
|
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
|
+
};
|
|
516
1803
|
}
|
|
517
|
-
return
|
|
518
|
-
script
|
|
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
|
+
}
|
|
519
1810
|
});
|
|
520
1811
|
}
|
|
521
1812
|
};
|
|
522
1813
|
}
|
|
1814
|
+
function getAgent(agentId, auth, baseURL) {
|
|
1815
|
+
const {
|
|
1816
|
+
getById
|
|
1817
|
+
} = createAgentsApi(auth, baseURL || didApiUrl);
|
|
1818
|
+
return getById(agentId);
|
|
1819
|
+
}
|
|
523
1820
|
export {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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
|
|
536
1847
|
};
|