sagedesk 2.2.0 → 2.3.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.
@@ -316,8 +316,11 @@ function reducer(state, action) {
316
316
  return { ...state, isOpen: true };
317
317
  case "CLOSE":
318
318
  return { ...state, isOpen: false };
319
- case "ADD_MESSAGE":
320
- return { ...state, messages: [...state.messages, action.payload] };
319
+ case "ADD_MESSAGE": {
320
+ const newMessages = [...state.messages, action.payload];
321
+ const newUserMessages = action.payload.role === "user" ? [...state.userMessages, action.payload] : state.userMessages;
322
+ return { ...state, messages: newMessages, userMessages: newUserMessages };
323
+ }
321
324
  case "SET_TYPING":
322
325
  return { ...state, isTyping: action.payload };
323
326
  case "SET_ENGINE_STATUS":
@@ -340,6 +343,7 @@ function useSageDesk(config) {
340
343
  const embedderRef = (0, import_react.useRef)(null);
341
344
  const engineStartedRef = (0, import_react.useRef)(false);
342
345
  const msgCounterRef = (0, import_react.useRef)(0);
346
+ const engineReadyCallbacksRef = (0, import_react.useRef)([]);
343
347
  const [chips, setChips] = (0, import_react.useState)([]);
344
348
  const makeId = () => `msg-${++msgCounterRef.current}`;
345
349
  const addMessage = (0, import_react.useCallback)(
@@ -351,6 +355,11 @@ function useSageDesk(config) {
351
355
  },
352
356
  []
353
357
  );
358
+ const notifyEngineReady = (0, import_react.useCallback)(() => {
359
+ const callbacks = engineReadyCallbacksRef.current;
360
+ engineReadyCallbacksRef.current = [];
361
+ callbacks.forEach((cb) => cb());
362
+ }, []);
354
363
  const startEngine = (0, import_react.useCallback)(async () => {
355
364
  if (engineStartedRef.current) return;
356
365
  engineStartedRef.current = true;
@@ -361,9 +370,11 @@ function useSageDesk(config) {
361
370
  embedderRef.current = new EmbedderRuntime();
362
371
  await embedderRef.current.load(config.agent.model);
363
372
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
373
+ notifyEngineReady();
364
374
  } catch (err) {
365
375
  console.warn("[sagedesk] WASM embedder failed to load - LLM mode will use fallback messages.", err);
366
376
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "error-model", error: String(err) } });
377
+ notifyEngineReady();
367
378
  }
368
379
  return;
369
380
  }
@@ -376,6 +387,7 @@ function useSageDesk(config) {
376
387
  type: "SET_ENGINE_STATUS",
377
388
  payload: { status: "error-index", error: String(err) }
378
389
  });
390
+ notifyEngineReady();
379
391
  addMessage({
380
392
  role: "bot",
381
393
  text: "I'm having trouble loading right now. Please try again in a moment."
@@ -388,12 +400,14 @@ function useSageDesk(config) {
388
400
  embedderRef.current = new EmbedderRuntime();
389
401
  await embedderRef.current.load(config.agent.model);
390
402
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
403
+ notifyEngineReady();
391
404
  } catch (err) {
392
405
  console.warn("[sagedesk] WASM model failed to load, falling back to keyword search -", err);
393
406
  embedderRef.current = new EmbedderRuntime();
394
407
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "degraded" } });
408
+ notifyEngineReady();
395
409
  }
396
- }, [config.mode, config.indexUrl, config.agent.model, config.agent.suggestedChips, addMessage]);
410
+ }, [config.mode, config.indexUrl, config.agent.model, config.agent.suggestedChips, addMessage, notifyEngineReady]);
397
411
  const greetingShownRef = (0, import_react.useRef)(false);
398
412
  const open = (0, import_react.useCallback)(() => {
399
413
  dispatch({ type: "OPEN" });
@@ -410,16 +424,12 @@ function useSageDesk(config) {
410
424
  dispatch({ type: "CLOSE" });
411
425
  }, []);
412
426
  const waitForEngine = (0, import_react.useCallback)(() => {
427
+ const s = engineStatusRef.current;
428
+ if (s === "ready" || s === "degraded" || s === "error-index" || s === "error-model") {
429
+ return Promise.resolve();
430
+ }
413
431
  return new Promise((resolve) => {
414
- const check = () => {
415
- const s = engineStatusRef.current;
416
- if (s === "ready" || s === "degraded" || s === "error-index" || s === "error-model") {
417
- resolve();
418
- } else {
419
- setTimeout(check, 100);
420
- }
421
- };
422
- check();
432
+ engineReadyCallbacksRef.current.push(resolve);
423
433
  });
424
434
  }, []);
425
435
  const submit = (0, import_react.useCallback)(
@@ -500,8 +510,8 @@ function useSageDesk(config) {
500
510
  }
501
511
  if (config.mode !== "llm") {
502
512
  const elapsed = Date.now() - typingStart;
503
- const delayBase = retrievalMode === "keyword" || isFallback ? 800 : 3e3;
504
- const minTypingMs = delayBase + Math.random() * 2e3;
513
+ const delayBase = retrievalMode === "keyword" || isFallback ? 400 : 800;
514
+ const minTypingMs = delayBase + Math.random() * 400;
505
515
  const remaining = minTypingMs - elapsed;
506
516
  if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
507
517
  }
@@ -519,11 +529,9 @@ function useSageDesk(config) {
519
529
  return () => document.removeEventListener("keydown", handler);
520
530
  }, [state.isOpen, close]);
521
531
  const activeChips = (0, import_react.useMemo)(() => {
522
- const askedTexts = new Set(
523
- state.messages.filter((m) => m.role === "user").map((m) => m.text.toLowerCase().trim())
524
- );
532
+ const askedTexts = new Set(state.userMessages.map((m) => m.text.toLowerCase().trim()));
525
533
  return chips.filter((chip) => !askedTexts.has(chip.toLowerCase().trim()));
526
- }, [chips, state.messages]);
534
+ }, [chips, state.userMessages]);
527
535
  return { state, chips: activeChips, open, close, submit };
528
536
  }
529
537
  var import_react, initialState;
@@ -537,6 +545,7 @@ var init_useSageDesk = __esm({
537
545
  init_fallback();
538
546
  initialState = {
539
547
  messages: [],
548
+ userMessages: [],
540
549
  isOpen: false,
541
550
  isTyping: false,
542
551
  engineStatus: "idle",
@@ -611,34 +620,6 @@ function injectStyles(theme) {
611
620
  style.textContent = THEME_CSS[theme];
612
621
  document.head.prepend(style);
613
622
  }
614
- function ClassicMessageBubble({ msg, accent }) {
615
- const isBot = msg.role === "bot";
616
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
617
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: isBot ? "flex-start" : "flex-end", gap: "4px" }, children: [
618
- msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", fontWeight: 500, color: "#9b9aa3", margin: 0, padding: "0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
619
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
620
- maxWidth: "82%",
621
- padding: "10px 14px",
622
- fontSize: "14px",
623
- lineHeight: 1.5,
624
- borderRadius: isBot ? "16px 16px 16px 6px" : "16px 16px 6px 16px",
625
- background: isBot ? "#fff" : accent,
626
- color: isBot ? "#1a1a2e" : "#fff",
627
- border: isBot ? "1px solid rgba(20,20,40,0.06)" : "none",
628
- boxShadow: isBot ? "0 1px 2px rgba(20,20,40,0.04)" : `0 6px 16px -6px color-mix(in oklab, ${accent} 60%, transparent)`,
629
- wordBreak: "break-word",
630
- fontFamily: "inherit"
631
- }, className: "sd-r-markdown", children: isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text }) }),
632
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
633
- fontSize: "11px",
634
- color: "#a8a8b0",
635
- marginTop: "2px",
636
- padding: isBot ? "0 0 0 4px" : "0 4px 0 0",
637
- fontVariantNumeric: "tabular-nums",
638
- fontFamily: "inherit"
639
- }, children: "just now" })
640
- ] });
641
- }
642
623
  function ClassicTypingIndicator() {
643
624
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "#c8c8ce", display: "inline-block" };
644
625
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "4px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
@@ -656,44 +637,6 @@ function ClassicTypingIndicator() {
656
637
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dot, className: "sd-r-dot-3" })
657
638
  ] }) });
658
639
  }
659
- function LightMessageBubble({ msg, accent, agentName }) {
660
- const isBot = msg.role === "bot";
661
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
662
- if (isBot) {
663
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
664
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
665
- width: 28,
666
- height: 28,
667
- borderRadius: "50%",
668
- background: `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 60%, #fff))`,
669
- flexShrink: 0,
670
- marginTop: "2px"
671
- } }),
672
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: "8px", marginBottom: "4px" }, children: [
674
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "13px", fontWeight: 600, color: "#1a1a2e", fontFamily: "inherit" }, children: agentName }),
675
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "#a8a89e", fontVariantNumeric: "tabular-nums", fontFamily: "inherit" }, children: "just now" })
676
- ] }),
677
- msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", color: "#9b9aa3", margin: "0 0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
678
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: "14px", lineHeight: 1.55, color: "#2a2a36", fontFamily: "inherit", wordBreak: "break-word" }, className: "sd-r-markdown", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) })
679
- ] })
680
- ] });
681
- }
682
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
683
- maxWidth: "78%",
684
- padding: "11px 15px",
685
- fontSize: "14px",
686
- lineHeight: 1.5,
687
- borderRadius: "16px 16px 4px 16px",
688
- background: `color-mix(in oklab, ${accent} 10%, white)`,
689
- color: accent,
690
- border: `1px solid color-mix(in oklab, ${accent} 22%, transparent)`,
691
- fontWeight: 500,
692
- whiteSpace: "pre-wrap",
693
- wordBreak: "break-word",
694
- fontFamily: "inherit"
695
- }, children: msg.text }) });
696
- }
697
640
  function LightTypingIndicator({ accent }) {
698
641
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "#c4c4be", display: "inline-block" };
699
642
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
@@ -721,27 +664,6 @@ function LightTypingIndicator({ accent }) {
721
664
  ] })
722
665
  ] });
723
666
  }
724
- function DarkMessageBubble({ msg, accent }) {
725
- const isBot = msg.role === "bot";
726
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
727
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
728
- maxWidth: "85%",
729
- padding: "12px 14px",
730
- fontSize: "14px",
731
- lineHeight: isBot ? 1.6 : 1.5,
732
- borderRadius: isBot ? "14px 14px 14px 6px" : "14px 14px 6px 14px",
733
- background: isBot ? "rgba(255,255,255,0.05)" : `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 75%, #1a1340))`,
734
- border: isBot ? "1px solid rgba(255,255,255,0.06)" : "none",
735
- color: isBot ? "rgba(255,255,255,0.92)" : "#fff",
736
- alignSelf: isBot ? "flex-start" : "flex-end",
737
- boxShadow: isBot ? "none" : `0 8px 20px -8px color-mix(in oklab, ${accent} 70%, transparent)`,
738
- wordBreak: "break-word",
739
- fontFamily: "inherit"
740
- }, className: isBot ? "sd-r-markdown" : "", children: [
741
- msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "rgba(255,255,255,0.5)", display: "block", marginBottom: "4px" }, children: "Not sure about that one" }),
742
- isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text })
743
- ] });
744
- }
745
667
  function DarkTypingIndicator() {
746
668
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "rgba(255,255,255,0.4)", display: "inline-block" };
747
669
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
@@ -760,7 +682,7 @@ function DarkTypingIndicator() {
760
682
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dot, className: "sd-r-dot-3" })
761
683
  ] });
762
684
  }
763
- function renderClassic(p) {
685
+ function ClassicTheme(p) {
764
686
  const {
765
687
  agent,
766
688
  state,
@@ -949,7 +871,7 @@ function renderClassic(p) {
949
871
  ] })
950
872
  ] });
951
873
  }
952
- function renderLight(p) {
874
+ function LightTheme(p) {
953
875
  const {
954
876
  agent,
955
877
  state,
@@ -1137,7 +1059,7 @@ function renderLight(p) {
1137
1059
  ] })
1138
1060
  ] });
1139
1061
  }
1140
- function renderDark(p) {
1062
+ function DarkTheme(p) {
1141
1063
  const {
1142
1064
  agent,
1143
1065
  state,
@@ -1374,7 +1296,10 @@ function SageDeskWidget({ mode, indexUrl, endpoint, agent, search: search2 }) {
1374
1296
  '[sagedesk] Required prop "endpoint" is missing for llm mode. Provide your backend route, e.g. endpoint="/api/sagedesk".'
1375
1297
  );
1376
1298
  }
1377
- const config = { mode: resolvedMode, indexUrl, endpoint, agent, search: search2 };
1299
+ const config = (0, import_react2.useMemo)(
1300
+ () => ({ mode: resolvedMode, indexUrl, endpoint, agent, search: search2 }),
1301
+ [resolvedMode, indexUrl, endpoint, agent, search2]
1302
+ );
1378
1303
  const { state, chips, open, close, submit } = useSageDesk(config);
1379
1304
  const theme = agent.theme ?? "classic";
1380
1305
  const accent = agent.accentColor ?? "#534AB7";
@@ -1453,14 +1378,14 @@ function SageDeskWidget({ mode, indexUrl, endpoint, agent, search: search2 }) {
1453
1378
  open,
1454
1379
  submit
1455
1380
  };
1456
- const content = theme === "dark" ? renderDark(props) : theme === "light" ? renderLight(props) : renderClassic(props);
1381
+ const content = theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DarkTheme, { ...props }) : theme === "light" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LightTheme, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClassicTheme, { ...props });
1457
1382
  return (0, import_react_dom.createPortal)(content, document.body);
1458
1383
  }
1459
- var import_react2, import_react_dom, import_jsx_runtime, STYLE_ID, SHARED, THEME_CSS, IconChat, IconSend, IconClose, IconBot, IconPerson, PoweredBy;
1384
+ var import_react2, import_react_dom, import_jsx_runtime, STYLE_ID, SHARED, THEME_CSS, IconChat, IconSend, IconClose, IconBot, IconPerson, PoweredBy, ClassicMessageBubble, LightMessageBubble, DarkMessageBubble;
1460
1385
  var init_SageDeskWidget = __esm({
1461
1386
  "src/react/SageDeskWidget.tsx"() {
1462
1387
  "use strict";
1463
- import_react2 = require("react");
1388
+ import_react2 = __toESM(require("react"), 1);
1464
1389
  import_react_dom = require("react-dom");
1465
1390
  init_useSageDesk();
1466
1391
  init_markdownUtils();
@@ -1601,6 +1526,93 @@ var init_SageDeskWidget = __esm({
1601
1526
  }
1602
1527
  )
1603
1528
  ] });
1529
+ ClassicMessageBubble = import_react2.default.memo(function ClassicMessageBubble2({ msg, accent }) {
1530
+ const isBot = msg.role === "bot";
1531
+ const renderedHtml = (0, import_react2.useMemo)(() => isBot ? parseMarkdown(msg.text) : msg.text, [isBot, msg.text]);
1532
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: isBot ? "flex-start" : "flex-end", gap: "4px" }, children: [
1533
+ msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", fontWeight: 500, color: "#9b9aa3", margin: 0, padding: "0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
1534
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1535
+ maxWidth: "82%",
1536
+ padding: "10px 14px",
1537
+ fontSize: "14px",
1538
+ lineHeight: 1.5,
1539
+ borderRadius: isBot ? "16px 16px 16px 6px" : "16px 16px 6px 16px",
1540
+ background: isBot ? "#fff" : accent,
1541
+ color: isBot ? "#1a1a2e" : "#fff",
1542
+ border: isBot ? "1px solid rgba(20,20,40,0.06)" : "none",
1543
+ boxShadow: isBot ? "0 1px 2px rgba(20,20,40,0.04)" : `0 6px 16px -6px color-mix(in oklab, ${accent} 60%, transparent)`,
1544
+ wordBreak: "break-word",
1545
+ fontFamily: "inherit"
1546
+ }, className: "sd-r-markdown", children: isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text }) }),
1547
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
1548
+ fontSize: "11px",
1549
+ color: "#a8a8b0",
1550
+ marginTop: "2px",
1551
+ padding: isBot ? "0 0 0 4px" : "0 4px 0 0",
1552
+ fontVariantNumeric: "tabular-nums",
1553
+ fontFamily: "inherit"
1554
+ }, children: "just now" })
1555
+ ] });
1556
+ });
1557
+ LightMessageBubble = import_react2.default.memo(function LightMessageBubble2({ msg, accent, agentName }) {
1558
+ const isBot = msg.role === "bot";
1559
+ const renderedHtml = (0, import_react2.useMemo)(() => isBot ? parseMarkdown(msg.text) : msg.text, [isBot, msg.text]);
1560
+ if (isBot) {
1561
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
1562
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1563
+ width: 28,
1564
+ height: 28,
1565
+ borderRadius: "50%",
1566
+ background: `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 60%, #fff))`,
1567
+ flexShrink: 0,
1568
+ marginTop: "2px"
1569
+ } }),
1570
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1571
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: "8px", marginBottom: "4px" }, children: [
1572
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "13px", fontWeight: 600, color: "#1a1a2e", fontFamily: "inherit" }, children: agentName }),
1573
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "#a8a89e", fontVariantNumeric: "tabular-nums", fontFamily: "inherit" }, children: "just now" })
1574
+ ] }),
1575
+ msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { fontSize: "11px", color: "#9b9aa3", margin: "0 0 4px", fontFamily: "inherit" }, children: "Not sure about that one" }),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: "14px", lineHeight: 1.55, color: "#2a2a36", fontFamily: "inherit", wordBreak: "break-word" }, className: "sd-r-markdown", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) })
1577
+ ] })
1578
+ ] });
1579
+ }
1580
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1581
+ maxWidth: "78%",
1582
+ padding: "11px 15px",
1583
+ fontSize: "14px",
1584
+ lineHeight: 1.5,
1585
+ borderRadius: "16px 16px 4px 16px",
1586
+ background: `color-mix(in oklab, ${accent} 10%, white)`,
1587
+ color: accent,
1588
+ border: `1px solid color-mix(in oklab, ${accent} 22%, transparent)`,
1589
+ fontWeight: 500,
1590
+ whiteSpace: "pre-wrap",
1591
+ wordBreak: "break-word",
1592
+ fontFamily: "inherit"
1593
+ }, children: msg.text }) });
1594
+ });
1595
+ DarkMessageBubble = import_react2.default.memo(function DarkMessageBubble2({ msg, accent }) {
1596
+ const isBot = msg.role === "bot";
1597
+ const renderedHtml = (0, import_react2.useMemo)(() => isBot ? parseMarkdown(msg.text) : msg.text, [isBot, msg.text]);
1598
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
1599
+ maxWidth: "85%",
1600
+ padding: "12px 14px",
1601
+ fontSize: "14px",
1602
+ lineHeight: isBot ? 1.6 : 1.5,
1603
+ borderRadius: isBot ? "14px 14px 14px 6px" : "14px 14px 6px 14px",
1604
+ background: isBot ? "rgba(255,255,255,0.05)" : `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 75%, #1a1340))`,
1605
+ border: isBot ? "1px solid rgba(255,255,255,0.06)" : "none",
1606
+ color: isBot ? "rgba(255,255,255,0.92)" : "#fff",
1607
+ alignSelf: isBot ? "flex-start" : "flex-end",
1608
+ boxShadow: isBot ? "none" : `0 8px 20px -8px color-mix(in oklab, ${accent} 70%, transparent)`,
1609
+ wordBreak: "break-word",
1610
+ fontFamily: "inherit"
1611
+ }, className: isBot ? "sd-r-markdown" : "", children: [
1612
+ msg.isFallback && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "rgba(255,255,255,0.5)", display: "block", marginBottom: "4px" }, children: "Not sure about that one" }),
1613
+ isBot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { whiteSpace: "pre-wrap" }, children: msg.text })
1614
+ ] });
1615
+ });
1604
1616
  }
1605
1617
  });
1606
1618