ai12z 3.15.1 → 3.16.1-alpha.1
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/cjs/ai12z-bot.cjs.entry.js +165 -52
- package/dist/cjs/ai12z-chat-message.cjs.entry.js +11 -11
- package/dist/cjs/chat-avatar_6.cjs.entry.js +12 -11
- package/dist/collection/components/ai12z-bot/ai12z-bot.js +111 -46
- package/dist/collection/components/ai12z-bot/components/interaction-buttons/interaction-buttons.js +12 -11
- package/dist/collection/components/ai12z-knowledge-box/components/ai12z-chat-message.js +11 -11
- package/dist/collection/utils/liveagents/providers/salesforce.js +55 -7
- package/dist/components/ai12z-bot.js +1 -1
- package/dist/components/ai12z-chat-message.js +1 -1
- package/dist/components/ai12z-chat.js +1 -1
- package/dist/components/ai12z-container.js +1 -1
- package/dist/components/ai12z-cta.js +1 -1
- package/dist/components/ai12z-form.js +1 -1
- package/dist/components/ai12z-inline-search.js +1 -1
- package/dist/components/ai12z-input-form.js +1 -1
- package/dist/components/ai12z-knowledge-box.js +1 -1
- package/dist/components/ai12z-search-panel.js +1 -1
- package/dist/components/audio-recorder.js +1 -1
- package/dist/components/dynamic-form.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/interaction-buttons.js +1 -1
- package/dist/components/item-list.js +1 -1
- package/dist/components/p-BKtxX2NI.js +1 -0
- package/dist/components/p-BLccTHb0.js +1 -0
- package/dist/components/{p-Crr5-qOu.js → p-BNRHkg-z.js} +1 -1
- package/dist/components/{p-DU8l3fUF.js → p-BPDEFLRB.js} +1 -1
- package/dist/components/{p-BkJ2N8cm.js → p-BX6jfJVh.js} +1 -1
- package/dist/components/{p-c9R9wdZM.js → p-Bbl-20Mv.js} +1 -1
- package/dist/components/{p-nIR_us0u.js → p-Bi-REV5s.js} +1 -1
- package/dist/components/{p-DtdLjSwM.js → p-BvDN-lhu.js} +1 -1
- package/dist/components/{p-QO3g1E0T.js → p-C3NXZJ8l.js} +1 -1
- package/dist/components/{p-CLtV90Um.js → p-CBiDiWMi.js} +1 -1
- package/dist/components/{p-H_Oufd6v.js → p-CC8cite0.js} +1 -1
- package/dist/components/{p-BSva-YCE.js → p-CLPdxk7O.js} +1 -1
- package/dist/components/{p-DBIwC6w6.js → p-Cem5FyPk.js} +1 -1
- package/dist/components/p-CigYNDIu.js +1 -0
- package/dist/components/{p-BvLFdH7U.js → p-DOqH37Pm.js} +2 -2
- package/dist/components/{p-VgIOw1rD.js → p-DXrJp_Oi.js} +1 -1
- package/dist/components/p-Dq1olnpE.js +1 -0
- package/dist/components/{p-C9rXDQ8C.js → p-DurEFI7x.js} +1 -1
- package/dist/components/p-Q_-aQ2HA.js +1 -0
- package/dist/components/p-VKmtVBdp.js +1 -0
- package/dist/components/{p-3BAAsU08.js → p-fJE54v21.js} +1 -1
- package/dist/components/privacy-modal.js +1 -1
- package/dist/components/search-results-page.js +1 -1
- package/dist/esm/ai12z-bot.entry.js +166 -53
- package/dist/esm/ai12z-chat-message.entry.js +11 -11
- package/dist/esm/chat-avatar_6.entry.js +12 -11
- package/dist/library/library.esm.js +1 -1
- package/dist/library/p-20244e8e.entry.js +1 -0
- package/dist/library/{p-8bfd66d2.entry.js → p-2d001378.entry.js} +1 -1
- package/dist/library/p-d30afe73.entry.js +1 -0
- package/dist/types/components/ai12z-bot/ai12z-bot.d.ts +13 -0
- package/dist/types/utils/liveagents/providers/salesforce.d.ts +1 -0
- package/package.json +2 -2
- package/dist/components/p-B6Z8iUC6.js +0 -1
- package/dist/components/p-BNi-pmSE.js +0 -1
- package/dist/components/p-BmUFHK-0.js +0 -1
- package/dist/components/p-C81g_cTG.js +0 -1
- package/dist/components/p-T7hfVn0q.js +0 -1
- package/dist/components/p-bq6ZwcFk.js +0 -1
- package/dist/library/p-0064ee30.entry.js +0 -1
- package/dist/library/p-d0e0337d.entry.js +0 -1
|
@@ -406,6 +406,7 @@ class SalesforceLiveAgentProvider {
|
|
|
406
406
|
return "unknown";
|
|
407
407
|
}
|
|
408
408
|
handleSessionStatusChange(event) {
|
|
409
|
+
var _a;
|
|
409
410
|
try {
|
|
410
411
|
if (!event.data)
|
|
411
412
|
return;
|
|
@@ -416,6 +417,18 @@ class SalesforceLiveAgentProvider {
|
|
|
416
417
|
if ((entryPayload === null || entryPayload === void 0 ? void 0 : entryPayload.sessionStatus) === "Active") {
|
|
417
418
|
ChatEventBus.emit("AGENT_SESSION_CREATED", true);
|
|
418
419
|
}
|
|
420
|
+
else if ((entryPayload === null || entryPayload === void 0 ? void 0 : entryPayload.sessionStatus) === "Ended") {
|
|
421
|
+
// The agent (or system) ended the session. Salesforce's authoritative
|
|
422
|
+
// CloseConversation event can lag by minutes, so end the live-agent
|
|
423
|
+
// session now — otherwise the user is stuck in "Type a message to the
|
|
424
|
+
// agent" mode with no indication the agent left. This is transfer-safe:
|
|
425
|
+
// a transfer keeps the session "Active", only a real end reports "Ended".
|
|
426
|
+
ChatEventBus.emit("CONVERSATION_CLOSED", true);
|
|
427
|
+
// Mirror the CloseConversation case: tear down the SSE connection too.
|
|
428
|
+
// Closing halts delivery of the registered named listeners, so the now-
|
|
429
|
+
// redundant (and delayed) CloseConversation event won't reopen this path.
|
|
430
|
+
(_a = this.eventSource) === null || _a === void 0 ? void 0 : _a.close();
|
|
431
|
+
}
|
|
419
432
|
}
|
|
420
433
|
catch (error) {
|
|
421
434
|
logger.error("Error handling session status change event:", error);
|
|
@@ -423,16 +436,20 @@ class SalesforceLiveAgentProvider {
|
|
|
423
436
|
}
|
|
424
437
|
}
|
|
425
438
|
listenToMessages() {
|
|
426
|
-
var _a, _b, _c;
|
|
439
|
+
var _a, _b, _c, _d;
|
|
427
440
|
logger.debug("Listening to messages from Salesforce Live Agent");
|
|
428
441
|
// this.endpointSSE = "http://localhost:5050"
|
|
429
|
-
|
|
442
|
+
// Close any existing connection before opening a new one (e.g. on resume)
|
|
443
|
+
// so we don't leak a dangling SSE stream.
|
|
444
|
+
(_a = this.eventSource) === null || _a === void 0 ? void 0 : _a.close();
|
|
445
|
+
const eventSource = new EventSource(`${this.endpointSSE}/bot/liveagent/sse?token=${(_b = this.sessionContext) === null || _b === void 0 ? void 0 : _b.accessToken}&org_id=${(_c = this.configSettings) === null || _c === void 0 ? void 0 : _c.orgId}&sse_url=${(_d = this.configSettings) === null || _d === void 0 ? void 0 : _d.instanceUrl}`, {
|
|
430
446
|
withCredentials: true,
|
|
431
447
|
});
|
|
432
448
|
if (!eventSource) {
|
|
433
449
|
logger.error("Failed to create EventSource");
|
|
434
450
|
throw new Error("Failed to create EventSource");
|
|
435
451
|
}
|
|
452
|
+
this.eventSource = eventSource;
|
|
436
453
|
eventSource.onerror = () => {
|
|
437
454
|
logger.error("❌ SSE Error: Connection lost or error occurred");
|
|
438
455
|
// Handle error, e.g., retry connection or notify user
|
|
@@ -444,7 +461,7 @@ class SalesforceLiveAgentProvider {
|
|
|
444
461
|
logger.debug("✅ SSE Connection Established");
|
|
445
462
|
// ChatEventBus.emit("liveAgentReady", undefined)
|
|
446
463
|
};
|
|
447
|
-
|
|
464
|
+
const handleSSEMessage = (event) => {
|
|
448
465
|
var _a, _b;
|
|
449
466
|
try {
|
|
450
467
|
const parsedEventData = JSON.parse(event.data);
|
|
@@ -508,6 +525,34 @@ class SalesforceLiveAgentProvider {
|
|
|
508
525
|
return;
|
|
509
526
|
}
|
|
510
527
|
};
|
|
528
|
+
// Salesforce MIAW delivers NAMED SSE events (event:CONVERSATION_*), which do
|
|
529
|
+
// NOT trigger EventSource.onmessage — that only fires for unnamed "message"
|
|
530
|
+
// events. Register the handler for each named conversation event (and keep
|
|
531
|
+
// onmessage as a fallback) so the lifecycle events are actually processed.
|
|
532
|
+
// Without this the widget never sees SessionStatusChanged/ParticipantChanged,
|
|
533
|
+
// never emits AGENT_SESSION_CREATED, times out, and tears down the session.
|
|
534
|
+
//
|
|
535
|
+
// Single source of truth: every conversationEntry.entryType the handleSSEMessage
|
|
536
|
+
// switch above handles maps 1:1 to its named CONVERSATION_* event here. Keep
|
|
537
|
+
// this map in sync with the switch — a missing entry means that event is
|
|
538
|
+
// silently never delivered (that is exactly what happened to StreamingToken /
|
|
539
|
+
// ProgressIndicator before this map existed).
|
|
540
|
+
const SF_ENTRY_EVENT_MAP = {
|
|
541
|
+
Message: "CONVERSATION_MESSAGE",
|
|
542
|
+
RoutingResult: "CONVERSATION_ROUTING_RESULT",
|
|
543
|
+
RoutingWorkResult: "CONVERSATION_ROUTING_WORK_RESULT",
|
|
544
|
+
ParticipantChanged: "CONVERSATION_PARTICIPANT_CHANGED",
|
|
545
|
+
TypingStartedIndicator: "CONVERSATION_TYPING_STARTED_INDICATOR",
|
|
546
|
+
TypingStoppedIndicator: "CONVERSATION_TYPING_STOPPED_INDICATOR",
|
|
547
|
+
DeliveryAcknowledgement: "CONVERSATION_DELIVERY_ACKNOWLEDGEMENT",
|
|
548
|
+
ReadAcknowledgement: "CONVERSATION_READ_ACKNOWLEDGEMENT",
|
|
549
|
+
CloseConversation: "CONVERSATION_CLOSE_CONVERSATION",
|
|
550
|
+
StreamingToken: "CONVERSATION_STREAMING_TOKEN",
|
|
551
|
+
ProgressIndicator: "CONVERSATION_PROGRESS_INDICATOR",
|
|
552
|
+
SessionStatusChanged: "CONVERSATION_SESSION_STATUS_CHANGED",
|
|
553
|
+
};
|
|
554
|
+
Object.values(SF_ENTRY_EVENT_MAP).forEach(type => eventSource.addEventListener(type, handleSSEMessage));
|
|
555
|
+
eventSource.onmessage = handleSSEMessage;
|
|
511
556
|
}
|
|
512
557
|
/** Interface Implementation */
|
|
513
558
|
/**
|
|
@@ -679,14 +724,17 @@ class SalesforceLiveAgentProvider {
|
|
|
679
724
|
* It sends a POST request to the Salesforce MIAW API to close the conversation.
|
|
680
725
|
*/
|
|
681
726
|
async endChat(_sessionId) {
|
|
682
|
-
var _a, _b, _c, _d, _e, _f;
|
|
727
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
683
728
|
(_a = this.availabilityAbort) === null || _a === void 0 ? void 0 : _a.abort();
|
|
729
|
+
// Tear down the SSE stream on an explicit end so the connection and its
|
|
730
|
+
// registered named listeners don't leak past the session.
|
|
731
|
+
(_b = this.eventSource) === null || _b === void 0 ? void 0 : _b.close();
|
|
684
732
|
// console.log("this.sessionContext?.conversationId", this.sessionContext?.conversationId)
|
|
685
|
-
if ((
|
|
686
|
-
const res = await fetch(`${(
|
|
733
|
+
if ((_c = this.sessionContext) === null || _c === void 0 ? void 0 : _c.conversationId) {
|
|
734
|
+
const res = await fetch(`${(_d = this.configSettings) === null || _d === void 0 ? void 0 : _d.instanceUrl}/iamessage/api/v2/conversation/${(_e = this.sessionContext) === null || _e === void 0 ? void 0 : _e.conversationId}?esDeveloperName=${(_f = this.configSettings) === null || _f === void 0 ? void 0 : _f.messagingChannelId}`, {
|
|
687
735
|
method: "DELETE",
|
|
688
736
|
headers: {
|
|
689
|
-
"Authorization": `Bearer ${(
|
|
737
|
+
"Authorization": `Bearer ${(_g = this.sessionContext) === null || _g === void 0 ? void 0 : _g.accessToken}`,
|
|
690
738
|
"Content-Type": "application/json",
|
|
691
739
|
},
|
|
692
740
|
});
|
|
@@ -1262,49 +1310,51 @@ const Ai12zBot = class {
|
|
|
1262
1310
|
// }
|
|
1263
1311
|
};
|
|
1264
1312
|
this.agentMessageCreated = (message) => {
|
|
1265
|
-
|
|
1266
|
-
// Get the last message in the messages array
|
|
1267
|
-
const lastMessage = this.messages[this.messages.length - 1];
|
|
1268
|
-
// check if last message is from user or agent
|
|
1269
|
-
if (!lastMessage.sender || lastMessage.sender === null || lastMessage.type === "system") {
|
|
1270
|
-
// Generate a new temporary message object
|
|
1271
|
-
const tempMsg = utils.generateMessage(this.conversationId);
|
|
1272
|
-
// Generate a unique ID for the new message
|
|
1273
|
-
this.currentDomId = `chatbot-${utils.generateUUID()}`;
|
|
1274
|
-
tempMsg.id = this.currentDomId;
|
|
1275
|
-
tempMsg.isLoading = false;
|
|
1276
|
-
// Set sender to 'agent' for live agent messages
|
|
1277
|
-
this.messages = [...this.messages, tempMsg];
|
|
1278
|
-
}
|
|
1279
|
-
else {
|
|
1280
|
-
// If the last message is from the user or already has a sender, update its ID
|
|
1281
|
-
const { id, idChanged } = parseHelper.ensureMessageId(this.currentDomId, this.messages, "chatbot");
|
|
1282
|
-
this.currentDomId = id;
|
|
1283
|
-
if (idChanged)
|
|
1284
|
-
this.messages = [...this.messages];
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1313
|
+
var _a;
|
|
1287
1314
|
const retMessage = this.liveAgentEventHandler.handleAgentMessage(message);
|
|
1288
|
-
if (retMessage)
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1315
|
+
if (!retMessage)
|
|
1316
|
+
return;
|
|
1317
|
+
this.announce("New message received from live agent");
|
|
1318
|
+
// Render agent messages declaratively through component state (the same way
|
|
1319
|
+
// agentEventHandler renders the "agent joined" banner) instead of writing
|
|
1320
|
+
// into a DOM bubble that Stencil may not have rendered yet. The old code
|
|
1321
|
+
// added an empty bubble to state then, one requestAnimationFrame later,
|
|
1322
|
+
// queried `#currentDomId` in the shadow DOM to write the text — but Stencil's
|
|
1323
|
+
// re-render is async, so for the first agent message(s) the element didn't
|
|
1324
|
+
// exist yet, the querySelector returned null, and the text was dropped
|
|
1325
|
+
// entirely (never stored in state). It only "worked after" a user reply
|
|
1326
|
+
// forced a re-render. Building the message in state removes that race.
|
|
1327
|
+
const converter = new processCarouselData.showdown.Converter();
|
|
1328
|
+
const finalHtml = converter.makeHtml(retMessage);
|
|
1329
|
+
const entry = Array.isArray(message) ? message[0] : message;
|
|
1330
|
+
// Behavior change vs. pre-#2493: each agent message now renders as its own
|
|
1331
|
+
// bubble. The previous code concatenated consecutive agent messages that
|
|
1332
|
+
// arrived before a user reply into one growing bubble (via a persistent
|
|
1333
|
+
// currentDomId + string concat). One-bubble-per-message is intentional here —
|
|
1334
|
+
// it matches how bot/user messages already render and avoids the DOM-append
|
|
1335
|
+
// race this PR fixes. To restore merged bubbles, append to the last agent
|
|
1336
|
+
// message's `text` in state (when the last message is the same sender and no
|
|
1337
|
+
// user message interrupted) instead of always pushing a new entry.
|
|
1338
|
+
const agentMsg = {
|
|
1339
|
+
id: `chatbot-${utils.generateUUID()}`,
|
|
1340
|
+
text: finalHtml,
|
|
1341
|
+
isUser: false,
|
|
1342
|
+
isLoading: false,
|
|
1343
|
+
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
|
|
1344
|
+
images: [],
|
|
1345
|
+
conversationId: this.conversationId,
|
|
1346
|
+
formModel: {},
|
|
1347
|
+
surveyDomId: "",
|
|
1348
|
+
thumbsId: `${utils.generateUUID()}`,
|
|
1349
|
+
showIcon: true,
|
|
1350
|
+
hideThumbsUpandDown: true,
|
|
1351
|
+
insightId: null,
|
|
1352
|
+
sender: (_a = entry === null || entry === void 0 ? void 0 : entry.sender) !== null && _a !== void 0 ? _a : { role: "agent", displayName: "Agent" },
|
|
1353
|
+
};
|
|
1354
|
+
this.messages = [...this.messages, agentMsg];
|
|
1355
|
+
this.currentDomId = "";
|
|
1356
|
+
this.updateBotState();
|
|
1357
|
+
this.scheduleAutoScroll();
|
|
1308
1358
|
};
|
|
1309
1359
|
this.addEventMessage = (_message) => {
|
|
1310
1360
|
const agentEventMessages = this.liveAgentEventHandler.addAgentEventMessage([
|
|
@@ -1356,10 +1406,42 @@ const Ai12zBot = class {
|
|
|
1356
1406
|
this.announce("Live agent connection failed");
|
|
1357
1407
|
};
|
|
1358
1408
|
this.handleAgentConversationEnded = () => {
|
|
1359
|
-
// Only
|
|
1360
|
-
//
|
|
1409
|
+
// Only notify if an agent was actually connected; suppress when the session
|
|
1410
|
+
// timed out with no agent available.
|
|
1411
|
+
//
|
|
1412
|
+
// This can be invoked more than once — the sessionStatus="Ended" path and the
|
|
1413
|
+
// delayed CloseConversation both emit CONVERSATION_CLOSED. That double-fire is
|
|
1414
|
+
// handled by the isLiveAgent gate below, NOT by alreadyNotified: isLiveAgent is
|
|
1415
|
+
// set false synchronously in this same call, so any later invocation skips the
|
|
1416
|
+
// whole block (JS is single-threaded; no await runs in between).
|
|
1417
|
+
//
|
|
1418
|
+
// alreadyNotified guards a different case: when the agent leaving already
|
|
1419
|
+
// produced a "<name> has left the chat" participant banner, don't stack a
|
|
1420
|
+
// near-duplicate "The live agent has left the conversation." notice on top.
|
|
1361
1421
|
if (this.isLiveAgent) {
|
|
1362
|
-
this.
|
|
1422
|
+
const last = this.messages[this.messages.length - 1];
|
|
1423
|
+
const alreadyNotified = (last === null || last === void 0 ? void 0 : last.type) === "system" && typeof (last === null || last === void 0 ? void 0 : last.text) === "string" && last.text.toLowerCase().includes("left");
|
|
1424
|
+
if (!alreadyNotified) {
|
|
1425
|
+
// Render the banner through state (like agentEventHandler) rather than
|
|
1426
|
+
// the DOM-query addEventMessage, which silently no-ops when the target
|
|
1427
|
+
// bubble isn't rendered — that's why the "ended" notice never showed.
|
|
1428
|
+
this.messages = [
|
|
1429
|
+
...this.messages,
|
|
1430
|
+
{
|
|
1431
|
+
id: `system-${utils.generateUUID()}`,
|
|
1432
|
+
text: "The live agent has left the conversation.",
|
|
1433
|
+
type: "system",
|
|
1434
|
+
isUser: false,
|
|
1435
|
+
isLoading: false,
|
|
1436
|
+
timestamp: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
|
|
1437
|
+
images: [],
|
|
1438
|
+
conversationId: this.conversationId,
|
|
1439
|
+
formModel: {},
|
|
1440
|
+
surveyDomId: "",
|
|
1441
|
+
sender: null,
|
|
1442
|
+
},
|
|
1443
|
+
];
|
|
1444
|
+
}
|
|
1363
1445
|
this.announce("Live agent chat ended");
|
|
1364
1446
|
}
|
|
1365
1447
|
this.isLiveAgent = false;
|
|
@@ -1367,7 +1449,10 @@ const Ai12zBot = class {
|
|
|
1367
1449
|
this.liveAgentConversationId = "";
|
|
1368
1450
|
this.isTypingIndicatorVisible = false;
|
|
1369
1451
|
this.liveAgentButtonText = "Talk to a Live Agent";
|
|
1452
|
+
this.currentDomId = "";
|
|
1370
1453
|
this.clearEvents();
|
|
1454
|
+
this.updateBotState();
|
|
1455
|
+
this.scheduleAutoScroll();
|
|
1371
1456
|
};
|
|
1372
1457
|
this.agentEventHandler = event => {
|
|
1373
1458
|
this.isTypingIndicatorVisible = false;
|
|
@@ -1394,6 +1479,10 @@ const Ai12zBot = class {
|
|
|
1394
1479
|
this.inputEl.value = "";
|
|
1395
1480
|
}
|
|
1396
1481
|
this.currentDomId = "";
|
|
1482
|
+
// Scroll the new banner (e.g. "… has joined the chat") into view — but only
|
|
1483
|
+
// when the user is already near the bottom (see scheduleAutoScroll), so we
|
|
1484
|
+
// don't yank them down mid-scroll during a join/leave burst.
|
|
1485
|
+
this.scheduleAutoScroll();
|
|
1397
1486
|
}
|
|
1398
1487
|
};
|
|
1399
1488
|
this.handleAgentSessionCreated = () => {
|
|
@@ -2212,6 +2301,7 @@ const Ai12zBot = class {
|
|
|
2212
2301
|
controlType: data.controlType,
|
|
2213
2302
|
thumbsId: `${utils.generateUUID()}`,
|
|
2214
2303
|
showIcon: !data.controlType && !this.surveyDomId,
|
|
2304
|
+
hideThumbsUpandDown: this.isLiveAgent ? true : false,
|
|
2215
2305
|
insightId: (_f = data === null || data === void 0 ? void 0 : data.insightId) !== null && _f !== void 0 ? _f : null,
|
|
2216
2306
|
sender: (_g = data === null || data === void 0 ? void 0 : data.sender) !== null && _g !== void 0 ? _g : null,
|
|
2217
2307
|
itemComponent: data,
|
|
@@ -2533,6 +2623,29 @@ const Ai12zBot = class {
|
|
|
2533
2623
|
this.unreadCount = 0;
|
|
2534
2624
|
}
|
|
2535
2625
|
}
|
|
2626
|
+
/** True when the chat is scrolled to (or within `threshold`px of) the bottom. */
|
|
2627
|
+
isNearBottom(threshold = 150) {
|
|
2628
|
+
var _a;
|
|
2629
|
+
const container = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(".chat-body");
|
|
2630
|
+
if (!container)
|
|
2631
|
+
return true;
|
|
2632
|
+
return container.scrollHeight - container.scrollTop - container.clientHeight <= threshold;
|
|
2633
|
+
}
|
|
2634
|
+
/**
|
|
2635
|
+
* Auto-scroll for the live-agent path (agent messages + join/leave banners).
|
|
2636
|
+
* Unlike scrollToBottom(), this (1) only scrolls when the user is already near
|
|
2637
|
+
* the bottom, so a burst never yanks the view down while they read history, and
|
|
2638
|
+
* (2) coalesces rapid messages into a single scroll via a short debounce.
|
|
2639
|
+
* The near-bottom check is captured now, before Stencil re-renders and grows the
|
|
2640
|
+
* container — if they weren't near the bottom, their position is left alone.
|
|
2641
|
+
*/
|
|
2642
|
+
scheduleAutoScroll() {
|
|
2643
|
+
if (!this.isNearBottom())
|
|
2644
|
+
return;
|
|
2645
|
+
if (this.autoScrollTimer)
|
|
2646
|
+
clearTimeout(this.autoScrollTimer);
|
|
2647
|
+
this.autoScrollTimer = setTimeout(() => this.scrollToBottom(), 60);
|
|
2648
|
+
}
|
|
2536
2649
|
checkLiveAgentMode() {
|
|
2537
2650
|
var _a, _b, _c, _d;
|
|
2538
2651
|
const isLiveAgentConfigured = ((_b = (_a = this.botSettings) === null || _a === void 0 ? void 0 : _a.liveagent) === null || _b === void 0 ? void 0 : _b.providers) && Object.keys((_d = (_c = this.botSettings) === null || _c === void 0 ? void 0 : _c.liveagent) === null || _d === void 0 ? void 0 : _d.providers).length > 0;
|
|
@@ -55,18 +55,10 @@ const Ai12zChatMessage = class {
|
|
|
55
55
|
botHelpers.initializeScript(event.detail.id, this.mainObject);
|
|
56
56
|
}
|
|
57
57
|
componentWillLoad() {
|
|
58
|
-
var _a, _b;
|
|
59
58
|
this.loadScriptsSequentially();
|
|
60
|
-
// Adopt customCSS in this shadow root using the shared CSSStyleSheet
|
|
61
|
-
// already constructed by the parent knowledge-box (zero extra fetches).
|
|
62
|
-
if ((_a = this.kbSettings) === null || _a === void 0 ? void 0 : _a.customCSS) {
|
|
63
|
-
styleSheetRegistry.adoptStyleSheet(this.kbSettings.customCSS, this.el.shadowRoot);
|
|
64
|
-
}
|
|
65
|
-
if ((_b = this.kbSettings) === null || _b === void 0 ? void 0 : _b.customJS) {
|
|
66
|
-
styleSheetRegistry.loadScriptOnce(this.kbSettings.customJS, this.el.shadowRoot);
|
|
67
|
-
}
|
|
68
59
|
}
|
|
69
60
|
componentDidLoad() {
|
|
61
|
+
var _a, _b;
|
|
70
62
|
// Initialise the ai12z global exactly once; never overwrite an existing value.
|
|
71
63
|
if (!window["ai12z"]) {
|
|
72
64
|
window["ai12z"] = {};
|
|
@@ -75,6 +67,14 @@ const Ai12zChatMessage = class {
|
|
|
75
67
|
ai12zHeading.text = `var ai12zChat = window["ai12z"] = {}`;
|
|
76
68
|
this.el.shadowRoot.appendChild(ai12zHeading);
|
|
77
69
|
this.checkOverflow();
|
|
70
|
+
// Adopt customCSS in this shadow root using the shared CSSStyleSheet
|
|
71
|
+
// already constructed by the parent knowledge-box (zero extra fetches).
|
|
72
|
+
if ((_a = this.kbSettings) === null || _a === void 0 ? void 0 : _a.customCSS) {
|
|
73
|
+
styleSheetRegistry.adoptStyleSheet(this.kbSettings.customCSS, this.el.shadowRoot);
|
|
74
|
+
}
|
|
75
|
+
if ((_b = this.kbSettings) === null || _b === void 0 ? void 0 : _b.customJS) {
|
|
76
|
+
styleSheetRegistry.loadScriptOnce(this.kbSettings.customJS, this.el.shadowRoot);
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
79
|
async loadScriptsSequentially() {
|
|
80
80
|
try {
|
|
@@ -156,9 +156,9 @@ const Ai12zChatMessage = class {
|
|
|
156
156
|
render() {
|
|
157
157
|
var _a, _b, _c, _d;
|
|
158
158
|
const lineClamp = (_b = (_a = this.kbSettings) === null || _a === void 0 ? void 0 : _a.numberOfLines) !== null && _b !== void 0 ? _b : 10;
|
|
159
|
-
return (index.h("div", { key: '
|
|
159
|
+
return (index.h("div", { key: '2d24739583f2f73daa28590c6c121531cf6ab4ce', class: "chat-message" }, index.h("div", { key: '9e8ca0a62a0de746f367164ff51ea9b9a22e93a0', ref: (el) => this.messageRef = el, class: { 'message-text': true, "custom-line-clamp": !this.isExpanded && !this.isCollapsing && this.showButton }, style: {
|
|
160
160
|
"--line-clamp": `${lineClamp}`,
|
|
161
|
-
}, innerHTML: this.text, onClick: this.showButton ? this.toggleExpand : undefined }), !this.isExpanded && this.showButton && this.canExpand && index.h("div", { key: '
|
|
161
|
+
}, innerHTML: this.text, onClick: this.showButton ? this.toggleExpand : undefined }), !this.isExpanded && this.showButton && this.canExpand && index.h("div", { key: '12f386a03fc84f97d2e585ea21cf4f8d31964c34', class: "fade-overlay" }), this.showButton && this.canExpand && index.h("button", { key: '1633be8cd35334eae64f75d7ce5fd87b30054849', class: "show-more-btn", onClick: this.toggleExpand }, this.isExpanded ? (((_c = this.kbSettings) === null || _c === void 0 ? void 0 : _c.showLessButtonLabel) || "Show less") : (((_d = this.kbSettings) === null || _d === void 0 ? void 0 : _d.showMoreButtonLabel) || "Show more"), this.isExpanded ? index.h("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("polyline", { points: "6 9 12 15 18 9" })) : index.h("svg", { width: "1em", height: "1em", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, index.h("polyline", { points: "18 15 12 9 6 15" })))));
|
|
162
162
|
}
|
|
163
163
|
get el() { return index.getElement(this); }
|
|
164
164
|
static get watchers() { return {
|
|
@@ -228,16 +228,17 @@ const InteractionButtons = class {
|
|
|
228
228
|
this.audioElement = null; // Dereference the object
|
|
229
229
|
}
|
|
230
230
|
// this.isPlayed = false
|
|
231
|
-
} }, index.h("svg", { key: '7917d77a2ae82e41ecca58761b24bdd40ed901f8', width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", class: "icon-md-heavy" }, index.h("path", { key: '709788d90a11ef6e33c4b504b58f5daab0d91d6d', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12ZM9.5 8.5C8.94772 8.5 8.5 8.94772 8.5 9.5V14.5C8.5 15.0523 8.94772 15.5 9.5 15.5H14.5C15.0523 15.5 15.5 15.0523 15.5 14.5V9.5C15.5 8.94772 15.0523 8.5 14.5 8.5H9.5Z", fill: "currentColor" })))), !this.isPlayed && (index.h("button", { key: '007f1ba6c2f17d809dafb460e49e6d58cac83b2f', class: "copy-btn", tabindex: "0", onClick: () => this.speakText(utils.removeHtmlTags(this.message.text)), "aria-label": "Speak Text" }, index.h("svg", { key: 'ff62913d5c73c19b3b1bdf5b37057cc9e022fda4', class: "w-6 h-6", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: '8186495b322cd06040e9ea23e50d2c9ea50bebd4', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M11 4.9099C11 4.47485 10.4828 4.24734 10.1621 4.54132L6.67572 7.7372C6.49129 7.90626 6.25019 8.00005 6 8.00005H4C3.44772 8.00005 3 8.44776 3 9.00005V15C3 15.5523 3.44772 16 4 16H6C6.25019 16 6.49129 16.0938 6.67572 16.2629L10.1621 19.4588C10.4828 19.7527 11 19.5252 11 19.0902V4.9099ZM8.81069 3.06701C10.4142 1.59714 13 2.73463 13 4.9099V19.0902C13 21.2655 10.4142 22.403 8.81069 20.9331L5.61102 18H4C2.34315 18 1 16.6569 1 15V9.00005C1 7.34319 2.34315 6.00005 4 6.00005H5.61102L8.81069 3.06701ZM20.3166 6.35665C20.8019 6.09313 21.409 6.27296 21.6725 6.75833C22.5191 8.3176 22.9996 10.1042 22.9996 12.0001C22.9996 13.8507 22.5418 15.5974 21.7323 17.1302C21.4744 17.6185 20.8695 17.8054 20.3811 17.5475C19.8927 17.2896 19.7059 16.6846 19.9638 16.1962C20.6249 14.9444 20.9996 13.5175 20.9996 12.0001C20.9996 10.4458 20.6064 8.98627 19.9149 7.71262C19.6514 7.22726 19.8312 6.62017 20.3166 6.35665ZM15.7994 7.90049C16.241 7.5688 16.8679 7.65789 17.1995 8.09947C18.0156 9.18593 18.4996 10.5379 18.4996 12.0001C18.4996 13.3127 18.1094 14.5372 17.4385 15.5604C17.1357 16.0222 16.5158 16.1511 16.0539 15.8483C15.5921 15.5455 15.4632 14.9255 15.766 14.4637C16.2298 13.7564 16.4996 12.9113 16.4996 12.0001C16.4996 10.9859 16.1653 10.0526 15.6004 9.30063C15.2687 8.85905 15.3578 8.23218 15.7994 7.90049Z", fill: "currentColor" })))),
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
231
|
+
} }, index.h("svg", { key: '7917d77a2ae82e41ecca58761b24bdd40ed901f8', width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", class: "icon-md-heavy" }, index.h("path", { key: '709788d90a11ef6e33c4b504b58f5daab0d91d6d', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12ZM9.5 8.5C8.94772 8.5 8.5 8.94772 8.5 9.5V14.5C8.5 15.0523 8.94772 15.5 9.5 15.5H14.5C15.0523 15.5 15.5 15.0523 15.5 14.5V9.5C15.5 8.94772 15.0523 8.5 14.5 8.5H9.5Z", fill: "currentColor" })))), !this.isPlayed && (index.h("button", { key: '007f1ba6c2f17d809dafb460e49e6d58cac83b2f', class: "copy-btn", tabindex: "0", onClick: () => this.speakText(utils.removeHtmlTags(this.message.text)), "aria-label": "Speak Text" }, index.h("svg", { key: 'ff62913d5c73c19b3b1bdf5b37057cc9e022fda4', class: "w-6 h-6", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: '8186495b322cd06040e9ea23e50d2c9ea50bebd4', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M11 4.9099C11 4.47485 10.4828 4.24734 10.1621 4.54132L6.67572 7.7372C6.49129 7.90626 6.25019 8.00005 6 8.00005H4C3.44772 8.00005 3 8.44776 3 9.00005V15C3 15.5523 3.44772 16 4 16H6C6.25019 16 6.49129 16.0938 6.67572 16.2629L10.1621 19.4588C10.4828 19.7527 11 19.5252 11 19.0902V4.9099ZM8.81069 3.06701C10.4142 1.59714 13 2.73463 13 4.9099V19.0902C13 21.2655 10.4142 22.403 8.81069 20.9331L5.61102 18H4C2.34315 18 1 16.6569 1 15V9.00005C1 7.34319 2.34315 6.00005 4 6.00005H5.61102L8.81069 3.06701ZM20.3166 6.35665C20.8019 6.09313 21.409 6.27296 21.6725 6.75833C22.5191 8.3176 22.9996 10.1042 22.9996 12.0001C22.9996 13.8507 22.5418 15.5974 21.7323 17.1302C21.4744 17.6185 20.8695 17.8054 20.3811 17.5475C19.8927 17.2896 19.7059 16.6846 19.9638 16.1962C20.6249 14.9444 20.9996 13.5175 20.9996 12.0001C20.9996 10.4458 20.6064 8.98627 19.9149 7.71262C19.6514 7.22726 19.8312 6.62017 20.3166 6.35665ZM15.7994 7.90049C16.241 7.5688 16.8679 7.65789 17.1995 8.09947C18.0156 9.18593 18.4996 10.5379 18.4996 12.0001C18.4996 13.3127 18.1094 14.5372 17.4385 15.5604C17.1357 16.0222 16.5158 16.1511 16.0539 15.8483C15.5921 15.5455 15.4632 14.9255 15.766 14.4637C16.2298 13.7564 16.4996 12.9113 16.4996 12.0001C16.4996 10.9859 16.1653 10.0526 15.6004 9.30063C15.2687 8.85905 15.3578 8.23218 15.7994 7.90049Z", fill: "currentColor" })))), !this.message.hideThumbsUpandDown &&
|
|
232
|
+
index.h("button", { key: '6f5dff07e526e2cdc47bc44b2f58a0f89fd53cce', id: `thumbsUp_${this.message.thumbsId}`, tabindex: "0", onClick: () => {
|
|
233
|
+
var _a;
|
|
234
|
+
thumbsUp(this.message.thumbsId, this.message.insightId, this.el, {
|
|
235
|
+
dataKey: this.dataKey,
|
|
236
|
+
dataMode: this.dataMode,
|
|
237
|
+
conversationId: this.conversationId,
|
|
238
|
+
projectId: this.projectId,
|
|
239
|
+
questionText: ((_a = this.chatArray[this.currentIndex - 1]) === null || _a === void 0 ? void 0 : _a.text) || "",
|
|
240
|
+
});
|
|
241
|
+
}, class: "chat-thumbs-up", "aria-label": "Thumbs Up" }, index.h("svg", { key: '2cd7fdb5e05b9b74faeebe6eed0bca21e646f69a', xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", class: "w-6 h-6" }, index.h("path", { key: '3804be8337ef4725d77d371c6236d443355223e7', "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6.633 10.25c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 0 1 2.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 0 0 .322-1.672V2.75a.75.75 0 0 1 .75-.75 2.25 2.25 0 0 1 2.25 2.25c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282m0 0h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 0 1-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 0 0-1.423-.23H5.904m10.598-9.75H14.25M5.904 18.5c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 0 1-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 9.953 4.167 9.5 5 9.5h1.053c.472 0 .745.556.5.96a8.958 8.958 0 0 0-1.302 4.665c0 1.194.232 2.333.654 3.375Z" }))), !this.message.hideThumbsUpandDown && index.h("button", { key: '6698fb5391a1fa1636461d622cbeba9b1f240a3c', id: `thumbsDown_${this.message.thumbsId}`, onClick: () => {
|
|
241
242
|
var _a;
|
|
242
243
|
return thumbsDown(this.message.thumbsId, this.message.insightId, this.el, {
|
|
243
244
|
dataKey: this.dataKey,
|
|
@@ -246,7 +247,7 @@ const InteractionButtons = class {
|
|
|
246
247
|
projectId: this.projectId,
|
|
247
248
|
questionText: ((_a = this.chatArray[this.currentIndex - 1]) === null || _a === void 0 ? void 0 : _a.text) || "",
|
|
248
249
|
});
|
|
249
|
-
}, class: "chat-thumbs-up", "aria-label": "Thumbs Down" }, index.h("svg", { key: '
|
|
250
|
+
}, class: "chat-thumbs-up", "aria-label": "Thumbs Down" }, index.h("svg", { key: 'c9a9095c0d387c67c649d0ff66e0554d27ac25fd', xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", class: "w-6 h-6" }, index.h("path", { key: 'e7c3f597faf0cb79d2c439ac5b3cd835a681d71e', "stroke-linecap": "round", "stroke-linejoin": "round", d: "M7.498 15.25H4.372c-1.026 0-1.945-.694-2.054-1.715a12.137 12.137 0 0 1-.068-1.285c0-2.848.992-5.464 2.649-7.521C5.287 4.247 5.886 4 6.504 4h4.016a4.5 4.5 0 0 1 1.423.23l3.114 1.04a4.5 4.5 0 0 0 1.423.23h1.294M7.498 15.25c.618 0 .991.724.725 1.282A7.471 7.471 0 0 0 7.5 19.75 2.25 2.25 0 0 0 9.75 22a.75.75 0 0 0 .75-.75v-.633c0-.573.11-1.14.322-1.672.304-.76.93-1.33 1.653-1.715a9.04 9.04 0 0 0 2.86-2.4c.498-.634 1.226-1.08 2.032-1.08h.384m-10.253 1.5H9.7m8.075-9.75c.01.05.027.1.05.148.593 1.2.925 2.55.925 3.977 0 1.487-.36 2.89-.999 4.125m.023-8.25c-.076-.365.183-.75.575-.75h.908c.889 0 1.713.518 1.972 1.368.339 1.11.521 2.287.521 3.507 0 1.553-.295 3.036-.831 4.398-.306.774-1.086 1.227-1.918 1.227h-1.053c-.472 0-.745-.556-.5-.96a8.95 8.95 0 0 0 .303-.54" }))), index.h("button", { key: '04a0db0b288f173529d8cb19ccc09c50847ec8aa', class: "copy-btn", onClick: () => this.copyToClipboard(this.message.text), "aria-label": "Copy Text" }, !this.copied && (index.h("svg", { key: '3f69ba67f017ed628c01b765d0fde102a0219edb', class: "w-6 h-6", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: 'b721b1aff45c6f7452e77ea9eb4a86280b41273b', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M7 5C7 3.34315 8.34315 2 10 2H19C20.6569 2 22 3.34315 22 5V14C22 15.6569 20.6569 17 19 17H17V19C17 20.6569 15.6569 22 14 22H5C3.34315 22 2 20.6569 2 19V10C2 8.34315 3.34315 7 5 7H7V5ZM9 7H14C15.6569 7 17 8.34315 17 10V15H19C19.5523 15 20 14.5523 20 14V5C20 4.44772 19.5523 4 19 4H10C9.44772 4 9 4.44772 9 5V7ZM5 9C4.44772 9 4 9.44772 4 10V19C4 19.5523 4.44772 20 5 20H14C14.5523 20 15 19.5523 15 19V10C15 9.44772 14.5523 9 14 9H5Z", fill: "currentColor" }))), this.copied && (index.h("svg", { key: '11c6d49c31049913fe6533549abe5255cc87c27b', viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", class: "w-6 h-6" }, index.h("path", { key: '35a4885c4110d49320643a908f83e4e7138cdf0f', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M19.8198 6.19526C20.0601 6.45561 20.0601 6.87772 19.8198 7.13807L9.9736 17.8047C9.73328 18.0651 9.34364 18.0651 9.10332 17.8047L4.18024 12.4714C3.93992 12.2111 3.93992 11.7889 4.18024 11.5286C4.42056 11.2682 4.8102 11.2682 5.05053 11.5286L9.53846 16.3905L18.9495 6.19526C19.1898 5.93491 19.5794 5.93491 19.8198 6.19526Z", fill: "currentColor" })))), index.h("button", { key: 'ed8932a55da4f4bd3aaa281390217400ae9be59b', class: "copy-btn", "aria-label": "Send Email" }, index.h("a", { key: '267d94e1d9850464820978266a97b52a07aabb7f', href: `mailto:${email}?subject=${encodeURIComponent((_a = this.chatArray[this.currentIndex - 1]) === null || _a === void 0 ? void 0 : _a.text)}&body=${encodeURIComponent(utils.removeHtmlTags(this.message.text))}`, target: "_blank" }, index.h("svg", { key: '2bb1ac9deaf577086dbbfbbf981600ff9031c46c', viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: "currentColor", "stroke-width": "0.3", class: "w-6 h-6" }, index.h("path", { key: '062336e4dac5379b18271bc3411d4ff2c0665895', "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M3.75 5.25L3 6V18L3.75 18.75H20.25L21 18V6L20.25 5.25H3.75ZM4.5 7.6955V17.25H19.5V7.69525L11.9999 14.5136L4.5 7.6955ZM18.3099 6.75H5.68986L11.9999 12.4864L18.3099 6.75Z", fill: "currentColor" }), " ")))));
|
|
250
251
|
}
|
|
251
252
|
get el() { return index.getElement(this); }
|
|
252
253
|
};
|