@burtson-labs/bandit-engine 2.0.152 → 2.0.154

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.
Files changed (47) hide show
  1. package/dist/chat-E3VSYTAB.mjs +16 -0
  2. package/dist/chat-provider.js +8 -10
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +5 -5
  5. package/dist/{chunk-6STVJJSG.mjs → chunk-2HGBMNX4.mjs} +17 -3
  6. package/dist/chunk-2HGBMNX4.mjs.map +1 -0
  7. package/dist/{chunk-LPSM62OE.mjs → chunk-2X46TMFE.mjs} +19 -14
  8. package/dist/chunk-2X46TMFE.mjs.map +1 -0
  9. package/dist/{chunk-7ESJJN6D.mjs → chunk-7AMLR6P4.mjs} +263 -75
  10. package/dist/chunk-7AMLR6P4.mjs.map +1 -0
  11. package/dist/{chunk-RRCCSN3N.mjs → chunk-B2TJZM4Z.mjs} +2 -2
  12. package/dist/{chunk-U33KBX3Y.mjs → chunk-GQ3X6VPR.mjs} +4 -4
  13. package/dist/{chunk-CVFFNX7H.mjs → chunk-IS2LWSBZ.mjs} +10 -12
  14. package/dist/chunk-IS2LWSBZ.mjs.map +1 -0
  15. package/dist/{chunk-TYRYAAP2.mjs → chunk-RN7FRSMX.mjs} +3 -3
  16. package/dist/{chunk-QLATFSSO.mjs → chunk-TVPYBRWF.mjs} +5 -5
  17. package/dist/{chunk-EORIRPPX.mjs → chunk-ZOCXFQID.mjs} +2 -2
  18. package/dist/{chunk-EORIRPPX.mjs.map → chunk-ZOCXFQID.mjs.map} +1 -1
  19. package/dist/{chunk-VLUXQE24.mjs → chunk-ZW3YNAD7.mjs} +2 -2
  20. package/dist/index.d.mts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +790 -570
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +10 -10
  25. package/dist/management/management.js +489 -269
  26. package/dist/management/management.js.map +1 -1
  27. package/dist/management/management.mjs +8 -8
  28. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  29. package/dist/modals/chat-modal/chat-modal.mjs +4 -4
  30. package/dist/{modelStore-U57LUIIB.mjs → modelStore-KBUW3XAV.mjs} +2 -2
  31. package/dist/{public-20My32EB.d.mts → public-0EYmtpGD.d.mts} +8 -0
  32. package/dist/{public-20My32EB.d.ts → public-0EYmtpGD.d.ts} +8 -0
  33. package/dist/public-types.d.mts +1 -1
  34. package/dist/public-types.d.ts +1 -1
  35. package/package.json +1 -1
  36. package/dist/chat-Y3WOTIKI.mjs +0 -16
  37. package/dist/chunk-6STVJJSG.mjs.map +0 -1
  38. package/dist/chunk-7ESJJN6D.mjs.map +0 -1
  39. package/dist/chunk-CVFFNX7H.mjs.map +0 -1
  40. package/dist/chunk-LPSM62OE.mjs.map +0 -1
  41. /package/dist/{chat-Y3WOTIKI.mjs.map → chat-E3VSYTAB.mjs.map} +0 -0
  42. /package/dist/{chunk-RRCCSN3N.mjs.map → chunk-B2TJZM4Z.mjs.map} +0 -0
  43. /package/dist/{chunk-U33KBX3Y.mjs.map → chunk-GQ3X6VPR.mjs.map} +0 -0
  44. /package/dist/{chunk-TYRYAAP2.mjs.map → chunk-RN7FRSMX.mjs.map} +0 -0
  45. /package/dist/{chunk-QLATFSSO.mjs.map → chunk-TVPYBRWF.mjs.map} +0 -0
  46. /package/dist/{chunk-VLUXQE24.mjs.map → chunk-ZW3YNAD7.mjs.map} +0 -0
  47. /package/dist/{modelStore-U57LUIIB.mjs.map → modelStore-KBUW3XAV.mjs.map} +0 -0
package/dist/index.js CHANGED
@@ -3459,19 +3459,17 @@ var init_mcpToolsStore = __esm({
3459
3459
  imageGenerationTool = {
3460
3460
  id: "image-generation",
3461
3461
  name: "image_generation",
3462
- description: "Generate high-quality images using DALL-E 3 from text prompts",
3462
+ description: "Generate an image from a text prompt on the Burtson Labs GPU",
3463
3463
  enabled: true,
3464
3464
  type: "function",
3465
3465
  function: {
3466
3466
  name: "image_generation",
3467
- description: "Generate high-quality images using DALL-E 3 from text prompts",
3467
+ description: "Generate an image from a text prompt on the Burtson Labs GPU",
3468
3468
  parameters: {
3469
3469
  type: "object",
3470
3470
  properties: {
3471
3471
  prompt: { type: "string", description: "Text description of the image to generate" },
3472
- size: { type: "string", enum: ["1024x1024", "1024x1792", "1792x1024"], description: "Image dimensions" },
3473
- quality: { type: "string", enum: ["standard", "hd"], description: "Image quality" },
3474
- style: { type: "string", enum: ["vivid", "natural"], description: "Style preference" }
3472
+ size: { type: "string", enum: ["1024x1024", "1344x768", "768x1344"], description: "Canvas: square, landscape, or portrait" }
3475
3473
  },
3476
3474
  required: ["prompt"]
3477
3475
  }
@@ -3483,20 +3481,20 @@ var init_mcpToolsStore = __esm({
3483
3481
  createFileTool = {
3484
3482
  id: "create-file",
3485
3483
  name: "create_file",
3486
- description: "Create a downloadable file for the user (md, txt, csv, json, html, docx, pptx). Returns a temporary (~1 hour) download link.",
3484
+ description: "Create a downloadable file for the user (md, txt, csv, json, html, docx, pptx, pdf). Returns a temporary (~1 hour) download link.",
3487
3485
  enabled: true,
3488
3486
  type: "function",
3489
3487
  function: {
3490
3488
  name: "create_file",
3491
- description: "Generate a file the user can download. For docx/pptx write well-structured Markdown (headings, lists, tables; use '## ' headings to start each slide). Returns a short-lived (~1 hour) download URL \u2014 tell the user it expires.",
3489
+ description: "Generate a file the user can download. For docx/pptx write well-structured Markdown (headings, lists, tables; use '## ' headings to start each slide). For pdf, prefer complete HTML with inline CSS (branded proposals, print layouts) \u2014 Chromium renders it without browser headers/footers; Markdown also works. Returns a short-lived (~1 hour) download URL \u2014 tell the user it expires.",
3492
3490
  parameters: {
3493
3491
  type: "object",
3494
3492
  properties: {
3495
- content: { type: "string", description: "The file content (Markdown for docx/pptx; raw text for others)." },
3496
- filename: { type: "string", description: "Desired filename, e.g. 'report.docx' or 'notes.md'." },
3493
+ content: { type: "string", description: "The file content (HTML preferred for pdf; Markdown for docx/pptx/pdf; raw text for others)." },
3494
+ filename: { type: "string", description: "Desired filename, e.g. 'report.pdf' or 'notes.md'." },
3497
3495
  format: {
3498
3496
  type: "string",
3499
- enum: ["md", "txt", "csv", "json", "html", "xml", "yaml", "docx", "pptx"],
3497
+ enum: ["md", "txt", "csv", "json", "html", "xml", "yaml", "docx", "pptx", "pdf"],
3500
3498
  description: "File format. Defaults to md."
3501
3499
  }
3502
3500
  },
@@ -16085,6 +16083,7 @@ var init_engine_picker = __esm({
16085
16083
  const tier = String(getCurrentTier());
16086
16084
  return tier !== "trial" && tier !== "expired" && tier !== "free" && tier !== "basic";
16087
16085
  })();
16086
+ const hideUpgradePrompts = usePackageSettingsStore((s) => s.settings?.hideUpgradePrompts === true);
16088
16087
  const plansPath = typeof window !== "undefined" && !(window.location.hostname === "banditailabs.com" || window.location.hostname.endsWith(".banditailabs.com") || window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") ? "https://banditailabs.com/plans" : "/plans";
16089
16088
  if (engines.length === 0) return null;
16090
16089
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
@@ -16163,8 +16162,8 @@ var init_engine_picker = __esm({
16163
16162
  ),
16164
16163
  engine.id === resolvedEngineId && !isGated && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material13.Box, { sx: { width: 8, height: 8, borderRadius: "50%", bgcolor: theme.palette.primary.main } })
16165
16164
  ] }),
16166
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material13.Typography, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: isGated ? "Premium engine \u2014 available on a paid plan." : engine.available ? engine.description : engine.unavailableReason || "Unavailable" }),
16167
- isGated && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
16165
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material13.Typography, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: isGated ? hideUpgradePrompts ? "Not available on your current plan." : "Premium engine \u2014 available on a paid plan." : engine.available ? engine.description : engine.unavailableReason || "Unavailable" }),
16166
+ isGated && !hideUpgradePrompts && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
16168
16167
  import_material13.Button,
16169
16168
  {
16170
16169
  size: "small",
@@ -19014,12 +19013,14 @@ var init_rate_limit_prompt = __esm({
19014
19013
  import_react_router_dom = require("react-router-dom");
19015
19014
  init_lucide_icons();
19016
19015
  init_rateLimitStore();
19016
+ init_packageSettingsStore();
19017
19017
  init_debugLogger();
19018
19018
  import_jsx_runtime21 = require("react/jsx-runtime");
19019
19019
  RateLimitPrompt = () => {
19020
19020
  const theme = (0, import_material18.useTheme)();
19021
19021
  const prompt = useRateLimitStore((s) => s.prompt);
19022
19022
  const dismiss = useRateLimitStore((s) => s.dismiss);
19023
+ const hideUpgradePrompts = usePackageSettingsStore((s) => s.settings?.hideUpgradePrompts === true);
19023
19024
  const hasLoggedRouterWarningRef = (0, import_react24.useRef)(false);
19024
19025
  let navigate = null;
19025
19026
  try {
@@ -19049,6 +19050,12 @@ var init_rate_limit_prompt = __esm({
19049
19050
  const { scope, frontier } = prompt;
19050
19051
  const title = scope === "weekly" ? "You've reached your weekly limit" : "You've hit your session limit";
19051
19052
  const body = (() => {
19053
+ if (hideUpgradePrompts) {
19054
+ if (frontier) {
19055
+ return scope === "weekly" ? "You've used your weekly allowance on premium engines. It resets with your weekly cycle." : "You've hit your session limit on premium engines. It resets soon.";
19056
+ }
19057
+ return scope === "weekly" ? "Your weekly chat allowance is used up. It resets with your weekly cycle." : "It resets shortly \u2014 check back in a bit.";
19058
+ }
19052
19059
  if (frontier) {
19053
19060
  return scope === "weekly" ? "You've used your weekly allowance on premium engines. Upgrade to keep chatting on the most capable models." : "You've hit your session limit on premium engines. It resets soon \u2014 or upgrade for higher limits and uninterrupted access.";
19054
19061
  }
@@ -19093,7 +19100,7 @@ var init_rate_limit_prompt = __esm({
19093
19100
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "subtitle2", sx: { fontWeight: 600, color: theme.palette.text.primary }, children: title }),
19094
19101
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "body2", sx: { color: theme.palette.text.secondary, mt: 0.25 }, children: body }),
19095
19102
  /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_material18.Box, { sx: { display: "flex", gap: 1, mt: 1, flexWrap: "wrap" }, children: [
19096
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
19103
+ !hideUpgradePrompts && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
19097
19104
  import_material18.Button,
19098
19105
  {
19099
19106
  size: "small",
@@ -20965,7 +20972,7 @@ TOOL USAGE PROTOCOL (conservative approach)
20965
20972
  - Only call tools for SPECIFIC, CURRENT information that requires real-time data or a source you don't already have:
20966
20973
  * web_search() - when asked about recent/current events, breaking news, live information (weather, prices, sports scores), or when you need to look up documentation, libraries, APIs, error messages, or verify a specific fact
20967
20974
  * web_fetch() - to read the FULL contents of a specific URL you already have. Reach for this when the user wants to "tell me more", "go deeper", "read/open that article", or asks for details about a specific source, link, or article from an EARLIER answer: take that item's URL from the previous Sources list in this conversation and fetch it, then answer from the page's actual content (not just the prior summary)
20968
- * image_generation() - ONLY when explicitly asked to create or generate an image
20975
+ * image_generation() - ONLY when explicitly asked to create or generate an image. Runs on Burtson's local GPU; it can take a couple of minutes when the GPU is cold, and is limited to admin and partner accounts
20969
20976
  * create_file({"content": "...", "filename": "report.docx", "format": "docx"}) - when the user asks for a downloadable FILE (a document, spreadsheet, slides, markdown, code, etc.) or to "export"/"download"/"save" something. Formats: md, txt, csv, json, html, xml, yaml, docx, pptx. PDF is NOT a supported format \u2014 if the user asks for a PDF, create a docx instead. For docx/pptx write well-structured Markdown (use "## " headings to start each slide for pptx). It returns a temporary download link \u2014 ALWAYS tell the user the file expires (~1 hour). If it is unclear whether they want it shown inline vs. as a downloadable file, use ask_user first.
20970
20977
  * ask_user({"questions": [{"question": "...", "header": "Format", "options": [{"label": "Inline (Recommended)"}, {"label": "Download a file"}]}]}) - when the request is AMBIGUOUS or missing a detail you need to do a good job (unclear scope, audience, format, tone, which of several interpretations they meant), or you are blocked on a decision that is the user's to make and cannot resolve from the request, context, or sensible defaults. Renders clickable options the user answers in one step \u2014 ALWAYS prefer this over asking a clarifying question in prose and ending your turn. Give 1-4 questions, each with 2-4 short options; if one is clearly best, list it first and append " (Recommended)". The user may also type their own answer; act on it directly. Don't overuse it \u2014 when a sensible default exists, take it and note the assumption instead.
20971
20978
  - For general questions about concepts, definitions, explanations, or how-to topics, use your built-in knowledge WITHOUT calling tools.
@@ -23159,12 +23166,67 @@ var init_FeedbackModal = __esm({
23159
23166
  }
23160
23167
  });
23161
23168
 
23169
+ // src/utils/installedApp.ts
23170
+ var isNativeShell, isStandalonePwa2;
23171
+ var init_installedApp = __esm({
23172
+ "src/utils/installedApp.ts"() {
23173
+ "use strict";
23174
+ isNativeShell = () => {
23175
+ if (typeof window === "undefined") return false;
23176
+ const cap = window.Capacitor;
23177
+ return typeof cap?.isNativePlatform === "function" && cap.isNativePlatform() === true;
23178
+ };
23179
+ isStandalonePwa2 = () => {
23180
+ if (typeof window === "undefined") return false;
23181
+ const nav = window.navigator;
23182
+ return window.matchMedia?.("(display-mode: standalone)").matches || nav.standalone === true;
23183
+ };
23184
+ }
23185
+ });
23186
+
23187
+ // src/hooks/useSafeNavigate.ts
23188
+ var import_react30, import_react_router_dom2, useSafeNavigate;
23189
+ var init_useSafeNavigate = __esm({
23190
+ "src/hooks/useSafeNavigate.ts"() {
23191
+ "use strict";
23192
+ import_react30 = require("react");
23193
+ import_react_router_dom2 = require("react-router-dom");
23194
+ init_debugLogger();
23195
+ useSafeNavigate = () => {
23196
+ const warned = (0, import_react30.useRef)(false);
23197
+ let navigate = null;
23198
+ try {
23199
+ navigate = (0, import_react_router_dom2.useNavigate)();
23200
+ } catch (error) {
23201
+ if (!warned.current) {
23202
+ debugLogger.warn("useSafeNavigate: no Router context; falling back to location", { error });
23203
+ warned.current = true;
23204
+ }
23205
+ navigate = null;
23206
+ }
23207
+ return (to) => {
23208
+ if (typeof window !== "undefined" && /^[a-z]+:\/\//i.test(to)) {
23209
+ window.location.href = to;
23210
+ return;
23211
+ }
23212
+ if (navigate) {
23213
+ navigate(to);
23214
+ return;
23215
+ }
23216
+ if (typeof window !== "undefined") {
23217
+ window.location.href = to;
23218
+ }
23219
+ };
23220
+ };
23221
+ }
23222
+ });
23223
+
23162
23224
  // src/chat/project-management-modal.tsx
23163
- var import_react30, import_material21, import_lucide_react7, import_styles12, import_jsx_runtime23, DEFAULT_COLORS2, ProjectManagementModal, project_management_modal_default;
23225
+ var import_react31, import_material21, import_lucide_react7, import_styles12, import_jsx_runtime23, DEFAULT_COLORS2, ProjectManagementModal, project_management_modal_default;
23164
23226
  var init_project_management_modal = __esm({
23165
23227
  "src/chat/project-management-modal.tsx"() {
23166
23228
  "use strict";
23167
- import_react30 = require("react");
23229
+ import_react31 = require("react");
23168
23230
  import_material21 = require("@mui/material");
23169
23231
  import_lucide_react7 = require("lucide-react");
23170
23232
  import_styles12 = require("@mui/material/styles");
@@ -23200,25 +23262,25 @@ var init_project_management_modal = __esm({
23200
23262
  hydrate
23201
23263
  } = useProjectStore();
23202
23264
  const { getConversationsByProject } = useConversationStore();
23203
- const [showCreateForm, setShowCreateForm] = (0, import_react30.useState)(false);
23204
- const [editingProject, setEditingProject] = (0, import_react30.useState)(null);
23205
- const [formData, setFormData] = (0, import_react30.useState)({
23265
+ const [showCreateForm, setShowCreateForm] = (0, import_react31.useState)(false);
23266
+ const [editingProject, setEditingProject] = (0, import_react31.useState)(null);
23267
+ const [formData, setFormData] = (0, import_react31.useState)({
23206
23268
  name: "",
23207
23269
  description: "",
23208
23270
  instructions: "",
23209
23271
  color: DEFAULT_COLORS2[0]
23210
23272
  });
23211
- const [menuAnchor, setMenuAnchor] = (0, import_react30.useState)(null);
23212
- const [selectedProject, setSelectedProject] = (0, import_react30.useState)(null);
23213
- const [loading, setLoading] = (0, import_react30.useState)(false);
23214
- const [error, setError] = (0, import_react30.useState)(null);
23215
- const modalContainerRef = (0, import_react30.useRef)(null);
23216
- (0, import_react30.useEffect)(() => {
23273
+ const [menuAnchor, setMenuAnchor] = (0, import_react31.useState)(null);
23274
+ const [selectedProject, setSelectedProject] = (0, import_react31.useState)(null);
23275
+ const [loading, setLoading] = (0, import_react31.useState)(false);
23276
+ const [error, setError] = (0, import_react31.useState)(null);
23277
+ const modalContainerRef = (0, import_react31.useRef)(null);
23278
+ (0, import_react31.useEffect)(() => {
23217
23279
  if (open && !_hasHydrated) {
23218
23280
  hydrate();
23219
23281
  }
23220
23282
  }, [open, _hasHydrated, hydrate]);
23221
- (0, import_react30.useEffect)(() => {
23283
+ (0, import_react31.useEffect)(() => {
23222
23284
  if (!open) {
23223
23285
  setMenuAnchor(null);
23224
23286
  setSelectedProject(null);
@@ -23753,11 +23815,11 @@ var init_project_management_modal = __esm({
23753
23815
  });
23754
23816
 
23755
23817
  // src/chat/move-conversation-modal.tsx
23756
- var import_react31, import_material22, import_lucide_react8, import_styles13, import_jsx_runtime24, MoveConversationModal, move_conversation_modal_default;
23818
+ var import_react32, import_material22, import_lucide_react8, import_styles13, import_jsx_runtime24, MoveConversationModal, move_conversation_modal_default;
23757
23819
  var init_move_conversation_modal = __esm({
23758
23820
  "src/chat/move-conversation-modal.tsx"() {
23759
23821
  "use strict";
23760
- import_react31 = require("react");
23822
+ import_react32 = require("react");
23761
23823
  import_material22 = require("@mui/material");
23762
23824
  import_lucide_react8 = require("lucide-react");
23763
23825
  import_styles13 = require("@mui/material/styles");
@@ -23774,15 +23836,15 @@ var init_move_conversation_modal = __esm({
23774
23836
  const theme = (0, import_styles13.useTheme)();
23775
23837
  const { projects, _hasHydrated, hydrate } = useProjectStore();
23776
23838
  const { moveConversationToProject } = useConversationStore();
23777
- const [selectedProjectId, setSelectedProjectId] = (0, import_react31.useState)(
23839
+ const [selectedProjectId, setSelectedProjectId] = (0, import_react32.useState)(
23778
23840
  currentProjectId
23779
23841
  );
23780
- (0, import_react31.useEffect)(() => {
23842
+ (0, import_react32.useEffect)(() => {
23781
23843
  if (open && !_hasHydrated) {
23782
23844
  hydrate();
23783
23845
  }
23784
23846
  }, [open, _hasHydrated, hydrate]);
23785
- (0, import_react31.useEffect)(() => {
23847
+ (0, import_react32.useEffect)(() => {
23786
23848
  setSelectedProjectId(currentProjectId);
23787
23849
  }, [currentProjectId, open]);
23788
23850
  const handleMove = async () => {
@@ -23924,11 +23986,11 @@ var init_move_conversation_modal = __esm({
23924
23986
  });
23925
23987
 
23926
23988
  // src/chat/simple-conversation-item.tsx
23927
- var import_react32, import_material23, import_lucide_react9, import_styles14, import_jsx_runtime25, SimpleConversationItem, simple_conversation_item_default;
23989
+ var import_react33, import_material23, import_lucide_react9, import_styles14, import_jsx_runtime25, SimpleConversationItem, simple_conversation_item_default;
23928
23990
  var init_simple_conversation_item = __esm({
23929
23991
  "src/chat/simple-conversation-item.tsx"() {
23930
23992
  "use strict";
23931
- import_react32 = require("react");
23993
+ import_react33 = require("react");
23932
23994
  import_material23 = require("@mui/material");
23933
23995
  import_lucide_react9 = require("lucide-react");
23934
23996
  import_styles14 = require("@mui/material/styles");
@@ -23950,16 +24012,16 @@ var init_simple_conversation_item = __esm({
23950
24012
  }) => {
23951
24013
  const theme = (0, import_styles14.useTheme)();
23952
24014
  const isMobile = (0, import_material23.useMediaQuery)(theme.breakpoints.down("sm"));
23953
- const [anchorEl, setAnchorEl] = (0, import_react32.useState)(null);
23954
- const [isEditing, setIsEditing] = (0, import_react32.useState)(false);
23955
- const [editName, setEditName] = (0, import_react32.useState)(conversation.name);
23956
- const [isDragging, setIsDragging] = (0, import_react32.useState)(false);
23957
- const [isTouchDragging, setIsTouchDragging] = (0, import_react32.useState)(false);
23958
- const [showRenameDialog, setShowRenameDialog] = (0, import_react32.useState)(false);
23959
- const longPressTimeoutRef = (0, import_react32.useRef)(null);
23960
- const touchStartPointRef = (0, import_react32.useRef)(null);
23961
- const activeTouchIdRef = (0, import_react32.useRef)(null);
23962
- const suppressClickRef = (0, import_react32.useRef)(false);
24015
+ const [anchorEl, setAnchorEl] = (0, import_react33.useState)(null);
24016
+ const [isEditing, setIsEditing] = (0, import_react33.useState)(false);
24017
+ const [editName, setEditName] = (0, import_react33.useState)(conversation.name);
24018
+ const [isDragging, setIsDragging] = (0, import_react33.useState)(false);
24019
+ const [isTouchDragging, setIsTouchDragging] = (0, import_react33.useState)(false);
24020
+ const [showRenameDialog, setShowRenameDialog] = (0, import_react33.useState)(false);
24021
+ const longPressTimeoutRef = (0, import_react33.useRef)(null);
24022
+ const touchStartPointRef = (0, import_react33.useRef)(null);
24023
+ const activeTouchIdRef = (0, import_react33.useRef)(null);
24024
+ const suppressClickRef = (0, import_react33.useRef)(false);
23963
24025
  const highlightText = (text, query) => {
23964
24026
  if (!query || !query.trim()) {
23965
24027
  return text;
@@ -24098,7 +24160,7 @@ var init_simple_conversation_item = __esm({
24098
24160
  if (!isMobile) return;
24099
24161
  finalizeTouchDrag();
24100
24162
  };
24101
- (0, import_react32.useEffect)(() => {
24163
+ (0, import_react33.useEffect)(() => {
24102
24164
  if (!isTouchDragActive && isTouchDragging) {
24103
24165
  setIsTouchDragging(false);
24104
24166
  }
@@ -24364,11 +24426,11 @@ var init_simple_conversation_item = __esm({
24364
24426
  });
24365
24427
 
24366
24428
  // src/chat/project-header.tsx
24367
- var import_react33, import_material24, import_lucide_react10, import_styles15, import_jsx_runtime26, ProjectHeader, project_header_default;
24429
+ var import_react34, import_material24, import_lucide_react10, import_styles15, import_jsx_runtime26, ProjectHeader, project_header_default;
24368
24430
  var init_project_header = __esm({
24369
24431
  "src/chat/project-header.tsx"() {
24370
24432
  "use strict";
24371
- import_react33 = require("react");
24433
+ import_react34 = require("react");
24372
24434
  import_material24 = require("@mui/material");
24373
24435
  import_lucide_react10 = require("lucide-react");
24374
24436
  import_styles15 = require("@mui/material/styles");
@@ -24392,10 +24454,10 @@ var init_project_header = __esm({
24392
24454
  const theme = (0, import_styles15.useTheme)();
24393
24455
  const { createNewConversation } = useConversationStore();
24394
24456
  const { renameProject } = useProjectStore();
24395
- const [isHovered, setIsHovered] = (0, import_react33.useState)(false);
24396
- const [isDragOver, setIsDragOver] = (0, import_react33.useState)(false);
24397
- const [renameDraft, setRenameDraft] = (0, import_react33.useState)(projectName);
24398
- const renameActionRef = (0, import_react33.useRef)("none");
24457
+ const [isHovered, setIsHovered] = (0, import_react34.useState)(false);
24458
+ const [isDragOver, setIsDragOver] = (0, import_react34.useState)(false);
24459
+ const [renameDraft, setRenameDraft] = (0, import_react34.useState)(projectName);
24460
+ const renameActionRef = (0, import_react34.useRef)("none");
24399
24461
  const isUngrouped = projectId === null;
24400
24462
  const Icon = isCollapsed ? import_lucide_react10.Folder : import_lucide_react10.FolderOpen;
24401
24463
  const handleAddConversation = (e) => {
@@ -24669,11 +24731,11 @@ var init_tooltips = __esm({
24669
24731
  });
24670
24732
 
24671
24733
  // src/chat/conversation-drawer.tsx
24672
- var import_react34, import_material25, import_lucide_react11, import_styles16, import_jsx_runtime27, BANDIT_AVATAR, coerceOptionalString, deriveInitials, ConversationDrawer, conversation_drawer_default;
24734
+ var import_react35, import_material25, import_lucide_react11, import_styles16, import_jsx_runtime27, BANDIT_AVATAR, coerceOptionalString, deriveInitials, ConversationDrawer, conversation_drawer_default;
24673
24735
  var init_conversation_drawer = __esm({
24674
24736
  "src/chat/conversation-drawer.tsx"() {
24675
24737
  "use strict";
24676
- import_react34 = require("react");
24738
+ import_react35 = require("react");
24677
24739
  import_material25 = require("@mui/material");
24678
24740
  import_lucide_react11 = require("lucide-react");
24679
24741
  init_FeedbackModal();
@@ -24682,6 +24744,8 @@ var init_conversation_drawer = __esm({
24682
24744
  init_projectStore();
24683
24745
  init_authenticationStore();
24684
24746
  init_packageSettingsStore();
24747
+ init_installedApp();
24748
+ init_useSafeNavigate();
24685
24749
  init_brandingService();
24686
24750
  init_authenticationService();
24687
24751
  init_project_management_modal();
@@ -24745,23 +24809,23 @@ var init_conversation_drawer = __esm({
24745
24809
  createProject,
24746
24810
  deleteProject
24747
24811
  } = useProjectStore();
24748
- const [projectManagementOpen, setProjectManagementOpen] = (0, import_react34.useState)(false);
24749
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react34.useState)(false);
24750
- const [collapsedProjects, setCollapsedProjects] = (0, import_react34.useState)(/* @__PURE__ */ new Set());
24751
- const didInitCollapseRef = (0, import_react34.useRef)(false);
24752
- const [searchQuery, setSearchQuery] = (0, import_react34.useState)("");
24753
- const [menuAnchorEl, setMenuAnchorEl] = (0, import_react34.useState)(null);
24754
- const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react34.useState)(false);
24755
- const [feedbackOpen, setFeedbackOpen] = (0, import_react34.useState)(false);
24756
- const [moveModalOpen, setMoveModalOpen] = (0, import_react34.useState)(false);
24757
- const [conversationToMove, setConversationToMove] = (0, import_react34.useState)(null);
24758
- const [renameProjectId, setRenameProjectId] = (0, import_react34.useState)(null);
24759
- const getCustomClaim = (0, import_react34.useCallback)((key) => {
24812
+ const [projectManagementOpen, setProjectManagementOpen] = (0, import_react35.useState)(false);
24813
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react35.useState)(false);
24814
+ const [collapsedProjects, setCollapsedProjects] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
24815
+ const didInitCollapseRef = (0, import_react35.useRef)(false);
24816
+ const [searchQuery, setSearchQuery] = (0, import_react35.useState)("");
24817
+ const [menuAnchorEl, setMenuAnchorEl] = (0, import_react35.useState)(null);
24818
+ const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react35.useState)(false);
24819
+ const [feedbackOpen, setFeedbackOpen] = (0, import_react35.useState)(false);
24820
+ const [moveModalOpen, setMoveModalOpen] = (0, import_react35.useState)(false);
24821
+ const [conversationToMove, setConversationToMove] = (0, import_react35.useState)(null);
24822
+ const [renameProjectId, setRenameProjectId] = (0, import_react35.useState)(null);
24823
+ const getCustomClaim = (0, import_react35.useCallback)((key) => {
24760
24824
  if (!user2) return void 0;
24761
24825
  const record = user2;
24762
24826
  return coerceOptionalString(record[key]);
24763
24827
  }, [user2]);
24764
- const userDisplayName = (0, import_react34.useMemo)(() => {
24828
+ const userDisplayName = (0, import_react35.useMemo)(() => {
24765
24829
  if (!user2) return void 0;
24766
24830
  const candidateFields = [
24767
24831
  coerceOptionalString(user2.name),
@@ -24776,7 +24840,7 @@ var init_conversation_drawer = __esm({
24776
24840
  if (trimmedEmail) return trimmedEmail;
24777
24841
  return user2.sub;
24778
24842
  }, [user2, getCustomClaim]);
24779
- const userSecondaryText = (0, import_react34.useMemo)(() => {
24843
+ const userSecondaryText = (0, import_react35.useMemo)(() => {
24780
24844
  if (!user2) return void 0;
24781
24845
  const trimmedEmail = coerceOptionalString(user2.email);
24782
24846
  if (trimmedEmail && trimmedEmail !== userDisplayName) {
@@ -24788,13 +24852,13 @@ var init_conversation_drawer = __esm({
24788
24852
  }
24789
24853
  return void 0;
24790
24854
  }, [user2, userDisplayName]);
24791
- const [avatarImage, setAvatarImage] = (0, import_react34.useState)(BANDIT_AVATAR);
24792
- (0, import_react34.useEffect)(() => {
24855
+ const [avatarImage, setAvatarImage] = (0, import_react35.useState)(BANDIT_AVATAR);
24856
+ (0, import_react35.useEffect)(() => {
24793
24857
  const fresh = readPersistedToken();
24794
24858
  const store = useAuthenticationStore.getState();
24795
24859
  if (fresh && fresh !== store.token) store.setToken(fresh);
24796
24860
  }, []);
24797
- (0, import_react34.useEffect)(() => {
24861
+ (0, import_react35.useEffect)(() => {
24798
24862
  let active2 = true;
24799
24863
  let objectUrl = null;
24800
24864
  const resolveAvatar2 = async () => {
@@ -24835,13 +24899,13 @@ var init_conversation_drawer = __esm({
24835
24899
  };
24836
24900
  }, [getCustomClaim]);
24837
24901
  const avatarLabel = userDisplayName || user2?.email || "Bandit";
24838
- const avatarInitials = (0, import_react34.useMemo)(() => deriveInitials(avatarLabel), [avatarLabel]);
24839
- (0, import_react34.useEffect)(() => {
24902
+ const avatarInitials = (0, import_react35.useMemo)(() => deriveInitials(avatarLabel), [avatarLabel]);
24903
+ (0, import_react35.useEffect)(() => {
24840
24904
  if (!projectsHydrated) {
24841
24905
  hydrateProjects();
24842
24906
  }
24843
24907
  }, [projectsHydrated, hydrateProjects]);
24844
- (0, import_react34.useEffect)(() => {
24908
+ (0, import_react35.useEffect)(() => {
24845
24909
  if (projectsHydrated && !didInitCollapseRef.current) {
24846
24910
  didInitCollapseRef.current = true;
24847
24911
  if (projects && projects.length > 0) {
@@ -24854,7 +24918,7 @@ var init_conversation_drawer = __esm({
24854
24918
  const end = Math.min(text.length, idx + query.length + 60);
24855
24919
  return text.slice(start, end).replace(/\s+/g, " ").trim();
24856
24920
  };
24857
- const projectGroups = (0, import_react34.useMemo)(() => {
24921
+ const projectGroups = (0, import_react35.useMemo)(() => {
24858
24922
  const listable = conversations.filter((conversation) => !conversation.incognito);
24859
24923
  const groups = projects.map((project) => ({
24860
24924
  id: project.id,
@@ -24878,7 +24942,7 @@ var init_conversation_drawer = __esm({
24878
24942
  }
24879
24943
  return groups.filter((group) => group.conversations.length > 0 || group.id !== null);
24880
24944
  }, [projects, conversations, collapsedProjects]);
24881
- const filteredProjectGroups = (0, import_react34.useMemo)(() => {
24945
+ const filteredProjectGroups = (0, import_react35.useMemo)(() => {
24882
24946
  if (!searchQuery.trim()) return projectGroups;
24883
24947
  const query = searchQuery.toLowerCase();
24884
24948
  return projectGroups.map((group) => {
@@ -24926,15 +24990,18 @@ var init_conversation_drawer = __esm({
24926
24990
  const syncEnabled = useConversationSyncStore((s) => s.syncEnabled);
24927
24991
  const syncStatus = useConversationSyncStore((s) => s.status);
24928
24992
  const runSync = useConversationSyncStore((s) => s.runSync);
24993
+ const safeNavigate = useSafeNavigate();
24929
24994
  const goToHome = () => {
24930
24995
  const resolvedHomeUrl = preferences.homeUrl?.trim() || usePackageSettingsStore.getState().settings?.homeUrl?.trim() || "";
24931
24996
  if (resolvedHomeUrl) {
24932
24997
  window.location.href = resolvedHomeUrl;
24933
24998
  return;
24934
24999
  }
24935
- const navigatorWithStandalone = window.navigator;
24936
- const isStandalone = window.matchMedia?.("(display-mode: standalone)").matches || navigatorWithStandalone.standalone === true;
24937
- if (isStandalone) {
25000
+ if (isNativeShell()) {
25001
+ safeNavigate("/chat");
25002
+ return;
25003
+ }
25004
+ if (isStandalonePwa2()) {
24938
25005
  try {
24939
25006
  sessionStorage.setItem("banditPwaStayOnHome", "true");
24940
25007
  } catch {
@@ -25405,7 +25472,7 @@ var init_conversation_drawer = __esm({
25405
25472
  import_material25.Box,
25406
25473
  {
25407
25474
  onClick: user2 ? () => {
25408
- window.location.href = "/profile";
25475
+ safeNavigate("/profile");
25409
25476
  } : void 0,
25410
25477
  title: user2 ? "Profile & settings" : void 0,
25411
25478
  sx: {
@@ -25498,7 +25565,7 @@ var init_conversation_drawer = __esm({
25498
25565
  title: "Management & settings",
25499
25566
  onClick: (event) => {
25500
25567
  event.stopPropagation();
25501
- window.location.href = managementPath;
25568
+ safeNavigate(managementPath);
25502
25569
  },
25503
25570
  sx: {
25504
25571
  flexShrink: 0,
@@ -25658,11 +25725,11 @@ var init_conversation_drawer = __esm({
25658
25725
  });
25659
25726
 
25660
25727
  // src/chat/enhanced-mobile-conversations-modal.tsx
25661
- var import_react35, import_material26, import_lucide_react12, import_styles17, import_jsx_runtime28, BANDIT_AVATAR2, coerceOptionalString2, deriveInitials2, EnhancedMobileConversationsModal, enhanced_mobile_conversations_modal_default;
25728
+ var import_react36, import_material26, import_lucide_react12, import_styles17, import_jsx_runtime28, BANDIT_AVATAR2, coerceOptionalString2, deriveInitials2, EnhancedMobileConversationsModal, enhanced_mobile_conversations_modal_default;
25662
25729
  var init_enhanced_mobile_conversations_modal = __esm({
25663
25730
  "src/chat/enhanced-mobile-conversations-modal.tsx"() {
25664
25731
  "use strict";
25665
- import_react35 = require("react");
25732
+ import_react36 = require("react");
25666
25733
  import_material26 = require("@mui/material");
25667
25734
  import_lucide_react12 = require("lucide-react");
25668
25735
  import_styles17 = require("@mui/material/styles");
@@ -25670,6 +25737,8 @@ var init_enhanced_mobile_conversations_modal = __esm({
25670
25737
  init_projectStore();
25671
25738
  init_authenticationStore();
25672
25739
  init_packageSettingsStore();
25740
+ init_installedApp();
25741
+ init_useSafeNavigate();
25673
25742
  init_memory_modal();
25674
25743
  init_brandingService();
25675
25744
  init_authenticationService();
@@ -25710,7 +25779,8 @@ var init_enhanced_mobile_conversations_modal = __esm({
25710
25779
  };
25711
25780
  EnhancedMobileConversationsModal = ({
25712
25781
  open,
25713
- onClose
25782
+ onClose,
25783
+ drag
25714
25784
  }) => {
25715
25785
  const theme = (0, import_styles17.useTheme)();
25716
25786
  const { user: user2 } = useAuthenticationStore();
@@ -25737,15 +25807,18 @@ var init_enhanced_mobile_conversations_modal = __esm({
25737
25807
  const syncEnabled = useConversationSyncStore((s) => s.syncEnabled);
25738
25808
  const syncStatus = useConversationSyncStore((s) => s.status);
25739
25809
  const runSync = useConversationSyncStore((s) => s.runSync);
25810
+ const safeNavigate = useSafeNavigate();
25740
25811
  const goToHome = () => {
25741
25812
  const resolvedHomeUrl = preferences.homeUrl?.trim() || usePackageSettingsStore.getState().settings?.homeUrl?.trim() || "";
25742
25813
  if (resolvedHomeUrl) {
25743
25814
  window.location.href = resolvedHomeUrl;
25744
25815
  return;
25745
25816
  }
25746
- const navigatorWithStandalone = window.navigator;
25747
- const isStandalone = window.matchMedia?.("(display-mode: standalone)").matches || navigatorWithStandalone.standalone === true;
25748
- if (isStandalone) {
25817
+ if (isNativeShell()) {
25818
+ safeNavigate("/chat");
25819
+ return;
25820
+ }
25821
+ if (isStandalonePwa2()) {
25749
25822
  try {
25750
25823
  sessionStorage.setItem("banditPwaStayOnHome", "true");
25751
25824
  } catch {
@@ -25756,25 +25829,25 @@ var init_enhanced_mobile_conversations_modal = __esm({
25756
25829
  window.location.href = "/";
25757
25830
  };
25758
25831
  const managementPath = typeof window !== "undefined" && window.location.pathname.startsWith("/playground") ? "/playground/management" : "/management";
25759
- const [projectManagementOpen, setProjectManagementOpen] = (0, import_react35.useState)(false);
25760
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react35.useState)(false);
25761
- const [collapsedProjects, setCollapsedProjects] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
25762
- const didInitCollapseRef = (0, import_react35.useRef)(false);
25763
- const [searchQuery, setSearchQuery] = (0, import_react35.useState)("");
25764
- const [menuAnchorEl, setMenuAnchorEl] = (0, import_react35.useState)(null);
25765
- const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react35.useState)(false);
25766
- const [moveModalOpen, setMoveModalOpen] = (0, import_react35.useState)(false);
25767
- const [conversationToMove, setConversationToMove] = (0, import_react35.useState)(null);
25768
- const [renameProjectId, setRenameProjectId] = (0, import_react35.useState)(null);
25769
- const [deletedConversationIds, setDeletedConversationIds] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
25770
- const [touchDragState, setTouchDragState] = (0, import_react35.useState)({ conversationId: null, originProjectId: null, hoverProjectId: null });
25771
- const [avatarImage, setAvatarImage] = (0, import_react35.useState)(BANDIT_AVATAR2);
25772
- const getCustomClaim = (0, import_react35.useCallback)((key) => {
25832
+ const [projectManagementOpen, setProjectManagementOpen] = (0, import_react36.useState)(false);
25833
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react36.useState)(false);
25834
+ const [collapsedProjects, setCollapsedProjects] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
25835
+ const didInitCollapseRef = (0, import_react36.useRef)(false);
25836
+ const [searchQuery, setSearchQuery] = (0, import_react36.useState)("");
25837
+ const [menuAnchorEl, setMenuAnchorEl] = (0, import_react36.useState)(null);
25838
+ const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react36.useState)(false);
25839
+ const [moveModalOpen, setMoveModalOpen] = (0, import_react36.useState)(false);
25840
+ const [conversationToMove, setConversationToMove] = (0, import_react36.useState)(null);
25841
+ const [renameProjectId, setRenameProjectId] = (0, import_react36.useState)(null);
25842
+ const [deletedConversationIds, setDeletedConversationIds] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
25843
+ const [touchDragState, setTouchDragState] = (0, import_react36.useState)({ conversationId: null, originProjectId: null, hoverProjectId: null });
25844
+ const [avatarImage, setAvatarImage] = (0, import_react36.useState)(BANDIT_AVATAR2);
25845
+ const getCustomClaim = (0, import_react36.useCallback)((key) => {
25773
25846
  if (!user2) return void 0;
25774
25847
  const record = user2;
25775
25848
  return coerceOptionalString2(record[key]);
25776
25849
  }, [user2]);
25777
- const userDisplayName = (0, import_react35.useMemo)(() => {
25850
+ const userDisplayName = (0, import_react36.useMemo)(() => {
25778
25851
  if (!user2) return void 0;
25779
25852
  const candidateFields = [
25780
25853
  coerceOptionalString2(user2.name),
@@ -25789,7 +25862,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25789
25862
  if (trimmedEmail) return trimmedEmail;
25790
25863
  return user2.sub;
25791
25864
  }, [user2, getCustomClaim]);
25792
- const userSecondaryText = (0, import_react35.useMemo)(() => {
25865
+ const userSecondaryText = (0, import_react36.useMemo)(() => {
25793
25866
  if (!user2) return void 0;
25794
25867
  const trimmedEmail = coerceOptionalString2(user2.email);
25795
25868
  if (trimmedEmail && trimmedEmail !== userDisplayName) {
@@ -25801,7 +25874,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25801
25874
  }
25802
25875
  return void 0;
25803
25876
  }, [user2, userDisplayName]);
25804
- (0, import_react35.useEffect)(() => {
25877
+ (0, import_react36.useEffect)(() => {
25805
25878
  if (!open) return;
25806
25879
  const fresh = readPersistedToken();
25807
25880
  const authStore = useAuthenticationStore.getState();
@@ -25846,18 +25919,18 @@ var init_enhanced_mobile_conversations_modal = __esm({
25846
25919
  };
25847
25920
  }, [open, getCustomClaim]);
25848
25921
  const avatarLabel = userDisplayName || user2?.email || "Bandit";
25849
- const avatarInitials = (0, import_react35.useMemo)(() => deriveInitials2(avatarLabel), [avatarLabel]);
25922
+ const avatarInitials = (0, import_react36.useMemo)(() => deriveInitials2(avatarLabel), [avatarLabel]);
25850
25923
  const buildSnippet = (text, query, idx) => {
25851
25924
  const start = Math.max(0, idx - 40);
25852
25925
  const end = Math.min(text.length, idx + query.length + 60);
25853
25926
  return text.slice(start, end).replace(/\s+/g, " ").trim();
25854
25927
  };
25855
- (0, import_react35.useEffect)(() => {
25928
+ (0, import_react36.useEffect)(() => {
25856
25929
  if (open && !projectsHydrated) {
25857
25930
  hydrateProjects();
25858
25931
  }
25859
25932
  }, [open, projectsHydrated, hydrateProjects]);
25860
- (0, import_react35.useEffect)(() => {
25933
+ (0, import_react36.useEffect)(() => {
25861
25934
  if (projectsHydrated && !didInitCollapseRef.current) {
25862
25935
  didInitCollapseRef.current = true;
25863
25936
  if (projects && projects.length > 0) {
@@ -25865,7 +25938,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25865
25938
  }
25866
25939
  }
25867
25940
  }, [projectsHydrated, projects]);
25868
- const projectGroups = (0, import_react35.useMemo)(() => {
25941
+ const projectGroups = (0, import_react36.useMemo)(() => {
25869
25942
  const visibleConversations = conversations.filter(
25870
25943
  (conversation) => !deletedConversationIds.has(conversation.id) && !conversation.incognito
25871
25944
  );
@@ -25891,11 +25964,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
25891
25964
  }
25892
25965
  return groups.filter((group) => group.conversations.length > 0 || group.id !== null);
25893
25966
  }, [projects, conversations, collapsedProjects, deletedConversationIds]);
25894
- const visibleConversationCount = (0, import_react35.useMemo)(
25967
+ const visibleConversationCount = (0, import_react36.useMemo)(
25895
25968
  () => projectGroups.reduce((total, group) => total + group.conversations.length, 0),
25896
25969
  [projectGroups]
25897
25970
  );
25898
- const filteredProjectGroups = (0, import_react35.useMemo)(() => {
25971
+ const filteredProjectGroups = (0, import_react36.useMemo)(() => {
25899
25972
  if (!searchQuery.trim()) return projectGroups;
25900
25973
  const query = searchQuery.toLowerCase();
25901
25974
  return projectGroups.map((group) => {
@@ -25920,14 +25993,14 @@ var init_enhanced_mobile_conversations_modal = __esm({
25920
25993
  }).filter((group) => group.conversations.length > 0);
25921
25994
  }, [projectGroups, searchQuery]);
25922
25995
  const touchDragActive = Boolean(touchDragState.conversationId);
25923
- const getProjectIdFromPoint = (0, import_react35.useCallback)((clientX, clientY) => {
25996
+ const getProjectIdFromPoint = (0, import_react36.useCallback)((clientX, clientY) => {
25924
25997
  if (typeof document === "undefined") return null;
25925
25998
  const element = document.elementFromPoint(clientX, clientY);
25926
25999
  if (!element) return null;
25927
26000
  const projectNode = element.closest("[data-project-id]");
25928
26001
  return projectNode?.getAttribute("data-project-id") ?? null;
25929
26002
  }, []);
25930
- const handleTouchDragStart = (0, import_react35.useCallback)((conversation, touch) => {
26003
+ const handleTouchDragStart = (0, import_react36.useCallback)((conversation, touch) => {
25931
26004
  const initialHover = getProjectIdFromPoint(touch.clientX, touch.clientY);
25932
26005
  setTouchDragState({
25933
26006
  conversationId: conversation.id,
@@ -25935,7 +26008,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25935
26008
  hoverProjectId: initialHover ?? (conversation.projectId ?? null)
25936
26009
  });
25937
26010
  }, [getProjectIdFromPoint]);
25938
- const handleTouchDragMove = (0, import_react35.useCallback)((touch) => {
26011
+ const handleTouchDragMove = (0, import_react36.useCallback)((touch) => {
25939
26012
  setTouchDragState((prev) => {
25940
26013
  if (!prev.conversationId) return prev;
25941
26014
  const hoverId = getProjectIdFromPoint(touch.clientX, touch.clientY);
@@ -25943,7 +26016,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25943
26016
  return { ...prev, hoverProjectId: hoverId };
25944
26017
  });
25945
26018
  }, [getProjectIdFromPoint]);
25946
- const handleTouchDragEnd = (0, import_react35.useCallback)((touch) => {
26019
+ const handleTouchDragEnd = (0, import_react36.useCallback)((touch) => {
25947
26020
  setTouchDragState((prev) => {
25948
26021
  if (!prev.conversationId) {
25949
26022
  return { conversationId: null, originProjectId: null, hoverProjectId: null };
@@ -25971,11 +26044,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
25971
26044
  return { conversationId: null, originProjectId: null, hoverProjectId: null };
25972
26045
  });
25973
26046
  }, [getProjectIdFromPoint, moveConversationToProject]);
25974
- const activeDragConversation = (0, import_react35.useMemo)(() => {
26047
+ const activeDragConversation = (0, import_react36.useMemo)(() => {
25975
26048
  if (!touchDragState.conversationId) return null;
25976
26049
  return conversations.find((conv) => conv.id === touchDragState.conversationId) || null;
25977
26050
  }, [touchDragState.conversationId, conversations]);
25978
- const activeHoverLabel = (0, import_react35.useMemo)(() => {
26051
+ const activeHoverLabel = (0, import_react36.useMemo)(() => {
25979
26052
  if (!touchDragState.hoverProjectId) return "";
25980
26053
  if (touchDragState.hoverProjectId === "__ungrouped") return "Ungrouped";
25981
26054
  const project = projects.find((p) => p.id === touchDragState.hoverProjectId);
@@ -26024,7 +26097,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26024
26097
  setMoveModalOpen(false);
26025
26098
  setConversationToMove(null);
26026
26099
  };
26027
- (0, import_react35.useEffect)(() => {
26100
+ (0, import_react36.useEffect)(() => {
26028
26101
  setDeletedConversationIds((prev) => {
26029
26102
  let changed = false;
26030
26103
  const active2 = new Set(conversations.map((conv) => conv.id));
@@ -26049,6 +26122,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
26049
26122
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material26.Slide, { direction: "right", in: open, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
26050
26123
  import_material26.Box,
26051
26124
  {
26125
+ style: drag?.style,
26126
+ onTouchStart: drag?.onTouchStart,
26127
+ onTouchMove: drag?.onTouchMove,
26128
+ onTouchEnd: drag?.onTouchEnd,
26129
+ onTouchCancel: drag?.onTouchEnd,
26052
26130
  sx: {
26053
26131
  position: "fixed",
26054
26132
  top: 0,
@@ -26556,7 +26634,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26556
26634
  import_material26.Box,
26557
26635
  {
26558
26636
  onClick: user2 ? () => {
26559
- window.location.href = "/profile";
26637
+ safeNavigate("/profile");
26560
26638
  } : void 0,
26561
26639
  sx: {
26562
26640
  mt: "auto",
@@ -26632,7 +26710,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26632
26710
  title: "Management & settings",
26633
26711
  onClick: (event) => {
26634
26712
  event.stopPropagation();
26635
- window.location.href = managementPath;
26713
+ safeNavigate(managementPath);
26636
26714
  },
26637
26715
  sx: {
26638
26716
  flexShrink: 0,
@@ -26794,15 +26872,15 @@ var init_enhanced_mobile_conversations_modal = __esm({
26794
26872
  });
26795
26873
 
26796
26874
  // src/chat/chat-app-bar.tsx
26797
- var import_material27, import_react36, import_material28, import_react_router_dom2, import_shallow2, import_jsx_runtime29, CDN_BASE, banditHead2, modelAvatars2, ChatAppBar, chat_app_bar_default;
26875
+ var import_material27, import_react37, import_material28, import_react_router_dom3, import_shallow2, import_jsx_runtime29, CDN_BASE, banditHead2, modelAvatars2, ChatAppBar, chat_app_bar_default;
26798
26876
  var init_chat_app_bar = __esm({
26799
26877
  "src/chat/chat-app-bar.tsx"() {
26800
26878
  "use strict";
26801
26879
  import_material27 = require("@mui/material");
26802
26880
  init_modelStore();
26803
- import_react36 = require("react");
26881
+ import_react37 = require("react");
26804
26882
  import_material28 = require("@mui/material");
26805
- import_react_router_dom2 = require("react-router-dom");
26883
+ import_react_router_dom3 = require("react-router-dom");
26806
26884
  init_lucide_icons();
26807
26885
  init_conversation_drawer();
26808
26886
  init_enhanced_mobile_conversations_modal();
@@ -26834,14 +26912,15 @@ var init_chat_app_bar = __esm({
26834
26912
  drawerOpen,
26835
26913
  setDrawerOpen,
26836
26914
  mobileConversationsOpen,
26837
- onMobileConversationsOpenChange
26915
+ onMobileConversationsOpenChange,
26916
+ mobileConversationsDrag
26838
26917
  }) => {
26839
26918
  const theme = (0, import_material28.useTheme)();
26840
26919
  const isMobile = (0, import_material28.useMediaQuery)(theme.breakpoints.down("sm"));
26841
- const hasLoggedRouterWarningRef = (0, import_react36.useRef)(false);
26920
+ const hasLoggedRouterWarningRef = (0, import_react37.useRef)(false);
26842
26921
  let navigate = null;
26843
26922
  try {
26844
- navigate = (0, import_react_router_dom2.useNavigate)();
26923
+ navigate = (0, import_react_router_dom3.useNavigate)();
26845
26924
  } catch (error) {
26846
26925
  if (!hasLoggedRouterWarningRef.current) {
26847
26926
  debugLogger.warn("ChatAppBar: Navigation not available (missing Router context)", { error });
@@ -26868,17 +26947,17 @@ var init_chat_app_bar = __esm({
26868
26947
  menuBackground,
26869
26948
  menuText
26870
26949
  } = theme.palette.chat.appBar;
26871
- const [modelAnchorEl, setModelAnchorEl] = (0, import_react36.useState)(null);
26872
- const [engineAnchorEl, setEngineAnchorEl] = (0, import_react36.useState)(null);
26873
- const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react36.useState)(null);
26874
- const [internalModalOpen, setInternalModalOpen] = (0, import_react36.useState)(false);
26950
+ const [modelAnchorEl, setModelAnchorEl] = (0, import_react37.useState)(null);
26951
+ const [engineAnchorEl, setEngineAnchorEl] = (0, import_react37.useState)(null);
26952
+ const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react37.useState)(null);
26953
+ const [internalModalOpen, setInternalModalOpen] = (0, import_react37.useState)(false);
26875
26954
  const modalOpen = mobileConversationsOpen ?? internalModalOpen;
26876
26955
  const setModalOpen = (open) => {
26877
26956
  setInternalModalOpen(open);
26878
26957
  onMobileConversationsOpenChange?.(open);
26879
26958
  };
26880
- const [confirmModelChangeOpen, setConfirmModelChangeOpen] = (0, import_react36.useState)(false);
26881
- const [pendingModel, setPendingModel] = (0, import_react36.useState)(null);
26959
+ const [confirmModelChangeOpen, setConfirmModelChangeOpen] = (0, import_react37.useState)(false);
26960
+ const [pendingModel, setPendingModel] = (0, import_react37.useState)(null);
26882
26961
  const { conversations, currentId, createNewConversation, toggleIncognito, _hasHydrated } = useConversationStore();
26883
26962
  const { preferences } = usePreferencesStore();
26884
26963
  const { settings: packageSettings } = usePackageSettingsStore();
@@ -26888,7 +26967,7 @@ var init_chat_app_bar = __esm({
26888
26967
  syncEnabled: state.syncEnabled,
26889
26968
  setSyncEnabled: state.setSyncEnabled
26890
26969
  }), import_shallow2.shallow);
26891
- (0, import_react36.useEffect)(() => {
26970
+ (0, import_react37.useEffect)(() => {
26892
26971
  if (isPlaygroundMode3 && syncEnabled) {
26893
26972
  void setSyncEnabled(false).catch((error) => {
26894
26973
  debugLogger.warn("ChatAppBar: Failed to disable sync in playground", {
@@ -26943,7 +27022,7 @@ var init_chat_app_bar = __esm({
26943
27022
  const resolvedEngineId = currentEngine?.id ?? effectiveEngineId;
26944
27023
  const cleanEngineName = (name) => (name || "").replace(/\s*\([^)]*\)\s*$/, "").trim();
26945
27024
  const engineDisplay = cleanEngineName(currentEngine?.displayName) || "Engine";
26946
- (0, import_react36.useEffect)(() => {
27025
+ (0, import_react37.useEffect)(() => {
26947
27026
  useEngineStore.getState().fetchEngines();
26948
27027
  }, []);
26949
27028
  const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead2;
@@ -27186,7 +27265,7 @@ var init_chat_app_bar = __esm({
27186
27265
  }
27187
27266
  ),
27188
27267
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(conversation_drawer_default, { open: drawerOpen, onClose: () => setDrawerOpen(false) }),
27189
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(enhanced_mobile_conversations_modal_default, { open: modalOpen, onClose: () => setModalOpen(false) }),
27268
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(enhanced_mobile_conversations_modal_default, { open: modalOpen, onClose: () => setModalOpen(false), drag: mobileConversationsDrag }),
27190
27269
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
27191
27270
  import_material28.Dialog,
27192
27271
  {
@@ -27326,11 +27405,11 @@ Respond with just the title and nothing else.
27326
27405
  });
27327
27406
 
27328
27407
  // src/chat/query-suggestion-picker.tsx
27329
- var import_react37, import_material29, import_styles18, import_react_markdown3, import_remark_gfm3, import_rehype_raw3, import_jsx_runtime30, markdownComponents, QuerySuggestionPicker;
27408
+ var import_react38, import_material29, import_styles18, import_react_markdown3, import_remark_gfm3, import_rehype_raw3, import_jsx_runtime30, markdownComponents, QuerySuggestionPicker;
27330
27409
  var init_query_suggestion_picker = __esm({
27331
27410
  "src/chat/query-suggestion-picker.tsx"() {
27332
27411
  "use strict";
27333
- import_react37 = require("react");
27412
+ import_react38 = require("react");
27334
27413
  import_material29 = require("@mui/material");
27335
27414
  import_styles18 = require("@mui/material/styles");
27336
27415
  import_react_markdown3 = __toESM(require("react-markdown"));
@@ -27355,16 +27434,16 @@ var init_query_suggestion_picker = __esm({
27355
27434
  onSend,
27356
27435
  inputHeight
27357
27436
  }) => {
27358
- const hasGenerated = (0, import_react37.useRef)(false);
27359
- const [hasSentPrompt, setHasSentPrompt] = (0, import_react37.useState)(false);
27360
- const [examplePrompts, setExamplePrompts] = (0, import_react37.useState)([]);
27361
- const [visiblePrompts, setVisiblePrompts] = (0, import_react37.useState)([]);
27362
- const scrollRef = (0, import_react37.useRef)(null);
27437
+ const hasGenerated = (0, import_react38.useRef)(false);
27438
+ const [hasSentPrompt, setHasSentPrompt] = (0, import_react38.useState)(false);
27439
+ const [examplePrompts, setExamplePrompts] = (0, import_react38.useState)([]);
27440
+ const [visiblePrompts, setVisiblePrompts] = (0, import_react38.useState)([]);
27441
+ const scrollRef = (0, import_react38.useRef)(null);
27363
27442
  const theme = (0, import_styles18.useTheme)();
27364
27443
  const isMobile = (0, import_material29.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
27365
27444
  const { background, text, border, hoverBackground, hoverBorder } = theme.palette.chat.suggestion;
27366
27445
  const { getCurrentModel, isLoading } = useModelStore();
27367
- (0, import_react37.useEffect)(() => {
27446
+ (0, import_react38.useEffect)(() => {
27368
27447
  if (hasGenerated.current || isLoading) return;
27369
27448
  hasGenerated.current = true;
27370
27449
  const currentModel = getCurrentModel();
@@ -27397,12 +27476,12 @@ var init_query_suggestion_picker = __esm({
27397
27476
  hasGenerated.current = false;
27398
27477
  });
27399
27478
  }, [getCurrentModel, isLoading]);
27400
- (0, import_react37.useEffect)(() => {
27479
+ (0, import_react38.useEffect)(() => {
27401
27480
  if (!isLoading) {
27402
27481
  hasGenerated.current = false;
27403
27482
  }
27404
27483
  }, [isLoading]);
27405
- (0, import_react37.useEffect)(() => {
27484
+ (0, import_react38.useEffect)(() => {
27406
27485
  if (hasSentPrompt || examplePrompts.length === 0) return;
27407
27486
  const interval = setInterval(() => {
27408
27487
  setExamplePrompts((prev) => {
@@ -29978,17 +30057,17 @@ var init_themeMap = __esm({
29978
30057
  });
29979
30058
 
29980
30059
  // src/components/UnderReview.tsx
29981
- var import_material30, import_react_router_dom3, import_jsx_runtime31, UnderReview, UnderReview_default;
30060
+ var import_material30, import_react_router_dom4, import_jsx_runtime31, UnderReview, UnderReview_default;
29982
30061
  var init_UnderReview = __esm({
29983
30062
  "src/components/UnderReview.tsx"() {
29984
30063
  "use strict";
29985
30064
  import_material30 = require("@mui/material");
29986
- import_react_router_dom3 = require("react-router-dom");
30065
+ import_react_router_dom4 = require("react-router-dom");
29987
30066
  init_authenticationService();
29988
30067
  import_jsx_runtime31 = require("react/jsx-runtime");
29989
30068
  UnderReview = () => {
29990
30069
  const theme = (0, import_material30.useTheme)();
29991
- const navigate = (0, import_react_router_dom3.useNavigate)();
30070
+ const navigate = (0, import_react_router_dom4.useNavigate)();
29992
30071
  const handleResetSession = () => {
29993
30072
  authenticationService2.clearToken();
29994
30073
  navigate("/login");
@@ -30052,11 +30131,11 @@ var init_UnderReview = __esm({
30052
30131
  });
30053
30132
 
30054
30133
  // src/components/feedback/FeedbackPulse.tsx
30055
- var import_react38, import_material31, import_styles32, import_lucide_react13, import_jsx_runtime32, STORAGE_KEY3, COOLDOWN_DAYS, MIN_SESSION_MS, MIN_MESSAGES_SENT, CHECK_INTERVAL_MS, readLastInteraction, recordInteraction, FeedbackPulse, FeedbackPulse_default;
30134
+ var import_react39, import_material31, import_styles32, import_lucide_react13, import_jsx_runtime32, STORAGE_KEY3, COOLDOWN_DAYS, MIN_SESSION_MS, MIN_MESSAGES_SENT, CHECK_INTERVAL_MS, readLastInteraction, recordInteraction, FeedbackPulse, FeedbackPulse_default;
30056
30135
  var init_FeedbackPulse = __esm({
30057
30136
  "src/components/feedback/FeedbackPulse.tsx"() {
30058
30137
  "use strict";
30059
- import_react38 = require("react");
30138
+ import_react39 = require("react");
30060
30139
  import_material31 = require("@mui/material");
30061
30140
  import_styles32 = require("@mui/material/styles");
30062
30141
  import_lucide_react13 = require("lucide-react");
@@ -30085,21 +30164,21 @@ var init_FeedbackPulse = __esm({
30085
30164
  };
30086
30165
  FeedbackPulse = ({ isMobile, feedbackEmail }) => {
30087
30166
  const theme = (0, import_styles32.useTheme)();
30088
- const [visible, setVisible] = (0, import_react38.useState)(false);
30089
- const [thanked, setThanked] = (0, import_react38.useState)(false);
30090
- const [modalOpen, setModalOpen] = (0, import_react38.useState)(false);
30091
- const mountedAtRef = (0, import_react38.useRef)(Date.now());
30092
- const baselineMessagesRef = (0, import_react38.useRef)(null);
30167
+ const [visible, setVisible] = (0, import_react39.useState)(false);
30168
+ const [thanked, setThanked] = (0, import_react39.useState)(false);
30169
+ const [modalOpen, setModalOpen] = (0, import_react39.useState)(false);
30170
+ const mountedAtRef = (0, import_react39.useRef)(Date.now());
30171
+ const baselineMessagesRef = (0, import_react39.useRef)(null);
30093
30172
  const totalMessages = useConversationStore(
30094
30173
  (s) => s.conversations.reduce((n, c) => n + c.history.length, 0)
30095
30174
  );
30096
30175
  const hydrated = useConversationStore((s) => s._hasHydrated);
30097
- (0, import_react38.useEffect)(() => {
30176
+ (0, import_react39.useEffect)(() => {
30098
30177
  if (hydrated && baselineMessagesRef.current === null) {
30099
30178
  baselineMessagesRef.current = totalMessages;
30100
30179
  }
30101
30180
  }, [hydrated, totalMessages]);
30102
- (0, import_react38.useEffect)(() => {
30181
+ (0, import_react39.useEffect)(() => {
30103
30182
  const cooldownMs = COOLDOWN_DAYS * 24 * 60 * 60 * 1e3;
30104
30183
  const forced = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("feedbackPulse");
30105
30184
  const check = () => {
@@ -30217,16 +30296,16 @@ var init_FeedbackPulse = __esm({
30217
30296
  });
30218
30297
 
30219
30298
  // src/hooks/useNotificationService.ts
30220
- var import_react39, useNotificationService;
30299
+ var import_react40, useNotificationService;
30221
30300
  var init_useNotificationService = __esm({
30222
30301
  "src/hooks/useNotificationService.ts"() {
30223
30302
  "use strict";
30224
- import_react39 = require("react");
30303
+ import_react40 = require("react");
30225
30304
  init_NotificationProvider();
30226
30305
  init_notificationService();
30227
30306
  useNotificationService = () => {
30228
30307
  const notificationContext = useNotification();
30229
- (0, import_react39.useEffect)(() => {
30308
+ (0, import_react40.useEffect)(() => {
30230
30309
  notificationService.setContext(notificationContext);
30231
30310
  }, [notificationContext]);
30232
30311
  return {
@@ -30333,11 +30412,11 @@ var init_ConnectionStatus = __esm({
30333
30412
  });
30334
30413
 
30335
30414
  // src/hooks/useVoiceMode.ts
30336
- var import_react40, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
30415
+ var import_react41, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
30337
30416
  var init_useVoiceMode = __esm({
30338
30417
  "src/hooks/useVoiceMode.ts"() {
30339
30418
  "use strict";
30340
- import_react40 = require("react");
30419
+ import_react41 = require("react");
30341
30420
  init_stt_client();
30342
30421
  init_debugLogger();
30343
30422
  init_voiceModeStore();
@@ -30370,11 +30449,11 @@ var init_useVoiceMode = __esm({
30370
30449
  const setError = useVoiceModeStore((state) => state.setError);
30371
30450
  const resetTransientState = useVoiceModeStore((state) => state.resetTransientState);
30372
30451
  const setLastTranscript = useVoiceModeStore((state) => state.setLastTranscript);
30373
- const configRef = (0, import_react40.useRef)(config);
30374
- (0, import_react40.useEffect)(() => {
30452
+ const configRef = (0, import_react41.useRef)(config);
30453
+ (0, import_react41.useEffect)(() => {
30375
30454
  configRef.current = config;
30376
30455
  }, [config]);
30377
- (0, import_react40.useEffect)(() => {
30456
+ (0, import_react41.useEffect)(() => {
30378
30457
  if (!enabled) {
30379
30458
  return () => void 0;
30380
30459
  }
@@ -30635,11 +30714,11 @@ var chat_exports = {};
30635
30714
  __export(chat_exports, {
30636
30715
  default: () => chat_default
30637
30716
  });
30638
- var import_react41, import_material33, import_styles33, import_react_router_dom4, import_lucide_react14, import_jsx_runtime34, ChatContent, Chat, chat_default;
30717
+ var import_react42, import_material33, import_styles33, import_react_router_dom5, import_lucide_react14, import_jsx_runtime34, ChatContent, Chat, chat_default;
30639
30718
  var init_chat2 = __esm({
30640
30719
  "src/chat/chat.tsx"() {
30641
30720
  "use strict";
30642
- import_react41 = require("react");
30721
+ import_react42 = require("react");
30643
30722
  init_custom_logo();
30644
30723
  init_indexedDBService();
30645
30724
  import_material33 = require("@mui/material");
@@ -30648,7 +30727,7 @@ var init_chat2 = __esm({
30648
30727
  init_modelStore();
30649
30728
  init_canvasStore();
30650
30729
  init_canvas_panel();
30651
- import_react_router_dom4 = require("react-router-dom");
30730
+ import_react_router_dom5 = require("react-router-dom");
30652
30731
  init_chat_scroll_to_bottom_button();
30653
30732
  init_bandit_chat_logo();
30654
30733
  init_chat_messages();
@@ -30681,6 +30760,8 @@ var init_chat2 = __esm({
30681
30760
  init_voiceModeStore();
30682
30761
  init_ttsSanitizer();
30683
30762
  init_FeatureFlagContext();
30763
+ init_knowledgeStore();
30764
+ init_lucide_icons();
30684
30765
  import_lucide_react14 = require("lucide-react");
30685
30766
  import_jsx_runtime34 = require("react/jsx-runtime");
30686
30767
  ChatContent = () => {
@@ -30691,12 +30772,12 @@ var init_chat2 = __esm({
30691
30772
  const ossMode = isOSSMode() || !packageSettings?.featureFlags?.subscriptionType;
30692
30773
  const playgroundBypassAccess = packageSettings?.playgroundBypassAuth || typeof window !== "undefined" && window.location.pathname.includes("/playground");
30693
30774
  const notificationService2 = useNotificationService();
30694
- const [selectedTheme, setSelectedTheme] = (0, import_react41.useState)(null);
30695
- const [themeLoading, setThemeLoading] = (0, import_react41.useState)(true);
30775
+ const [selectedTheme, setSelectedTheme] = (0, import_react42.useState)(null);
30776
+ const [themeLoading, setThemeLoading] = (0, import_react42.useState)(true);
30696
30777
  const token = authenticationService2.getToken();
30697
30778
  const claims = token ? authenticationService2.parseJwtClaims(token) : null;
30698
30779
  const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
30699
- const banditTheme = (0, import_react41.useMemo)(() => {
30780
+ const banditTheme = (0, import_react42.useMemo)(() => {
30700
30781
  return (0, import_styles33.createTheme)(baseTheme, {
30701
30782
  components: {
30702
30783
  MuiInputBase: {
@@ -30744,12 +30825,12 @@ var init_chat2 = __esm({
30744
30825
  } = useVoiceStore();
30745
30826
  const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);
30746
30827
  const canvasOpen = useCanvasStore((state) => state.open);
30747
- const previousVoiceModeEnabledRef = (0, import_react41.useRef)(isVoiceModeEnabled);
30748
- const historyRef = (0, import_react41.useRef)(history);
30749
- (0, import_react41.useEffect)(() => {
30828
+ const previousVoiceModeEnabledRef = (0, import_react42.useRef)(isVoiceModeEnabled);
30829
+ const historyRef = (0, import_react42.useRef)(history);
30830
+ (0, import_react42.useEffect)(() => {
30750
30831
  historyRef.current = history;
30751
30832
  }, [history]);
30752
- (0, import_react41.useEffect)(() => {
30833
+ (0, import_react42.useEffect)(() => {
30753
30834
  if (!hydrated) return;
30754
30835
  const params = new URLSearchParams(window.location.search);
30755
30836
  const title = params.get("title") || "";
@@ -30765,7 +30846,7 @@ var init_chat2 = __esm({
30765
30846
  stop: ttsStop,
30766
30847
  isAvailable: isTTSAvailable
30767
30848
  } = useTTS();
30768
- (0, import_react41.useEffect)(() => {
30849
+ (0, import_react42.useEffect)(() => {
30769
30850
  const timer = setTimeout(() => {
30770
30851
  const isAuthenticated = authenticationService2.isAuthenticated();
30771
30852
  if (!initialized || availableVoices.length === 0) {
@@ -30779,7 +30860,7 @@ var init_chat2 = __esm({
30779
30860
  }, 500);
30780
30861
  return () => clearTimeout(timer);
30781
30862
  }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
30782
- (0, import_react41.useEffect)(() => {
30863
+ (0, import_react42.useEffect)(() => {
30783
30864
  const isAuthenticated = authenticationService2.isAuthenticated();
30784
30865
  if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
30785
30866
  if (token && isAuthenticated) {
@@ -30791,19 +30872,82 @@ var init_chat2 = __esm({
30791
30872
  }
30792
30873
  }, [packageSettings?.gatewayApiUrl, availableVoices.length, initialized, loadVoicesFromAPI, token]);
30793
30874
  const provider = useAIProviderStore((state) => state.provider);
30794
- const inputRef = (0, import_react41.useRef)(null);
30795
- const [pastedImages, setPastedImages] = (0, import_react41.useState)([]);
30796
- const inputContainerRef = (0, import_react41.useRef)(null);
30797
- const [inputHeight, setInputHeight] = (0, import_react41.useState)(80);
30798
- const [isSubmitting, setIsSubmitting] = (0, import_react41.useState)(false);
30799
- const [pendingMessage, setPendingMessage] = (0, import_react41.useState)(null);
30875
+ const inputRef = (0, import_react42.useRef)(null);
30876
+ const [pastedImages, setPastedImages] = (0, import_react42.useState)([]);
30877
+ const inputContainerRef = (0, import_react42.useRef)(null);
30878
+ const [inputHeight, setInputHeight] = (0, import_react42.useState)(80);
30879
+ const [isSubmitting, setIsSubmitting] = (0, import_react42.useState)(false);
30880
+ const [pendingMessage, setPendingMessage] = (0, import_react42.useState)(null);
30800
30881
  const { conversations, currentId, _hasHydrated, hydrate, toggleIncognito } = useConversationStore();
30801
30882
  const isTemporaryChat = Boolean(conversations.find((c) => c.id === currentId)?.incognito);
30802
- const [isMobile, setIsMobile] = (0, import_react41.useState)(false);
30803
- const [drawerOpen, setDrawerOpen] = (0, import_react41.useState)(false);
30804
- const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react41.useState)(false);
30805
- const cardSwipeStartXRef = (0, import_react41.useRef)(null);
30806
- (0, import_react41.useEffect)(() => {
30883
+ const [isMobile, setIsMobile] = (0, import_react42.useState)(false);
30884
+ const [drawerOpen, setDrawerOpen] = (0, import_react42.useState)(false);
30885
+ const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react42.useState)(false);
30886
+ const cardSwipeStartXRef = (0, import_react42.useRef)(null);
30887
+ const dragStartRef = (0, import_react42.useRef)(null);
30888
+ const [drawerDragX, setDrawerDragX] = (0, import_react42.useState)(null);
30889
+ const [drawerSettling, setDrawerSettling] = (0, import_react42.useState)(false);
30890
+ const [drawerSwap, setDrawerSwap] = (0, import_react42.useState)(false);
30891
+ const drawerOpenOffset = () => (typeof window === "undefined" ? 360 : Math.min(window.innerWidth - 56, 360)) - 12;
30892
+ const drawerDragStart = (e) => {
30893
+ const t = e.touches[0];
30894
+ if (!t) return;
30895
+ dragStartRef.current = { x: t.clientX, y: t.clientY, t: performance.now(), axis: null };
30896
+ };
30897
+ const drawerDragMove = (e) => {
30898
+ const s = dragStartRef.current;
30899
+ const t = e.touches[0];
30900
+ if (!s || !t) return;
30901
+ const dx = t.clientX - s.x;
30902
+ const dy = t.clientY - s.y;
30903
+ if (s.axis === null) {
30904
+ if (Math.abs(dx) < 8 && Math.abs(dy) < 8) return;
30905
+ s.axis = Math.abs(dx) > Math.abs(dy) ? "x" : "y";
30906
+ }
30907
+ if (s.axis !== "x") return;
30908
+ setDrawerDragX(dx < 0 ? Math.max(dx, -drawerOpenOffset()) : dx * 0.15);
30909
+ };
30910
+ const drawerDragEnd = () => {
30911
+ const s = dragStartRef.current;
30912
+ dragStartRef.current = null;
30913
+ if (!s || s.axis !== "x" || drawerDragX === null) {
30914
+ setDrawerDragX(null);
30915
+ return;
30916
+ }
30917
+ const dt = Math.max(1, performance.now() - s.t);
30918
+ const velocity = drawerDragX / dt;
30919
+ const offset = drawerOpenOffset();
30920
+ const shouldClose = drawerDragX < -offset * 0.35 || velocity < -0.45;
30921
+ if (shouldClose) {
30922
+ setDrawerSettling(true);
30923
+ setDrawerDragX(-offset);
30924
+ window.setTimeout(() => {
30925
+ setDrawerSwap(true);
30926
+ setMobileConversationsOpen(false);
30927
+ requestAnimationFrame(() => requestAnimationFrame(() => setDrawerSwap(false)));
30928
+ window.setTimeout(() => {
30929
+ setDrawerDragX(null);
30930
+ setDrawerSettling(false);
30931
+ }, 320);
30932
+ }, 220);
30933
+ } else {
30934
+ setDrawerSettling(true);
30935
+ setDrawerDragX(0);
30936
+ window.setTimeout(() => {
30937
+ setDrawerDragX(null);
30938
+ setDrawerSettling(false);
30939
+ }, 220);
30940
+ }
30941
+ };
30942
+ const drawerDragStyle = drawerSwap ? { translate: "0px 0", transition: "none" } : isMobile && mobileConversationsOpen && drawerDragX !== null ? {
30943
+ translate: `${drawerDragX}px 0`,
30944
+ transition: drawerSettling ? "translate 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)" : "none"
30945
+ } : void 0;
30946
+ const drawerPanelDragStyle = isMobile && drawerDragX !== null ? {
30947
+ translate: `${drawerDragX}px 0`,
30948
+ transition: drawerSettling ? "translate 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)" : "none"
30949
+ } : void 0;
30950
+ (0, import_react42.useEffect)(() => {
30807
30951
  if (typeof document === "undefined") return;
30808
30952
  const meta = document.querySelector('meta[name="theme-color"]');
30809
30953
  if (!meta) return;
@@ -30821,27 +30965,50 @@ var init_chat2 = __esm({
30821
30965
  const chatContainerEl = chatContainerRef.current;
30822
30966
  const scrollTargetEl = scrollTargetRef.current;
30823
30967
  const { isSlowConnection, connectionQuality, trackRequestStart, trackRequestEnd } = useNetworkStatus();
30824
- const [showScrollToBottom, setShowScrollToBottom] = (0, import_react41.useState)(false);
30825
- const [streamBuffer, setStreamBuffer] = (0, import_react41.useState)("");
30826
- const [responseStarted, setResponseStarted] = (0, import_react41.useState)(false);
30827
- const [isStreaming, setIsStreaming] = (0, import_react41.useState)(false);
30828
- const [isThinking, setIsThinking] = (0, import_react41.useState)(false);
30968
+ const [showScrollToBottom, setShowScrollToBottom] = (0, import_react42.useState)(false);
30969
+ const [streamBuffer, setStreamBuffer] = (0, import_react42.useState)("");
30970
+ const [responseStarted, setResponseStarted] = (0, import_react42.useState)(false);
30971
+ const [isStreaming, setIsStreaming] = (0, import_react42.useState)(false);
30972
+ const [isThinking, setIsThinking] = (0, import_react42.useState)(false);
30829
30973
  const initialLogoState = history.length === 0;
30830
- const [logoVisible, setLogoVisible] = (0, import_react41.useState)(initialLogoState);
30831
- const [logoShouldRender, setLogoShouldRender] = (0, import_react41.useState)(initialLogoState);
30832
- const streamingGraceUntilRef = (0, import_react41.useRef)(0);
30974
+ const [logoVisible, setLogoVisible] = (0, import_react42.useState)(initialLogoState);
30975
+ const [logoShouldRender, setLogoShouldRender] = (0, import_react42.useState)(initialLogoState);
30976
+ const streamingGraceUntilRef = (0, import_react42.useRef)(0);
30833
30977
  const GRACE_MS = 450;
30834
30978
  const GRACE_OFFSET_DESKTOP = 28;
30835
30979
  const GRACE_OFFSET_MOBILE = 20;
30836
- const followStreamRef = (0, import_react41.useRef)(true);
30837
- const lastSpokenResponseRef = (0, import_react41.useRef)(null);
30838
- const previousConversationIdRef = (0, import_react41.useRef)(null);
30839
- const logoFadeTimeoutRef = (0, import_react41.useRef)(null);
30840
- const [branding, setBranding] = (0, import_react41.useState)(null);
30841
- const [brandingLoading, setBrandingLoading] = (0, import_react41.useState)(true);
30842
- const isBrandingLoadInProgressRef = (0, import_react41.useRef)(false);
30980
+ const followStreamRef = (0, import_react42.useRef)(true);
30981
+ const lastSpokenResponseRef = (0, import_react42.useRef)(null);
30982
+ const previousConversationIdRef = (0, import_react42.useRef)(null);
30983
+ const logoFadeTimeoutRef = (0, import_react42.useRef)(null);
30984
+ const [branding, setBranding] = (0, import_react42.useState)(null);
30985
+ const [brandingLoading, setBrandingLoading] = (0, import_react42.useState)(true);
30986
+ const isBrandingLoadInProgressRef = (0, import_react42.useRef)(false);
30843
30987
  const logoOnly = history.length === 0 && !brandingLoading;
30844
- (0, import_react41.useEffect)(() => {
30988
+ const knowledgeDocs = useKnowledgeStore((s) => s.docs);
30989
+ const knowledgeLoaded = useKnowledgeStore((s) => s.isLoaded);
30990
+ const [knowledgeNudgeDismissed, setKnowledgeNudgeDismissed] = (0, import_react42.useState)(() => {
30991
+ try {
30992
+ return localStorage.getItem("bandit.knowledgeNudge.dismissed") === "true";
30993
+ } catch {
30994
+ return false;
30995
+ }
30996
+ });
30997
+ const dismissKnowledgeNudge = (0, import_react42.useCallback)(() => {
30998
+ setKnowledgeNudgeDismissed(true);
30999
+ try {
31000
+ localStorage.setItem("bandit.knowledgeNudge.dismissed", "true");
31001
+ } catch {
31002
+ }
31003
+ }, []);
31004
+ const showKnowledgeNudge = logoOnly && !knowledgeNudgeDismissed && knowledgeLoaded && knowledgeDocs.length === 0 && featureFlag.hasFeature("documentKnowledge");
31005
+ const knowledgePath = typeof window !== "undefined" && window.location.pathname.startsWith("/playground") ? "/playground/management" : "/management";
31006
+ const safeNavigateTo = (to) => {
31007
+ if (typeof window !== "undefined") {
31008
+ window.location.assign(to);
31009
+ }
31010
+ };
31011
+ (0, import_react42.useEffect)(() => {
30845
31012
  const isEmptyConversation = (history?.length ?? 0) === 0;
30846
31013
  const isSending = Boolean(pendingMessage);
30847
31014
  const shouldShowLogo = isEmptyConversation && !isSending;
@@ -30871,7 +31038,7 @@ var init_chat2 = __esm({
30871
31038
  }, 500);
30872
31039
  }
30873
31040
  }, [history, pendingMessage]);
30874
- (0, import_react41.useEffect)(() => {
31041
+ (0, import_react42.useEffect)(() => {
30875
31042
  if (!brandingLoading && !themeLoading) {
30876
31043
  return;
30877
31044
  }
@@ -30887,18 +31054,18 @@ var init_chat2 = __esm({
30887
31054
  }, 2500);
30888
31055
  return () => window.clearTimeout(timeoutId);
30889
31056
  }, [brandingLoading, themeLoading, selectedTheme]);
30890
- (0, import_react41.useEffect)(() => () => {
31057
+ (0, import_react42.useEffect)(() => () => {
30891
31058
  if (logoFadeTimeoutRef.current) {
30892
31059
  window.clearTimeout(logoFadeTimeoutRef.current);
30893
31060
  logoFadeTimeoutRef.current = null;
30894
31061
  }
30895
31062
  }, []);
30896
- (0, import_react41.useEffect)(() => {
31063
+ (0, import_react42.useEffect)(() => {
30897
31064
  if (isStreaming && streamBuffer.trim() === "") {
30898
31065
  streamingGraceUntilRef.current = Date.now() + GRACE_MS;
30899
31066
  }
30900
31067
  }, [isStreaming, streamBuffer]);
30901
- (0, import_react41.useEffect)(() => {
31068
+ (0, import_react42.useEffect)(() => {
30902
31069
  if (!isStreaming) return;
30903
31070
  const container = chatContainerRef.current;
30904
31071
  if (!container) return;
@@ -30909,13 +31076,13 @@ var init_chat2 = __esm({
30909
31076
  container.scrollTo({ top: targetTop, behavior: "smooth" });
30910
31077
  }
30911
31078
  }, [streamBuffer, isStreaming, isMobile, chatContainerRef]);
30912
- (0, import_react41.useEffect)(() => {
31079
+ (0, import_react42.useEffect)(() => {
30913
31080
  if (!_hasHydrated) {
30914
31081
  debugLogger.info("Chat component triggering conversation store hydration");
30915
31082
  hydrate();
30916
31083
  }
30917
31084
  }, [_hasHydrated, hydrate]);
30918
- (0, import_react41.useEffect)(() => {
31085
+ (0, import_react42.useEffect)(() => {
30919
31086
  const loadBrandingAndTheme = async () => {
30920
31087
  if (isBrandingLoadInProgressRef.current) {
30921
31088
  debugLogger.warn("Branding loading already in progress, skipping");
@@ -31104,7 +31271,7 @@ var init_chat2 = __esm({
31104
31271
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
31105
31272
  };
31106
31273
  }, []);
31107
- (0, import_react41.useEffect)(() => {
31274
+ (0, import_react42.useEffect)(() => {
31108
31275
  if (!chatContainerEl) return;
31109
31276
  const blurInputOnTouchScroll = () => {
31110
31277
  if (document.activeElement === inputRef.current) inputRef.current?.blur();
@@ -31112,13 +31279,13 @@ var init_chat2 = __esm({
31112
31279
  chatContainerEl.addEventListener("touchmove", blurInputOnTouchScroll, { passive: true });
31113
31280
  return () => chatContainerEl.removeEventListener("touchmove", blurInputOnTouchScroll);
31114
31281
  }, [chatContainerEl]);
31115
- (0, import_react41.useEffect)(() => {
31282
+ (0, import_react42.useEffect)(() => {
31116
31283
  const handleResize = () => setIsMobile(window.innerWidth <= 768);
31117
31284
  handleResize();
31118
31285
  window.addEventListener("resize", handleResize);
31119
31286
  return () => window.removeEventListener("resize", handleResize);
31120
31287
  }, []);
31121
- (0, import_react41.useEffect)(() => {
31288
+ (0, import_react42.useEffect)(() => {
31122
31289
  const setViewportHeight = () => {
31123
31290
  document.documentElement.style.setProperty(
31124
31291
  "--vh",
@@ -31129,7 +31296,7 @@ var init_chat2 = __esm({
31129
31296
  window.addEventListener("resize", setViewportHeight);
31130
31297
  return () => window.removeEventListener("resize", setViewportHeight);
31131
31298
  }, []);
31132
- (0, import_react41.useEffect)(() => {
31299
+ (0, import_react42.useEffect)(() => {
31133
31300
  if (!chatContainerEl) return;
31134
31301
  let rafId = null;
31135
31302
  const update = () => {
@@ -31148,7 +31315,7 @@ var init_chat2 = __esm({
31148
31315
  chatContainerEl.removeEventListener(SCROLL_STATE_CHANGED_EVENT, update);
31149
31316
  };
31150
31317
  }, [chatContainerEl, getScrollState]);
31151
- (0, import_react41.useEffect)(() => {
31318
+ (0, import_react42.useEffect)(() => {
31152
31319
  if (!chatContainerEl) return;
31153
31320
  let observer = null;
31154
31321
  let rafId = null;
@@ -31183,7 +31350,7 @@ var init_chat2 = __esm({
31183
31350
  if (observer) observer.disconnect();
31184
31351
  };
31185
31352
  }, [chatContainerEl, scrollTargetEl, scrollTargetRef, getScrollState, inputHeight, history.length]);
31186
- (0, import_react41.useEffect)(() => {
31353
+ (0, import_react42.useEffect)(() => {
31187
31354
  const isTransitioning = isStreaming || streamBuffer.trim() === "";
31188
31355
  const delay = isTransitioning ? 400 : 100;
31189
31356
  const timer = setTimeout(() => {
@@ -31192,7 +31359,7 @@ var init_chat2 = __esm({
31192
31359
  }, delay);
31193
31360
  return () => clearTimeout(timer);
31194
31361
  }, [history, streamBuffer, getScrollState, isStreaming]);
31195
- (0, import_react41.useLayoutEffect)(() => {
31362
+ (0, import_react42.useLayoutEffect)(() => {
31196
31363
  const scrollState = getScrollState();
31197
31364
  const now = Date.now();
31198
31365
  if (isStreaming && scrollState.shouldAutoScroll && followStreamRef.current) {
@@ -31226,7 +31393,7 @@ var init_chat2 = __esm({
31226
31393
  return () => clearTimeout(scrollTimer);
31227
31394
  }
31228
31395
  }, [history, isStreaming, scrollToBottom, getScrollState, isMobile, chatContainerRef]);
31229
- (0, import_react41.useEffect)(() => {
31396
+ (0, import_react42.useEffect)(() => {
31230
31397
  const observer = new ResizeObserver(() => {
31231
31398
  if (inputContainerRef.current)
31232
31399
  setInputHeight(inputContainerRef.current.offsetHeight);
@@ -31237,7 +31404,7 @@ var init_chat2 = __esm({
31237
31404
  }
31238
31405
  return () => observer.disconnect();
31239
31406
  }, []);
31240
- (0, import_react41.useEffect)(() => {
31407
+ (0, import_react42.useEffect)(() => {
31241
31408
  if (!hydrated || !_hasHydrated) return;
31242
31409
  if (currentId === null) {
31243
31410
  useAIQueryStore.setState({ history: [] });
@@ -31286,7 +31453,7 @@ var init_chat2 = __esm({
31286
31453
  setResponse,
31287
31454
  setComponentStatus
31288
31455
  ]);
31289
- (0, import_react41.useEffect)(() => {
31456
+ (0, import_react42.useEffect)(() => {
31290
31457
  debugLogger.info("Chat component conversation state", {
31291
31458
  hasHydrated: _hasHydrated,
31292
31459
  conversationCount: conversations.length,
@@ -31295,7 +31462,7 @@ var init_chat2 = __esm({
31295
31462
  storeState: "main-chat"
31296
31463
  });
31297
31464
  }, [_hasHydrated, conversations, currentId]);
31298
- (0, import_react41.useEffect)(() => {
31465
+ (0, import_react42.useEffect)(() => {
31299
31466
  if (!_hasHydrated || !chatContainerEl) return;
31300
31467
  let rafId = null;
31301
31468
  const sync = () => {
@@ -31330,7 +31497,7 @@ var init_chat2 = __esm({
31330
31497
  notificationService2?.handleHttpError(error);
31331
31498
  }
31332
31499
  });
31333
- const handleStop = (0, import_react41.useCallback)(() => {
31500
+ const handleStop = (0, import_react42.useCallback)(() => {
31334
31501
  try {
31335
31502
  aiProvider.cancel();
31336
31503
  } catch (error) {
@@ -31339,7 +31506,7 @@ var init_chat2 = __esm({
31339
31506
  });
31340
31507
  }
31341
31508
  }, [aiProvider]);
31342
- const handleVoiceInterrupt = (0, import_react41.useCallback)(() => {
31509
+ const handleVoiceInterrupt = (0, import_react42.useCallback)(() => {
31343
31510
  try {
31344
31511
  ttsStop();
31345
31512
  } catch (error) {
@@ -31358,7 +31525,7 @@ var init_chat2 = __esm({
31358
31525
  handleStop();
31359
31526
  }
31360
31527
  }, [ttsStop, isStreaming, handleStop]);
31361
- const handleSend = (0, import_react41.useCallback)(
31528
+ const handleSend = (0, import_react42.useCallback)(
31362
31529
  (question, images, displayQuestion) => {
31363
31530
  const requestStartTime = trackRequestStart();
31364
31531
  const questionForDisplay = displayQuestion || question;
@@ -31468,7 +31635,7 @@ var init_chat2 = __esm({
31468
31635
  trackRequestStart
31469
31636
  ]
31470
31637
  );
31471
- const handleVoiceTranscription = (0, import_react41.useCallback)(
31638
+ const handleVoiceTranscription = (0, import_react42.useCallback)(
31472
31639
  (text) => {
31473
31640
  const cleaned = text.trim();
31474
31641
  if (!cleaned) {
@@ -31485,7 +31652,7 @@ var init_chat2 = __esm({
31485
31652
  onInterrupt: handleVoiceInterrupt,
31486
31653
  onError: (message) => notificationService2?.showError?.(message)
31487
31654
  });
31488
- (0, import_react41.useEffect)(() => {
31655
+ (0, import_react42.useEffect)(() => {
31489
31656
  const previouslyEnabled = previousVoiceModeEnabledRef.current;
31490
31657
  previousVoiceModeEnabledRef.current = isVoiceModeEnabled;
31491
31658
  if (!previouslyEnabled && isVoiceModeEnabled) {
@@ -31510,7 +31677,7 @@ var init_chat2 = __esm({
31510
31677
  }
31511
31678
  }
31512
31679
  }, [isVoiceModeEnabled, ttsStop]);
31513
- (0, import_react41.useEffect)(() => {
31680
+ (0, import_react42.useEffect)(() => {
31514
31681
  if (!isVoiceModeEnabled || !isStreaming) {
31515
31682
  return;
31516
31683
  }
@@ -31530,7 +31697,7 @@ var init_chat2 = __esm({
31530
31697
  }
31531
31698
  lastSpokenResponseRef.current = null;
31532
31699
  }, [isStreaming, isVoiceModeEnabled, ttsStop]);
31533
- (0, import_react41.useEffect)(() => {
31700
+ (0, import_react42.useEffect)(() => {
31534
31701
  if (!isVoiceModeEnabled) {
31535
31702
  lastSpokenResponseRef.current = null;
31536
31703
  return;
@@ -31571,13 +31738,13 @@ var init_chat2 = __esm({
31571
31738
  cancelled = true;
31572
31739
  };
31573
31740
  }, [history, isStreaming, isVoiceModeEnabled, isTTSAvailable, ttsSpeak]);
31574
- const handleModelChange = (0, import_react41.useCallback)(
31741
+ const handleModelChange = (0, import_react42.useCallback)(
31575
31742
  (modelId) => {
31576
31743
  setSelectedModel(modelId);
31577
31744
  },
31578
31745
  [setSelectedModel]
31579
31746
  );
31580
- const handleVoiceChange = (0, import_react41.useCallback)(async (voiceId) => {
31747
+ const handleVoiceChange = (0, import_react42.useCallback)(async (voiceId) => {
31581
31748
  ttsStop();
31582
31749
  stopTTS();
31583
31750
  setSelectedVoice(voiceId);
@@ -31687,27 +31854,23 @@ var init_chat2 = __esm({
31687
31854
  // is the same near-black as the shell.
31688
31855
  border: isMobile && mobileConversationsOpen ? `1px solid ${theme.palette.mode === "dark" ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)"}` : "none",
31689
31856
  boxShadow: isMobile && mobileConversationsOpen ? `0 12px 40px ${theme.palette.mode === "dark" ? "rgba(0,0,0,0.55)" : "rgba(0,0,0,0.25)"}` : "none",
31690
- 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"
31857
+ transition: drawerSwap ? "none" : "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"
31691
31858
  }),
31692
31859
  onClick: isMobile && mobileConversationsOpen ? (e) => {
31693
31860
  if (e.currentTarget.contains(e.target)) {
31694
31861
  setMobileConversationsOpen(false);
31695
31862
  }
31696
31863
  } : void 0,
31864
+ style: drawerDragStyle,
31697
31865
  onTouchStart: isMobile && mobileConversationsOpen ? (e) => {
31698
31866
  if (e.currentTarget.contains(e.target)) {
31699
31867
  cardSwipeStartXRef.current = e.touches[0]?.clientX ?? null;
31868
+ drawerDragStart(e);
31700
31869
  }
31701
31870
  } : void 0,
31702
- onTouchMove: isMobile && mobileConversationsOpen ? (e) => {
31703
- const start = cardSwipeStartXRef.current;
31704
- if (start === null) return;
31705
- const dx = (e.touches[0]?.clientX ?? start) - start;
31706
- if (Math.abs(dx) > 40) {
31707
- cardSwipeStartXRef.current = null;
31708
- setMobileConversationsOpen(false);
31709
- }
31710
- } : void 0,
31871
+ onTouchMove: isMobile && mobileConversationsOpen ? drawerDragMove : void 0,
31872
+ onTouchEnd: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31873
+ onTouchCancel: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31711
31874
  children: [
31712
31875
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31713
31876
  chat_app_bar_default,
@@ -31720,7 +31883,13 @@ var init_chat2 = __esm({
31720
31883
  drawerOpen,
31721
31884
  setDrawerOpen,
31722
31885
  mobileConversationsOpen,
31723
- onMobileConversationsOpenChange: setMobileConversationsOpen
31886
+ onMobileConversationsOpenChange: setMobileConversationsOpen,
31887
+ mobileConversationsDrag: isMobile ? {
31888
+ style: drawerPanelDragStyle,
31889
+ onTouchStart: drawerDragStart,
31890
+ onTouchMove: drawerDragMove,
31891
+ onTouchEnd: drawerDragEnd
31892
+ } : void 0
31724
31893
  }
31725
31894
  ),
31726
31895
  isTemporaryChat && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
@@ -31876,6 +32045,53 @@ var init_chat2 = __esm({
31876
32045
  }
31877
32046
  return branding?.logoBase64 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(custom_logo_default, { visible: logoVisible, atTop: true }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(bandit_chat_logo_default, { visible: logoVisible, atTop: true });
31878
32047
  })(),
32048
+ showKnowledgeNudge && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
32049
+ import_material33.Box,
32050
+ {
32051
+ sx: (theme) => ({
32052
+ mx: "auto",
32053
+ mt: 2,
32054
+ mb: 1,
32055
+ px: 2,
32056
+ py: 1.25,
32057
+ maxWidth: 420,
32058
+ display: "flex",
32059
+ alignItems: "center",
32060
+ gap: 1.25,
32061
+ borderRadius: 2.5,
32062
+ border: `1px solid ${theme.palette.divider}`,
32063
+ bgcolor: theme.palette.action.hover,
32064
+ opacity: logoVisible ? 1 : 0,
32065
+ transition: "opacity 0.5s ease"
32066
+ }),
32067
+ children: [
32068
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_material33.Box, { sx: { flex: 1, minWidth: 0 }, children: [
32069
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material33.Typography, { variant: "body2", sx: { fontWeight: 600 }, children: "Add your documents" }),
32070
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material33.Typography, { variant: "caption", color: "text.secondary", children: "Upload your policies, handbooks or notes and Bandit answers from them, with sources." })
32071
+ ] }),
32072
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
32073
+ import_material33.Button,
32074
+ {
32075
+ size: "small",
32076
+ variant: "outlined",
32077
+ onClick: () => safeNavigateTo(knowledgePath),
32078
+ sx: { textTransform: "none", fontWeight: 600, flexShrink: 0 },
32079
+ children: "Upload"
32080
+ }
32081
+ ),
32082
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
32083
+ import_material33.IconButton,
32084
+ {
32085
+ size: "small",
32086
+ "aria-label": "Dismiss",
32087
+ onClick: dismissKnowledgeNudge,
32088
+ sx: { flexShrink: 0 },
32089
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CloseIcon, { fontSize: "small" })
32090
+ }
32091
+ )
32092
+ ]
32093
+ }
32094
+ ),
31879
32095
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31880
32096
  import_material33.Box,
31881
32097
  {
@@ -32012,7 +32228,7 @@ var init_chat2 = __esm({
32012
32228
  });
32013
32229
  if (!allowUnauthenticated && !bypassAuth && !authenticationService2.isAuthenticated()) {
32014
32230
  debugLogger.debug("User is not authenticated, redirecting to login");
32015
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_router_dom4.Navigate, { to: "/login", replace: true });
32231
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
32016
32232
  }
32017
32233
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ChatContent, {});
32018
32234
  };
@@ -32543,31 +32759,31 @@ var chat_provider_default = ChatProvider;
32543
32759
  init_chat2();
32544
32760
 
32545
32761
  // src/management/management.tsx
32546
- var import_react65 = require("react");
32762
+ var import_react66 = require("react");
32547
32763
  var import_useMediaQuery2 = __toESM(require("@mui/material/useMediaQuery"));
32548
32764
  var import_styles35 = require("@mui/material/styles");
32549
32765
  init_useKnowledgeStore();
32550
32766
  init_indexedDBService();
32551
32767
  var import_material55 = require("@mui/material");
32552
- var import_react_router_dom6 = require("react-router-dom");
32768
+ var import_react_router_dom7 = require("react-router-dom");
32553
32769
 
32554
32770
  // src/modals/chat-modal/chat-modal.tsx
32555
- var import_react49 = require("react");
32771
+ var import_react50 = require("react");
32556
32772
  var import_material41 = require("@mui/material");
32557
- var import_react_router_dom5 = require("react-router-dom");
32773
+ var import_react_router_dom6 = require("react-router-dom");
32558
32774
 
32559
32775
  // src/modals/chat-modal/draggable-box.tsx
32560
- var import_react42 = __toESM(require("react"));
32776
+ var import_react43 = __toESM(require("react"));
32561
32777
  var import_material34 = require("@mui/material");
32562
32778
  var import_jsx_runtime35 = require("react/jsx-runtime");
32563
32779
  var SCROLLABLE_THRESHOLD = 200;
32564
- var DraggableBox = import_react42.default.forwardRef(
32780
+ var DraggableBox = import_react43.default.forwardRef(
32565
32781
  ({ children, fullScreen, position, setPosition, onDrag, onScrollThresholdExceeded }, ref) => {
32566
32782
  const theme = (0, import_material34.useTheme)();
32567
- const [transitionProps, setTransitionProps] = (0, import_react42.useState)("all");
32568
- const [isDragging, setIsDragging] = (0, import_react42.useState)(false);
32569
- const [isHovering, setIsHovering] = (0, import_react42.useState)(false);
32570
- (0, import_react42.useEffect)(() => {
32783
+ const [transitionProps, setTransitionProps] = (0, import_react43.useState)("all");
32784
+ const [isDragging, setIsDragging] = (0, import_react43.useState)(false);
32785
+ const [isHovering, setIsHovering] = (0, import_react43.useState)(false);
32786
+ (0, import_react43.useEffect)(() => {
32571
32787
  if (ref && typeof ref !== "function" && ref.current && !fullScreen) {
32572
32788
  const modal = ref.current;
32573
32789
  const contentHeight = modal.scrollHeight;
@@ -32643,7 +32859,7 @@ var DraggableBox = import_react42.default.forwardRef(
32643
32859
  var draggable_box_default = DraggableBox;
32644
32860
 
32645
32861
  // src/modals/chat-modal/modal-header.tsx
32646
- var import_react43 = require("react");
32862
+ var import_react44 = require("react");
32647
32863
  var import_material35 = require("@mui/material");
32648
32864
  init_lucide_icons();
32649
32865
  var import_jsx_runtime36 = require("react/jsx-runtime");
@@ -32663,7 +32879,7 @@ var ModalHeader = ({
32663
32879
  const theme = (0, import_material35.useTheme)();
32664
32880
  const isMobile = (0, import_material35.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
32665
32881
  const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead3;
32666
- const [isHovering, setIsHovering] = (0, import_react43.useState)(false);
32882
+ const [isHovering, setIsHovering] = (0, import_react44.useState)(false);
32667
32883
  const buttonStyles = {
32668
32884
  transition: "all 0.15s ease-out",
32669
32885
  borderRadius: "8px",
@@ -32861,7 +33077,7 @@ var ModalHeader = ({
32861
33077
  var modal_header_default = ModalHeader;
32862
33078
 
32863
33079
  // src/modals/chat-modal/query-input.tsx
32864
- var import_react44 = require("react");
33080
+ var import_react45 = require("react");
32865
33081
  var import_material36 = require("@mui/material");
32866
33082
  init_lucide_icons();
32867
33083
  var import_jsx_runtime37 = require("react/jsx-runtime");
@@ -32879,7 +33095,7 @@ var QueryInput = ({
32879
33095
  // Destructure endAdornment
32880
33096
  }) => {
32881
33097
  const theme = (0, import_material36.useTheme)();
32882
- const inputRef = (0, import_react44.useRef)(null);
33098
+ const inputRef = (0, import_react45.useRef)(null);
32883
33099
  const handleSend = (e, payload) => {
32884
33100
  onSend(e, payload);
32885
33101
  };
@@ -32946,7 +33162,7 @@ init_ai_response_text_field();
32946
33162
  init_indexedDBService();
32947
33163
 
32948
33164
  // src/modals/chat-modal/chat-drawer.tsx
32949
- var import_react45 = __toESM(require("react"));
33165
+ var import_react46 = __toESM(require("react"));
32950
33166
  var import_material37 = require("@mui/material");
32951
33167
  init_aiQueryStore();
32952
33168
  init_conversationStore();
@@ -32981,23 +33197,23 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
32981
33197
  const { settings: packageSettings } = usePackageSettingsStore();
32982
33198
  const provider = useAIProviderStore((state) => state.provider);
32983
33199
  const { selectedModel, availableModels } = useModelStore();
32984
- const [searchTerm, setSearchTerm] = (0, import_react45.useState)("");
32985
- const [expandedItems, setExpandedItems] = (0, import_react45.useState)(/* @__PURE__ */ new Set());
32986
- const [expandedConversations, setExpandedConversations] = (0, import_react45.useState)(/* @__PURE__ */ new Set());
32987
- const [confirmClearOpen, setConfirmClearOpen] = (0, import_react45.useState)(false);
32988
- const [infoDialogOpen, setInfoDialogOpen] = (0, import_react45.useState)(false);
32989
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react45.useState)(false);
32990
- const [contextMode, setContextMode] = (0, import_react45.useState)("local");
32991
- const [expandedSections, setExpandedSections] = (0, import_react45.useState)(/* @__PURE__ */ new Set(["history", "voice"]));
32992
- const [audioSub, setAudioSub] = (0, import_react45.useState)(new import_rxjs22.Subscription());
32993
- const [isContextSwitching, setIsContextSwitching] = (0, import_react45.useState)(false);
32994
- const [isDrawerLoading, setIsDrawerLoading] = (0, import_react45.useState)(false);
32995
- (0, import_react45.useEffect)(() => {
33200
+ const [searchTerm, setSearchTerm] = (0, import_react46.useState)("");
33201
+ const [expandedItems, setExpandedItems] = (0, import_react46.useState)(/* @__PURE__ */ new Set());
33202
+ const [expandedConversations, setExpandedConversations] = (0, import_react46.useState)(/* @__PURE__ */ new Set());
33203
+ const [confirmClearOpen, setConfirmClearOpen] = (0, import_react46.useState)(false);
33204
+ const [infoDialogOpen, setInfoDialogOpen] = (0, import_react46.useState)(false);
33205
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react46.useState)(false);
33206
+ const [contextMode, setContextMode] = (0, import_react46.useState)("local");
33207
+ const [expandedSections, setExpandedSections] = (0, import_react46.useState)(/* @__PURE__ */ new Set(["history", "voice"]));
33208
+ const [audioSub, setAudioSub] = (0, import_react46.useState)(new import_rxjs22.Subscription());
33209
+ const [isContextSwitching, setIsContextSwitching] = (0, import_react46.useState)(false);
33210
+ const [isDrawerLoading, setIsDrawerLoading] = (0, import_react46.useState)(false);
33211
+ (0, import_react46.useEffect)(() => {
32996
33212
  if (drawerOpen && !_hasHydrated) {
32997
33213
  hydrate();
32998
33214
  }
32999
33215
  }, [drawerOpen, _hasHydrated, hydrate]);
33000
- (0, import_react45.useEffect)(() => {
33216
+ (0, import_react46.useEffect)(() => {
33001
33217
  if (!drawerOpen) {
33002
33218
  setIsDrawerLoading(false);
33003
33219
  const cleanupTimer = setTimeout(() => {
@@ -33008,7 +33224,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33008
33224
  return () => clearTimeout(cleanupTimer);
33009
33225
  }
33010
33226
  }, [drawerOpen]);
33011
- (0, import_react45.useEffect)(() => {
33227
+ (0, import_react46.useEffect)(() => {
33012
33228
  return () => {
33013
33229
  audioSub.unsubscribe();
33014
33230
  };
@@ -33055,7 +33271,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33055
33271
  const currentConversation = conversations.find((c) => c.id === currentId);
33056
33272
  const isInitialLoading = !_hasHydrated && contextMode === "main";
33057
33273
  const isContentLoading = isContextSwitching || isInitialLoading;
33058
- (0, import_react45.useEffect)(() => {
33274
+ (0, import_react46.useEffect)(() => {
33059
33275
  if (drawerOpen) {
33060
33276
  const debugTimer = setTimeout(() => {
33061
33277
  debugLogger.debug("Chat drawer loading states", {
@@ -33070,7 +33286,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33070
33286
  return () => clearTimeout(debugTimer);
33071
33287
  }
33072
33288
  }, [drawerOpen, _hasHydrated, isDrawerLoading, isContentLoading, contextMode]);
33073
- (0, import_react45.useEffect)(() => {
33289
+ (0, import_react46.useEffect)(() => {
33074
33290
  debugLogger.debug("Chat drawer voice availability check", {
33075
33291
  isServiceAvailable,
33076
33292
  ttsEnabled: preferences.ttsEnabled,
@@ -33081,14 +33297,14 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33081
33297
  storeState: "modal-chat-drawer-voice"
33082
33298
  });
33083
33299
  }, [isServiceAvailable, preferences.ttsEnabled, packageSettings?.gatewayApiUrl, isVoiceAvailable, availableVoices.length, selectedVoice]);
33084
- const activeHistory = (0, import_react45.useMemo)(() => {
33300
+ const activeHistory = (0, import_react46.useMemo)(() => {
33085
33301
  if (contextMode === "local") {
33086
33302
  return history;
33087
33303
  }
33088
33304
  return currentConversation?.history ?? [];
33089
33305
  }, [contextMode, history, currentConversation]);
33090
33306
  const effectiveContextMode = contextMode === "main" && (!currentConversation || currentConversation.history.length === 0) ? "local" : contextMode;
33091
- (0, import_react45.useEffect)(() => {
33307
+ (0, import_react46.useEffect)(() => {
33092
33308
  debugLogger.debug("Chat drawer context state", {
33093
33309
  contextMode,
33094
33310
  effectiveContextMode,
@@ -33101,13 +33317,13 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33101
33317
  storeState: "modal-chat-drawer"
33102
33318
  });
33103
33319
  }, [contextMode, effectiveContextMode, conversations.length, currentId, currentConversation, history.length, _hasHydrated]);
33104
- const filteredHistory = (0, import_react45.useMemo)(() => {
33320
+ const filteredHistory = (0, import_react46.useMemo)(() => {
33105
33321
  const filtered = activeHistory.filter(
33106
33322
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
33107
33323
  );
33108
33324
  return filtered.slice(-20);
33109
33325
  }, [activeHistory, searchTerm]);
33110
- const filteredConversations = (0, import_react45.useMemo)(() => {
33326
+ const filteredConversations = (0, import_react46.useMemo)(() => {
33111
33327
  const filtered = conversations.filter(
33112
33328
  (conversation) => conversation.name.toLowerCase().includes(searchTerm.toLowerCase()) || conversation.history.some(
33113
33329
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
@@ -33993,7 +34209,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33993
34209
  }
33994
34210
  ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material37.List, { sx: { p: 0 }, children: [...filteredHistory].reverse().map((entry, index) => {
33995
34211
  const isExpanded = expandedItems.has(index);
33996
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react45.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34212
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react46.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
33997
34213
  import_material37.ListItem,
33998
34214
  {
33999
34215
  sx: {
@@ -34470,7 +34686,7 @@ var GenericLoader = ({
34470
34686
  var generic_loader_default = GenericLoader;
34471
34687
 
34472
34688
  // src/components/feedback/FeedbackButton.tsx
34473
- var import_react46 = require("react");
34689
+ var import_react47 = require("react");
34474
34690
  var import_material39 = require("@mui/material");
34475
34691
  var import_lucide_react15 = require("lucide-react");
34476
34692
 
@@ -34491,7 +34707,7 @@ var FeedbackButton = ({
34491
34707
  absolute = false
34492
34708
  }) => {
34493
34709
  const theme = (0, import_material39.useTheme)();
34494
- const [open, setOpen] = (0, import_react46.useState)(false);
34710
+ const [open, setOpen] = (0, import_react47.useState)(false);
34495
34711
  const handleOpen = () => setOpen(true);
34496
34712
  const handleClose = () => setOpen(false);
34497
34713
  if (inline) {
@@ -34605,7 +34821,7 @@ var FeedbackButton = ({
34605
34821
  };
34606
34822
 
34607
34823
  // src/hooks/useAiChat.ts
34608
- var import_react47 = require("react");
34824
+ var import_react48 = require("react");
34609
34825
  var import_material40 = require("@mui/material");
34610
34826
  init_aiQueryStore();
34611
34827
  init_aiProviderStore();
@@ -34617,10 +34833,10 @@ var useAIChat = () => {
34617
34833
  const provider = useAIProviderStore((state) => state.provider);
34618
34834
  const SYSTEM_PROMPT = useModelStore((state) => state.systemPrompt);
34619
34835
  const OLLAMA_MODEL = usePackageSettingsStore((state) => state.settings?.defaultModel || "");
34620
- const [fullScreen, setFullScreen] = (0, import_react47.useState)(isMobile);
34621
- const [drawerOpen, setDrawerOpen] = (0, import_react47.useState)(false);
34622
- const [showSettings, setShowSettings] = (0, import_react47.useState)(false);
34623
- const [, setAutoFullscreenTriggered] = (0, import_react47.useState)(false);
34836
+ const [fullScreen, setFullScreen] = (0, import_react48.useState)(isMobile);
34837
+ const [drawerOpen, setDrawerOpen] = (0, import_react48.useState)(false);
34838
+ const [showSettings, setShowSettings] = (0, import_react48.useState)(false);
34839
+ const [, setAutoFullscreenTriggered] = (0, import_react48.useState)(false);
34624
34840
  const {
34625
34841
  apiKey,
34626
34842
  inputValue,
@@ -34708,7 +34924,7 @@ var useAIChat = () => {
34708
34924
  }
34709
34925
  sendWithAIProvider();
34710
34926
  };
34711
- (0, import_react47.useEffect)(() => {
34927
+ (0, import_react48.useEffect)(() => {
34712
34928
  setFullScreen(isMobile);
34713
34929
  }, [isMobile]);
34714
34930
  return {
@@ -34724,12 +34940,12 @@ var useAIChat = () => {
34724
34940
  var useAiChat_default = useAIChat;
34725
34941
 
34726
34942
  // src/hooks/useDraggable.ts
34727
- var import_react48 = require("react");
34943
+ var import_react49 = require("react");
34728
34944
  var useDraggable = () => {
34729
- const modalRef = (0, import_react48.useRef)(null);
34730
- const [dragging, setDragging] = (0, import_react48.useState)(false);
34731
- const [offset, setOffset] = (0, import_react48.useState)({ x: 0, y: 0 });
34732
- const [position, setPosition] = (0, import_react48.useState)({ x: 0, y: 0 });
34945
+ const modalRef = (0, import_react49.useRef)(null);
34946
+ const [dragging, setDragging] = (0, import_react49.useState)(false);
34947
+ const [offset, setOffset] = (0, import_react49.useState)({ x: 0, y: 0 });
34948
+ const [position, setPosition] = (0, import_react49.useState)({ x: 0, y: 0 });
34733
34949
  const handleHeaderMouseDown = (e) => {
34734
34950
  const rect = modalRef.current?.getBoundingClientRect();
34735
34951
  if (rect) {
@@ -34737,7 +34953,7 @@ var useDraggable = () => {
34737
34953
  setDragging(true);
34738
34954
  }
34739
34955
  };
34740
- const handleHeaderMouseMove = (0, import_react48.useCallback)(
34956
+ const handleHeaderMouseMove = (0, import_react49.useCallback)(
34741
34957
  (e) => {
34742
34958
  if (dragging) {
34743
34959
  setPosition({ x: e.clientX - offset.x, y: e.clientY - offset.y });
@@ -34748,7 +34964,7 @@ var useDraggable = () => {
34748
34964
  const handleHeaderMouseUp = () => {
34749
34965
  setDragging(false);
34750
34966
  };
34751
- (0, import_react48.useEffect)(() => {
34967
+ (0, import_react49.useEffect)(() => {
34752
34968
  if (dragging) {
34753
34969
  document.addEventListener("mousemove", handleHeaderMouseMove);
34754
34970
  document.addEventListener("mouseup", handleHeaderMouseUp);
@@ -34798,9 +35014,9 @@ var modelAvatars3 = {
34798
35014
  "Bandit-Exec": `${CDN_BASE2}/avatars/exec-avatar.png`
34799
35015
  };
34800
35016
  var useOptionalNavigate = () => {
34801
- const hasLoggedRef = (0, import_react49.useRef)(false);
35017
+ const hasLoggedRef = (0, import_react50.useRef)(false);
34802
35018
  try {
34803
- return (0, import_react_router_dom5.useNavigate)();
35019
+ return (0, import_react_router_dom6.useNavigate)();
34804
35020
  } catch (error) {
34805
35021
  if (!hasLoggedRef.current) {
34806
35022
  debugLogger.debug("Navigation not available in ChatModal context", { error });
@@ -34847,17 +35063,17 @@ var ChatModal = ({
34847
35063
  handleSend
34848
35064
  } = useAiChat_default();
34849
35065
  const { modalRef, position, setPosition, handleDrag, handleHeaderMouseDown } = useDraggable_default();
34850
- const [pastedImages, setPastedImages] = (0, import_react49.useState)([]);
34851
- const [responseStarted, setResponseStarted] = (0, import_react49.useState)(false);
34852
- const [modalLogo, setModalLogo] = (0, import_react49.useState)("https://cdn.burtson.ai/logos/bandit-ai-logo.png");
34853
- const [modelAnchorEl, setModelAnchorEl] = (0, import_react49.useState)(null);
34854
- const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react49.useState)(null);
34855
- const [audioSub, setAudioSub] = (0, import_react49.useState)(new import_rxjs23.Subscription());
34856
- const [selectedTheme, setSelectedTheme] = (0, import_react49.useState)(null);
34857
- const [themeLoading, setThemeLoading] = (0, import_react49.useState)(true);
34858
- const [autoFullscreenTriggered, setAutoFullscreenTriggered] = (0, import_react49.useState)(false);
34859
- const [userHasDragged, setUserHasDragged] = (0, import_react49.useState)(false);
34860
- const [manualFullscreenToggleTime, setManualFullscreenToggleTime] = (0, import_react49.useState)(0);
35066
+ const [pastedImages, setPastedImages] = (0, import_react50.useState)([]);
35067
+ const [responseStarted, setResponseStarted] = (0, import_react50.useState)(false);
35068
+ const [modalLogo, setModalLogo] = (0, import_react50.useState)("https://cdn.burtson.ai/logos/bandit-ai-logo.png");
35069
+ const [modelAnchorEl, setModelAnchorEl] = (0, import_react50.useState)(null);
35070
+ const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react50.useState)(null);
35071
+ const [audioSub, setAudioSub] = (0, import_react50.useState)(new import_rxjs23.Subscription());
35072
+ const [selectedTheme, setSelectedTheme] = (0, import_react50.useState)(null);
35073
+ const [themeLoading, setThemeLoading] = (0, import_react50.useState)(true);
35074
+ const [autoFullscreenTriggered, setAutoFullscreenTriggered] = (0, import_react50.useState)(false);
35075
+ const [userHasDragged, setUserHasDragged] = (0, import_react50.useState)(false);
35076
+ const [manualFullscreenToggleTime, setManualFullscreenToggleTime] = (0, import_react50.useState)(0);
34861
35077
  const handleExitFullscreen = () => {
34862
35078
  setPosition({
34863
35079
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34903,7 +35119,7 @@ var ChatModal = ({
34903
35119
  const toTitleCase2 = (str) => {
34904
35120
  return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
34905
35121
  };
34906
- (0, import_react49.useEffect)(() => {
35122
+ (0, import_react50.useEffect)(() => {
34907
35123
  if (!SYSTEM_PROMPT) {
34908
35124
  const defaultModel = availableModels.length > 0 ? availableModels[0] : null;
34909
35125
  if (defaultModel) {
@@ -34911,12 +35127,12 @@ var ChatModal = ({
34911
35127
  }
34912
35128
  }
34913
35129
  }, [SYSTEM_PROMPT, availableModels, setSelectedModel]);
34914
- (0, import_react49.useEffect)(() => {
35130
+ (0, import_react50.useEffect)(() => {
34915
35131
  return () => {
34916
35132
  audioSub.unsubscribe();
34917
35133
  };
34918
35134
  }, [audioSub]);
34919
- (0, import_react49.useEffect)(() => {
35135
+ (0, import_react50.useEffect)(() => {
34920
35136
  if (open) {
34921
35137
  setPosition({
34922
35138
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34928,7 +35144,7 @@ var ChatModal = ({
34928
35144
  getOptimalLogo().then(setModalLogo);
34929
35145
  }
34930
35146
  }, [open, setPosition]);
34931
- (0, import_react49.useEffect)(() => {
35147
+ (0, import_react50.useEffect)(() => {
34932
35148
  if (!open) return;
34933
35149
  const fetchTheme = async () => {
34934
35150
  try {
@@ -34962,7 +35178,7 @@ var ChatModal = ({
34962
35178
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
34963
35179
  };
34964
35180
  }, [open]);
34965
- (0, import_react49.useLayoutEffect)(() => {
35181
+ (0, import_react50.useLayoutEffect)(() => {
34966
35182
  const timeSinceManualToggle = Date.now() - manualFullscreenToggleTime;
34967
35183
  const manualToggleRecentlyUsed = timeSinceManualToggle < 5e3;
34968
35184
  if (modalRef.current && response && !fullScreen && !autoFullscreenTriggered && !manualToggleRecentlyUsed) {
@@ -34987,7 +35203,7 @@ var ChatModal = ({
34987
35203
  setFullScreen,
34988
35204
  setAutoFullscreenTriggered
34989
35205
  ]);
34990
- (0, import_react49.useEffect)(() => {
35206
+ (0, import_react50.useEffect)(() => {
34991
35207
  const handlePaste = (e) => {
34992
35208
  const items = e.clipboardData?.items;
34993
35209
  if (items) {
@@ -35012,7 +35228,7 @@ var ChatModal = ({
35012
35228
  document.removeEventListener("paste", handlePaste);
35013
35229
  };
35014
35230
  }, []);
35015
- (0, import_react49.useEffect)(() => {
35231
+ (0, import_react50.useEffect)(() => {
35016
35232
  if (response && !responseStarted) {
35017
35233
  setResponseStarted(true);
35018
35234
  }
@@ -35432,13 +35648,13 @@ var ChatModal = ({
35432
35648
  var chat_modal_default = ChatModal;
35433
35649
 
35434
35650
  // src/management/components/PersonalitiesTab.tsx
35435
- var import_react51 = require("react");
35651
+ var import_react52 = require("react");
35436
35652
  var import_material43 = require("@mui/material");
35437
35653
  var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"));
35438
35654
  var import_styles34 = require("@mui/material/styles");
35439
35655
 
35440
35656
  // src/components/AvatarCropper.tsx
35441
- var import_react50 = require("react");
35657
+ var import_react51 = require("react");
35442
35658
  var import_material42 = require("@mui/material");
35443
35659
  init_lucide_icons();
35444
35660
  var import_jsx_runtime42 = require("react/jsx-runtime");
@@ -35448,22 +35664,22 @@ var AvatarCropper = ({
35448
35664
  onCrop,
35449
35665
  imageFile
35450
35666
  }) => {
35451
- const canvasRef = (0, import_react50.useRef)(null);
35452
- const imageRef = (0, import_react50.useRef)(null);
35453
- const [imageSrc, setImageSrc] = (0, import_react50.useState)("");
35454
- const [cropSettings, setCropSettings] = (0, import_react50.useState)({
35667
+ const canvasRef = (0, import_react51.useRef)(null);
35668
+ const imageRef = (0, import_react51.useRef)(null);
35669
+ const [imageSrc, setImageSrc] = (0, import_react51.useState)("");
35670
+ const [cropSettings, setCropSettings] = (0, import_react51.useState)({
35455
35671
  x: 0,
35456
35672
  y: 0,
35457
35673
  scale: 1,
35458
35674
  rotation: 0
35459
35675
  });
35460
- const [isDragging, setIsDragging] = (0, import_react50.useState)(false);
35461
- const [dragStart, setDragStart] = (0, import_react50.useState)({ x: 0, y: 0 });
35462
- const [imageLoaded, setImageLoaded] = (0, import_react50.useState)(false);
35463
- const [imageNaturalSize, setImageNaturalSize] = (0, import_react50.useState)({ width: 0, height: 0 });
35676
+ const [isDragging, setIsDragging] = (0, import_react51.useState)(false);
35677
+ const [dragStart, setDragStart] = (0, import_react51.useState)({ x: 0, y: 0 });
35678
+ const [imageLoaded, setImageLoaded] = (0, import_react51.useState)(false);
35679
+ const [imageNaturalSize, setImageNaturalSize] = (0, import_react51.useState)({ width: 0, height: 0 });
35464
35680
  const CROP_SIZE = 400;
35465
35681
  const OUTPUT_SIZE = 512;
35466
- (0, import_react50.useEffect)(() => {
35682
+ (0, import_react51.useEffect)(() => {
35467
35683
  if (imageFile && open) {
35468
35684
  const reader = new FileReader();
35469
35685
  reader.onload = (e) => {
@@ -35475,7 +35691,7 @@ var AvatarCropper = ({
35475
35691
  reader.readAsDataURL(imageFile);
35476
35692
  }
35477
35693
  }, [imageFile, open]);
35478
- const handleImageLoad = (0, import_react50.useCallback)(() => {
35694
+ const handleImageLoad = (0, import_react51.useCallback)(() => {
35479
35695
  if (imageRef.current) {
35480
35696
  const { naturalWidth, naturalHeight } = imageRef.current;
35481
35697
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -35492,7 +35708,7 @@ var AvatarCropper = ({
35492
35708
  setImageLoaded(true);
35493
35709
  }
35494
35710
  }, []);
35495
- const drawCropPreview = (0, import_react50.useCallback)(() => {
35711
+ const drawCropPreview = (0, import_react51.useCallback)(() => {
35496
35712
  const canvas = canvasRef.current;
35497
35713
  const image = imageRef.current;
35498
35714
  if (!canvas || !image || !imageLoaded) return;
@@ -35515,14 +35731,14 @@ var AvatarCropper = ({
35515
35731
  ctx.fill();
35516
35732
  ctx.restore();
35517
35733
  }, [cropSettings, imageLoaded]);
35518
- (0, import_react50.useEffect)(() => {
35734
+ (0, import_react51.useEffect)(() => {
35519
35735
  drawCropPreview();
35520
35736
  }, [drawCropPreview]);
35521
- const handleMouseDown = (0, import_react50.useCallback)((e) => {
35737
+ const handleMouseDown = (0, import_react51.useCallback)((e) => {
35522
35738
  setIsDragging(true);
35523
35739
  setDragStart({ x: e.clientX, y: e.clientY });
35524
35740
  }, []);
35525
- const handleMouseMove = (0, import_react50.useCallback)((e) => {
35741
+ const handleMouseMove = (0, import_react51.useCallback)((e) => {
35526
35742
  if (!isDragging) return;
35527
35743
  const deltaX = e.clientX - dragStart.x;
35528
35744
  const deltaY = e.clientY - dragStart.y;
@@ -35533,16 +35749,16 @@ var AvatarCropper = ({
35533
35749
  }));
35534
35750
  setDragStart({ x: e.clientX, y: e.clientY });
35535
35751
  }, [isDragging, dragStart]);
35536
- const handleMouseUp = (0, import_react50.useCallback)(() => {
35752
+ const handleMouseUp = (0, import_react51.useCallback)(() => {
35537
35753
  setIsDragging(false);
35538
35754
  }, []);
35539
- const handleClose = (0, import_react50.useCallback)(() => {
35755
+ const handleClose = (0, import_react51.useCallback)(() => {
35540
35756
  setImageSrc("");
35541
35757
  setImageLoaded(false);
35542
35758
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
35543
35759
  onClose();
35544
35760
  }, [onClose]);
35545
- const handleCrop = (0, import_react50.useCallback)(() => {
35761
+ const handleCrop = (0, import_react51.useCallback)(() => {
35546
35762
  const canvas = document.createElement("canvas");
35547
35763
  const ctx = canvas.getContext("2d");
35548
35764
  const image = imageRef.current;
@@ -35569,7 +35785,7 @@ var AvatarCropper = ({
35569
35785
  onCrop(croppedDataUrl);
35570
35786
  handleClose();
35571
35787
  }, [cropSettings, onCrop, handleClose]);
35572
- const handleScaleChange = (0, import_react50.useCallback)((value) => {
35788
+ const handleScaleChange = (0, import_react51.useCallback)((value) => {
35573
35789
  const minScale2 = Math.max(
35574
35790
  CROP_SIZE / imageNaturalSize.width,
35575
35791
  CROP_SIZE / imageNaturalSize.height
@@ -35579,7 +35795,7 @@ var AvatarCropper = ({
35579
35795
  scale: Math.max(value, minScale2)
35580
35796
  }));
35581
35797
  }, [imageNaturalSize]);
35582
- const handleRotation = (0, import_react50.useCallback)((direction) => {
35798
+ const handleRotation = (0, import_react51.useCallback)((direction) => {
35583
35799
  setCropSettings((prev) => ({
35584
35800
  ...prev,
35585
35801
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -35815,15 +36031,15 @@ var PersonalitiesTab = ({
35815
36031
  }) => {
35816
36032
  const theme = (0, import_styles34.useTheme)();
35817
36033
  const isMobile = (0, import_useMediaQuery.default)(theme.breakpoints.down("sm"));
35818
- const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react51.useState)(0);
36034
+ const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react52.useState)(0);
35819
36035
  const tabWrapperStyles = isMobile ? { flexDirection: "column", gap: 0.35, fontSize: "0.78rem" } : { flexDirection: "row", gap: 0.75, fontSize: "0.95rem" };
35820
- const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react51.useState)(false);
35821
- const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react51.useState)(false);
35822
- const [personalityToDelete, setPersonalityToDelete] = (0, import_react51.useState)(null);
35823
- const [clickedChips, setClickedChips] = (0, import_react51.useState)(/* @__PURE__ */ new Set());
35824
- const [showTemplateHelp, setShowTemplateHelp] = (0, import_react51.useState)(false);
35825
- const [cropperOpen, setCropperOpen] = (0, import_react51.useState)(false);
35826
- const [selectedImageFile, setSelectedImageFile] = (0, import_react51.useState)(null);
36036
+ const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react52.useState)(false);
36037
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react52.useState)(false);
36038
+ const [personalityToDelete, setPersonalityToDelete] = (0, import_react52.useState)(null);
36039
+ const [clickedChips, setClickedChips] = (0, import_react52.useState)(/* @__PURE__ */ new Set());
36040
+ const [showTemplateHelp, setShowTemplateHelp] = (0, import_react52.useState)(false);
36041
+ const [cropperOpen, setCropperOpen] = (0, import_react52.useState)(false);
36042
+ const [selectedImageFile, setSelectedImageFile] = (0, import_react52.useState)(null);
35827
36043
  const promptTemplates = [
35828
36044
  {
35829
36045
  name: "Business Professional",
@@ -37320,7 +37536,7 @@ var PersonalitiesTab = ({
37320
37536
  var PersonalitiesTab_default = PersonalitiesTab;
37321
37537
 
37322
37538
  // src/management/components/PreferencesTab.tsx
37323
- var import_react53 = require("react");
37539
+ var import_react54 = require("react");
37324
37540
  init_memory_modal();
37325
37541
  var import_material44 = require("@mui/material");
37326
37542
  init_preferencesStore();
@@ -37331,7 +37547,7 @@ init_useFeatures();
37331
37547
  init_conversationSyncStore();
37332
37548
 
37333
37549
  // src/hooks/useGatewayQueries.ts
37334
- var import_react52 = require("react");
37550
+ var import_react53 = require("react");
37335
37551
  var import_rxjs24 = require("rxjs");
37336
37552
  var import_react_query2 = require("@tanstack/react-query");
37337
37553
  init_packageSettingsStore();
@@ -37341,7 +37557,7 @@ var useGatewayClient = () => {
37341
37557
  const settings = usePackageSettingsStore((state) => state.settings);
37342
37558
  const gatewayUrl = settings?.gatewayApiUrl;
37343
37559
  const feedbackEmail = settings?.feedbackEmail;
37344
- const service = (0, import_react52.useMemo)(() => {
37560
+ const service = (0, import_react53.useMemo)(() => {
37345
37561
  if (!gatewayUrl) {
37346
37562
  return null;
37347
37563
  }
@@ -37400,6 +37616,7 @@ var useGatewayMemory = (options) => {
37400
37616
  };
37401
37617
 
37402
37618
  // src/management/components/PreferencesTab.tsx
37619
+ init_installedApp();
37403
37620
  init_lucide_icons();
37404
37621
  var import_jsx_runtime44 = require("react/jsx-runtime");
37405
37622
  var PreferencesTab = ({
@@ -37411,16 +37628,16 @@ var PreferencesTab = ({
37411
37628
  }) => {
37412
37629
  const theme = (0, import_material44.useTheme)();
37413
37630
  const isMobile = (0, import_material44.useMediaQuery)(theme.breakpoints.down("sm"));
37414
- const [homeUrlStatus, setHomeUrlStatus] = (0, import_react53.useState)("idle");
37415
- const [homeUrlError, setHomeUrlError] = (0, import_react53.useState)("");
37416
- const [localHomeUrl, setLocalHomeUrl] = (0, import_react53.useState)(preferences.homeUrl || "");
37417
- const [importStatus, setImportStatus] = (0, import_react53.useState)("idle");
37418
- const [syncToggleLoading, setSyncToggleLoading] = (0, import_react53.useState)(false);
37419
- const [manualSyncLoading, setManualSyncLoading] = (0, import_react53.useState)(false);
37420
- const [advancedVectorToggleLoading, setAdvancedVectorToggleLoading] = (0, import_react53.useState)(false);
37421
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react53.useState)(false);
37422
- const timeoutRef = (0, import_react53.useRef)(null);
37423
- const fileInputRef = (0, import_react53.useRef)(null);
37631
+ const [homeUrlStatus, setHomeUrlStatus] = (0, import_react54.useState)("idle");
37632
+ const [homeUrlError, setHomeUrlError] = (0, import_react54.useState)("");
37633
+ const [localHomeUrl, setLocalHomeUrl] = (0, import_react54.useState)(preferences.homeUrl || "");
37634
+ const [importStatus, setImportStatus] = (0, import_react54.useState)("idle");
37635
+ const [syncToggleLoading, setSyncToggleLoading] = (0, import_react54.useState)(false);
37636
+ const [manualSyncLoading, setManualSyncLoading] = (0, import_react54.useState)(false);
37637
+ const [advancedVectorToggleLoading, setAdvancedVectorToggleLoading] = (0, import_react54.useState)(false);
37638
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react54.useState)(false);
37639
+ const timeoutRef = (0, import_react54.useRef)(null);
37640
+ const fileInputRef = (0, import_react54.useRef)(null);
37424
37641
  const { exportPreferences, importPreferences, resetToDefaults } = usePreferencesStore();
37425
37642
  const {
37426
37643
  isServiceAvailable: isTTSSTTAvailable,
@@ -37532,7 +37749,7 @@ var PreferencesTab = ({
37532
37749
  if (!gatewayHealth) return "warning";
37533
37750
  return gatewayHealth.status?.toLowerCase() === "healthy" ? "success" : "error";
37534
37751
  })();
37535
- const handleGatewayStatusRefresh = (0, import_react53.useCallback)(() => {
37752
+ const handleGatewayStatusRefresh = (0, import_react54.useCallback)(() => {
37536
37753
  if (!gatewayConfigured) {
37537
37754
  return;
37538
37755
  }
@@ -37594,7 +37811,7 @@ var PreferencesTab = ({
37594
37811
  }
37595
37812
  return packageSettings?.homeUrl || "";
37596
37813
  };
37597
- (0, import_react53.useEffect)(() => {
37814
+ (0, import_react54.useEffect)(() => {
37598
37815
  setLocalHomeUrl(preferences.homeUrl || "");
37599
37816
  }, [preferences.homeUrl]);
37600
37817
  const validateAndSaveHomeUrl = async (url) => {
@@ -37641,7 +37858,7 @@ var PreferencesTab = ({
37641
37858
  validateAndSaveHomeUrl(value);
37642
37859
  }, 1500);
37643
37860
  };
37644
- (0, import_react53.useEffect)(() => {
37861
+ (0, import_react54.useEffect)(() => {
37645
37862
  return () => {
37646
37863
  if (timeoutRef.current) {
37647
37864
  clearTimeout(timeoutRef.current);
@@ -38249,16 +38466,15 @@ var PreferencesTab = ({
38249
38466
  ] }) });
38250
38467
  };
38251
38468
  var ViewportDiagnostics = () => {
38252
- const [metrics, setMetrics] = (0, import_react53.useState)({});
38253
- (0, import_react53.useEffect)(() => {
38469
+ const [metrics, setMetrics] = (0, import_react54.useState)({});
38470
+ (0, import_react54.useEffect)(() => {
38254
38471
  const read = () => {
38255
38472
  const probe = document.createElement("div");
38256
38473
  probe.style.cssText = "position:fixed;top:0;bottom:0;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);visibility:hidden;pointer-events:none;";
38257
38474
  document.body.appendChild(probe);
38258
38475
  const cs = getComputedStyle(probe);
38259
- const standalone = window.matchMedia?.("(display-mode: standalone)").matches || window.navigator.standalone === true;
38260
38476
  setMetrics({
38261
- mode: standalone ? "standalone" : "browser",
38477
+ mode: isNativeShell() ? "native" : isStandalonePwa2() ? "standalone" : "browser",
38262
38478
  "screen.height": `${window.screen.height}`,
38263
38479
  innerHeight: `${window.innerHeight}`,
38264
38480
  "docElement.clientHeight": `${document.documentElement.clientHeight}`,
@@ -38285,11 +38501,11 @@ var ViewportDiagnostics = () => {
38285
38501
  var PreferencesTab_default = PreferencesTab;
38286
38502
 
38287
38503
  // src/management/components/BrandingTab.tsx
38288
- var import_react55 = require("react");
38504
+ var import_react56 = require("react");
38289
38505
  var import_material46 = require("@mui/material");
38290
38506
 
38291
38507
  // src/components/LogoCropper.tsx
38292
- var import_react54 = require("react");
38508
+ var import_react55 = require("react");
38293
38509
  var import_material45 = require("@mui/material");
38294
38510
  init_lucide_icons();
38295
38511
  var import_jsx_runtime45 = require("react/jsx-runtime");
@@ -38304,25 +38520,25 @@ var LogoCropper = ({
38304
38520
  onCrop,
38305
38521
  imageFile
38306
38522
  }) => {
38307
- const canvasRef = (0, import_react54.useRef)(null);
38308
- const previewCanvasRef = (0, import_react54.useRef)(null);
38309
- const imageRef = (0, import_react54.useRef)(null);
38310
- const [imageSrc, setImageSrc] = (0, import_react54.useState)("");
38311
- const [cropSettings, setCropSettings] = (0, import_react54.useState)({
38523
+ const canvasRef = (0, import_react55.useRef)(null);
38524
+ const previewCanvasRef = (0, import_react55.useRef)(null);
38525
+ const imageRef = (0, import_react55.useRef)(null);
38526
+ const [imageSrc, setImageSrc] = (0, import_react55.useState)("");
38527
+ const [cropSettings, setCropSettings] = (0, import_react55.useState)({
38312
38528
  x: 0,
38313
38529
  y: 0,
38314
38530
  scale: 1,
38315
38531
  rotation: 0
38316
38532
  });
38317
- const [isDragging, setIsDragging] = (0, import_react54.useState)(false);
38318
- const [dragStart, setDragStart] = (0, import_react54.useState)({ x: 0, y: 0 });
38319
- const [imageLoaded, setImageLoaded] = (0, import_react54.useState)(false);
38320
- const [imageNaturalSize, setImageNaturalSize] = (0, import_react54.useState)({ width: 0, height: 0 });
38321
- const [aspectRatio, setAspectRatio] = (0, import_react54.useState)("square");
38322
- const [cropArea, setCropArea] = (0, import_react54.useState)({ width: 400, height: 400 });
38533
+ const [isDragging, setIsDragging] = (0, import_react55.useState)(false);
38534
+ const [dragStart, setDragStart] = (0, import_react55.useState)({ x: 0, y: 0 });
38535
+ const [imageLoaded, setImageLoaded] = (0, import_react55.useState)(false);
38536
+ const [imageNaturalSize, setImageNaturalSize] = (0, import_react55.useState)({ width: 0, height: 0 });
38537
+ const [aspectRatio, setAspectRatio] = (0, import_react55.useState)("square");
38538
+ const [cropArea, setCropArea] = (0, import_react55.useState)({ width: 400, height: 400 });
38323
38539
  const CANVAS_SIZE = 500;
38324
- const [outputSize, setOutputSize] = (0, import_react54.useState)("large");
38325
- const getCropDimensions = (0, import_react54.useCallback)(() => {
38540
+ const [outputSize, setOutputSize] = (0, import_react55.useState)("large");
38541
+ const getCropDimensions = (0, import_react55.useCallback)(() => {
38326
38542
  const maxSize = 380;
38327
38543
  switch (aspectRatio) {
38328
38544
  case "square":
@@ -38337,7 +38553,7 @@ var LogoCropper = ({
38337
38553
  return cropArea;
38338
38554
  }
38339
38555
  }, [aspectRatio, cropArea]);
38340
- (0, import_react54.useEffect)(() => {
38556
+ (0, import_react55.useEffect)(() => {
38341
38557
  if (imageFile && open) {
38342
38558
  const reader = new FileReader();
38343
38559
  reader.onload = (e) => {
@@ -38349,7 +38565,7 @@ var LogoCropper = ({
38349
38565
  reader.readAsDataURL(imageFile);
38350
38566
  }
38351
38567
  }, [imageFile, open]);
38352
- const handleImageLoad = (0, import_react54.useCallback)(() => {
38568
+ const handleImageLoad = (0, import_react55.useCallback)(() => {
38353
38569
  if (imageRef.current) {
38354
38570
  const { naturalWidth, naturalHeight } = imageRef.current;
38355
38571
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -38367,7 +38583,7 @@ var LogoCropper = ({
38367
38583
  setImageLoaded(true);
38368
38584
  }
38369
38585
  }, [getCropDimensions]);
38370
- (0, import_react54.useEffect)(() => {
38586
+ (0, import_react55.useEffect)(() => {
38371
38587
  if (imageLoaded) {
38372
38588
  const cropDims = getCropDimensions();
38373
38589
  setCropArea(cropDims);
@@ -38381,7 +38597,7 @@ var LogoCropper = ({
38381
38597
  }));
38382
38598
  }
38383
38599
  }, [aspectRatio, imageLoaded, imageNaturalSize, getCropDimensions]);
38384
- const updatePreview = (0, import_react54.useCallback)((cropX, cropY, cropDims) => {
38600
+ const updatePreview = (0, import_react55.useCallback)((cropX, cropY, cropDims) => {
38385
38601
  const previewCanvas = previewCanvasRef.current;
38386
38602
  const mainCanvas = canvasRef.current;
38387
38603
  if (!previewCanvas || !mainCanvas) return;
@@ -38410,7 +38626,7 @@ var LogoCropper = ({
38410
38626
  previewCtx.lineWidth = 2;
38411
38627
  previewCtx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight);
38412
38628
  }, []);
38413
- const drawCropPreview = (0, import_react54.useCallback)(() => {
38629
+ const drawCropPreview = (0, import_react55.useCallback)(() => {
38414
38630
  const canvas = canvasRef.current;
38415
38631
  const image = imageRef.current;
38416
38632
  if (!canvas || !image || !imageLoaded) return;
@@ -38456,14 +38672,14 @@ var LogoCropper = ({
38456
38672
  ctx.fillRect(cropX + cropDims.width - 1, cropY + cropDims.height - cornerSize + 1, 3, cornerSize);
38457
38673
  updatePreview(cropX, cropY, cropDims);
38458
38674
  }, [cropSettings, imageLoaded, getCropDimensions, updatePreview]);
38459
- (0, import_react54.useEffect)(() => {
38675
+ (0, import_react55.useEffect)(() => {
38460
38676
  drawCropPreview();
38461
38677
  }, [drawCropPreview]);
38462
- const handleMouseDown = (0, import_react54.useCallback)((e) => {
38678
+ const handleMouseDown = (0, import_react55.useCallback)((e) => {
38463
38679
  setIsDragging(true);
38464
38680
  setDragStart({ x: e.clientX, y: e.clientY });
38465
38681
  }, []);
38466
- const handleMouseMove = (0, import_react54.useCallback)((e) => {
38682
+ const handleMouseMove = (0, import_react55.useCallback)((e) => {
38467
38683
  if (!isDragging) return;
38468
38684
  const deltaX = e.clientX - dragStart.x;
38469
38685
  const deltaY = e.clientY - dragStart.y;
@@ -38474,17 +38690,17 @@ var LogoCropper = ({
38474
38690
  }));
38475
38691
  setDragStart({ x: e.clientX, y: e.clientY });
38476
38692
  }, [isDragging, dragStart]);
38477
- const handleMouseUp = (0, import_react54.useCallback)(() => {
38693
+ const handleMouseUp = (0, import_react55.useCallback)(() => {
38478
38694
  setIsDragging(false);
38479
38695
  }, []);
38480
- const handleClose = (0, import_react54.useCallback)(() => {
38696
+ const handleClose = (0, import_react55.useCallback)(() => {
38481
38697
  setImageSrc("");
38482
38698
  setImageLoaded(false);
38483
38699
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
38484
38700
  setAspectRatio("square");
38485
38701
  onClose();
38486
38702
  }, [onClose]);
38487
- const handleCrop = (0, import_react54.useCallback)(() => {
38703
+ const handleCrop = (0, import_react55.useCallback)(() => {
38488
38704
  const image = imageRef.current;
38489
38705
  if (!image) return;
38490
38706
  const cropDims = getCropDimensions();
@@ -38537,7 +38753,7 @@ var LogoCropper = ({
38537
38753
  setAspectRatio("square");
38538
38754
  onClose();
38539
38755
  }, [cropSettings, onCrop, getCropDimensions, outputSize, onClose]);
38540
- const handleScaleChange = (0, import_react54.useCallback)((value) => {
38756
+ const handleScaleChange = (0, import_react55.useCallback)((value) => {
38541
38757
  const cropDims = getCropDimensions();
38542
38758
  const minScale2 = Math.max(
38543
38759
  cropDims.width / imageNaturalSize.width,
@@ -38548,7 +38764,7 @@ var LogoCropper = ({
38548
38764
  scale: Math.max(value, minScale2)
38549
38765
  }));
38550
38766
  }, [imageNaturalSize, getCropDimensions]);
38551
- const handleRotation = (0, import_react54.useCallback)((direction) => {
38767
+ const handleRotation = (0, import_react55.useCallback)((direction) => {
38552
38768
  setCropSettings((prev) => ({
38553
38769
  ...prev,
38554
38770
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -38833,15 +39049,15 @@ var BrandingTab = ({
38833
39049
  }) => {
38834
39050
  const muiTheme = (0, import_material46.useTheme)();
38835
39051
  const isMobile = (0, import_material46.useMediaQuery)(muiTheme.breakpoints.down("sm"));
38836
- const [dragOver, setDragOver] = (0, import_react55.useState)(false);
38837
- const [saveStatus, setSaveStatus] = (0, import_react55.useState)("idle");
38838
- const [snackbarMessage, setSnackbarMessage] = (0, import_react55.useState)("");
38839
- const [showSnackbar, setShowSnackbar] = (0, import_react55.useState)(false);
38840
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react55.useState)("success");
38841
- const [cropperOpen, setCropperOpen] = (0, import_react55.useState)(false);
38842
- const [selectedImageFile, setSelectedImageFile] = (0, import_react55.useState)(null);
38843
- const fileInputRef = (0, import_react55.useRef)(null);
38844
- const importInputRef = (0, import_react55.useRef)(null);
39052
+ const [dragOver, setDragOver] = (0, import_react56.useState)(false);
39053
+ const [saveStatus, setSaveStatus] = (0, import_react56.useState)("idle");
39054
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react56.useState)("");
39055
+ const [showSnackbar, setShowSnackbar] = (0, import_react56.useState)(false);
39056
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react56.useState)("success");
39057
+ const [cropperOpen, setCropperOpen] = (0, import_react56.useState)(false);
39058
+ const [selectedImageFile, setSelectedImageFile] = (0, import_react56.useState)(null);
39059
+ const fileInputRef = (0, import_react56.useRef)(null);
39060
+ const importInputRef = (0, import_react56.useRef)(null);
38845
39061
  const getDefaultLogo = () => {
38846
39062
  return muiTheme.palette.mode === "light" ? lightLogo2 : banditAiLogo;
38847
39063
  };
@@ -39468,11 +39684,11 @@ var BrandingTab = ({
39468
39684
  var BrandingTab_default = BrandingTab;
39469
39685
 
39470
39686
  // src/management/components/KnowledgeHubTab.tsx
39471
- var import_react60 = require("react");
39687
+ var import_react61 = require("react");
39472
39688
  var import_material50 = require("@mui/material");
39473
39689
 
39474
39690
  // src/management/components/KnowledgeTab.tsx
39475
- var import_react58 = require("react");
39691
+ var import_react59 = require("react");
39476
39692
  var import_uuid6 = require("uuid");
39477
39693
  var import_material48 = require("@mui/material");
39478
39694
  init_knowledge_file_modal();
@@ -39482,7 +39698,7 @@ init_authenticationStore();
39482
39698
  init_useFeatures();
39483
39699
 
39484
39700
  // src/components/shared/ProcessingOverlay.tsx
39485
- var import_react56 = require("react");
39701
+ var import_react57 = require("react");
39486
39702
  var import_material47 = require("@mui/material");
39487
39703
  var import_lucide_react16 = require("lucide-react");
39488
39704
  var import_jsx_runtime47 = require("react/jsx-runtime");
@@ -39555,17 +39771,17 @@ var ProcessingOverlay = ({
39555
39771
  customMessages
39556
39772
  }) => {
39557
39773
  const theme = (0, import_material47.useTheme)();
39558
- const [messageIndex, setMessageIndex] = (0, import_react56.useState)(0);
39559
- const [sparkles, setSparkles] = (0, import_react56.useState)([]);
39774
+ const [messageIndex, setMessageIndex] = (0, import_react57.useState)(0);
39775
+ const [sparkles, setSparkles] = (0, import_react57.useState)([]);
39560
39776
  const messages = customMessages || cleverMessages;
39561
- (0, import_react56.useEffect)(() => {
39777
+ (0, import_react57.useEffect)(() => {
39562
39778
  if (!open) return;
39563
39779
  const interval = setInterval(() => {
39564
39780
  setMessageIndex((prev) => (prev + 1) % messages.length);
39565
39781
  }, 3e3);
39566
39782
  return () => clearInterval(interval);
39567
39783
  }, [open, messages.length]);
39568
- (0, import_react56.useEffect)(() => {
39784
+ (0, import_react57.useEffect)(() => {
39569
39785
  if (!open) return;
39570
39786
  const generateSparkles = () => {
39571
39787
  const newSparkles = Array.from({ length: 5 }, (_, i) => ({
@@ -39777,16 +39993,16 @@ var ProcessingOverlay = ({
39777
39993
  var ProcessingOverlay_default = ProcessingOverlay;
39778
39994
 
39779
39995
  // src/hooks/useProcessingOverlay.ts
39780
- var import_react57 = require("react");
39996
+ var import_react58 = require("react");
39781
39997
  var useProcessingOverlay = () => {
39782
- const [processingState, setProcessingState] = (0, import_react57.useState)({
39998
+ const [processingState, setProcessingState] = (0, import_react58.useState)({
39783
39999
  isVisible: false,
39784
40000
  step: "upload",
39785
40001
  progress: 0,
39786
40002
  title: "Processing...",
39787
40003
  customMessages: void 0
39788
40004
  });
39789
- const showProcessing = (0, import_react57.useCallback)((title = "Processing...", messages) => {
40005
+ const showProcessing = (0, import_react58.useCallback)((title = "Processing...", messages) => {
39790
40006
  setProcessingState({
39791
40007
  isVisible: true,
39792
40008
  step: "upload",
@@ -39795,13 +40011,13 @@ var useProcessingOverlay = () => {
39795
40011
  customMessages: messages
39796
40012
  });
39797
40013
  }, []);
39798
- const hideProcessing = (0, import_react57.useCallback)(() => {
40014
+ const hideProcessing = (0, import_react58.useCallback)(() => {
39799
40015
  setProcessingState((prev) => ({
39800
40016
  ...prev,
39801
40017
  isVisible: false
39802
40018
  }));
39803
40019
  }, []);
39804
- const updateProgress = (0, import_react57.useCallback)((step, progress) => {
40020
+ const updateProgress = (0, import_react58.useCallback)((step, progress) => {
39805
40021
  setProcessingState((prev) => ({
39806
40022
  ...prev,
39807
40023
  step,
@@ -39953,28 +40169,28 @@ var KnowledgeTab = ({
39953
40169
  } = useVectorStore();
39954
40170
  const { showProcessing, hideProcessing, updateProgress, processingState } = useProcessingOverlay();
39955
40171
  const shouldUseVector = (features.isAdmin() || features.hasAdvancedSearch() || features.hasAdvancedMemories()) && isAdvancedVectorFeaturesEnabled && isVectorEnabled;
39956
- const [clearDocsDialogOpen, setClearDocsDialogOpen] = (0, import_react58.useState)(false);
39957
- const [selectedDoc, setSelectedDoc] = (0, import_react58.useState)(null);
39958
- const [vectorDocuments, setVectorDocuments] = (0, import_react58.useState)([]);
39959
- const [loadingVectorDocs, setLoadingVectorDocs] = (0, import_react58.useState)(false);
39960
- const [searchQuery, setSearchQuery] = (0, import_react58.useState)("");
39961
- const [selectedCategory, setSelectedCategory] = (0, import_react58.useState)("all");
39962
- const [contentSourceFilter, setContentSourceFilter] = (0, import_react58.useState)("all");
39963
- const [viewMode, setViewMode] = (0, import_react58.useState)("grid");
39964
- const [sortBy, setSortBy] = (0, import_react58.useState)("date");
39965
- const [sortOrder, setSortOrder] = (0, import_react58.useState)("desc");
39966
- const [selectedDocuments, setSelectedDocuments] = (0, import_react58.useState)([]);
39967
- const [showFilters, setShowFilters] = (0, import_react58.useState)(false);
39968
- const [uploadStatuses, setUploadStatuses] = (0, import_react58.useState)([]);
39969
- const [filterMenuAnchor, setFilterMenuAnchor] = (0, import_react58.useState)(null);
39970
- const [snackbarMessage, setSnackbarMessage] = (0, import_react58.useState)("");
39971
- const [showSnackbar, setShowSnackbar] = (0, import_react58.useState)(false);
39972
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react58.useState)("success");
39973
- const [deletingDocuments, setDeletingDocuments] = (0, import_react58.useState)(/* @__PURE__ */ new Set());
40172
+ const [clearDocsDialogOpen, setClearDocsDialogOpen] = (0, import_react59.useState)(false);
40173
+ const [selectedDoc, setSelectedDoc] = (0, import_react59.useState)(null);
40174
+ const [vectorDocuments, setVectorDocuments] = (0, import_react59.useState)([]);
40175
+ const [loadingVectorDocs, setLoadingVectorDocs] = (0, import_react59.useState)(false);
40176
+ const [searchQuery, setSearchQuery] = (0, import_react59.useState)("");
40177
+ const [selectedCategory, setSelectedCategory] = (0, import_react59.useState)("all");
40178
+ const [contentSourceFilter, setContentSourceFilter] = (0, import_react59.useState)("all");
40179
+ const [viewMode, setViewMode] = (0, import_react59.useState)("grid");
40180
+ const [sortBy, setSortBy] = (0, import_react59.useState)("date");
40181
+ const [sortOrder, setSortOrder] = (0, import_react59.useState)("desc");
40182
+ const [selectedDocuments, setSelectedDocuments] = (0, import_react59.useState)([]);
40183
+ const [showFilters, setShowFilters] = (0, import_react59.useState)(false);
40184
+ const [uploadStatuses, setUploadStatuses] = (0, import_react59.useState)([]);
40185
+ const [filterMenuAnchor, setFilterMenuAnchor] = (0, import_react59.useState)(null);
40186
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react59.useState)("");
40187
+ const [showSnackbar, setShowSnackbar] = (0, import_react59.useState)(false);
40188
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react59.useState)("success");
40189
+ const [deletingDocuments, setDeletingDocuments] = (0, import_react59.useState)(/* @__PURE__ */ new Set());
39974
40190
  const hasTeam = !!(authStore.user?.teamSid || authStore.user?.teamId);
39975
- const [shareWithTeam, setShareWithTeam] = (0, import_react58.useState)(false);
39976
- const [dragActive, setDragActive] = (0, import_react58.useState)(false);
39977
- const mapVectorDocsToKnowledgeDocs = (0, import_react58.useCallback)((vectorDocs) => {
40191
+ const [shareWithTeam, setShareWithTeam] = (0, import_react59.useState)(false);
40192
+ const [dragActive, setDragActive] = (0, import_react59.useState)(false);
40193
+ const mapVectorDocsToKnowledgeDocs = (0, import_react59.useCallback)((vectorDocs) => {
39978
40194
  return vectorDocs.map((doc) => {
39979
40195
  const primaryId = doc.id ?? doc.fileId ?? doc._id;
39980
40196
  const docId = typeof primaryId === "string" ? primaryId : primaryId ? JSON.stringify(primaryId) : (0, import_uuid6.v4)();
@@ -40002,7 +40218,7 @@ var KnowledgeTab = ({
40002
40218
  };
40003
40219
  });
40004
40220
  }, []);
40005
- const loadVectorDocuments = (0, import_react58.useCallback)(async () => {
40221
+ const loadVectorDocuments = (0, import_react59.useCallback)(async () => {
40006
40222
  if (!shouldUseVector) {
40007
40223
  return;
40008
40224
  }
@@ -40017,12 +40233,12 @@ var KnowledgeTab = ({
40017
40233
  setLoadingVectorDocs(false);
40018
40234
  }
40019
40235
  }, [shouldUseVector, getUserDocuments, mapVectorDocsToKnowledgeDocs]);
40020
- (0, import_react58.useEffect)(() => {
40236
+ (0, import_react59.useEffect)(() => {
40021
40237
  if (shouldUseVector) {
40022
40238
  loadVectorDocuments();
40023
40239
  }
40024
40240
  }, [shouldUseVector, loadVectorDocuments]);
40025
- const filteredAndSortedDocuments = (0, import_react58.useMemo)(() => {
40241
+ const filteredAndSortedDocuments = (0, import_react59.useMemo)(() => {
40026
40242
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40027
40243
  let filtered = sourceDocuments;
40028
40244
  if (searchQuery) {
@@ -40072,12 +40288,12 @@ var KnowledgeTab = ({
40072
40288
  });
40073
40289
  return filtered;
40074
40290
  }, [documents, vectorDocuments, shouldUseVector, searchQuery, selectedCategory, contentSourceFilter, sortBy, sortOrder]);
40075
- const categories = (0, import_react58.useMemo)(() => {
40291
+ const categories = (0, import_react59.useMemo)(() => {
40076
40292
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40077
40293
  const cats = new Set(sourceDocuments.map((doc) => getFileTypeInfo3(doc.name).category));
40078
40294
  return Array.from(cats).sort();
40079
40295
  }, [documents, vectorDocuments, shouldUseVector]);
40080
- const statistics = (0, import_react58.useMemo)(() => {
40296
+ const statistics = (0, import_react59.useMemo)(() => {
40081
40297
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40082
40298
  const totalSize = sourceDocuments.reduce((sum, doc) => {
40083
40299
  if (shouldUseVector && doc.size) {
@@ -41099,7 +41315,7 @@ var KnowledgeTab = ({
41099
41315
  var KnowledgeTab_default = KnowledgeTab;
41100
41316
 
41101
41317
  // src/management/components/SeedPacksTab.tsx
41102
- var import_react59 = require("react");
41318
+ var import_react60 = require("react");
41103
41319
  var import_material49 = require("@mui/material");
41104
41320
  init_packageSettingsStore();
41105
41321
  init_authenticationStore();
@@ -41708,45 +41924,45 @@ var SeedPacksTab = () => {
41708
41924
  const seedPackAdminRoles = /* @__PURE__ */ new Set(["admin", "super-user", "team_admin", "team_owner"]);
41709
41925
  const userRoles = authStore.user?.roles ?? [];
41710
41926
  const canManage = userRoles.some((role) => seedPackAdminRoles.has(role));
41711
- const [seedPacks, setSeedPacks] = (0, import_react59.useState)([]);
41712
- const [selectedSid, setSelectedSid] = (0, import_react59.useState)(null);
41713
- const [selectedSeedPack, setSelectedSeedPack] = (0, import_react59.useState)(null);
41714
- const [draft, setDraft] = (0, import_react59.useState)({
41927
+ const [seedPacks, setSeedPacks] = (0, import_react60.useState)([]);
41928
+ const [selectedSid, setSelectedSid] = (0, import_react60.useState)(null);
41929
+ const [selectedSeedPack, setSelectedSeedPack] = (0, import_react60.useState)(null);
41930
+ const [draft, setDraft] = (0, import_react60.useState)({
41715
41931
  name: "",
41716
41932
  description: "",
41717
41933
  content: ""
41718
41934
  });
41719
- const [tagsInput, setTagsInput] = (0, import_react59.useState)("");
41720
- const [importedFiles, setImportedFiles] = (0, import_react59.useState)([]);
41721
- const [createImportedFiles, setCreateImportedFiles] = (0, import_react59.useState)([]);
41722
- const [previewFile, setPreviewFile] = (0, import_react59.useState)(null);
41723
- const fileInputRef = (0, import_react59.useRef)(null);
41724
- const wikiFolderInputRef = (0, import_react59.useRef)(null);
41725
- const createFileInputRef = (0, import_react59.useRef)(null);
41726
- const createWikiFolderInputRef = (0, import_react59.useRef)(null);
41727
- const [isLoadingList, setIsLoadingList] = (0, import_react59.useState)(false);
41728
- const [isLoadingDetail, setIsLoadingDetail] = (0, import_react59.useState)(false);
41729
- const [isSaving, setIsSaving] = (0, import_react59.useState)(false);
41730
- const [isPublishing, setIsPublishing] = (0, import_react59.useState)(false);
41731
- const [isArchiving, setIsArchiving] = (0, import_react59.useState)(false);
41732
- const [isDeleting, setIsDeleting] = (0, import_react59.useState)(false);
41733
- const [isCreating, setIsCreating] = (0, import_react59.useState)(false);
41734
- const [createDialogOpen, setCreateDialogOpen] = (0, import_react59.useState)(false);
41735
- const [publishDialogOpen, setPublishDialogOpen] = (0, import_react59.useState)(false);
41736
- const [archiveDialogOpen, setArchiveDialogOpen] = (0, import_react59.useState)(false);
41737
- const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react59.useState)(false);
41738
- const [newPackName, setNewPackName] = (0, import_react59.useState)("");
41739
- const [newPackDescription, setNewPackDescription] = (0, import_react59.useState)("");
41740
- const [newPackTags, setNewPackTags] = (0, import_react59.useState)("");
41741
- const [snackbarOpen, setSnackbarOpen] = (0, import_react59.useState)(false);
41742
- const [snackbarMessage, setSnackbarMessage] = (0, import_react59.useState)("");
41743
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react59.useState)("success");
41744
- const parsedTags = (0, import_react59.useMemo)(() => parseTags(tagsInput), [tagsInput]);
41745
- const normalizedSelectedTags = (0, import_react59.useMemo)(
41935
+ const [tagsInput, setTagsInput] = (0, import_react60.useState)("");
41936
+ const [importedFiles, setImportedFiles] = (0, import_react60.useState)([]);
41937
+ const [createImportedFiles, setCreateImportedFiles] = (0, import_react60.useState)([]);
41938
+ const [previewFile, setPreviewFile] = (0, import_react60.useState)(null);
41939
+ const fileInputRef = (0, import_react60.useRef)(null);
41940
+ const wikiFolderInputRef = (0, import_react60.useRef)(null);
41941
+ const createFileInputRef = (0, import_react60.useRef)(null);
41942
+ const createWikiFolderInputRef = (0, import_react60.useRef)(null);
41943
+ const [isLoadingList, setIsLoadingList] = (0, import_react60.useState)(false);
41944
+ const [isLoadingDetail, setIsLoadingDetail] = (0, import_react60.useState)(false);
41945
+ const [isSaving, setIsSaving] = (0, import_react60.useState)(false);
41946
+ const [isPublishing, setIsPublishing] = (0, import_react60.useState)(false);
41947
+ const [isArchiving, setIsArchiving] = (0, import_react60.useState)(false);
41948
+ const [isDeleting, setIsDeleting] = (0, import_react60.useState)(false);
41949
+ const [isCreating, setIsCreating] = (0, import_react60.useState)(false);
41950
+ const [createDialogOpen, setCreateDialogOpen] = (0, import_react60.useState)(false);
41951
+ const [publishDialogOpen, setPublishDialogOpen] = (0, import_react60.useState)(false);
41952
+ const [archiveDialogOpen, setArchiveDialogOpen] = (0, import_react60.useState)(false);
41953
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react60.useState)(false);
41954
+ const [newPackName, setNewPackName] = (0, import_react60.useState)("");
41955
+ const [newPackDescription, setNewPackDescription] = (0, import_react60.useState)("");
41956
+ const [newPackTags, setNewPackTags] = (0, import_react60.useState)("");
41957
+ const [snackbarOpen, setSnackbarOpen] = (0, import_react60.useState)(false);
41958
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react60.useState)("");
41959
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react60.useState)("success");
41960
+ const parsedTags = (0, import_react60.useMemo)(() => parseTags(tagsInput), [tagsInput]);
41961
+ const normalizedSelectedTags = (0, import_react60.useMemo)(
41746
41962
  () => normalizeTags(selectedSeedPack?.tags),
41747
41963
  [selectedSeedPack?.tags]
41748
41964
  );
41749
- const isDirty = (0, import_react59.useMemo)(() => {
41965
+ const isDirty = (0, import_react60.useMemo)(() => {
41750
41966
  if (!selectedSeedPack) {
41751
41967
  return false;
41752
41968
  }
@@ -41757,17 +41973,17 @@ var SeedPacksTab = () => {
41757
41973
  return nameChanged || descriptionChanged || contentChanged || tagsChanged;
41758
41974
  }, [draft, parsedTags, normalizedSelectedTags, selectedSeedPack]);
41759
41975
  const isReadOnly = !canManage || selectedSeedPack?.status === "archived";
41760
- const sortedSeedPacks = (0, import_react59.useMemo)(() => {
41976
+ const sortedSeedPacks = (0, import_react60.useMemo)(() => {
41761
41977
  return [...seedPacks].sort((a, b) => getSeedPackTimestamp(b) - getSeedPackTimestamp(a));
41762
41978
  }, [seedPacks]);
41763
41979
  const scopeLabel = isTeamScope ? "Team scope" : "Personal scope";
41764
41980
  const scopeDescription = isTeamScope ? "Applies to all members of your team." : "Applies only to your account.";
41765
- const showSnackbar = (0, import_react59.useCallback)((message, severity) => {
41981
+ const showSnackbar = (0, import_react60.useCallback)((message, severity) => {
41766
41982
  setSnackbarMessage(message);
41767
41983
  setSnackbarSeverity(severity);
41768
41984
  setSnackbarOpen(true);
41769
41985
  }, []);
41770
- const hydrateDraft = (0, import_react59.useCallback)((pack) => {
41986
+ const hydrateDraft = (0, import_react60.useCallback)((pack) => {
41771
41987
  setDraft({
41772
41988
  name: pack.name ?? "",
41773
41989
  description: pack.description ?? "",
@@ -41777,14 +41993,14 @@ var SeedPacksTab = () => {
41777
41993
  setImportedFiles([]);
41778
41994
  setPreviewFile(null);
41779
41995
  }, []);
41780
- const resetCreateDialog = (0, import_react59.useCallback)(() => {
41996
+ const resetCreateDialog = (0, import_react60.useCallback)(() => {
41781
41997
  setCreateDialogOpen(false);
41782
41998
  setNewPackName("");
41783
41999
  setNewPackDescription("");
41784
42000
  setNewPackTags("");
41785
42001
  setCreateImportedFiles([]);
41786
42002
  }, []);
41787
- const refreshSeedPacks = (0, import_react59.useCallback)(
42003
+ const refreshSeedPacks = (0, import_react60.useCallback)(
41788
42004
  async (nextSelectedSid) => {
41789
42005
  if (!gatewayConfigured) {
41790
42006
  return;
@@ -41809,7 +42025,7 @@ var SeedPacksTab = () => {
41809
42025
  },
41810
42026
  [gatewayConfigured, selectedSid, showSnackbar]
41811
42027
  );
41812
- const loadSeedPackDetail = (0, import_react59.useCallback)(
42028
+ const loadSeedPackDetail = (0, import_react60.useCallback)(
41813
42029
  async (sid) => {
41814
42030
  if (!gatewayConfigured) {
41815
42031
  return;
@@ -41831,15 +42047,15 @@ var SeedPacksTab = () => {
41831
42047
  },
41832
42048
  [gatewayConfigured, hydrateDraft, showSnackbar]
41833
42049
  );
41834
- (0, import_react59.useEffect)(() => {
42050
+ (0, import_react60.useEffect)(() => {
41835
42051
  void refreshSeedPacks();
41836
42052
  }, [refreshSeedPacks, authStore.token]);
41837
- (0, import_react59.useEffect)(() => {
42053
+ (0, import_react60.useEffect)(() => {
41838
42054
  if (selectedSid) {
41839
42055
  void loadSeedPackDetail(selectedSid);
41840
42056
  }
41841
42057
  }, [selectedSid, loadSeedPackDetail]);
41842
- (0, import_react59.useEffect)(() => {
42058
+ (0, import_react60.useEffect)(() => {
41843
42059
  const setDirectoryUploadAttributes = (input) => {
41844
42060
  if (!input) {
41845
42061
  return;
@@ -41855,7 +42071,7 @@ var SeedPacksTab = () => {
41855
42071
  setSelectedSeedPack(pack);
41856
42072
  hydrateDraft(pack);
41857
42073
  };
41858
- const handleImportFiles = (0, import_react59.useCallback)(
42074
+ const handleImportFiles = (0, import_react60.useCallback)(
41859
42075
  async (files, source = "local") => {
41860
42076
  if (!files || files.length === 0) {
41861
42077
  return;
@@ -41898,24 +42114,24 @@ ${combined}` : combined;
41898
42114
  },
41899
42115
  [importedFiles, showSnackbar]
41900
42116
  );
41901
- const handleFileInputChange = (0, import_react59.useCallback)(
42117
+ const handleFileInputChange = (0, import_react60.useCallback)(
41902
42118
  async (event) => {
41903
42119
  await handleImportFiles(event.target.files, "local");
41904
42120
  event.target.value = "";
41905
42121
  },
41906
42122
  [handleImportFiles]
41907
42123
  );
41908
- const handleWikiFolderInputChange = (0, import_react59.useCallback)(
42124
+ const handleWikiFolderInputChange = (0, import_react60.useCallback)(
41909
42125
  async (event) => {
41910
42126
  await handleImportFiles(event.target.files, "azure-wiki");
41911
42127
  event.target.value = "";
41912
42128
  },
41913
42129
  [handleImportFiles]
41914
42130
  );
41915
- const handleRemoveImportedFile = (0, import_react59.useCallback)((id) => {
42131
+ const handleRemoveImportedFile = (0, import_react60.useCallback)((id) => {
41916
42132
  setImportedFiles((prev) => prev.filter((file) => file.id !== id));
41917
42133
  }, []);
41918
- const handleCreateImportFiles = (0, import_react59.useCallback)(
42134
+ const handleCreateImportFiles = (0, import_react60.useCallback)(
41919
42135
  async (files, source = "local") => {
41920
42136
  if (!files || files.length === 0) {
41921
42137
  return;
@@ -41936,24 +42152,24 @@ ${combined}` : combined;
41936
42152
  },
41937
42153
  [showSnackbar]
41938
42154
  );
41939
- const handleCreateFileInputChange = (0, import_react59.useCallback)(
42155
+ const handleCreateFileInputChange = (0, import_react60.useCallback)(
41940
42156
  async (event) => {
41941
42157
  await handleCreateImportFiles(event.target.files, "local");
41942
42158
  event.target.value = "";
41943
42159
  },
41944
42160
  [handleCreateImportFiles]
41945
42161
  );
41946
- const handleCreateWikiFolderInputChange = (0, import_react59.useCallback)(
42162
+ const handleCreateWikiFolderInputChange = (0, import_react60.useCallback)(
41947
42163
  async (event) => {
41948
42164
  await handleCreateImportFiles(event.target.files, "azure-wiki");
41949
42165
  event.target.value = "";
41950
42166
  },
41951
42167
  [handleCreateImportFiles]
41952
42168
  );
41953
- const handleRemoveCreateImportedFile = (0, import_react59.useCallback)((id) => {
42169
+ const handleRemoveCreateImportedFile = (0, import_react60.useCallback)((id) => {
41954
42170
  setCreateImportedFiles((prev) => prev.filter((file) => file.id !== id));
41955
42171
  }, []);
41956
- const buildDraftPayload2 = (0, import_react59.useCallback)(() => {
42172
+ const buildDraftPayload2 = (0, import_react60.useCallback)(() => {
41957
42173
  const name = draft.name.trim();
41958
42174
  if (!name) {
41959
42175
  showSnackbar("Seed pack name is required.", "error");
@@ -41967,7 +42183,7 @@ ${combined}` : combined;
41967
42183
  contentType: "markdown"
41968
42184
  };
41969
42185
  }, [draft, parsedTags, showSnackbar]);
41970
- const saveDraft = (0, import_react59.useCallback)(async () => {
42186
+ const saveDraft = (0, import_react60.useCallback)(async () => {
41971
42187
  if (!selectedSeedPack) {
41972
42188
  return null;
41973
42189
  }
@@ -42685,9 +42901,9 @@ var KnowledgeHubTab = (props) => {
42685
42901
  const theme = (0, import_material50.useTheme)();
42686
42902
  const isMobile = (0, import_material50.useMediaQuery)(theme.breakpoints.down("sm"));
42687
42903
  const { seedPacksEnabled = false } = props;
42688
- const [tabIndex, setTabIndex] = (0, import_react60.useState)(0);
42904
+ const [tabIndex, setTabIndex] = (0, import_react61.useState)(0);
42689
42905
  const effectiveTabIndex = seedPacksEnabled ? tabIndex : 0;
42690
- (0, import_react60.useEffect)(() => {
42906
+ (0, import_react61.useEffect)(() => {
42691
42907
  if (!seedPacksEnabled && tabIndex !== 0) {
42692
42908
  setTabIndex(0);
42693
42909
  }
@@ -42737,7 +42953,7 @@ var KnowledgeHubTab = (props) => {
42737
42953
  var KnowledgeHubTab_default = KnowledgeHubTab;
42738
42954
 
42739
42955
  // src/management/components/StorageTab.tsx
42740
- var import_react61 = require("react");
42956
+ var import_react62 = require("react");
42741
42957
  var import_material51 = require("@mui/material");
42742
42958
  init_debugLogger();
42743
42959
  init_indexedDBService();
@@ -43040,20 +43256,20 @@ var clearEntireDatabase = async (dbName) => {
43040
43256
  };
43041
43257
  var StorageTab = ({ currentTheme }) => {
43042
43258
  const theme = (0, import_material51.useTheme)();
43043
- const [storageQuota, setStorageQuota] = (0, import_react61.useState)({
43259
+ const [storageQuota, setStorageQuota] = (0, import_react62.useState)({
43044
43260
  used: 0,
43045
43261
  quota: 0,
43046
43262
  available: 0,
43047
43263
  browserQuotaEstimate: 0
43048
43264
  });
43049
- const [storageCategories, setStorageCategories] = (0, import_react61.useState)([]);
43050
- const [loading, setLoading] = (0, import_react61.useState)(true);
43051
- const [clearAllDialogOpen, setClearAllDialogOpen] = (0, import_react61.useState)(false);
43052
- const [clearCategoryDialog, setClearCategoryDialog] = (0, import_react61.useState)(null);
43053
- const [clearing, setClearing] = (0, import_react61.useState)(false);
43054
- const [snackbarMessage, setSnackbarMessage] = (0, import_react61.useState)("");
43055
- const [showSnackbar, setShowSnackbar] = (0, import_react61.useState)(false);
43056
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react61.useState)("success");
43265
+ const [storageCategories, setStorageCategories] = (0, import_react62.useState)([]);
43266
+ const [loading, setLoading] = (0, import_react62.useState)(true);
43267
+ const [clearAllDialogOpen, setClearAllDialogOpen] = (0, import_react62.useState)(false);
43268
+ const [clearCategoryDialog, setClearCategoryDialog] = (0, import_react62.useState)(null);
43269
+ const [clearing, setClearing] = (0, import_react62.useState)(false);
43270
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react62.useState)("");
43271
+ const [showSnackbar, setShowSnackbar] = (0, import_react62.useState)(false);
43272
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react62.useState)("success");
43057
43273
  const { syncEnabled, isAdvancedVectorFeaturesEnabled } = useConversationSyncStore((state) => ({
43058
43274
  syncEnabled: state.syncEnabled,
43059
43275
  isAdvancedVectorFeaturesEnabled: state.isAdvancedVectorFeaturesEnabled
@@ -43105,18 +43321,18 @@ var StorageTab = ({ currentTheme }) => {
43105
43321
  setLoading(false);
43106
43322
  }
43107
43323
  };
43108
- (0, import_react61.useEffect)(() => {
43324
+ (0, import_react62.useEffect)(() => {
43109
43325
  loadStorageData();
43110
43326
  }, []);
43111
- const totalUsed = (0, import_react61.useMemo)(() => {
43327
+ const totalUsed = (0, import_react62.useMemo)(() => {
43112
43328
  return storageCategories.reduce((sum, cat) => sum + cat.size, 0);
43113
43329
  }, [storageCategories]);
43114
- const usagePercentage = (0, import_react61.useMemo)(() => {
43330
+ const usagePercentage = (0, import_react62.useMemo)(() => {
43115
43331
  if (storageQuota.quota === 0) return 0;
43116
43332
  const percentage = Math.min(storageQuota.used / storageQuota.quota * 100, 100);
43117
43333
  return percentage > 0 && percentage < 0.1 ? 0.1 : percentage;
43118
43334
  }, [storageQuota]);
43119
- const clearableCategories = (0, import_react61.useMemo)(() => {
43335
+ const clearableCategories = (0, import_react62.useMemo)(() => {
43120
43336
  return storageCategories.filter((cat) => cat.canClear);
43121
43337
  }, [storageCategories]);
43122
43338
  const handleClearCategory = async (category) => {
@@ -43732,7 +43948,7 @@ var StorageTab = ({ currentTheme }) => {
43732
43948
  var StorageTab_default = StorageTab;
43733
43949
 
43734
43950
  // src/management/components/ProviderTab.tsx
43735
- var import_react62 = require("react");
43951
+ var import_react63 = require("react");
43736
43952
  var import_material52 = require("@mui/material");
43737
43953
  init_aiProviderStore();
43738
43954
  init_packageSettingsStore();
@@ -43746,7 +43962,7 @@ var ProviderTab = () => {
43746
43962
  const { settings: packageSettings } = usePackageSettingsStore();
43747
43963
  const theme = (0, import_material52.useTheme)();
43748
43964
  const isMobile = (0, import_material52.useMediaQuery)(theme.breakpoints.down("sm"));
43749
- const getSuggestedModel = (0, import_react62.useCallback)((type) => {
43965
+ const getSuggestedModel = (0, import_react63.useCallback)((type) => {
43750
43966
  const configuredDefault = packageSettings?.defaultModel?.trim();
43751
43967
  if (configuredDefault) {
43752
43968
  return configuredDefault;
@@ -43762,7 +43978,7 @@ var ProviderTab = () => {
43762
43978
  return "";
43763
43979
  }
43764
43980
  }, [packageSettings?.defaultModel]);
43765
- const applyDefaultModel = (0, import_react62.useCallback)((config) => {
43981
+ const applyDefaultModel = (0, import_react63.useCallback)((config) => {
43766
43982
  const normalized = { ...config };
43767
43983
  const trimmed = typeof normalized.defaultModel === "string" ? normalized.defaultModel.trim() : void 0;
43768
43984
  const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */ || normalized.type === "bandit" /* BANDIT */;
@@ -43782,7 +43998,7 @@ var ProviderTab = () => {
43782
43998
  }
43783
43999
  return normalized;
43784
44000
  }, [getSuggestedModel]);
43785
- const sanitizeConfigForSave = (0, import_react62.useCallback)((config) => {
44001
+ const sanitizeConfigForSave = (0, import_react63.useCallback)((config) => {
43786
44002
  const sanitized = { ...config };
43787
44003
  if (typeof sanitized.defaultModel === "string") {
43788
44004
  const trimmed = sanitized.defaultModel.trim();
@@ -43794,14 +44010,14 @@ var ProviderTab = () => {
43794
44010
  }
43795
44011
  return sanitized;
43796
44012
  }, []);
43797
- const [providerConfig, setProviderConfig] = (0, import_react62.useState)({
44013
+ const [providerConfig, setProviderConfig] = (0, import_react63.useState)({
43798
44014
  type: "gateway",
43799
44015
  gatewayUrl: packageSettings?.gatewayApiUrl || "",
43800
44016
  provider: "bandit"
43801
44017
  });
43802
- const [snackbarMessage, setSnackbarMessage] = (0, import_react62.useState)("");
43803
- const [showSnackbar, setShowSnackbar] = (0, import_react62.useState)(false);
43804
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react62.useState)("success");
44018
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react63.useState)("");
44019
+ const [showSnackbar, setShowSnackbar] = (0, import_react63.useState)(false);
44020
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react63.useState)("success");
43805
44021
  const saveProviderConfigToDB = async (config) => {
43806
44022
  try {
43807
44023
  const { tokenFactory: _tokenFactory, ...persistableConfig } = config;
@@ -43842,7 +44058,7 @@ var ProviderTab = () => {
43842
44058
  }
43843
44059
  return null;
43844
44060
  };
43845
- const convertAnthropicConfig = (0, import_react62.useCallback)((config) => {
44061
+ const convertAnthropicConfig = (0, import_react63.useCallback)((config) => {
43846
44062
  if (!config) return null;
43847
44063
  if (config.type !== "anthropic" /* ANTHROPIC */) {
43848
44064
  return config;
@@ -43858,7 +44074,7 @@ var ProviderTab = () => {
43858
44074
  };
43859
44075
  return converted;
43860
44076
  }, [packageSettings?.gatewayApiUrl]);
43861
- (0, import_react62.useEffect)(() => {
44077
+ (0, import_react63.useEffect)(() => {
43862
44078
  const initializeProviderConfig = async () => {
43863
44079
  const savedConfig = await loadProviderConfigFromDB();
43864
44080
  if (savedConfig) {
@@ -44328,7 +44544,7 @@ var ProviderTab = () => {
44328
44544
  };
44329
44545
 
44330
44546
  // src/management/components/MCPToolsTabV2.tsx
44331
- var import_react64 = require("react");
44547
+ var import_react65 = require("react");
44332
44548
  var import_material54 = require("@mui/material");
44333
44549
 
44334
44550
  // src/services/mcp/mcpControllerService.ts
@@ -44405,7 +44621,7 @@ async function fetchMcpHealth() {
44405
44621
  }
44406
44622
 
44407
44623
  // src/management/components/McpServersSection.tsx
44408
- var import_react63 = require("react");
44624
+ var import_react64 = require("react");
44409
44625
  var import_material53 = require("@mui/material");
44410
44626
  init_lucide_icons();
44411
44627
  init_mcpServersService();
@@ -44481,17 +44697,17 @@ var CATALOG = [
44481
44697
  }
44482
44698
  ];
44483
44699
  var McpServersSection = () => {
44484
- const [servers, setServers] = (0, import_react63.useState)([]);
44485
- const [loading, setLoading] = (0, import_react63.useState)(false);
44486
- const [error, setError] = (0, import_react63.useState)(null);
44487
- const [form, setForm] = (0, import_react63.useState)(emptyForm);
44488
- const [activeEntry, setActiveEntry] = (0, import_react63.useState)(null);
44489
- const [adding, setAdding] = (0, import_react63.useState)(false);
44490
- const [showForm, setShowForm] = (0, import_react63.useState)(false);
44491
- const [tools, setTools] = (0, import_react63.useState)({});
44700
+ const [servers, setServers] = (0, import_react64.useState)([]);
44701
+ const [loading, setLoading] = (0, import_react64.useState)(false);
44702
+ const [error, setError] = (0, import_react64.useState)(null);
44703
+ const [form, setForm] = (0, import_react64.useState)(emptyForm);
44704
+ const [activeEntry, setActiveEntry] = (0, import_react64.useState)(null);
44705
+ const [adding, setAdding] = (0, import_react64.useState)(false);
44706
+ const [showForm, setShowForm] = (0, import_react64.useState)(false);
44707
+ const [tools, setTools] = (0, import_react64.useState)({});
44492
44708
  const reloadChatTools = useMCPToolsStore((s) => s.loadMcpServerTools);
44493
- const formRef = (0, import_react63.useRef)(null);
44494
- const refresh = (0, import_react63.useCallback)(async () => {
44709
+ const formRef = (0, import_react64.useRef)(null);
44710
+ const refresh = (0, import_react64.useCallback)(async () => {
44495
44711
  setLoading(true);
44496
44712
  setError(null);
44497
44713
  try {
@@ -44502,7 +44718,7 @@ var McpServersSection = () => {
44502
44718
  setLoading(false);
44503
44719
  }
44504
44720
  }, []);
44505
- (0, import_react63.useEffect)(() => {
44721
+ (0, import_react64.useEffect)(() => {
44506
44722
  refresh();
44507
44723
  }, [refresh]);
44508
44724
  const connectedKeys = new Set(servers.map((s) => s.url.replace(/\/+$/, "")));
@@ -44798,10 +45014,10 @@ var import_jsx_runtime54 = require("react/jsx-runtime");
44798
45014
  var MCPToolsTabV2 = () => {
44799
45015
  const { settings } = usePackageSettingsStore();
44800
45016
  const { tools: localTools, loadTools, toggleTool, addTool, updateTool, isLoaded } = useMCPToolsStore();
44801
- const [loading, setLoading] = (0, import_react64.useState)(true);
44802
- const [error, setError] = (0, import_react64.useState)(null);
44803
- const [tools, setTools] = (0, import_react64.useState)([]);
44804
- const [health, setHealth] = (0, import_react64.useState)(null);
45017
+ const [loading, setLoading] = (0, import_react65.useState)(true);
45018
+ const [error, setError] = (0, import_react65.useState)(null);
45019
+ const [tools, setTools] = (0, import_react65.useState)([]);
45020
+ const [health, setHealth] = (0, import_react65.useState)(null);
44805
45021
  const gatewayConfigured = !!settings?.gatewayApiUrl;
44806
45022
  const refresh = async () => {
44807
45023
  setLoading(true);
@@ -44855,7 +45071,7 @@ var MCPToolsTabV2 = () => {
44855
45071
  setLoading(false);
44856
45072
  }
44857
45073
  };
44858
- (0, import_react64.useEffect)(() => {
45074
+ (0, import_react65.useEffect)(() => {
44859
45075
  if (isLoaded) {
44860
45076
  refresh();
44861
45077
  } else {
@@ -44864,7 +45080,7 @@ var MCPToolsTabV2 = () => {
44864
45080
  });
44865
45081
  }
44866
45082
  }, [isLoaded]);
44867
- const localEnabledMap = (0, import_react64.useMemo)(() => {
45083
+ const localEnabledMap = (0, import_react65.useMemo)(() => {
44868
45084
  const map23 = /* @__PURE__ */ new Map();
44869
45085
  const sortedTools = [...localTools].sort((a, b) => {
44870
45086
  if (a.isBuiltIn && !b.isBuiltIn) return -1;
@@ -44995,10 +45211,10 @@ var buildCapabilitiesUrl = (gatewayApiUrl) => {
44995
45211
  return `${trimmed}/api/capabilities`;
44996
45212
  };
44997
45213
  var Management = () => {
44998
- const navigate = (0, import_react_router_dom6.useNavigate)();
45214
+ const navigate = (0, import_react_router_dom7.useNavigate)();
44999
45215
  const notificationService2 = useNotificationService();
45000
45216
  const isMobile = (0, import_useMediaQuery2.default)("(max-width:900px)");
45001
- const [sidebarOpen, setSidebarOpen] = (0, import_react65.useState)(false);
45217
+ const [sidebarOpen, setSidebarOpen] = (0, import_react66.useState)(false);
45002
45218
  const getOptimalFabLogo = async () => {
45003
45219
  const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
45004
45220
  try {
@@ -45038,17 +45254,17 @@ var Management = () => {
45038
45254
  hasTransparentLogo,
45039
45255
  setHasTransparentLogo
45040
45256
  } = useModelStore();
45041
- const [modalOpen, setModalOpen] = (0, import_react65.useState)(false);
45257
+ const [modalOpen, setModalOpen] = (0, import_react66.useState)(false);
45042
45258
  const banditHead5 = "https://cdn.burtson.ai/images/bandit-head.png";
45043
- const [fabLogo, setFabLogo] = (0, import_react65.useState)(banditHead5);
45044
- const [tabIndex, setTabIndex] = (0, import_react65.useState)(4);
45045
- const [logoFile, setLogoFile] = (0, import_react65.useState)(null);
45046
- const [logoBase64, setLogoBase64] = (0, import_react65.useState)(null);
45047
- const [brandingText, setBrandingText] = (0, import_react65.useState)("");
45048
- const [headerMode, setHeaderMode] = (0, import_react65.useState)("logo");
45049
- const [theme, setTheme] = (0, import_react65.useState)("bandit-dark");
45050
- const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react65.useState)(null);
45051
- const [presetAvatar, setPresetAvatar] = (0, import_react65.useState)(null);
45259
+ const [fabLogo, setFabLogo] = (0, import_react66.useState)(banditHead5);
45260
+ const [tabIndex, setTabIndex] = (0, import_react66.useState)(4);
45261
+ const [logoFile, setLogoFile] = (0, import_react66.useState)(null);
45262
+ const [logoBase64, setLogoBase64] = (0, import_react66.useState)(null);
45263
+ const [brandingText, setBrandingText] = (0, import_react66.useState)("");
45264
+ const [headerMode, setHeaderMode] = (0, import_react66.useState)("logo");
45265
+ const [theme, setTheme] = (0, import_react66.useState)("bandit-dark");
45266
+ const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react66.useState)(null);
45267
+ const [presetAvatar, setPresetAvatar] = (0, import_react66.useState)(null);
45052
45268
  const showSnackbarMessage = (message, severity = "success") => {
45053
45269
  if (severity === "success") {
45054
45270
  notificationService2?.showSuccess(message);
@@ -45056,9 +45272,9 @@ var Management = () => {
45056
45272
  notificationService2?.showError(message);
45057
45273
  }
45058
45274
  };
45059
- const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react65.useState)(false);
45060
- const [brandingLoaded, setBrandingLoaded] = (0, import_react65.useState)(false);
45061
- const [isLoadingBranding, setIsLoadingBranding] = (0, import_react65.useState)(false);
45275
+ const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react66.useState)(false);
45276
+ const [brandingLoaded, setBrandingLoaded] = (0, import_react66.useState)(false);
45277
+ const [isLoadingBranding, setIsLoadingBranding] = (0, import_react66.useState)(false);
45062
45278
  const { initModels } = useModelStore();
45063
45279
  const { settings: packageSettings } = usePackageSettingsStore();
45064
45280
  const authToken = useAuthenticationStore((state) => state.token);
@@ -45066,8 +45282,8 @@ var Management = () => {
45066
45282
  const { hasAdminDashboard, hasLimitedAdminDashboard, getCurrentTier, hasAdvancedSearch } = useFeatures();
45067
45283
  const { showAdminPanel, showLimitedAdminPanel } = useFeatureVisibility();
45068
45284
  const { provider: currentProvider, config: currentProviderConfig } = useAIProviderStore();
45069
- const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react65.useState)(false);
45070
- const [localSelectedModel, setLocalSelectedModel] = (0, import_react65.useState)({
45285
+ const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react66.useState)(false);
45286
+ const [localSelectedModel, setLocalSelectedModel] = (0, import_react66.useState)({
45071
45287
  name: "",
45072
45288
  tagline: "",
45073
45289
  systemPrompt: "",
@@ -45080,7 +45296,7 @@ var Management = () => {
45080
45296
  loadDocuments,
45081
45297
  clearAllDocuments
45082
45298
  } = useKnowledgeStore2();
45083
- (0, import_react65.useEffect)(() => {
45299
+ (0, import_react66.useEffect)(() => {
45084
45300
  if (selectedModel) {
45085
45301
  const selected = availableModels.find((m) => m.name === selectedModel);
45086
45302
  if (selected) {
@@ -45104,7 +45320,7 @@ var Management = () => {
45104
45320
  }
45105
45321
  }
45106
45322
  }, [selectedModel, availableModels]);
45107
- const loadBrandingConfig = (0, import_react65.useCallback)(async () => {
45323
+ const loadBrandingConfig = (0, import_react66.useCallback)(async () => {
45108
45324
  if (isLoadingBranding || brandingLoaded) {
45109
45325
  debugLogger.warn("Branding loading already in progress or completed, skipping");
45110
45326
  return;
@@ -45221,15 +45437,15 @@ var Management = () => {
45221
45437
  setTagline,
45222
45438
  setTheme
45223
45439
  ]);
45224
- (0, import_react65.useEffect)(() => {
45440
+ (0, import_react66.useEffect)(() => {
45225
45441
  void loadBrandingConfig();
45226
45442
  }, [loadBrandingConfig]);
45227
45443
  const handleOpenModal = () => setModalOpen(true);
45228
45444
  const handleCloseModal = () => setModalOpen(false);
45229
- (0, import_react65.useEffect)(() => {
45445
+ (0, import_react66.useEffect)(() => {
45230
45446
  getOptimalFabLogo().then(setFabLogo);
45231
45447
  }, []);
45232
- (0, import_react65.useEffect)(() => {
45448
+ (0, import_react66.useEffect)(() => {
45233
45449
  if (logoBase64) {
45234
45450
  setFabLogo(logoBase64);
45235
45451
  } else {
@@ -45682,7 +45898,7 @@ var Management = () => {
45682
45898
  reader.readAsText(file);
45683
45899
  }
45684
45900
  };
45685
- (0, import_react65.useEffect)(() => {
45901
+ (0, import_react66.useEffect)(() => {
45686
45902
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
45687
45903
  setLocalSelectedModel((prev) => ({
45688
45904
  ...prev,
@@ -45690,10 +45906,10 @@ var Management = () => {
45690
45906
  }));
45691
45907
  }
45692
45908
  }, [availableModels, localSelectedModel.selectedModel]);
45693
- (0, import_react65.useEffect)(() => {
45909
+ (0, import_react66.useEffect)(() => {
45694
45910
  loadDocuments();
45695
45911
  }, [loadDocuments]);
45696
- (0, import_react65.useEffect)(() => {
45912
+ (0, import_react66.useEffect)(() => {
45697
45913
  const gatewayApiUrl = packageSettings?.gatewayApiUrl;
45698
45914
  if (!gatewayApiUrl || gatewayApiUrl.toLowerCase().startsWith("playground://")) {
45699
45915
  setSeedPacksEnabled(false);
@@ -45736,7 +45952,7 @@ var Management = () => {
45736
45952
  isActive = false;
45737
45953
  };
45738
45954
  }, [packageSettings?.gatewayApiUrl, authToken]);
45739
- const currentTheme = (0, import_react65.useMemo)(() => {
45955
+ const currentTheme = (0, import_react66.useMemo)(() => {
45740
45956
  const baseTheme = predefinedThemes[theme] || banditDarkTheme;
45741
45957
  return (0, import_styles35.createTheme)(baseTheme, {
45742
45958
  // Management-scoped density: condenses every settings tab at once. This
@@ -45857,7 +46073,7 @@ var Management = () => {
45857
46073
  });
45858
46074
  const preferredDefaultTabIndex = navTabs.findIndex((tab) => tab.label === "Preferences");
45859
46075
  const defaultTabIndex = preferredDefaultTabIndex >= 0 ? preferredDefaultTabIndex : 0;
45860
- (0, import_react65.useEffect)(() => {
46076
+ (0, import_react66.useEffect)(() => {
45861
46077
  setTabIndex((current) => {
45862
46078
  if (current < 0 || current >= navTabs.length) {
45863
46079
  return defaultTabIndex;
@@ -46014,6 +46230,10 @@ var Management = () => {
46014
46230
  justifyContent: "space-between",
46015
46231
  px: 3,
46016
46232
  py: 1.5,
46233
+ // The native shell and installed PWAs run edge-to-edge, so the
46234
+ // sticky bar starts underneath the status bar / notch unless it
46235
+ // reserves the inset itself (chat-app-bar does the same).
46236
+ pt: "calc(12px + env(safe-area-inset-top, 0px))",
46017
46237
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(24,28,40,0.95)" : "rgba(255,255,255,0.95)",
46018
46238
  borderBottom: (theme2) => `1px solid ${theme2.palette.divider}`,
46019
46239
  backdropFilter: "blur(12px)",
@@ -46309,7 +46529,7 @@ var Management = () => {
46309
46529
  ]
46310
46530
  }
46311
46531
  ),
46312
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46532
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46313
46533
  import_material55.Fab,
46314
46534
  {
46315
46535
  "aria-label": "AI",
@@ -46345,7 +46565,7 @@ var Management = () => {
46345
46565
  )
46346
46566
  }
46347
46567
  ),
46348
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
46568
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
46349
46569
  ]
46350
46570
  }
46351
46571
  )
@@ -46354,7 +46574,7 @@ var Management = () => {
46354
46574
  var management_default = Management;
46355
46575
 
46356
46576
  // src/management/components/InterestsEditor.tsx
46357
- var import_react66 = require("react");
46577
+ var import_react67 = require("react");
46358
46578
  var import_material56 = require("@mui/material");
46359
46579
  init_preferencesStore();
46360
46580
  init_getStableQuestionPrompt();
@@ -46367,7 +46587,7 @@ var InterestsEditor = ({
46367
46587
  const updatePreference = usePreferencesStore((s) => s.updatePreference);
46368
46588
  const loadPreferences = usePreferencesStore((s) => s.loadPreferences);
46369
46589
  const isLoaded = usePreferencesStore((s) => s.isLoaded);
46370
- (0, import_react66.useEffect)(() => {
46590
+ (0, import_react67.useEffect)(() => {
46371
46591
  if (!isLoaded) {
46372
46592
  void loadPreferences();
46373
46593
  }
@@ -46399,7 +46619,7 @@ var InterestsEditor = ({
46399
46619
  var InterestsEditor_default = InterestsEditor;
46400
46620
 
46401
46621
  // src/shared/custom-element.ts
46402
- var import_react67 = __toESM(require("react"));
46622
+ var import_react68 = __toESM(require("react"));
46403
46623
  var import_client = __toESM(require("react-dom/client"));
46404
46624
  function defineCustomElement(name, Component) {
46405
46625
  if (customElements.get(name)) return;
@@ -46427,7 +46647,7 @@ function defineCustomElement(name, Component) {
46427
46647
  if (!this.root) {
46428
46648
  this.root = import_client.default.createRoot(this.mountPoint);
46429
46649
  }
46430
- this.root.render(import_react67.default.createElement(Component, props));
46650
+ this.root.render(import_react68.default.createElement(Component, props));
46431
46651
  }
46432
46652
  }
46433
46653
  customElements.define(name, ReactElement);
@@ -46636,7 +46856,7 @@ var getFeatureMatrix = () => featureFlagService.generateFeatureMatrix();
46636
46856
  init_featureFlags();
46637
46857
 
46638
46858
  // src/hooks/useVoices.ts
46639
- var import_react68 = require("react");
46859
+ var import_react69 = require("react");
46640
46860
  init_voiceStore();
46641
46861
  init_packageSettingsStore();
46642
46862
  init_authenticationStore();
@@ -46656,7 +46876,7 @@ var useVoices = () => {
46656
46876
  } = useVoiceStore();
46657
46877
  const gatewayApiUrl = usePackageSettingsStore((state) => state.settings?.gatewayApiUrl);
46658
46878
  const { token } = useAuthenticationStore();
46659
- (0, import_react68.useEffect)(() => {
46879
+ (0, import_react69.useEffect)(() => {
46660
46880
  const isAuthenticated = authenticationService2.isAuthenticated();
46661
46881
  if (gatewayApiUrl && token && isAuthenticated && !isServiceAvailable) {
46662
46882
  debugLogger.debug("Gateway API URL and JWT token available, loading voice models...");
@@ -46784,7 +47004,7 @@ var SubscriptionExpiredModal = ({
46784
47004
  };
46785
47005
 
46786
47006
  // src/guards/SubscriptionExpiredGuard.tsx
46787
- var import_react69 = require("react");
47007
+ var import_react70 = require("react");
46788
47008
  init_useFeatures();
46789
47009
  var import_jsx_runtime58 = require("react/jsx-runtime");
46790
47010
  var SubscriptionExpiredGuard = ({
@@ -46795,9 +47015,9 @@ var SubscriptionExpiredGuard = ({
46795
47015
  allowContinue = false
46796
47016
  }) => {
46797
47017
  const { isExpiredTier, getFullEvaluation } = useFeatures();
46798
- const [showModal, setShowModal] = (0, import_react69.useState)(false);
46799
- const [userDismissed, setUserDismissed] = (0, import_react69.useState)(false);
46800
- (0, import_react69.useEffect)(() => {
47018
+ const [showModal, setShowModal] = (0, import_react70.useState)(false);
47019
+ const [userDismissed, setUserDismissed] = (0, import_react70.useState)(false);
47020
+ (0, import_react70.useEffect)(() => {
46801
47021
  if (isExpiredTier() && !userDismissed) {
46802
47022
  setShowModal(true);
46803
47023
  } else {