advaisor-chatbot 1.6.0 → 1.7.1-beta.0
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/testchatbot.js +344 -215
- package/package.json +1 -1
package/dist/testchatbot.js
CHANGED
|
@@ -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,215 +1400,238 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1399
1400
|
}
|
|
1400
1401
|
render() {
|
|
1401
1402
|
this.shadowRoot.innerHTML = `
|
|
1402
|
-
<
|
|
1403
|
-
|
|
1404
|
-
:
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
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
|
-
|
|
1446
|
-
|
|
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
|
-
|
|
1449
|
-
overflow: hidden;
|
|
1431
|
+
.chat-trigger:hover { transform: scale(1.05); }
|
|
1450
1432
|
|
|
1451
|
-
|
|
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
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1452
|
+
.chat-window.expanded {
|
|
1453
|
+
width: min(700px, 95vw);
|
|
1454
|
+
height: 90vh;
|
|
1455
|
+
}
|
|
1457
1456
|
|
|
1458
|
-
|
|
1457
|
+
@media (max-width: 768px) {
|
|
1458
|
+
.chat-window,
|
|
1459
1459
|
.chat-window.expanded {
|
|
1460
|
-
width:
|
|
1461
|
-
|
|
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
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
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
|
+
}
|
|
1473
1480
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
align-items: center;
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
.chat-body {
|
|
1485
|
-
flex: 1;
|
|
1486
|
-
overflow-y: auto;
|
|
1487
|
-
overflow-x: hidden;
|
|
1488
|
-
}
|
|
1481
|
+
.close-btn, .resize-btn, .history-btn {
|
|
1482
|
+
background: none;
|
|
1483
|
+
border: none;
|
|
1484
|
+
color: white;
|
|
1485
|
+
cursor: pointer;
|
|
1486
|
+
font-size: 16px;
|
|
1487
|
+
}
|
|
1489
1488
|
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
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
|
+
}
|
|
1494
1499
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
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
|
+
}
|
|
1500
1509
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
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
|
+
}
|
|
1509
1518
|
|
|
1510
|
-
|
|
1519
|
+
.message.bot {
|
|
1520
|
+
align-self: flex-start;
|
|
1521
|
+
display: flex;
|
|
1522
|
+
flex-direction: column;
|
|
1523
|
+
align-items: flex-start;
|
|
1524
|
+
gap: 4px;
|
|
1525
|
+
}
|
|
1511
1526
|
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
}
|
|
1527
|
+
.message.user {
|
|
1528
|
+
align-self: flex-end;
|
|
1529
|
+
background: var(--user-bubble);
|
|
1530
|
+
color: white;
|
|
1531
|
+
padding: 8px 16px;
|
|
1532
|
+
border-radius: 18px 18px 4px 18px;
|
|
1533
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
|
1534
|
+
}
|
|
1521
1535
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1536
|
+
/* Bot message content bubble */
|
|
1537
|
+
.message.bot .content {
|
|
1538
|
+
background: var(--bot-bubble);
|
|
1539
|
+
color: #1f2937;
|
|
1540
|
+
padding: 8px 16px;
|
|
1541
|
+
border-radius: 18px 18px 18px 4px;
|
|
1542
|
+
word-wrap: break-word;
|
|
1543
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
|
1544
|
+
}
|
|
1529
1545
|
|
|
1530
|
-
|
|
1531
|
-
|
|
1546
|
+
.message.bot .content p {
|
|
1547
|
+
margin: 4px 0;
|
|
1548
|
+
}
|
|
1532
1549
|
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
padding: 12px;
|
|
1536
|
-
display: flex;
|
|
1537
|
-
gap: 8px;
|
|
1538
|
-
}
|
|
1550
|
+
.message.bot .content p:first-child { margin-top: 0; }
|
|
1551
|
+
.message.bot .content p:last-child { margin-bottom: 0; }
|
|
1539
1552
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
padding: 8px 12px;
|
|
1545
|
-
outline: none;
|
|
1546
|
-
}
|
|
1553
|
+
.message pre, .message code {
|
|
1554
|
+
white-space: pre-wrap;
|
|
1555
|
+
word-break: break-word;
|
|
1556
|
+
}
|
|
1547
1557
|
|
|
1548
|
-
|
|
1558
|
+
/* Status message (outside bubble) */
|
|
1559
|
+
.status-message {
|
|
1560
|
+
font-style: italic;
|
|
1561
|
+
color: #888;
|
|
1562
|
+
font-size: 0.85em;
|
|
1563
|
+
padding: 4px 12px;
|
|
1564
|
+
margin: 2px 0;
|
|
1565
|
+
background: transparent;
|
|
1566
|
+
border-radius: 12px;
|
|
1567
|
+
display: inline-block;
|
|
1568
|
+
max-width: 80%;
|
|
1569
|
+
}
|
|
1549
1570
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1571
|
+
/* Typing indicator as message bubble */
|
|
1572
|
+
.typing-indicator {
|
|
1573
|
+
display: inline-flex;
|
|
1574
|
+
align-items: center;
|
|
1575
|
+
gap: 4px;
|
|
1576
|
+
padding: 8px 16px;
|
|
1577
|
+
background: var(--bot-bubble);
|
|
1578
|
+
border-radius: 18px 18px 18px 4px;
|
|
1579
|
+
margin: 4px 0;
|
|
1580
|
+
max-width: fit-content;
|
|
1581
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
|
1582
|
+
}
|
|
1559
1583
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1584
|
+
.typing-indicator span {
|
|
1585
|
+
width: 8px;
|
|
1586
|
+
height: 8px;
|
|
1587
|
+
background: #666;
|
|
1588
|
+
border-radius: 50%;
|
|
1589
|
+
display: inline-block;
|
|
1590
|
+
animation: typingBounce 1.4s infinite ease-in-out both;
|
|
1591
|
+
}
|
|
1567
1592
|
|
|
1593
|
+
.typing-indicator span:nth-child(1) { animation-delay: -0.32s; }
|
|
1594
|
+
.typing-indicator span:nth-child(2) { animation-delay: -0.16s; }
|
|
1595
|
+
.typing-indicator span:nth-child(3) { animation-delay: 0; }
|
|
1568
1596
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
border-radius: 50%;
|
|
1574
|
-
animation: blink 1.4s infinite;
|
|
1575
|
-
}
|
|
1597
|
+
@keyframes typingBounce {
|
|
1598
|
+
0%, 80%, 100% { transform: scale(0.6); opacity: 0.6; }
|
|
1599
|
+
40% { transform: scale(1); opacity: 1; }
|
|
1600
|
+
}
|
|
1576
1601
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1602
|
+
.input-area {
|
|
1603
|
+
border-top: 1px solid #e5e7eb;
|
|
1604
|
+
padding: 12px;
|
|
1605
|
+
display: flex;
|
|
1606
|
+
gap: 8px;
|
|
1607
|
+
}
|
|
1579
1608
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1609
|
+
input {
|
|
1610
|
+
flex: 1;
|
|
1611
|
+
border: 1px solid #e5e7eb;
|
|
1612
|
+
border-radius: 6px;
|
|
1613
|
+
padding: 8px 12px;
|
|
1614
|
+
outline: none;
|
|
1615
|
+
}
|
|
1584
1616
|
|
|
1585
|
-
|
|
1586
|
-
opacity: 0.6;
|
|
1587
|
-
cursor: not-allowed;
|
|
1588
|
-
}
|
|
1617
|
+
input:focus { border-color: var(--primary-color); }
|
|
1589
1618
|
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1619
|
+
.send-btn {
|
|
1620
|
+
background: var(--user-bubble);
|
|
1621
|
+
color: white;
|
|
1622
|
+
border: none;
|
|
1623
|
+
padding: 0 16px;
|
|
1624
|
+
border-radius: 6px;
|
|
1625
|
+
cursor: pointer;
|
|
1626
|
+
}
|
|
1595
1627
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
color: white;
|
|
1604
|
-
font-size: 14px;
|
|
1605
|
-
display: flex;
|
|
1606
|
-
align-items: center;
|
|
1607
|
-
justify-content: center;
|
|
1608
|
-
margin-top: 4px;
|
|
1609
|
-
}
|
|
1610
|
-
</style>
|
|
1628
|
+
.send-btn:disabled {
|
|
1629
|
+
opacity: 0.6;
|
|
1630
|
+
cursor: not-allowed;
|
|
1631
|
+
}
|
|
1632
|
+
</style>
|
|
1633
|
+
|
|
1634
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
|
1611
1635
|
|
|
1612
1636
|
<button class="chat-trigger" id="trigger">\u{1F4AC}</button>
|
|
1613
1637
|
|
|
@@ -1651,6 +1675,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1651
1675
|
const historyBtn = this.shadowRoot.getElementById("history");
|
|
1652
1676
|
const sidebar = this.shadowRoot.getElementById("sidebar");
|
|
1653
1677
|
sidebar.addEventListener("new-chat", () => {
|
|
1678
|
+
if (this.abortController) {
|
|
1679
|
+
this.abortController.abort();
|
|
1680
|
+
this.abortController = null;
|
|
1681
|
+
}
|
|
1654
1682
|
this.activeSessionId = null;
|
|
1655
1683
|
const body2 = this.shadowRoot.getElementById("body");
|
|
1656
1684
|
body2.innerHTML = `<div class="message bot">Hi ${this.userName}! How can I help?</div>`;
|
|
@@ -1679,6 +1707,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1679
1707
|
body.scrollTop = body.scrollHeight;
|
|
1680
1708
|
};
|
|
1681
1709
|
closeBtn.onclick = () => {
|
|
1710
|
+
if (this.abortController) {
|
|
1711
|
+
this.abortController.abort();
|
|
1712
|
+
this.abortController = null;
|
|
1713
|
+
}
|
|
1682
1714
|
windowEl.style.display = "none";
|
|
1683
1715
|
trigger.style.display = "flex";
|
|
1684
1716
|
};
|
|
@@ -1692,6 +1724,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1692
1724
|
const sendMessage = async () => {
|
|
1693
1725
|
const text = input.value.trim();
|
|
1694
1726
|
if (!text) return;
|
|
1727
|
+
if (this.abortController) {
|
|
1728
|
+
this.abortController.abort();
|
|
1729
|
+
this.abortController = null;
|
|
1730
|
+
}
|
|
1695
1731
|
input.disabled = true;
|
|
1696
1732
|
sendBtn.disabled = true;
|
|
1697
1733
|
const userMsg = document.createElement("div");
|
|
@@ -1700,21 +1736,39 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1700
1736
|
body.appendChild(userMsg);
|
|
1701
1737
|
input.value = "";
|
|
1702
1738
|
body.scrollTop = body.scrollHeight;
|
|
1739
|
+
const botMessageContainer = document.createElement("div");
|
|
1740
|
+
botMessageContainer.className = "message bot";
|
|
1741
|
+
const contentDiv = document.createElement("div");
|
|
1742
|
+
contentDiv.className = "content";
|
|
1743
|
+
contentDiv.id = "answer-content";
|
|
1703
1744
|
const typingDiv = document.createElement("div");
|
|
1704
|
-
typingDiv.className = "
|
|
1745
|
+
typingDiv.className = "typing-indicator";
|
|
1705
1746
|
typingDiv.id = "typing-indicator";
|
|
1706
1747
|
typingDiv.innerHTML = `
|
|
1707
|
-
<
|
|
1708
|
-
<span></span><span></span><span></span>
|
|
1709
|
-
</div>
|
|
1748
|
+
<span></span><span></span><span></span>
|
|
1710
1749
|
`;
|
|
1711
|
-
|
|
1750
|
+
const statusDiv = document.createElement("div");
|
|
1751
|
+
statusDiv.className = "status-message";
|
|
1752
|
+
statusDiv.id = "status-message";
|
|
1753
|
+
botMessageContainer.appendChild(contentDiv);
|
|
1754
|
+
botMessageContainer.appendChild(typingDiv);
|
|
1755
|
+
botMessageContainer.appendChild(statusDiv);
|
|
1756
|
+
body.appendChild(botMessageContainer);
|
|
1712
1757
|
body.scrollTop = body.scrollHeight;
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1758
|
+
const timeoutId = setTimeout(() => {
|
|
1759
|
+
if (this.abortController) {
|
|
1760
|
+
this.abortController.abort();
|
|
1761
|
+
this.abortController = null;
|
|
1762
|
+
this.showErrorMessage(body, "Request timed out after 30 seconds. Please try again.");
|
|
1763
|
+
botMessageContainer.remove();
|
|
1764
|
+
input.disabled = false;
|
|
1765
|
+
sendBtn.disabled = false;
|
|
1766
|
+
input.focus();
|
|
1767
|
+
}
|
|
1768
|
+
}, 3e4);
|
|
1716
1769
|
try {
|
|
1717
|
-
|
|
1770
|
+
this.abortController = new AbortController();
|
|
1771
|
+
const response = await fetch(this.apiEndpoint, {
|
|
1718
1772
|
method: "POST",
|
|
1719
1773
|
headers: {
|
|
1720
1774
|
"Content-Type": "application/json",
|
|
@@ -1727,36 +1781,90 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1727
1781
|
bookshelf_name: "All Bookshelves",
|
|
1728
1782
|
package_id: 30,
|
|
1729
1783
|
user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
1730
|
-
})
|
|
1784
|
+
}),
|
|
1785
|
+
signal: this.abortController.signal
|
|
1731
1786
|
});
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1787
|
+
clearTimeout(timeoutId);
|
|
1788
|
+
if (!response.ok) {
|
|
1789
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1790
|
+
}
|
|
1791
|
+
const reader = response.body.getReader();
|
|
1792
|
+
const decoder = new TextDecoder("utf-8");
|
|
1793
|
+
let buffer = "";
|
|
1794
|
+
let accumulatedAnswer = "";
|
|
1795
|
+
let lastStatusMessage = "";
|
|
1796
|
+
while (true) {
|
|
1797
|
+
const { value, done } = await reader.read();
|
|
1798
|
+
if (done) break;
|
|
1799
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1800
|
+
const events = buffer.split("\n\n");
|
|
1801
|
+
buffer = events.pop();
|
|
1802
|
+
for (const event of events) {
|
|
1803
|
+
const match = event.match(/^data: (.+)$/m);
|
|
1804
|
+
if (!match) continue;
|
|
1805
|
+
const jsonStr = match[1].trim();
|
|
1806
|
+
try {
|
|
1807
|
+
const data = JSON.parse(jsonStr);
|
|
1808
|
+
if (data.type === "message") {
|
|
1809
|
+
lastStatusMessage = data.text;
|
|
1810
|
+
statusDiv.textContent = data.text;
|
|
1811
|
+
typingDiv.style.display = "none";
|
|
1812
|
+
}
|
|
1813
|
+
if (data.type === "answer") {
|
|
1814
|
+
typingDiv.style.display = "none";
|
|
1815
|
+
if (data.session_id) {
|
|
1816
|
+
this.activeSessionId = data.session_id;
|
|
1817
|
+
}
|
|
1818
|
+
if (accumulatedAnswer && !accumulatedAnswer.endsWith("\n\n")) {
|
|
1819
|
+
accumulatedAnswer += "\n\n";
|
|
1820
|
+
}
|
|
1821
|
+
const newText = data.text;
|
|
1822
|
+
accumulatedAnswer += newText;
|
|
1823
|
+
const words = newText.split(" ");
|
|
1824
|
+
let currentDisplayText = accumulatedAnswer.substring(0, accumulatedAnswer.length - newText.length);
|
|
1825
|
+
if (currentDisplayText) {
|
|
1826
|
+
const cleanExisting = this.fixMarkdown(currentDisplayText);
|
|
1827
|
+
const htmlExisting = d.parse(cleanExisting);
|
|
1828
|
+
contentDiv.innerHTML = htmlExisting;
|
|
1829
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1830
|
+
}
|
|
1831
|
+
for (let i = 0; i < words.length; i++) {
|
|
1832
|
+
currentDisplayText += (i > 0 || currentDisplayText ? " " : "") + words[i];
|
|
1833
|
+
const cleanReply = this.fixMarkdown(currentDisplayText + (i < words.length - 1 ? " ..." : ""));
|
|
1834
|
+
const htmlReply = d.parse(cleanReply);
|
|
1835
|
+
contentDiv.innerHTML = htmlReply;
|
|
1836
|
+
if (i < words.length - 1) {
|
|
1837
|
+
await new Promise((resolve) => setTimeout(resolve, 30));
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
if (data.is_last) {
|
|
1842
|
+
statusDiv.remove();
|
|
1843
|
+
typingDiv.style.display = "none";
|
|
1844
|
+
const cleanReply = this.fixMarkdown(accumulatedAnswer);
|
|
1845
|
+
const htmlReply = d.parse(cleanReply);
|
|
1846
|
+
contentDiv.innerHTML = htmlReply;
|
|
1847
|
+
break;
|
|
1848
|
+
}
|
|
1849
|
+
} catch (parseError) {
|
|
1850
|
+
console.error("Error parsing JSON:", jsonStr, parseError);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1736
1853
|
}
|
|
1737
|
-
const botReply = response?.answer || "No response received.";
|
|
1738
|
-
d.setOptions({
|
|
1739
|
-
breaks: true,
|
|
1740
|
-
gfm: true
|
|
1741
|
-
});
|
|
1742
|
-
const cleanReply = fixMarkdown(botReply);
|
|
1743
|
-
const htmlReply = d.parse(cleanReply);
|
|
1744
|
-
const wrapper = document.createElement("div");
|
|
1745
|
-
wrapper.className = "message bot";
|
|
1746
|
-
wrapper.innerHTML = htmlReply;
|
|
1747
|
-
body.appendChild(wrapper);
|
|
1748
|
-
body.scrollTop = body.scrollHeight;
|
|
1749
1854
|
} catch (error) {
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1855
|
+
clearTimeout(timeoutId);
|
|
1856
|
+
botMessageContainer.remove();
|
|
1857
|
+
if (error.name === "AbortError") {
|
|
1858
|
+
console.log("Stream aborted");
|
|
1859
|
+
} else {
|
|
1860
|
+
this.showErrorMessage(body, "Sorry, something went wrong. Please try again.");
|
|
1861
|
+
console.error("Stream error:", error);
|
|
1862
|
+
}
|
|
1756
1863
|
} finally {
|
|
1757
1864
|
input.disabled = false;
|
|
1758
1865
|
sendBtn.disabled = false;
|
|
1759
1866
|
input.focus();
|
|
1867
|
+
this.abortController = null;
|
|
1760
1868
|
}
|
|
1761
1869
|
};
|
|
1762
1870
|
sendBtn.onclick = sendMessage;
|
|
@@ -1823,7 +1931,21 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1823
1931
|
}
|
|
1824
1932
|
});
|
|
1825
1933
|
}
|
|
1934
|
+
fixMarkdown(text) {
|
|
1935
|
+
return text.replace(/}```/g, "}\n```").replace(/```(\S)/g, "```\n$1");
|
|
1936
|
+
}
|
|
1937
|
+
showErrorMessage(body, message) {
|
|
1938
|
+
const errorMsg = document.createElement("div");
|
|
1939
|
+
errorMsg.className = "message bot error-message";
|
|
1940
|
+
errorMsg.textContent = message;
|
|
1941
|
+
body.appendChild(errorMsg);
|
|
1942
|
+
body.scrollTop = body.scrollHeight;
|
|
1943
|
+
}
|
|
1826
1944
|
async loadSession(sessionId) {
|
|
1945
|
+
if (this.abortController) {
|
|
1946
|
+
this.abortController.abort();
|
|
1947
|
+
this.abortController = null;
|
|
1948
|
+
}
|
|
1827
1949
|
this.activeSessionId = sessionId;
|
|
1828
1950
|
const body = this.shadowRoot.getElementById("body");
|
|
1829
1951
|
body.innerHTML = `<div class="message bot">Loading conversation...</div>`;
|
|
@@ -1841,6 +1963,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1841
1963
|
})
|
|
1842
1964
|
}
|
|
1843
1965
|
);
|
|
1966
|
+
if (!res.ok) {
|
|
1967
|
+
throw new Error(`HTTP error! status: ${res.status}`);
|
|
1968
|
+
}
|
|
1844
1969
|
const data = await res.json();
|
|
1845
1970
|
const history = data?.body?.chat_history || [];
|
|
1846
1971
|
body.innerHTML = "";
|
|
@@ -1850,6 +1975,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1850
1975
|
});
|
|
1851
1976
|
} catch (err) {
|
|
1852
1977
|
console.error("Failed to load session", err);
|
|
1978
|
+
body.innerHTML = `<div class="message bot error-message">Failed to load conversation. Please try again.</div>`;
|
|
1853
1979
|
}
|
|
1854
1980
|
}
|
|
1855
1981
|
renderMessage(content, type, isMarkdown = false) {
|
|
@@ -1857,8 +1983,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
1857
1983
|
const wrapper = document.createElement("div");
|
|
1858
1984
|
wrapper.className = `message ${type}`;
|
|
1859
1985
|
if (isMarkdown) {
|
|
1860
|
-
const cleanReply =
|
|
1861
|
-
|
|
1986
|
+
const cleanReply = this.fixMarkdown(content);
|
|
1987
|
+
const contentDiv = document.createElement("div");
|
|
1988
|
+
contentDiv.className = "content";
|
|
1989
|
+
contentDiv.innerHTML = d.parse(cleanReply);
|
|
1990
|
+
wrapper.appendChild(contentDiv);
|
|
1862
1991
|
} else {
|
|
1863
1992
|
wrapper.textContent = content;
|
|
1864
1993
|
}
|