@burtson-labs/bandit-engine 2.0.129 → 2.0.130

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.
@@ -13090,7 +13090,8 @@ var init_ai_response_text_field = __esm({
13090
13090
  memoryUpdated,
13091
13091
  sourceFiles,
13092
13092
  isMobile = false,
13093
- cancelled = false
13093
+ cancelled = false,
13094
+ revealActionsOnHover = false
13094
13095
  }) => {
13095
13096
  (0, import_react14.useEffect)(() => {
13096
13097
  if (typeof response !== "string" && !import_react14.default.isValidElement(response)) {
@@ -13578,7 +13579,8 @@ ${sourcesMarkdownList.join("\n")}`;
13578
13579
  color: chatResponse.aiText || theme.palette.text.primary,
13579
13580
  px: isMobile ? 0.5 : 2,
13580
13581
  py: 1,
13581
- userSelect: "text"
13582
+ userSelect: "text",
13583
+ "&:hover .ai-response-actions": { opacity: 1 }
13582
13584
  },
13583
13585
  children: [
13584
13586
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Box, { sx: { display: "flex", justifyContent: "flex-end", mb: 2.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material8.Box, { sx: { maxWidth: { xs: "100%", sm: "85%" }, minWidth: 0 }, children: [
@@ -13678,7 +13680,18 @@ ${sourcesMarkdownList.join("\n")}`;
13678
13680
  }
13679
13681
  ) : import_react14.default.isValidElement(response) ? response : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Typography, { color: "error", children: "\u26A0\uFE0F Invalid AI response" }) })
13680
13682
  ] }),
13681
- !!(responseText || typeof response === "string" && response) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ai_response_action_bar_default, { text: responseText || response }),
13683
+ !!(responseText || typeof response === "string" && response) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
13684
+ import_material8.Box,
13685
+ {
13686
+ className: "ai-response-actions",
13687
+ sx: revealActionsOnHover ? {
13688
+ opacity: 0,
13689
+ transition: "opacity 0.15s ease",
13690
+ "&:focus-within": { opacity: 1 }
13691
+ } : void 0,
13692
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ai_response_action_bar_default, { text: responseText || response })
13693
+ }
13694
+ ),
13682
13695
  displaySourceFiles && displaySourceFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Box, { sx: { mt: 1.5, display: "flex", gap: 2, flexWrap: "wrap", justifyContent: "flex-start" }, children: displaySourceFiles.map((doc, idx) => {
13683
13696
  debugLogger.debug("Rendering DocumentCard in AI response", {
13684
13697
  index: idx,
@@ -16361,152 +16374,6 @@ var init_FeedbackModal = __esm({
16361
16374
  }
16362
16375
  });
16363
16376
 
16364
- // src/components/feedback/index.tsx
16365
- var init_feedback = __esm({
16366
- "src/components/feedback/index.tsx"() {
16367
- "use strict";
16368
- init_FeedbackButton();
16369
- init_FeedbackModal();
16370
- }
16371
- });
16372
-
16373
- // src/components/feedback/FeedbackButton.tsx
16374
- var import_react18, import_material14, import_lucide_react4, import_jsx_runtime14, FeedbackButton;
16375
- var init_FeedbackButton = __esm({
16376
- "src/components/feedback/FeedbackButton.tsx"() {
16377
- "use strict";
16378
- import_react18 = require("react");
16379
- import_material14 = require("@mui/material");
16380
- import_lucide_react4 = require("lucide-react");
16381
- init_feedback();
16382
- import_jsx_runtime14 = require("react/jsx-runtime");
16383
- FeedbackButton = ({
16384
- fullScreen = false,
16385
- className,
16386
- zIndex = 1400,
16387
- feedbackEmail,
16388
- inline = false,
16389
- buttonText = "Send Feedback",
16390
- size = "small",
16391
- position,
16392
- absolute = false
16393
- }) => {
16394
- const theme = (0, import_material14.useTheme)();
16395
- const [open, setOpen] = (0, import_react18.useState)(false);
16396
- const handleOpen = () => setOpen(true);
16397
- const handleClose = () => setOpen(false);
16398
- if (inline) {
16399
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
16400
- buttonText ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16401
- import_material14.Button,
16402
- {
16403
- variant: "outlined",
16404
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {}),
16405
- onClick: handleOpen,
16406
- className,
16407
- size,
16408
- sx: {
16409
- borderRadius: 2,
16410
- textTransform: "none",
16411
- "&:hover": {
16412
- transform: "translateY(-1px)",
16413
- boxShadow: theme.shadows[4]
16414
- }
16415
- },
16416
- children: buttonText
16417
- }
16418
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material14.Tooltip, { title: "Send Feedback", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16419
- import_material14.IconButton,
16420
- {
16421
- onClick: handleOpen,
16422
- className,
16423
- size,
16424
- sx: {
16425
- color: theme.palette.primary.main,
16426
- borderRadius: 2,
16427
- transition: "all 0.2s ease",
16428
- "&:hover": {
16429
- bgcolor: theme.palette.primary.main + "15",
16430
- transform: "translateY(-1px)"
16431
- }
16432
- },
16433
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {})
16434
- }
16435
- ) }),
16436
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16437
- FeedbackModal,
16438
- {
16439
- open,
16440
- onClose: handleClose,
16441
- feedbackEmail
16442
- }
16443
- )
16444
- ] });
16445
- }
16446
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
16447
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material14.Zoom, { in: true, timeout: 300, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16448
- import_material14.Tooltip,
16449
- {
16450
- title: "Send Feedback",
16451
- placement: "left",
16452
- arrow: true,
16453
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16454
- import_material14.Fab,
16455
- {
16456
- size,
16457
- onClick: handleOpen,
16458
- className,
16459
- sx: {
16460
- position: absolute ? "absolute" : "relative",
16461
- ...absolute && {
16462
- bottom: position?.bottom ?? (fullScreen ? 16 : 20),
16463
- right: position?.right ?? 16,
16464
- top: position?.top,
16465
- left: position?.left
16466
- },
16467
- zIndex,
16468
- bgcolor: theme.palette.primary.main,
16469
- color: theme.palette.primary.contrastText,
16470
- boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.15)",
16471
- border: `1px solid ${theme.palette.divider}`,
16472
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
16473
- "&:hover": {
16474
- bgcolor: theme.palette.primary.dark,
16475
- transform: "scale(1.05) translateY(-2px)",
16476
- boxShadow: theme.palette.mode === "dark" ? "0 12px 40px rgba(0,0,0,0.5)" : "0 12px 40px rgba(0,0,0,0.2)"
16477
- },
16478
- "&:active": {
16479
- transform: "scale(0.98) translateY(0px)"
16480
- },
16481
- // Subtle pulsing animation
16482
- animation: "feedbackPulse 3s ease-in-out infinite",
16483
- "@keyframes feedbackPulse": {
16484
- "0%, 100%": {
16485
- boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.15)"
16486
- },
16487
- "50%": {
16488
- boxShadow: theme.palette.mode === "dark" ? `0 8px 32px ${theme.palette.primary.main}40` : `0 8px 32px ${theme.palette.primary.main}30`
16489
- }
16490
- }
16491
- },
16492
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {})
16493
- }
16494
- )
16495
- }
16496
- ) }),
16497
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
16498
- FeedbackModal,
16499
- {
16500
- open,
16501
- onClose: handleClose,
16502
- feedbackEmail
16503
- }
16504
- )
16505
- ] });
16506
- };
16507
- }
16508
- });
16509
-
16510
16377
  // src/shared/components/NotificationProvider.tsx
16511
16378
  var import_react21, import_material16, import_jsx_runtime15, NotificationContext, useNotification;
16512
16379
  var init_NotificationProvider = __esm({
@@ -20731,7 +20598,8 @@ var init_chat_messages = __esm({
20731
20598
  memoryUpdated: entry.memoryUpdated && !isPlaceholder,
20732
20599
  sourceFiles: rawSources,
20733
20600
  isMobile,
20734
- cancelled: entry.cancelled
20601
+ cancelled: entry.cancelled,
20602
+ revealActionsOnHover: !isLast && !isMobile
20735
20603
  }
20736
20604
  ) }, index);
20737
20605
  }),
@@ -26862,6 +26730,7 @@ var init_conversation_drawer = __esm({
26862
26730
  import_react57 = require("react");
26863
26731
  import_material46 = require("@mui/material");
26864
26732
  import_lucide_react14 = require("lucide-react");
26733
+ init_FeedbackModal();
26865
26734
  import_styles30 = require("@mui/material/styles");
26866
26735
  init_conversationStore();
26867
26736
  init_projectStore();
@@ -26937,6 +26806,7 @@ var init_conversation_drawer = __esm({
26937
26806
  const [searchQuery, setSearchQuery] = (0, import_react57.useState)("");
26938
26807
  const [menuAnchorEl, setMenuAnchorEl] = (0, import_react57.useState)(null);
26939
26808
  const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react57.useState)(false);
26809
+ const [feedbackOpen, setFeedbackOpen] = (0, import_react57.useState)(false);
26940
26810
  const [moveModalOpen, setMoveModalOpen] = (0, import_react57.useState)(false);
26941
26811
  const [conversationToMove, setConversationToMove] = (0, import_react57.useState)(null);
26942
26812
  const [renameProjectId, setRenameProjectId] = (0, import_react57.useState)(null);
@@ -27757,7 +27627,7 @@ var init_conversation_drawer = __esm({
27757
27627
  currentProjectId: conversationToMove.projectId
27758
27628
  }
27759
27629
  ),
27760
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
27630
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
27761
27631
  import_material46.Menu,
27762
27632
  {
27763
27633
  anchorEl: menuAnchorEl,
@@ -27771,20 +27641,43 @@ var init_conversation_drawer = __esm({
27771
27641
  vertical: "bottom",
27772
27642
  horizontal: "right"
27773
27643
  },
27774
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
27775
- import_material46.MenuItem,
27776
- {
27777
- onClick: () => {
27778
- setClearConfirmOpen(true);
27779
- handleMenuClose();
27780
- },
27781
- sx: { color: theme.palette.error.main },
27782
- children: [
27783
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react14.Trash2, { size: 16, color: theme.palette.error.main }) }),
27784
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemText, { children: "Clear All Conversations" })
27785
- ]
27786
- }
27787
- )
27644
+ children: [
27645
+ preferences.feedbackEnabled && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
27646
+ import_material46.MenuItem,
27647
+ {
27648
+ onClick: () => {
27649
+ setFeedbackOpen(true);
27650
+ handleMenuClose();
27651
+ },
27652
+ children: [
27653
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react14.MessageSquare, { size: 16 }) }),
27654
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemText, { children: "Send feedback" })
27655
+ ]
27656
+ }
27657
+ ),
27658
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
27659
+ import_material46.MenuItem,
27660
+ {
27661
+ onClick: () => {
27662
+ setClearConfirmOpen(true);
27663
+ handleMenuClose();
27664
+ },
27665
+ sx: { color: theme.palette.error.main },
27666
+ children: [
27667
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react14.Trash2, { size: 16, color: theme.palette.error.main }) }),
27668
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material46.ListItemText, { children: "Clear All Conversations" })
27669
+ ]
27670
+ }
27671
+ )
27672
+ ]
27673
+ }
27674
+ ),
27675
+ preferences.feedbackEnabled && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
27676
+ FeedbackModal,
27677
+ {
27678
+ open: feedbackOpen,
27679
+ onClose: () => setFeedbackOpen(false),
27680
+ feedbackEmail: usePackageSettingsStore.getState().settings?.feedbackEmail
27788
27681
  }
27789
27682
  ),
27790
27683
  /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
@@ -29744,20 +29637,185 @@ var init_UnderReview = __esm({
29744
29637
  }
29745
29638
  });
29746
29639
 
29640
+ // src/components/feedback/FeedbackPulse.tsx
29641
+ var import_react61, import_material52, import_styles33, import_lucide_react16, import_jsx_runtime51, STORAGE_KEY3, COOLDOWN_DAYS, MIN_SESSION_MS, MIN_MESSAGES_SENT, CHECK_INTERVAL_MS, readLastInteraction, recordInteraction, FeedbackPulse, FeedbackPulse_default;
29642
+ var init_FeedbackPulse = __esm({
29643
+ "src/components/feedback/FeedbackPulse.tsx"() {
29644
+ "use strict";
29645
+ import_react61 = require("react");
29646
+ import_material52 = require("@mui/material");
29647
+ import_styles33 = require("@mui/material/styles");
29648
+ import_lucide_react16 = require("lucide-react");
29649
+ init_conversationStore();
29650
+ init_FeedbackModal();
29651
+ init_debugLogger();
29652
+ import_jsx_runtime51 = require("react/jsx-runtime");
29653
+ STORAGE_KEY3 = "bandit-feedback-pulse-last";
29654
+ COOLDOWN_DAYS = 14;
29655
+ MIN_SESSION_MS = 5 * 60 * 1e3;
29656
+ MIN_MESSAGES_SENT = 2;
29657
+ CHECK_INTERVAL_MS = 30 * 1e3;
29658
+ readLastInteraction = () => {
29659
+ try {
29660
+ return Number(localStorage.getItem(STORAGE_KEY3)) || 0;
29661
+ } catch {
29662
+ return 0;
29663
+ }
29664
+ };
29665
+ recordInteraction = (outcome) => {
29666
+ try {
29667
+ localStorage.setItem(STORAGE_KEY3, String(Date.now()));
29668
+ } catch {
29669
+ }
29670
+ debugLogger.info("FeedbackPulse: interaction recorded", { outcome });
29671
+ };
29672
+ FeedbackPulse = ({ isMobile, feedbackEmail }) => {
29673
+ const theme = (0, import_styles33.useTheme)();
29674
+ const [visible, setVisible] = (0, import_react61.useState)(false);
29675
+ const [thanked, setThanked] = (0, import_react61.useState)(false);
29676
+ const [modalOpen, setModalOpen] = (0, import_react61.useState)(false);
29677
+ const mountedAtRef = (0, import_react61.useRef)(Date.now());
29678
+ const baselineMessagesRef = (0, import_react61.useRef)(null);
29679
+ const totalMessages = useConversationStore(
29680
+ (s) => s.conversations.reduce((n, c) => n + c.history.length, 0)
29681
+ );
29682
+ const hydrated = useConversationStore((s) => s._hasHydrated);
29683
+ (0, import_react61.useEffect)(() => {
29684
+ if (hydrated && baselineMessagesRef.current === null) {
29685
+ baselineMessagesRef.current = totalMessages;
29686
+ }
29687
+ }, [hydrated, totalMessages]);
29688
+ (0, import_react61.useEffect)(() => {
29689
+ const cooldownMs = COOLDOWN_DAYS * 24 * 60 * 60 * 1e3;
29690
+ const forced = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("feedbackPulse");
29691
+ const check = () => {
29692
+ if (visible || thanked || modalOpen) return;
29693
+ if (forced) {
29694
+ setVisible(true);
29695
+ return;
29696
+ }
29697
+ if (Date.now() - readLastInteraction() < cooldownMs) return;
29698
+ if (Date.now() - mountedAtRef.current < MIN_SESSION_MS) return;
29699
+ const baseline = baselineMessagesRef.current;
29700
+ if (baseline === null) return;
29701
+ const sentThisSession = useConversationStore.getState().conversations.reduce((n, c) => n + c.history.length, 0) - baseline;
29702
+ if (sentThisSession < MIN_MESSAGES_SENT) return;
29703
+ setVisible(true);
29704
+ };
29705
+ if (forced) check();
29706
+ const timer = setInterval(check, CHECK_INTERVAL_MS);
29707
+ return () => clearInterval(timer);
29708
+ }, [visible, thanked, modalOpen]);
29709
+ const answer = (outcome) => {
29710
+ recordInteraction(outcome);
29711
+ if (outcome === "bad") {
29712
+ setVisible(false);
29713
+ setModalOpen(true);
29714
+ return;
29715
+ }
29716
+ setThanked(true);
29717
+ setTimeout(() => {
29718
+ setVisible(false);
29719
+ setThanked(false);
29720
+ }, 1600);
29721
+ };
29722
+ const dismiss = () => {
29723
+ recordInteraction("dismissed");
29724
+ setVisible(false);
29725
+ };
29726
+ const choice = (emoji, label, outcome) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
29727
+ import_material52.Box,
29728
+ {
29729
+ component: "button",
29730
+ type: "button",
29731
+ onClick: () => answer(outcome),
29732
+ sx: {
29733
+ font: "inherit",
29734
+ display: "flex",
29735
+ flexDirection: "column",
29736
+ alignItems: "center",
29737
+ gap: 0.25,
29738
+ px: 1.5,
29739
+ py: 0.75,
29740
+ border: "none",
29741
+ borderRadius: 2,
29742
+ cursor: "pointer",
29743
+ bgcolor: "transparent",
29744
+ color: theme.palette.text.secondary,
29745
+ transition: "background-color 0.15s ease, transform 0.1s ease",
29746
+ "&:hover": {
29747
+ bgcolor: (0, import_styles33.alpha)(theme.palette.text.primary, 0.06),
29748
+ color: theme.palette.text.primary
29749
+ },
29750
+ "&:active": { transform: "scale(0.96)" }
29751
+ },
29752
+ children: [
29753
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Box, { component: "span", sx: { fontSize: "1.3rem", lineHeight: 1 }, children: emoji }),
29754
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { variant: "caption", sx: { fontWeight: 600 }, children: label })
29755
+ ]
29756
+ }
29757
+ );
29758
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
29759
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Slide, { direction: isMobile ? "down" : "up", in: visible, mountOnEnter: true, unmountOnExit: true, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
29760
+ import_material52.Paper,
29761
+ {
29762
+ elevation: 0,
29763
+ sx: {
29764
+ position: "fixed",
29765
+ zIndex: 1350,
29766
+ ...isMobile ? {
29767
+ top: `calc(${theme.spacing(8)} + env(safe-area-inset-top, 0px))`,
29768
+ left: "50%",
29769
+ transform: "translateX(-50%) !important",
29770
+ width: "min(92vw, 360px)"
29771
+ } : { bottom: 24, right: 24, width: 320 },
29772
+ p: 1.5,
29773
+ borderRadius: 3,
29774
+ border: `1px solid ${theme.palette.divider}`,
29775
+ bgcolor: theme.palette.background.paper,
29776
+ boxShadow: `0 12px 40px ${(0, import_styles33.alpha)(theme.palette.common.black, theme.palette.mode === "dark" ? 0.5 : 0.18)}`
29777
+ },
29778
+ children: thanked ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { sx: { textAlign: "center", py: 1.5, fontWeight: 600 }, children: "Thanks for the feedback! \u{1F64C}" }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
29779
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_material52.Box, { sx: { display: "flex", alignItems: "center", mb: 0.5 }, children: [
29780
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: "How's Bandit doing?" }),
29781
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.IconButton, { size: "small", onClick: dismiss, "aria-label": "Dismiss feedback prompt", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react16.X, { size: 16 }) })
29782
+ ] }),
29783
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_material52.Box, { sx: { display: "flex", justifyContent: "space-evenly" }, children: [
29784
+ choice("\u{1F60A}", "Good", "good"),
29785
+ choice("\u{1F610}", "Fine", "fine"),
29786
+ choice("\u{1F641}", "Bad", "bad")
29787
+ ] })
29788
+ ] })
29789
+ }
29790
+ ) }),
29791
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
29792
+ FeedbackModal,
29793
+ {
29794
+ open: modalOpen,
29795
+ onClose: () => setModalOpen(false),
29796
+ feedbackEmail
29797
+ }
29798
+ )
29799
+ ] });
29800
+ };
29801
+ FeedbackPulse_default = FeedbackPulse;
29802
+ }
29803
+ });
29804
+
29747
29805
  // src/components/ConnectionStatus.tsx
29748
- var import_material52, import_jsx_runtime51, ConnectionStatus;
29806
+ var import_material53, import_jsx_runtime52, ConnectionStatus;
29749
29807
  var init_ConnectionStatus = __esm({
29750
29808
  "src/components/ConnectionStatus.tsx"() {
29751
29809
  "use strict";
29752
- import_material52 = require("@mui/material");
29810
+ import_material53 = require("@mui/material");
29753
29811
  init_useNetworkStatus();
29754
29812
  init_lucide_icons();
29755
- import_jsx_runtime51 = require("react/jsx-runtime");
29813
+ import_jsx_runtime52 = require("react/jsx-runtime");
29756
29814
  ConnectionStatus = ({
29757
29815
  showWhenGood = false,
29758
29816
  position = "top"
29759
29817
  }) => {
29760
- const theme = (0, import_material52.useTheme)();
29818
+ const theme = (0, import_material53.useTheme)();
29761
29819
  const { isOnline, connectionQuality, isSlowConnection } = useNetworkStatus();
29762
29820
  if (connectionQuality === "fast" && !showWhenGood) {
29763
29821
  return null;
@@ -29766,28 +29824,28 @@ var init_ConnectionStatus = __esm({
29766
29824
  switch (connectionQuality) {
29767
29825
  case "offline":
29768
29826
  return {
29769
- icon: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(WifiOffIcon, { sx: { fontSize: 16 } }),
29827
+ icon: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(WifiOffIcon, { sx: { fontSize: 16 } }),
29770
29828
  label: "Offline",
29771
29829
  color: "error",
29772
29830
  severity: "high"
29773
29831
  };
29774
29832
  case "slow":
29775
29833
  return {
29776
- icon: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(SignalWifi2BarIcon, { sx: { fontSize: 16 } }),
29834
+ icon: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(SignalWifi2BarIcon, { sx: { fontSize: 16 } }),
29777
29835
  label: "Slow connection",
29778
29836
  color: "warning",
29779
29837
  severity: "medium"
29780
29838
  };
29781
29839
  case "fast":
29782
29840
  return {
29783
- icon: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(WifiIcon, { sx: { fontSize: 16 } }),
29841
+ icon: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(WifiIcon, { sx: { fontSize: 16 } }),
29784
29842
  label: "Connected",
29785
29843
  color: "success",
29786
29844
  severity: "low"
29787
29845
  };
29788
29846
  default:
29789
29847
  return {
29790
- icon: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(WifiIcon, { sx: { fontSize: 16 } }),
29848
+ icon: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(WifiIcon, { sx: { fontSize: 16 } }),
29791
29849
  label: "Unknown",
29792
29850
  color: "default",
29793
29851
  severity: "low"
@@ -29795,8 +29853,8 @@ var init_ConnectionStatus = __esm({
29795
29853
  }
29796
29854
  };
29797
29855
  const config = getStatusConfig();
29798
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
29799
- import_material52.Box,
29856
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
29857
+ import_material53.Box,
29800
29858
  {
29801
29859
  sx: {
29802
29860
  position: "fixed",
@@ -29811,8 +29869,8 @@ var init_ConnectionStatus = __esm({
29811
29869
  "100%": { opacity: 1 }
29812
29870
  }
29813
29871
  },
29814
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
29815
- import_material52.Chip,
29872
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
29873
+ import_material53.Chip,
29816
29874
  {
29817
29875
  icon: config.icon,
29818
29876
  label: config.label,
@@ -29837,11 +29895,11 @@ var init_ConnectionStatus = __esm({
29837
29895
  });
29838
29896
 
29839
29897
  // src/hooks/useVoiceMode.ts
29840
- var import_react61, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
29898
+ var import_react62, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
29841
29899
  var init_useVoiceMode = __esm({
29842
29900
  "src/hooks/useVoiceMode.ts"() {
29843
29901
  "use strict";
29844
- import_react61 = require("react");
29902
+ import_react62 = require("react");
29845
29903
  init_stt_client();
29846
29904
  init_debugLogger();
29847
29905
  init_voiceModeStore();
@@ -29874,11 +29932,11 @@ var init_useVoiceMode = __esm({
29874
29932
  const setError = useVoiceModeStore((state) => state.setError);
29875
29933
  const resetTransientState = useVoiceModeStore((state) => state.resetTransientState);
29876
29934
  const setLastTranscript = useVoiceModeStore((state) => state.setLastTranscript);
29877
- const configRef = (0, import_react61.useRef)(config);
29878
- (0, import_react61.useEffect)(() => {
29935
+ const configRef = (0, import_react62.useRef)(config);
29936
+ (0, import_react62.useEffect)(() => {
29879
29937
  configRef.current = config;
29880
29938
  }, [config]);
29881
- (0, import_react61.useEffect)(() => {
29939
+ (0, import_react62.useEffect)(() => {
29882
29940
  if (!enabled) {
29883
29941
  return () => void 0;
29884
29942
  }
@@ -30139,15 +30197,15 @@ var chat_exports = {};
30139
30197
  __export(chat_exports, {
30140
30198
  default: () => chat_default
30141
30199
  });
30142
- var import_react62, import_material53, import_styles33, import_react_router_dom5, import_jsx_runtime52, ChatContent, Chat, chat_default;
30200
+ var import_react63, import_material54, import_styles34, import_react_router_dom5, import_jsx_runtime53, ChatContent, Chat, chat_default;
30143
30201
  var init_chat2 = __esm({
30144
30202
  "src/chat/chat.tsx"() {
30145
30203
  "use strict";
30146
- import_react62 = require("react");
30204
+ import_react63 = require("react");
30147
30205
  init_custom_logo();
30148
30206
  init_indexedDBService();
30149
- import_material53 = require("@mui/material");
30150
- import_styles33 = require("@mui/material/styles");
30207
+ import_material54 = require("@mui/material");
30208
+ import_styles34 = require("@mui/material/styles");
30151
30209
  init_aiQueryStore();
30152
30210
  init_modelStore();
30153
30211
  init_canvasStore();
@@ -30178,14 +30236,14 @@ var init_chat2 = __esm({
30178
30236
  init_preferencesStore();
30179
30237
  init_debugLogger();
30180
30238
  init_streaming_tts();
30181
- init_FeedbackButton();
30239
+ init_FeedbackPulse();
30182
30240
  init_useNotificationService();
30183
30241
  init_ConnectionStatus();
30184
30242
  init_useVoiceMode();
30185
30243
  init_voiceModeStore();
30186
30244
  init_ttsSanitizer();
30187
30245
  init_FeatureFlagContext();
30188
- import_jsx_runtime52 = require("react/jsx-runtime");
30246
+ import_jsx_runtime53 = require("react/jsx-runtime");
30189
30247
  ChatContent = () => {
30190
30248
  const packageSettings = usePackageSettingsStore((state) => state.settings);
30191
30249
  const UnderReviewView = packageSettings?.components?.UnderReview ?? UnderReview_default;
@@ -30194,13 +30252,13 @@ var init_chat2 = __esm({
30194
30252
  const ossMode = isOSSMode() || !packageSettings?.featureFlags?.subscriptionType;
30195
30253
  const playgroundBypassAccess = packageSettings?.playgroundBypassAuth || typeof window !== "undefined" && window.location.pathname.includes("/playground");
30196
30254
  const notificationService2 = useNotificationService();
30197
- const [selectedTheme, setSelectedTheme] = (0, import_react62.useState)(null);
30198
- const [themeLoading, setThemeLoading] = (0, import_react62.useState)(true);
30255
+ const [selectedTheme, setSelectedTheme] = (0, import_react63.useState)(null);
30256
+ const [themeLoading, setThemeLoading] = (0, import_react63.useState)(true);
30199
30257
  const token = authenticationService.getToken();
30200
30258
  const claims = token ? authenticationService.parseJwtClaims(token) : null;
30201
30259
  const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
30202
- const banditTheme = (0, import_react62.useMemo)(() => {
30203
- return (0, import_styles33.createTheme)(baseTheme, {
30260
+ const banditTheme = (0, import_react63.useMemo)(() => {
30261
+ return (0, import_styles34.createTheme)(baseTheme, {
30204
30262
  components: {
30205
30263
  MuiInputBase: {
30206
30264
  styleOverrides: {
@@ -30247,12 +30305,12 @@ var init_chat2 = __esm({
30247
30305
  } = useVoiceStore();
30248
30306
  const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);
30249
30307
  const canvasOpen = useCanvasStore((state) => state.open);
30250
- const previousVoiceModeEnabledRef = (0, import_react62.useRef)(isVoiceModeEnabled);
30251
- const historyRef = (0, import_react62.useRef)(history);
30252
- (0, import_react62.useEffect)(() => {
30308
+ const previousVoiceModeEnabledRef = (0, import_react63.useRef)(isVoiceModeEnabled);
30309
+ const historyRef = (0, import_react63.useRef)(history);
30310
+ (0, import_react63.useEffect)(() => {
30253
30311
  historyRef.current = history;
30254
30312
  }, [history]);
30255
- (0, import_react62.useEffect)(() => {
30313
+ (0, import_react63.useEffect)(() => {
30256
30314
  if (!hydrated) return;
30257
30315
  const params = new URLSearchParams(window.location.search);
30258
30316
  const title = params.get("title") || "";
@@ -30268,7 +30326,7 @@ var init_chat2 = __esm({
30268
30326
  stop: ttsStop,
30269
30327
  isAvailable: isTTSAvailable
30270
30328
  } = useTTS();
30271
- (0, import_react62.useEffect)(() => {
30329
+ (0, import_react63.useEffect)(() => {
30272
30330
  const timer = setTimeout(() => {
30273
30331
  const isAuthenticated = authenticationService.isAuthenticated();
30274
30332
  if (!initialized || availableVoices.length === 0) {
@@ -30282,7 +30340,7 @@ var init_chat2 = __esm({
30282
30340
  }, 500);
30283
30341
  return () => clearTimeout(timer);
30284
30342
  }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
30285
- (0, import_react62.useEffect)(() => {
30343
+ (0, import_react63.useEffect)(() => {
30286
30344
  const isAuthenticated = authenticationService.isAuthenticated();
30287
30345
  if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
30288
30346
  if (token && isAuthenticated) {
@@ -30294,17 +30352,17 @@ var init_chat2 = __esm({
30294
30352
  }
30295
30353
  }, [packageSettings?.gatewayApiUrl, availableVoices.length, initialized, loadVoicesFromAPI, token]);
30296
30354
  const provider = useAIProviderStore((state) => state.provider);
30297
- const inputRef = (0, import_react62.useRef)(null);
30298
- const [pastedImages, setPastedImages] = (0, import_react62.useState)([]);
30299
- const inputContainerRef = (0, import_react62.useRef)(null);
30300
- const [inputHeight, setInputHeight] = (0, import_react62.useState)(80);
30301
- const [isSubmitting, setIsSubmitting] = (0, import_react62.useState)(false);
30302
- const [pendingMessage, setPendingMessage] = (0, import_react62.useState)(null);
30355
+ const inputRef = (0, import_react63.useRef)(null);
30356
+ const [pastedImages, setPastedImages] = (0, import_react63.useState)([]);
30357
+ const inputContainerRef = (0, import_react63.useRef)(null);
30358
+ const [inputHeight, setInputHeight] = (0, import_react63.useState)(80);
30359
+ const [isSubmitting, setIsSubmitting] = (0, import_react63.useState)(false);
30360
+ const [pendingMessage, setPendingMessage] = (0, import_react63.useState)(null);
30303
30361
  const { conversations, currentId, _hasHydrated, hydrate, toggleIncognito } = useConversationStore();
30304
30362
  const isTemporaryChat = Boolean(conversations.find((c) => c.id === currentId)?.incognito);
30305
- const [isMobile, setIsMobile] = (0, import_react62.useState)(false);
30306
- const [drawerOpen, setDrawerOpen] = (0, import_react62.useState)(false);
30307
- const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react62.useState)(false);
30363
+ const [isMobile, setIsMobile] = (0, import_react63.useState)(false);
30364
+ const [drawerOpen, setDrawerOpen] = (0, import_react63.useState)(false);
30365
+ const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react63.useState)(false);
30308
30366
  const { generateName } = useConversationNameGenerator();
30309
30367
  const { preferences } = usePreferencesStore();
30310
30368
  const { containerRef: chatContainerRef, targetRef: scrollTargetRef, scrollToBottom, getScrollState } = useAutoScroll({
@@ -30316,27 +30374,27 @@ var init_chat2 = __esm({
30316
30374
  const chatContainerEl = chatContainerRef.current;
30317
30375
  const scrollTargetEl = scrollTargetRef.current;
30318
30376
  const { isSlowConnection, connectionQuality, trackRequestStart, trackRequestEnd } = useNetworkStatus();
30319
- const [showScrollToBottom, setShowScrollToBottom] = (0, import_react62.useState)(false);
30320
- const [streamBuffer, setStreamBuffer] = (0, import_react62.useState)("");
30321
- const [responseStarted, setResponseStarted] = (0, import_react62.useState)(false);
30322
- const [isStreaming, setIsStreaming] = (0, import_react62.useState)(false);
30323
- const [isThinking, setIsThinking] = (0, import_react62.useState)(false);
30377
+ const [showScrollToBottom, setShowScrollToBottom] = (0, import_react63.useState)(false);
30378
+ const [streamBuffer, setStreamBuffer] = (0, import_react63.useState)("");
30379
+ const [responseStarted, setResponseStarted] = (0, import_react63.useState)(false);
30380
+ const [isStreaming, setIsStreaming] = (0, import_react63.useState)(false);
30381
+ const [isThinking, setIsThinking] = (0, import_react63.useState)(false);
30324
30382
  const initialLogoState = history.length === 0;
30325
- const [logoVisible, setLogoVisible] = (0, import_react62.useState)(initialLogoState);
30326
- const [logoShouldRender, setLogoShouldRender] = (0, import_react62.useState)(initialLogoState);
30327
- const streamingGraceUntilRef = (0, import_react62.useRef)(0);
30383
+ const [logoVisible, setLogoVisible] = (0, import_react63.useState)(initialLogoState);
30384
+ const [logoShouldRender, setLogoShouldRender] = (0, import_react63.useState)(initialLogoState);
30385
+ const streamingGraceUntilRef = (0, import_react63.useRef)(0);
30328
30386
  const GRACE_MS = 450;
30329
30387
  const GRACE_OFFSET_DESKTOP = 28;
30330
30388
  const GRACE_OFFSET_MOBILE = 20;
30331
- const followStreamRef = (0, import_react62.useRef)(true);
30332
- const lastSpokenResponseRef = (0, import_react62.useRef)(null);
30333
- const previousConversationIdRef = (0, import_react62.useRef)(null);
30334
- const logoFadeTimeoutRef = (0, import_react62.useRef)(null);
30335
- const [branding, setBranding] = (0, import_react62.useState)(null);
30336
- const [brandingLoading, setBrandingLoading] = (0, import_react62.useState)(true);
30337
- const isBrandingLoadInProgressRef = (0, import_react62.useRef)(false);
30389
+ const followStreamRef = (0, import_react63.useRef)(true);
30390
+ const lastSpokenResponseRef = (0, import_react63.useRef)(null);
30391
+ const previousConversationIdRef = (0, import_react63.useRef)(null);
30392
+ const logoFadeTimeoutRef = (0, import_react63.useRef)(null);
30393
+ const [branding, setBranding] = (0, import_react63.useState)(null);
30394
+ const [brandingLoading, setBrandingLoading] = (0, import_react63.useState)(true);
30395
+ const isBrandingLoadInProgressRef = (0, import_react63.useRef)(false);
30338
30396
  const logoOnly = history.length === 0 && !brandingLoading;
30339
- (0, import_react62.useEffect)(() => {
30397
+ (0, import_react63.useEffect)(() => {
30340
30398
  const isEmptyConversation = (history?.length ?? 0) === 0;
30341
30399
  const isSending = Boolean(pendingMessage);
30342
30400
  const shouldShowLogo = isEmptyConversation && !isSending;
@@ -30366,7 +30424,7 @@ var init_chat2 = __esm({
30366
30424
  }, 500);
30367
30425
  }
30368
30426
  }, [history, pendingMessage]);
30369
- (0, import_react62.useEffect)(() => {
30427
+ (0, import_react63.useEffect)(() => {
30370
30428
  if (!brandingLoading && !themeLoading) {
30371
30429
  return;
30372
30430
  }
@@ -30382,18 +30440,18 @@ var init_chat2 = __esm({
30382
30440
  }, 2500);
30383
30441
  return () => window.clearTimeout(timeoutId);
30384
30442
  }, [brandingLoading, themeLoading, selectedTheme]);
30385
- (0, import_react62.useEffect)(() => () => {
30443
+ (0, import_react63.useEffect)(() => () => {
30386
30444
  if (logoFadeTimeoutRef.current) {
30387
30445
  window.clearTimeout(logoFadeTimeoutRef.current);
30388
30446
  logoFadeTimeoutRef.current = null;
30389
30447
  }
30390
30448
  }, []);
30391
- (0, import_react62.useEffect)(() => {
30449
+ (0, import_react63.useEffect)(() => {
30392
30450
  if (isStreaming && streamBuffer.trim() === "") {
30393
30451
  streamingGraceUntilRef.current = Date.now() + GRACE_MS;
30394
30452
  }
30395
30453
  }, [isStreaming, streamBuffer]);
30396
- (0, import_react62.useEffect)(() => {
30454
+ (0, import_react63.useEffect)(() => {
30397
30455
  if (!isStreaming) return;
30398
30456
  const container = chatContainerRef.current;
30399
30457
  if (!container) return;
@@ -30404,13 +30462,13 @@ var init_chat2 = __esm({
30404
30462
  container.scrollTo({ top: targetTop, behavior: "smooth" });
30405
30463
  }
30406
30464
  }, [streamBuffer, isStreaming, isMobile, chatContainerRef]);
30407
- (0, import_react62.useEffect)(() => {
30465
+ (0, import_react63.useEffect)(() => {
30408
30466
  if (!_hasHydrated) {
30409
30467
  debugLogger.info("Chat component triggering conversation store hydration");
30410
30468
  hydrate();
30411
30469
  }
30412
30470
  }, [_hasHydrated, hydrate]);
30413
- (0, import_react62.useEffect)(() => {
30471
+ (0, import_react63.useEffect)(() => {
30414
30472
  const loadBrandingAndTheme = async () => {
30415
30473
  if (isBrandingLoadInProgressRef.current) {
30416
30474
  debugLogger.warn("Branding loading already in progress, skipping");
@@ -30599,7 +30657,7 @@ var init_chat2 = __esm({
30599
30657
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
30600
30658
  };
30601
30659
  }, []);
30602
- (0, import_react62.useEffect)(() => {
30660
+ (0, import_react63.useEffect)(() => {
30603
30661
  if (!chatContainerEl) return;
30604
30662
  const blurInputOnTouchScroll = () => {
30605
30663
  if (document.activeElement === inputRef.current) inputRef.current?.blur();
@@ -30607,13 +30665,13 @@ var init_chat2 = __esm({
30607
30665
  chatContainerEl.addEventListener("touchmove", blurInputOnTouchScroll, { passive: true });
30608
30666
  return () => chatContainerEl.removeEventListener("touchmove", blurInputOnTouchScroll);
30609
30667
  }, [chatContainerEl]);
30610
- (0, import_react62.useEffect)(() => {
30668
+ (0, import_react63.useEffect)(() => {
30611
30669
  const handleResize = () => setIsMobile(window.innerWidth <= 768);
30612
30670
  handleResize();
30613
30671
  window.addEventListener("resize", handleResize);
30614
30672
  return () => window.removeEventListener("resize", handleResize);
30615
30673
  }, []);
30616
- (0, import_react62.useEffect)(() => {
30674
+ (0, import_react63.useEffect)(() => {
30617
30675
  const setViewportHeight = () => {
30618
30676
  document.documentElement.style.setProperty(
30619
30677
  "--vh",
@@ -30624,7 +30682,7 @@ var init_chat2 = __esm({
30624
30682
  window.addEventListener("resize", setViewportHeight);
30625
30683
  return () => window.removeEventListener("resize", setViewportHeight);
30626
30684
  }, []);
30627
- (0, import_react62.useEffect)(() => {
30685
+ (0, import_react63.useEffect)(() => {
30628
30686
  if (!chatContainerEl) return;
30629
30687
  let rafId = null;
30630
30688
  const update = () => {
@@ -30643,7 +30701,7 @@ var init_chat2 = __esm({
30643
30701
  chatContainerEl.removeEventListener(SCROLL_STATE_CHANGED_EVENT, update);
30644
30702
  };
30645
30703
  }, [chatContainerEl, getScrollState]);
30646
- (0, import_react62.useEffect)(() => {
30704
+ (0, import_react63.useEffect)(() => {
30647
30705
  if (!chatContainerEl) return;
30648
30706
  let observer = null;
30649
30707
  let rafId = null;
@@ -30678,7 +30736,7 @@ var init_chat2 = __esm({
30678
30736
  if (observer) observer.disconnect();
30679
30737
  };
30680
30738
  }, [chatContainerEl, scrollTargetEl, scrollTargetRef, getScrollState, inputHeight, history.length]);
30681
- (0, import_react62.useEffect)(() => {
30739
+ (0, import_react63.useEffect)(() => {
30682
30740
  const isTransitioning = isStreaming || streamBuffer.trim() === "";
30683
30741
  const delay = isTransitioning ? 400 : 100;
30684
30742
  const timer = setTimeout(() => {
@@ -30687,7 +30745,7 @@ var init_chat2 = __esm({
30687
30745
  }, delay);
30688
30746
  return () => clearTimeout(timer);
30689
30747
  }, [history, streamBuffer, getScrollState, isStreaming]);
30690
- (0, import_react62.useLayoutEffect)(() => {
30748
+ (0, import_react63.useLayoutEffect)(() => {
30691
30749
  const scrollState = getScrollState();
30692
30750
  const now = Date.now();
30693
30751
  if (isStreaming && scrollState.shouldAutoScroll && followStreamRef.current) {
@@ -30721,7 +30779,7 @@ var init_chat2 = __esm({
30721
30779
  return () => clearTimeout(scrollTimer);
30722
30780
  }
30723
30781
  }, [history, isStreaming, scrollToBottom, getScrollState, isMobile, chatContainerRef]);
30724
- (0, import_react62.useEffect)(() => {
30782
+ (0, import_react63.useEffect)(() => {
30725
30783
  const observer = new ResizeObserver(() => {
30726
30784
  if (inputContainerRef.current)
30727
30785
  setInputHeight(inputContainerRef.current.offsetHeight);
@@ -30732,7 +30790,7 @@ var init_chat2 = __esm({
30732
30790
  }
30733
30791
  return () => observer.disconnect();
30734
30792
  }, []);
30735
- (0, import_react62.useEffect)(() => {
30793
+ (0, import_react63.useEffect)(() => {
30736
30794
  if (!hydrated || !_hasHydrated) return;
30737
30795
  if (currentId === null) {
30738
30796
  useAIQueryStore.setState({ history: [] });
@@ -30781,7 +30839,7 @@ var init_chat2 = __esm({
30781
30839
  setResponse,
30782
30840
  setComponentStatus
30783
30841
  ]);
30784
- (0, import_react62.useEffect)(() => {
30842
+ (0, import_react63.useEffect)(() => {
30785
30843
  debugLogger.info("Chat component conversation state", {
30786
30844
  hasHydrated: _hasHydrated,
30787
30845
  conversationCount: conversations.length,
@@ -30790,7 +30848,7 @@ var init_chat2 = __esm({
30790
30848
  storeState: "main-chat"
30791
30849
  });
30792
30850
  }, [_hasHydrated, conversations, currentId]);
30793
- (0, import_react62.useEffect)(() => {
30851
+ (0, import_react63.useEffect)(() => {
30794
30852
  if (!_hasHydrated || !chatContainerEl) return;
30795
30853
  let rafId = null;
30796
30854
  const sync = () => {
@@ -30825,7 +30883,7 @@ var init_chat2 = __esm({
30825
30883
  notificationService2?.handleHttpError(error);
30826
30884
  }
30827
30885
  });
30828
- const handleStop = (0, import_react62.useCallback)(() => {
30886
+ const handleStop = (0, import_react63.useCallback)(() => {
30829
30887
  try {
30830
30888
  aiProvider.cancel();
30831
30889
  } catch (error) {
@@ -30834,7 +30892,7 @@ var init_chat2 = __esm({
30834
30892
  });
30835
30893
  }
30836
30894
  }, [aiProvider]);
30837
- const handleVoiceInterrupt = (0, import_react62.useCallback)(() => {
30895
+ const handleVoiceInterrupt = (0, import_react63.useCallback)(() => {
30838
30896
  try {
30839
30897
  ttsStop();
30840
30898
  } catch (error) {
@@ -30853,7 +30911,7 @@ var init_chat2 = __esm({
30853
30911
  handleStop();
30854
30912
  }
30855
30913
  }, [ttsStop, isStreaming, handleStop]);
30856
- const handleSend = (0, import_react62.useCallback)(
30914
+ const handleSend = (0, import_react63.useCallback)(
30857
30915
  (question, images, displayQuestion) => {
30858
30916
  const requestStartTime = trackRequestStart();
30859
30917
  const questionForDisplay = displayQuestion || question;
@@ -30963,7 +31021,7 @@ var init_chat2 = __esm({
30963
31021
  trackRequestStart
30964
31022
  ]
30965
31023
  );
30966
- const handleVoiceTranscription = (0, import_react62.useCallback)(
31024
+ const handleVoiceTranscription = (0, import_react63.useCallback)(
30967
31025
  (text) => {
30968
31026
  const cleaned = text.trim();
30969
31027
  if (!cleaned) {
@@ -30980,7 +31038,7 @@ var init_chat2 = __esm({
30980
31038
  onInterrupt: handleVoiceInterrupt,
30981
31039
  onError: (message) => notificationService2?.showError?.(message)
30982
31040
  });
30983
- (0, import_react62.useEffect)(() => {
31041
+ (0, import_react63.useEffect)(() => {
30984
31042
  const previouslyEnabled = previousVoiceModeEnabledRef.current;
30985
31043
  previousVoiceModeEnabledRef.current = isVoiceModeEnabled;
30986
31044
  if (!previouslyEnabled && isVoiceModeEnabled) {
@@ -31005,7 +31063,7 @@ var init_chat2 = __esm({
31005
31063
  }
31006
31064
  }
31007
31065
  }, [isVoiceModeEnabled, ttsStop]);
31008
- (0, import_react62.useEffect)(() => {
31066
+ (0, import_react63.useEffect)(() => {
31009
31067
  if (!isVoiceModeEnabled || !isStreaming) {
31010
31068
  return;
31011
31069
  }
@@ -31025,7 +31083,7 @@ var init_chat2 = __esm({
31025
31083
  }
31026
31084
  lastSpokenResponseRef.current = null;
31027
31085
  }, [isStreaming, isVoiceModeEnabled, ttsStop]);
31028
- (0, import_react62.useEffect)(() => {
31086
+ (0, import_react63.useEffect)(() => {
31029
31087
  if (!isVoiceModeEnabled) {
31030
31088
  lastSpokenResponseRef.current = null;
31031
31089
  return;
@@ -31066,13 +31124,13 @@ var init_chat2 = __esm({
31066
31124
  cancelled = true;
31067
31125
  };
31068
31126
  }, [history, isStreaming, isVoiceModeEnabled, isTTSAvailable, ttsSpeak]);
31069
- const handleModelChange = (0, import_react62.useCallback)(
31127
+ const handleModelChange = (0, import_react63.useCallback)(
31070
31128
  (modelId) => {
31071
31129
  setSelectedModel(modelId);
31072
31130
  },
31073
31131
  [setSelectedModel]
31074
31132
  );
31075
- const handleVoiceChange = (0, import_react62.useCallback)(async (voiceId) => {
31133
+ const handleVoiceChange = (0, import_react63.useCallback)(async (voiceId) => {
31076
31134
  ttsStop();
31077
31135
  stopTTS();
31078
31136
  setSelectedVoice(voiceId);
@@ -31105,10 +31163,10 @@ var init_chat2 = __esm({
31105
31163
  }
31106
31164
  };
31107
31165
  if (!hydrated || brandingLoading || themeLoading) {
31108
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material53.ThemeProvider, { theme: banditTheme, children: [
31109
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.CssBaseline, {}),
31110
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
31111
- import_material53.Box,
31166
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_material54.ThemeProvider, { theme: banditTheme, children: [
31167
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.CssBaseline, {}),
31168
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
31169
+ import_material54.Box,
31112
31170
  {
31113
31171
  sx: (theme) => ({
31114
31172
  minHeight: "100dvh",
@@ -31121,8 +31179,8 @@ var init_chat2 = __esm({
31121
31179
  color: theme.palette.text.primary
31122
31180
  }),
31123
31181
  children: [
31124
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.CircularProgress, { size: 32, thickness: 4 }),
31125
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Typography, { variant: "body2", color: "text.secondary", children: "Preparing your workspace..." })
31182
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.CircularProgress, { size: 32, thickness: 4 }),
31183
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Typography, { variant: "body2", color: "text.secondary", children: "Preparing your workspace..." })
31126
31184
  ]
31127
31185
  }
31128
31186
  )
@@ -31130,15 +31188,15 @@ var init_chat2 = __esm({
31130
31188
  }
31131
31189
  const userHasAccess = playgroundBypassAccess || ossMode || claims?.roles?.includes("super-user") || claims?.roles?.includes("admin");
31132
31190
  if (!userHasAccess) {
31133
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material53.ThemeProvider, { theme: banditTheme, children: [
31134
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.CssBaseline, {}),
31135
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(UnderReviewView, {})
31191
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_material54.ThemeProvider, { theme: banditTheme, children: [
31192
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.CssBaseline, {}),
31193
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(UnderReviewView, {})
31136
31194
  ] });
31137
31195
  }
31138
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_material53.ThemeProvider, { theme: banditTheme, children: [
31139
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.CssBaseline, {}),
31140
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
31141
- import_material53.Box,
31196
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_material54.ThemeProvider, { theme: banditTheme, children: [
31197
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.CssBaseline, {}),
31198
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
31199
+ import_material54.Box,
31142
31200
  {
31143
31201
  sx: (theme) => ({
31144
31202
  display: "flex",
@@ -31167,7 +31225,7 @@ var init_chat2 = __esm({
31167
31225
  transition: "left 0.3s ease-in-out, width 0.3s ease-in-out, transform 0.3s ease-in-out, border-radius 0.3s ease-in-out"
31168
31226
  }),
31169
31227
  children: [
31170
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31228
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31171
31229
  chat_app_bar_default,
31172
31230
  {
31173
31231
  availableModels,
@@ -31181,9 +31239,9 @@ var init_chat2 = __esm({
31181
31239
  onMobileConversationsOpenChange: setMobileConversationsOpen
31182
31240
  }
31183
31241
  ),
31184
- isTemporaryChat && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
31185
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31186
- import_material53.Box,
31242
+ isTemporaryChat && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
31243
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31244
+ import_material54.Box,
31187
31245
  {
31188
31246
  sx: (theme) => ({
31189
31247
  position: "absolute",
@@ -31195,8 +31253,8 @@ var init_chat2 = __esm({
31195
31253
  })
31196
31254
  }
31197
31255
  ),
31198
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
31199
- import_material53.Box,
31256
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
31257
+ import_material54.Box,
31200
31258
  {
31201
31259
  sx: (theme) => ({
31202
31260
  position: "absolute",
@@ -31220,10 +31278,10 @@ var init_chat2 = __esm({
31220
31278
  whiteSpace: "nowrap"
31221
31279
  }),
31222
31280
  children: [
31223
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Box, { component: "span", "aria-hidden": true, sx: { fontSize: "0.9rem", lineHeight: 1 }, children: "\u{1F47B}" }),
31281
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { component: "span", "aria-hidden": true, sx: { fontSize: "0.9rem", lineHeight: 1 }, children: "\u{1F47B}" }),
31224
31282
  "Temporary chat",
31225
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31226
- import_material53.Box,
31283
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31284
+ import_material54.Box,
31227
31285
  {
31228
31286
  component: "button",
31229
31287
  type: "button",
@@ -31257,8 +31315,8 @@ var init_chat2 = __esm({
31257
31315
  }
31258
31316
  )
31259
31317
  ] }),
31260
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31261
- import_material53.Box,
31318
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31319
+ import_material54.Box,
31262
31320
  {
31263
31321
  ref: chatContainerRef,
31264
31322
  sx: {
@@ -31278,8 +31336,8 @@ var init_chat2 = __esm({
31278
31336
  msOverflowStyle: "none",
31279
31337
  "&::-webkit-scrollbar": { display: "none" }
31280
31338
  },
31281
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
31282
- import_material53.Box,
31339
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
31340
+ import_material54.Box,
31283
31341
  {
31284
31342
  sx: {
31285
31343
  width: "100%",
@@ -31292,8 +31350,8 @@ var init_chat2 = __esm({
31292
31350
  logoShouldRender && !brandingLoading && (() => {
31293
31351
  const headerMode = branding?.headerMode ?? "logo";
31294
31352
  if (headerMode === "minimal") {
31295
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31296
- import_material53.Box,
31353
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31354
+ import_material54.Box,
31297
31355
  {
31298
31356
  sx: (theme) => ({
31299
31357
  textAlign: "center",
@@ -31304,13 +31362,13 @@ var init_chat2 = __esm({
31304
31362
  transition: "opacity 0.5s ease",
31305
31363
  color: theme.palette.text.primary
31306
31364
  }),
31307
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Typography, { sx: { fontWeight: 500, fontSize: { xs: "1.5rem", md: "1.9rem" }, lineHeight: 1.2 }, children: "What can I help with?" })
31365
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Typography, { sx: { fontWeight: 500, fontSize: { xs: "1.5rem", md: "1.9rem" }, lineHeight: 1.2 }, children: "What can I help with?" })
31308
31366
  }
31309
31367
  );
31310
31368
  }
31311
31369
  if (headerMode === "text") {
31312
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31313
- import_material53.Box,
31370
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31371
+ import_material54.Box,
31314
31372
  {
31315
31373
  sx: (theme) => ({
31316
31374
  textAlign: "center",
@@ -31321,14 +31379,14 @@ var init_chat2 = __esm({
31321
31379
  transition: "opacity 0.5s ease",
31322
31380
  color: theme.palette.text.primary
31323
31381
  }),
31324
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Typography, { sx: { fontWeight: 600, fontSize: { xs: "1.6rem", md: "2.1rem" }, lineHeight: 1.2 }, children: branding?.brandingText?.trim() || "Bandit AI" })
31382
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Typography, { sx: { fontWeight: 600, fontSize: { xs: "1.6rem", md: "2.1rem" }, lineHeight: 1.2 }, children: branding?.brandingText?.trim() || "Bandit AI" })
31325
31383
  }
31326
31384
  );
31327
31385
  }
31328
- return branding?.logoBase64 ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(custom_logo_default, { visible: logoVisible, atTop: true }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(bandit_chat_logo_default, { visible: logoVisible, atTop: true });
31386
+ return branding?.logoBase64 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(custom_logo_default, { visible: logoVisible, atTop: true }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(bandit_chat_logo_default, { visible: logoVisible, atTop: true });
31329
31387
  })(),
31330
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31331
- import_material53.Box,
31388
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31389
+ import_material54.Box,
31332
31390
  {
31333
31391
  sx: {
31334
31392
  margin: "0 auto",
@@ -31337,7 +31395,7 @@ var init_chat2 = __esm({
31337
31395
  flexShrink: 0,
31338
31396
  px: isMobile ? 0 : 0
31339
31397
  },
31340
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31398
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31341
31399
  chat_messages_default,
31342
31400
  {
31343
31401
  isStreaming,
@@ -31361,7 +31419,7 @@ var init_chat2 = __esm({
31361
31419
  )
31362
31420
  }
31363
31421
  ),
31364
- showScrollToBottom && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31422
+ showScrollToBottom && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31365
31423
  chat_scroll_to_bottom_button_default,
31366
31424
  {
31367
31425
  inputHeight,
@@ -31370,8 +31428,8 @@ var init_chat2 = __esm({
31370
31428
  onClick: handleScrollToBottomClick
31371
31429
  }
31372
31430
  ),
31373
- history.length === 0 && componentStatus !== "Loading" && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31374
- import_material53.Box,
31431
+ history.length === 0 && componentStatus !== "Loading" && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31432
+ import_material54.Box,
31375
31433
  {
31376
31434
  sx: (theme) => ({
31377
31435
  position: "absolute",
@@ -31389,8 +31447,8 @@ var init_chat2 = __esm({
31389
31447
  })
31390
31448
  }
31391
31449
  ),
31392
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
31393
- import_material53.Box,
31450
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
31451
+ import_material54.Box,
31394
31452
  {
31395
31453
  sx: {
31396
31454
  display: "flex",
@@ -31401,11 +31459,11 @@ var init_chat2 = __esm({
31401
31459
  maxWidth: "768px"
31402
31460
  },
31403
31461
  children: [
31404
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Box, { sx: { flex: "1 1 auto" } }),
31405
- history.length === 0 && componentStatus !== "Loading" && !pendingMessage && preferences.chatSuggestionsEnabled && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_material53.Box, { sx: { marginBottom: "20px" }, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(QuerySuggestionPicker, { onSend: handleSend, inputHeight }) }),
31406
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(rate_limit_prompt_default, {}),
31407
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ask_user_card_default, {}),
31408
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31462
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { sx: { flex: "1 1 auto" } }),
31463
+ history.length === 0 && componentStatus !== "Loading" && !pendingMessage && preferences.chatSuggestionsEnabled && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { sx: { marginBottom: "20px" }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(QuerySuggestionPicker, { onSend: handleSend, inputHeight }) }),
31464
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(rate_limit_prompt_default, {}),
31465
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ask_user_card_default, {}),
31466
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31409
31467
  chat_input_default,
31410
31468
  {
31411
31469
  inputValue,
@@ -31432,24 +31490,12 @@ var init_chat2 = __esm({
31432
31490
  ]
31433
31491
  }
31434
31492
  ),
31435
- preferences.feedbackEnabled && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
31436
- FeedbackButton,
31437
- {
31438
- fullScreen: false,
31439
- zIndex: 1300,
31440
- feedbackEmail: packageSettings?.feedbackEmail,
31441
- absolute: true,
31442
- position: {
31443
- bottom: 20,
31444
- right: 20
31445
- }
31446
- }
31447
- ),
31448
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ConnectionStatus, { position: "top", showWhenGood: false })
31493
+ preferences.feedbackEnabled && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(FeedbackPulse_default, { isMobile, feedbackEmail: packageSettings?.feedbackEmail }),
31494
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ConnectionStatus, { position: "top", showWhenGood: false })
31449
31495
  ]
31450
31496
  }
31451
31497
  ),
31452
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(canvas_panel_default, { isMobile })
31498
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(canvas_panel_default, { isMobile })
31453
31499
  ] });
31454
31500
  };
31455
31501
  Chat = () => {
@@ -31475,9 +31521,9 @@ var init_chat2 = __esm({
31475
31521
  });
31476
31522
  if (!allowUnauthenticated && !bypassAuth && !authenticationService.isAuthenticated()) {
31477
31523
  debugLogger.debug("User is not authenticated, redirecting to login");
31478
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
31524
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
31479
31525
  }
31480
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ChatContent, {});
31526
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ChatContent, {});
31481
31527
  };
31482
31528
  chat_default = Chat;
31483
31529
  }
@@ -31489,12 +31535,12 @@ __export(management_exports, {
31489
31535
  default: () => management_default
31490
31536
  });
31491
31537
  module.exports = __toCommonJS(management_exports);
31492
- var import_react63 = require("react");
31538
+ var import_react64 = require("react");
31493
31539
  var import_useMediaQuery2 = __toESM(require("@mui/material/useMediaQuery"));
31494
- var import_styles34 = require("@mui/material/styles");
31540
+ var import_styles35 = require("@mui/material/styles");
31495
31541
  init_useKnowledgeStore();
31496
31542
  init_indexedDBService();
31497
- var import_material54 = require("@mui/material");
31543
+ var import_material55 = require("@mui/material");
31498
31544
  var import_react_router_dom6 = require("react-router-dom");
31499
31545
 
31500
31546
  // src/modals/chat-modal/chat-modal.tsx
@@ -33415,8 +33461,140 @@ var GenericLoader = ({
33415
33461
  };
33416
33462
  var generic_loader_default = GenericLoader;
33417
33463
 
33418
- // src/modals/chat-modal/chat-modal.tsx
33419
- init_FeedbackButton();
33464
+ // src/components/feedback/FeedbackButton.tsx
33465
+ var import_react18 = require("react");
33466
+ var import_material14 = require("@mui/material");
33467
+ var import_lucide_react4 = require("lucide-react");
33468
+
33469
+ // src/components/feedback/index.tsx
33470
+ init_FeedbackModal();
33471
+
33472
+ // src/components/feedback/FeedbackButton.tsx
33473
+ var import_jsx_runtime14 = require("react/jsx-runtime");
33474
+ var FeedbackButton = ({
33475
+ fullScreen = false,
33476
+ className,
33477
+ zIndex = 1400,
33478
+ feedbackEmail,
33479
+ inline = false,
33480
+ buttonText = "Send Feedback",
33481
+ size = "small",
33482
+ position,
33483
+ absolute = false
33484
+ }) => {
33485
+ const theme = (0, import_material14.useTheme)();
33486
+ const [open, setOpen] = (0, import_react18.useState)(false);
33487
+ const handleOpen = () => setOpen(true);
33488
+ const handleClose = () => setOpen(false);
33489
+ if (inline) {
33490
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
33491
+ buttonText ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33492
+ import_material14.Button,
33493
+ {
33494
+ variant: "outlined",
33495
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {}),
33496
+ onClick: handleOpen,
33497
+ className,
33498
+ size,
33499
+ sx: {
33500
+ borderRadius: 2,
33501
+ textTransform: "none",
33502
+ "&:hover": {
33503
+ transform: "translateY(-1px)",
33504
+ boxShadow: theme.shadows[4]
33505
+ }
33506
+ },
33507
+ children: buttonText
33508
+ }
33509
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material14.Tooltip, { title: "Send Feedback", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33510
+ import_material14.IconButton,
33511
+ {
33512
+ onClick: handleOpen,
33513
+ className,
33514
+ size,
33515
+ sx: {
33516
+ color: theme.palette.primary.main,
33517
+ borderRadius: 2,
33518
+ transition: "all 0.2s ease",
33519
+ "&:hover": {
33520
+ bgcolor: theme.palette.primary.main + "15",
33521
+ transform: "translateY(-1px)"
33522
+ }
33523
+ },
33524
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {})
33525
+ }
33526
+ ) }),
33527
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33528
+ FeedbackModal,
33529
+ {
33530
+ open,
33531
+ onClose: handleClose,
33532
+ feedbackEmail
33533
+ }
33534
+ )
33535
+ ] });
33536
+ }
33537
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
33538
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material14.Zoom, { in: true, timeout: 300, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33539
+ import_material14.Tooltip,
33540
+ {
33541
+ title: "Send Feedback",
33542
+ placement: "left",
33543
+ arrow: true,
33544
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33545
+ import_material14.Fab,
33546
+ {
33547
+ size,
33548
+ onClick: handleOpen,
33549
+ className,
33550
+ sx: {
33551
+ position: absolute ? "absolute" : "relative",
33552
+ ...absolute && {
33553
+ bottom: position?.bottom ?? (fullScreen ? 16 : 20),
33554
+ right: position?.right ?? 16,
33555
+ top: position?.top,
33556
+ left: position?.left
33557
+ },
33558
+ zIndex,
33559
+ bgcolor: theme.palette.primary.main,
33560
+ color: theme.palette.primary.contrastText,
33561
+ boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.15)",
33562
+ border: `1px solid ${theme.palette.divider}`,
33563
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
33564
+ "&:hover": {
33565
+ bgcolor: theme.palette.primary.dark,
33566
+ transform: "scale(1.05) translateY(-2px)",
33567
+ boxShadow: theme.palette.mode === "dark" ? "0 12px 40px rgba(0,0,0,0.5)" : "0 12px 40px rgba(0,0,0,0.2)"
33568
+ },
33569
+ "&:active": {
33570
+ transform: "scale(0.98) translateY(0px)"
33571
+ },
33572
+ // Subtle pulsing animation
33573
+ animation: "feedbackPulse 3s ease-in-out infinite",
33574
+ "@keyframes feedbackPulse": {
33575
+ "0%, 100%": {
33576
+ boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.15)"
33577
+ },
33578
+ "50%": {
33579
+ boxShadow: theme.palette.mode === "dark" ? `0 8px 32px ${theme.palette.primary.main}40` : `0 8px 32px ${theme.palette.primary.main}30`
33580
+ }
33581
+ }
33582
+ },
33583
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react4.MessageCircle, {})
33584
+ }
33585
+ )
33586
+ }
33587
+ ) }),
33588
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
33589
+ FeedbackModal,
33590
+ {
33591
+ open,
33592
+ onClose: handleClose,
33593
+ feedbackEmail
33594
+ }
33595
+ )
33596
+ ] });
33597
+ };
33420
33598
 
33421
33599
  // src/hooks/useAiChat.ts
33422
33600
  var import_react19 = require("react");
@@ -43993,7 +44171,7 @@ init_authenticationStore();
43993
44171
  init_useNotificationService();
43994
44172
  init_useFeatures();
43995
44173
  init_lucide_icons();
43996
- var import_jsx_runtime53 = require("react/jsx-runtime");
44174
+ var import_jsx_runtime54 = require("react/jsx-runtime");
43997
44175
  var preloadChatPage = () => Promise.resolve().then(() => (init_chat2(), chat_exports));
43998
44176
  var buildCapabilitiesUrl = (gatewayApiUrl) => {
43999
44177
  const trimmed = gatewayApiUrl.replace(/\/$/, "");
@@ -44006,7 +44184,7 @@ var Management = () => {
44006
44184
  const navigate = (0, import_react_router_dom6.useNavigate)();
44007
44185
  const notificationService2 = useNotificationService();
44008
44186
  const isMobile = (0, import_useMediaQuery2.default)("(max-width:900px)");
44009
- const [sidebarOpen, setSidebarOpen] = (0, import_react63.useState)(false);
44187
+ const [sidebarOpen, setSidebarOpen] = (0, import_react64.useState)(false);
44010
44188
  const getOptimalFabLogo = async () => {
44011
44189
  const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
44012
44190
  try {
@@ -44046,17 +44224,17 @@ var Management = () => {
44046
44224
  hasTransparentLogo,
44047
44225
  setHasTransparentLogo
44048
44226
  } = useModelStore();
44049
- const [modalOpen, setModalOpen] = (0, import_react63.useState)(false);
44227
+ const [modalOpen, setModalOpen] = (0, import_react64.useState)(false);
44050
44228
  const banditHead5 = "https://cdn.burtson.ai/images/bandit-head.png";
44051
- const [fabLogo, setFabLogo] = (0, import_react63.useState)(banditHead5);
44052
- const [tabIndex, setTabIndex] = (0, import_react63.useState)(4);
44053
- const [logoFile, setLogoFile] = (0, import_react63.useState)(null);
44054
- const [logoBase64, setLogoBase64] = (0, import_react63.useState)(null);
44055
- const [brandingText, setBrandingText] = (0, import_react63.useState)("");
44056
- const [headerMode, setHeaderMode] = (0, import_react63.useState)("logo");
44057
- const [theme, setTheme] = (0, import_react63.useState)("bandit-dark");
44058
- const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react63.useState)(null);
44059
- const [presetAvatar, setPresetAvatar] = (0, import_react63.useState)(null);
44229
+ const [fabLogo, setFabLogo] = (0, import_react64.useState)(banditHead5);
44230
+ const [tabIndex, setTabIndex] = (0, import_react64.useState)(4);
44231
+ const [logoFile, setLogoFile] = (0, import_react64.useState)(null);
44232
+ const [logoBase64, setLogoBase64] = (0, import_react64.useState)(null);
44233
+ const [brandingText, setBrandingText] = (0, import_react64.useState)("");
44234
+ const [headerMode, setHeaderMode] = (0, import_react64.useState)("logo");
44235
+ const [theme, setTheme] = (0, import_react64.useState)("bandit-dark");
44236
+ const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react64.useState)(null);
44237
+ const [presetAvatar, setPresetAvatar] = (0, import_react64.useState)(null);
44060
44238
  const showSnackbarMessage = (message, severity = "success") => {
44061
44239
  if (severity === "success") {
44062
44240
  notificationService2?.showSuccess(message);
@@ -44064,9 +44242,9 @@ var Management = () => {
44064
44242
  notificationService2?.showError(message);
44065
44243
  }
44066
44244
  };
44067
- const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react63.useState)(false);
44068
- const [brandingLoaded, setBrandingLoaded] = (0, import_react63.useState)(false);
44069
- const [isLoadingBranding, setIsLoadingBranding] = (0, import_react63.useState)(false);
44245
+ const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react64.useState)(false);
44246
+ const [brandingLoaded, setBrandingLoaded] = (0, import_react64.useState)(false);
44247
+ const [isLoadingBranding, setIsLoadingBranding] = (0, import_react64.useState)(false);
44070
44248
  const { initModels } = useModelStore();
44071
44249
  const { settings: packageSettings } = usePackageSettingsStore();
44072
44250
  const authToken = useAuthenticationStore((state) => state.token);
@@ -44074,8 +44252,8 @@ var Management = () => {
44074
44252
  const { hasAdminDashboard, hasLimitedAdminDashboard, getCurrentTier, hasAdvancedSearch } = useFeatures();
44075
44253
  const { showAdminPanel, showLimitedAdminPanel } = useFeatureVisibility();
44076
44254
  const { provider: currentProvider, config: currentProviderConfig } = useAIProviderStore();
44077
- const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react63.useState)(false);
44078
- const [localSelectedModel, setLocalSelectedModel] = (0, import_react63.useState)({
44255
+ const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react64.useState)(false);
44256
+ const [localSelectedModel, setLocalSelectedModel] = (0, import_react64.useState)({
44079
44257
  name: "",
44080
44258
  tagline: "",
44081
44259
  systemPrompt: "",
@@ -44088,7 +44266,7 @@ var Management = () => {
44088
44266
  loadDocuments,
44089
44267
  clearAllDocuments
44090
44268
  } = useKnowledgeStore2();
44091
- (0, import_react63.useEffect)(() => {
44269
+ (0, import_react64.useEffect)(() => {
44092
44270
  if (selectedModel) {
44093
44271
  const selected = availableModels.find((m) => m.name === selectedModel);
44094
44272
  if (selected) {
@@ -44112,7 +44290,7 @@ var Management = () => {
44112
44290
  }
44113
44291
  }
44114
44292
  }, [selectedModel, availableModels]);
44115
- const loadBrandingConfig = (0, import_react63.useCallback)(async () => {
44293
+ const loadBrandingConfig = (0, import_react64.useCallback)(async () => {
44116
44294
  if (isLoadingBranding || brandingLoaded) {
44117
44295
  debugLogger.warn("Branding loading already in progress or completed, skipping");
44118
44296
  return;
@@ -44229,15 +44407,15 @@ var Management = () => {
44229
44407
  setTagline,
44230
44408
  setTheme
44231
44409
  ]);
44232
- (0, import_react63.useEffect)(() => {
44410
+ (0, import_react64.useEffect)(() => {
44233
44411
  void loadBrandingConfig();
44234
44412
  }, [loadBrandingConfig]);
44235
44413
  const handleOpenModal = () => setModalOpen(true);
44236
44414
  const handleCloseModal = () => setModalOpen(false);
44237
- (0, import_react63.useEffect)(() => {
44415
+ (0, import_react64.useEffect)(() => {
44238
44416
  getOptimalFabLogo().then(setFabLogo);
44239
44417
  }, []);
44240
- (0, import_react63.useEffect)(() => {
44418
+ (0, import_react64.useEffect)(() => {
44241
44419
  if (logoBase64) {
44242
44420
  setFabLogo(logoBase64);
44243
44421
  } else {
@@ -44690,7 +44868,7 @@ var Management = () => {
44690
44868
  reader.readAsText(file);
44691
44869
  }
44692
44870
  };
44693
- (0, import_react63.useEffect)(() => {
44871
+ (0, import_react64.useEffect)(() => {
44694
44872
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
44695
44873
  setLocalSelectedModel((prev) => ({
44696
44874
  ...prev,
@@ -44698,10 +44876,10 @@ var Management = () => {
44698
44876
  }));
44699
44877
  }
44700
44878
  }, [availableModels, localSelectedModel.selectedModel]);
44701
- (0, import_react63.useEffect)(() => {
44879
+ (0, import_react64.useEffect)(() => {
44702
44880
  loadDocuments();
44703
44881
  }, [loadDocuments]);
44704
- (0, import_react63.useEffect)(() => {
44882
+ (0, import_react64.useEffect)(() => {
44705
44883
  const gatewayApiUrl = packageSettings?.gatewayApiUrl;
44706
44884
  if (!gatewayApiUrl || gatewayApiUrl.toLowerCase().startsWith("playground://")) {
44707
44885
  setSeedPacksEnabled(false);
@@ -44744,9 +44922,9 @@ var Management = () => {
44744
44922
  isActive = false;
44745
44923
  };
44746
44924
  }, [packageSettings?.gatewayApiUrl, authToken]);
44747
- const currentTheme = (0, import_react63.useMemo)(() => {
44925
+ const currentTheme = (0, import_react64.useMemo)(() => {
44748
44926
  const baseTheme = predefinedThemes[theme] || banditDarkTheme;
44749
- return (0, import_styles34.createTheme)(baseTheme, {
44927
+ return (0, import_styles35.createTheme)(baseTheme, {
44750
44928
  // Management-scoped density: condenses every settings tab at once. This
44751
44929
  // theme only wraps the admin console, so the chat UI is unaffected.
44752
44930
  typography: {
@@ -44801,43 +44979,43 @@ var Management = () => {
44801
44979
  const allNavTabs = [
44802
44980
  {
44803
44981
  label: "Personalities",
44804
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(FaceRetouchingNaturalIcon, {}),
44982
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(FaceRetouchingNaturalIcon, {}),
44805
44983
  requiresFeature: "limitedAdminDashboard",
44806
44984
  requiresAdmin: true
44807
44985
  },
44808
44986
  {
44809
44987
  label: "Branding",
44810
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(BrushIcon, {}),
44988
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(BrushIcon, {}),
44811
44989
  requiresFeature: "limitedAdminDashboard",
44812
44990
  requiresAdmin: true
44813
44991
  },
44814
44992
  {
44815
44993
  label: "Knowledge",
44816
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(MenuBookIcon, {}),
44994
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(MenuBookIcon, {}),
44817
44995
  requiresFeature: "limitedAdminDashboard",
44818
44996
  requiresAdmin: true
44819
44997
  },
44820
44998
  {
44821
44999
  label: "Storage",
44822
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StorageIcon, {}),
45000
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(StorageIcon, {}),
44823
45001
  requiresFeature: "limitedAdminDashboard",
44824
45002
  requiresAdmin: true
44825
45003
  },
44826
45004
  {
44827
45005
  label: "Preferences",
44828
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TuneIcon, {}),
45006
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(TuneIcon, {}),
44829
45007
  requiresFeature: "limitedAdminDashboard",
44830
45008
  requiresAdmin: false
44831
45009
  },
44832
45010
  {
44833
45011
  label: "Provider",
44834
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CloudIcon, {}),
45012
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CloudIcon, {}),
44835
45013
  requiresFeature: "advancedSearch",
44836
45014
  requiresAdmin: true
44837
45015
  },
44838
45016
  {
44839
45017
  label: "Tools",
44840
- icon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(BuildIcon, {}),
45018
+ icon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(BuildIcon, {}),
44841
45019
  requiresFeature: "advancedSearch",
44842
45020
  requiresAdmin: true
44843
45021
  }
@@ -44865,7 +45043,7 @@ var Management = () => {
44865
45043
  });
44866
45044
  const preferredDefaultTabIndex = navTabs.findIndex((tab) => tab.label === "Preferences");
44867
45045
  const defaultTabIndex = preferredDefaultTabIndex >= 0 ? preferredDefaultTabIndex : 0;
44868
- (0, import_react63.useEffect)(() => {
45046
+ (0, import_react64.useEffect)(() => {
44869
45047
  setTabIndex((current) => {
44870
45048
  if (current < 0 || current >= navTabs.length) {
44871
45049
  return defaultTabIndex;
@@ -44875,8 +45053,8 @@ var Management = () => {
44875
45053
  }, [navTabs.length, defaultTabIndex]);
44876
45054
  const mobileQuickTabs = navTabs.slice(0, 5);
44877
45055
  const hasMobileOverflowTabs = navTabs.length > mobileQuickTabs.length;
44878
- const navigationContent = /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
44879
- import_material54.Box,
45056
+ const navigationContent = /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45057
+ import_material55.Box,
44880
45058
  {
44881
45059
  sx: {
44882
45060
  display: "flex",
@@ -44886,29 +45064,29 @@ var Management = () => {
44886
45064
  bgcolor: "inherit"
44887
45065
  },
44888
45066
  children: [
44889
- isMobile && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
44890
- import_material54.Box,
45067
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45068
+ import_material55.Box,
44891
45069
  {
44892
45070
  sx: {
44893
45071
  height: 6,
44894
45072
  width: 56,
44895
45073
  borderRadius: 999,
44896
- bgcolor: (theme2) => (0, import_styles34.alpha)(theme2.palette.text.primary, 0.18),
45074
+ bgcolor: (theme2) => (0, import_styles35.alpha)(theme2.palette.text.primary, 0.18),
44897
45075
  alignSelf: "center",
44898
45076
  mt: 1.25,
44899
45077
  mb: 0.75
44900
45078
  }
44901
45079
  }
44902
45080
  ),
44903
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { sx: { p: isMobile ? 2.5 : 3, pb: isMobile ? 1.5 : 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
44904
- import_material54.Button,
45081
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.Box, { sx: { p: isMobile ? 2.5 : 3, pb: isMobile ? 1.5 : 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45082
+ import_material55.Button,
44905
45083
  {
44906
45084
  onClick: () => {
44907
45085
  if (isMobile) setSidebarOpen(false);
44908
45086
  navigate("/chat");
44909
45087
  },
44910
45088
  onMouseEnter: preloadChatPage,
44911
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ChevronLeftIcon, { sx: { fontSize: 20 } }),
45089
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ChevronLeftIcon, { sx: { fontSize: 20 } }),
44912
45090
  fullWidth: true,
44913
45091
  variant: "outlined",
44914
45092
  sx: {
@@ -44935,9 +45113,9 @@ var Management = () => {
44935
45113
  children: "Back to Chat"
44936
45114
  }
44937
45115
  ) }),
44938
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Divider, { sx: { mx: isMobile ? 2 : 3, mb: 2, opacity: 0.6 } }),
44939
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { sx: { flex: 1, px: isMobile ? 1.5 : 2, pb: 3, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.List, { sx: { px: 0, py: 0 }, children: navTabs.map((tab, idx) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
44940
- import_material54.ListItemButton,
45116
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.Divider, { sx: { mx: isMobile ? 2 : 3, mb: 2, opacity: 0.6 } }),
45117
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.Box, { sx: { flex: 1, px: isMobile ? 1.5 : 2, pb: 3, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.List, { sx: { px: 0, py: 0 }, children: navTabs.map((tab, idx) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45118
+ import_material55.ListItemButton,
44941
45119
  {
44942
45120
  selected: tabIndex === idx,
44943
45121
  onClick: () => {
@@ -44977,9 +45155,9 @@ var Management = () => {
44977
45155
  "& .MuiListItemIcon-root svg": { width: 17, height: 17 }
44978
45156
  },
44979
45157
  children: [
44980
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.ListItemIcon, { children: tab.icon }),
44981
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
44982
- import_material54.ListItemText,
45158
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.ListItemIcon, { children: tab.icon }),
45159
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45160
+ import_material55.ListItemText,
44983
45161
  {
44984
45162
  primary: tab.label,
44985
45163
  primaryTypographyProps: {
@@ -44996,10 +45174,10 @@ var Management = () => {
44996
45174
  }
44997
45175
  );
44998
45176
  if (!brandingLoaded) return null;
44999
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_material54.ThemeProvider, { theme: currentTheme, children: [
45000
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.CssBaseline, {}),
45001
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
45002
- import_material54.Box,
45177
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_material55.ThemeProvider, { theme: currentTheme, children: [
45178
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.CssBaseline, {}),
45179
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45180
+ import_material55.Box,
45003
45181
  {
45004
45182
  display: "flex",
45005
45183
  height: "100vh",
@@ -45011,8 +45189,8 @@ var Management = () => {
45011
45189
  position: "relative"
45012
45190
  },
45013
45191
  children: [
45014
- isMobile && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
45015
- import_material54.Box,
45192
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45193
+ import_material55.Box,
45016
45194
  {
45017
45195
  sx: {
45018
45196
  width: "100%",
@@ -45031,8 +45209,8 @@ var Management = () => {
45031
45209
  boxShadow: "0 2px 8px rgba(0,0,0,0.1)"
45032
45210
  },
45033
45211
  children: [
45034
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45035
- import_material54.Button,
45212
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45213
+ import_material55.Button,
45036
45214
  {
45037
45215
  onClick: () => navigate("/chat"),
45038
45216
  onMouseEnter: preloadChatPage,
@@ -45045,11 +45223,11 @@ var Management = () => {
45045
45223
  color: "primary.main",
45046
45224
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.04)"
45047
45225
  },
45048
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ChevronLeftIcon, { sx: { fontSize: 22 } })
45226
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ChevronLeftIcon, { sx: { fontSize: 22 } })
45049
45227
  }
45050
45228
  ),
45051
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45052
- import_material54.Button,
45229
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45230
+ import_material55.Button,
45053
45231
  {
45054
45232
  onClick: () => setSidebarOpen((o) => !o),
45055
45233
  sx: {
@@ -45070,7 +45248,7 @@ var Management = () => {
45070
45248
  transform: sidebarOpen ? "rotate(90deg) scale(0.95)" : "scale(0.95)"
45071
45249
  }
45072
45250
  },
45073
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45251
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45074
45252
  "path",
45075
45253
  {
45076
45254
  d: sidebarOpen ? "M18 6L6 18M6 6L18 18" : "M3 12H21M3 6H21M3 18H21",
@@ -45082,8 +45260,8 @@ var Management = () => {
45082
45260
  ) })
45083
45261
  }
45084
45262
  ),
45085
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45086
- import_material54.Typography,
45263
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45264
+ import_material55.Typography,
45087
45265
  {
45088
45266
  variant: "h6",
45089
45267
  sx: {
@@ -45095,14 +45273,14 @@ var Management = () => {
45095
45273
  children: "Management"
45096
45274
  }
45097
45275
  ),
45098
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { sx: {
45276
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_material55.Box, { sx: {
45099
45277
  px: 2,
45100
45278
  py: 0.5,
45101
45279
  borderRadius: 2,
45102
45280
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(25,118,210,0.12)" : "rgba(25,118,210,0.08)",
45103
45281
  border: (theme2) => `1px solid ${theme2.palette.primary.main}20`
45104
- }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45105
- import_material54.Typography,
45282
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45283
+ import_material55.Typography,
45106
45284
  {
45107
45285
  variant: "caption",
45108
45286
  sx: {
@@ -45116,8 +45294,8 @@ var Management = () => {
45116
45294
  ]
45117
45295
  }
45118
45296
  ),
45119
- isMobile && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
45120
- import_material54.Box,
45297
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45298
+ import_material55.Box,
45121
45299
  {
45122
45300
  sx: {
45123
45301
  width: "100%",
@@ -45134,8 +45312,8 @@ var Management = () => {
45134
45312
  mobileQuickTabs.map((tab) => {
45135
45313
  const quickTabIndex = navTabs.findIndex((navTab) => navTab.label === tab.label);
45136
45314
  const selected = tabIndex === quickTabIndex;
45137
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45138
- import_material54.Button,
45315
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45316
+ import_material55.Button,
45139
45317
  {
45140
45318
  size: "small",
45141
45319
  onClick: () => setTabIndex(quickTabIndex),
@@ -45150,7 +45328,7 @@ var Management = () => {
45150
45328
  fontWeight: selected ? 700 : 600,
45151
45329
  bgcolor: selected ? (theme2) => theme2.palette.mode === "dark" ? "rgba(25,118,210,0.2)" : "rgba(25,118,210,0.12)" : "transparent",
45152
45330
  color: selected ? "primary.main" : "text.secondary",
45153
- border: (theme2) => selected ? `1px solid ${theme2.palette.primary.main}66` : `1px solid ${(0, import_styles34.alpha)(theme2.palette.divider, 0.45)}`,
45331
+ border: (theme2) => selected ? `1px solid ${theme2.palette.primary.main}66` : `1px solid ${(0, import_styles35.alpha)(theme2.palette.divider, 0.45)}`,
45154
45332
  "&:hover": {
45155
45333
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(25,118,210,0.16)" : "rgba(25,118,210,0.1)"
45156
45334
  }
@@ -45160,8 +45338,8 @@ var Management = () => {
45160
45338
  tab.label
45161
45339
  );
45162
45340
  }),
45163
- hasMobileOverflowTabs && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45164
- import_material54.Button,
45341
+ hasMobileOverflowTabs && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45342
+ import_material55.Button,
45165
45343
  {
45166
45344
  size: "small",
45167
45345
  onClick: () => setSidebarOpen(true),
@@ -45175,7 +45353,7 @@ var Management = () => {
45175
45353
  fontSize: "0.78rem",
45176
45354
  fontWeight: 600,
45177
45355
  color: "text.secondary",
45178
- border: (theme2) => `1px dashed ${(0, import_styles34.alpha)(theme2.palette.divider, 0.6)}`
45356
+ border: (theme2) => `1px dashed ${(0, import_styles35.alpha)(theme2.palette.divider, 0.6)}`
45179
45357
  },
45180
45358
  children: "More"
45181
45359
  }
@@ -45183,8 +45361,8 @@ var Management = () => {
45183
45361
  ]
45184
45362
  }
45185
45363
  ),
45186
- isMobile ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45187
- import_material54.SwipeableDrawer,
45364
+ isMobile ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45365
+ import_material55.SwipeableDrawer,
45188
45366
  {
45189
45367
  anchor: "bottom",
45190
45368
  open: sidebarOpen,
@@ -45204,8 +45382,8 @@ var Management = () => {
45204
45382
  },
45205
45383
  children: navigationContent
45206
45384
  }
45207
- ) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45208
- import_material54.Box,
45385
+ ) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45386
+ import_material55.Box,
45209
45387
  {
45210
45388
  sx: {
45211
45389
  width: 240,
@@ -45228,8 +45406,8 @@ var Management = () => {
45228
45406
  children: navigationContent
45229
45407
  }
45230
45408
  ),
45231
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
45232
- import_material54.Box,
45409
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
45410
+ import_material55.Box,
45233
45411
  {
45234
45412
  sx: {
45235
45413
  flex: 1,
@@ -45248,7 +45426,7 @@ var Management = () => {
45248
45426
  transition: "margin-left 0.2s"
45249
45427
  },
45250
45428
  children: [
45251
- navTabs[tabIndex]?.label === "Personalities" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45429
+ navTabs[tabIndex]?.label === "Personalities" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45252
45430
  PersonalitiesTab_default,
45253
45431
  {
45254
45432
  availableModels,
@@ -45267,7 +45445,7 @@ var Management = () => {
45267
45445
  showSnackbar: showSnackbarMessage
45268
45446
  }
45269
45447
  ),
45270
- navTabs[tabIndex]?.label === "Branding" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45448
+ navTabs[tabIndex]?.label === "Branding" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45271
45449
  BrandingTab_default,
45272
45450
  {
45273
45451
  logoFile,
@@ -45288,7 +45466,7 @@ var Management = () => {
45288
45466
  setLogoBase64
45289
45467
  }
45290
45468
  ),
45291
- navTabs[tabIndex]?.label === "Knowledge" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45469
+ navTabs[tabIndex]?.label === "Knowledge" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45292
45470
  KnowledgeHubTab_default,
45293
45471
  {
45294
45472
  documents,
@@ -45301,8 +45479,8 @@ var Management = () => {
45301
45479
  seedPacksEnabled
45302
45480
  }
45303
45481
  ),
45304
- navTabs[tabIndex]?.label === "Storage" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StorageTab_default, { currentTheme }),
45305
- navTabs[tabIndex]?.label === "Preferences" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45482
+ navTabs[tabIndex]?.label === "Storage" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(StorageTab_default, { currentTheme }),
45483
+ navTabs[tabIndex]?.label === "Preferences" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45306
45484
  PreferencesTab_default,
45307
45485
  {
45308
45486
  preferences,
@@ -45312,13 +45490,13 @@ var Management = () => {
45312
45490
  showSnackbar: showSnackbarMessage
45313
45491
  }
45314
45492
  ),
45315
- navTabs[tabIndex]?.label === "Provider" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ProviderTab, {}),
45316
- navTabs[tabIndex]?.label === "Tools" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(MCPToolsTabV2_default, {})
45493
+ navTabs[tabIndex]?.label === "Provider" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ProviderTab, {}),
45494
+ navTabs[tabIndex]?.label === "Tools" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(MCPToolsTabV2_default, {})
45317
45495
  ]
45318
45496
  }
45319
45497
  ),
45320
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45321
- import_material54.Fab,
45498
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45499
+ import_material55.Fab,
45322
45500
  {
45323
45501
  "aria-label": "AI",
45324
45502
  onClick: handleOpenModal,
@@ -45339,7 +45517,7 @@ var Management = () => {
45339
45517
  boxShadow: theme2.shadows[6],
45340
45518
  zIndex: 2e3
45341
45519
  }),
45342
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
45520
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
45343
45521
  "img",
45344
45522
  {
45345
45523
  src: fabLogo,
@@ -45353,7 +45531,7 @@ var Management = () => {
45353
45531
  )
45354
45532
  }
45355
45533
  ),
45356
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
45534
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
45357
45535
  ]
45358
45536
  }
45359
45537
  )