@alan-ai/alan-sdk-web 1.8.93 → 1.8.94

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/alan_lib.js CHANGED
@@ -98913,7 +98913,7 @@
98913
98913
  function broadcastThemeToIframes() {
98914
98914
  let theme;
98915
98915
  try {
98916
- theme = uiState?.currentTheme;
98916
+ theme = uiState?.currentTheme || window["alanCurrentTheme"];
98917
98917
  } catch (error) {
98918
98918
  theme = window["alanCurrentTheme"];
98919
98919
  }
@@ -100397,7 +100397,7 @@
100397
100397
  color: ${textChatOptions?.notifications?.color || `#ffffff`};
100398
100398
  border-radius: 50%;
100399
100399
  z-index: ${uiState.btn.zIndex + 1};
100400
- display: flex;
100400
+ display: ${window._alanBtnState?.textChat?.notifications?.enabled ? "flex" : "none"};
100401
100401
  flex-direction: column;
100402
100402
  align-items: center;
100403
100403
  justify-content: center;
@@ -102611,9 +102611,49 @@ code.hljs {
102611
102611
 
102612
102612
  // alan_btn/src/autosync.ts
102613
102613
  var html2canvas = require_html2canvas();
102614
+ var SEND_PAGE_STATE_THROTTLE_MS = 2e3;
102614
102615
  var popstateListenerWasAdded = false;
102615
- var prevPageContent = "";
102616
+ var requestCounter = 0;
102617
+ var lastSendPageStateTime = 0;
102618
+ var pendingSync = false;
102619
+ var pendingSyncTimeout = null;
102616
102620
  var ALAN_BTN_PAGE_SYNC_EVENT = "alan-btn__page-sync";
102621
+ var prevPageState = {
102622
+ contentHash: "",
102623
+ scrollX: 0,
102624
+ scrollY: 0,
102625
+ viewportWidth: 0,
102626
+ viewportHeight: 0
102627
+ };
102628
+ function generateContentHash(content) {
102629
+ let hash = 0;
102630
+ for (let i = 0; i < content.length; i++) {
102631
+ const char = content.charCodeAt(i);
102632
+ hash = (hash << 5) - hash + char;
102633
+ hash = hash & hash;
102634
+ }
102635
+ return hash.toString();
102636
+ }
102637
+ function hasPageStateChanged(pageContent, forceUpdate) {
102638
+ if (forceUpdate)
102639
+ return true;
102640
+ const currentScrollX = window.pageXOffset || document.documentElement.scrollLeft;
102641
+ const currentScrollY = window.pageYOffset || document.documentElement.scrollTop;
102642
+ const currentViewportWidth = window.innerWidth || document.documentElement.clientWidth;
102643
+ const currentViewportHeight = window.innerHeight || document.documentElement.clientHeight;
102644
+ const currentContentHash = generateContentHash(pageContent);
102645
+ const hasChanged = prevPageState.contentHash !== currentContentHash || Math.abs(prevPageState.scrollX - currentScrollX) > 10 || Math.abs(prevPageState.scrollY - currentScrollY) > 10 || prevPageState.viewportWidth !== currentViewportWidth || prevPageState.viewportHeight !== currentViewportHeight;
102646
+ if (hasChanged) {
102647
+ prevPageState = {
102648
+ contentHash: currentContentHash,
102649
+ scrollX: currentScrollX,
102650
+ scrollY: currentScrollY,
102651
+ viewportWidth: currentViewportWidth,
102652
+ viewportHeight: currentViewportHeight
102653
+ };
102654
+ }
102655
+ return hasChanged;
102656
+ }
102617
102657
  function manageSyncPageStateListeners(isEnabled) {
102618
102658
  if (isEnabled) {
102619
102659
  if (popstateListenerWasAdded !== true) {
@@ -102625,47 +102665,118 @@ code.hljs {
102625
102665
  window.removeEventListener(ALAN_BTN_PAGE_SYNC_EVENT, listenForPageChanges);
102626
102666
  }
102627
102667
  }
102668
+ async function attemptPageStateSync(onSendCb, forceUpdate = false) {
102669
+ const currentTime = performance.now();
102670
+ const timeSinceLastCall = currentTime - lastSendPageStateTime;
102671
+ if (timeSinceLastCall < SEND_PAGE_STATE_THROTTLE_MS && !forceUpdate) {
102672
+ const delayMs = SEND_PAGE_STATE_THROTTLE_MS - timeSinceLastCall + 50;
102673
+ if (pendingSyncTimeout) {
102674
+ clearTimeout(pendingSyncTimeout);
102675
+ }
102676
+ pendingSync = true;
102677
+ pendingSyncTimeout = setTimeout(() => {
102678
+ pendingSync = false;
102679
+ pendingSyncTimeout = null;
102680
+ sendPageState(onSendCb, true);
102681
+ }, delayMs);
102682
+ return;
102683
+ }
102684
+ if (pendingSyncTimeout) {
102685
+ clearTimeout(pendingSyncTimeout);
102686
+ pendingSyncTimeout = null;
102687
+ pendingSync = false;
102688
+ }
102689
+ await sendPageState(onSendCb, forceUpdate);
102690
+ }
102628
102691
  function syncPageState(onSendCb, forceUpdate) {
102629
- sendPageState(onSendCb, forceUpdate);
102692
+ attemptPageStateSync(onSendCb, forceUpdate);
102630
102693
  }
102631
102694
  function listenForPageChanges() {
102632
102695
  sendPageState();
102633
102696
  }
102634
- async function captureScreenshot() {
102635
- const canvas = await html2canvas(document.body, {
102636
- logging: false,
102637
- scale: 1
102638
- });
102639
- return canvas.toDataURL("image/png");
102697
+ async function captureScreenshot(requestId) {
102698
+ if (!document.body) {
102699
+ throw new Error("Document body not available");
102700
+ }
102701
+ const bodyRect = document.body.getBoundingClientRect();
102702
+ const maxWidth = 1280;
102703
+ const maxHeight = 1024;
102704
+ const scale = Math.min(maxWidth / bodyRect.width, maxHeight / bodyRect.height, 1);
102705
+ try {
102706
+ const canvas = await html2canvas(document.body, {
102707
+ logging: false,
102708
+ scale,
102709
+ useCORS: false,
102710
+ allowTaint: false,
102711
+ backgroundColor: "#ffffff",
102712
+ removeContainer: true,
102713
+ ignoreElements: (element) => {
102714
+ if (!element || !element.tagName)
102715
+ return false;
102716
+ if (element.classList) {
102717
+ if (element.classList.contains("hidden"))
102718
+ return true;
102719
+ }
102720
+ return false;
102721
+ }
102722
+ });
102723
+ await new Promise((resolve) => setTimeout(resolve, 0));
102724
+ const dataURL = canvas.toDataURL("image/jpeg", 0.8);
102725
+ canvas.width = 0;
102726
+ canvas.height = 0;
102727
+ return dataURL;
102728
+ } catch (error) {
102729
+ throw error;
102730
+ }
102640
102731
  }
102641
102732
  async function sendPageState(onSendCb, forceUpdate) {
102642
- var page = document.createElement("html");
102643
- page.innerHTML = document.getElementsByTagName("html")[0].innerHTML;
102644
- var scripts = page.getElementsByTagName("script");
102645
- var styles = page.getElementsByTagName("style");
102646
- var alanBtnEl = page.getElementsByClassName("alanBtn-root");
102647
- var debugChatEl = page.getElementsByClassName("alanStudio-debug-chat");
102648
- var elementsToRemove = [...scripts, ...styles, ...alanBtnEl, ...debugChatEl];
102649
- for (var i = 0; i < elementsToRemove.length; i++) {
102650
- elementsToRemove[i].remove();
102651
- }
102652
- const pageContent = page.outerHTML;
102653
- if (onSendCb) {
102654
- onSendCb();
102655
- }
102656
- if (prevPageContent === pageContent && !forceUpdate) {
102657
- return;
102658
- }
102659
- prevPageContent = pageContent;
102660
- if (window.tutorProject) {
102661
- let params = {
102733
+ lastSendPageStateTime = performance.now();
102734
+ const currentRequestId = ++requestCounter;
102735
+ try {
102736
+ if (!document.getElementsByTagName("html")[0]) {
102737
+ throw new Error("HTML document not available");
102738
+ }
102739
+ const page = document.createElement("html");
102740
+ page.innerHTML = document.getElementsByTagName("html")[0].innerHTML;
102741
+ const scripts = page.getElementsByTagName("script");
102742
+ const styles = page.getElementsByTagName("style");
102743
+ const alanBtnEl = page.getElementsByClassName("alanBtn-root");
102744
+ const debugChatEl = page.getElementsByClassName("alanStudio-debug-chat");
102745
+ const elementsToRemove = [...scripts, ...styles, ...alanBtnEl, ...debugChatEl];
102746
+ for (let i = 0; i < elementsToRemove.length; i++) {
102747
+ if (elementsToRemove[i] && elementsToRemove[i].remove) {
102748
+ elementsToRemove[i].remove();
102749
+ }
102750
+ }
102751
+ const pageContent = page.outerHTML;
102752
+ if (onSendCb) {
102753
+ onSendCb();
102754
+ }
102755
+ const hasChanged = hasPageStateChanged(pageContent, forceUpdate);
102756
+ if (!hasChanged) {
102757
+ return;
102758
+ }
102759
+ if (!window.tutorProject) {
102760
+ return;
102761
+ }
102762
+ const params = {
102662
102763
  html: pageContent,
102663
- url: window.location.href
102764
+ url: window.location.href,
102765
+ scrollPosition: {
102766
+ x: prevPageState.scrollX,
102767
+ y: prevPageState.scrollY
102768
+ },
102769
+ viewport: {
102770
+ width: prevPageState.viewportWidth,
102771
+ height: prevPageState.viewportHeight
102772
+ }
102664
102773
  };
102665
102774
  if (window._alanBtnState?.pageState?.screenshot?.enabled) {
102666
- params.screenshot = await captureScreenshot();
102775
+ params.screenshot = await captureScreenshot(currentRequestId);
102667
102776
  }
102668
102777
  window.tutorProject.call("syncPageState", params);
102778
+ } catch (error) {
102779
+ throw error;
102669
102780
  }
102670
102781
  }
102671
102782
 
@@ -109370,6 +109481,19 @@ code.hljs {
109370
109481
  return null;
109371
109482
  }
109372
109483
  }
109484
+ function applyThemeToHtmlContent(htmlContent2, theme) {
109485
+ if (!theme || theme !== "light" && theme !== "dark") {
109486
+ return htmlContent2;
109487
+ }
109488
+ const parser2 = new DOMParser();
109489
+ const doc2 = parser2.parseFromString(htmlContent2, "text/html");
109490
+ const htmlElement = doc2.documentElement;
109491
+ if (htmlElement) {
109492
+ const themeClass = theme === "light" ? "light-theme" : "dark-theme";
109493
+ htmlElement.classList.add(themeClass);
109494
+ }
109495
+ return doc2.documentElement.outerHTML;
109496
+ }
109373
109497
  function extractScriptContents(html) {
109374
109498
  const scriptContents = [];
109375
109499
  const parser2 = new DOMParser();
@@ -109405,7 +109529,8 @@ code.hljs {
109405
109529
  projectId,
109406
109530
  environment,
109407
109531
  requestIds,
109408
- headContent
109532
+ headContent,
109533
+ data: data2
109409
109534
  }) {
109410
109535
  const chatConteiner = chatEl.cloneNode(true);
109411
109536
  const images = Array.from(chatConteiner.querySelectorAll("img"));
@@ -109425,6 +109550,7 @@ code.hljs {
109425
109550
  continue;
109426
109551
  }
109427
109552
  let initHtmlContent = await response.text();
109553
+ initHtmlContent = applyThemeToHtmlContent(initHtmlContent, data2?.theme);
109428
109554
  let { htmlContent: htmlContent2 } = await inlineExternalResources(initHtmlContent);
109429
109555
  const initIframeFn2 = extractFunctionWithRegex(htmlContent2, "initIframe");
109430
109556
  if (initIframeFn2) {
@@ -109878,6 +110004,8 @@ code.hljs {
109878
110004
  };
109879
110005
  <\/script>
109880
110006
  `;
110007
+ const txtMessages = data2?.textChatMessages ? JSON.stringify(data2?.textChatMessages, null, 2) : '"no-provided"';
110008
+ const socketMessages = data2?.socketMessages ? JSON.stringify(data2?.socketMessages, null, 2) : '"no-provided"';
109881
110009
  const newHtmlContent = `
109882
110010
  <!DOCTYPE html>
109883
110011
  <html lang="en">
@@ -109890,6 +110018,15 @@ code.hljs {
109890
110018
  <script src="${LIBS_PREFIX}/alan_markdown.js" type="text/javascript"><\/script>
109891
110019
  <script src="${LIBS_PREFIX}/highlight.min.js?v=2" type="text/javascript"><\/script>
109892
110020
  ${headContent ? headContent : ""}
110021
+
110022
+ <script>
110023
+ console.info('Alan lib v: ${window.alanLib?.version || "-"}, exporter v: 1.0.1');
110024
+ function showAlanDebugInfo() {
110025
+ console.info('Messages in chat:', ${txtMessages});
110026
+ console.info('Messages in socket:', ${socketMessages});
110027
+ }
110028
+ <\/script>
110029
+
109893
110030
  <style>
109894
110031
  * {
109895
110032
  box-sizing: border-box;
@@ -110164,7 +110301,7 @@ code.hljs {
110164
110301
  }
110165
110302
  }
110166
110303
 
110167
- window.alanCurrentTheme = '${uiState.currentTheme}';
110304
+ window.alanCurrentTheme = '${data2?.theme || "null"}';
110168
110305
 
110169
110306
  <\/script>
110170
110307
 
@@ -110611,7 +110748,8 @@ code.hljs {
110611
110748
 
110612
110749
  // alan_btn/alan_btn.ts
110613
110750
  (function(ns) {
110614
- uiState.lib.version = "alan-version.1.8.93".replace("alan-version.", "");
110751
+ uiState.lib.version = "alan-version.1.8.94".replace("alan-version.", "");
110752
+ window.alanLib = { version: "alan-version.1.8.93".replace("alan-version.", "") };
110615
110753
  if (window.alanBtn) {
110616
110754
  console.warn("Alan: the Alan Button source code has already added (v." + uiState.lib.version + ")");
110617
110755
  }
@@ -110854,6 +110992,8 @@ code.hljs {
110854
110992
  alanAudio.off("command", onCommandCbInMicBtn);
110855
110993
  alanAudio.off("afterText", onAfterTextCbInMicBtn);
110856
110994
  document.removeEventListener("click", alanBtnClickEventListener);
110995
+ document.removeEventListener("click", performLikeOrDislike);
110996
+ document.removeEventListener("click", onCopyClick);
110857
110997
  rootEl.innerHTML = "";
110858
110998
  btnInstance = null;
110859
110999
  if (!isTutorMode()) {
@@ -110978,6 +111118,11 @@ code.hljs {
110978
111118
  screenshot: {
110979
111119
  enabled: false
110980
111120
  }
111121
+ },
111122
+ textChat: {
111123
+ notifications: {
111124
+ enabled: false
111125
+ }
110981
111126
  }
110982
111127
  };
110983
111128
  if (isTutorMode()) {
@@ -112301,6 +112446,7 @@ code.hljs {
112301
112446
  console.log("Alan: options received");
112302
112447
  console.timeEnd("Alan: receiving options time");
112303
112448
  saveOptions(data2);
112449
+ window._alanBtnState.textChat.notifications.enabled = data2?.web?.chatOptions?.textChat?.notifications?.enabled;
112304
112450
  window._alanBtnState.pageState.screenshot.enabled = data2?.web?.pageState?.screenshot?.enabled;
112305
112451
  uiState.textChat.autocomplete.enabled = data2?.web?.chatOptions?.textChat?.textarea?.autocomplete?.enabled;
112306
112452
  uiState.textChat.maxCharactersCount = data2?.web?.chatOptions?.textChat?.textarea?.maxCharactersCount ? +data2?.web?.chatOptions?.textChat?.textarea?.maxCharactersCount : 2e4;
@@ -112960,7 +113106,7 @@ ${curDialogId}`);
112960
113106
  return `${buildImagesContent(msg)}${buildMsgTextContent(msg)}${buildLinksContent(msg)}${buildCommandsBlock(msg, uiState?.textChat?.options)}${buildMsgIncommingLoader(msg)}${addGraphIcon(msg)}`;
112961
113107
  }
112962
113108
  initMathJax(textChatMessages.length, (i2) => getMsgElForMathJax(i2));
112963
- document.addEventListener("click", (e) => {
113109
+ function onCopyClick(e) {
112964
113110
  let clickedEl = e.target;
112965
113111
  clickedEl = clickedEl.closest(".alan-btn__chat-response__copy-btn");
112966
113112
  if (clickedEl) {
@@ -113000,7 +113146,8 @@ ${LEARN_MORE_LABEL}
113000
113146
  }
113001
113147
  enableTextareaInTheChat();
113002
113148
  }
113003
- }, false);
113149
+ }
113150
+ document.addEventListener("click", onCopyClick, false);
113004
113151
  window.addEventListener("click", (0, import_lodash2.debounce)((e) => {
113005
113152
  if (isTutorMode())
113006
113153
  return;
@@ -113210,7 +113357,7 @@ ${LEARN_MORE_LABEL}
113210
113357
  innerEl.insertAdjacentHTML("beforeend", buildCommandsBlock(msg, uiState?.textChat?.options));
113211
113358
  innerEl.insertAdjacentHTML("beforeend", buildMsgIncommingLoader(updatedMsg));
113212
113359
  innerEl.insertAdjacentHTML("beforeend", addGraphIcon(updatedMsg));
113213
- const newSuggestions = msg?.suggestions;
113360
+ const newSuggestions = updatedMsg?.suggestions;
113214
113361
  if (newSuggestions?.length > 0) {
113215
113362
  if (innerEl.nextElementSibling?.classList.contains("alan-btn__chat-suggestions")) {
113216
113363
  innerEl.nextElementSibling.remove();
@@ -114310,18 +114457,8 @@ ${LEARN_MORE_LABEL}
114310
114457
  ];
114311
114458
  const styles = head.querySelectorAll(styleSelectors.join(", "));
114312
114459
  const combinedStylesHTML = Array.from(styles).map((style) => style.outerHTML).join("\n");
114313
- const txtMessages = JSON.stringify(textChatMessages, null, 2);
114314
- const socketMessages = JSON.stringify(uiState.socketMessages, null, 2);
114315
114460
  const customHeadContent = `
114316
114461
  ${combinedStylesHTML}
114317
-
114318
- <script>
114319
- function showAlanDebugLogs() {
114320
- console.info('Alan lib v: ${uiState.lib.version}');
114321
- console.info('Messages in chat:', ${txtMessages});
114322
- console.info('Messages in socket:', ${socketMessages});
114323
- }
114324
- <\/script>
114325
114462
  `;
114326
114463
  const initChat = document.querySelector("#chatMessagesWrapper");
114327
114464
  if (!initChat)
@@ -114343,7 +114480,12 @@ ${LEARN_MORE_LABEL}
114343
114480
  projectId,
114344
114481
  environment: getEnvironment(),
114345
114482
  requestIds: textChatMessages?.length > 0 ? textChatMessages.filter((m) => m.type === "response" /* Response */).map((m) => getMsgReqId(m)) : [],
114346
- headContent: customHeadContent
114483
+ headContent: customHeadContent,
114484
+ data: {
114485
+ textChatMessages,
114486
+ socketMessages: uiState.socketMessages,
114487
+ theme: uiState.currentTheme
114488
+ }
114347
114489
  });
114348
114490
  if (saveChatStateBtnImg) {
114349
114491
  saveChatStateBtnImg.classList.remove("saving");
@@ -114386,7 +114528,7 @@ ${LEARN_MORE_LABEL}
114386
114528
  function showChatNotifications() {
114387
114529
  if (unreadChatMsgCount > 0) {
114388
114530
  chatNotificationsBubble.innerHTML = unreadChatMsgCount > 99 ? `99+` : `${unreadChatMsgCount}`;
114389
- chatNotificationsBubble.style.display = "flex";
114531
+ chatNotificationsBubble.classList.remove("super-hidden");
114390
114532
  }
114391
114533
  }
114392
114534
  function manageUnmuteAlanIcon(iconEl, unmuted) {
@@ -114445,7 +114587,7 @@ ${LEARN_MORE_LABEL}
114445
114587
  }
114446
114588
  function hideChatNotifications() {
114447
114589
  unreadChatMsgCount = 0;
114448
- chatNotificationsBubble.style.display = "none";
114590
+ chatNotificationsBubble.classList.add("super-hidden");
114449
114591
  for (let i2 = 0; i2 < textChatMessages.length; i2++) {
114450
114592
  textChatMessages[i2].read = true;
114451
114593
  }