@informedai/react 0.4.15 → 0.4.17

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.d.mts CHANGED
@@ -82,6 +82,8 @@ interface InformedAssistantConfig {
82
82
  documentTypeId: string;
83
83
  /** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
84
84
  apiUrl?: string;
85
+ /** Pool access key (pak_*) for authentication */
86
+ accessKey?: string;
85
87
  /**
86
88
  * External ID for idempotency - your object's ID in your system.
87
89
  * If provided, the widget will find or create a document linked to this ID.
@@ -240,6 +242,7 @@ declare function AdminChatbot({ className, ...config }: AdminChatbotProps): reac
240
242
  * WebsiteChatbot
241
243
  * An embeddable chatbot widget for website agents.
242
244
  * Uses domain-based authentication - no API key required.
245
+ * Supports rendering rich cards from AI responses.
243
246
  */
244
247
  interface WebsiteChatbotTheme {
245
248
  primaryColor?: string;
@@ -346,7 +349,8 @@ interface ApplyResponse {
346
349
  }
347
350
  declare class InformedAIClient {
348
351
  private apiUrl;
349
- constructor(apiUrl?: string);
352
+ private accessKey?;
353
+ constructor(apiUrl?: string, accessKey?: string);
350
354
  private getHeaders;
351
355
  private request;
352
356
  /**
package/dist/index.d.ts CHANGED
@@ -82,6 +82,8 @@ interface InformedAssistantConfig {
82
82
  documentTypeId: string;
83
83
  /** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
84
84
  apiUrl?: string;
85
+ /** Pool access key (pak_*) for authentication */
86
+ accessKey?: string;
85
87
  /**
86
88
  * External ID for idempotency - your object's ID in your system.
87
89
  * If provided, the widget will find or create a document linked to this ID.
@@ -240,6 +242,7 @@ declare function AdminChatbot({ className, ...config }: AdminChatbotProps): reac
240
242
  * WebsiteChatbot
241
243
  * An embeddable chatbot widget for website agents.
242
244
  * Uses domain-based authentication - no API key required.
245
+ * Supports rendering rich cards from AI responses.
243
246
  */
244
247
  interface WebsiteChatbotTheme {
245
248
  primaryColor?: string;
@@ -346,7 +349,8 @@ interface ApplyResponse {
346
349
  }
347
350
  declare class InformedAIClient {
348
351
  private apiUrl;
349
- constructor(apiUrl?: string);
352
+ private accessKey?;
353
+ constructor(apiUrl?: string, accessKey?: string);
350
354
  private getHeaders;
351
355
  private request;
352
356
  /**
package/dist/index.js CHANGED
@@ -40,13 +40,18 @@ var import_react_dom = require("react-dom");
40
40
  // src/utils/api-client.ts
41
41
  var DEFAULT_API_URL = "https://api.informedassistant.ai/api/v1";
42
42
  var InformedAIClient = class {
43
- constructor(apiUrl) {
43
+ constructor(apiUrl, accessKey) {
44
44
  this.apiUrl = apiUrl || DEFAULT_API_URL;
45
+ this.accessKey = accessKey;
45
46
  }
46
47
  getHeaders() {
47
- return {
48
+ const headers = {
48
49
  "Content-Type": "application/json"
49
50
  };
51
+ if (this.accessKey) {
52
+ headers["Authorization"] = `Bearer ${this.accessKey}`;
53
+ }
54
+ return headers;
50
55
  }
51
56
  async request(endpoint, options = {}) {
52
57
  const response = await fetch(`${this.apiUrl}${endpoint}`, {
@@ -304,8 +309,8 @@ function InformedAIProvider({ config, children }) {
304
309
  const shouldPersist = config.persistSession ?? true;
305
310
  const storageKey = getStorageKey(config.documentTypeId, config.externalId);
306
311
  (0, import_react.useEffect)(() => {
307
- clientRef.current = new InformedAIClient(config.apiUrl);
308
- }, [config.apiUrl]);
312
+ clientRef.current = new InformedAIClient(config.apiUrl, config.accessKey);
313
+ }, [config.apiUrl, config.accessKey]);
309
314
  const createNewSession = (0, import_react.useCallback)(async () => {
310
315
  if (!clientRef.current) return null;
311
316
  const result = await clientRef.current.createSession(
@@ -1699,6 +1704,91 @@ function AdminChatbot({ className, ...config }) {
1699
1704
 
1700
1705
  // src/components/WebsiteChatbot.tsx
1701
1706
  var import_react4 = require("react");
1707
+
1708
+ // src/utils/card-parser.ts
1709
+ var CARD_MARKER_REGEX = /\[([A-Z][A-Z0-9_]*):([^\]]+)\]/g;
1710
+ function parseCardMarker(marker) {
1711
+ const match = marker.match(/^\[([A-Z][A-Z0-9_]*):([^\]]+)\]$/);
1712
+ if (!match) return null;
1713
+ const [, type, valuesStr] = match;
1714
+ const values = valuesStr.split("|").map((v) => v.trim());
1715
+ return {
1716
+ type,
1717
+ values,
1718
+ originalMarker: marker
1719
+ };
1720
+ }
1721
+ function parseMessageContent(content) {
1722
+ const segments = [];
1723
+ let lastIndex = 0;
1724
+ const matches = [...content.matchAll(CARD_MARKER_REGEX)];
1725
+ for (const match of matches) {
1726
+ const marker = match[0];
1727
+ const startIndex = match.index;
1728
+ if (startIndex > lastIndex) {
1729
+ const text = content.slice(lastIndex, startIndex).trim();
1730
+ if (text) {
1731
+ segments.push({ type: "text", content: text });
1732
+ }
1733
+ }
1734
+ const card = parseCardMarker(marker);
1735
+ if (card) {
1736
+ segments.push({ type: "card", card });
1737
+ }
1738
+ lastIndex = startIndex + marker.length;
1739
+ }
1740
+ if (lastIndex < content.length) {
1741
+ const text = content.slice(lastIndex).trim();
1742
+ if (text) {
1743
+ segments.push({ type: "text", content: text });
1744
+ }
1745
+ }
1746
+ if (segments.length === 0 && content.trim()) {
1747
+ segments.push({ type: "text", content: content.trim() });
1748
+ }
1749
+ return segments;
1750
+ }
1751
+ function isUrl(str) {
1752
+ return /^https?:\/\//i.test(str);
1753
+ }
1754
+ function isImageUrl(url) {
1755
+ if (!isUrl(url)) return false;
1756
+ return /\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/i.test(url);
1757
+ }
1758
+ function extractCardDisplayData(card) {
1759
+ const values = [...card.values];
1760
+ const result = {
1761
+ title: values[0] || card.type,
1762
+ extraValues: []
1763
+ };
1764
+ if (values.length <= 1) return result;
1765
+ const imageIndex = values.findIndex((v, i) => i > 0 && isImageUrl(v));
1766
+ if (imageIndex > 0) {
1767
+ result.imageUrl = values[imageIndex];
1768
+ values.splice(imageIndex, 1);
1769
+ }
1770
+ const actionIndex = values.findIndex((v, i) => i > 0 && isUrl(v) && !isImageUrl(v));
1771
+ if (actionIndex > 0) {
1772
+ result.actionUrl = values[actionIndex];
1773
+ result.actionLabel = "View";
1774
+ values.splice(actionIndex, 1);
1775
+ }
1776
+ const remaining = values.slice(1);
1777
+ if (remaining.length > 0) {
1778
+ if (remaining[0].length <= 50) {
1779
+ result.subtitle = remaining[0];
1780
+ remaining.shift();
1781
+ }
1782
+ }
1783
+ if (remaining.length > 0) {
1784
+ result.description = remaining[0];
1785
+ remaining.shift();
1786
+ }
1787
+ result.extraValues = remaining;
1788
+ return result;
1789
+ }
1790
+
1791
+ // src/components/WebsiteChatbot.tsx
1702
1792
  var import_jsx_runtime4 = require("react/jsx-runtime");
1703
1793
  var defaultTheme3 = {
1704
1794
  primaryColor: "#f59e0b",
@@ -1708,6 +1798,167 @@ var defaultTheme3 = {
1708
1798
  borderRadius: "12px",
1709
1799
  fontFamily: "system-ui, -apple-system, sans-serif"
1710
1800
  };
1801
+ function ChatCard({ card, theme }) {
1802
+ const data = extractCardDisplayData(card);
1803
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1804
+ "div",
1805
+ {
1806
+ style: {
1807
+ border: "1px solid #e5e7eb",
1808
+ borderRadius: "8px",
1809
+ overflow: "hidden",
1810
+ backgroundColor: "#fff",
1811
+ marginTop: "8px",
1812
+ marginBottom: "8px"
1813
+ },
1814
+ children: [
1815
+ data.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1816
+ "div",
1817
+ {
1818
+ style: {
1819
+ width: "100%",
1820
+ height: "140px",
1821
+ backgroundColor: "#f3f4f6",
1822
+ overflow: "hidden"
1823
+ },
1824
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1825
+ "img",
1826
+ {
1827
+ src: data.imageUrl,
1828
+ alt: data.title,
1829
+ style: {
1830
+ width: "100%",
1831
+ height: "100%",
1832
+ objectFit: "cover"
1833
+ },
1834
+ onError: (e) => {
1835
+ e.target.style.display = "none";
1836
+ }
1837
+ }
1838
+ )
1839
+ }
1840
+ ),
1841
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { padding: "12px" }, children: [
1842
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1843
+ "div",
1844
+ {
1845
+ style: {
1846
+ display: "inline-block",
1847
+ fontSize: "10px",
1848
+ fontWeight: 600,
1849
+ textTransform: "uppercase",
1850
+ letterSpacing: "0.5px",
1851
+ color: theme.primaryColor,
1852
+ backgroundColor: `${theme.primaryColor}15`,
1853
+ padding: "2px 6px",
1854
+ borderRadius: "4px",
1855
+ marginBottom: "6px"
1856
+ },
1857
+ children: card.type
1858
+ }
1859
+ ),
1860
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1861
+ "div",
1862
+ {
1863
+ style: {
1864
+ fontSize: "15px",
1865
+ fontWeight: 600,
1866
+ color: "#1f2937",
1867
+ marginBottom: "4px",
1868
+ lineHeight: "1.3"
1869
+ },
1870
+ children: data.title
1871
+ }
1872
+ ),
1873
+ data.subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1874
+ "div",
1875
+ {
1876
+ style: {
1877
+ fontSize: "13px",
1878
+ color: "#6b7280",
1879
+ marginBottom: "6px"
1880
+ },
1881
+ children: data.subtitle
1882
+ }
1883
+ ),
1884
+ data.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1885
+ "div",
1886
+ {
1887
+ style: {
1888
+ fontSize: "13px",
1889
+ color: "#4b5563",
1890
+ lineHeight: "1.4",
1891
+ marginBottom: "8px"
1892
+ },
1893
+ children: data.description
1894
+ }
1895
+ ),
1896
+ data.extraValues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1897
+ "div",
1898
+ {
1899
+ style: {
1900
+ fontSize: "12px",
1901
+ color: "#6b7280",
1902
+ marginBottom: "8px"
1903
+ },
1904
+ children: data.extraValues.join(" \u2022 ")
1905
+ }
1906
+ ),
1907
+ data.actionUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1908
+ "a",
1909
+ {
1910
+ href: data.actionUrl,
1911
+ target: "_blank",
1912
+ rel: "noopener noreferrer",
1913
+ style: {
1914
+ display: "inline-flex",
1915
+ alignItems: "center",
1916
+ gap: "4px",
1917
+ fontSize: "13px",
1918
+ fontWeight: 500,
1919
+ color: theme.primaryColor,
1920
+ textDecoration: "none",
1921
+ padding: "6px 12px",
1922
+ borderRadius: "6px",
1923
+ backgroundColor: `${theme.primaryColor}10`,
1924
+ transition: "background-color 0.2s"
1925
+ },
1926
+ onMouseEnter: (e) => {
1927
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}20`;
1928
+ },
1929
+ onMouseLeave: (e) => {
1930
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}10`;
1931
+ },
1932
+ children: [
1933
+ data.actionLabel || "View",
1934
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1935
+ /* @__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" }),
1936
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "15 3 21 3 21 9" }),
1937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1938
+ ] })
1939
+ ]
1940
+ }
1941
+ )
1942
+ ] })
1943
+ ]
1944
+ }
1945
+ );
1946
+ }
1947
+ function MessageContent({ content, theme }) {
1948
+ const segments = parseMessageContent(content);
1949
+ if (segments.length === 1 && segments[0].type === "text") {
1950
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: segments[0].content });
1951
+ }
1952
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: segments.map((segment, index) => {
1953
+ if (segment.type === "text") {
1954
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: segment.content }, index);
1955
+ }
1956
+ if (segment.type === "card" && segment.card) {
1957
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatCard, { card: segment.card, theme }, index);
1958
+ }
1959
+ return null;
1960
+ }) });
1961
+ }
1711
1962
  function WebsiteChatbot({ className, ...config }) {
1712
1963
  const theme = { ...defaultTheme3, ...config.theme };
1713
1964
  const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
@@ -1729,13 +1980,12 @@ function WebsiteChatbot({ className, ...config }) {
1729
1980
  const newMessages = [...messages, { role: "user", content: message }];
1730
1981
  setMessages(newMessages);
1731
1982
  try {
1732
- const response = await fetch(`${apiUrl}/website-agent/message`, {
1983
+ const response = await fetch(`${apiUrl}/website-agent/${config.agentId}/message`, {
1733
1984
  method: "POST",
1734
1985
  headers: {
1735
1986
  "Content-Type": "application/json"
1736
1987
  },
1737
1988
  body: JSON.stringify({
1738
- agentId: config.agentId,
1739
1989
  message,
1740
1990
  history: messages
1741
1991
  })
@@ -1955,10 +2205,9 @@ function WebsiteChatbot({ className, ...config }) {
1955
2205
  backgroundColor: msg.role === "user" ? "var(--wc-primary)" : "#f3f4f6",
1956
2206
  color: msg.role === "user" ? "white" : "var(--wc-text)",
1957
2207
  fontSize: "14px",
1958
- lineHeight: "1.5",
1959
- whiteSpace: "pre-wrap"
2208
+ lineHeight: "1.5"
1960
2209
  },
1961
- children: msg.content
2210
+ children: msg.role === "user" ? msg.content : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContent, { content: msg.content, theme })
1962
2211
  }
1963
2212
  )
1964
2213
  },
@@ -1973,11 +2222,10 @@ function WebsiteChatbot({ className, ...config }) {
1973
2222
  backgroundColor: "#f3f4f6",
1974
2223
  color: "var(--wc-text)",
1975
2224
  fontSize: "14px",
1976
- lineHeight: "1.5",
1977
- whiteSpace: "pre-wrap"
2225
+ lineHeight: "1.5"
1978
2226
  },
1979
2227
  children: [
1980
- streamingContent,
2228
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContent, { content: streamingContent, theme }),
1981
2229
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
1982
2230
  ]
1983
2231
  }
package/dist/index.mjs CHANGED
@@ -8,13 +8,18 @@ import { flushSync } from "react-dom";
8
8
  // src/utils/api-client.ts
9
9
  var DEFAULT_API_URL = "https://api.informedassistant.ai/api/v1";
10
10
  var InformedAIClient = class {
11
- constructor(apiUrl) {
11
+ constructor(apiUrl, accessKey) {
12
12
  this.apiUrl = apiUrl || DEFAULT_API_URL;
13
+ this.accessKey = accessKey;
13
14
  }
14
15
  getHeaders() {
15
- return {
16
+ const headers = {
16
17
  "Content-Type": "application/json"
17
18
  };
19
+ if (this.accessKey) {
20
+ headers["Authorization"] = `Bearer ${this.accessKey}`;
21
+ }
22
+ return headers;
18
23
  }
19
24
  async request(endpoint, options = {}) {
20
25
  const response = await fetch(`${this.apiUrl}${endpoint}`, {
@@ -272,8 +277,8 @@ function InformedAIProvider({ config, children }) {
272
277
  const shouldPersist = config.persistSession ?? true;
273
278
  const storageKey = getStorageKey(config.documentTypeId, config.externalId);
274
279
  useEffect(() => {
275
- clientRef.current = new InformedAIClient(config.apiUrl);
276
- }, [config.apiUrl]);
280
+ clientRef.current = new InformedAIClient(config.apiUrl, config.accessKey);
281
+ }, [config.apiUrl, config.accessKey]);
277
282
  const createNewSession = useCallback(async () => {
278
283
  if (!clientRef.current) return null;
279
284
  const result = await clientRef.current.createSession(
@@ -1667,7 +1672,92 @@ function AdminChatbot({ className, ...config }) {
1667
1672
 
1668
1673
  // src/components/WebsiteChatbot.tsx
1669
1674
  import { useState as useState4, useRef as useRef4, useEffect as useEffect4 } from "react";
1670
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1675
+
1676
+ // src/utils/card-parser.ts
1677
+ var CARD_MARKER_REGEX = /\[([A-Z][A-Z0-9_]*):([^\]]+)\]/g;
1678
+ function parseCardMarker(marker) {
1679
+ const match = marker.match(/^\[([A-Z][A-Z0-9_]*):([^\]]+)\]$/);
1680
+ if (!match) return null;
1681
+ const [, type, valuesStr] = match;
1682
+ const values = valuesStr.split("|").map((v) => v.trim());
1683
+ return {
1684
+ type,
1685
+ values,
1686
+ originalMarker: marker
1687
+ };
1688
+ }
1689
+ function parseMessageContent(content) {
1690
+ const segments = [];
1691
+ let lastIndex = 0;
1692
+ const matches = [...content.matchAll(CARD_MARKER_REGEX)];
1693
+ for (const match of matches) {
1694
+ const marker = match[0];
1695
+ const startIndex = match.index;
1696
+ if (startIndex > lastIndex) {
1697
+ const text = content.slice(lastIndex, startIndex).trim();
1698
+ if (text) {
1699
+ segments.push({ type: "text", content: text });
1700
+ }
1701
+ }
1702
+ const card = parseCardMarker(marker);
1703
+ if (card) {
1704
+ segments.push({ type: "card", card });
1705
+ }
1706
+ lastIndex = startIndex + marker.length;
1707
+ }
1708
+ if (lastIndex < content.length) {
1709
+ const text = content.slice(lastIndex).trim();
1710
+ if (text) {
1711
+ segments.push({ type: "text", content: text });
1712
+ }
1713
+ }
1714
+ if (segments.length === 0 && content.trim()) {
1715
+ segments.push({ type: "text", content: content.trim() });
1716
+ }
1717
+ return segments;
1718
+ }
1719
+ function isUrl(str) {
1720
+ return /^https?:\/\//i.test(str);
1721
+ }
1722
+ function isImageUrl(url) {
1723
+ if (!isUrl(url)) return false;
1724
+ return /\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/i.test(url);
1725
+ }
1726
+ function extractCardDisplayData(card) {
1727
+ const values = [...card.values];
1728
+ const result = {
1729
+ title: values[0] || card.type,
1730
+ extraValues: []
1731
+ };
1732
+ if (values.length <= 1) return result;
1733
+ const imageIndex = values.findIndex((v, i) => i > 0 && isImageUrl(v));
1734
+ if (imageIndex > 0) {
1735
+ result.imageUrl = values[imageIndex];
1736
+ values.splice(imageIndex, 1);
1737
+ }
1738
+ const actionIndex = values.findIndex((v, i) => i > 0 && isUrl(v) && !isImageUrl(v));
1739
+ if (actionIndex > 0) {
1740
+ result.actionUrl = values[actionIndex];
1741
+ result.actionLabel = "View";
1742
+ values.splice(actionIndex, 1);
1743
+ }
1744
+ const remaining = values.slice(1);
1745
+ if (remaining.length > 0) {
1746
+ if (remaining[0].length <= 50) {
1747
+ result.subtitle = remaining[0];
1748
+ remaining.shift();
1749
+ }
1750
+ }
1751
+ if (remaining.length > 0) {
1752
+ result.description = remaining[0];
1753
+ remaining.shift();
1754
+ }
1755
+ result.extraValues = remaining;
1756
+ return result;
1757
+ }
1758
+
1759
+ // src/components/WebsiteChatbot.tsx
1760
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1671
1761
  var defaultTheme3 = {
1672
1762
  primaryColor: "#f59e0b",
1673
1763
  // Amber
@@ -1676,6 +1766,167 @@ var defaultTheme3 = {
1676
1766
  borderRadius: "12px",
1677
1767
  fontFamily: "system-ui, -apple-system, sans-serif"
1678
1768
  };
1769
+ function ChatCard({ card, theme }) {
1770
+ const data = extractCardDisplayData(card);
1771
+ return /* @__PURE__ */ jsxs3(
1772
+ "div",
1773
+ {
1774
+ style: {
1775
+ border: "1px solid #e5e7eb",
1776
+ borderRadius: "8px",
1777
+ overflow: "hidden",
1778
+ backgroundColor: "#fff",
1779
+ marginTop: "8px",
1780
+ marginBottom: "8px"
1781
+ },
1782
+ children: [
1783
+ data.imageUrl && /* @__PURE__ */ jsx4(
1784
+ "div",
1785
+ {
1786
+ style: {
1787
+ width: "100%",
1788
+ height: "140px",
1789
+ backgroundColor: "#f3f4f6",
1790
+ overflow: "hidden"
1791
+ },
1792
+ children: /* @__PURE__ */ jsx4(
1793
+ "img",
1794
+ {
1795
+ src: data.imageUrl,
1796
+ alt: data.title,
1797
+ style: {
1798
+ width: "100%",
1799
+ height: "100%",
1800
+ objectFit: "cover"
1801
+ },
1802
+ onError: (e) => {
1803
+ e.target.style.display = "none";
1804
+ }
1805
+ }
1806
+ )
1807
+ }
1808
+ ),
1809
+ /* @__PURE__ */ jsxs3("div", { style: { padding: "12px" }, children: [
1810
+ /* @__PURE__ */ jsx4(
1811
+ "div",
1812
+ {
1813
+ style: {
1814
+ display: "inline-block",
1815
+ fontSize: "10px",
1816
+ fontWeight: 600,
1817
+ textTransform: "uppercase",
1818
+ letterSpacing: "0.5px",
1819
+ color: theme.primaryColor,
1820
+ backgroundColor: `${theme.primaryColor}15`,
1821
+ padding: "2px 6px",
1822
+ borderRadius: "4px",
1823
+ marginBottom: "6px"
1824
+ },
1825
+ children: card.type
1826
+ }
1827
+ ),
1828
+ /* @__PURE__ */ jsx4(
1829
+ "div",
1830
+ {
1831
+ style: {
1832
+ fontSize: "15px",
1833
+ fontWeight: 600,
1834
+ color: "#1f2937",
1835
+ marginBottom: "4px",
1836
+ lineHeight: "1.3"
1837
+ },
1838
+ children: data.title
1839
+ }
1840
+ ),
1841
+ data.subtitle && /* @__PURE__ */ jsx4(
1842
+ "div",
1843
+ {
1844
+ style: {
1845
+ fontSize: "13px",
1846
+ color: "#6b7280",
1847
+ marginBottom: "6px"
1848
+ },
1849
+ children: data.subtitle
1850
+ }
1851
+ ),
1852
+ data.description && /* @__PURE__ */ jsx4(
1853
+ "div",
1854
+ {
1855
+ style: {
1856
+ fontSize: "13px",
1857
+ color: "#4b5563",
1858
+ lineHeight: "1.4",
1859
+ marginBottom: "8px"
1860
+ },
1861
+ children: data.description
1862
+ }
1863
+ ),
1864
+ data.extraValues.length > 0 && /* @__PURE__ */ jsx4(
1865
+ "div",
1866
+ {
1867
+ style: {
1868
+ fontSize: "12px",
1869
+ color: "#6b7280",
1870
+ marginBottom: "8px"
1871
+ },
1872
+ children: data.extraValues.join(" \u2022 ")
1873
+ }
1874
+ ),
1875
+ data.actionUrl && /* @__PURE__ */ jsxs3(
1876
+ "a",
1877
+ {
1878
+ href: data.actionUrl,
1879
+ target: "_blank",
1880
+ rel: "noopener noreferrer",
1881
+ style: {
1882
+ display: "inline-flex",
1883
+ alignItems: "center",
1884
+ gap: "4px",
1885
+ fontSize: "13px",
1886
+ fontWeight: 500,
1887
+ color: theme.primaryColor,
1888
+ textDecoration: "none",
1889
+ padding: "6px 12px",
1890
+ borderRadius: "6px",
1891
+ backgroundColor: `${theme.primaryColor}10`,
1892
+ transition: "background-color 0.2s"
1893
+ },
1894
+ onMouseEnter: (e) => {
1895
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}20`;
1896
+ },
1897
+ onMouseLeave: (e) => {
1898
+ e.currentTarget.style.backgroundColor = `${theme.primaryColor}10`;
1899
+ },
1900
+ children: [
1901
+ data.actionLabel || "View",
1902
+ /* @__PURE__ */ jsxs3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1903
+ /* @__PURE__ */ jsx4("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
1904
+ /* @__PURE__ */ jsx4("polyline", { points: "15 3 21 3 21 9" }),
1905
+ /* @__PURE__ */ jsx4("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
1906
+ ] })
1907
+ ]
1908
+ }
1909
+ )
1910
+ ] })
1911
+ ]
1912
+ }
1913
+ );
1914
+ }
1915
+ function MessageContent({ content, theme }) {
1916
+ const segments = parseMessageContent(content);
1917
+ if (segments.length === 1 && segments[0].type === "text") {
1918
+ return /* @__PURE__ */ jsx4(Fragment2, { children: segments[0].content });
1919
+ }
1920
+ return /* @__PURE__ */ jsx4(Fragment2, { children: segments.map((segment, index) => {
1921
+ if (segment.type === "text") {
1922
+ return /* @__PURE__ */ jsx4("span", { style: { whiteSpace: "pre-wrap" }, children: segment.content }, index);
1923
+ }
1924
+ if (segment.type === "card" && segment.card) {
1925
+ return /* @__PURE__ */ jsx4(ChatCard, { card: segment.card, theme }, index);
1926
+ }
1927
+ return null;
1928
+ }) });
1929
+ }
1679
1930
  function WebsiteChatbot({ className, ...config }) {
1680
1931
  const theme = { ...defaultTheme3, ...config.theme };
1681
1932
  const apiUrl = config.apiUrl || "https://api.informedai.app/api/v1";
@@ -1697,13 +1948,12 @@ function WebsiteChatbot({ className, ...config }) {
1697
1948
  const newMessages = [...messages, { role: "user", content: message }];
1698
1949
  setMessages(newMessages);
1699
1950
  try {
1700
- const response = await fetch(`${apiUrl}/website-agent/message`, {
1951
+ const response = await fetch(`${apiUrl}/website-agent/${config.agentId}/message`, {
1701
1952
  method: "POST",
1702
1953
  headers: {
1703
1954
  "Content-Type": "application/json"
1704
1955
  },
1705
1956
  body: JSON.stringify({
1706
- agentId: config.agentId,
1707
1957
  message,
1708
1958
  history: messages
1709
1959
  })
@@ -1923,10 +2173,9 @@ function WebsiteChatbot({ className, ...config }) {
1923
2173
  backgroundColor: msg.role === "user" ? "var(--wc-primary)" : "#f3f4f6",
1924
2174
  color: msg.role === "user" ? "white" : "var(--wc-text)",
1925
2175
  fontSize: "14px",
1926
- lineHeight: "1.5",
1927
- whiteSpace: "pre-wrap"
2176
+ lineHeight: "1.5"
1928
2177
  },
1929
- children: msg.content
2178
+ children: msg.role === "user" ? msg.content : /* @__PURE__ */ jsx4(MessageContent, { content: msg.content, theme })
1930
2179
  }
1931
2180
  )
1932
2181
  },
@@ -1941,11 +2190,10 @@ function WebsiteChatbot({ className, ...config }) {
1941
2190
  backgroundColor: "#f3f4f6",
1942
2191
  color: "var(--wc-text)",
1943
2192
  fontSize: "14px",
1944
- lineHeight: "1.5",
1945
- whiteSpace: "pre-wrap"
2193
+ lineHeight: "1.5"
1946
2194
  },
1947
2195
  children: [
1948
- streamingContent,
2196
+ /* @__PURE__ */ jsx4(MessageContent, { content: streamingContent, theme }),
1949
2197
  /* @__PURE__ */ jsx4("span", { style: { opacity: 0.5, animation: "blink 1s infinite" }, children: "|" })
1950
2198
  ]
1951
2199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@informedai/react",
3
- "version": "0.4.15",
3
+ "version": "0.4.17",
4
4
  "description": "React SDK for InformedAI Assistant - AI-powered content creation widget",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",