advaisor-chatbot 1.7.0 → 1.7.1-beta.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.
Files changed (2) hide show
  1. package/dist/testchatbot.js +348 -215
  2. package/package.json +1 -1
@@ -1390,6 +1390,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1390
1390
  this.attachShadow({ mode: "open" });
1391
1391
  this.isOpen = false;
1392
1392
  this.activeSessionId = null;
1393
+ this.abortController = null;
1393
1394
  }
1394
1395
  connectedCallback() {
1395
1396
  this.apiEndpoint = this.getAttribute("api_endpoint") || "https://silicore.ai:2002/cds_bookshelves/ask_all_bookshelves";
@@ -1399,216 +1400,243 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1399
1400
  }
1400
1401
  render() {
1401
1402
  this.shadowRoot.innerHTML = `
1402
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
1403
- <style>
1404
- :host {
1405
- --primary-color: #EC9588;
1406
- --user-bubble: #f29b8c;
1407
- --bot-bubble: #e5e7eb;
1408
- font-family: system-ui, -apple-system, sans-serif;
1409
- }
1410
-
1411
- .chat-trigger {
1412
- position: fixed;
1413
- bottom: 20px;
1414
- right: 20px;
1415
- z-index: 9999;
1416
- height: 56px;
1417
- width: 56px;
1418
- border-radius: 50%;
1419
- background: var(--primary-color);
1420
- color: white;
1421
- display: flex;
1422
- align-items: center;
1423
- justify-content: center;
1424
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1425
- font-size: 24px;
1426
- cursor: pointer;
1427
- transition: transform 0.2s;
1428
- border: none;
1429
- }
1430
-
1431
- .chat-trigger:hover { transform: scale(1.05); }
1432
-
1433
- .chat-window {
1434
- position: fixed;
1435
- bottom: 20px;
1436
- right: 20px;
1437
- z-index: 10000;
1438
-
1439
- display: none;
1440
- flex-direction: column;
1441
-
1442
- background: #ffffff;
1443
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
1403
+ <style>
1404
+ :host {
1405
+ --primary-color: #EC9588;
1406
+ --user-bubble: #f29b8c;
1407
+ --bot-bubble: #e5e7eb;
1408
+ font-family: system-ui, -apple-system, sans-serif;
1409
+ }
1444
1410
 
1445
- width: min(30vw, 420px);
1446
- height: 90vh;
1411
+ .chat-trigger {
1412
+ position: fixed;
1413
+ bottom: 20px;
1414
+ right: 20px;
1415
+ z-index: 9999;
1416
+ height: 56px;
1417
+ width: 56px;
1418
+ border-radius: 50%;
1419
+ background: var(--primary-color);
1420
+ color: white;
1421
+ display: flex;
1422
+ align-items: center;
1423
+ justify-content: center;
1424
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
1425
+ font-size: 24px;
1426
+ cursor: pointer;
1427
+ transition: transform 0.2s;
1428
+ border: none;
1429
+ }
1447
1430
 
1448
- border-radius: 16px;
1449
- overflow: hidden;
1431
+ .chat-trigger:hover { transform: scale(1.05); }
1450
1432
 
1451
- transition: all 0.25s ease;
1433
+ .chat-window {
1434
+ position: fixed;
1435
+ bottom: 20px;
1436
+ right: 20px;
1437
+ z-index: 10000;
1438
+ display: none;
1439
+ flex-direction: column;
1440
+ background: #ffffff;
1441
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
1442
+ width: min(30vw, 420px);
1443
+ height: 90vh;
1444
+ border-radius: 16px;
1445
+ overflow: hidden;
1446
+ transition: all 0.25s ease;
1447
+ resize: both;
1448
+ min-width: 300px;
1449
+ min-height: 450px;
1450
+ }
1452
1451
 
1453
- resize: both;
1454
- min-width: 300px;
1455
- min-height: 450px;
1456
- }
1452
+ .chat-window.expanded {
1453
+ width: min(700px, 95vw);
1454
+ height: 90vh;
1455
+ }
1457
1456
 
1458
- /* \u2705 Proper desktop expanded */
1457
+ @media (max-width: 768px) {
1458
+ .chat-window,
1459
1459
  .chat-window.expanded {
1460
- width: min(700px, 95vw);
1461
- height: 90vh;
1462
-
1460
+ width: 100vw !important;
1461
+ max-width: 100vw !important;
1462
+ height: 85vh !important;
1463
+ bottom: 0;
1464
+ right: 0;
1465
+ border-radius: 16px 16px 0 0;
1463
1466
  }
1467
+ }
1464
1468
 
1465
- /* \u2705 Mobile override */
1466
- @media (max-width: 768px) {
1467
- .chat-window,
1468
- .chat-window.expanded {
1469
- width: 100vw !important;
1470
- max-width: 100vw !important;
1469
+ .header {
1470
+ background: var(--primary-color);
1471
+ padding: 12px 16px;
1472
+ color: white;
1473
+ display: flex;
1474
+ justify-content: space-between;
1475
+ align-items: center;
1476
+ cursor: move;
1477
+ user-select: none;
1478
+ touch-action: none;
1479
+ }
1471
1480
 
1472
- height: 85vh !important;
1473
- bottom: 0;
1474
- right: 0;
1475
- border-radius: 16px 16px 0 0;
1476
- }
1477
- }
1478
-
1479
- .typing {
1480
- display: flex;
1481
- gap: 4px;
1482
- align-items: center;
1483
- }
1481
+ .close-btn, .resize-btn, .history-btn {
1482
+ background: none;
1483
+ border: none;
1484
+ color: white;
1485
+ cursor: pointer;
1486
+ font-size: 16px;
1487
+ }
1484
1488
 
1485
- .chat-body {
1486
- flex: 1;
1487
- overflow-y: auto;
1488
- overflow-x: hidden;
1489
- }
1489
+ .history-btn {
1490
+ height: 32px;
1491
+ width: 32px;
1492
+ border-radius: 50%;
1493
+ font-size: 14px;
1494
+ display: flex;
1495
+ align-items: center;
1496
+ justify-content: center;
1497
+ margin-top: 4px;
1498
+ }
1490
1499
 
1491
- .message {
1492
- word-wrap: break-word;
1493
- overflow-wrap: break-word;
1494
- }
1500
+ .chat-body {
1501
+ flex: 1;
1502
+ padding: 16px;
1503
+ overflow-y: auto;
1504
+ background: #f9fafb;
1505
+ display: flex;
1506
+ flex-direction: column;
1507
+ gap: 12px;
1508
+ }
1495
1509
 
1496
- .message pre,
1497
- .message code {
1498
- white-space: pre-wrap;
1499
- word-break: break-word;
1500
- }
1510
+ /* Base message styles */
1511
+ .message {
1512
+ max-width: 75%;
1513
+ font-size: 15px;
1514
+ line-height: 1.5;
1515
+ word-wrap: break-word;
1516
+ overflow-wrap: break-word;
1517
+ }
1501
1518
 
1502
- .header {
1503
- background: var(--primary-color);
1504
- padding: 12px 16px;
1505
- color: white;
1506
- display: flex;
1507
- justify-content: space-between;
1508
- align-items: center;
1509
- }
1519
+ .message.bot {
1520
+ align-self: flex-start;
1521
+ display: flex;
1522
+ flex-direction: column;
1523
+ align-items: flex-start;
1524
+ padding: 8px 16px;
1525
+ border-radius: 12px;
1526
+ font-size: 15px;
1527
+ line-height: 1.5;
1528
+ gap: 4px;
1529
+ }
1510
1530
 
1511
- .close-btn { background: none; border: none; color: white; cursor: pointer; font-size: 16px; }
1531
+ .message.user {
1532
+ align-self: flex-end;
1533
+ background: var(--user-bubble);
1534
+ color: white;
1535
+ padding: 8px 16px;
1536
+ border-radius: 18px 18px 4px 18px;
1537
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
1538
+ }
1512
1539
 
1513
- .chat-body {
1514
- flex: 1;
1515
- padding: 16px;
1516
- overflow-y: auto;
1517
- background: #f9fafb;
1518
- display: flex;
1519
- flex-direction: column;
1520
- gap: 12px;
1521
- }
1540
+ /* Bot message content bubble */
1541
+ .message.bot .content {
1542
+ background: var(--bot-bubble);
1543
+ color: #1f2937;
1544
+ border-radius: 18px 18px 18px 4px;
1545
+ word-wrap: break-word;
1546
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
1547
+ }
1522
1548
 
1523
- .message {
1524
- max-width: 75%;
1525
- padding: 8px 16px;
1526
- border-radius: 12px;
1527
- font-size: 15px;
1528
- line-height: 1.5;
1529
- }
1549
+ .message.bot .content p {
1550
+ margin: 4px 0;
1551
+ }
1530
1552
 
1531
- .bot { align-self: flex-start; background: var(--bot-bubble); color: #1f2937; }
1532
- .user { align-self: flex-end; background: var(--user-bubble); color: white; }
1553
+ .message.bot .content p:first-child { margin-top: 0; }
1554
+ .message.bot .content p:last-child { margin-bottom: 0; }
1533
1555
 
1534
- .input-area {
1535
- border-top: 1px solid #e5e7eb;
1536
- padding: 12px;
1537
- display: flex;
1538
- gap: 8px;
1539
- }
1556
+ .bot { align-self: flex-start; background: var(--bot-bubble); color: #1f2937; }
1540
1557
 
1541
- input {
1542
- flex: 1;
1543
- border: 1px solid #e5e7eb;
1544
- border-radius: 6px;
1545
- padding: 8px 12px;
1546
- outline: none;
1547
- }
1558
+ .message pre, .message code {
1559
+ white-space: pre-wrap;
1560
+ word-break: break-word;
1561
+ }
1548
1562
 
1549
- input:focus { border-color: var(--primary-color); }
1563
+ /* Status message (outside bubble) */
1564
+ .status-message {
1565
+ font-style: italic;
1566
+ color: #888;
1567
+ font-size: 0.85em;
1568
+ padding: 4px 12px;
1569
+ margin: 2px 0;
1570
+ background: transparent;
1571
+ border-radius: 12px;
1572
+ display: inline-block;
1573
+ max-width: 80%;
1574
+ }
1550
1575
 
1551
- .send-btn {
1552
- background: var(--user-bubble);
1553
- color: white;
1554
- border: none;
1555
- padding: 0 16px;
1556
- border-radius: 6px;
1557
- cursor: pointer;
1558
- }
1559
-
1576
+ /* Typing indicator as message bubble */
1577
+ .typing-indicator {
1578
+ display: inline-flex;
1579
+ align-items: center;
1580
+ gap: 4px;
1581
+ padding: 8px 16px;
1582
+ background: var(--bot-bubble);
1583
+ border-radius: 18px 18px 18px 4px;
1584
+ margin: 4px 0;
1585
+ max-width: fit-content;
1586
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
1587
+ }
1560
1588
 
1561
- .resize-btn {
1562
- background: none;
1563
- border: none;
1564
- color: white;
1565
- cursor: pointer;
1566
- font-size: 16px;
1567
- }
1589
+ .typing-indicator span {
1590
+ width: 8px;
1591
+ height: 8px;
1592
+ background: #666;
1593
+ border-radius: 50%;
1594
+ display: inline-block;
1595
+ animation: typingBounce 1.4s infinite ease-in-out both;
1596
+ }
1568
1597
 
1598
+ .typing-indicator span:nth-child(1) { animation-delay: -0.32s; }
1599
+ .typing-indicator span:nth-child(2) { animation-delay: -0.16s; }
1600
+ .typing-indicator span:nth-child(3) { animation-delay: 0; }
1569
1601
 
1570
- .typing span {
1571
- width: 6px;
1572
- height: 6px;
1573
- background: #999;
1574
- border-radius: 50%;
1575
- animation: blink 1.4s infinite;
1576
- }
1602
+ @keyframes typingBounce {
1603
+ 0%, 80%, 100% { transform: scale(0.6); opacity: 0.6; }
1604
+ 40% { transform: scale(1); opacity: 1; }
1605
+ }
1577
1606
 
1578
- .typing span:nth-child(2) { animation-delay: 0.2s; }
1579
- .typing span:nth-child(3) { animation-delay: 0.4s; }
1607
+ .input-area {
1608
+ border-top: 1px solid #e5e7eb;
1609
+ padding: 12px;
1610
+ display: flex;
1611
+ gap: 8px;
1612
+ }
1580
1613
 
1581
- @keyframes blink {
1582
- 0%, 80%, 100% { opacity: 0.2; transform: scale(1); }
1583
- 40% { opacity: 1; transform: scale(1.3); }
1584
- }
1614
+ input {
1615
+ flex: 1;
1616
+ border: 1px solid #e5e7eb;
1617
+ border-radius: 6px;
1618
+ padding: 8px 12px;
1619
+ outline: none;
1620
+ }
1585
1621
 
1586
- .send-btn:disabled {
1587
- opacity: 0.6;
1588
- cursor: not-allowed;
1589
- }
1622
+ input:focus { border-color: var(--primary-color); }
1590
1623
 
1591
- .header {
1592
- cursor: move;
1593
- user-select: none;
1594
- touch-action: none;
1595
- }
1624
+ .send-btn {
1625
+ background: var(--user-bubble);
1626
+ color: white;
1627
+ border: none;
1628
+ padding: 0 16px;
1629
+ border-radius: 6px;
1630
+ cursor: pointer;
1631
+ }
1596
1632
 
1597
- .history-btn {
1598
- height: 32px;
1599
- width: 32px;
1600
- border-radius: 50%;
1601
- border: none;
1602
- cursor: pointer;
1603
- background: rgba(255,255,255,0.0);
1604
- color: white;
1605
- font-size: 14px;
1606
- display: flex;
1607
- align-items: center;
1608
- justify-content: center;
1609
- margin-top: 4px;
1610
- }
1611
- </style>
1633
+ .send-btn:disabled {
1634
+ opacity: 0.6;
1635
+ cursor: not-allowed;
1636
+ }
1637
+ </style>
1638
+
1639
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
1612
1640
 
1613
1641
  <button class="chat-trigger" id="trigger">\u{1F4AC}</button>
1614
1642
 
@@ -1652,6 +1680,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1652
1680
  const historyBtn = this.shadowRoot.getElementById("history");
1653
1681
  const sidebar = this.shadowRoot.getElementById("sidebar");
1654
1682
  sidebar.addEventListener("new-chat", () => {
1683
+ if (this.abortController) {
1684
+ this.abortController.abort();
1685
+ this.abortController = null;
1686
+ }
1655
1687
  this.activeSessionId = null;
1656
1688
  const body2 = this.shadowRoot.getElementById("body");
1657
1689
  body2.innerHTML = `<div class="message bot">Hi ${this.userName}! How can I help?</div>`;
@@ -1680,6 +1712,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1680
1712
  body.scrollTop = body.scrollHeight;
1681
1713
  };
1682
1714
  closeBtn.onclick = () => {
1715
+ if (this.abortController) {
1716
+ this.abortController.abort();
1717
+ this.abortController = null;
1718
+ }
1683
1719
  windowEl.style.display = "none";
1684
1720
  trigger.style.display = "flex";
1685
1721
  };
@@ -1693,6 +1729,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1693
1729
  const sendMessage = async () => {
1694
1730
  const text = input.value.trim();
1695
1731
  if (!text) return;
1732
+ if (this.abortController) {
1733
+ this.abortController.abort();
1734
+ this.abortController = null;
1735
+ }
1696
1736
  input.disabled = true;
1697
1737
  sendBtn.disabled = true;
1698
1738
  const userMsg = document.createElement("div");
@@ -1701,21 +1741,39 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1701
1741
  body.appendChild(userMsg);
1702
1742
  input.value = "";
1703
1743
  body.scrollTop = body.scrollHeight;
1744
+ const botMessageContainer = document.createElement("div");
1745
+ botMessageContainer.className = "message bot";
1746
+ const contentDiv = document.createElement("div");
1747
+ contentDiv.className = "content";
1748
+ contentDiv.id = "answer-content";
1704
1749
  const typingDiv = document.createElement("div");
1705
- typingDiv.className = "message bot";
1750
+ typingDiv.className = "typing-indicator";
1706
1751
  typingDiv.id = "typing-indicator";
1707
1752
  typingDiv.innerHTML = `
1708
- <div class="typing">
1709
- <span></span><span></span><span></span>
1710
- </div>
1753
+ <span></span><span></span><span></span>
1711
1754
  `;
1712
- body.appendChild(typingDiv);
1755
+ const statusDiv = document.createElement("div");
1756
+ statusDiv.className = "status-message";
1757
+ statusDiv.id = "status-message";
1758
+ botMessageContainer.appendChild(contentDiv);
1759
+ botMessageContainer.appendChild(typingDiv);
1760
+ botMessageContainer.appendChild(statusDiv);
1761
+ body.appendChild(botMessageContainer);
1713
1762
  body.scrollTop = body.scrollHeight;
1714
- function fixMarkdown(text2) {
1715
- return text2.replace(/}```/g, "}\n```").replace(/```(\S)/g, "```\n$1");
1716
- }
1763
+ const timeoutId = setTimeout(() => {
1764
+ if (this.abortController) {
1765
+ this.abortController.abort();
1766
+ this.abortController = null;
1767
+ this.showErrorMessage(body, "Request timed out after 30 seconds. Please try again.");
1768
+ botMessageContainer.remove();
1769
+ input.disabled = false;
1770
+ sendBtn.disabled = false;
1771
+ input.focus();
1772
+ }
1773
+ }, 3e4);
1717
1774
  try {
1718
- const res = await fetch(this.apiEndpoint, {
1775
+ this.abortController = new AbortController();
1776
+ const response = await fetch(this.apiEndpoint, {
1719
1777
  method: "POST",
1720
1778
  headers: {
1721
1779
  "Content-Type": "application/json",
@@ -1728,36 +1786,90 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1728
1786
  bookshelf_name: "All Bookshelves",
1729
1787
  package_id: 30,
1730
1788
  user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
1731
- })
1789
+ }),
1790
+ signal: this.abortController.signal
1732
1791
  });
1733
- const response = await res.json();
1734
- typingDiv.remove();
1735
- if (response?.session_id) {
1736
- this.activeSessionId = response.session_id;
1792
+ clearTimeout(timeoutId);
1793
+ if (!response.ok) {
1794
+ throw new Error(`HTTP error! status: ${response.status}`);
1795
+ }
1796
+ const reader = response.body.getReader();
1797
+ const decoder = new TextDecoder("utf-8");
1798
+ let buffer = "";
1799
+ let accumulatedAnswer = "";
1800
+ let lastStatusMessage = "";
1801
+ while (true) {
1802
+ const { value, done } = await reader.read();
1803
+ if (done) break;
1804
+ buffer += decoder.decode(value, { stream: true });
1805
+ const events = buffer.split("\n\n");
1806
+ buffer = events.pop();
1807
+ for (const event of events) {
1808
+ const match = event.match(/^data: (.+)$/m);
1809
+ if (!match) continue;
1810
+ const jsonStr = match[1].trim();
1811
+ try {
1812
+ const data = JSON.parse(jsonStr);
1813
+ if (data.type === "message") {
1814
+ lastStatusMessage = data.text;
1815
+ statusDiv.textContent = data.text;
1816
+ typingDiv.style.display = "none";
1817
+ }
1818
+ if (data.type === "answer") {
1819
+ typingDiv.style.display = "none";
1820
+ if (data.session_id) {
1821
+ this.activeSessionId = data.session_id;
1822
+ }
1823
+ if (accumulatedAnswer && !accumulatedAnswer.endsWith("\n\n")) {
1824
+ accumulatedAnswer += "\n\n";
1825
+ }
1826
+ const newText = data.text;
1827
+ accumulatedAnswer += newText;
1828
+ const words = newText.split(" ");
1829
+ let currentDisplayText = accumulatedAnswer.substring(0, accumulatedAnswer.length - newText.length);
1830
+ if (currentDisplayText) {
1831
+ const cleanExisting = this.fixMarkdown(currentDisplayText);
1832
+ const htmlExisting = d.parse(cleanExisting);
1833
+ contentDiv.innerHTML = htmlExisting;
1834
+ await new Promise((resolve) => setTimeout(resolve, 50));
1835
+ }
1836
+ for (let i = 0; i < words.length; i++) {
1837
+ currentDisplayText += (i > 0 || currentDisplayText ? " " : "") + words[i];
1838
+ const cleanReply = this.fixMarkdown(currentDisplayText + (i < words.length - 1 ? " ..." : ""));
1839
+ const htmlReply = d.parse(cleanReply);
1840
+ contentDiv.innerHTML = htmlReply;
1841
+ if (i < words.length - 1) {
1842
+ await new Promise((resolve) => setTimeout(resolve, 30));
1843
+ }
1844
+ }
1845
+ }
1846
+ if (data.is_last) {
1847
+ statusDiv.remove();
1848
+ typingDiv.style.display = "none";
1849
+ const cleanReply = this.fixMarkdown(accumulatedAnswer);
1850
+ const htmlReply = d.parse(cleanReply);
1851
+ contentDiv.innerHTML = htmlReply;
1852
+ break;
1853
+ }
1854
+ } catch (parseError) {
1855
+ console.error("Error parsing JSON:", jsonStr, parseError);
1856
+ }
1857
+ }
1737
1858
  }
1738
- const botReply = response?.answer || "No response received.";
1739
- d.setOptions({
1740
- breaks: true,
1741
- gfm: true
1742
- });
1743
- const cleanReply = fixMarkdown(botReply);
1744
- const htmlReply = d.parse(cleanReply);
1745
- const wrapper = document.createElement("div");
1746
- wrapper.className = "message bot";
1747
- wrapper.innerHTML = htmlReply;
1748
- body.appendChild(wrapper);
1749
- body.scrollTop = body.scrollHeight;
1750
1859
  } catch (error) {
1751
- typingDiv.remove();
1752
- const errorMsg = document.createElement("div");
1753
- errorMsg.className = "message bot";
1754
- errorMsg.textContent = "Sorry, something went wrong.";
1755
- body.appendChild(errorMsg);
1756
- console.error(error);
1860
+ clearTimeout(timeoutId);
1861
+ botMessageContainer.remove();
1862
+ if (error.name === "AbortError") {
1863
+ console.log("Stream aborted");
1864
+ } else {
1865
+ this.showErrorMessage(body, "Sorry, something went wrong. Please try again.");
1866
+ console.error("Stream error:", error);
1867
+ }
1757
1868
  } finally {
1758
1869
  input.disabled = false;
1759
1870
  sendBtn.disabled = false;
1760
1871
  input.focus();
1872
+ this.abortController = null;
1761
1873
  }
1762
1874
  };
1763
1875
  sendBtn.onclick = sendMessage;
@@ -1824,7 +1936,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1824
1936
  }
1825
1937
  });
1826
1938
  }
1939
+ fixMarkdown(text) {
1940
+ return text.replace(/}```/g, "}\n```").replace(/```(\S)/g, "```\n$1");
1941
+ }
1942
+ showErrorMessage(body, message) {
1943
+ const errorMsg = document.createElement("div");
1944
+ errorMsg.className = "message bot error-message";
1945
+ errorMsg.textContent = message;
1946
+ body.appendChild(errorMsg);
1947
+ body.scrollTop = body.scrollHeight;
1948
+ }
1827
1949
  async loadSession(sessionId) {
1950
+ if (this.abortController) {
1951
+ this.abortController.abort();
1952
+ this.abortController = null;
1953
+ }
1828
1954
  this.activeSessionId = sessionId;
1829
1955
  const body = this.shadowRoot.getElementById("body");
1830
1956
  body.innerHTML = `<div class="message bot">Loading conversation...</div>`;
@@ -1842,6 +1968,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1842
1968
  })
1843
1969
  }
1844
1970
  );
1971
+ if (!res.ok) {
1972
+ throw new Error(`HTTP error! status: ${res.status}`);
1973
+ }
1845
1974
  const data = await res.json();
1846
1975
  const history = data?.body?.chat_history || [];
1847
1976
  body.innerHTML = "";
@@ -1851,6 +1980,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1851
1980
  });
1852
1981
  } catch (err) {
1853
1982
  console.error("Failed to load session", err);
1983
+ body.innerHTML = `<div class="message bot error-message">Failed to load conversation. Please try again.</div>`;
1854
1984
  }
1855
1985
  }
1856
1986
  renderMessage(content, type, isMarkdown = false) {
@@ -1858,8 +1988,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
1858
1988
  const wrapper = document.createElement("div");
1859
1989
  wrapper.className = `message ${type}`;
1860
1990
  if (isMarkdown) {
1861
- const cleanReply = content.replace(/}```/g, "}\n```").replace(/```(\S)/g, "```\n$1");
1862
- wrapper.innerHTML = d.parse(cleanReply);
1991
+ const cleanReply = this.fixMarkdown(content);
1992
+ const contentDiv = document.createElement("div");
1993
+ contentDiv.className = "content";
1994
+ contentDiv.innerHTML = d.parse(cleanReply);
1995
+ wrapper.appendChild(contentDiv);
1863
1996
  } else {
1864
1997
  wrapper.textContent = content;
1865
1998
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "advaisor-chatbot",
3
- "version": "1.7.0",
3
+ "version": "1.7.1-beta.1",
4
4
  "description": "Embeddable chatbot component",
5
5
  "main": "dist/testchatbot.js",
6
6
  "scripts": {