@informedai/react 0.4.14 → 0.4.15

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.mjs CHANGED
@@ -1271,19 +1271,765 @@ function LoadingSpinner({ size = 20 }) {
1271
1271
  );
1272
1272
  }
1273
1273
 
1274
+ // src/components/AdminChatbot.tsx
1275
+ import { useState as useState3, useRef as useRef3, useEffect as useEffect3 } from "react";
1276
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1277
+ var defaultTheme2 = {
1278
+ primaryColor: "#3b82f6",
1279
+ // Blue (different from widget's amber)
1280
+ backgroundColor: "#ffffff",
1281
+ textColor: "#1c1917",
1282
+ borderRadius: "12px",
1283
+ fontFamily: "system-ui, -apple-system, sans-serif"
1284
+ };
1285
+ function AdminChatbot({ className, ...config }) {
1286
+ const theme = { ...defaultTheme2, ...config.theme };
1287
+ const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
1288
+ const [messages, setMessages] = useState3([]);
1289
+ const [inputValue, setInputValue] = useState3("");
1290
+ const [systemPrompt, setSystemPrompt] = useState3(config.systemPrompt || "");
1291
+ const [showSystemPromptEditor, setShowSystemPromptEditor] = useState3(false);
1292
+ const [isStreaming, setIsStreaming] = useState3(false);
1293
+ const [streamingContent, setStreamingContent] = useState3("");
1294
+ const [error, setError] = useState3(null);
1295
+ const [isCollapsed, setIsCollapsed] = useState3(config.defaultCollapsed ?? false);
1296
+ const messagesEndRef = useRef3(null);
1297
+ const inputRef = useRef3(null);
1298
+ useEffect3(() => {
1299
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1300
+ }, [messages, streamingContent]);
1301
+ const sendMessage = async (message) => {
1302
+ if (!message.trim() || isStreaming) return;
1303
+ setError(null);
1304
+ setIsStreaming(true);
1305
+ setStreamingContent("");
1306
+ const newMessages = [...messages, { role: "user", content: message }];
1307
+ setMessages(newMessages);
1308
+ try {
1309
+ const response = await fetch(`${apiUrl}/admin-chatbot/message`, {
1310
+ method: "POST",
1311
+ headers: {
1312
+ "Content-Type": "application/json",
1313
+ Authorization: `Bearer ${config.apiKey}`
1314
+ },
1315
+ body: JSON.stringify({
1316
+ message,
1317
+ history: messages,
1318
+ // Send previous messages (not including current)
1319
+ systemPrompt: systemPrompt || void 0
1320
+ })
1321
+ });
1322
+ if (!response.ok) {
1323
+ const err = await response.json().catch(() => ({ error: "Request failed" }));
1324
+ throw new Error(err.error || `HTTP ${response.status}`);
1325
+ }
1326
+ const reader = response.body?.getReader();
1327
+ if (!reader) throw new Error("No response body");
1328
+ const decoder = new TextDecoder();
1329
+ let buffer = "";
1330
+ let fullContent = "";
1331
+ while (true) {
1332
+ const { done, value } = await reader.read();
1333
+ if (done) break;
1334
+ buffer += decoder.decode(value, { stream: true });
1335
+ const lines = buffer.split("\n");
1336
+ buffer = lines.pop() || "";
1337
+ for (const line of lines) {
1338
+ if (line.startsWith("event:")) continue;
1339
+ if (line.startsWith("data:")) {
1340
+ const data = line.slice(5).trim();
1341
+ try {
1342
+ const parsed = JSON.parse(data);
1343
+ if (parsed.content) {
1344
+ fullContent += parsed.content;
1345
+ setStreamingContent(fullContent);
1346
+ }
1347
+ if (parsed.fullContent) {
1348
+ fullContent = parsed.fullContent;
1349
+ }
1350
+ } catch {
1351
+ }
1352
+ }
1353
+ }
1354
+ }
1355
+ setMessages([...newMessages, { role: "assistant", content: fullContent }]);
1356
+ setStreamingContent("");
1357
+ } catch (err) {
1358
+ setError(err instanceof Error ? err.message : "Failed to send message");
1359
+ } finally {
1360
+ setIsStreaming(false);
1361
+ }
1362
+ };
1363
+ const handleSubmit = (e) => {
1364
+ e.preventDefault();
1365
+ if (!inputValue.trim() || isStreaming) return;
1366
+ const message = inputValue.trim();
1367
+ setInputValue("");
1368
+ sendMessage(message);
1369
+ };
1370
+ const clearConversation = () => {
1371
+ setMessages([]);
1372
+ setStreamingContent("");
1373
+ setError(null);
1374
+ };
1375
+ const cssVars = {
1376
+ "--ac-primary": theme.primaryColor,
1377
+ "--ac-bg": theme.backgroundColor,
1378
+ "--ac-text": theme.textColor,
1379
+ "--ac-radius": theme.borderRadius,
1380
+ "--ac-font": theme.fontFamily
1381
+ };
1382
+ const positionStyles = config.position === "inline" ? {} : {
1383
+ position: "fixed",
1384
+ [config.position === "bottom-left" ? "left" : "right"]: "20px",
1385
+ bottom: "20px",
1386
+ zIndex: 9999
1387
+ };
1388
+ if (isCollapsed && config.position !== "inline") {
1389
+ return /* @__PURE__ */ jsx3(
1390
+ "button",
1391
+ {
1392
+ onClick: () => setIsCollapsed(false),
1393
+ className,
1394
+ style: {
1395
+ ...cssVars,
1396
+ ...positionStyles,
1397
+ width: "56px",
1398
+ height: "56px",
1399
+ borderRadius: "50%",
1400
+ backgroundColor: "var(--ac-primary)",
1401
+ color: "white",
1402
+ border: "none",
1403
+ cursor: "pointer",
1404
+ display: "flex",
1405
+ alignItems: "center",
1406
+ justifyContent: "center",
1407
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
1408
+ fontFamily: "var(--ac-font)"
1409
+ },
1410
+ children: /* @__PURE__ */ jsx3("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx3("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
1411
+ }
1412
+ );
1413
+ }
1414
+ return /* @__PURE__ */ jsxs2(
1415
+ "div",
1416
+ {
1417
+ className,
1418
+ style: {
1419
+ ...cssVars,
1420
+ ...positionStyles,
1421
+ width: config.position === "inline" ? "100%" : "400px",
1422
+ maxHeight: config.position === "inline" ? "600px" : "80vh",
1423
+ backgroundColor: "var(--ac-bg)",
1424
+ borderRadius: "var(--ac-radius)",
1425
+ border: "1px solid #e5e5e5",
1426
+ fontFamily: "var(--ac-font)",
1427
+ display: "flex",
1428
+ flexDirection: "column",
1429
+ boxShadow: config.position === "inline" ? "none" : "0 4px 20px rgba(0,0,0,0.15)",
1430
+ overflow: "hidden"
1431
+ },
1432
+ children: [
1433
+ /* @__PURE__ */ jsxs2(
1434
+ "div",
1435
+ {
1436
+ style: {
1437
+ padding: "16px",
1438
+ borderBottom: "1px solid #e5e5e5",
1439
+ display: "flex",
1440
+ alignItems: "center",
1441
+ justifyContent: "space-between",
1442
+ backgroundColor: "var(--ac-primary)",
1443
+ color: "white"
1444
+ },
1445
+ children: [
1446
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1447
+ /* @__PURE__ */ jsxs2("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1448
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
1449
+ /* @__PURE__ */ jsx3("path", { d: "M12 16v-4M12 8h.01" })
1450
+ ] }),
1451
+ /* @__PURE__ */ jsx3("span", { style: { fontWeight: 600 }, children: config.title || "Knowledge Library" })
1452
+ ] }),
1453
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1454
+ config.allowEditSystemPrompt && /* @__PURE__ */ jsx3(
1455
+ "button",
1456
+ {
1457
+ onClick: () => setShowSystemPromptEditor(!showSystemPromptEditor),
1458
+ style: {
1459
+ background: "rgba(255,255,255,0.2)",
1460
+ border: "none",
1461
+ borderRadius: "4px",
1462
+ padding: "4px 8px",
1463
+ color: "white",
1464
+ cursor: "pointer",
1465
+ fontSize: "12px"
1466
+ },
1467
+ children: showSystemPromptEditor ? "Hide Prompt" : "Edit Prompt"
1468
+ }
1469
+ ),
1470
+ /* @__PURE__ */ jsx3(
1471
+ "button",
1472
+ {
1473
+ onClick: clearConversation,
1474
+ style: {
1475
+ background: "rgba(255,255,255,0.2)",
1476
+ border: "none",
1477
+ borderRadius: "4px",
1478
+ padding: "4px 8px",
1479
+ color: "white",
1480
+ cursor: "pointer",
1481
+ fontSize: "12px"
1482
+ },
1483
+ children: "Clear"
1484
+ }
1485
+ ),
1486
+ config.position !== "inline" && /* @__PURE__ */ jsx3(
1487
+ "button",
1488
+ {
1489
+ onClick: () => setIsCollapsed(true),
1490
+ style: {
1491
+ background: "none",
1492
+ border: "none",
1493
+ color: "white",
1494
+ cursor: "pointer",
1495
+ padding: "4px"
1496
+ },
1497
+ children: /* @__PURE__ */ jsxs2("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1498
+ /* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1499
+ /* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1500
+ ] })
1501
+ }
1502
+ )
1503
+ ] })
1504
+ ]
1505
+ }
1506
+ ),
1507
+ showSystemPromptEditor && /* @__PURE__ */ jsxs2("div", { style: { padding: "12px", borderBottom: "1px solid #e5e5e5", backgroundColor: "#f9fafb" }, children: [
1508
+ /* @__PURE__ */ jsx3("label", { style: { display: "block", fontSize: "12px", fontWeight: 500, marginBottom: "4px", color: "#6b7280" }, children: "System Prompt" }),
1509
+ /* @__PURE__ */ jsx3(
1510
+ "textarea",
1511
+ {
1512
+ value: systemPrompt,
1513
+ onChange: (e) => setSystemPrompt(e.target.value),
1514
+ placeholder: "Enter a system prompt to guide the chatbot's behavior...",
1515
+ style: {
1516
+ width: "100%",
1517
+ minHeight: "80px",
1518
+ padding: "8px",
1519
+ borderRadius: "6px",
1520
+ border: "1px solid #d1d5db",
1521
+ fontSize: "13px",
1522
+ fontFamily: "var(--ac-font)",
1523
+ resize: "vertical"
1524
+ }
1525
+ }
1526
+ )
1527
+ ] }),
1528
+ /* @__PURE__ */ jsxs2(
1529
+ "div",
1530
+ {
1531
+ style: {
1532
+ flex: 1,
1533
+ overflowY: "auto",
1534
+ padding: "16px",
1535
+ display: "flex",
1536
+ flexDirection: "column",
1537
+ gap: "12px",
1538
+ minHeight: "200px"
1539
+ },
1540
+ children: [
1541
+ messages.length === 0 && !streamingContent && /* @__PURE__ */ jsxs2("div", { style: { textAlign: "center", color: "#9ca3af", padding: "40px 20px" }, children: [
1542
+ /* @__PURE__ */ jsx3(
1543
+ "svg",
1544
+ {
1545
+ width: "48",
1546
+ height: "48",
1547
+ viewBox: "0 0 24 24",
1548
+ fill: "none",
1549
+ stroke: "currentColor",
1550
+ strokeWidth: "1.5",
1551
+ style: { margin: "0 auto 16px" },
1552
+ children: /* @__PURE__ */ jsx3("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
1553
+ }
1554
+ ),
1555
+ /* @__PURE__ */ jsx3("p", { style: { margin: 0, fontSize: "14px" }, children: "Ask a question about your knowledge library" })
1556
+ ] }),
1557
+ messages.map((msg, i) => /* @__PURE__ */ jsx3(
1558
+ "div",
1559
+ {
1560
+ style: {
1561
+ alignSelf: msg.role === "user" ? "flex-end" : "flex-start",
1562
+ maxWidth: "85%"
1563
+ },
1564
+ children: /* @__PURE__ */ jsx3(
1565
+ "div",
1566
+ {
1567
+ style: {
1568
+ padding: "10px 14px",
1569
+ borderRadius: "12px",
1570
+ backgroundColor: msg.role === "user" ? "var(--ac-primary)" : "#f3f4f6",
1571
+ color: msg.role === "user" ? "white" : "var(--ac-text)",
1572
+ fontSize: "14px",
1573
+ lineHeight: "1.5",
1574
+ whiteSpace: "pre-wrap"
1575
+ },
1576
+ children: msg.content
1577
+ }
1578
+ )
1579
+ },
1580
+ i
1581
+ )),
1582
+ streamingContent && /* @__PURE__ */ jsx3("div", { style: { alignSelf: "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ jsxs2(
1583
+ "div",
1584
+ {
1585
+ style: {
1586
+ padding: "10px 14px",
1587
+ borderRadius: "12px",
1588
+ backgroundColor: "#f3f4f6",
1589
+ color: "var(--ac-text)",
1590
+ fontSize: "14px",
1591
+ lineHeight: "1.5",
1592
+ whiteSpace: "pre-wrap"
1593
+ },
1594
+ children: [
1595
+ streamingContent,
1596
+ /* @__PURE__ */ jsx3("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
1597
+ ]
1598
+ }
1599
+ ) }),
1600
+ error && /* @__PURE__ */ jsx3(
1601
+ "div",
1602
+ {
1603
+ style: {
1604
+ padding: "10px 14px",
1605
+ borderRadius: "8px",
1606
+ backgroundColor: "#fef2f2",
1607
+ color: "#dc2626",
1608
+ fontSize: "13px"
1609
+ },
1610
+ children: error
1611
+ }
1612
+ ),
1613
+ /* @__PURE__ */ jsx3("div", { ref: messagesEndRef })
1614
+ ]
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ jsx3("form", { onSubmit: handleSubmit, style: { padding: "12px", borderTop: "1px solid #e5e5e5" }, children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
1618
+ /* @__PURE__ */ jsx3(
1619
+ "input",
1620
+ {
1621
+ ref: inputRef,
1622
+ type: "text",
1623
+ value: inputValue,
1624
+ onChange: (e) => setInputValue(e.target.value),
1625
+ placeholder: config.placeholder || "Ask a question...",
1626
+ disabled: isStreaming,
1627
+ style: {
1628
+ flex: 1,
1629
+ padding: "10px 14px",
1630
+ borderRadius: "8px",
1631
+ border: "1px solid #d1d5db",
1632
+ fontSize: "14px",
1633
+ fontFamily: "var(--ac-font)",
1634
+ outline: "none"
1635
+ }
1636
+ }
1637
+ ),
1638
+ /* @__PURE__ */ jsx3(
1639
+ "button",
1640
+ {
1641
+ type: "submit",
1642
+ disabled: isStreaming || !inputValue.trim(),
1643
+ style: {
1644
+ padding: "10px 16px",
1645
+ borderRadius: "8px",
1646
+ backgroundColor: isStreaming || !inputValue.trim() ? "#d1d5db" : "var(--ac-primary)",
1647
+ color: "white",
1648
+ border: "none",
1649
+ cursor: isStreaming || !inputValue.trim() ? "not-allowed" : "pointer",
1650
+ fontWeight: 500,
1651
+ fontSize: "14px"
1652
+ },
1653
+ children: isStreaming ? "..." : "Send"
1654
+ }
1655
+ )
1656
+ ] }) }),
1657
+ /* @__PURE__ */ jsx3("style", { children: `
1658
+ @keyframes blink {
1659
+ 0%, 50% { opacity: 1; }
1660
+ 51%, 100% { opacity: 0; }
1661
+ }
1662
+ ` })
1663
+ ]
1664
+ }
1665
+ );
1666
+ }
1667
+
1668
+ // src/components/WebsiteChatbot.tsx
1669
+ import { useState as useState4, useRef as useRef4, useEffect as useEffect4 } from "react";
1670
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1671
+ var defaultTheme3 = {
1672
+ primaryColor: "#f59e0b",
1673
+ // Amber
1674
+ backgroundColor: "#ffffff",
1675
+ textColor: "#1c1917",
1676
+ borderRadius: "12px",
1677
+ fontFamily: "system-ui, -apple-system, sans-serif"
1678
+ };
1679
+ function WebsiteChatbot({ className, ...config }) {
1680
+ const theme = { ...defaultTheme3, ...config.theme };
1681
+ const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
1682
+ const [messages, setMessages] = useState4([]);
1683
+ const [inputValue, setInputValue] = useState4("");
1684
+ const [isStreaming, setIsStreaming] = useState4(false);
1685
+ const [streamingContent, setStreamingContent] = useState4("");
1686
+ const [error, setError] = useState4(null);
1687
+ const [isCollapsed, setIsCollapsed] = useState4(config.defaultCollapsed ?? false);
1688
+ const messagesEndRef = useRef4(null);
1689
+ useEffect4(() => {
1690
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1691
+ }, [messages, streamingContent]);
1692
+ const sendMessage = async (message) => {
1693
+ if (!message.trim() || isStreaming) return;
1694
+ setError(null);
1695
+ setIsStreaming(true);
1696
+ setStreamingContent("");
1697
+ const newMessages = [...messages, { role: "user", content: message }];
1698
+ setMessages(newMessages);
1699
+ try {
1700
+ const response = await fetch(`${apiUrl}/website-agent/message`, {
1701
+ method: "POST",
1702
+ headers: {
1703
+ "Content-Type": "application/json"
1704
+ },
1705
+ body: JSON.stringify({
1706
+ agentId: config.agentId,
1707
+ message,
1708
+ history: messages
1709
+ })
1710
+ });
1711
+ if (!response.ok) {
1712
+ const err = await response.json().catch(() => ({ error: "Request failed" }));
1713
+ throw new Error(err.error || `HTTP ${response.status}`);
1714
+ }
1715
+ const reader = response.body?.getReader();
1716
+ if (!reader) throw new Error("No response body");
1717
+ const decoder = new TextDecoder();
1718
+ let buffer = "";
1719
+ let fullContent = "";
1720
+ while (true) {
1721
+ const { done, value } = await reader.read();
1722
+ if (done) break;
1723
+ buffer += decoder.decode(value, { stream: true });
1724
+ const lines = buffer.split("\n");
1725
+ buffer = lines.pop() || "";
1726
+ for (const line of lines) {
1727
+ if (line.startsWith("event:")) continue;
1728
+ if (line.startsWith("data:")) {
1729
+ const data = line.slice(5).trim();
1730
+ try {
1731
+ const parsed = JSON.parse(data);
1732
+ if (parsed.content) {
1733
+ fullContent += parsed.content;
1734
+ setStreamingContent(fullContent);
1735
+ }
1736
+ if (parsed.fullContent) {
1737
+ fullContent = parsed.fullContent;
1738
+ }
1739
+ } catch {
1740
+ }
1741
+ }
1742
+ }
1743
+ }
1744
+ setMessages([...newMessages, { role: "assistant", content: fullContent }]);
1745
+ setStreamingContent("");
1746
+ } catch (err) {
1747
+ setError(err instanceof Error ? err.message : "Failed to send message");
1748
+ } finally {
1749
+ setIsStreaming(false);
1750
+ }
1751
+ };
1752
+ const handleSubmit = (e) => {
1753
+ e.preventDefault();
1754
+ if (!inputValue.trim() || isStreaming) return;
1755
+ const message = inputValue.trim();
1756
+ setInputValue("");
1757
+ sendMessage(message);
1758
+ };
1759
+ const clearConversation = () => {
1760
+ setMessages([]);
1761
+ setStreamingContent("");
1762
+ setError(null);
1763
+ };
1764
+ const cssVars = {
1765
+ "--wc-primary": theme.primaryColor,
1766
+ "--wc-bg": theme.backgroundColor,
1767
+ "--wc-text": theme.textColor,
1768
+ "--wc-radius": theme.borderRadius,
1769
+ "--wc-font": theme.fontFamily
1770
+ };
1771
+ const positionStyles = config.position === "inline" ? {} : {
1772
+ position: "fixed",
1773
+ [config.position === "bottom-left" ? "left" : "right"]: "20px",
1774
+ bottom: "20px",
1775
+ zIndex: 9999
1776
+ };
1777
+ if (isCollapsed && config.position !== "inline") {
1778
+ return /* @__PURE__ */ jsx4(
1779
+ "button",
1780
+ {
1781
+ onClick: () => setIsCollapsed(false),
1782
+ className,
1783
+ style: {
1784
+ ...cssVars,
1785
+ ...positionStyles,
1786
+ width: "56px",
1787
+ height: "56px",
1788
+ borderRadius: "50%",
1789
+ backgroundColor: "var(--wc-primary)",
1790
+ color: "white",
1791
+ border: "none",
1792
+ cursor: "pointer",
1793
+ display: "flex",
1794
+ alignItems: "center",
1795
+ justifyContent: "center",
1796
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
1797
+ fontFamily: "var(--wc-font)"
1798
+ },
1799
+ children: /* @__PURE__ */ jsx4("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })
1800
+ }
1801
+ );
1802
+ }
1803
+ return /* @__PURE__ */ jsxs3(
1804
+ "div",
1805
+ {
1806
+ className,
1807
+ style: {
1808
+ ...cssVars,
1809
+ ...positionStyles,
1810
+ width: config.position === "inline" ? "100%" : "400px",
1811
+ maxHeight: config.position === "inline" ? "600px" : "80vh",
1812
+ backgroundColor: "var(--wc-bg)",
1813
+ borderRadius: "var(--wc-radius)",
1814
+ border: "1px solid #e5e5e5",
1815
+ fontFamily: "var(--wc-font)",
1816
+ display: "flex",
1817
+ flexDirection: "column",
1818
+ boxShadow: config.position === "inline" ? "none" : "0 4px 20px rgba(0,0,0,0.15)",
1819
+ overflow: "hidden"
1820
+ },
1821
+ children: [
1822
+ /* @__PURE__ */ jsxs3(
1823
+ "div",
1824
+ {
1825
+ style: {
1826
+ padding: "16px",
1827
+ borderBottom: "1px solid #e5e5e5",
1828
+ display: "flex",
1829
+ alignItems: "center",
1830
+ justifyContent: "space-between",
1831
+ backgroundColor: "var(--wc-primary)",
1832
+ color: "white"
1833
+ },
1834
+ children: [
1835
+ /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1836
+ /* @__PURE__ */ jsxs3("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1837
+ /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10" }),
1838
+ /* @__PURE__ */ jsx4("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1839
+ /* @__PURE__ */ jsx4("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" })
1840
+ ] }),
1841
+ /* @__PURE__ */ jsx4("span", { style: { fontWeight: 600 }, children: config.title || "Chat" })
1842
+ ] }),
1843
+ /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
1844
+ /* @__PURE__ */ jsx4(
1845
+ "button",
1846
+ {
1847
+ onClick: clearConversation,
1848
+ style: {
1849
+ background: "rgba(255,255,255,0.2)",
1850
+ border: "none",
1851
+ borderRadius: "4px",
1852
+ padding: "4px 8px",
1853
+ color: "white",
1854
+ cursor: "pointer",
1855
+ fontSize: "12px"
1856
+ },
1857
+ children: "Clear"
1858
+ }
1859
+ ),
1860
+ config.position !== "inline" && /* @__PURE__ */ jsx4(
1861
+ "button",
1862
+ {
1863
+ onClick: () => setIsCollapsed(true),
1864
+ style: {
1865
+ background: "none",
1866
+ border: "none",
1867
+ color: "white",
1868
+ cursor: "pointer",
1869
+ padding: "4px"
1870
+ },
1871
+ children: /* @__PURE__ */ jsxs3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1872
+ /* @__PURE__ */ jsx4("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1873
+ /* @__PURE__ */ jsx4("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1874
+ ] })
1875
+ }
1876
+ )
1877
+ ] })
1878
+ ]
1879
+ }
1880
+ ),
1881
+ /* @__PURE__ */ jsxs3(
1882
+ "div",
1883
+ {
1884
+ style: {
1885
+ flex: 1,
1886
+ overflowY: "auto",
1887
+ padding: "16px",
1888
+ display: "flex",
1889
+ flexDirection: "column",
1890
+ gap: "12px",
1891
+ minHeight: "200px"
1892
+ },
1893
+ children: [
1894
+ messages.length === 0 && !streamingContent && /* @__PURE__ */ jsxs3("div", { style: { textAlign: "center", color: "#9ca3af", padding: "40px 20px" }, children: [
1895
+ /* @__PURE__ */ jsx4(
1896
+ "svg",
1897
+ {
1898
+ width: "48",
1899
+ height: "48",
1900
+ viewBox: "0 0 24 24",
1901
+ fill: "none",
1902
+ stroke: "currentColor",
1903
+ strokeWidth: "1.5",
1904
+ style: { margin: "0 auto 16px" },
1905
+ children: /* @__PURE__ */ jsx4("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
1906
+ }
1907
+ ),
1908
+ /* @__PURE__ */ jsx4("p", { style: { margin: 0, fontSize: "14px" }, children: "How can I help you today?" })
1909
+ ] }),
1910
+ messages.map((msg, i) => /* @__PURE__ */ jsx4(
1911
+ "div",
1912
+ {
1913
+ style: {
1914
+ alignSelf: msg.role === "user" ? "flex-end" : "flex-start",
1915
+ maxWidth: "85%"
1916
+ },
1917
+ children: /* @__PURE__ */ jsx4(
1918
+ "div",
1919
+ {
1920
+ style: {
1921
+ padding: "10px 14px",
1922
+ borderRadius: "12px",
1923
+ backgroundColor: msg.role === "user" ? "var(--wc-primary)" : "#f3f4f6",
1924
+ color: msg.role === "user" ? "white" : "var(--wc-text)",
1925
+ fontSize: "14px",
1926
+ lineHeight: "1.5",
1927
+ whiteSpace: "pre-wrap"
1928
+ },
1929
+ children: msg.content
1930
+ }
1931
+ )
1932
+ },
1933
+ i
1934
+ )),
1935
+ streamingContent && /* @__PURE__ */ jsx4("div", { style: { alignSelf: "flex-start", maxWidth: "85%" }, children: /* @__PURE__ */ jsxs3(
1936
+ "div",
1937
+ {
1938
+ style: {
1939
+ padding: "10px 14px",
1940
+ borderRadius: "12px",
1941
+ backgroundColor: "#f3f4f6",
1942
+ color: "var(--wc-text)",
1943
+ fontSize: "14px",
1944
+ lineHeight: "1.5",
1945
+ whiteSpace: "pre-wrap"
1946
+ },
1947
+ children: [
1948
+ streamingContent,
1949
+ /* @__PURE__ */ jsx4("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
1950
+ ]
1951
+ }
1952
+ ) }),
1953
+ error && /* @__PURE__ */ jsx4(
1954
+ "div",
1955
+ {
1956
+ style: {
1957
+ padding: "10px 14px",
1958
+ borderRadius: "8px",
1959
+ backgroundColor: "#fef2f2",
1960
+ color: "#dc2626",
1961
+ fontSize: "13px"
1962
+ },
1963
+ children: error
1964
+ }
1965
+ ),
1966
+ /* @__PURE__ */ jsx4("div", { ref: messagesEndRef })
1967
+ ]
1968
+ }
1969
+ ),
1970
+ /* @__PURE__ */ jsx4("form", { onSubmit: handleSubmit, style: { padding: "12px", borderTop: "1px solid #e5e5e5" }, children: /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
1971
+ /* @__PURE__ */ jsx4(
1972
+ "input",
1973
+ {
1974
+ type: "text",
1975
+ value: inputValue,
1976
+ onChange: (e) => setInputValue(e.target.value),
1977
+ placeholder: config.placeholder || "Type a message...",
1978
+ disabled: isStreaming,
1979
+ style: {
1980
+ flex: 1,
1981
+ padding: "10px 14px",
1982
+ borderRadius: "8px",
1983
+ border: "1px solid #d1d5db",
1984
+ fontSize: "14px",
1985
+ fontFamily: "var(--wc-font)",
1986
+ outline: "none"
1987
+ }
1988
+ }
1989
+ ),
1990
+ /* @__PURE__ */ jsx4(
1991
+ "button",
1992
+ {
1993
+ type: "submit",
1994
+ disabled: isStreaming || !inputValue.trim(),
1995
+ style: {
1996
+ padding: "10px 16px",
1997
+ borderRadius: "8px",
1998
+ backgroundColor: isStreaming || !inputValue.trim() ? "#d1d5db" : "var(--wc-primary)",
1999
+ color: "white",
2000
+ border: "none",
2001
+ cursor: isStreaming || !inputValue.trim() ? "not-allowed" : "pointer",
2002
+ fontWeight: 500,
2003
+ fontSize: "14px"
2004
+ },
2005
+ children: isStreaming ? "..." : "Send"
2006
+ }
2007
+ )
2008
+ ] }) }),
2009
+ /* @__PURE__ */ jsx4("style", { children: `
2010
+ @keyframes blink {
2011
+ 0%, 50% { opacity: 1; }
2012
+ 51%, 100% { opacity: 0; }
2013
+ }
2014
+ ` })
2015
+ ]
2016
+ }
2017
+ );
2018
+ }
2019
+
1274
2020
  // src/hooks/useSession.ts
1275
- import { useState as useState3, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef3 } from "react";
2021
+ import { useState as useState5, useEffect as useEffect5, useCallback as useCallback2, useRef as useRef5 } from "react";
1276
2022
  function useSession(options) {
1277
2023
  const { apiUrl, documentTypeId, sessionId, onSessionChange, onError } = options;
1278
- const [session, setSession] = useState3(null);
1279
- const [isLoading, setIsLoading] = useState3(true);
1280
- const [error, setError] = useState3(null);
1281
- const clientRef = useRef3(null);
1282
- const isStreamingRef = useRef3(false);
1283
- useEffect3(() => {
2024
+ const [session, setSession] = useState5(null);
2025
+ const [isLoading, setIsLoading] = useState5(true);
2026
+ const [error, setError] = useState5(null);
2027
+ const clientRef = useRef5(null);
2028
+ const isStreamingRef = useRef5(false);
2029
+ useEffect5(() => {
1284
2030
  clientRef.current = new InformedAIClient(apiUrl);
1285
2031
  }, [apiUrl]);
1286
- useEffect3(() => {
2032
+ useEffect5(() => {
1287
2033
  async function initialize() {
1288
2034
  if (!clientRef.current) return;
1289
2035
  try {
@@ -1393,9 +2139,11 @@ function useSession(options) {
1393
2139
  };
1394
2140
  }
1395
2141
  export {
2142
+ AdminChatbot,
1396
2143
  InformedAIClient,
1397
2144
  InformedAIProvider,
1398
2145
  InformedAssistant,
2146
+ WebsiteChatbot,
1399
2147
  useInformedAI,
1400
2148
  useSession
1401
2149
  };