@informedai/react 0.4.14 → 0.4.16

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/index.js CHANGED
@@ -20,9 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ AdminChatbot: () => AdminChatbot,
23
24
  InformedAIClient: () => InformedAIClient,
24
25
  InformedAIProvider: () => InformedAIProvider,
25
26
  InformedAssistant: () => InformedAssistant,
27
+ WebsiteChatbot: () => WebsiteChatbot,
26
28
  useInformedAI: () => useInformedAI,
27
29
  useSession: () => useSession
28
30
  });
@@ -1301,19 +1303,1008 @@ function LoadingSpinner({ size = 20 }) {
1301
1303
  );
1302
1304
  }
1303
1305
 
1304
- // src/hooks/useSession.ts
1306
+ // src/components/AdminChatbot.tsx
1305
1307
  var import_react3 = require("react");
1306
- function useSession(options) {
1307
- const { apiUrl, documentTypeId, sessionId, onSessionChange, onError } = options;
1308
- const [session, setSession] = (0, import_react3.useState)(null);
1309
- const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
1308
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1309
+ var defaultTheme2 = {
1310
+ primaryColor: "#3b82f6",
1311
+ // Blue (different from widget's amber)
1312
+ backgroundColor: "#ffffff",
1313
+ textColor: "#1c1917",
1314
+ borderRadius: "12px",
1315
+ fontFamily: "system-ui, -apple-system, sans-serif"
1316
+ };
1317
+ function AdminChatbot({ className, ...config }) {
1318
+ const theme = { ...defaultTheme2, ...config.theme };
1319
+ const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
1320
+ const [messages, setMessages] = (0, import_react3.useState)([]);
1321
+ const [inputValue, setInputValue] = (0, import_react3.useState)("");
1322
+ const [systemPrompt, setSystemPrompt] = (0, import_react3.useState)(config.systemPrompt || "");
1323
+ const [showSystemPromptEditor, setShowSystemPromptEditor] = (0, import_react3.useState)(false);
1324
+ const [isStreaming, setIsStreaming] = (0, import_react3.useState)(false);
1325
+ const [streamingContent, setStreamingContent] = (0, import_react3.useState)("");
1310
1326
  const [error, setError] = (0, import_react3.useState)(null);
1311
- const clientRef = (0, import_react3.useRef)(null);
1312
- const isStreamingRef = (0, import_react3.useRef)(false);
1327
+ const [isCollapsed, setIsCollapsed] = (0, import_react3.useState)(config.defaultCollapsed ?? false);
1328
+ const messagesEndRef = (0, import_react3.useRef)(null);
1329
+ const inputRef = (0, import_react3.useRef)(null);
1313
1330
  (0, import_react3.useEffect)(() => {
1331
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1332
+ }, [messages, streamingContent]);
1333
+ const sendMessage = async (message) => {
1334
+ if (!message.trim() || isStreaming) return;
1335
+ setError(null);
1336
+ setIsStreaming(true);
1337
+ setStreamingContent("");
1338
+ const newMessages = [...messages, { role: "user", content: message }];
1339
+ setMessages(newMessages);
1340
+ try {
1341
+ const response = await fetch(`${apiUrl}/admin-chatbot/message`, {
1342
+ method: "POST",
1343
+ headers: {
1344
+ "Content-Type": "application/json",
1345
+ Authorization: `Bearer ${config.apiKey}`
1346
+ },
1347
+ body: JSON.stringify({
1348
+ message,
1349
+ history: messages,
1350
+ // Send previous messages (not including current)
1351
+ systemPrompt: systemPrompt || void 0
1352
+ })
1353
+ });
1354
+ if (!response.ok) {
1355
+ const err = await response.json().catch(() => ({ error: "Request failed" }));
1356
+ throw new Error(err.error || `HTTP ${response.status}`);
1357
+ }
1358
+ const reader = response.body?.getReader();
1359
+ if (!reader) throw new Error("No response body");
1360
+ const decoder = new TextDecoder();
1361
+ let buffer = "";
1362
+ let fullContent = "";
1363
+ while (true) {
1364
+ const { done, value } = await reader.read();
1365
+ if (done) break;
1366
+ buffer += decoder.decode(value, { stream: true });
1367
+ const lines = buffer.split("\n");
1368
+ buffer = lines.pop() || "";
1369
+ for (const line of lines) {
1370
+ if (line.startsWith("event:")) continue;
1371
+ if (line.startsWith("data:")) {
1372
+ const data = line.slice(5).trim();
1373
+ try {
1374
+ const parsed = JSON.parse(data);
1375
+ if (parsed.content) {
1376
+ fullContent += parsed.content;
1377
+ setStreamingContent(fullContent);
1378
+ }
1379
+ if (parsed.fullContent) {
1380
+ fullContent = parsed.fullContent;
1381
+ }
1382
+ } catch {
1383
+ }
1384
+ }
1385
+ }
1386
+ }
1387
+ setMessages([...newMessages, { role: "assistant", content: fullContent }]);
1388
+ setStreamingContent("");
1389
+ } catch (err) {
1390
+ setError(err instanceof Error ? err.message : "Failed to send message");
1391
+ } finally {
1392
+ setIsStreaming(false);
1393
+ }
1394
+ };
1395
+ const handleSubmit = (e) => {
1396
+ e.preventDefault();
1397
+ if (!inputValue.trim() || isStreaming) return;
1398
+ const message = inputValue.trim();
1399
+ setInputValue("");
1400
+ sendMessage(message);
1401
+ };
1402
+ const clearConversation = () => {
1403
+ setMessages([]);
1404
+ setStreamingContent("");
1405
+ setError(null);
1406
+ };
1407
+ const cssVars = {
1408
+ "--ac-primary": theme.primaryColor,
1409
+ "--ac-bg": theme.backgroundColor,
1410
+ "--ac-text": theme.textColor,
1411
+ "--ac-radius": theme.borderRadius,
1412
+ "--ac-font": theme.fontFamily
1413
+ };
1414
+ const positionStyles = config.position === "inline" ? {} : {
1415
+ position: "fixed",
1416
+ [config.position === "bottom-left" ? "left" : "right"]: "20px",
1417
+ bottom: "20px",
1418
+ zIndex: 9999
1419
+ };
1420
+ if (isCollapsed && config.position !== "inline") {
1421
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1422
+ "button",
1423
+ {
1424
+ onClick: () => setIsCollapsed(false),
1425
+ className,
1426
+ style: {
1427
+ ...cssVars,
1428
+ ...positionStyles,
1429
+ width: "56px",
1430
+ height: "56px",
1431
+ borderRadius: "50%",
1432
+ backgroundColor: "var(--ac-primary)",
1433
+ color: "white",
1434
+ border: "none",
1435
+ cursor: "pointer",
1436
+ display: "flex",
1437
+ alignItems: "center",
1438
+ justifyContent: "center",
1439
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
1440
+ fontFamily: "var(--ac-font)"
1441
+ },
1442
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
1443
+ }
1444
+ );
1445
+ }
1446
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1447
+ "div",
1448
+ {
1449
+ className,
1450
+ style: {
1451
+ ...cssVars,
1452
+ ...positionStyles,
1453
+ width: config.position === "inline" ? "100%" : "400px",
1454
+ maxHeight: config.position === "inline" ? "600px" : "80vh",
1455
+ backgroundColor: "var(--ac-bg)",
1456
+ borderRadius: "var(--ac-radius)",
1457
+ border: "1px solid #e5e5e5",
1458
+ fontFamily: "var(--ac-font)",
1459
+ display: "flex",
1460
+ flexDirection: "column",
1461
+ boxShadow: config.position === "inline" ? "none" : "0 4px 20px rgba(0,0,0,0.15)",
1462
+ overflow: "hidden"
1463
+ },
1464
+ children: [
1465
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1466
+ "div",
1467
+ {
1468
+ style: {
1469
+ padding: "16px",
1470
+ borderBottom: "1px solid #e5e5e5",
1471
+ display: "flex",
1472
+ alignItems: "center",
1473
+ justifyContent: "space-between",
1474
+ backgroundColor: "var(--ac-primary)",
1475
+ color: "white"
1476
+ },
1477
+ children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1479
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
1481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 16v-4M12 8h.01" })
1482
+ ] }),
1483
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontWeight: 600 }, children: config.title || "Knowledge Library" })
1484
+ ] }),
1485
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
1486
+ config.allowEditSystemPrompt && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1487
+ "button",
1488
+ {
1489
+ onClick: () => setShowSystemPromptEditor(!showSystemPromptEditor),
1490
+ style: {
1491
+ background: "rgba(255,255,255,0.2)",
1492
+ border: "none",
1493
+ borderRadius: "4px",
1494
+ padding: "4px 8px",
1495
+ color: "white",
1496
+ cursor: "pointer",
1497
+ fontSize: "12px"
1498
+ },
1499
+ children: showSystemPromptEditor ? "Hide Prompt" : "Edit Prompt"
1500
+ }
1501
+ ),
1502
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1503
+ "button",
1504
+ {
1505
+ onClick: clearConversation,
1506
+ style: {
1507
+ background: "rgba(255,255,255,0.2)",
1508
+ border: "none",
1509
+ borderRadius: "4px",
1510
+ padding: "4px 8px",
1511
+ color: "white",
1512
+ cursor: "pointer",
1513
+ fontSize: "12px"
1514
+ },
1515
+ children: "Clear"
1516
+ }
1517
+ ),
1518
+ config.position !== "inline" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1519
+ "button",
1520
+ {
1521
+ onClick: () => setIsCollapsed(true),
1522
+ style: {
1523
+ background: "none",
1524
+ border: "none",
1525
+ color: "white",
1526
+ cursor: "pointer",
1527
+ padding: "4px"
1528
+ },
1529
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1530
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1531
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1532
+ ] })
1533
+ }
1534
+ )
1535
+ ] })
1536
+ ]
1537
+ }
1538
+ ),
1539
+ showSystemPromptEditor && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { padding: "12px", borderBottom: "1px solid #e5e5e5", backgroundColor: "#f9fafb" }, children: [
1540
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { style: { display: "block", fontSize: "12px", fontWeight: 500, marginBottom: "4px", color: "#6b7280" }, children: "System Prompt" }),
1541
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1542
+ "textarea",
1543
+ {
1544
+ value: systemPrompt,
1545
+ onChange: (e) => setSystemPrompt(e.target.value),
1546
+ placeholder: "Enter a system prompt to guide the chatbot's behavior...",
1547
+ style: {
1548
+ width: "100%",
1549
+ minHeight: "80px",
1550
+ padding: "8px",
1551
+ borderRadius: "6px",
1552
+ border: "1px solid #d1d5db",
1553
+ fontSize: "13px",
1554
+ fontFamily: "var(--ac-font)",
1555
+ resize: "vertical"
1556
+ }
1557
+ }
1558
+ )
1559
+ ] }),
1560
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1561
+ "div",
1562
+ {
1563
+ style: {
1564
+ flex: 1,
1565
+ overflowY: "auto",
1566
+ padding: "16px",
1567
+ display: "flex",
1568
+ flexDirection: "column",
1569
+ gap: "12px",
1570
+ minHeight: "200px"
1571
+ },
1572
+ children: [
1573
+ messages.length === 0 && !streamingContent && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { textAlign: "center", color: "#9ca3af", padding: "40px 20px" }, children: [
1574
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1575
+ "svg",
1576
+ {
1577
+ width: "48",
1578
+ height: "48",
1579
+ viewBox: "0 0 24 24",
1580
+ fill: "none",
1581
+ stroke: "currentColor",
1582
+ strokeWidth: "1.5",
1583
+ style: { margin: "0 auto 16px" },
1584
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
1585
+ }
1586
+ ),
1587
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: { margin: 0, fontSize: "14px" }, children: "Ask a question about your knowledge library" })
1588
+ ] }),
1589
+ messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1590
+ "div",
1591
+ {
1592
+ style: {
1593
+ alignSelf: msg.role === "user" ? "flex-end" : "flex-start",
1594
+ maxWidth: "85%"
1595
+ },
1596
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1597
+ "div",
1598
+ {
1599
+ style: {
1600
+ padding: "10px 14px",
1601
+ borderRadius: "12px",
1602
+ backgroundColor: msg.role === "user" ? "var(--ac-primary)" : "#f3f4f6",
1603
+ color: msg.role === "user" ? "white" : "var(--ac-text)",
1604
+ fontSize: "14px",
1605
+ lineHeight: "1.5",
1606
+ whiteSpace: "pre-wrap"
1607
+ },
1608
+ children: msg.content
1609
+ }
1610
+ )
1611
+ },
1612
+ i
1613
+ )),
1614
+ streamingContent && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { alignSelf: "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1615
+ "div",
1616
+ {
1617
+ style: {
1618
+ padding: "10px 14px",
1619
+ borderRadius: "12px",
1620
+ backgroundColor: "#f3f4f6",
1621
+ color: "var(--ac-text)",
1622
+ fontSize: "14px",
1623
+ lineHeight: "1.5",
1624
+ whiteSpace: "pre-wrap"
1625
+ },
1626
+ children: [
1627
+ streamingContent,
1628
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
1629
+ ]
1630
+ }
1631
+ ) }),
1632
+ error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1633
+ "div",
1634
+ {
1635
+ style: {
1636
+ padding: "10px 14px",
1637
+ borderRadius: "8px",
1638
+ backgroundColor: "#fef2f2",
1639
+ color: "#dc2626",
1640
+ fontSize: "13px"
1641
+ },
1642
+ children: error
1643
+ }
1644
+ ),
1645
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: messagesEndRef })
1646
+ ]
1647
+ }
1648
+ ),
1649
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("form", { onSubmit: handleSubmit, style: { padding: "12px", borderTop: "1px solid #e5e5e5" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1651
+ "input",
1652
+ {
1653
+ ref: inputRef,
1654
+ type: "text",
1655
+ value: inputValue,
1656
+ onChange: (e) => setInputValue(e.target.value),
1657
+ placeholder: config.placeholder || "Ask a question...",
1658
+ disabled: isStreaming,
1659
+ style: {
1660
+ flex: 1,
1661
+ padding: "10px 14px",
1662
+ borderRadius: "8px",
1663
+ border: "1px solid #d1d5db",
1664
+ fontSize: "14px",
1665
+ fontFamily: "var(--ac-font)",
1666
+ outline: "none"
1667
+ }
1668
+ }
1669
+ ),
1670
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1671
+ "button",
1672
+ {
1673
+ type: "submit",
1674
+ disabled: isStreaming || !inputValue.trim(),
1675
+ style: {
1676
+ padding: "10px 16px",
1677
+ borderRadius: "8px",
1678
+ backgroundColor: isStreaming || !inputValue.trim() ? "#d1d5db" : "var(--ac-primary)",
1679
+ color: "white",
1680
+ border: "none",
1681
+ cursor: isStreaming || !inputValue.trim() ? "not-allowed" : "pointer",
1682
+ fontWeight: 500,
1683
+ fontSize: "14px"
1684
+ },
1685
+ children: isStreaming ? "..." : "Send"
1686
+ }
1687
+ )
1688
+ ] }) }),
1689
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
1690
+ @keyframes blink {
1691
+ 0%, 50% { opacity: 1; }
1692
+ 51%, 100% { opacity: 0; }
1693
+ }
1694
+ ` })
1695
+ ]
1696
+ }
1697
+ );
1698
+ }
1699
+
1700
+ // src/components/WebsiteChatbot.tsx
1701
+ var import_react4 = require("react");
1702
+
1703
+ // src/utils/card-parser.ts
1704
+ var CARD_MARKER_REGEX = /\[([A-Z][A-Z0-9_]*):([^\]]+)\]/g;
1705
+ function parseCardMarker(marker) {
1706
+ const match = marker.match(/^\[([A-Z][A-Z0-9_]*):([^\]]+)\]$/);
1707
+ if (!match) return null;
1708
+ const [, type, valuesStr] = match;
1709
+ const values = valuesStr.split("|").map((v) => v.trim());
1710
+ return {
1711
+ type,
1712
+ values,
1713
+ originalMarker: marker
1714
+ };
1715
+ }
1716
+ function parseMessageContent(content) {
1717
+ const segments = [];
1718
+ let lastIndex = 0;
1719
+ const matches = [...content.matchAll(CARD_MARKER_REGEX)];
1720
+ for (const match of matches) {
1721
+ const marker = match[0];
1722
+ const startIndex = match.index;
1723
+ if (startIndex > lastIndex) {
1724
+ const text = content.slice(lastIndex, startIndex).trim();
1725
+ if (text) {
1726
+ segments.push({ type: "text", content: text });
1727
+ }
1728
+ }
1729
+ const card = parseCardMarker(marker);
1730
+ if (card) {
1731
+ segments.push({ type: "card", card });
1732
+ }
1733
+ lastIndex = startIndex + marker.length;
1734
+ }
1735
+ if (lastIndex < content.length) {
1736
+ const text = content.slice(lastIndex).trim();
1737
+ if (text) {
1738
+ segments.push({ type: "text", content: text });
1739
+ }
1740
+ }
1741
+ if (segments.length === 0 && content.trim()) {
1742
+ segments.push({ type: "text", content: content.trim() });
1743
+ }
1744
+ return segments;
1745
+ }
1746
+ function isUrl(str) {
1747
+ return /^https?:\/\//i.test(str);
1748
+ }
1749
+ function isImageUrl(url) {
1750
+ if (!isUrl(url)) return false;
1751
+ return /\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/i.test(url);
1752
+ }
1753
+ function extractCardDisplayData(card) {
1754
+ const values = [...card.values];
1755
+ const result = {
1756
+ title: values[0] || card.type,
1757
+ extraValues: []
1758
+ };
1759
+ if (values.length <= 1) return result;
1760
+ const imageIndex = values.findIndex((v, i) => i > 0 && isImageUrl(v));
1761
+ if (imageIndex > 0) {
1762
+ result.imageUrl = values[imageIndex];
1763
+ values.splice(imageIndex, 1);
1764
+ }
1765
+ const actionIndex = values.findIndex((v, i) => i > 0 && isUrl(v) && !isImageUrl(v));
1766
+ if (actionIndex > 0) {
1767
+ result.actionUrl = values[actionIndex];
1768
+ result.actionLabel = "View";
1769
+ values.splice(actionIndex, 1);
1770
+ }
1771
+ const remaining = values.slice(1);
1772
+ if (remaining.length > 0) {
1773
+ if (remaining[0].length <= 50) {
1774
+ result.subtitle = remaining[0];
1775
+ remaining.shift();
1776
+ }
1777
+ }
1778
+ if (remaining.length > 0) {
1779
+ result.description = remaining[0];
1780
+ remaining.shift();
1781
+ }
1782
+ result.extraValues = remaining;
1783
+ return result;
1784
+ }
1785
+
1786
+ // src/components/WebsiteChatbot.tsx
1787
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1788
+ var defaultTheme3 = {
1789
+ primaryColor: "#f59e0b",
1790
+ // Amber
1791
+ backgroundColor: "#ffffff",
1792
+ textColor: "#1c1917",
1793
+ borderRadius: "12px",
1794
+ fontFamily: "system-ui, -apple-system, sans-serif"
1795
+ };
1796
+ function ChatCard({ card, theme }) {
1797
+ const data = extractCardDisplayData(card);
1798
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1799
+ "div",
1800
+ {
1801
+ style: {
1802
+ border: "1px solid #e5e7eb",
1803
+ borderRadius: "8px",
1804
+ overflow: "hidden",
1805
+ backgroundColor: "#fff",
1806
+ marginTop: "8px",
1807
+ marginBottom: "8px"
1808
+ },
1809
+ children: [
1810
+ data.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1811
+ "div",
1812
+ {
1813
+ style: {
1814
+ width: "100%",
1815
+ height: "140px",
1816
+ backgroundColor: "#f3f4f6",
1817
+ overflow: "hidden"
1818
+ },
1819
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1820
+ "img",
1821
+ {
1822
+ src: data.imageUrl,
1823
+ alt: data.title,
1824
+ style: {
1825
+ width: "100%",
1826
+ height: "100%",
1827
+ objectFit: "cover"
1828
+ },
1829
+ onError: (e) => {
1830
+ e.target.style.display = "none";
1831
+ }
1832
+ }
1833
+ )
1834
+ }
1835
+ ),
1836
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { padding: "12px" }, children: [
1837
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1838
+ "div",
1839
+ {
1840
+ style: {
1841
+ display: "inline-block",
1842
+ fontSize: "10px",
1843
+ fontWeight: 600,
1844
+ textTransform: "uppercase",
1845
+ letterSpacing: "0.5px",
1846
+ color: theme.primaryColor,
1847
+ backgroundColor: `${theme.primaryColor}15`,
1848
+ padding: "2px 6px",
1849
+ borderRadius: "4px",
1850
+ marginBottom: "6px"
1851
+ },
1852
+ children: card.type
1853
+ }
1854
+ ),
1855
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1856
+ "div",
1857
+ {
1858
+ style: {
1859
+ fontSize: "15px",
1860
+ fontWeight: 600,
1861
+ color: "#1f2937",
1862
+ marginBottom: "4px",
1863
+ lineHeight: "1.3"
1864
+ },
1865
+ children: data.title
1866
+ }
1867
+ ),
1868
+ data.subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1869
+ "div",
1870
+ {
1871
+ style: {
1872
+ fontSize: "13px",
1873
+ color: "#6b7280",
1874
+ marginBottom: "6px"
1875
+ },
1876
+ children: data.subtitle
1877
+ }
1878
+ ),
1879
+ data.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1880
+ "div",
1881
+ {
1882
+ style: {
1883
+ fontSize: "13px",
1884
+ color: "#4b5563",
1885
+ lineHeight: "1.4",
1886
+ marginBottom: "8px"
1887
+ },
1888
+ children: data.description
1889
+ }
1890
+ ),
1891
+ data.extraValues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1892
+ "div",
1893
+ {
1894
+ style: {
1895
+ fontSize: "12px",
1896
+ color: "#6b7280",
1897
+ marginBottom: "8px"
1898
+ },
1899
+ children: data.extraValues.join(" \u2022 ")
1900
+ }
1901
+ ),
1902
+ data.actionUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1903
+ "a",
1904
+ {
1905
+ href: data.actionUrl,
1906
+ target: "_blank",
1907
+ rel: "noopener noreferrer",
1908
+ style: {
1909
+ display: "inline-flex",
1910
+ alignItems: "center",
1911
+ gap: "4px",
1912
+ fontSize: "13px",
1913
+ fontWeight: 500,
1914
+ color: theme.primaryColor,
1915
+ textDecoration: "none",
1916
+ padding: "6px 12px",
1917
+ borderRadius: "6px",
1918
+ backgroundColor: `${theme.primaryColor}10`,
1919
+ transition: "background-color 0.2s"
1920
+ },
1921
+ onMouseEnter: (e) => {
1922
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}20`;
1923
+ },
1924
+ onMouseLeave: (e) => {
1925
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}10`;
1926
+ },
1927
+ children: [
1928
+ data.actionLabel || "View",
1929
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1930
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1931
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "15 3 21 3 21 9" }),
1932
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1933
+ ] })
1934
+ ]
1935
+ }
1936
+ )
1937
+ ] })
1938
+ ]
1939
+ }
1940
+ );
1941
+ }
1942
+ function MessageContent({ content, theme }) {
1943
+ const segments = parseMessageContent(content);
1944
+ if (segments.length === 1 && segments[0].type === "text") {
1945
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: segments[0].content });
1946
+ }
1947
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: segments.map((segment, index) => {
1948
+ if (segment.type === "text") {
1949
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: segment.content }, index);
1950
+ }
1951
+ if (segment.type === "card" && segment.card) {
1952
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatCard, { card: segment.card, theme }, index);
1953
+ }
1954
+ return null;
1955
+ }) });
1956
+ }
1957
+ function WebsiteChatbot({ className, ...config }) {
1958
+ const theme = { ...defaultTheme3, ...config.theme };
1959
+ const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
1960
+ const [messages, setMessages] = (0, import_react4.useState)([]);
1961
+ const [inputValue, setInputValue] = (0, import_react4.useState)("");
1962
+ const [isStreaming, setIsStreaming] = (0, import_react4.useState)(false);
1963
+ const [streamingContent, setStreamingContent] = (0, import_react4.useState)("");
1964
+ const [error, setError] = (0, import_react4.useState)(null);
1965
+ const [isCollapsed, setIsCollapsed] = (0, import_react4.useState)(config.defaultCollapsed ?? false);
1966
+ const messagesEndRef = (0, import_react4.useRef)(null);
1967
+ (0, import_react4.useEffect)(() => {
1968
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1969
+ }, [messages, streamingContent]);
1970
+ const sendMessage = async (message) => {
1971
+ if (!message.trim() || isStreaming) return;
1972
+ setError(null);
1973
+ setIsStreaming(true);
1974
+ setStreamingContent("");
1975
+ const newMessages = [...messages, { role: "user", content: message }];
1976
+ setMessages(newMessages);
1977
+ try {
1978
+ const response = await fetch(`${apiUrl}/website-agent/${config.agentId}/message`, {
1979
+ method: "POST",
1980
+ headers: {
1981
+ "Content-Type": "application/json"
1982
+ },
1983
+ body: JSON.stringify({
1984
+ message,
1985
+ history: messages
1986
+ })
1987
+ });
1988
+ if (!response.ok) {
1989
+ const err = await response.json().catch(() => ({ error: "Request failed" }));
1990
+ throw new Error(err.error || `HTTP ${response.status}`);
1991
+ }
1992
+ const reader = response.body?.getReader();
1993
+ if (!reader) throw new Error("No response body");
1994
+ const decoder = new TextDecoder();
1995
+ let buffer = "";
1996
+ let fullContent = "";
1997
+ while (true) {
1998
+ const { done, value } = await reader.read();
1999
+ if (done) break;
2000
+ buffer += decoder.decode(value, { stream: true });
2001
+ const lines = buffer.split("\n");
2002
+ buffer = lines.pop() || "";
2003
+ for (const line of lines) {
2004
+ if (line.startsWith("event:")) continue;
2005
+ if (line.startsWith("data:")) {
2006
+ const data = line.slice(5).trim();
2007
+ try {
2008
+ const parsed = JSON.parse(data);
2009
+ if (parsed.content) {
2010
+ fullContent += parsed.content;
2011
+ setStreamingContent(fullContent);
2012
+ }
2013
+ if (parsed.fullContent) {
2014
+ fullContent = parsed.fullContent;
2015
+ }
2016
+ } catch {
2017
+ }
2018
+ }
2019
+ }
2020
+ }
2021
+ setMessages([...newMessages, { role: "assistant", content: fullContent }]);
2022
+ setStreamingContent("");
2023
+ } catch (err) {
2024
+ setError(err instanceof Error ? err.message : "Failed to send message");
2025
+ } finally {
2026
+ setIsStreaming(false);
2027
+ }
2028
+ };
2029
+ const handleSubmit = (e) => {
2030
+ e.preventDefault();
2031
+ if (!inputValue.trim() || isStreaming) return;
2032
+ const message = inputValue.trim();
2033
+ setInputValue("");
2034
+ sendMessage(message);
2035
+ };
2036
+ const clearConversation = () => {
2037
+ setMessages([]);
2038
+ setStreamingContent("");
2039
+ setError(null);
2040
+ };
2041
+ const cssVars = {
2042
+ "--wc-primary": theme.primaryColor,
2043
+ "--wc-bg": theme.backgroundColor,
2044
+ "--wc-text": theme.textColor,
2045
+ "--wc-radius": theme.borderRadius,
2046
+ "--wc-font": theme.fontFamily
2047
+ };
2048
+ const positionStyles = config.position === "inline" ? {} : {
2049
+ position: "fixed",
2050
+ [config.position === "bottom-left" ? "left" : "right"]: "20px",
2051
+ bottom: "20px",
2052
+ zIndex: 9999
2053
+ };
2054
+ if (isCollapsed && config.position !== "inline") {
2055
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2056
+ "button",
2057
+ {
2058
+ onClick: () => setIsCollapsed(false),
2059
+ className,
2060
+ style: {
2061
+ ...cssVars,
2062
+ ...positionStyles,
2063
+ width: "56px",
2064
+ height: "56px",
2065
+ borderRadius: "50%",
2066
+ backgroundColor: "var(--wc-primary)",
2067
+ color: "white",
2068
+ border: "none",
2069
+ cursor: "pointer",
2070
+ display: "flex",
2071
+ alignItems: "center",
2072
+ justifyContent: "center",
2073
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
2074
+ fontFamily: "var(--wc-font)"
2075
+ },
2076
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
2077
+ }
2078
+ );
2079
+ }
2080
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2081
+ "div",
2082
+ {
2083
+ className,
2084
+ style: {
2085
+ ...cssVars,
2086
+ ...positionStyles,
2087
+ width: config.position === "inline" ? "100%" : "400px",
2088
+ maxHeight: config.position === "inline" ? "600px" : "80vh",
2089
+ backgroundColor: "var(--wc-bg)",
2090
+ borderRadius: "var(--wc-radius)",
2091
+ border: "1px solid #e5e5e5",
2092
+ fontFamily: "var(--wc-font)",
2093
+ display: "flex",
2094
+ flexDirection: "column",
2095
+ boxShadow: config.position === "inline" ? "none" : "0 4px 20px rgba(0,0,0,0.15)",
2096
+ overflow: "hidden"
2097
+ },
2098
+ children: [
2099
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2100
+ "div",
2101
+ {
2102
+ style: {
2103
+ padding: "16px",
2104
+ borderBottom: "1px solid #e5e5e5",
2105
+ display: "flex",
2106
+ alignItems: "center",
2107
+ justifyContent: "space-between",
2108
+ backgroundColor: "var(--wc-primary)",
2109
+ color: "white"
2110
+ },
2111
+ children: [
2112
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
2113
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
2114
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
2116
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
2117
+ ] }),
2118
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontWeight: 600 }, children: config.title || "Chat" })
2119
+ ] }),
2120
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
2121
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2122
+ "button",
2123
+ {
2124
+ onClick: clearConversation,
2125
+ style: {
2126
+ background: "rgba(255,255,255,0.2)",
2127
+ border: "none",
2128
+ borderRadius: "4px",
2129
+ padding: "4px 8px",
2130
+ color: "white",
2131
+ cursor: "pointer",
2132
+ fontSize: "12px"
2133
+ },
2134
+ children: "Clear"
2135
+ }
2136
+ ),
2137
+ config.position !== "inline" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2138
+ "button",
2139
+ {
2140
+ onClick: () => setIsCollapsed(true),
2141
+ style: {
2142
+ background: "none",
2143
+ border: "none",
2144
+ color: "white",
2145
+ cursor: "pointer",
2146
+ padding: "4px"
2147
+ },
2148
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
2149
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2150
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2151
+ ] })
2152
+ }
2153
+ )
2154
+ ] })
2155
+ ]
2156
+ }
2157
+ ),
2158
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2159
+ "div",
2160
+ {
2161
+ style: {
2162
+ flex: 1,
2163
+ overflowY: "auto",
2164
+ padding: "16px",
2165
+ display: "flex",
2166
+ flexDirection: "column",
2167
+ gap: "12px",
2168
+ minHeight: "200px"
2169
+ },
2170
+ children: [
2171
+ messages.length === 0 && !streamingContent && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { textAlign: "center", color: "#9ca3af", padding: "40px 20px" }, children: [
2172
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2173
+ "svg",
2174
+ {
2175
+ width: "48",
2176
+ height: "48",
2177
+ viewBox: "0 0 24 24",
2178
+ fill: "none",
2179
+ stroke: "currentColor",
2180
+ strokeWidth: "1.5",
2181
+ style: { margin: "0 auto 16px" },
2182
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
2183
+ }
2184
+ ),
2185
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: { margin: 0, fontSize: "14px" }, children: "How can I help you today?" })
2186
+ ] }),
2187
+ messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2188
+ "div",
2189
+ {
2190
+ style: {
2191
+ alignSelf: msg.role === "user" ? "flex-end" : "flex-start",
2192
+ maxWidth: "85%"
2193
+ },
2194
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2195
+ "div",
2196
+ {
2197
+ style: {
2198
+ padding: "10px 14px",
2199
+ borderRadius: "12px",
2200
+ backgroundColor: msg.role === "user" ? "var(--wc-primary)" : "#f3f4f6",
2201
+ color: msg.role === "user" ? "white" : "var(--wc-text)",
2202
+ fontSize: "14px",
2203
+ lineHeight: "1.5"
2204
+ },
2205
+ children: msg.role === "user" ? msg.content : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContent, { content: msg.content, theme })
2206
+ }
2207
+ )
2208
+ },
2209
+ i
2210
+ )),
2211
+ streamingContent && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { alignSelf: "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2212
+ "div",
2213
+ {
2214
+ style: {
2215
+ padding: "10px 14px",
2216
+ borderRadius: "12px",
2217
+ backgroundColor: "#f3f4f6",
2218
+ color: "var(--wc-text)",
2219
+ fontSize: "14px",
2220
+ lineHeight: "1.5"
2221
+ },
2222
+ children: [
2223
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContent, { content: streamingContent, theme }),
2224
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
2225
+ ]
2226
+ }
2227
+ ) }),
2228
+ error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2229
+ "div",
2230
+ {
2231
+ style: {
2232
+ padding: "10px 14px",
2233
+ borderRadius: "8px",
2234
+ backgroundColor: "#fef2f2",
2235
+ color: "#dc2626",
2236
+ fontSize: "13px"
2237
+ },
2238
+ children: error
2239
+ }
2240
+ ),
2241
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: messagesEndRef })
2242
+ ]
2243
+ }
2244
+ ),
2245
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("form", { onSubmit: handleSubmit, style: { padding: "12px", borderTop: "1px solid #e5e5e5" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
2246
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2247
+ "input",
2248
+ {
2249
+ type: "text",
2250
+ value: inputValue,
2251
+ onChange: (e) => setInputValue(e.target.value),
2252
+ placeholder: config.placeholder || "Type a message...",
2253
+ disabled: isStreaming,
2254
+ style: {
2255
+ flex: 1,
2256
+ padding: "10px 14px",
2257
+ borderRadius: "8px",
2258
+ border: "1px solid #d1d5db",
2259
+ fontSize: "14px",
2260
+ fontFamily: "var(--wc-font)",
2261
+ outline: "none"
2262
+ }
2263
+ }
2264
+ ),
2265
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2266
+ "button",
2267
+ {
2268
+ type: "submit",
2269
+ disabled: isStreaming || !inputValue.trim(),
2270
+ style: {
2271
+ padding: "10px 16px",
2272
+ borderRadius: "8px",
2273
+ backgroundColor: isStreaming || !inputValue.trim() ? "#d1d5db" : "var(--wc-primary)",
2274
+ color: "white",
2275
+ border: "none",
2276
+ cursor: isStreaming || !inputValue.trim() ? "not-allowed" : "pointer",
2277
+ fontWeight: 500,
2278
+ fontSize: "14px"
2279
+ },
2280
+ children: isStreaming ? "..." : "Send"
2281
+ }
2282
+ )
2283
+ ] }) }),
2284
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: `
2285
+ @keyframes blink {
2286
+ 0%, 50% { opacity: 1; }
2287
+ 51%, 100% { opacity: 0; }
2288
+ }
2289
+ ` })
2290
+ ]
2291
+ }
2292
+ );
2293
+ }
2294
+
2295
+ // src/hooks/useSession.ts
2296
+ var import_react5 = require("react");
2297
+ function useSession(options) {
2298
+ const { apiUrl, documentTypeId, sessionId, onSessionChange, onError } = options;
2299
+ const [session, setSession] = (0, import_react5.useState)(null);
2300
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(true);
2301
+ const [error, setError] = (0, import_react5.useState)(null);
2302
+ const clientRef = (0, import_react5.useRef)(null);
2303
+ const isStreamingRef = (0, import_react5.useRef)(false);
2304
+ (0, import_react5.useEffect)(() => {
1314
2305
  clientRef.current = new InformedAIClient(apiUrl);
1315
2306
  }, [apiUrl]);
1316
- (0, import_react3.useEffect)(() => {
2307
+ (0, import_react5.useEffect)(() => {
1317
2308
  async function initialize() {
1318
2309
  if (!clientRef.current) return;
1319
2310
  try {
@@ -1338,7 +2329,7 @@ function useSession(options) {
1338
2329
  }
1339
2330
  initialize();
1340
2331
  }, [documentTypeId, sessionId, onSessionChange, onError]);
1341
- const handleSSEEvent = (0, import_react3.useCallback)((event) => {
2332
+ const handleSSEEvent = (0, import_react5.useCallback)((event) => {
1342
2333
  if (event.type === "done" || event.type === "session_update") {
1343
2334
  if (event.session) {
1344
2335
  setSession(event.session);
@@ -1353,7 +2344,7 @@ function useSession(options) {
1353
2344
  isStreamingRef.current = false;
1354
2345
  }
1355
2346
  }, [onSessionChange, onError]);
1356
- const sendMessage = (0, import_react3.useCallback)(async (message) => {
2347
+ const sendMessage = (0, import_react5.useCallback)(async (message) => {
1357
2348
  if (!clientRef.current || !session || isStreamingRef.current) return;
1358
2349
  try {
1359
2350
  isStreamingRef.current = true;
@@ -1366,7 +2357,7 @@ function useSession(options) {
1366
2357
  isStreamingRef.current = false;
1367
2358
  }
1368
2359
  }, [session, handleSSEEvent, onError]);
1369
- const sendQuickAction = (0, import_react3.useCallback)(async (action) => {
2360
+ const sendQuickAction = (0, import_react5.useCallback)(async (action) => {
1370
2361
  if (!clientRef.current || !session || isStreamingRef.current) return;
1371
2362
  try {
1372
2363
  isStreamingRef.current = true;
@@ -1386,7 +2377,7 @@ function useSession(options) {
1386
2377
  isStreamingRef.current = false;
1387
2378
  }
1388
2379
  }, [session, handleSSEEvent, onSessionChange, onError]);
1389
- const applyPendingValue = (0, import_react3.useCallback)(async () => {
2380
+ const applyPendingValue = (0, import_react5.useCallback)(async () => {
1390
2381
  if (!clientRef.current || !session) return;
1391
2382
  try {
1392
2383
  setError(null);
@@ -1399,7 +2390,7 @@ function useSession(options) {
1399
2390
  onError?.(error2);
1400
2391
  }
1401
2392
  }, [session, onSessionChange, onError]);
1402
- const skipTask = (0, import_react3.useCallback)(async () => {
2393
+ const skipTask = (0, import_react5.useCallback)(async () => {
1403
2394
  if (!clientRef.current || !session) return;
1404
2395
  try {
1405
2396
  setError(null);
@@ -1424,9 +2415,11 @@ function useSession(options) {
1424
2415
  }
1425
2416
  // Annotate the CommonJS export names for ESM import in node:
1426
2417
  0 && (module.exports = {
2418
+ AdminChatbot,
1427
2419
  InformedAIClient,
1428
2420
  InformedAIProvider,
1429
2421
  InformedAssistant,
2422
+ WebsiteChatbot,
1430
2423
  useInformedAI,
1431
2424
  useSession
1432
2425
  });