ai12z 3.17.2 → 3.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ import { LiveAgentAuthExpiredError } from "../../utils/liveagents/liveagent-type
41
41
  import { initBeacon, setConversationId, buildBeacon } from "../../utils/beacon";
42
42
  import { bodyScrollLock } from "../../utils/bodyScrollLock";
43
43
  const logger = new Logger("Ai12zBot");
44
+ const STREAM_END_TIMEOUT_MS = 30000;
44
45
  export class Ai12zBot {
45
46
  constructor() {
46
47
  this.cdnPath = "https://cdn.ai12z.net/assets/bot";
@@ -113,6 +114,7 @@ export class Ai12zBot {
113
114
  this.liveAgentListenersRegistered = false;
114
115
  this.shortcuts = DEFAULT_SHORTCUTS;
115
116
  this.announceMessage = ""; // For accessibility announcements
117
+ this.isSending = false;
116
118
  this.messageRefs = [];
117
119
  // Replace your existing handlePaste method with this enhanced version
118
120
  this.handlePaste = (event) => {
@@ -225,12 +227,30 @@ export class Ai12zBot {
225
227
  }
226
228
  };
227
229
  this.handleSend = async (eleValue, options = {}) => {
228
- var _a, _b;
229
- const { isHide = false, isLiveChatEnded = false } = options;
230
- const resolvedQuery = (typeof this.query === "string" && this.query.trim()) || eleValue.trim() || ((_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.value.trim()) || "";
230
+ var _a, _b, _c;
231
+ const { isHide = false, isLiveChatEnded = false, bypassSendGuard = false } = options;
232
+ // Acquire the lock before any await.
233
+ if ((this.isSending || this.isStreaming) && !bypassSendGuard) {
234
+ this.query = "";
235
+ return false;
236
+ }
237
+ this.isSending = true;
238
+ const queryText = typeof this.query === "string" ? this.query.trim() : "";
239
+ const displayText = typeof eleValue === "string" ? eleValue.trim() : "";
240
+ const inputText = ((_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.value.trim()) || "";
241
+ const resolvedQuery = queryText || displayText || inputText;
242
+ const resolvedDisplayText = displayText || (!isHide ? resolvedQuery : "");
231
243
  if (!resolvedQuery && this.imagesBase64List.length === 0) {
232
244
  this.showEmptyMessageValidation();
233
- return;
245
+ this.query = "";
246
+ this.isSending = false;
247
+ return false;
248
+ }
249
+ if (!isHide && !resolvedDisplayText && this.imagesBase64List.length === 0) {
250
+ this.query = "";
251
+ this.isSending = false;
252
+ this.showEmptyMessageValidation();
253
+ return false;
234
254
  }
235
255
  this.emptyMessageError = false;
236
256
  this.surveyDomId = "";
@@ -239,7 +259,7 @@ export class Ai12zBot {
239
259
  this.questionCounter = this.questionCounter + 1;
240
260
  localStorage.setItem(`ai12z-bot-data`, JSON.stringify({ qCounter: this.questionCounter }));
241
261
  }
242
- const inputValue = eleValue;
262
+ const inputValue = resolvedDisplayText;
243
263
  if (this.inputEl) {
244
264
  this.inputEl.value = inputValue;
245
265
  }
@@ -249,11 +269,19 @@ export class Ai12zBot {
249
269
  if (this.showWelcomeScreen && this.botSettings.botVersion === "v1") {
250
270
  this.showWelcomeScreen = false;
251
271
  }
252
- if (this.messages.length === 0) {
253
- await this.socketConnection();
272
+ try {
273
+ if (this.messages.length === 0 || !((_b = this.socket) === null || _b === void 0 ? void 0 : _b.connected)) {
274
+ await this.socketConnection();
275
+ }
276
+ else if (!this.socket || !this.socket.connected) {
277
+ await this.socketConnection();
278
+ }
254
279
  }
255
- else if (!this.socket || !this.socket.connected) {
256
- await this.socketConnection();
280
+ catch (error) {
281
+ console.error("Error in handleSend:", error);
282
+ this.query = "";
283
+ this.isSending = false;
284
+ return false;
257
285
  }
258
286
  // if (inputValue.trim()) {
259
287
  const now = new Date();
@@ -300,6 +328,9 @@ export class Ai12zBot {
300
328
  if (this.botSettings.maxQuestion > 0 && this.questionCounter > this.botSettings.maxQuestion && !this.isLiveAgent && !isLiveChatEnded) {
301
329
  // console.log("Max question limit reached")
302
330
  this.inputEl.value = "";
331
+ this.query = "";
332
+ this.releaseSendLock();
333
+ return false;
303
334
  }
304
335
  else {
305
336
  this.currentDomId = "";
@@ -311,16 +342,18 @@ export class Ai12zBot {
311
342
  this.inputEl.value = "";
312
343
  }
313
344
  this.query = "";
345
+ this.isSending = false;
314
346
  }
315
347
  else {
316
348
  this.checkLiveAgentMode();
317
349
  this.isStreaming = true;
318
350
  this.ignoreChunks = false;
319
- this.invokeSocket();
351
+ this.resetStreamEndWatchdog();
352
+ this.invokeSocket(resolvedQuery);
320
353
  }
321
354
  }
322
355
  // this.invokeSocket()
323
- const parent = (_b = this.el.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("#previewContainer");
356
+ const parent = (_c = this.el.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector("#previewContainer");
324
357
  if (parent) {
325
358
  parent.innerHTML = "";
326
359
  }
@@ -328,6 +361,7 @@ export class Ai12zBot {
328
361
  this.rowCount = 1;
329
362
  this.showSubmit = false;
330
363
  // }
364
+ return true;
331
365
  };
332
366
  this.agentMessageCreated = (message) => {
333
367
  var _a;
@@ -672,6 +706,7 @@ export class Ai12zBot {
672
706
  this.showWelcomeScreen = true;
673
707
  this.showHistory = false;
674
708
  this.isOpened = true;
709
+ this.releaseSendLock();
675
710
  // Focus input if available
676
711
  setTimeout(() => {
677
712
  var _a;
@@ -719,9 +754,6 @@ export class Ai12zBot {
719
754
  }
720
755
  async sendMessage(message, displayText, options) {
721
756
  this.query = message;
722
- // if (!this.isChatOpen) {
723
- // this.isChatOpen = true
724
- // }
725
757
  this.handleSend(displayText !== null && displayText !== void 0 ? displayText : message, options);
726
758
  }
727
759
  async sendQuery(query) {
@@ -730,9 +762,6 @@ export class Ai12zBot {
730
762
  }
731
763
  async sendJSON(jsonData, displayText) {
732
764
  this.query = JSON.stringify(jsonData);
733
- // if (!this.isChatOpen) {
734
- // this.isChatOpen = true
735
- // }
736
765
  this.handleSend(displayText);
737
766
  }
738
767
  async openBot(expanded = false) {
@@ -862,6 +891,28 @@ export class Ai12zBot {
862
891
  this.clearEvents();
863
892
  }
864
893
  }
894
+ releaseSendLock() {
895
+ this.clearStreamEndWatchdog();
896
+ this.isStreaming = false;
897
+ this.isSending = false;
898
+ }
899
+ clearStreamEndWatchdog() {
900
+ if (this.streamEndWatchdog) {
901
+ clearTimeout(this.streamEndWatchdog);
902
+ this.streamEndWatchdog = undefined;
903
+ }
904
+ }
905
+ resetStreamEndWatchdog() {
906
+ this.clearStreamEndWatchdog();
907
+ this.streamEndWatchdog = setTimeout(() => {
908
+ this.streamEndWatchdog = undefined;
909
+ if (!this.isStreaming) {
910
+ return;
911
+ }
912
+ console.error("Socket response timed out before completion");
913
+ this.failTurn("Something went wrong. Please try again.");
914
+ }, STREAM_END_TIMEOUT_MS);
915
+ }
865
916
  componentDidLoad() {
866
917
  var _a;
867
918
  setBotElement(this.el); // register globally
@@ -944,6 +995,7 @@ export class Ai12zBot {
944
995
  // fire scrollToBottom() against a torn-down component.
945
996
  if (this.autoScrollTimer)
946
997
  clearTimeout(this.autoScrollTimer);
998
+ this.clearStreamEndWatchdog();
947
999
  }
948
1000
  handleClickOutside(event) {
949
1001
  // Check if the clicked target is outside the menu
@@ -1215,6 +1267,7 @@ export class Ai12zBot {
1215
1267
  const responseEvent = protocol === "v2" ? "chunk" : "response";
1216
1268
  const endEvent = protocol === "v2" ? "complete" : "end_response";
1217
1269
  this.socket.on(responseEvent, async (event) => {
1270
+ this.resetStreamEndWatchdog();
1218
1271
  const { id, idChanged } = ensureMessageId(this.currentDomId, this.messages, "chatbot");
1219
1272
  this.currentDomId = id;
1220
1273
  if (idChanged)
@@ -1229,6 +1282,12 @@ export class Ai12zBot {
1229
1282
  });
1230
1283
  });
1231
1284
  this.socket.on(endEvent, async (rawData) => {
1285
+ if (!rawData) {
1286
+ console.error("Received empty end response payload");
1287
+ this.failTurn("Something went wrong. Please try again.");
1288
+ return;
1289
+ }
1290
+ this.clearStreamEndWatchdog();
1232
1291
  // For v2, adapt the response format to match legacy expectations
1233
1292
  const data = protocol === "v2" ? adaptCompleteToLegacy(rawData) : rawData;
1234
1293
  if (data.showInput !== undefined && typeof data.showInput === "boolean") {
@@ -1343,12 +1402,12 @@ export class Ai12zBot {
1343
1402
  this.updateBotState();
1344
1403
  }
1345
1404
  this.scrollToBottom();
1346
- this.isStreaming = false;
1405
+ this.releaseSendLock();
1347
1406
  this.currentDomId = "";
1348
1407
  }
1349
1408
  catch (error) {
1350
1409
  console.error("Error handling end_response:", error);
1351
- this.isStreaming = false;
1410
+ this.releaseSendLock();
1352
1411
  }
1353
1412
  });
1354
1413
  });
@@ -1430,7 +1489,7 @@ export class Ai12zBot {
1430
1489
  }
1431
1490
  }
1432
1491
  // ✅ Handle the survey completion rendering
1433
- handleSurveyCompletionRender(processedResults) {
1492
+ async handleSurveyCompletionRender(processedResults) {
1434
1493
  // console.log("Survey completed with results:", processedResults)
1435
1494
  // Find and update the message
1436
1495
  const idx = this.messages.findIndex(item => item.surveyDomId === processedResults.domId);
@@ -1439,8 +1498,26 @@ export class Ai12zBot {
1439
1498
  this.surveyDomId = processedResults.domId;
1440
1499
  // Update conversations with completed HTML
1441
1500
  this.updateConversations(processedResults.completedHtml, {});
1501
+ // Use the JSON payload as the query and the completion text as display text.
1502
+ const surveyQuery = processedResults.jsonData;
1503
+ this.query = surveyQuery;
1504
+ let sent = false;
1442
1505
  // Send the JSON data message
1443
- this.sendMessage(processedResults.jsonData, processedResults.completeText, { isHide: true });
1506
+ try {
1507
+ sent = await this.handleSend(processedResults.completeText, { isHide: true, bypassSendGuard: true });
1508
+ }
1509
+ finally {
1510
+ if (!sent) {
1511
+ console.error("Failed to send form data in finally block");
1512
+ }
1513
+ if (this.query === surveyQuery) {
1514
+ this.query = "";
1515
+ }
1516
+ }
1517
+ if (!sent) {
1518
+ console.error("Failed to send form data");
1519
+ return;
1520
+ }
1444
1521
  this.formSubmitted.emit(processedResults.sender.data);
1445
1522
  // Scroll to bottom
1446
1523
  this.scrollToBottom();
@@ -1576,20 +1653,37 @@ export class Ai12zBot {
1576
1653
  this.messages = [...this.messages];
1577
1654
  }
1578
1655
  this.isStreaming = false;
1656
+ this.isSending = false;
1579
1657
  });
1580
1658
  this.socket.on("connect_error", error => {
1581
1659
  this.errored.emit(error);
1582
1660
  this.announce("Unable to connect to chat server. Please try again.");
1583
1661
  console.error("Connection error:", error);
1584
1662
  });
1663
+ this.socket.on("error", () => {
1664
+ if (this.isStreaming)
1665
+ this.failTurn("Something went wrong. Please try again.");
1666
+ });
1585
1667
  this.socket.on("disconnect", () => {
1586
1668
  // console.log("Disconnected from Socket.IO server")
1587
1669
  this.socket.off("response");
1588
1670
  this.socket.off("chunk");
1589
1671
  // Handle disconnection if needed
1672
+ if (this.isStreaming)
1673
+ this.failTurn("Connection lost. Please try again.");
1590
1674
  });
1591
1675
  }
1592
- invokeSocket() {
1676
+ failTurn(message) {
1677
+ // Release the lock so another message can be sent.
1678
+ this.releaseSendLock();
1679
+ const last = this.messages[this.messages.length - 1];
1680
+ if (last && !last.isUser && last.isLoading) {
1681
+ last.text = message;
1682
+ last.isLoading = false;
1683
+ this.messages = [...this.messages];
1684
+ }
1685
+ }
1686
+ invokeSocket(query) {
1593
1687
  var _a;
1594
1688
  const protocol = getBackendProtocol(this.dataMode);
1595
1689
  let data;
@@ -1597,13 +1691,13 @@ export class Ai12zBot {
1597
1691
  if (protocol === "v2") {
1598
1692
  eventName = "query";
1599
1693
  const beaconId = sessionStorage.getItem("ai12zBeaconId");
1600
- data = Object.assign({ query: this.query !== "" ? this.query : this.inputEl.value, conversation_id: this.conversationId || "", base64_images: ((_a = this.imagesBase64List) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.imagesBase64List : undefined, beacon_id: this.botSettings.disableBeacon ? "" : beaconId !== null && beaconId !== void 0 ? beaconId : "" }, (this.botSettings.disableBeacon || beaconId ? {} : { beacon_data: buildBeacon() }));
1694
+ data = Object.assign({ query, conversation_id: this.conversationId || "", base64_images: ((_a = this.imagesBase64List) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.imagesBase64List : undefined, beacon_id: this.botSettings.disableBeacon ? "" : beaconId !== null && beaconId !== void 0 ? beaconId : "" }, (this.botSettings.disableBeacon || beaconId ? {} : { beacon_data: buildBeacon() }));
1601
1695
  }
1602
1696
  else {
1603
1697
  eventName = "evaluate_query";
1604
1698
  data = {
1605
1699
  apiKey: this.dataKey,
1606
- query: this.query !== "" ? this.query : this.inputEl.value,
1700
+ query,
1607
1701
  conversationId: this.conversationId,
1608
1702
  event: "evaluate_query",
1609
1703
  attributes: this.dataAttributes,
@@ -1640,6 +1734,7 @@ export class Ai12zBot {
1640
1734
  .catch(error => {
1641
1735
  console.error("Error in processDataOverride:", error);
1642
1736
  this.errored.emit(error);
1737
+ this.releaseSendLock();
1643
1738
  this.announce("An error occurred while sending your message.");
1644
1739
  });
1645
1740
  }
@@ -1672,6 +1767,7 @@ export class Ai12zBot {
1672
1767
  stopResponse() {
1673
1768
  this.ignoreChunks = true; // drop future chunks
1674
1769
  this.isStreaming = false;
1770
+ this.releaseSendLock();
1675
1771
  this.messages[this.messages.length - 1].isLoading = false;
1676
1772
  // this.socket.off('response');
1677
1773
  }
@@ -1773,9 +1869,12 @@ export class Ai12zBot {
1773
1869
  this.liveAgentSessionId = "";
1774
1870
  this.liveAgentConversationId = "";
1775
1871
  this.liveAgentButtonText = "Talk to a Live Agent";
1776
- this.sendMessage(((_a = this.botSettings) === null || _a === void 0 ? void 0 : _a.llmMessageOnDisconnect) !== ""
1872
+ const llmMessage = ((_a = this.botSettings) === null || _a === void 0 ? void 0 : _a.llmMessageOnDisconnect) !== ""
1777
1873
  ? (_b = this.botSettings) === null || _b === void 0 ? void 0 : _b.llmMessageOnDisconnect
1778
- : "The live agent has been disconnected. Please do not initiate the live agent directive again.", ((_c = this.botSettings) === null || _c === void 0 ? void 0 : _c.userMessageOnDisconnect) !== "" ? (_d = this.botSettings) === null || _d === void 0 ? void 0 : _d.userMessageOnDisconnect : "The live agent has ended the conversation.", { isLiveChatEnded: true });
1874
+ : "The live agent has been disconnected. Please do not initiate the live agent directive again.";
1875
+ const displayText = ((_c = this.botSettings) === null || _c === void 0 ? void 0 : _c.userMessageOnDisconnect) !== "" ? (_d = this.botSettings) === null || _d === void 0 ? void 0 : _d.userMessageOnDisconnect : "The live agent has ended the conversation.";
1876
+ this.query = llmMessage;
1877
+ void this.handleSend(displayText, { isLiveChatEnded: true, bypassSendGuard: true });
1779
1878
  this.announce("Live agent chat ended");
1780
1879
  this.clearEvents();
1781
1880
  }
@@ -2413,7 +2512,8 @@ export class Ai12zBot {
2413
2512
  "liveAgentListenersRegistered": {},
2414
2513
  "shortcuts": {},
2415
2514
  "announceMessage": {},
2416
- "liveAgentDirective": {}
2515
+ "liveAgentDirective": {},
2516
+ "isSending": {}
2417
2517
  };
2418
2518
  }
2419
2519
  static get events() {
@@ -1 +1 @@
1
- import{A as o,d as s}from"./p-CdRaSl47.js";const a=o,p=s;export{a as Ai12zBot,p as defineCustomElement}
1
+ import{A as o,d as s}from"./p-BDHD9yF0.js";const p=o,r=s;export{p as Ai12zBot,r as defineCustomElement}
@@ -1 +1 @@
1
- import{g as e}from"./p-rVmRQ8bG.js";export{a as getAssetPath,r as render,s as setAssetPath,b as setNonce,c as setPlatformOptions}from"./p-rVmRQ8bG.js";export{A as Ai12zBeacon}from"./p-BLStO0nm.js";export{A as Ai12zBot}from"./p-CdRaSl47.js";export{A as Ai12zCta}from"./p-BLKO6yGt.js";export{A as Ai12zKnowledgeBox}from"./p-BqU2KPcS.js";export{S as Ai12zSearchPanel}from"./p-BVEbp8i6.js";export{S as Ai12zSearchResultsPage}from"./p-jdVWMDxz.js";export{A as Ai12zInlineSearch}from"./p-CFedR60q.js";export{A as Ai12zForm}from"./p-DM33B5uU.js";export{A as Ai12zContainer}from"./p-BqsAwiBV.js";e();
1
+ import{g as e}from"./p-rVmRQ8bG.js";export{a as getAssetPath,r as render,s as setAssetPath,b as setNonce,c as setPlatformOptions}from"./p-rVmRQ8bG.js";export{A as Ai12zBeacon}from"./p-BLStO0nm.js";export{A as Ai12zBot}from"./p-BDHD9yF0.js";export{A as Ai12zCta}from"./p-BLKO6yGt.js";export{A as Ai12zKnowledgeBox}from"./p-BqU2KPcS.js";export{S as Ai12zSearchPanel}from"./p-BVEbp8i6.js";export{S as Ai12zSearchResultsPage}from"./p-jdVWMDxz.js";export{A as Ai12zInlineSearch}from"./p-CFedR60q.js";export{A as Ai12zForm}from"./p-DM33B5uU.js";export{A as Ai12zContainer}from"./p-BqsAwiBV.js";e();