sagedesk 2.1.1 → 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,12 +355,27 @@ 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;
357
366
  if (config.mode === "llm") {
358
367
  setChips(config.agent.suggestedChips ?? []);
359
- dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
368
+ dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "loading-model" } });
369
+ try {
370
+ embedderRef.current = new EmbedderRuntime();
371
+ await embedderRef.current.load(config.agent.model);
372
+ dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
373
+ notifyEngineReady();
374
+ } catch (err) {
375
+ console.warn("[sagedesk] WASM embedder failed to load - LLM mode will use fallback messages.", err);
376
+ dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "error-model", error: String(err) } });
377
+ notifyEngineReady();
378
+ }
360
379
  return;
361
380
  }
362
381
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "loading-index" } });
@@ -368,6 +387,7 @@ function useSageDesk(config) {
368
387
  type: "SET_ENGINE_STATUS",
369
388
  payload: { status: "error-index", error: String(err) }
370
389
  });
390
+ notifyEngineReady();
371
391
  addMessage({
372
392
  role: "bot",
373
393
  text: "I'm having trouble loading right now. Please try again in a moment."
@@ -380,12 +400,14 @@ function useSageDesk(config) {
380
400
  embedderRef.current = new EmbedderRuntime();
381
401
  await embedderRef.current.load(config.agent.model);
382
402
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "ready" } });
403
+ notifyEngineReady();
383
404
  } catch (err) {
384
405
  console.warn("[sagedesk] WASM model failed to load, falling back to keyword search -", err);
385
406
  embedderRef.current = new EmbedderRuntime();
386
407
  dispatch({ type: "SET_ENGINE_STATUS", payload: { status: "degraded" } });
408
+ notifyEngineReady();
387
409
  }
388
- }, [config.mode, config.indexUrl, config.agent.suggestedChips, addMessage]);
410
+ }, [config.mode, config.indexUrl, config.agent.model, config.agent.suggestedChips, addMessage, notifyEngineReady]);
389
411
  const greetingShownRef = (0, import_react.useRef)(false);
390
412
  const open = (0, import_react.useCallback)(() => {
391
413
  dispatch({ type: "OPEN" });
@@ -402,16 +424,12 @@ function useSageDesk(config) {
402
424
  dispatch({ type: "CLOSE" });
403
425
  }, []);
404
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
+ }
405
431
  return new Promise((resolve) => {
406
- const check = () => {
407
- const s = engineStatusRef.current;
408
- if (s === "ready" || s === "degraded" || s === "error-index" || s === "error-model") {
409
- resolve();
410
- } else {
411
- setTimeout(check, 100);
412
- }
413
- };
414
- check();
432
+ engineReadyCallbacksRef.current.push(resolve);
415
433
  });
416
434
  }, []);
417
435
  const submit = (0, import_react.useCallback)(
@@ -435,12 +453,20 @@ function useSageDesk(config) {
435
453
  console.warn('[sagedesk] LLM mode requires an "endpoint" prop.');
436
454
  botText = getFallback(config.agent);
437
455
  isFallback = true;
456
+ } else if (!embedderRef.current?.isReady) {
457
+ console.warn("[sagedesk] Embedder not ready - showing fallback.");
458
+ botText = getFallback(config.agent);
459
+ isFallback = true;
438
460
  } else {
439
461
  try {
462
+ const vector = await embedderRef.current.embed(trimmed);
440
463
  const res = await fetch(config.endpoint, {
441
464
  method: "POST",
442
465
  headers: { "Content-Type": "application/json" },
443
- body: JSON.stringify({ query: trimmed })
466
+ body: JSON.stringify({
467
+ query: trimmed,
468
+ queryVector: Array.from(vector)
469
+ })
444
470
  });
445
471
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
446
472
  const data = await res.json();
@@ -484,8 +510,8 @@ function useSageDesk(config) {
484
510
  }
485
511
  if (config.mode !== "llm") {
486
512
  const elapsed = Date.now() - typingStart;
487
- const delayBase = retrievalMode === "keyword" || isFallback ? 800 : 3e3;
488
- const minTypingMs = delayBase + Math.random() * 2e3;
513
+ const delayBase = retrievalMode === "keyword" || isFallback ? 400 : 800;
514
+ const minTypingMs = delayBase + Math.random() * 400;
489
515
  const remaining = minTypingMs - elapsed;
490
516
  if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));
491
517
  }
@@ -503,11 +529,9 @@ function useSageDesk(config) {
503
529
  return () => document.removeEventListener("keydown", handler);
504
530
  }, [state.isOpen, close]);
505
531
  const activeChips = (0, import_react.useMemo)(() => {
506
- const askedTexts = new Set(
507
- state.messages.filter((m) => m.role === "user").map((m) => m.text.toLowerCase().trim())
508
- );
532
+ const askedTexts = new Set(state.userMessages.map((m) => m.text.toLowerCase().trim()));
509
533
  return chips.filter((chip) => !askedTexts.has(chip.toLowerCase().trim()));
510
- }, [chips, state.messages]);
534
+ }, [chips, state.userMessages]);
511
535
  return { state, chips: activeChips, open, close, submit };
512
536
  }
513
537
  var import_react, initialState;
@@ -521,6 +545,7 @@ var init_useSageDesk = __esm({
521
545
  init_fallback();
522
546
  initialState = {
523
547
  messages: [],
548
+ userMessages: [],
524
549
  isOpen: false,
525
550
  isTyping: false,
526
551
  engineStatus: "idle",
@@ -595,34 +620,6 @@ function injectStyles(theme) {
595
620
  style.textContent = THEME_CSS[theme];
596
621
  document.head.prepend(style);
597
622
  }
598
- function ClassicMessageBubble({ msg, accent }) {
599
- const isBot = msg.role === "bot";
600
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
601
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: isBot ? "flex-start" : "flex-end", gap: "4px" }, children: [
602
- 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" }),
603
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
604
- maxWidth: "82%",
605
- padding: "10px 14px",
606
- fontSize: "14px",
607
- lineHeight: 1.5,
608
- borderRadius: isBot ? "16px 16px 16px 6px" : "16px 16px 6px 16px",
609
- background: isBot ? "#fff" : accent,
610
- color: isBot ? "#1a1a2e" : "#fff",
611
- border: isBot ? "1px solid rgba(20,20,40,0.06)" : "none",
612
- boxShadow: isBot ? "0 1px 2px rgba(20,20,40,0.04)" : `0 6px 16px -6px color-mix(in oklab, ${accent} 60%, transparent)`,
613
- wordBreak: "break-word",
614
- fontFamily: "inherit"
615
- }, 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 }) }),
616
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
617
- fontSize: "11px",
618
- color: "#a8a8b0",
619
- marginTop: "2px",
620
- padding: isBot ? "0 0 0 4px" : "0 4px 0 0",
621
- fontVariantNumeric: "tabular-nums",
622
- fontFamily: "inherit"
623
- }, children: "just now" })
624
- ] });
625
- }
626
623
  function ClassicTypingIndicator() {
627
624
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "#c8c8ce", display: "inline-block" };
628
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: {
@@ -640,44 +637,6 @@ function ClassicTypingIndicator() {
640
637
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dot, className: "sd-r-dot-3" })
641
638
  ] }) });
642
639
  }
643
- function LightMessageBubble({ msg, accent, agentName }) {
644
- const isBot = msg.role === "bot";
645
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
646
- if (isBot) {
647
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
648
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
649
- width: 28,
650
- height: 28,
651
- borderRadius: "50%",
652
- background: `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 60%, #fff))`,
653
- flexShrink: 0,
654
- marginTop: "2px"
655
- } }),
656
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
657
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: "8px", marginBottom: "4px" }, children: [
658
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "13px", fontWeight: 600, color: "#1a1a2e", fontFamily: "inherit" }, children: agentName }),
659
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "11px", color: "#a8a89e", fontVariantNumeric: "tabular-nums", fontFamily: "inherit" }, children: "just now" })
660
- ] }),
661
- 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" }),
662
- /* @__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 } }) })
663
- ] })
664
- ] });
665
- }
666
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
667
- maxWidth: "78%",
668
- padding: "11px 15px",
669
- fontSize: "14px",
670
- lineHeight: 1.5,
671
- borderRadius: "16px 16px 4px 16px",
672
- background: `color-mix(in oklab, ${accent} 10%, white)`,
673
- color: accent,
674
- border: `1px solid color-mix(in oklab, ${accent} 22%, transparent)`,
675
- fontWeight: 500,
676
- whiteSpace: "pre-wrap",
677
- wordBreak: "break-word",
678
- fontFamily: "inherit"
679
- }, children: msg.text }) });
680
- }
681
640
  function LightTypingIndicator({ accent }) {
682
641
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "#c4c4be", display: "inline-block" };
683
642
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: "10px" }, children: [
@@ -705,27 +664,6 @@ function LightTypingIndicator({ accent }) {
705
664
  ] })
706
665
  ] });
707
666
  }
708
- function DarkMessageBubble({ msg, accent }) {
709
- const isBot = msg.role === "bot";
710
- const renderedHtml = isBot ? parseMarkdown(msg.text) : msg.text;
711
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
712
- maxWidth: "85%",
713
- padding: "12px 14px",
714
- fontSize: "14px",
715
- lineHeight: isBot ? 1.6 : 1.5,
716
- borderRadius: isBot ? "14px 14px 14px 6px" : "14px 14px 6px 14px",
717
- background: isBot ? "rgba(255,255,255,0.05)" : `linear-gradient(135deg, ${accent}, color-mix(in oklab, ${accent} 75%, #1a1340))`,
718
- border: isBot ? "1px solid rgba(255,255,255,0.06)" : "none",
719
- color: isBot ? "rgba(255,255,255,0.92)" : "#fff",
720
- alignSelf: isBot ? "flex-start" : "flex-end",
721
- boxShadow: isBot ? "none" : `0 8px 20px -8px color-mix(in oklab, ${accent} 70%, transparent)`,
722
- wordBreak: "break-word",
723
- fontFamily: "inherit"
724
- }, className: isBot ? "sd-r-markdown" : "", children: [
725
- 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" }),
726
- 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 })
727
- ] });
728
- }
729
667
  function DarkTypingIndicator() {
730
668
  const dot = { width: 6, height: 6, borderRadius: "50%", background: "rgba(255,255,255,0.4)", display: "inline-block" };
731
669
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
@@ -744,7 +682,7 @@ function DarkTypingIndicator() {
744
682
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dot, className: "sd-r-dot-3" })
745
683
  ] });
746
684
  }
747
- function renderClassic(p) {
685
+ function ClassicTheme(p) {
748
686
  const {
749
687
  agent,
750
688
  state,
@@ -933,7 +871,7 @@ function renderClassic(p) {
933
871
  ] })
934
872
  ] });
935
873
  }
936
- function renderLight(p) {
874
+ function LightTheme(p) {
937
875
  const {
938
876
  agent,
939
877
  state,
@@ -1121,7 +1059,7 @@ function renderLight(p) {
1121
1059
  ] })
1122
1060
  ] });
1123
1061
  }
1124
- function renderDark(p) {
1062
+ function DarkTheme(p) {
1125
1063
  const {
1126
1064
  agent,
1127
1065
  state,
@@ -1358,7 +1296,10 @@ function SageDeskWidget({ mode, indexUrl, endpoint, agent, search: search2 }) {
1358
1296
  '[sagedesk] Required prop "endpoint" is missing for llm mode. Provide your backend route, e.g. endpoint="/api/sagedesk".'
1359
1297
  );
1360
1298
  }
1361
- 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
+ );
1362
1303
  const { state, chips, open, close, submit } = useSageDesk(config);
1363
1304
  const theme = agent.theme ?? "classic";
1364
1305
  const accent = agent.accentColor ?? "#534AB7";
@@ -1437,14 +1378,14 @@ function SageDeskWidget({ mode, indexUrl, endpoint, agent, search: search2 }) {
1437
1378
  open,
1438
1379
  submit
1439
1380
  };
1440
- 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 });
1441
1382
  return (0, import_react_dom.createPortal)(content, document.body);
1442
1383
  }
1443
- 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;
1444
1385
  var init_SageDeskWidget = __esm({
1445
1386
  "src/react/SageDeskWidget.tsx"() {
1446
1387
  "use strict";
1447
- import_react2 = require("react");
1388
+ import_react2 = __toESM(require("react"), 1);
1448
1389
  import_react_dom = require("react-dom");
1449
1390
  init_useSageDesk();
1450
1391
  init_markdownUtils();
@@ -1585,6 +1526,93 @@ var init_SageDeskWidget = __esm({
1585
1526
  }
1586
1527
  )
1587
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
+ });
1588
1616
  }
1589
1617
  });
1590
1618