@burtson-labs/bandit-engine 2.0.152 → 2.0.153

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-4UZ5QT7B.mjs +16 -0
  2. package/dist/chat-provider.js +6 -30
  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-CVFFNX7H.mjs → chunk-6KOEXQJN.mjs} +8 -32
  8. package/dist/chunk-6KOEXQJN.mjs.map +1 -0
  9. package/dist/{chunk-7ESJJN6D.mjs → chunk-6NYYYKYZ.mjs} +262 -75
  10. package/dist/chunk-6NYYYKYZ.mjs.map +1 -0
  11. package/dist/{chunk-QLATFSSO.mjs → chunk-AJL3JOD6.mjs} +5 -5
  12. package/dist/{chunk-RRCCSN3N.mjs → chunk-B2TJZM4Z.mjs} +2 -2
  13. package/dist/{chunk-LPSM62OE.mjs → chunk-DADHPWB7.mjs} +19 -14
  14. package/dist/chunk-DADHPWB7.mjs.map +1 -0
  15. package/dist/{chunk-U33KBX3Y.mjs → chunk-GQ3X6VPR.mjs} +4 -4
  16. package/dist/{chunk-TYRYAAP2.mjs → chunk-RN7FRSMX.mjs} +3 -3
  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 +788 -591
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +10 -10
  25. package/dist/management/management.js +487 -290
  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-4UZ5QT7B.mjs.map} +0 -0
  42. /package/dist/{chunk-QLATFSSO.mjs.map → chunk-AJL3JOD6.mjs.map} +0 -0
  43. /package/dist/{chunk-RRCCSN3N.mjs.map → chunk-B2TJZM4Z.mjs.map} +0 -0
  44. /package/dist/{chunk-U33KBX3Y.mjs.map → chunk-GQ3X6VPR.mjs.map} +0 -0
  45. /package/dist/{chunk-TYRYAAP2.mjs.map → chunk-RN7FRSMX.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
@@ -3384,7 +3384,7 @@ var init_mcpServersService = __esm({
3384
3384
  });
3385
3385
 
3386
3386
  // src/store/mcpToolsStore.ts
3387
- var import_zustand11, sanitizeMcpToolName, healthCheckTool, webSearchTool, webFetchTool, imageGenerationTool, createFileTool, defaultTools, useMCPToolsStore;
3387
+ var import_zustand11, sanitizeMcpToolName, healthCheckTool, webSearchTool, webFetchTool, createFileTool, defaultTools, useMCPToolsStore;
3388
3388
  var init_mcpToolsStore = __esm({
3389
3389
  "src/store/mcpToolsStore.ts"() {
3390
3390
  "use strict";
@@ -3456,47 +3456,23 @@ var init_mcpToolsStore = __esm({
3456
3456
  method: "GET",
3457
3457
  isBuiltIn: true
3458
3458
  };
3459
- imageGenerationTool = {
3460
- id: "image-generation",
3461
- name: "image_generation",
3462
- description: "Generate high-quality images using DALL-E 3 from text prompts",
3463
- enabled: true,
3464
- type: "function",
3465
- function: {
3466
- name: "image_generation",
3467
- description: "Generate high-quality images using DALL-E 3 from text prompts",
3468
- parameters: {
3469
- type: "object",
3470
- properties: {
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" }
3475
- },
3476
- required: ["prompt"]
3477
- }
3478
- },
3479
- endpoint: "/mcp/generate-image",
3480
- method: "POST",
3481
- isBuiltIn: true
3482
- };
3483
3459
  createFileTool = {
3484
3460
  id: "create-file",
3485
3461
  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.",
3462
+ description: "Create a downloadable file for the user (md, txt, csv, json, html, docx, pptx, pdf). Returns a temporary (~1 hour) download link.",
3487
3463
  enabled: true,
3488
3464
  type: "function",
3489
3465
  function: {
3490
3466
  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.",
3467
+ 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
3468
  parameters: {
3493
3469
  type: "object",
3494
3470
  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'." },
3471
+ content: { type: "string", description: "The file content (HTML preferred for pdf; Markdown for docx/pptx/pdf; raw text for others)." },
3472
+ filename: { type: "string", description: "Desired filename, e.g. 'report.pdf' or 'notes.md'." },
3497
3473
  format: {
3498
3474
  type: "string",
3499
- enum: ["md", "txt", "csv", "json", "html", "xml", "yaml", "docx", "pptx"],
3475
+ enum: ["md", "txt", "csv", "json", "html", "xml", "yaml", "docx", "pptx", "pdf"],
3500
3476
  description: "File format. Defaults to md."
3501
3477
  }
3502
3478
  },
@@ -3507,7 +3483,7 @@ var init_mcpToolsStore = __esm({
3507
3483
  method: "POST",
3508
3484
  isBuiltIn: true
3509
3485
  };
3510
- defaultTools = [healthCheckTool, webSearchTool, webFetchTool, imageGenerationTool, createFileTool];
3486
+ defaultTools = [healthCheckTool, webSearchTool, webFetchTool, createFileTool];
3511
3487
  useMCPToolsStore = (0, import_zustand11.create)((set, get) => ({
3512
3488
  tools: defaultTools,
3513
3489
  isLoaded: false,
@@ -16085,6 +16061,7 @@ var init_engine_picker = __esm({
16085
16061
  const tier = String(getCurrentTier());
16086
16062
  return tier !== "trial" && tier !== "expired" && tier !== "free" && tier !== "basic";
16087
16063
  })();
16064
+ const hideUpgradePrompts = usePackageSettingsStore((s) => s.settings?.hideUpgradePrompts === true);
16088
16065
  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
16066
  if (engines.length === 0) return null;
16090
16067
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
@@ -16163,8 +16140,8 @@ var init_engine_picker = __esm({
16163
16140
  ),
16164
16141
  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
16142
  ] }),
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)(
16143
+ /* @__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" }),
16144
+ isGated && !hideUpgradePrompts && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
16168
16145
  import_material13.Button,
16169
16146
  {
16170
16147
  size: "small",
@@ -19014,12 +18991,14 @@ var init_rate_limit_prompt = __esm({
19014
18991
  import_react_router_dom = require("react-router-dom");
19015
18992
  init_lucide_icons();
19016
18993
  init_rateLimitStore();
18994
+ init_packageSettingsStore();
19017
18995
  init_debugLogger();
19018
18996
  import_jsx_runtime21 = require("react/jsx-runtime");
19019
18997
  RateLimitPrompt = () => {
19020
18998
  const theme = (0, import_material18.useTheme)();
19021
18999
  const prompt = useRateLimitStore((s) => s.prompt);
19022
19000
  const dismiss = useRateLimitStore((s) => s.dismiss);
19001
+ const hideUpgradePrompts = usePackageSettingsStore((s) => s.settings?.hideUpgradePrompts === true);
19023
19002
  const hasLoggedRouterWarningRef = (0, import_react24.useRef)(false);
19024
19003
  let navigate = null;
19025
19004
  try {
@@ -19049,6 +19028,12 @@ var init_rate_limit_prompt = __esm({
19049
19028
  const { scope, frontier } = prompt;
19050
19029
  const title = scope === "weekly" ? "You've reached your weekly limit" : "You've hit your session limit";
19051
19030
  const body = (() => {
19031
+ if (hideUpgradePrompts) {
19032
+ if (frontier) {
19033
+ 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.";
19034
+ }
19035
+ 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.";
19036
+ }
19052
19037
  if (frontier) {
19053
19038
  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
19039
  }
@@ -19093,7 +19078,7 @@ var init_rate_limit_prompt = __esm({
19093
19078
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "subtitle2", sx: { fontWeight: 600, color: theme.palette.text.primary }, children: title }),
19094
19079
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_material18.Typography, { variant: "body2", sx: { color: theme.palette.text.secondary, mt: 0.25 }, children: body }),
19095
19080
  /* @__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)(
19081
+ !hideUpgradePrompts && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
19097
19082
  import_material18.Button,
19098
19083
  {
19099
19084
  size: "small",
@@ -20965,7 +20950,6 @@ TOOL USAGE PROTOCOL (conservative approach)
20965
20950
  - Only call tools for SPECIFIC, CURRENT information that requires real-time data or a source you don't already have:
20966
20951
  * 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
20952
  * 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
20969
20953
  * 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
20954
  * 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
20955
  - For general questions about concepts, definitions, explanations, or how-to topics, use your built-in knowledge WITHOUT calling tools.
@@ -23159,12 +23143,67 @@ var init_FeedbackModal = __esm({
23159
23143
  }
23160
23144
  });
23161
23145
 
23146
+ // src/utils/installedApp.ts
23147
+ var isNativeShell, isStandalonePwa2;
23148
+ var init_installedApp = __esm({
23149
+ "src/utils/installedApp.ts"() {
23150
+ "use strict";
23151
+ isNativeShell = () => {
23152
+ if (typeof window === "undefined") return false;
23153
+ const cap = window.Capacitor;
23154
+ return typeof cap?.isNativePlatform === "function" && cap.isNativePlatform() === true;
23155
+ };
23156
+ isStandalonePwa2 = () => {
23157
+ if (typeof window === "undefined") return false;
23158
+ const nav = window.navigator;
23159
+ return window.matchMedia?.("(display-mode: standalone)").matches || nav.standalone === true;
23160
+ };
23161
+ }
23162
+ });
23163
+
23164
+ // src/hooks/useSafeNavigate.ts
23165
+ var import_react30, import_react_router_dom2, useSafeNavigate;
23166
+ var init_useSafeNavigate = __esm({
23167
+ "src/hooks/useSafeNavigate.ts"() {
23168
+ "use strict";
23169
+ import_react30 = require("react");
23170
+ import_react_router_dom2 = require("react-router-dom");
23171
+ init_debugLogger();
23172
+ useSafeNavigate = () => {
23173
+ const warned = (0, import_react30.useRef)(false);
23174
+ let navigate = null;
23175
+ try {
23176
+ navigate = (0, import_react_router_dom2.useNavigate)();
23177
+ } catch (error) {
23178
+ if (!warned.current) {
23179
+ debugLogger.warn("useSafeNavigate: no Router context; falling back to location", { error });
23180
+ warned.current = true;
23181
+ }
23182
+ navigate = null;
23183
+ }
23184
+ return (to) => {
23185
+ if (typeof window !== "undefined" && /^[a-z]+:\/\//i.test(to)) {
23186
+ window.location.href = to;
23187
+ return;
23188
+ }
23189
+ if (navigate) {
23190
+ navigate(to);
23191
+ return;
23192
+ }
23193
+ if (typeof window !== "undefined") {
23194
+ window.location.href = to;
23195
+ }
23196
+ };
23197
+ };
23198
+ }
23199
+ });
23200
+
23162
23201
  // 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;
23202
+ var import_react31, import_material21, import_lucide_react7, import_styles12, import_jsx_runtime23, DEFAULT_COLORS2, ProjectManagementModal, project_management_modal_default;
23164
23203
  var init_project_management_modal = __esm({
23165
23204
  "src/chat/project-management-modal.tsx"() {
23166
23205
  "use strict";
23167
- import_react30 = require("react");
23206
+ import_react31 = require("react");
23168
23207
  import_material21 = require("@mui/material");
23169
23208
  import_lucide_react7 = require("lucide-react");
23170
23209
  import_styles12 = require("@mui/material/styles");
@@ -23200,25 +23239,25 @@ var init_project_management_modal = __esm({
23200
23239
  hydrate
23201
23240
  } = useProjectStore();
23202
23241
  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)({
23242
+ const [showCreateForm, setShowCreateForm] = (0, import_react31.useState)(false);
23243
+ const [editingProject, setEditingProject] = (0, import_react31.useState)(null);
23244
+ const [formData, setFormData] = (0, import_react31.useState)({
23206
23245
  name: "",
23207
23246
  description: "",
23208
23247
  instructions: "",
23209
23248
  color: DEFAULT_COLORS2[0]
23210
23249
  });
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)(() => {
23250
+ const [menuAnchor, setMenuAnchor] = (0, import_react31.useState)(null);
23251
+ const [selectedProject, setSelectedProject] = (0, import_react31.useState)(null);
23252
+ const [loading, setLoading] = (0, import_react31.useState)(false);
23253
+ const [error, setError] = (0, import_react31.useState)(null);
23254
+ const modalContainerRef = (0, import_react31.useRef)(null);
23255
+ (0, import_react31.useEffect)(() => {
23217
23256
  if (open && !_hasHydrated) {
23218
23257
  hydrate();
23219
23258
  }
23220
23259
  }, [open, _hasHydrated, hydrate]);
23221
- (0, import_react30.useEffect)(() => {
23260
+ (0, import_react31.useEffect)(() => {
23222
23261
  if (!open) {
23223
23262
  setMenuAnchor(null);
23224
23263
  setSelectedProject(null);
@@ -23753,11 +23792,11 @@ var init_project_management_modal = __esm({
23753
23792
  });
23754
23793
 
23755
23794
  // 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;
23795
+ var import_react32, import_material22, import_lucide_react8, import_styles13, import_jsx_runtime24, MoveConversationModal, move_conversation_modal_default;
23757
23796
  var init_move_conversation_modal = __esm({
23758
23797
  "src/chat/move-conversation-modal.tsx"() {
23759
23798
  "use strict";
23760
- import_react31 = require("react");
23799
+ import_react32 = require("react");
23761
23800
  import_material22 = require("@mui/material");
23762
23801
  import_lucide_react8 = require("lucide-react");
23763
23802
  import_styles13 = require("@mui/material/styles");
@@ -23774,15 +23813,15 @@ var init_move_conversation_modal = __esm({
23774
23813
  const theme = (0, import_styles13.useTheme)();
23775
23814
  const { projects, _hasHydrated, hydrate } = useProjectStore();
23776
23815
  const { moveConversationToProject } = useConversationStore();
23777
- const [selectedProjectId, setSelectedProjectId] = (0, import_react31.useState)(
23816
+ const [selectedProjectId, setSelectedProjectId] = (0, import_react32.useState)(
23778
23817
  currentProjectId
23779
23818
  );
23780
- (0, import_react31.useEffect)(() => {
23819
+ (0, import_react32.useEffect)(() => {
23781
23820
  if (open && !_hasHydrated) {
23782
23821
  hydrate();
23783
23822
  }
23784
23823
  }, [open, _hasHydrated, hydrate]);
23785
- (0, import_react31.useEffect)(() => {
23824
+ (0, import_react32.useEffect)(() => {
23786
23825
  setSelectedProjectId(currentProjectId);
23787
23826
  }, [currentProjectId, open]);
23788
23827
  const handleMove = async () => {
@@ -23924,11 +23963,11 @@ var init_move_conversation_modal = __esm({
23924
23963
  });
23925
23964
 
23926
23965
  // 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;
23966
+ var import_react33, import_material23, import_lucide_react9, import_styles14, import_jsx_runtime25, SimpleConversationItem, simple_conversation_item_default;
23928
23967
  var init_simple_conversation_item = __esm({
23929
23968
  "src/chat/simple-conversation-item.tsx"() {
23930
23969
  "use strict";
23931
- import_react32 = require("react");
23970
+ import_react33 = require("react");
23932
23971
  import_material23 = require("@mui/material");
23933
23972
  import_lucide_react9 = require("lucide-react");
23934
23973
  import_styles14 = require("@mui/material/styles");
@@ -23950,16 +23989,16 @@ var init_simple_conversation_item = __esm({
23950
23989
  }) => {
23951
23990
  const theme = (0, import_styles14.useTheme)();
23952
23991
  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);
23992
+ const [anchorEl, setAnchorEl] = (0, import_react33.useState)(null);
23993
+ const [isEditing, setIsEditing] = (0, import_react33.useState)(false);
23994
+ const [editName, setEditName] = (0, import_react33.useState)(conversation.name);
23995
+ const [isDragging, setIsDragging] = (0, import_react33.useState)(false);
23996
+ const [isTouchDragging, setIsTouchDragging] = (0, import_react33.useState)(false);
23997
+ const [showRenameDialog, setShowRenameDialog] = (0, import_react33.useState)(false);
23998
+ const longPressTimeoutRef = (0, import_react33.useRef)(null);
23999
+ const touchStartPointRef = (0, import_react33.useRef)(null);
24000
+ const activeTouchIdRef = (0, import_react33.useRef)(null);
24001
+ const suppressClickRef = (0, import_react33.useRef)(false);
23963
24002
  const highlightText = (text, query) => {
23964
24003
  if (!query || !query.trim()) {
23965
24004
  return text;
@@ -24098,7 +24137,7 @@ var init_simple_conversation_item = __esm({
24098
24137
  if (!isMobile) return;
24099
24138
  finalizeTouchDrag();
24100
24139
  };
24101
- (0, import_react32.useEffect)(() => {
24140
+ (0, import_react33.useEffect)(() => {
24102
24141
  if (!isTouchDragActive && isTouchDragging) {
24103
24142
  setIsTouchDragging(false);
24104
24143
  }
@@ -24364,11 +24403,11 @@ var init_simple_conversation_item = __esm({
24364
24403
  });
24365
24404
 
24366
24405
  // src/chat/project-header.tsx
24367
- var import_react33, import_material24, import_lucide_react10, import_styles15, import_jsx_runtime26, ProjectHeader, project_header_default;
24406
+ var import_react34, import_material24, import_lucide_react10, import_styles15, import_jsx_runtime26, ProjectHeader, project_header_default;
24368
24407
  var init_project_header = __esm({
24369
24408
  "src/chat/project-header.tsx"() {
24370
24409
  "use strict";
24371
- import_react33 = require("react");
24410
+ import_react34 = require("react");
24372
24411
  import_material24 = require("@mui/material");
24373
24412
  import_lucide_react10 = require("lucide-react");
24374
24413
  import_styles15 = require("@mui/material/styles");
@@ -24392,10 +24431,10 @@ var init_project_header = __esm({
24392
24431
  const theme = (0, import_styles15.useTheme)();
24393
24432
  const { createNewConversation } = useConversationStore();
24394
24433
  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");
24434
+ const [isHovered, setIsHovered] = (0, import_react34.useState)(false);
24435
+ const [isDragOver, setIsDragOver] = (0, import_react34.useState)(false);
24436
+ const [renameDraft, setRenameDraft] = (0, import_react34.useState)(projectName);
24437
+ const renameActionRef = (0, import_react34.useRef)("none");
24399
24438
  const isUngrouped = projectId === null;
24400
24439
  const Icon = isCollapsed ? import_lucide_react10.Folder : import_lucide_react10.FolderOpen;
24401
24440
  const handleAddConversation = (e) => {
@@ -24669,11 +24708,11 @@ var init_tooltips = __esm({
24669
24708
  });
24670
24709
 
24671
24710
  // 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;
24711
+ var import_react35, import_material25, import_lucide_react11, import_styles16, import_jsx_runtime27, BANDIT_AVATAR, coerceOptionalString, deriveInitials, ConversationDrawer, conversation_drawer_default;
24673
24712
  var init_conversation_drawer = __esm({
24674
24713
  "src/chat/conversation-drawer.tsx"() {
24675
24714
  "use strict";
24676
- import_react34 = require("react");
24715
+ import_react35 = require("react");
24677
24716
  import_material25 = require("@mui/material");
24678
24717
  import_lucide_react11 = require("lucide-react");
24679
24718
  init_FeedbackModal();
@@ -24682,6 +24721,8 @@ var init_conversation_drawer = __esm({
24682
24721
  init_projectStore();
24683
24722
  init_authenticationStore();
24684
24723
  init_packageSettingsStore();
24724
+ init_installedApp();
24725
+ init_useSafeNavigate();
24685
24726
  init_brandingService();
24686
24727
  init_authenticationService();
24687
24728
  init_project_management_modal();
@@ -24745,23 +24786,23 @@ var init_conversation_drawer = __esm({
24745
24786
  createProject,
24746
24787
  deleteProject
24747
24788
  } = 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) => {
24789
+ const [projectManagementOpen, setProjectManagementOpen] = (0, import_react35.useState)(false);
24790
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react35.useState)(false);
24791
+ const [collapsedProjects, setCollapsedProjects] = (0, import_react35.useState)(/* @__PURE__ */ new Set());
24792
+ const didInitCollapseRef = (0, import_react35.useRef)(false);
24793
+ const [searchQuery, setSearchQuery] = (0, import_react35.useState)("");
24794
+ const [menuAnchorEl, setMenuAnchorEl] = (0, import_react35.useState)(null);
24795
+ const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react35.useState)(false);
24796
+ const [feedbackOpen, setFeedbackOpen] = (0, import_react35.useState)(false);
24797
+ const [moveModalOpen, setMoveModalOpen] = (0, import_react35.useState)(false);
24798
+ const [conversationToMove, setConversationToMove] = (0, import_react35.useState)(null);
24799
+ const [renameProjectId, setRenameProjectId] = (0, import_react35.useState)(null);
24800
+ const getCustomClaim = (0, import_react35.useCallback)((key) => {
24760
24801
  if (!user2) return void 0;
24761
24802
  const record = user2;
24762
24803
  return coerceOptionalString(record[key]);
24763
24804
  }, [user2]);
24764
- const userDisplayName = (0, import_react34.useMemo)(() => {
24805
+ const userDisplayName = (0, import_react35.useMemo)(() => {
24765
24806
  if (!user2) return void 0;
24766
24807
  const candidateFields = [
24767
24808
  coerceOptionalString(user2.name),
@@ -24776,7 +24817,7 @@ var init_conversation_drawer = __esm({
24776
24817
  if (trimmedEmail) return trimmedEmail;
24777
24818
  return user2.sub;
24778
24819
  }, [user2, getCustomClaim]);
24779
- const userSecondaryText = (0, import_react34.useMemo)(() => {
24820
+ const userSecondaryText = (0, import_react35.useMemo)(() => {
24780
24821
  if (!user2) return void 0;
24781
24822
  const trimmedEmail = coerceOptionalString(user2.email);
24782
24823
  if (trimmedEmail && trimmedEmail !== userDisplayName) {
@@ -24788,13 +24829,13 @@ var init_conversation_drawer = __esm({
24788
24829
  }
24789
24830
  return void 0;
24790
24831
  }, [user2, userDisplayName]);
24791
- const [avatarImage, setAvatarImage] = (0, import_react34.useState)(BANDIT_AVATAR);
24792
- (0, import_react34.useEffect)(() => {
24832
+ const [avatarImage, setAvatarImage] = (0, import_react35.useState)(BANDIT_AVATAR);
24833
+ (0, import_react35.useEffect)(() => {
24793
24834
  const fresh = readPersistedToken();
24794
24835
  const store = useAuthenticationStore.getState();
24795
24836
  if (fresh && fresh !== store.token) store.setToken(fresh);
24796
24837
  }, []);
24797
- (0, import_react34.useEffect)(() => {
24838
+ (0, import_react35.useEffect)(() => {
24798
24839
  let active2 = true;
24799
24840
  let objectUrl = null;
24800
24841
  const resolveAvatar2 = async () => {
@@ -24835,13 +24876,13 @@ var init_conversation_drawer = __esm({
24835
24876
  };
24836
24877
  }, [getCustomClaim]);
24837
24878
  const avatarLabel = userDisplayName || user2?.email || "Bandit";
24838
- const avatarInitials = (0, import_react34.useMemo)(() => deriveInitials(avatarLabel), [avatarLabel]);
24839
- (0, import_react34.useEffect)(() => {
24879
+ const avatarInitials = (0, import_react35.useMemo)(() => deriveInitials(avatarLabel), [avatarLabel]);
24880
+ (0, import_react35.useEffect)(() => {
24840
24881
  if (!projectsHydrated) {
24841
24882
  hydrateProjects();
24842
24883
  }
24843
24884
  }, [projectsHydrated, hydrateProjects]);
24844
- (0, import_react34.useEffect)(() => {
24885
+ (0, import_react35.useEffect)(() => {
24845
24886
  if (projectsHydrated && !didInitCollapseRef.current) {
24846
24887
  didInitCollapseRef.current = true;
24847
24888
  if (projects && projects.length > 0) {
@@ -24854,7 +24895,7 @@ var init_conversation_drawer = __esm({
24854
24895
  const end = Math.min(text.length, idx + query.length + 60);
24855
24896
  return text.slice(start, end).replace(/\s+/g, " ").trim();
24856
24897
  };
24857
- const projectGroups = (0, import_react34.useMemo)(() => {
24898
+ const projectGroups = (0, import_react35.useMemo)(() => {
24858
24899
  const listable = conversations.filter((conversation) => !conversation.incognito);
24859
24900
  const groups = projects.map((project) => ({
24860
24901
  id: project.id,
@@ -24878,7 +24919,7 @@ var init_conversation_drawer = __esm({
24878
24919
  }
24879
24920
  return groups.filter((group) => group.conversations.length > 0 || group.id !== null);
24880
24921
  }, [projects, conversations, collapsedProjects]);
24881
- const filteredProjectGroups = (0, import_react34.useMemo)(() => {
24922
+ const filteredProjectGroups = (0, import_react35.useMemo)(() => {
24882
24923
  if (!searchQuery.trim()) return projectGroups;
24883
24924
  const query = searchQuery.toLowerCase();
24884
24925
  return projectGroups.map((group) => {
@@ -24926,15 +24967,18 @@ var init_conversation_drawer = __esm({
24926
24967
  const syncEnabled = useConversationSyncStore((s) => s.syncEnabled);
24927
24968
  const syncStatus = useConversationSyncStore((s) => s.status);
24928
24969
  const runSync = useConversationSyncStore((s) => s.runSync);
24970
+ const safeNavigate = useSafeNavigate();
24929
24971
  const goToHome = () => {
24930
24972
  const resolvedHomeUrl = preferences.homeUrl?.trim() || usePackageSettingsStore.getState().settings?.homeUrl?.trim() || "";
24931
24973
  if (resolvedHomeUrl) {
24932
24974
  window.location.href = resolvedHomeUrl;
24933
24975
  return;
24934
24976
  }
24935
- const navigatorWithStandalone = window.navigator;
24936
- const isStandalone = window.matchMedia?.("(display-mode: standalone)").matches || navigatorWithStandalone.standalone === true;
24937
- if (isStandalone) {
24977
+ if (isNativeShell()) {
24978
+ safeNavigate("/chat");
24979
+ return;
24980
+ }
24981
+ if (isStandalonePwa2()) {
24938
24982
  try {
24939
24983
  sessionStorage.setItem("banditPwaStayOnHome", "true");
24940
24984
  } catch {
@@ -25405,7 +25449,7 @@ var init_conversation_drawer = __esm({
25405
25449
  import_material25.Box,
25406
25450
  {
25407
25451
  onClick: user2 ? () => {
25408
- window.location.href = "/profile";
25452
+ safeNavigate("/profile");
25409
25453
  } : void 0,
25410
25454
  title: user2 ? "Profile & settings" : void 0,
25411
25455
  sx: {
@@ -25498,7 +25542,7 @@ var init_conversation_drawer = __esm({
25498
25542
  title: "Management & settings",
25499
25543
  onClick: (event) => {
25500
25544
  event.stopPropagation();
25501
- window.location.href = managementPath;
25545
+ safeNavigate(managementPath);
25502
25546
  },
25503
25547
  sx: {
25504
25548
  flexShrink: 0,
@@ -25658,11 +25702,11 @@ var init_conversation_drawer = __esm({
25658
25702
  });
25659
25703
 
25660
25704
  // 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;
25705
+ var import_react36, import_material26, import_lucide_react12, import_styles17, import_jsx_runtime28, BANDIT_AVATAR2, coerceOptionalString2, deriveInitials2, EnhancedMobileConversationsModal, enhanced_mobile_conversations_modal_default;
25662
25706
  var init_enhanced_mobile_conversations_modal = __esm({
25663
25707
  "src/chat/enhanced-mobile-conversations-modal.tsx"() {
25664
25708
  "use strict";
25665
- import_react35 = require("react");
25709
+ import_react36 = require("react");
25666
25710
  import_material26 = require("@mui/material");
25667
25711
  import_lucide_react12 = require("lucide-react");
25668
25712
  import_styles17 = require("@mui/material/styles");
@@ -25670,6 +25714,8 @@ var init_enhanced_mobile_conversations_modal = __esm({
25670
25714
  init_projectStore();
25671
25715
  init_authenticationStore();
25672
25716
  init_packageSettingsStore();
25717
+ init_installedApp();
25718
+ init_useSafeNavigate();
25673
25719
  init_memory_modal();
25674
25720
  init_brandingService();
25675
25721
  init_authenticationService();
@@ -25710,7 +25756,8 @@ var init_enhanced_mobile_conversations_modal = __esm({
25710
25756
  };
25711
25757
  EnhancedMobileConversationsModal = ({
25712
25758
  open,
25713
- onClose
25759
+ onClose,
25760
+ drag
25714
25761
  }) => {
25715
25762
  const theme = (0, import_styles17.useTheme)();
25716
25763
  const { user: user2 } = useAuthenticationStore();
@@ -25737,15 +25784,18 @@ var init_enhanced_mobile_conversations_modal = __esm({
25737
25784
  const syncEnabled = useConversationSyncStore((s) => s.syncEnabled);
25738
25785
  const syncStatus = useConversationSyncStore((s) => s.status);
25739
25786
  const runSync = useConversationSyncStore((s) => s.runSync);
25787
+ const safeNavigate = useSafeNavigate();
25740
25788
  const goToHome = () => {
25741
25789
  const resolvedHomeUrl = preferences.homeUrl?.trim() || usePackageSettingsStore.getState().settings?.homeUrl?.trim() || "";
25742
25790
  if (resolvedHomeUrl) {
25743
25791
  window.location.href = resolvedHomeUrl;
25744
25792
  return;
25745
25793
  }
25746
- const navigatorWithStandalone = window.navigator;
25747
- const isStandalone = window.matchMedia?.("(display-mode: standalone)").matches || navigatorWithStandalone.standalone === true;
25748
- if (isStandalone) {
25794
+ if (isNativeShell()) {
25795
+ safeNavigate("/chat");
25796
+ return;
25797
+ }
25798
+ if (isStandalonePwa2()) {
25749
25799
  try {
25750
25800
  sessionStorage.setItem("banditPwaStayOnHome", "true");
25751
25801
  } catch {
@@ -25756,25 +25806,25 @@ var init_enhanced_mobile_conversations_modal = __esm({
25756
25806
  window.location.href = "/";
25757
25807
  };
25758
25808
  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) => {
25809
+ const [projectManagementOpen, setProjectManagementOpen] = (0, import_react36.useState)(false);
25810
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react36.useState)(false);
25811
+ const [collapsedProjects, setCollapsedProjects] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
25812
+ const didInitCollapseRef = (0, import_react36.useRef)(false);
25813
+ const [searchQuery, setSearchQuery] = (0, import_react36.useState)("");
25814
+ const [menuAnchorEl, setMenuAnchorEl] = (0, import_react36.useState)(null);
25815
+ const [clearConfirmOpen, setClearConfirmOpen] = (0, import_react36.useState)(false);
25816
+ const [moveModalOpen, setMoveModalOpen] = (0, import_react36.useState)(false);
25817
+ const [conversationToMove, setConversationToMove] = (0, import_react36.useState)(null);
25818
+ const [renameProjectId, setRenameProjectId] = (0, import_react36.useState)(null);
25819
+ const [deletedConversationIds, setDeletedConversationIds] = (0, import_react36.useState)(/* @__PURE__ */ new Set());
25820
+ const [touchDragState, setTouchDragState] = (0, import_react36.useState)({ conversationId: null, originProjectId: null, hoverProjectId: null });
25821
+ const [avatarImage, setAvatarImage] = (0, import_react36.useState)(BANDIT_AVATAR2);
25822
+ const getCustomClaim = (0, import_react36.useCallback)((key) => {
25773
25823
  if (!user2) return void 0;
25774
25824
  const record = user2;
25775
25825
  return coerceOptionalString2(record[key]);
25776
25826
  }, [user2]);
25777
- const userDisplayName = (0, import_react35.useMemo)(() => {
25827
+ const userDisplayName = (0, import_react36.useMemo)(() => {
25778
25828
  if (!user2) return void 0;
25779
25829
  const candidateFields = [
25780
25830
  coerceOptionalString2(user2.name),
@@ -25789,7 +25839,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25789
25839
  if (trimmedEmail) return trimmedEmail;
25790
25840
  return user2.sub;
25791
25841
  }, [user2, getCustomClaim]);
25792
- const userSecondaryText = (0, import_react35.useMemo)(() => {
25842
+ const userSecondaryText = (0, import_react36.useMemo)(() => {
25793
25843
  if (!user2) return void 0;
25794
25844
  const trimmedEmail = coerceOptionalString2(user2.email);
25795
25845
  if (trimmedEmail && trimmedEmail !== userDisplayName) {
@@ -25801,7 +25851,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25801
25851
  }
25802
25852
  return void 0;
25803
25853
  }, [user2, userDisplayName]);
25804
- (0, import_react35.useEffect)(() => {
25854
+ (0, import_react36.useEffect)(() => {
25805
25855
  if (!open) return;
25806
25856
  const fresh = readPersistedToken();
25807
25857
  const authStore = useAuthenticationStore.getState();
@@ -25846,18 +25896,18 @@ var init_enhanced_mobile_conversations_modal = __esm({
25846
25896
  };
25847
25897
  }, [open, getCustomClaim]);
25848
25898
  const avatarLabel = userDisplayName || user2?.email || "Bandit";
25849
- const avatarInitials = (0, import_react35.useMemo)(() => deriveInitials2(avatarLabel), [avatarLabel]);
25899
+ const avatarInitials = (0, import_react36.useMemo)(() => deriveInitials2(avatarLabel), [avatarLabel]);
25850
25900
  const buildSnippet = (text, query, idx) => {
25851
25901
  const start = Math.max(0, idx - 40);
25852
25902
  const end = Math.min(text.length, idx + query.length + 60);
25853
25903
  return text.slice(start, end).replace(/\s+/g, " ").trim();
25854
25904
  };
25855
- (0, import_react35.useEffect)(() => {
25905
+ (0, import_react36.useEffect)(() => {
25856
25906
  if (open && !projectsHydrated) {
25857
25907
  hydrateProjects();
25858
25908
  }
25859
25909
  }, [open, projectsHydrated, hydrateProjects]);
25860
- (0, import_react35.useEffect)(() => {
25910
+ (0, import_react36.useEffect)(() => {
25861
25911
  if (projectsHydrated && !didInitCollapseRef.current) {
25862
25912
  didInitCollapseRef.current = true;
25863
25913
  if (projects && projects.length > 0) {
@@ -25865,7 +25915,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25865
25915
  }
25866
25916
  }
25867
25917
  }, [projectsHydrated, projects]);
25868
- const projectGroups = (0, import_react35.useMemo)(() => {
25918
+ const projectGroups = (0, import_react36.useMemo)(() => {
25869
25919
  const visibleConversations = conversations.filter(
25870
25920
  (conversation) => !deletedConversationIds.has(conversation.id) && !conversation.incognito
25871
25921
  );
@@ -25891,11 +25941,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
25891
25941
  }
25892
25942
  return groups.filter((group) => group.conversations.length > 0 || group.id !== null);
25893
25943
  }, [projects, conversations, collapsedProjects, deletedConversationIds]);
25894
- const visibleConversationCount = (0, import_react35.useMemo)(
25944
+ const visibleConversationCount = (0, import_react36.useMemo)(
25895
25945
  () => projectGroups.reduce((total, group) => total + group.conversations.length, 0),
25896
25946
  [projectGroups]
25897
25947
  );
25898
- const filteredProjectGroups = (0, import_react35.useMemo)(() => {
25948
+ const filteredProjectGroups = (0, import_react36.useMemo)(() => {
25899
25949
  if (!searchQuery.trim()) return projectGroups;
25900
25950
  const query = searchQuery.toLowerCase();
25901
25951
  return projectGroups.map((group) => {
@@ -25920,14 +25970,14 @@ var init_enhanced_mobile_conversations_modal = __esm({
25920
25970
  }).filter((group) => group.conversations.length > 0);
25921
25971
  }, [projectGroups, searchQuery]);
25922
25972
  const touchDragActive = Boolean(touchDragState.conversationId);
25923
- const getProjectIdFromPoint = (0, import_react35.useCallback)((clientX, clientY) => {
25973
+ const getProjectIdFromPoint = (0, import_react36.useCallback)((clientX, clientY) => {
25924
25974
  if (typeof document === "undefined") return null;
25925
25975
  const element = document.elementFromPoint(clientX, clientY);
25926
25976
  if (!element) return null;
25927
25977
  const projectNode = element.closest("[data-project-id]");
25928
25978
  return projectNode?.getAttribute("data-project-id") ?? null;
25929
25979
  }, []);
25930
- const handleTouchDragStart = (0, import_react35.useCallback)((conversation, touch) => {
25980
+ const handleTouchDragStart = (0, import_react36.useCallback)((conversation, touch) => {
25931
25981
  const initialHover = getProjectIdFromPoint(touch.clientX, touch.clientY);
25932
25982
  setTouchDragState({
25933
25983
  conversationId: conversation.id,
@@ -25935,7 +25985,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25935
25985
  hoverProjectId: initialHover ?? (conversation.projectId ?? null)
25936
25986
  });
25937
25987
  }, [getProjectIdFromPoint]);
25938
- const handleTouchDragMove = (0, import_react35.useCallback)((touch) => {
25988
+ const handleTouchDragMove = (0, import_react36.useCallback)((touch) => {
25939
25989
  setTouchDragState((prev) => {
25940
25990
  if (!prev.conversationId) return prev;
25941
25991
  const hoverId = getProjectIdFromPoint(touch.clientX, touch.clientY);
@@ -25943,7 +25993,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25943
25993
  return { ...prev, hoverProjectId: hoverId };
25944
25994
  });
25945
25995
  }, [getProjectIdFromPoint]);
25946
- const handleTouchDragEnd = (0, import_react35.useCallback)((touch) => {
25996
+ const handleTouchDragEnd = (0, import_react36.useCallback)((touch) => {
25947
25997
  setTouchDragState((prev) => {
25948
25998
  if (!prev.conversationId) {
25949
25999
  return { conversationId: null, originProjectId: null, hoverProjectId: null };
@@ -25971,11 +26021,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
25971
26021
  return { conversationId: null, originProjectId: null, hoverProjectId: null };
25972
26022
  });
25973
26023
  }, [getProjectIdFromPoint, moveConversationToProject]);
25974
- const activeDragConversation = (0, import_react35.useMemo)(() => {
26024
+ const activeDragConversation = (0, import_react36.useMemo)(() => {
25975
26025
  if (!touchDragState.conversationId) return null;
25976
26026
  return conversations.find((conv) => conv.id === touchDragState.conversationId) || null;
25977
26027
  }, [touchDragState.conversationId, conversations]);
25978
- const activeHoverLabel = (0, import_react35.useMemo)(() => {
26028
+ const activeHoverLabel = (0, import_react36.useMemo)(() => {
25979
26029
  if (!touchDragState.hoverProjectId) return "";
25980
26030
  if (touchDragState.hoverProjectId === "__ungrouped") return "Ungrouped";
25981
26031
  const project = projects.find((p) => p.id === touchDragState.hoverProjectId);
@@ -26024,7 +26074,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26024
26074
  setMoveModalOpen(false);
26025
26075
  setConversationToMove(null);
26026
26076
  };
26027
- (0, import_react35.useEffect)(() => {
26077
+ (0, import_react36.useEffect)(() => {
26028
26078
  setDeletedConversationIds((prev) => {
26029
26079
  let changed = false;
26030
26080
  const active2 = new Set(conversations.map((conv) => conv.id));
@@ -26049,6 +26099,11 @@ var init_enhanced_mobile_conversations_modal = __esm({
26049
26099
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_material26.Slide, { direction: "right", in: open, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
26050
26100
  import_material26.Box,
26051
26101
  {
26102
+ style: drag?.style,
26103
+ onTouchStart: drag?.onTouchStart,
26104
+ onTouchMove: drag?.onTouchMove,
26105
+ onTouchEnd: drag?.onTouchEnd,
26106
+ onTouchCancel: drag?.onTouchEnd,
26052
26107
  sx: {
26053
26108
  position: "fixed",
26054
26109
  top: 0,
@@ -26556,7 +26611,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26556
26611
  import_material26.Box,
26557
26612
  {
26558
26613
  onClick: user2 ? () => {
26559
- window.location.href = "/profile";
26614
+ safeNavigate("/profile");
26560
26615
  } : void 0,
26561
26616
  sx: {
26562
26617
  mt: "auto",
@@ -26632,7 +26687,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
26632
26687
  title: "Management & settings",
26633
26688
  onClick: (event) => {
26634
26689
  event.stopPropagation();
26635
- window.location.href = managementPath;
26690
+ safeNavigate(managementPath);
26636
26691
  },
26637
26692
  sx: {
26638
26693
  flexShrink: 0,
@@ -26794,15 +26849,15 @@ var init_enhanced_mobile_conversations_modal = __esm({
26794
26849
  });
26795
26850
 
26796
26851
  // 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;
26852
+ 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
26853
  var init_chat_app_bar = __esm({
26799
26854
  "src/chat/chat-app-bar.tsx"() {
26800
26855
  "use strict";
26801
26856
  import_material27 = require("@mui/material");
26802
26857
  init_modelStore();
26803
- import_react36 = require("react");
26858
+ import_react37 = require("react");
26804
26859
  import_material28 = require("@mui/material");
26805
- import_react_router_dom2 = require("react-router-dom");
26860
+ import_react_router_dom3 = require("react-router-dom");
26806
26861
  init_lucide_icons();
26807
26862
  init_conversation_drawer();
26808
26863
  init_enhanced_mobile_conversations_modal();
@@ -26834,14 +26889,15 @@ var init_chat_app_bar = __esm({
26834
26889
  drawerOpen,
26835
26890
  setDrawerOpen,
26836
26891
  mobileConversationsOpen,
26837
- onMobileConversationsOpenChange
26892
+ onMobileConversationsOpenChange,
26893
+ mobileConversationsDrag
26838
26894
  }) => {
26839
26895
  const theme = (0, import_material28.useTheme)();
26840
26896
  const isMobile = (0, import_material28.useMediaQuery)(theme.breakpoints.down("sm"));
26841
- const hasLoggedRouterWarningRef = (0, import_react36.useRef)(false);
26897
+ const hasLoggedRouterWarningRef = (0, import_react37.useRef)(false);
26842
26898
  let navigate = null;
26843
26899
  try {
26844
- navigate = (0, import_react_router_dom2.useNavigate)();
26900
+ navigate = (0, import_react_router_dom3.useNavigate)();
26845
26901
  } catch (error) {
26846
26902
  if (!hasLoggedRouterWarningRef.current) {
26847
26903
  debugLogger.warn("ChatAppBar: Navigation not available (missing Router context)", { error });
@@ -26868,17 +26924,17 @@ var init_chat_app_bar = __esm({
26868
26924
  menuBackground,
26869
26925
  menuText
26870
26926
  } = 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);
26927
+ const [modelAnchorEl, setModelAnchorEl] = (0, import_react37.useState)(null);
26928
+ const [engineAnchorEl, setEngineAnchorEl] = (0, import_react37.useState)(null);
26929
+ const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react37.useState)(null);
26930
+ const [internalModalOpen, setInternalModalOpen] = (0, import_react37.useState)(false);
26875
26931
  const modalOpen = mobileConversationsOpen ?? internalModalOpen;
26876
26932
  const setModalOpen = (open) => {
26877
26933
  setInternalModalOpen(open);
26878
26934
  onMobileConversationsOpenChange?.(open);
26879
26935
  };
26880
- const [confirmModelChangeOpen, setConfirmModelChangeOpen] = (0, import_react36.useState)(false);
26881
- const [pendingModel, setPendingModel] = (0, import_react36.useState)(null);
26936
+ const [confirmModelChangeOpen, setConfirmModelChangeOpen] = (0, import_react37.useState)(false);
26937
+ const [pendingModel, setPendingModel] = (0, import_react37.useState)(null);
26882
26938
  const { conversations, currentId, createNewConversation, toggleIncognito, _hasHydrated } = useConversationStore();
26883
26939
  const { preferences } = usePreferencesStore();
26884
26940
  const { settings: packageSettings } = usePackageSettingsStore();
@@ -26888,7 +26944,7 @@ var init_chat_app_bar = __esm({
26888
26944
  syncEnabled: state.syncEnabled,
26889
26945
  setSyncEnabled: state.setSyncEnabled
26890
26946
  }), import_shallow2.shallow);
26891
- (0, import_react36.useEffect)(() => {
26947
+ (0, import_react37.useEffect)(() => {
26892
26948
  if (isPlaygroundMode3 && syncEnabled) {
26893
26949
  void setSyncEnabled(false).catch((error) => {
26894
26950
  debugLogger.warn("ChatAppBar: Failed to disable sync in playground", {
@@ -26943,7 +26999,7 @@ var init_chat_app_bar = __esm({
26943
26999
  const resolvedEngineId = currentEngine?.id ?? effectiveEngineId;
26944
27000
  const cleanEngineName = (name) => (name || "").replace(/\s*\([^)]*\)\s*$/, "").trim();
26945
27001
  const engineDisplay = cleanEngineName(currentEngine?.displayName) || "Engine";
26946
- (0, import_react36.useEffect)(() => {
27002
+ (0, import_react37.useEffect)(() => {
26947
27003
  useEngineStore.getState().fetchEngines();
26948
27004
  }, []);
26949
27005
  const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead2;
@@ -27186,7 +27242,7 @@ var init_chat_app_bar = __esm({
27186
27242
  }
27187
27243
  ),
27188
27244
  /* @__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) }),
27245
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(enhanced_mobile_conversations_modal_default, { open: modalOpen, onClose: () => setModalOpen(false), drag: mobileConversationsDrag }),
27190
27246
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
27191
27247
  import_material28.Dialog,
27192
27248
  {
@@ -27326,11 +27382,11 @@ Respond with just the title and nothing else.
27326
27382
  });
27327
27383
 
27328
27384
  // 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;
27385
+ var import_react38, import_material29, import_styles18, import_react_markdown3, import_remark_gfm3, import_rehype_raw3, import_jsx_runtime30, markdownComponents, QuerySuggestionPicker;
27330
27386
  var init_query_suggestion_picker = __esm({
27331
27387
  "src/chat/query-suggestion-picker.tsx"() {
27332
27388
  "use strict";
27333
- import_react37 = require("react");
27389
+ import_react38 = require("react");
27334
27390
  import_material29 = require("@mui/material");
27335
27391
  import_styles18 = require("@mui/material/styles");
27336
27392
  import_react_markdown3 = __toESM(require("react-markdown"));
@@ -27355,16 +27411,16 @@ var init_query_suggestion_picker = __esm({
27355
27411
  onSend,
27356
27412
  inputHeight
27357
27413
  }) => {
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);
27414
+ const hasGenerated = (0, import_react38.useRef)(false);
27415
+ const [hasSentPrompt, setHasSentPrompt] = (0, import_react38.useState)(false);
27416
+ const [examplePrompts, setExamplePrompts] = (0, import_react38.useState)([]);
27417
+ const [visiblePrompts, setVisiblePrompts] = (0, import_react38.useState)([]);
27418
+ const scrollRef = (0, import_react38.useRef)(null);
27363
27419
  const theme = (0, import_styles18.useTheme)();
27364
27420
  const isMobile = (0, import_material29.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
27365
27421
  const { background, text, border, hoverBackground, hoverBorder } = theme.palette.chat.suggestion;
27366
27422
  const { getCurrentModel, isLoading } = useModelStore();
27367
- (0, import_react37.useEffect)(() => {
27423
+ (0, import_react38.useEffect)(() => {
27368
27424
  if (hasGenerated.current || isLoading) return;
27369
27425
  hasGenerated.current = true;
27370
27426
  const currentModel = getCurrentModel();
@@ -27397,12 +27453,12 @@ var init_query_suggestion_picker = __esm({
27397
27453
  hasGenerated.current = false;
27398
27454
  });
27399
27455
  }, [getCurrentModel, isLoading]);
27400
- (0, import_react37.useEffect)(() => {
27456
+ (0, import_react38.useEffect)(() => {
27401
27457
  if (!isLoading) {
27402
27458
  hasGenerated.current = false;
27403
27459
  }
27404
27460
  }, [isLoading]);
27405
- (0, import_react37.useEffect)(() => {
27461
+ (0, import_react38.useEffect)(() => {
27406
27462
  if (hasSentPrompt || examplePrompts.length === 0) return;
27407
27463
  const interval = setInterval(() => {
27408
27464
  setExamplePrompts((prev) => {
@@ -29978,17 +30034,17 @@ var init_themeMap = __esm({
29978
30034
  });
29979
30035
 
29980
30036
  // src/components/UnderReview.tsx
29981
- var import_material30, import_react_router_dom3, import_jsx_runtime31, UnderReview, UnderReview_default;
30037
+ var import_material30, import_react_router_dom4, import_jsx_runtime31, UnderReview, UnderReview_default;
29982
30038
  var init_UnderReview = __esm({
29983
30039
  "src/components/UnderReview.tsx"() {
29984
30040
  "use strict";
29985
30041
  import_material30 = require("@mui/material");
29986
- import_react_router_dom3 = require("react-router-dom");
30042
+ import_react_router_dom4 = require("react-router-dom");
29987
30043
  init_authenticationService();
29988
30044
  import_jsx_runtime31 = require("react/jsx-runtime");
29989
30045
  UnderReview = () => {
29990
30046
  const theme = (0, import_material30.useTheme)();
29991
- const navigate = (0, import_react_router_dom3.useNavigate)();
30047
+ const navigate = (0, import_react_router_dom4.useNavigate)();
29992
30048
  const handleResetSession = () => {
29993
30049
  authenticationService2.clearToken();
29994
30050
  navigate("/login");
@@ -30052,11 +30108,11 @@ var init_UnderReview = __esm({
30052
30108
  });
30053
30109
 
30054
30110
  // 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;
30111
+ 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
30112
  var init_FeedbackPulse = __esm({
30057
30113
  "src/components/feedback/FeedbackPulse.tsx"() {
30058
30114
  "use strict";
30059
- import_react38 = require("react");
30115
+ import_react39 = require("react");
30060
30116
  import_material31 = require("@mui/material");
30061
30117
  import_styles32 = require("@mui/material/styles");
30062
30118
  import_lucide_react13 = require("lucide-react");
@@ -30085,21 +30141,21 @@ var init_FeedbackPulse = __esm({
30085
30141
  };
30086
30142
  FeedbackPulse = ({ isMobile, feedbackEmail }) => {
30087
30143
  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);
30144
+ const [visible, setVisible] = (0, import_react39.useState)(false);
30145
+ const [thanked, setThanked] = (0, import_react39.useState)(false);
30146
+ const [modalOpen, setModalOpen] = (0, import_react39.useState)(false);
30147
+ const mountedAtRef = (0, import_react39.useRef)(Date.now());
30148
+ const baselineMessagesRef = (0, import_react39.useRef)(null);
30093
30149
  const totalMessages = useConversationStore(
30094
30150
  (s) => s.conversations.reduce((n, c) => n + c.history.length, 0)
30095
30151
  );
30096
30152
  const hydrated = useConversationStore((s) => s._hasHydrated);
30097
- (0, import_react38.useEffect)(() => {
30153
+ (0, import_react39.useEffect)(() => {
30098
30154
  if (hydrated && baselineMessagesRef.current === null) {
30099
30155
  baselineMessagesRef.current = totalMessages;
30100
30156
  }
30101
30157
  }, [hydrated, totalMessages]);
30102
- (0, import_react38.useEffect)(() => {
30158
+ (0, import_react39.useEffect)(() => {
30103
30159
  const cooldownMs = COOLDOWN_DAYS * 24 * 60 * 60 * 1e3;
30104
30160
  const forced = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("feedbackPulse");
30105
30161
  const check = () => {
@@ -30217,16 +30273,16 @@ var init_FeedbackPulse = __esm({
30217
30273
  });
30218
30274
 
30219
30275
  // src/hooks/useNotificationService.ts
30220
- var import_react39, useNotificationService;
30276
+ var import_react40, useNotificationService;
30221
30277
  var init_useNotificationService = __esm({
30222
30278
  "src/hooks/useNotificationService.ts"() {
30223
30279
  "use strict";
30224
- import_react39 = require("react");
30280
+ import_react40 = require("react");
30225
30281
  init_NotificationProvider();
30226
30282
  init_notificationService();
30227
30283
  useNotificationService = () => {
30228
30284
  const notificationContext = useNotification();
30229
- (0, import_react39.useEffect)(() => {
30285
+ (0, import_react40.useEffect)(() => {
30230
30286
  notificationService.setContext(notificationContext);
30231
30287
  }, [notificationContext]);
30232
30288
  return {
@@ -30333,11 +30389,11 @@ var init_ConnectionStatus = __esm({
30333
30389
  });
30334
30390
 
30335
30391
  // src/hooks/useVoiceMode.ts
30336
- var import_react40, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
30392
+ var import_react41, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
30337
30393
  var init_useVoiceMode = __esm({
30338
30394
  "src/hooks/useVoiceMode.ts"() {
30339
30395
  "use strict";
30340
- import_react40 = require("react");
30396
+ import_react41 = require("react");
30341
30397
  init_stt_client();
30342
30398
  init_debugLogger();
30343
30399
  init_voiceModeStore();
@@ -30370,11 +30426,11 @@ var init_useVoiceMode = __esm({
30370
30426
  const setError = useVoiceModeStore((state) => state.setError);
30371
30427
  const resetTransientState = useVoiceModeStore((state) => state.resetTransientState);
30372
30428
  const setLastTranscript = useVoiceModeStore((state) => state.setLastTranscript);
30373
- const configRef = (0, import_react40.useRef)(config);
30374
- (0, import_react40.useEffect)(() => {
30429
+ const configRef = (0, import_react41.useRef)(config);
30430
+ (0, import_react41.useEffect)(() => {
30375
30431
  configRef.current = config;
30376
30432
  }, [config]);
30377
- (0, import_react40.useEffect)(() => {
30433
+ (0, import_react41.useEffect)(() => {
30378
30434
  if (!enabled) {
30379
30435
  return () => void 0;
30380
30436
  }
@@ -30635,11 +30691,11 @@ var chat_exports = {};
30635
30691
  __export(chat_exports, {
30636
30692
  default: () => chat_default
30637
30693
  });
30638
- var import_react41, import_material33, import_styles33, import_react_router_dom4, import_lucide_react14, import_jsx_runtime34, ChatContent, Chat, chat_default;
30694
+ var import_react42, import_material33, import_styles33, import_react_router_dom5, import_lucide_react14, import_jsx_runtime34, ChatContent, Chat, chat_default;
30639
30695
  var init_chat2 = __esm({
30640
30696
  "src/chat/chat.tsx"() {
30641
30697
  "use strict";
30642
- import_react41 = require("react");
30698
+ import_react42 = require("react");
30643
30699
  init_custom_logo();
30644
30700
  init_indexedDBService();
30645
30701
  import_material33 = require("@mui/material");
@@ -30648,7 +30704,7 @@ var init_chat2 = __esm({
30648
30704
  init_modelStore();
30649
30705
  init_canvasStore();
30650
30706
  init_canvas_panel();
30651
- import_react_router_dom4 = require("react-router-dom");
30707
+ import_react_router_dom5 = require("react-router-dom");
30652
30708
  init_chat_scroll_to_bottom_button();
30653
30709
  init_bandit_chat_logo();
30654
30710
  init_chat_messages();
@@ -30681,6 +30737,8 @@ var init_chat2 = __esm({
30681
30737
  init_voiceModeStore();
30682
30738
  init_ttsSanitizer();
30683
30739
  init_FeatureFlagContext();
30740
+ init_knowledgeStore();
30741
+ init_lucide_icons();
30684
30742
  import_lucide_react14 = require("lucide-react");
30685
30743
  import_jsx_runtime34 = require("react/jsx-runtime");
30686
30744
  ChatContent = () => {
@@ -30691,12 +30749,12 @@ var init_chat2 = __esm({
30691
30749
  const ossMode = isOSSMode() || !packageSettings?.featureFlags?.subscriptionType;
30692
30750
  const playgroundBypassAccess = packageSettings?.playgroundBypassAuth || typeof window !== "undefined" && window.location.pathname.includes("/playground");
30693
30751
  const notificationService2 = useNotificationService();
30694
- const [selectedTheme, setSelectedTheme] = (0, import_react41.useState)(null);
30695
- const [themeLoading, setThemeLoading] = (0, import_react41.useState)(true);
30752
+ const [selectedTheme, setSelectedTheme] = (0, import_react42.useState)(null);
30753
+ const [themeLoading, setThemeLoading] = (0, import_react42.useState)(true);
30696
30754
  const token = authenticationService2.getToken();
30697
30755
  const claims = token ? authenticationService2.parseJwtClaims(token) : null;
30698
30756
  const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
30699
- const banditTheme = (0, import_react41.useMemo)(() => {
30757
+ const banditTheme = (0, import_react42.useMemo)(() => {
30700
30758
  return (0, import_styles33.createTheme)(baseTheme, {
30701
30759
  components: {
30702
30760
  MuiInputBase: {
@@ -30744,12 +30802,12 @@ var init_chat2 = __esm({
30744
30802
  } = useVoiceStore();
30745
30803
  const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);
30746
30804
  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)(() => {
30805
+ const previousVoiceModeEnabledRef = (0, import_react42.useRef)(isVoiceModeEnabled);
30806
+ const historyRef = (0, import_react42.useRef)(history);
30807
+ (0, import_react42.useEffect)(() => {
30750
30808
  historyRef.current = history;
30751
30809
  }, [history]);
30752
- (0, import_react41.useEffect)(() => {
30810
+ (0, import_react42.useEffect)(() => {
30753
30811
  if (!hydrated) return;
30754
30812
  const params = new URLSearchParams(window.location.search);
30755
30813
  const title = params.get("title") || "";
@@ -30765,7 +30823,7 @@ var init_chat2 = __esm({
30765
30823
  stop: ttsStop,
30766
30824
  isAvailable: isTTSAvailable
30767
30825
  } = useTTS();
30768
- (0, import_react41.useEffect)(() => {
30826
+ (0, import_react42.useEffect)(() => {
30769
30827
  const timer = setTimeout(() => {
30770
30828
  const isAuthenticated = authenticationService2.isAuthenticated();
30771
30829
  if (!initialized || availableVoices.length === 0) {
@@ -30779,7 +30837,7 @@ var init_chat2 = __esm({
30779
30837
  }, 500);
30780
30838
  return () => clearTimeout(timer);
30781
30839
  }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
30782
- (0, import_react41.useEffect)(() => {
30840
+ (0, import_react42.useEffect)(() => {
30783
30841
  const isAuthenticated = authenticationService2.isAuthenticated();
30784
30842
  if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
30785
30843
  if (token && isAuthenticated) {
@@ -30791,19 +30849,82 @@ var init_chat2 = __esm({
30791
30849
  }
30792
30850
  }, [packageSettings?.gatewayApiUrl, availableVoices.length, initialized, loadVoicesFromAPI, token]);
30793
30851
  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);
30852
+ const inputRef = (0, import_react42.useRef)(null);
30853
+ const [pastedImages, setPastedImages] = (0, import_react42.useState)([]);
30854
+ const inputContainerRef = (0, import_react42.useRef)(null);
30855
+ const [inputHeight, setInputHeight] = (0, import_react42.useState)(80);
30856
+ const [isSubmitting, setIsSubmitting] = (0, import_react42.useState)(false);
30857
+ const [pendingMessage, setPendingMessage] = (0, import_react42.useState)(null);
30800
30858
  const { conversations, currentId, _hasHydrated, hydrate, toggleIncognito } = useConversationStore();
30801
30859
  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)(() => {
30860
+ const [isMobile, setIsMobile] = (0, import_react42.useState)(false);
30861
+ const [drawerOpen, setDrawerOpen] = (0, import_react42.useState)(false);
30862
+ const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react42.useState)(false);
30863
+ const cardSwipeStartXRef = (0, import_react42.useRef)(null);
30864
+ const dragStartRef = (0, import_react42.useRef)(null);
30865
+ const [drawerDragX, setDrawerDragX] = (0, import_react42.useState)(null);
30866
+ const [drawerSettling, setDrawerSettling] = (0, import_react42.useState)(false);
30867
+ const [drawerSwap, setDrawerSwap] = (0, import_react42.useState)(false);
30868
+ const drawerOpenOffset = () => (typeof window === "undefined" ? 360 : Math.min(window.innerWidth - 56, 360)) - 12;
30869
+ const drawerDragStart = (e) => {
30870
+ const t = e.touches[0];
30871
+ if (!t) return;
30872
+ dragStartRef.current = { x: t.clientX, y: t.clientY, t: performance.now(), axis: null };
30873
+ };
30874
+ const drawerDragMove = (e) => {
30875
+ const s = dragStartRef.current;
30876
+ const t = e.touches[0];
30877
+ if (!s || !t) return;
30878
+ const dx = t.clientX - s.x;
30879
+ const dy = t.clientY - s.y;
30880
+ if (s.axis === null) {
30881
+ if (Math.abs(dx) < 8 && Math.abs(dy) < 8) return;
30882
+ s.axis = Math.abs(dx) > Math.abs(dy) ? "x" : "y";
30883
+ }
30884
+ if (s.axis !== "x") return;
30885
+ setDrawerDragX(dx < 0 ? Math.max(dx, -drawerOpenOffset()) : dx * 0.15);
30886
+ };
30887
+ const drawerDragEnd = () => {
30888
+ const s = dragStartRef.current;
30889
+ dragStartRef.current = null;
30890
+ if (!s || s.axis !== "x" || drawerDragX === null) {
30891
+ setDrawerDragX(null);
30892
+ return;
30893
+ }
30894
+ const dt = Math.max(1, performance.now() - s.t);
30895
+ const velocity = drawerDragX / dt;
30896
+ const offset = drawerOpenOffset();
30897
+ const shouldClose = drawerDragX < -offset * 0.35 || velocity < -0.45;
30898
+ if (shouldClose) {
30899
+ setDrawerSettling(true);
30900
+ setDrawerDragX(-offset);
30901
+ window.setTimeout(() => {
30902
+ setDrawerSwap(true);
30903
+ setMobileConversationsOpen(false);
30904
+ requestAnimationFrame(() => requestAnimationFrame(() => setDrawerSwap(false)));
30905
+ window.setTimeout(() => {
30906
+ setDrawerDragX(null);
30907
+ setDrawerSettling(false);
30908
+ }, 320);
30909
+ }, 220);
30910
+ } else {
30911
+ setDrawerSettling(true);
30912
+ setDrawerDragX(0);
30913
+ window.setTimeout(() => {
30914
+ setDrawerDragX(null);
30915
+ setDrawerSettling(false);
30916
+ }, 220);
30917
+ }
30918
+ };
30919
+ const drawerDragStyle = drawerSwap ? { translate: "0px 0", transition: "none" } : isMobile && mobileConversationsOpen && drawerDragX !== null ? {
30920
+ translate: `${drawerDragX}px 0`,
30921
+ transition: drawerSettling ? "translate 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)" : "none"
30922
+ } : void 0;
30923
+ const drawerPanelDragStyle = isMobile && drawerDragX !== null ? {
30924
+ translate: `${drawerDragX}px 0`,
30925
+ transition: drawerSettling ? "translate 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)" : "none"
30926
+ } : void 0;
30927
+ (0, import_react42.useEffect)(() => {
30807
30928
  if (typeof document === "undefined") return;
30808
30929
  const meta = document.querySelector('meta[name="theme-color"]');
30809
30930
  if (!meta) return;
@@ -30821,27 +30942,50 @@ var init_chat2 = __esm({
30821
30942
  const chatContainerEl = chatContainerRef.current;
30822
30943
  const scrollTargetEl = scrollTargetRef.current;
30823
30944
  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);
30945
+ const [showScrollToBottom, setShowScrollToBottom] = (0, import_react42.useState)(false);
30946
+ const [streamBuffer, setStreamBuffer] = (0, import_react42.useState)("");
30947
+ const [responseStarted, setResponseStarted] = (0, import_react42.useState)(false);
30948
+ const [isStreaming, setIsStreaming] = (0, import_react42.useState)(false);
30949
+ const [isThinking, setIsThinking] = (0, import_react42.useState)(false);
30829
30950
  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);
30951
+ const [logoVisible, setLogoVisible] = (0, import_react42.useState)(initialLogoState);
30952
+ const [logoShouldRender, setLogoShouldRender] = (0, import_react42.useState)(initialLogoState);
30953
+ const streamingGraceUntilRef = (0, import_react42.useRef)(0);
30833
30954
  const GRACE_MS = 450;
30834
30955
  const GRACE_OFFSET_DESKTOP = 28;
30835
30956
  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);
30957
+ const followStreamRef = (0, import_react42.useRef)(true);
30958
+ const lastSpokenResponseRef = (0, import_react42.useRef)(null);
30959
+ const previousConversationIdRef = (0, import_react42.useRef)(null);
30960
+ const logoFadeTimeoutRef = (0, import_react42.useRef)(null);
30961
+ const [branding, setBranding] = (0, import_react42.useState)(null);
30962
+ const [brandingLoading, setBrandingLoading] = (0, import_react42.useState)(true);
30963
+ const isBrandingLoadInProgressRef = (0, import_react42.useRef)(false);
30843
30964
  const logoOnly = history.length === 0 && !brandingLoading;
30844
- (0, import_react41.useEffect)(() => {
30965
+ const knowledgeDocs = useKnowledgeStore((s) => s.docs);
30966
+ const knowledgeLoaded = useKnowledgeStore((s) => s.isLoaded);
30967
+ const [knowledgeNudgeDismissed, setKnowledgeNudgeDismissed] = (0, import_react42.useState)(() => {
30968
+ try {
30969
+ return localStorage.getItem("bandit.knowledgeNudge.dismissed") === "true";
30970
+ } catch {
30971
+ return false;
30972
+ }
30973
+ });
30974
+ const dismissKnowledgeNudge = (0, import_react42.useCallback)(() => {
30975
+ setKnowledgeNudgeDismissed(true);
30976
+ try {
30977
+ localStorage.setItem("bandit.knowledgeNudge.dismissed", "true");
30978
+ } catch {
30979
+ }
30980
+ }, []);
30981
+ const showKnowledgeNudge = logoOnly && !knowledgeNudgeDismissed && knowledgeLoaded && knowledgeDocs.length === 0 && featureFlag.hasFeature("documentKnowledge");
30982
+ const knowledgePath = typeof window !== "undefined" && window.location.pathname.startsWith("/playground") ? "/playground/management" : "/management";
30983
+ const safeNavigateTo = (to) => {
30984
+ if (typeof window !== "undefined") {
30985
+ window.location.assign(to);
30986
+ }
30987
+ };
30988
+ (0, import_react42.useEffect)(() => {
30845
30989
  const isEmptyConversation = (history?.length ?? 0) === 0;
30846
30990
  const isSending = Boolean(pendingMessage);
30847
30991
  const shouldShowLogo = isEmptyConversation && !isSending;
@@ -30871,7 +31015,7 @@ var init_chat2 = __esm({
30871
31015
  }, 500);
30872
31016
  }
30873
31017
  }, [history, pendingMessage]);
30874
- (0, import_react41.useEffect)(() => {
31018
+ (0, import_react42.useEffect)(() => {
30875
31019
  if (!brandingLoading && !themeLoading) {
30876
31020
  return;
30877
31021
  }
@@ -30887,18 +31031,18 @@ var init_chat2 = __esm({
30887
31031
  }, 2500);
30888
31032
  return () => window.clearTimeout(timeoutId);
30889
31033
  }, [brandingLoading, themeLoading, selectedTheme]);
30890
- (0, import_react41.useEffect)(() => () => {
31034
+ (0, import_react42.useEffect)(() => () => {
30891
31035
  if (logoFadeTimeoutRef.current) {
30892
31036
  window.clearTimeout(logoFadeTimeoutRef.current);
30893
31037
  logoFadeTimeoutRef.current = null;
30894
31038
  }
30895
31039
  }, []);
30896
- (0, import_react41.useEffect)(() => {
31040
+ (0, import_react42.useEffect)(() => {
30897
31041
  if (isStreaming && streamBuffer.trim() === "") {
30898
31042
  streamingGraceUntilRef.current = Date.now() + GRACE_MS;
30899
31043
  }
30900
31044
  }, [isStreaming, streamBuffer]);
30901
- (0, import_react41.useEffect)(() => {
31045
+ (0, import_react42.useEffect)(() => {
30902
31046
  if (!isStreaming) return;
30903
31047
  const container = chatContainerRef.current;
30904
31048
  if (!container) return;
@@ -30909,13 +31053,13 @@ var init_chat2 = __esm({
30909
31053
  container.scrollTo({ top: targetTop, behavior: "smooth" });
30910
31054
  }
30911
31055
  }, [streamBuffer, isStreaming, isMobile, chatContainerRef]);
30912
- (0, import_react41.useEffect)(() => {
31056
+ (0, import_react42.useEffect)(() => {
30913
31057
  if (!_hasHydrated) {
30914
31058
  debugLogger.info("Chat component triggering conversation store hydration");
30915
31059
  hydrate();
30916
31060
  }
30917
31061
  }, [_hasHydrated, hydrate]);
30918
- (0, import_react41.useEffect)(() => {
31062
+ (0, import_react42.useEffect)(() => {
30919
31063
  const loadBrandingAndTheme = async () => {
30920
31064
  if (isBrandingLoadInProgressRef.current) {
30921
31065
  debugLogger.warn("Branding loading already in progress, skipping");
@@ -31104,7 +31248,7 @@ var init_chat2 = __esm({
31104
31248
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
31105
31249
  };
31106
31250
  }, []);
31107
- (0, import_react41.useEffect)(() => {
31251
+ (0, import_react42.useEffect)(() => {
31108
31252
  if (!chatContainerEl) return;
31109
31253
  const blurInputOnTouchScroll = () => {
31110
31254
  if (document.activeElement === inputRef.current) inputRef.current?.blur();
@@ -31112,13 +31256,13 @@ var init_chat2 = __esm({
31112
31256
  chatContainerEl.addEventListener("touchmove", blurInputOnTouchScroll, { passive: true });
31113
31257
  return () => chatContainerEl.removeEventListener("touchmove", blurInputOnTouchScroll);
31114
31258
  }, [chatContainerEl]);
31115
- (0, import_react41.useEffect)(() => {
31259
+ (0, import_react42.useEffect)(() => {
31116
31260
  const handleResize = () => setIsMobile(window.innerWidth <= 768);
31117
31261
  handleResize();
31118
31262
  window.addEventListener("resize", handleResize);
31119
31263
  return () => window.removeEventListener("resize", handleResize);
31120
31264
  }, []);
31121
- (0, import_react41.useEffect)(() => {
31265
+ (0, import_react42.useEffect)(() => {
31122
31266
  const setViewportHeight = () => {
31123
31267
  document.documentElement.style.setProperty(
31124
31268
  "--vh",
@@ -31129,7 +31273,7 @@ var init_chat2 = __esm({
31129
31273
  window.addEventListener("resize", setViewportHeight);
31130
31274
  return () => window.removeEventListener("resize", setViewportHeight);
31131
31275
  }, []);
31132
- (0, import_react41.useEffect)(() => {
31276
+ (0, import_react42.useEffect)(() => {
31133
31277
  if (!chatContainerEl) return;
31134
31278
  let rafId = null;
31135
31279
  const update = () => {
@@ -31148,7 +31292,7 @@ var init_chat2 = __esm({
31148
31292
  chatContainerEl.removeEventListener(SCROLL_STATE_CHANGED_EVENT, update);
31149
31293
  };
31150
31294
  }, [chatContainerEl, getScrollState]);
31151
- (0, import_react41.useEffect)(() => {
31295
+ (0, import_react42.useEffect)(() => {
31152
31296
  if (!chatContainerEl) return;
31153
31297
  let observer = null;
31154
31298
  let rafId = null;
@@ -31183,7 +31327,7 @@ var init_chat2 = __esm({
31183
31327
  if (observer) observer.disconnect();
31184
31328
  };
31185
31329
  }, [chatContainerEl, scrollTargetEl, scrollTargetRef, getScrollState, inputHeight, history.length]);
31186
- (0, import_react41.useEffect)(() => {
31330
+ (0, import_react42.useEffect)(() => {
31187
31331
  const isTransitioning = isStreaming || streamBuffer.trim() === "";
31188
31332
  const delay = isTransitioning ? 400 : 100;
31189
31333
  const timer = setTimeout(() => {
@@ -31192,7 +31336,7 @@ var init_chat2 = __esm({
31192
31336
  }, delay);
31193
31337
  return () => clearTimeout(timer);
31194
31338
  }, [history, streamBuffer, getScrollState, isStreaming]);
31195
- (0, import_react41.useLayoutEffect)(() => {
31339
+ (0, import_react42.useLayoutEffect)(() => {
31196
31340
  const scrollState = getScrollState();
31197
31341
  const now = Date.now();
31198
31342
  if (isStreaming && scrollState.shouldAutoScroll && followStreamRef.current) {
@@ -31226,7 +31370,7 @@ var init_chat2 = __esm({
31226
31370
  return () => clearTimeout(scrollTimer);
31227
31371
  }
31228
31372
  }, [history, isStreaming, scrollToBottom, getScrollState, isMobile, chatContainerRef]);
31229
- (0, import_react41.useEffect)(() => {
31373
+ (0, import_react42.useEffect)(() => {
31230
31374
  const observer = new ResizeObserver(() => {
31231
31375
  if (inputContainerRef.current)
31232
31376
  setInputHeight(inputContainerRef.current.offsetHeight);
@@ -31237,7 +31381,7 @@ var init_chat2 = __esm({
31237
31381
  }
31238
31382
  return () => observer.disconnect();
31239
31383
  }, []);
31240
- (0, import_react41.useEffect)(() => {
31384
+ (0, import_react42.useEffect)(() => {
31241
31385
  if (!hydrated || !_hasHydrated) return;
31242
31386
  if (currentId === null) {
31243
31387
  useAIQueryStore.setState({ history: [] });
@@ -31286,7 +31430,7 @@ var init_chat2 = __esm({
31286
31430
  setResponse,
31287
31431
  setComponentStatus
31288
31432
  ]);
31289
- (0, import_react41.useEffect)(() => {
31433
+ (0, import_react42.useEffect)(() => {
31290
31434
  debugLogger.info("Chat component conversation state", {
31291
31435
  hasHydrated: _hasHydrated,
31292
31436
  conversationCount: conversations.length,
@@ -31295,7 +31439,7 @@ var init_chat2 = __esm({
31295
31439
  storeState: "main-chat"
31296
31440
  });
31297
31441
  }, [_hasHydrated, conversations, currentId]);
31298
- (0, import_react41.useEffect)(() => {
31442
+ (0, import_react42.useEffect)(() => {
31299
31443
  if (!_hasHydrated || !chatContainerEl) return;
31300
31444
  let rafId = null;
31301
31445
  const sync = () => {
@@ -31330,7 +31474,7 @@ var init_chat2 = __esm({
31330
31474
  notificationService2?.handleHttpError(error);
31331
31475
  }
31332
31476
  });
31333
- const handleStop = (0, import_react41.useCallback)(() => {
31477
+ const handleStop = (0, import_react42.useCallback)(() => {
31334
31478
  try {
31335
31479
  aiProvider.cancel();
31336
31480
  } catch (error) {
@@ -31339,7 +31483,7 @@ var init_chat2 = __esm({
31339
31483
  });
31340
31484
  }
31341
31485
  }, [aiProvider]);
31342
- const handleVoiceInterrupt = (0, import_react41.useCallback)(() => {
31486
+ const handleVoiceInterrupt = (0, import_react42.useCallback)(() => {
31343
31487
  try {
31344
31488
  ttsStop();
31345
31489
  } catch (error) {
@@ -31358,7 +31502,7 @@ var init_chat2 = __esm({
31358
31502
  handleStop();
31359
31503
  }
31360
31504
  }, [ttsStop, isStreaming, handleStop]);
31361
- const handleSend = (0, import_react41.useCallback)(
31505
+ const handleSend = (0, import_react42.useCallback)(
31362
31506
  (question, images, displayQuestion) => {
31363
31507
  const requestStartTime = trackRequestStart();
31364
31508
  const questionForDisplay = displayQuestion || question;
@@ -31468,7 +31612,7 @@ var init_chat2 = __esm({
31468
31612
  trackRequestStart
31469
31613
  ]
31470
31614
  );
31471
- const handleVoiceTranscription = (0, import_react41.useCallback)(
31615
+ const handleVoiceTranscription = (0, import_react42.useCallback)(
31472
31616
  (text) => {
31473
31617
  const cleaned = text.trim();
31474
31618
  if (!cleaned) {
@@ -31485,7 +31629,7 @@ var init_chat2 = __esm({
31485
31629
  onInterrupt: handleVoiceInterrupt,
31486
31630
  onError: (message) => notificationService2?.showError?.(message)
31487
31631
  });
31488
- (0, import_react41.useEffect)(() => {
31632
+ (0, import_react42.useEffect)(() => {
31489
31633
  const previouslyEnabled = previousVoiceModeEnabledRef.current;
31490
31634
  previousVoiceModeEnabledRef.current = isVoiceModeEnabled;
31491
31635
  if (!previouslyEnabled && isVoiceModeEnabled) {
@@ -31510,7 +31654,7 @@ var init_chat2 = __esm({
31510
31654
  }
31511
31655
  }
31512
31656
  }, [isVoiceModeEnabled, ttsStop]);
31513
- (0, import_react41.useEffect)(() => {
31657
+ (0, import_react42.useEffect)(() => {
31514
31658
  if (!isVoiceModeEnabled || !isStreaming) {
31515
31659
  return;
31516
31660
  }
@@ -31530,7 +31674,7 @@ var init_chat2 = __esm({
31530
31674
  }
31531
31675
  lastSpokenResponseRef.current = null;
31532
31676
  }, [isStreaming, isVoiceModeEnabled, ttsStop]);
31533
- (0, import_react41.useEffect)(() => {
31677
+ (0, import_react42.useEffect)(() => {
31534
31678
  if (!isVoiceModeEnabled) {
31535
31679
  lastSpokenResponseRef.current = null;
31536
31680
  return;
@@ -31571,13 +31715,13 @@ var init_chat2 = __esm({
31571
31715
  cancelled = true;
31572
31716
  };
31573
31717
  }, [history, isStreaming, isVoiceModeEnabled, isTTSAvailable, ttsSpeak]);
31574
- const handleModelChange = (0, import_react41.useCallback)(
31718
+ const handleModelChange = (0, import_react42.useCallback)(
31575
31719
  (modelId) => {
31576
31720
  setSelectedModel(modelId);
31577
31721
  },
31578
31722
  [setSelectedModel]
31579
31723
  );
31580
- const handleVoiceChange = (0, import_react41.useCallback)(async (voiceId) => {
31724
+ const handleVoiceChange = (0, import_react42.useCallback)(async (voiceId) => {
31581
31725
  ttsStop();
31582
31726
  stopTTS();
31583
31727
  setSelectedVoice(voiceId);
@@ -31687,27 +31831,23 @@ var init_chat2 = __esm({
31687
31831
  // is the same near-black as the shell.
31688
31832
  border: isMobile && mobileConversationsOpen ? `1px solid ${theme.palette.mode === "dark" ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)"}` : "none",
31689
31833
  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"
31834
+ 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
31835
  }),
31692
31836
  onClick: isMobile && mobileConversationsOpen ? (e) => {
31693
31837
  if (e.currentTarget.contains(e.target)) {
31694
31838
  setMobileConversationsOpen(false);
31695
31839
  }
31696
31840
  } : void 0,
31841
+ style: drawerDragStyle,
31697
31842
  onTouchStart: isMobile && mobileConversationsOpen ? (e) => {
31698
31843
  if (e.currentTarget.contains(e.target)) {
31699
31844
  cardSwipeStartXRef.current = e.touches[0]?.clientX ?? null;
31845
+ drawerDragStart(e);
31700
31846
  }
31701
31847
  } : 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,
31848
+ onTouchMove: isMobile && mobileConversationsOpen ? drawerDragMove : void 0,
31849
+ onTouchEnd: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31850
+ onTouchCancel: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31711
31851
  children: [
31712
31852
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31713
31853
  chat_app_bar_default,
@@ -31720,7 +31860,13 @@ var init_chat2 = __esm({
31720
31860
  drawerOpen,
31721
31861
  setDrawerOpen,
31722
31862
  mobileConversationsOpen,
31723
- onMobileConversationsOpenChange: setMobileConversationsOpen
31863
+ onMobileConversationsOpenChange: setMobileConversationsOpen,
31864
+ mobileConversationsDrag: isMobile ? {
31865
+ style: drawerPanelDragStyle,
31866
+ onTouchStart: drawerDragStart,
31867
+ onTouchMove: drawerDragMove,
31868
+ onTouchEnd: drawerDragEnd
31869
+ } : void 0
31724
31870
  }
31725
31871
  ),
31726
31872
  isTemporaryChat && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
@@ -31876,6 +32022,53 @@ var init_chat2 = __esm({
31876
32022
  }
31877
32023
  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
32024
  })(),
32025
+ showKnowledgeNudge && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
32026
+ import_material33.Box,
32027
+ {
32028
+ sx: (theme) => ({
32029
+ mx: "auto",
32030
+ mt: 2,
32031
+ mb: 1,
32032
+ px: 2,
32033
+ py: 1.25,
32034
+ maxWidth: 420,
32035
+ display: "flex",
32036
+ alignItems: "center",
32037
+ gap: 1.25,
32038
+ borderRadius: 2.5,
32039
+ border: `1px solid ${theme.palette.divider}`,
32040
+ bgcolor: theme.palette.action.hover,
32041
+ opacity: logoVisible ? 1 : 0,
32042
+ transition: "opacity 0.5s ease"
32043
+ }),
32044
+ children: [
32045
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_material33.Box, { sx: { flex: 1, minWidth: 0 }, children: [
32046
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_material33.Typography, { variant: "body2", sx: { fontWeight: 600 }, children: "Add your documents" }),
32047
+ /* @__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." })
32048
+ ] }),
32049
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
32050
+ import_material33.Button,
32051
+ {
32052
+ size: "small",
32053
+ variant: "outlined",
32054
+ onClick: () => safeNavigateTo(knowledgePath),
32055
+ sx: { textTransform: "none", fontWeight: 600, flexShrink: 0 },
32056
+ children: "Upload"
32057
+ }
32058
+ ),
32059
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
32060
+ import_material33.IconButton,
32061
+ {
32062
+ size: "small",
32063
+ "aria-label": "Dismiss",
32064
+ onClick: dismissKnowledgeNudge,
32065
+ sx: { flexShrink: 0 },
32066
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CloseIcon, { fontSize: "small" })
32067
+ }
32068
+ )
32069
+ ]
32070
+ }
32071
+ ),
31879
32072
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31880
32073
  import_material33.Box,
31881
32074
  {
@@ -32012,7 +32205,7 @@ var init_chat2 = __esm({
32012
32205
  });
32013
32206
  if (!allowUnauthenticated && !bypassAuth && !authenticationService2.isAuthenticated()) {
32014
32207
  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 });
32208
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
32016
32209
  }
32017
32210
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ChatContent, {});
32018
32211
  };
@@ -32543,31 +32736,31 @@ var chat_provider_default = ChatProvider;
32543
32736
  init_chat2();
32544
32737
 
32545
32738
  // src/management/management.tsx
32546
- var import_react65 = require("react");
32739
+ var import_react66 = require("react");
32547
32740
  var import_useMediaQuery2 = __toESM(require("@mui/material/useMediaQuery"));
32548
32741
  var import_styles35 = require("@mui/material/styles");
32549
32742
  init_useKnowledgeStore();
32550
32743
  init_indexedDBService();
32551
32744
  var import_material55 = require("@mui/material");
32552
- var import_react_router_dom6 = require("react-router-dom");
32745
+ var import_react_router_dom7 = require("react-router-dom");
32553
32746
 
32554
32747
  // src/modals/chat-modal/chat-modal.tsx
32555
- var import_react49 = require("react");
32748
+ var import_react50 = require("react");
32556
32749
  var import_material41 = require("@mui/material");
32557
- var import_react_router_dom5 = require("react-router-dom");
32750
+ var import_react_router_dom6 = require("react-router-dom");
32558
32751
 
32559
32752
  // src/modals/chat-modal/draggable-box.tsx
32560
- var import_react42 = __toESM(require("react"));
32753
+ var import_react43 = __toESM(require("react"));
32561
32754
  var import_material34 = require("@mui/material");
32562
32755
  var import_jsx_runtime35 = require("react/jsx-runtime");
32563
32756
  var SCROLLABLE_THRESHOLD = 200;
32564
- var DraggableBox = import_react42.default.forwardRef(
32757
+ var DraggableBox = import_react43.default.forwardRef(
32565
32758
  ({ children, fullScreen, position, setPosition, onDrag, onScrollThresholdExceeded }, ref) => {
32566
32759
  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)(() => {
32760
+ const [transitionProps, setTransitionProps] = (0, import_react43.useState)("all");
32761
+ const [isDragging, setIsDragging] = (0, import_react43.useState)(false);
32762
+ const [isHovering, setIsHovering] = (0, import_react43.useState)(false);
32763
+ (0, import_react43.useEffect)(() => {
32571
32764
  if (ref && typeof ref !== "function" && ref.current && !fullScreen) {
32572
32765
  const modal = ref.current;
32573
32766
  const contentHeight = modal.scrollHeight;
@@ -32643,7 +32836,7 @@ var DraggableBox = import_react42.default.forwardRef(
32643
32836
  var draggable_box_default = DraggableBox;
32644
32837
 
32645
32838
  // src/modals/chat-modal/modal-header.tsx
32646
- var import_react43 = require("react");
32839
+ var import_react44 = require("react");
32647
32840
  var import_material35 = require("@mui/material");
32648
32841
  init_lucide_icons();
32649
32842
  var import_jsx_runtime36 = require("react/jsx-runtime");
@@ -32663,7 +32856,7 @@ var ModalHeader = ({
32663
32856
  const theme = (0, import_material35.useTheme)();
32664
32857
  const isMobile = (0, import_material35.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
32665
32858
  const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead3;
32666
- const [isHovering, setIsHovering] = (0, import_react43.useState)(false);
32859
+ const [isHovering, setIsHovering] = (0, import_react44.useState)(false);
32667
32860
  const buttonStyles = {
32668
32861
  transition: "all 0.15s ease-out",
32669
32862
  borderRadius: "8px",
@@ -32861,7 +33054,7 @@ var ModalHeader = ({
32861
33054
  var modal_header_default = ModalHeader;
32862
33055
 
32863
33056
  // src/modals/chat-modal/query-input.tsx
32864
- var import_react44 = require("react");
33057
+ var import_react45 = require("react");
32865
33058
  var import_material36 = require("@mui/material");
32866
33059
  init_lucide_icons();
32867
33060
  var import_jsx_runtime37 = require("react/jsx-runtime");
@@ -32879,7 +33072,7 @@ var QueryInput = ({
32879
33072
  // Destructure endAdornment
32880
33073
  }) => {
32881
33074
  const theme = (0, import_material36.useTheme)();
32882
- const inputRef = (0, import_react44.useRef)(null);
33075
+ const inputRef = (0, import_react45.useRef)(null);
32883
33076
  const handleSend = (e, payload) => {
32884
33077
  onSend(e, payload);
32885
33078
  };
@@ -32946,7 +33139,7 @@ init_ai_response_text_field();
32946
33139
  init_indexedDBService();
32947
33140
 
32948
33141
  // src/modals/chat-modal/chat-drawer.tsx
32949
- var import_react45 = __toESM(require("react"));
33142
+ var import_react46 = __toESM(require("react"));
32950
33143
  var import_material37 = require("@mui/material");
32951
33144
  init_aiQueryStore();
32952
33145
  init_conversationStore();
@@ -32981,23 +33174,23 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
32981
33174
  const { settings: packageSettings } = usePackageSettingsStore();
32982
33175
  const provider = useAIProviderStore((state) => state.provider);
32983
33176
  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)(() => {
33177
+ const [searchTerm, setSearchTerm] = (0, import_react46.useState)("");
33178
+ const [expandedItems, setExpandedItems] = (0, import_react46.useState)(/* @__PURE__ */ new Set());
33179
+ const [expandedConversations, setExpandedConversations] = (0, import_react46.useState)(/* @__PURE__ */ new Set());
33180
+ const [confirmClearOpen, setConfirmClearOpen] = (0, import_react46.useState)(false);
33181
+ const [infoDialogOpen, setInfoDialogOpen] = (0, import_react46.useState)(false);
33182
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react46.useState)(false);
33183
+ const [contextMode, setContextMode] = (0, import_react46.useState)("local");
33184
+ const [expandedSections, setExpandedSections] = (0, import_react46.useState)(/* @__PURE__ */ new Set(["history", "voice"]));
33185
+ const [audioSub, setAudioSub] = (0, import_react46.useState)(new import_rxjs22.Subscription());
33186
+ const [isContextSwitching, setIsContextSwitching] = (0, import_react46.useState)(false);
33187
+ const [isDrawerLoading, setIsDrawerLoading] = (0, import_react46.useState)(false);
33188
+ (0, import_react46.useEffect)(() => {
32996
33189
  if (drawerOpen && !_hasHydrated) {
32997
33190
  hydrate();
32998
33191
  }
32999
33192
  }, [drawerOpen, _hasHydrated, hydrate]);
33000
- (0, import_react45.useEffect)(() => {
33193
+ (0, import_react46.useEffect)(() => {
33001
33194
  if (!drawerOpen) {
33002
33195
  setIsDrawerLoading(false);
33003
33196
  const cleanupTimer = setTimeout(() => {
@@ -33008,7 +33201,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33008
33201
  return () => clearTimeout(cleanupTimer);
33009
33202
  }
33010
33203
  }, [drawerOpen]);
33011
- (0, import_react45.useEffect)(() => {
33204
+ (0, import_react46.useEffect)(() => {
33012
33205
  return () => {
33013
33206
  audioSub.unsubscribe();
33014
33207
  };
@@ -33055,7 +33248,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33055
33248
  const currentConversation = conversations.find((c) => c.id === currentId);
33056
33249
  const isInitialLoading = !_hasHydrated && contextMode === "main";
33057
33250
  const isContentLoading = isContextSwitching || isInitialLoading;
33058
- (0, import_react45.useEffect)(() => {
33251
+ (0, import_react46.useEffect)(() => {
33059
33252
  if (drawerOpen) {
33060
33253
  const debugTimer = setTimeout(() => {
33061
33254
  debugLogger.debug("Chat drawer loading states", {
@@ -33070,7 +33263,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33070
33263
  return () => clearTimeout(debugTimer);
33071
33264
  }
33072
33265
  }, [drawerOpen, _hasHydrated, isDrawerLoading, isContentLoading, contextMode]);
33073
- (0, import_react45.useEffect)(() => {
33266
+ (0, import_react46.useEffect)(() => {
33074
33267
  debugLogger.debug("Chat drawer voice availability check", {
33075
33268
  isServiceAvailable,
33076
33269
  ttsEnabled: preferences.ttsEnabled,
@@ -33081,14 +33274,14 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33081
33274
  storeState: "modal-chat-drawer-voice"
33082
33275
  });
33083
33276
  }, [isServiceAvailable, preferences.ttsEnabled, packageSettings?.gatewayApiUrl, isVoiceAvailable, availableVoices.length, selectedVoice]);
33084
- const activeHistory = (0, import_react45.useMemo)(() => {
33277
+ const activeHistory = (0, import_react46.useMemo)(() => {
33085
33278
  if (contextMode === "local") {
33086
33279
  return history;
33087
33280
  }
33088
33281
  return currentConversation?.history ?? [];
33089
33282
  }, [contextMode, history, currentConversation]);
33090
33283
  const effectiveContextMode = contextMode === "main" && (!currentConversation || currentConversation.history.length === 0) ? "local" : contextMode;
33091
- (0, import_react45.useEffect)(() => {
33284
+ (0, import_react46.useEffect)(() => {
33092
33285
  debugLogger.debug("Chat drawer context state", {
33093
33286
  contextMode,
33094
33287
  effectiveContextMode,
@@ -33101,13 +33294,13 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33101
33294
  storeState: "modal-chat-drawer"
33102
33295
  });
33103
33296
  }, [contextMode, effectiveContextMode, conversations.length, currentId, currentConversation, history.length, _hasHydrated]);
33104
- const filteredHistory = (0, import_react45.useMemo)(() => {
33297
+ const filteredHistory = (0, import_react46.useMemo)(() => {
33105
33298
  const filtered = activeHistory.filter(
33106
33299
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
33107
33300
  );
33108
33301
  return filtered.slice(-20);
33109
33302
  }, [activeHistory, searchTerm]);
33110
- const filteredConversations = (0, import_react45.useMemo)(() => {
33303
+ const filteredConversations = (0, import_react46.useMemo)(() => {
33111
33304
  const filtered = conversations.filter(
33112
33305
  (conversation) => conversation.name.toLowerCase().includes(searchTerm.toLowerCase()) || conversation.history.some(
33113
33306
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
@@ -33993,7 +34186,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33993
34186
  }
33994
34187
  ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material37.List, { sx: { p: 0 }, children: [...filteredHistory].reverse().map((entry, index) => {
33995
34188
  const isExpanded = expandedItems.has(index);
33996
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react45.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34189
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react46.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
33997
34190
  import_material37.ListItem,
33998
34191
  {
33999
34192
  sx: {
@@ -34470,7 +34663,7 @@ var GenericLoader = ({
34470
34663
  var generic_loader_default = GenericLoader;
34471
34664
 
34472
34665
  // src/components/feedback/FeedbackButton.tsx
34473
- var import_react46 = require("react");
34666
+ var import_react47 = require("react");
34474
34667
  var import_material39 = require("@mui/material");
34475
34668
  var import_lucide_react15 = require("lucide-react");
34476
34669
 
@@ -34491,7 +34684,7 @@ var FeedbackButton = ({
34491
34684
  absolute = false
34492
34685
  }) => {
34493
34686
  const theme = (0, import_material39.useTheme)();
34494
- const [open, setOpen] = (0, import_react46.useState)(false);
34687
+ const [open, setOpen] = (0, import_react47.useState)(false);
34495
34688
  const handleOpen = () => setOpen(true);
34496
34689
  const handleClose = () => setOpen(false);
34497
34690
  if (inline) {
@@ -34605,7 +34798,7 @@ var FeedbackButton = ({
34605
34798
  };
34606
34799
 
34607
34800
  // src/hooks/useAiChat.ts
34608
- var import_react47 = require("react");
34801
+ var import_react48 = require("react");
34609
34802
  var import_material40 = require("@mui/material");
34610
34803
  init_aiQueryStore();
34611
34804
  init_aiProviderStore();
@@ -34617,10 +34810,10 @@ var useAIChat = () => {
34617
34810
  const provider = useAIProviderStore((state) => state.provider);
34618
34811
  const SYSTEM_PROMPT = useModelStore((state) => state.systemPrompt);
34619
34812
  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);
34813
+ const [fullScreen, setFullScreen] = (0, import_react48.useState)(isMobile);
34814
+ const [drawerOpen, setDrawerOpen] = (0, import_react48.useState)(false);
34815
+ const [showSettings, setShowSettings] = (0, import_react48.useState)(false);
34816
+ const [, setAutoFullscreenTriggered] = (0, import_react48.useState)(false);
34624
34817
  const {
34625
34818
  apiKey,
34626
34819
  inputValue,
@@ -34708,7 +34901,7 @@ var useAIChat = () => {
34708
34901
  }
34709
34902
  sendWithAIProvider();
34710
34903
  };
34711
- (0, import_react47.useEffect)(() => {
34904
+ (0, import_react48.useEffect)(() => {
34712
34905
  setFullScreen(isMobile);
34713
34906
  }, [isMobile]);
34714
34907
  return {
@@ -34724,12 +34917,12 @@ var useAIChat = () => {
34724
34917
  var useAiChat_default = useAIChat;
34725
34918
 
34726
34919
  // src/hooks/useDraggable.ts
34727
- var import_react48 = require("react");
34920
+ var import_react49 = require("react");
34728
34921
  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 });
34922
+ const modalRef = (0, import_react49.useRef)(null);
34923
+ const [dragging, setDragging] = (0, import_react49.useState)(false);
34924
+ const [offset, setOffset] = (0, import_react49.useState)({ x: 0, y: 0 });
34925
+ const [position, setPosition] = (0, import_react49.useState)({ x: 0, y: 0 });
34733
34926
  const handleHeaderMouseDown = (e) => {
34734
34927
  const rect = modalRef.current?.getBoundingClientRect();
34735
34928
  if (rect) {
@@ -34737,7 +34930,7 @@ var useDraggable = () => {
34737
34930
  setDragging(true);
34738
34931
  }
34739
34932
  };
34740
- const handleHeaderMouseMove = (0, import_react48.useCallback)(
34933
+ const handleHeaderMouseMove = (0, import_react49.useCallback)(
34741
34934
  (e) => {
34742
34935
  if (dragging) {
34743
34936
  setPosition({ x: e.clientX - offset.x, y: e.clientY - offset.y });
@@ -34748,7 +34941,7 @@ var useDraggable = () => {
34748
34941
  const handleHeaderMouseUp = () => {
34749
34942
  setDragging(false);
34750
34943
  };
34751
- (0, import_react48.useEffect)(() => {
34944
+ (0, import_react49.useEffect)(() => {
34752
34945
  if (dragging) {
34753
34946
  document.addEventListener("mousemove", handleHeaderMouseMove);
34754
34947
  document.addEventListener("mouseup", handleHeaderMouseUp);
@@ -34798,9 +34991,9 @@ var modelAvatars3 = {
34798
34991
  "Bandit-Exec": `${CDN_BASE2}/avatars/exec-avatar.png`
34799
34992
  };
34800
34993
  var useOptionalNavigate = () => {
34801
- const hasLoggedRef = (0, import_react49.useRef)(false);
34994
+ const hasLoggedRef = (0, import_react50.useRef)(false);
34802
34995
  try {
34803
- return (0, import_react_router_dom5.useNavigate)();
34996
+ return (0, import_react_router_dom6.useNavigate)();
34804
34997
  } catch (error) {
34805
34998
  if (!hasLoggedRef.current) {
34806
34999
  debugLogger.debug("Navigation not available in ChatModal context", { error });
@@ -34847,17 +35040,17 @@ var ChatModal = ({
34847
35040
  handleSend
34848
35041
  } = useAiChat_default();
34849
35042
  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);
35043
+ const [pastedImages, setPastedImages] = (0, import_react50.useState)([]);
35044
+ const [responseStarted, setResponseStarted] = (0, import_react50.useState)(false);
35045
+ const [modalLogo, setModalLogo] = (0, import_react50.useState)("https://cdn.burtson.ai/logos/bandit-ai-logo.png");
35046
+ const [modelAnchorEl, setModelAnchorEl] = (0, import_react50.useState)(null);
35047
+ const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react50.useState)(null);
35048
+ const [audioSub, setAudioSub] = (0, import_react50.useState)(new import_rxjs23.Subscription());
35049
+ const [selectedTheme, setSelectedTheme] = (0, import_react50.useState)(null);
35050
+ const [themeLoading, setThemeLoading] = (0, import_react50.useState)(true);
35051
+ const [autoFullscreenTriggered, setAutoFullscreenTriggered] = (0, import_react50.useState)(false);
35052
+ const [userHasDragged, setUserHasDragged] = (0, import_react50.useState)(false);
35053
+ const [manualFullscreenToggleTime, setManualFullscreenToggleTime] = (0, import_react50.useState)(0);
34861
35054
  const handleExitFullscreen = () => {
34862
35055
  setPosition({
34863
35056
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34903,7 +35096,7 @@ var ChatModal = ({
34903
35096
  const toTitleCase2 = (str) => {
34904
35097
  return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
34905
35098
  };
34906
- (0, import_react49.useEffect)(() => {
35099
+ (0, import_react50.useEffect)(() => {
34907
35100
  if (!SYSTEM_PROMPT) {
34908
35101
  const defaultModel = availableModels.length > 0 ? availableModels[0] : null;
34909
35102
  if (defaultModel) {
@@ -34911,12 +35104,12 @@ var ChatModal = ({
34911
35104
  }
34912
35105
  }
34913
35106
  }, [SYSTEM_PROMPT, availableModels, setSelectedModel]);
34914
- (0, import_react49.useEffect)(() => {
35107
+ (0, import_react50.useEffect)(() => {
34915
35108
  return () => {
34916
35109
  audioSub.unsubscribe();
34917
35110
  };
34918
35111
  }, [audioSub]);
34919
- (0, import_react49.useEffect)(() => {
35112
+ (0, import_react50.useEffect)(() => {
34920
35113
  if (open) {
34921
35114
  setPosition({
34922
35115
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34928,7 +35121,7 @@ var ChatModal = ({
34928
35121
  getOptimalLogo().then(setModalLogo);
34929
35122
  }
34930
35123
  }, [open, setPosition]);
34931
- (0, import_react49.useEffect)(() => {
35124
+ (0, import_react50.useEffect)(() => {
34932
35125
  if (!open) return;
34933
35126
  const fetchTheme = async () => {
34934
35127
  try {
@@ -34962,7 +35155,7 @@ var ChatModal = ({
34962
35155
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
34963
35156
  };
34964
35157
  }, [open]);
34965
- (0, import_react49.useLayoutEffect)(() => {
35158
+ (0, import_react50.useLayoutEffect)(() => {
34966
35159
  const timeSinceManualToggle = Date.now() - manualFullscreenToggleTime;
34967
35160
  const manualToggleRecentlyUsed = timeSinceManualToggle < 5e3;
34968
35161
  if (modalRef.current && response && !fullScreen && !autoFullscreenTriggered && !manualToggleRecentlyUsed) {
@@ -34987,7 +35180,7 @@ var ChatModal = ({
34987
35180
  setFullScreen,
34988
35181
  setAutoFullscreenTriggered
34989
35182
  ]);
34990
- (0, import_react49.useEffect)(() => {
35183
+ (0, import_react50.useEffect)(() => {
34991
35184
  const handlePaste = (e) => {
34992
35185
  const items = e.clipboardData?.items;
34993
35186
  if (items) {
@@ -35012,7 +35205,7 @@ var ChatModal = ({
35012
35205
  document.removeEventListener("paste", handlePaste);
35013
35206
  };
35014
35207
  }, []);
35015
- (0, import_react49.useEffect)(() => {
35208
+ (0, import_react50.useEffect)(() => {
35016
35209
  if (response && !responseStarted) {
35017
35210
  setResponseStarted(true);
35018
35211
  }
@@ -35432,13 +35625,13 @@ var ChatModal = ({
35432
35625
  var chat_modal_default = ChatModal;
35433
35626
 
35434
35627
  // src/management/components/PersonalitiesTab.tsx
35435
- var import_react51 = require("react");
35628
+ var import_react52 = require("react");
35436
35629
  var import_material43 = require("@mui/material");
35437
35630
  var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"));
35438
35631
  var import_styles34 = require("@mui/material/styles");
35439
35632
 
35440
35633
  // src/components/AvatarCropper.tsx
35441
- var import_react50 = require("react");
35634
+ var import_react51 = require("react");
35442
35635
  var import_material42 = require("@mui/material");
35443
35636
  init_lucide_icons();
35444
35637
  var import_jsx_runtime42 = require("react/jsx-runtime");
@@ -35448,22 +35641,22 @@ var AvatarCropper = ({
35448
35641
  onCrop,
35449
35642
  imageFile
35450
35643
  }) => {
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)({
35644
+ const canvasRef = (0, import_react51.useRef)(null);
35645
+ const imageRef = (0, import_react51.useRef)(null);
35646
+ const [imageSrc, setImageSrc] = (0, import_react51.useState)("");
35647
+ const [cropSettings, setCropSettings] = (0, import_react51.useState)({
35455
35648
  x: 0,
35456
35649
  y: 0,
35457
35650
  scale: 1,
35458
35651
  rotation: 0
35459
35652
  });
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 });
35653
+ const [isDragging, setIsDragging] = (0, import_react51.useState)(false);
35654
+ const [dragStart, setDragStart] = (0, import_react51.useState)({ x: 0, y: 0 });
35655
+ const [imageLoaded, setImageLoaded] = (0, import_react51.useState)(false);
35656
+ const [imageNaturalSize, setImageNaturalSize] = (0, import_react51.useState)({ width: 0, height: 0 });
35464
35657
  const CROP_SIZE = 400;
35465
35658
  const OUTPUT_SIZE = 512;
35466
- (0, import_react50.useEffect)(() => {
35659
+ (0, import_react51.useEffect)(() => {
35467
35660
  if (imageFile && open) {
35468
35661
  const reader = new FileReader();
35469
35662
  reader.onload = (e) => {
@@ -35475,7 +35668,7 @@ var AvatarCropper = ({
35475
35668
  reader.readAsDataURL(imageFile);
35476
35669
  }
35477
35670
  }, [imageFile, open]);
35478
- const handleImageLoad = (0, import_react50.useCallback)(() => {
35671
+ const handleImageLoad = (0, import_react51.useCallback)(() => {
35479
35672
  if (imageRef.current) {
35480
35673
  const { naturalWidth, naturalHeight } = imageRef.current;
35481
35674
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -35492,7 +35685,7 @@ var AvatarCropper = ({
35492
35685
  setImageLoaded(true);
35493
35686
  }
35494
35687
  }, []);
35495
- const drawCropPreview = (0, import_react50.useCallback)(() => {
35688
+ const drawCropPreview = (0, import_react51.useCallback)(() => {
35496
35689
  const canvas = canvasRef.current;
35497
35690
  const image = imageRef.current;
35498
35691
  if (!canvas || !image || !imageLoaded) return;
@@ -35515,14 +35708,14 @@ var AvatarCropper = ({
35515
35708
  ctx.fill();
35516
35709
  ctx.restore();
35517
35710
  }, [cropSettings, imageLoaded]);
35518
- (0, import_react50.useEffect)(() => {
35711
+ (0, import_react51.useEffect)(() => {
35519
35712
  drawCropPreview();
35520
35713
  }, [drawCropPreview]);
35521
- const handleMouseDown = (0, import_react50.useCallback)((e) => {
35714
+ const handleMouseDown = (0, import_react51.useCallback)((e) => {
35522
35715
  setIsDragging(true);
35523
35716
  setDragStart({ x: e.clientX, y: e.clientY });
35524
35717
  }, []);
35525
- const handleMouseMove = (0, import_react50.useCallback)((e) => {
35718
+ const handleMouseMove = (0, import_react51.useCallback)((e) => {
35526
35719
  if (!isDragging) return;
35527
35720
  const deltaX = e.clientX - dragStart.x;
35528
35721
  const deltaY = e.clientY - dragStart.y;
@@ -35533,16 +35726,16 @@ var AvatarCropper = ({
35533
35726
  }));
35534
35727
  setDragStart({ x: e.clientX, y: e.clientY });
35535
35728
  }, [isDragging, dragStart]);
35536
- const handleMouseUp = (0, import_react50.useCallback)(() => {
35729
+ const handleMouseUp = (0, import_react51.useCallback)(() => {
35537
35730
  setIsDragging(false);
35538
35731
  }, []);
35539
- const handleClose = (0, import_react50.useCallback)(() => {
35732
+ const handleClose = (0, import_react51.useCallback)(() => {
35540
35733
  setImageSrc("");
35541
35734
  setImageLoaded(false);
35542
35735
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
35543
35736
  onClose();
35544
35737
  }, [onClose]);
35545
- const handleCrop = (0, import_react50.useCallback)(() => {
35738
+ const handleCrop = (0, import_react51.useCallback)(() => {
35546
35739
  const canvas = document.createElement("canvas");
35547
35740
  const ctx = canvas.getContext("2d");
35548
35741
  const image = imageRef.current;
@@ -35569,7 +35762,7 @@ var AvatarCropper = ({
35569
35762
  onCrop(croppedDataUrl);
35570
35763
  handleClose();
35571
35764
  }, [cropSettings, onCrop, handleClose]);
35572
- const handleScaleChange = (0, import_react50.useCallback)((value) => {
35765
+ const handleScaleChange = (0, import_react51.useCallback)((value) => {
35573
35766
  const minScale2 = Math.max(
35574
35767
  CROP_SIZE / imageNaturalSize.width,
35575
35768
  CROP_SIZE / imageNaturalSize.height
@@ -35579,7 +35772,7 @@ var AvatarCropper = ({
35579
35772
  scale: Math.max(value, minScale2)
35580
35773
  }));
35581
35774
  }, [imageNaturalSize]);
35582
- const handleRotation = (0, import_react50.useCallback)((direction) => {
35775
+ const handleRotation = (0, import_react51.useCallback)((direction) => {
35583
35776
  setCropSettings((prev) => ({
35584
35777
  ...prev,
35585
35778
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -35815,15 +36008,15 @@ var PersonalitiesTab = ({
35815
36008
  }) => {
35816
36009
  const theme = (0, import_styles34.useTheme)();
35817
36010
  const isMobile = (0, import_useMediaQuery.default)(theme.breakpoints.down("sm"));
35818
- const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react51.useState)(0);
36011
+ const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react52.useState)(0);
35819
36012
  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);
36013
+ const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react52.useState)(false);
36014
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react52.useState)(false);
36015
+ const [personalityToDelete, setPersonalityToDelete] = (0, import_react52.useState)(null);
36016
+ const [clickedChips, setClickedChips] = (0, import_react52.useState)(/* @__PURE__ */ new Set());
36017
+ const [showTemplateHelp, setShowTemplateHelp] = (0, import_react52.useState)(false);
36018
+ const [cropperOpen, setCropperOpen] = (0, import_react52.useState)(false);
36019
+ const [selectedImageFile, setSelectedImageFile] = (0, import_react52.useState)(null);
35827
36020
  const promptTemplates = [
35828
36021
  {
35829
36022
  name: "Business Professional",
@@ -37320,7 +37513,7 @@ var PersonalitiesTab = ({
37320
37513
  var PersonalitiesTab_default = PersonalitiesTab;
37321
37514
 
37322
37515
  // src/management/components/PreferencesTab.tsx
37323
- var import_react53 = require("react");
37516
+ var import_react54 = require("react");
37324
37517
  init_memory_modal();
37325
37518
  var import_material44 = require("@mui/material");
37326
37519
  init_preferencesStore();
@@ -37331,7 +37524,7 @@ init_useFeatures();
37331
37524
  init_conversationSyncStore();
37332
37525
 
37333
37526
  // src/hooks/useGatewayQueries.ts
37334
- var import_react52 = require("react");
37527
+ var import_react53 = require("react");
37335
37528
  var import_rxjs24 = require("rxjs");
37336
37529
  var import_react_query2 = require("@tanstack/react-query");
37337
37530
  init_packageSettingsStore();
@@ -37341,7 +37534,7 @@ var useGatewayClient = () => {
37341
37534
  const settings = usePackageSettingsStore((state) => state.settings);
37342
37535
  const gatewayUrl = settings?.gatewayApiUrl;
37343
37536
  const feedbackEmail = settings?.feedbackEmail;
37344
- const service = (0, import_react52.useMemo)(() => {
37537
+ const service = (0, import_react53.useMemo)(() => {
37345
37538
  if (!gatewayUrl) {
37346
37539
  return null;
37347
37540
  }
@@ -37400,6 +37593,7 @@ var useGatewayMemory = (options) => {
37400
37593
  };
37401
37594
 
37402
37595
  // src/management/components/PreferencesTab.tsx
37596
+ init_installedApp();
37403
37597
  init_lucide_icons();
37404
37598
  var import_jsx_runtime44 = require("react/jsx-runtime");
37405
37599
  var PreferencesTab = ({
@@ -37411,16 +37605,16 @@ var PreferencesTab = ({
37411
37605
  }) => {
37412
37606
  const theme = (0, import_material44.useTheme)();
37413
37607
  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);
37608
+ const [homeUrlStatus, setHomeUrlStatus] = (0, import_react54.useState)("idle");
37609
+ const [homeUrlError, setHomeUrlError] = (0, import_react54.useState)("");
37610
+ const [localHomeUrl, setLocalHomeUrl] = (0, import_react54.useState)(preferences.homeUrl || "");
37611
+ const [importStatus, setImportStatus] = (0, import_react54.useState)("idle");
37612
+ const [syncToggleLoading, setSyncToggleLoading] = (0, import_react54.useState)(false);
37613
+ const [manualSyncLoading, setManualSyncLoading] = (0, import_react54.useState)(false);
37614
+ const [advancedVectorToggleLoading, setAdvancedVectorToggleLoading] = (0, import_react54.useState)(false);
37615
+ const [memoryModalOpen, setMemoryModalOpen] = (0, import_react54.useState)(false);
37616
+ const timeoutRef = (0, import_react54.useRef)(null);
37617
+ const fileInputRef = (0, import_react54.useRef)(null);
37424
37618
  const { exportPreferences, importPreferences, resetToDefaults } = usePreferencesStore();
37425
37619
  const {
37426
37620
  isServiceAvailable: isTTSSTTAvailable,
@@ -37532,7 +37726,7 @@ var PreferencesTab = ({
37532
37726
  if (!gatewayHealth) return "warning";
37533
37727
  return gatewayHealth.status?.toLowerCase() === "healthy" ? "success" : "error";
37534
37728
  })();
37535
- const handleGatewayStatusRefresh = (0, import_react53.useCallback)(() => {
37729
+ const handleGatewayStatusRefresh = (0, import_react54.useCallback)(() => {
37536
37730
  if (!gatewayConfigured) {
37537
37731
  return;
37538
37732
  }
@@ -37594,7 +37788,7 @@ var PreferencesTab = ({
37594
37788
  }
37595
37789
  return packageSettings?.homeUrl || "";
37596
37790
  };
37597
- (0, import_react53.useEffect)(() => {
37791
+ (0, import_react54.useEffect)(() => {
37598
37792
  setLocalHomeUrl(preferences.homeUrl || "");
37599
37793
  }, [preferences.homeUrl]);
37600
37794
  const validateAndSaveHomeUrl = async (url) => {
@@ -37641,7 +37835,7 @@ var PreferencesTab = ({
37641
37835
  validateAndSaveHomeUrl(value);
37642
37836
  }, 1500);
37643
37837
  };
37644
- (0, import_react53.useEffect)(() => {
37838
+ (0, import_react54.useEffect)(() => {
37645
37839
  return () => {
37646
37840
  if (timeoutRef.current) {
37647
37841
  clearTimeout(timeoutRef.current);
@@ -38249,16 +38443,15 @@ var PreferencesTab = ({
38249
38443
  ] }) });
38250
38444
  };
38251
38445
  var ViewportDiagnostics = () => {
38252
- const [metrics, setMetrics] = (0, import_react53.useState)({});
38253
- (0, import_react53.useEffect)(() => {
38446
+ const [metrics, setMetrics] = (0, import_react54.useState)({});
38447
+ (0, import_react54.useEffect)(() => {
38254
38448
  const read = () => {
38255
38449
  const probe = document.createElement("div");
38256
38450
  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
38451
  document.body.appendChild(probe);
38258
38452
  const cs = getComputedStyle(probe);
38259
- const standalone = window.matchMedia?.("(display-mode: standalone)").matches || window.navigator.standalone === true;
38260
38453
  setMetrics({
38261
- mode: standalone ? "standalone" : "browser",
38454
+ mode: isNativeShell() ? "native" : isStandalonePwa2() ? "standalone" : "browser",
38262
38455
  "screen.height": `${window.screen.height}`,
38263
38456
  innerHeight: `${window.innerHeight}`,
38264
38457
  "docElement.clientHeight": `${document.documentElement.clientHeight}`,
@@ -38285,11 +38478,11 @@ var ViewportDiagnostics = () => {
38285
38478
  var PreferencesTab_default = PreferencesTab;
38286
38479
 
38287
38480
  // src/management/components/BrandingTab.tsx
38288
- var import_react55 = require("react");
38481
+ var import_react56 = require("react");
38289
38482
  var import_material46 = require("@mui/material");
38290
38483
 
38291
38484
  // src/components/LogoCropper.tsx
38292
- var import_react54 = require("react");
38485
+ var import_react55 = require("react");
38293
38486
  var import_material45 = require("@mui/material");
38294
38487
  init_lucide_icons();
38295
38488
  var import_jsx_runtime45 = require("react/jsx-runtime");
@@ -38304,25 +38497,25 @@ var LogoCropper = ({
38304
38497
  onCrop,
38305
38498
  imageFile
38306
38499
  }) => {
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)({
38500
+ const canvasRef = (0, import_react55.useRef)(null);
38501
+ const previewCanvasRef = (0, import_react55.useRef)(null);
38502
+ const imageRef = (0, import_react55.useRef)(null);
38503
+ const [imageSrc, setImageSrc] = (0, import_react55.useState)("");
38504
+ const [cropSettings, setCropSettings] = (0, import_react55.useState)({
38312
38505
  x: 0,
38313
38506
  y: 0,
38314
38507
  scale: 1,
38315
38508
  rotation: 0
38316
38509
  });
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 });
38510
+ const [isDragging, setIsDragging] = (0, import_react55.useState)(false);
38511
+ const [dragStart, setDragStart] = (0, import_react55.useState)({ x: 0, y: 0 });
38512
+ const [imageLoaded, setImageLoaded] = (0, import_react55.useState)(false);
38513
+ const [imageNaturalSize, setImageNaturalSize] = (0, import_react55.useState)({ width: 0, height: 0 });
38514
+ const [aspectRatio, setAspectRatio] = (0, import_react55.useState)("square");
38515
+ const [cropArea, setCropArea] = (0, import_react55.useState)({ width: 400, height: 400 });
38323
38516
  const CANVAS_SIZE = 500;
38324
- const [outputSize, setOutputSize] = (0, import_react54.useState)("large");
38325
- const getCropDimensions = (0, import_react54.useCallback)(() => {
38517
+ const [outputSize, setOutputSize] = (0, import_react55.useState)("large");
38518
+ const getCropDimensions = (0, import_react55.useCallback)(() => {
38326
38519
  const maxSize = 380;
38327
38520
  switch (aspectRatio) {
38328
38521
  case "square":
@@ -38337,7 +38530,7 @@ var LogoCropper = ({
38337
38530
  return cropArea;
38338
38531
  }
38339
38532
  }, [aspectRatio, cropArea]);
38340
- (0, import_react54.useEffect)(() => {
38533
+ (0, import_react55.useEffect)(() => {
38341
38534
  if (imageFile && open) {
38342
38535
  const reader = new FileReader();
38343
38536
  reader.onload = (e) => {
@@ -38349,7 +38542,7 @@ var LogoCropper = ({
38349
38542
  reader.readAsDataURL(imageFile);
38350
38543
  }
38351
38544
  }, [imageFile, open]);
38352
- const handleImageLoad = (0, import_react54.useCallback)(() => {
38545
+ const handleImageLoad = (0, import_react55.useCallback)(() => {
38353
38546
  if (imageRef.current) {
38354
38547
  const { naturalWidth, naturalHeight } = imageRef.current;
38355
38548
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -38367,7 +38560,7 @@ var LogoCropper = ({
38367
38560
  setImageLoaded(true);
38368
38561
  }
38369
38562
  }, [getCropDimensions]);
38370
- (0, import_react54.useEffect)(() => {
38563
+ (0, import_react55.useEffect)(() => {
38371
38564
  if (imageLoaded) {
38372
38565
  const cropDims = getCropDimensions();
38373
38566
  setCropArea(cropDims);
@@ -38381,7 +38574,7 @@ var LogoCropper = ({
38381
38574
  }));
38382
38575
  }
38383
38576
  }, [aspectRatio, imageLoaded, imageNaturalSize, getCropDimensions]);
38384
- const updatePreview = (0, import_react54.useCallback)((cropX, cropY, cropDims) => {
38577
+ const updatePreview = (0, import_react55.useCallback)((cropX, cropY, cropDims) => {
38385
38578
  const previewCanvas = previewCanvasRef.current;
38386
38579
  const mainCanvas = canvasRef.current;
38387
38580
  if (!previewCanvas || !mainCanvas) return;
@@ -38410,7 +38603,7 @@ var LogoCropper = ({
38410
38603
  previewCtx.lineWidth = 2;
38411
38604
  previewCtx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight);
38412
38605
  }, []);
38413
- const drawCropPreview = (0, import_react54.useCallback)(() => {
38606
+ const drawCropPreview = (0, import_react55.useCallback)(() => {
38414
38607
  const canvas = canvasRef.current;
38415
38608
  const image = imageRef.current;
38416
38609
  if (!canvas || !image || !imageLoaded) return;
@@ -38456,14 +38649,14 @@ var LogoCropper = ({
38456
38649
  ctx.fillRect(cropX + cropDims.width - 1, cropY + cropDims.height - cornerSize + 1, 3, cornerSize);
38457
38650
  updatePreview(cropX, cropY, cropDims);
38458
38651
  }, [cropSettings, imageLoaded, getCropDimensions, updatePreview]);
38459
- (0, import_react54.useEffect)(() => {
38652
+ (0, import_react55.useEffect)(() => {
38460
38653
  drawCropPreview();
38461
38654
  }, [drawCropPreview]);
38462
- const handleMouseDown = (0, import_react54.useCallback)((e) => {
38655
+ const handleMouseDown = (0, import_react55.useCallback)((e) => {
38463
38656
  setIsDragging(true);
38464
38657
  setDragStart({ x: e.clientX, y: e.clientY });
38465
38658
  }, []);
38466
- const handleMouseMove = (0, import_react54.useCallback)((e) => {
38659
+ const handleMouseMove = (0, import_react55.useCallback)((e) => {
38467
38660
  if (!isDragging) return;
38468
38661
  const deltaX = e.clientX - dragStart.x;
38469
38662
  const deltaY = e.clientY - dragStart.y;
@@ -38474,17 +38667,17 @@ var LogoCropper = ({
38474
38667
  }));
38475
38668
  setDragStart({ x: e.clientX, y: e.clientY });
38476
38669
  }, [isDragging, dragStart]);
38477
- const handleMouseUp = (0, import_react54.useCallback)(() => {
38670
+ const handleMouseUp = (0, import_react55.useCallback)(() => {
38478
38671
  setIsDragging(false);
38479
38672
  }, []);
38480
- const handleClose = (0, import_react54.useCallback)(() => {
38673
+ const handleClose = (0, import_react55.useCallback)(() => {
38481
38674
  setImageSrc("");
38482
38675
  setImageLoaded(false);
38483
38676
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
38484
38677
  setAspectRatio("square");
38485
38678
  onClose();
38486
38679
  }, [onClose]);
38487
- const handleCrop = (0, import_react54.useCallback)(() => {
38680
+ const handleCrop = (0, import_react55.useCallback)(() => {
38488
38681
  const image = imageRef.current;
38489
38682
  if (!image) return;
38490
38683
  const cropDims = getCropDimensions();
@@ -38537,7 +38730,7 @@ var LogoCropper = ({
38537
38730
  setAspectRatio("square");
38538
38731
  onClose();
38539
38732
  }, [cropSettings, onCrop, getCropDimensions, outputSize, onClose]);
38540
- const handleScaleChange = (0, import_react54.useCallback)((value) => {
38733
+ const handleScaleChange = (0, import_react55.useCallback)((value) => {
38541
38734
  const cropDims = getCropDimensions();
38542
38735
  const minScale2 = Math.max(
38543
38736
  cropDims.width / imageNaturalSize.width,
@@ -38548,7 +38741,7 @@ var LogoCropper = ({
38548
38741
  scale: Math.max(value, minScale2)
38549
38742
  }));
38550
38743
  }, [imageNaturalSize, getCropDimensions]);
38551
- const handleRotation = (0, import_react54.useCallback)((direction) => {
38744
+ const handleRotation = (0, import_react55.useCallback)((direction) => {
38552
38745
  setCropSettings((prev) => ({
38553
38746
  ...prev,
38554
38747
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -38833,15 +39026,15 @@ var BrandingTab = ({
38833
39026
  }) => {
38834
39027
  const muiTheme = (0, import_material46.useTheme)();
38835
39028
  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);
39029
+ const [dragOver, setDragOver] = (0, import_react56.useState)(false);
39030
+ const [saveStatus, setSaveStatus] = (0, import_react56.useState)("idle");
39031
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react56.useState)("");
39032
+ const [showSnackbar, setShowSnackbar] = (0, import_react56.useState)(false);
39033
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react56.useState)("success");
39034
+ const [cropperOpen, setCropperOpen] = (0, import_react56.useState)(false);
39035
+ const [selectedImageFile, setSelectedImageFile] = (0, import_react56.useState)(null);
39036
+ const fileInputRef = (0, import_react56.useRef)(null);
39037
+ const importInputRef = (0, import_react56.useRef)(null);
38845
39038
  const getDefaultLogo = () => {
38846
39039
  return muiTheme.palette.mode === "light" ? lightLogo2 : banditAiLogo;
38847
39040
  };
@@ -39468,11 +39661,11 @@ var BrandingTab = ({
39468
39661
  var BrandingTab_default = BrandingTab;
39469
39662
 
39470
39663
  // src/management/components/KnowledgeHubTab.tsx
39471
- var import_react60 = require("react");
39664
+ var import_react61 = require("react");
39472
39665
  var import_material50 = require("@mui/material");
39473
39666
 
39474
39667
  // src/management/components/KnowledgeTab.tsx
39475
- var import_react58 = require("react");
39668
+ var import_react59 = require("react");
39476
39669
  var import_uuid6 = require("uuid");
39477
39670
  var import_material48 = require("@mui/material");
39478
39671
  init_knowledge_file_modal();
@@ -39482,7 +39675,7 @@ init_authenticationStore();
39482
39675
  init_useFeatures();
39483
39676
 
39484
39677
  // src/components/shared/ProcessingOverlay.tsx
39485
- var import_react56 = require("react");
39678
+ var import_react57 = require("react");
39486
39679
  var import_material47 = require("@mui/material");
39487
39680
  var import_lucide_react16 = require("lucide-react");
39488
39681
  var import_jsx_runtime47 = require("react/jsx-runtime");
@@ -39555,17 +39748,17 @@ var ProcessingOverlay = ({
39555
39748
  customMessages
39556
39749
  }) => {
39557
39750
  const theme = (0, import_material47.useTheme)();
39558
- const [messageIndex, setMessageIndex] = (0, import_react56.useState)(0);
39559
- const [sparkles, setSparkles] = (0, import_react56.useState)([]);
39751
+ const [messageIndex, setMessageIndex] = (0, import_react57.useState)(0);
39752
+ const [sparkles, setSparkles] = (0, import_react57.useState)([]);
39560
39753
  const messages = customMessages || cleverMessages;
39561
- (0, import_react56.useEffect)(() => {
39754
+ (0, import_react57.useEffect)(() => {
39562
39755
  if (!open) return;
39563
39756
  const interval = setInterval(() => {
39564
39757
  setMessageIndex((prev) => (prev + 1) % messages.length);
39565
39758
  }, 3e3);
39566
39759
  return () => clearInterval(interval);
39567
39760
  }, [open, messages.length]);
39568
- (0, import_react56.useEffect)(() => {
39761
+ (0, import_react57.useEffect)(() => {
39569
39762
  if (!open) return;
39570
39763
  const generateSparkles = () => {
39571
39764
  const newSparkles = Array.from({ length: 5 }, (_, i) => ({
@@ -39777,16 +39970,16 @@ var ProcessingOverlay = ({
39777
39970
  var ProcessingOverlay_default = ProcessingOverlay;
39778
39971
 
39779
39972
  // src/hooks/useProcessingOverlay.ts
39780
- var import_react57 = require("react");
39973
+ var import_react58 = require("react");
39781
39974
  var useProcessingOverlay = () => {
39782
- const [processingState, setProcessingState] = (0, import_react57.useState)({
39975
+ const [processingState, setProcessingState] = (0, import_react58.useState)({
39783
39976
  isVisible: false,
39784
39977
  step: "upload",
39785
39978
  progress: 0,
39786
39979
  title: "Processing...",
39787
39980
  customMessages: void 0
39788
39981
  });
39789
- const showProcessing = (0, import_react57.useCallback)((title = "Processing...", messages) => {
39982
+ const showProcessing = (0, import_react58.useCallback)((title = "Processing...", messages) => {
39790
39983
  setProcessingState({
39791
39984
  isVisible: true,
39792
39985
  step: "upload",
@@ -39795,13 +39988,13 @@ var useProcessingOverlay = () => {
39795
39988
  customMessages: messages
39796
39989
  });
39797
39990
  }, []);
39798
- const hideProcessing = (0, import_react57.useCallback)(() => {
39991
+ const hideProcessing = (0, import_react58.useCallback)(() => {
39799
39992
  setProcessingState((prev) => ({
39800
39993
  ...prev,
39801
39994
  isVisible: false
39802
39995
  }));
39803
39996
  }, []);
39804
- const updateProgress = (0, import_react57.useCallback)((step, progress) => {
39997
+ const updateProgress = (0, import_react58.useCallback)((step, progress) => {
39805
39998
  setProcessingState((prev) => ({
39806
39999
  ...prev,
39807
40000
  step,
@@ -39953,28 +40146,28 @@ var KnowledgeTab = ({
39953
40146
  } = useVectorStore();
39954
40147
  const { showProcessing, hideProcessing, updateProgress, processingState } = useProcessingOverlay();
39955
40148
  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());
40149
+ const [clearDocsDialogOpen, setClearDocsDialogOpen] = (0, import_react59.useState)(false);
40150
+ const [selectedDoc, setSelectedDoc] = (0, import_react59.useState)(null);
40151
+ const [vectorDocuments, setVectorDocuments] = (0, import_react59.useState)([]);
40152
+ const [loadingVectorDocs, setLoadingVectorDocs] = (0, import_react59.useState)(false);
40153
+ const [searchQuery, setSearchQuery] = (0, import_react59.useState)("");
40154
+ const [selectedCategory, setSelectedCategory] = (0, import_react59.useState)("all");
40155
+ const [contentSourceFilter, setContentSourceFilter] = (0, import_react59.useState)("all");
40156
+ const [viewMode, setViewMode] = (0, import_react59.useState)("grid");
40157
+ const [sortBy, setSortBy] = (0, import_react59.useState)("date");
40158
+ const [sortOrder, setSortOrder] = (0, import_react59.useState)("desc");
40159
+ const [selectedDocuments, setSelectedDocuments] = (0, import_react59.useState)([]);
40160
+ const [showFilters, setShowFilters] = (0, import_react59.useState)(false);
40161
+ const [uploadStatuses, setUploadStatuses] = (0, import_react59.useState)([]);
40162
+ const [filterMenuAnchor, setFilterMenuAnchor] = (0, import_react59.useState)(null);
40163
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react59.useState)("");
40164
+ const [showSnackbar, setShowSnackbar] = (0, import_react59.useState)(false);
40165
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react59.useState)("success");
40166
+ const [deletingDocuments, setDeletingDocuments] = (0, import_react59.useState)(/* @__PURE__ */ new Set());
39974
40167
  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) => {
40168
+ const [shareWithTeam, setShareWithTeam] = (0, import_react59.useState)(false);
40169
+ const [dragActive, setDragActive] = (0, import_react59.useState)(false);
40170
+ const mapVectorDocsToKnowledgeDocs = (0, import_react59.useCallback)((vectorDocs) => {
39978
40171
  return vectorDocs.map((doc) => {
39979
40172
  const primaryId = doc.id ?? doc.fileId ?? doc._id;
39980
40173
  const docId = typeof primaryId === "string" ? primaryId : primaryId ? JSON.stringify(primaryId) : (0, import_uuid6.v4)();
@@ -40002,7 +40195,7 @@ var KnowledgeTab = ({
40002
40195
  };
40003
40196
  });
40004
40197
  }, []);
40005
- const loadVectorDocuments = (0, import_react58.useCallback)(async () => {
40198
+ const loadVectorDocuments = (0, import_react59.useCallback)(async () => {
40006
40199
  if (!shouldUseVector) {
40007
40200
  return;
40008
40201
  }
@@ -40017,12 +40210,12 @@ var KnowledgeTab = ({
40017
40210
  setLoadingVectorDocs(false);
40018
40211
  }
40019
40212
  }, [shouldUseVector, getUserDocuments, mapVectorDocsToKnowledgeDocs]);
40020
- (0, import_react58.useEffect)(() => {
40213
+ (0, import_react59.useEffect)(() => {
40021
40214
  if (shouldUseVector) {
40022
40215
  loadVectorDocuments();
40023
40216
  }
40024
40217
  }, [shouldUseVector, loadVectorDocuments]);
40025
- const filteredAndSortedDocuments = (0, import_react58.useMemo)(() => {
40218
+ const filteredAndSortedDocuments = (0, import_react59.useMemo)(() => {
40026
40219
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40027
40220
  let filtered = sourceDocuments;
40028
40221
  if (searchQuery) {
@@ -40072,12 +40265,12 @@ var KnowledgeTab = ({
40072
40265
  });
40073
40266
  return filtered;
40074
40267
  }, [documents, vectorDocuments, shouldUseVector, searchQuery, selectedCategory, contentSourceFilter, sortBy, sortOrder]);
40075
- const categories = (0, import_react58.useMemo)(() => {
40268
+ const categories = (0, import_react59.useMemo)(() => {
40076
40269
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40077
40270
  const cats = new Set(sourceDocuments.map((doc) => getFileTypeInfo3(doc.name).category));
40078
40271
  return Array.from(cats).sort();
40079
40272
  }, [documents, vectorDocuments, shouldUseVector]);
40080
- const statistics = (0, import_react58.useMemo)(() => {
40273
+ const statistics = (0, import_react59.useMemo)(() => {
40081
40274
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40082
40275
  const totalSize = sourceDocuments.reduce((sum, doc) => {
40083
40276
  if (shouldUseVector && doc.size) {
@@ -41099,7 +41292,7 @@ var KnowledgeTab = ({
41099
41292
  var KnowledgeTab_default = KnowledgeTab;
41100
41293
 
41101
41294
  // src/management/components/SeedPacksTab.tsx
41102
- var import_react59 = require("react");
41295
+ var import_react60 = require("react");
41103
41296
  var import_material49 = require("@mui/material");
41104
41297
  init_packageSettingsStore();
41105
41298
  init_authenticationStore();
@@ -41708,45 +41901,45 @@ var SeedPacksTab = () => {
41708
41901
  const seedPackAdminRoles = /* @__PURE__ */ new Set(["admin", "super-user", "team_admin", "team_owner"]);
41709
41902
  const userRoles = authStore.user?.roles ?? [];
41710
41903
  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)({
41904
+ const [seedPacks, setSeedPacks] = (0, import_react60.useState)([]);
41905
+ const [selectedSid, setSelectedSid] = (0, import_react60.useState)(null);
41906
+ const [selectedSeedPack, setSelectedSeedPack] = (0, import_react60.useState)(null);
41907
+ const [draft, setDraft] = (0, import_react60.useState)({
41715
41908
  name: "",
41716
41909
  description: "",
41717
41910
  content: ""
41718
41911
  });
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)(
41912
+ const [tagsInput, setTagsInput] = (0, import_react60.useState)("");
41913
+ const [importedFiles, setImportedFiles] = (0, import_react60.useState)([]);
41914
+ const [createImportedFiles, setCreateImportedFiles] = (0, import_react60.useState)([]);
41915
+ const [previewFile, setPreviewFile] = (0, import_react60.useState)(null);
41916
+ const fileInputRef = (0, import_react60.useRef)(null);
41917
+ const wikiFolderInputRef = (0, import_react60.useRef)(null);
41918
+ const createFileInputRef = (0, import_react60.useRef)(null);
41919
+ const createWikiFolderInputRef = (0, import_react60.useRef)(null);
41920
+ const [isLoadingList, setIsLoadingList] = (0, import_react60.useState)(false);
41921
+ const [isLoadingDetail, setIsLoadingDetail] = (0, import_react60.useState)(false);
41922
+ const [isSaving, setIsSaving] = (0, import_react60.useState)(false);
41923
+ const [isPublishing, setIsPublishing] = (0, import_react60.useState)(false);
41924
+ const [isArchiving, setIsArchiving] = (0, import_react60.useState)(false);
41925
+ const [isDeleting, setIsDeleting] = (0, import_react60.useState)(false);
41926
+ const [isCreating, setIsCreating] = (0, import_react60.useState)(false);
41927
+ const [createDialogOpen, setCreateDialogOpen] = (0, import_react60.useState)(false);
41928
+ const [publishDialogOpen, setPublishDialogOpen] = (0, import_react60.useState)(false);
41929
+ const [archiveDialogOpen, setArchiveDialogOpen] = (0, import_react60.useState)(false);
41930
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react60.useState)(false);
41931
+ const [newPackName, setNewPackName] = (0, import_react60.useState)("");
41932
+ const [newPackDescription, setNewPackDescription] = (0, import_react60.useState)("");
41933
+ const [newPackTags, setNewPackTags] = (0, import_react60.useState)("");
41934
+ const [snackbarOpen, setSnackbarOpen] = (0, import_react60.useState)(false);
41935
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react60.useState)("");
41936
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react60.useState)("success");
41937
+ const parsedTags = (0, import_react60.useMemo)(() => parseTags(tagsInput), [tagsInput]);
41938
+ const normalizedSelectedTags = (0, import_react60.useMemo)(
41746
41939
  () => normalizeTags(selectedSeedPack?.tags),
41747
41940
  [selectedSeedPack?.tags]
41748
41941
  );
41749
- const isDirty = (0, import_react59.useMemo)(() => {
41942
+ const isDirty = (0, import_react60.useMemo)(() => {
41750
41943
  if (!selectedSeedPack) {
41751
41944
  return false;
41752
41945
  }
@@ -41757,17 +41950,17 @@ var SeedPacksTab = () => {
41757
41950
  return nameChanged || descriptionChanged || contentChanged || tagsChanged;
41758
41951
  }, [draft, parsedTags, normalizedSelectedTags, selectedSeedPack]);
41759
41952
  const isReadOnly = !canManage || selectedSeedPack?.status === "archived";
41760
- const sortedSeedPacks = (0, import_react59.useMemo)(() => {
41953
+ const sortedSeedPacks = (0, import_react60.useMemo)(() => {
41761
41954
  return [...seedPacks].sort((a, b) => getSeedPackTimestamp(b) - getSeedPackTimestamp(a));
41762
41955
  }, [seedPacks]);
41763
41956
  const scopeLabel = isTeamScope ? "Team scope" : "Personal scope";
41764
41957
  const scopeDescription = isTeamScope ? "Applies to all members of your team." : "Applies only to your account.";
41765
- const showSnackbar = (0, import_react59.useCallback)((message, severity) => {
41958
+ const showSnackbar = (0, import_react60.useCallback)((message, severity) => {
41766
41959
  setSnackbarMessage(message);
41767
41960
  setSnackbarSeverity(severity);
41768
41961
  setSnackbarOpen(true);
41769
41962
  }, []);
41770
- const hydrateDraft = (0, import_react59.useCallback)((pack) => {
41963
+ const hydrateDraft = (0, import_react60.useCallback)((pack) => {
41771
41964
  setDraft({
41772
41965
  name: pack.name ?? "",
41773
41966
  description: pack.description ?? "",
@@ -41777,14 +41970,14 @@ var SeedPacksTab = () => {
41777
41970
  setImportedFiles([]);
41778
41971
  setPreviewFile(null);
41779
41972
  }, []);
41780
- const resetCreateDialog = (0, import_react59.useCallback)(() => {
41973
+ const resetCreateDialog = (0, import_react60.useCallback)(() => {
41781
41974
  setCreateDialogOpen(false);
41782
41975
  setNewPackName("");
41783
41976
  setNewPackDescription("");
41784
41977
  setNewPackTags("");
41785
41978
  setCreateImportedFiles([]);
41786
41979
  }, []);
41787
- const refreshSeedPacks = (0, import_react59.useCallback)(
41980
+ const refreshSeedPacks = (0, import_react60.useCallback)(
41788
41981
  async (nextSelectedSid) => {
41789
41982
  if (!gatewayConfigured) {
41790
41983
  return;
@@ -41809,7 +42002,7 @@ var SeedPacksTab = () => {
41809
42002
  },
41810
42003
  [gatewayConfigured, selectedSid, showSnackbar]
41811
42004
  );
41812
- const loadSeedPackDetail = (0, import_react59.useCallback)(
42005
+ const loadSeedPackDetail = (0, import_react60.useCallback)(
41813
42006
  async (sid) => {
41814
42007
  if (!gatewayConfigured) {
41815
42008
  return;
@@ -41831,15 +42024,15 @@ var SeedPacksTab = () => {
41831
42024
  },
41832
42025
  [gatewayConfigured, hydrateDraft, showSnackbar]
41833
42026
  );
41834
- (0, import_react59.useEffect)(() => {
42027
+ (0, import_react60.useEffect)(() => {
41835
42028
  void refreshSeedPacks();
41836
42029
  }, [refreshSeedPacks, authStore.token]);
41837
- (0, import_react59.useEffect)(() => {
42030
+ (0, import_react60.useEffect)(() => {
41838
42031
  if (selectedSid) {
41839
42032
  void loadSeedPackDetail(selectedSid);
41840
42033
  }
41841
42034
  }, [selectedSid, loadSeedPackDetail]);
41842
- (0, import_react59.useEffect)(() => {
42035
+ (0, import_react60.useEffect)(() => {
41843
42036
  const setDirectoryUploadAttributes = (input) => {
41844
42037
  if (!input) {
41845
42038
  return;
@@ -41855,7 +42048,7 @@ var SeedPacksTab = () => {
41855
42048
  setSelectedSeedPack(pack);
41856
42049
  hydrateDraft(pack);
41857
42050
  };
41858
- const handleImportFiles = (0, import_react59.useCallback)(
42051
+ const handleImportFiles = (0, import_react60.useCallback)(
41859
42052
  async (files, source = "local") => {
41860
42053
  if (!files || files.length === 0) {
41861
42054
  return;
@@ -41898,24 +42091,24 @@ ${combined}` : combined;
41898
42091
  },
41899
42092
  [importedFiles, showSnackbar]
41900
42093
  );
41901
- const handleFileInputChange = (0, import_react59.useCallback)(
42094
+ const handleFileInputChange = (0, import_react60.useCallback)(
41902
42095
  async (event) => {
41903
42096
  await handleImportFiles(event.target.files, "local");
41904
42097
  event.target.value = "";
41905
42098
  },
41906
42099
  [handleImportFiles]
41907
42100
  );
41908
- const handleWikiFolderInputChange = (0, import_react59.useCallback)(
42101
+ const handleWikiFolderInputChange = (0, import_react60.useCallback)(
41909
42102
  async (event) => {
41910
42103
  await handleImportFiles(event.target.files, "azure-wiki");
41911
42104
  event.target.value = "";
41912
42105
  },
41913
42106
  [handleImportFiles]
41914
42107
  );
41915
- const handleRemoveImportedFile = (0, import_react59.useCallback)((id) => {
42108
+ const handleRemoveImportedFile = (0, import_react60.useCallback)((id) => {
41916
42109
  setImportedFiles((prev) => prev.filter((file) => file.id !== id));
41917
42110
  }, []);
41918
- const handleCreateImportFiles = (0, import_react59.useCallback)(
42111
+ const handleCreateImportFiles = (0, import_react60.useCallback)(
41919
42112
  async (files, source = "local") => {
41920
42113
  if (!files || files.length === 0) {
41921
42114
  return;
@@ -41936,24 +42129,24 @@ ${combined}` : combined;
41936
42129
  },
41937
42130
  [showSnackbar]
41938
42131
  );
41939
- const handleCreateFileInputChange = (0, import_react59.useCallback)(
42132
+ const handleCreateFileInputChange = (0, import_react60.useCallback)(
41940
42133
  async (event) => {
41941
42134
  await handleCreateImportFiles(event.target.files, "local");
41942
42135
  event.target.value = "";
41943
42136
  },
41944
42137
  [handleCreateImportFiles]
41945
42138
  );
41946
- const handleCreateWikiFolderInputChange = (0, import_react59.useCallback)(
42139
+ const handleCreateWikiFolderInputChange = (0, import_react60.useCallback)(
41947
42140
  async (event) => {
41948
42141
  await handleCreateImportFiles(event.target.files, "azure-wiki");
41949
42142
  event.target.value = "";
41950
42143
  },
41951
42144
  [handleCreateImportFiles]
41952
42145
  );
41953
- const handleRemoveCreateImportedFile = (0, import_react59.useCallback)((id) => {
42146
+ const handleRemoveCreateImportedFile = (0, import_react60.useCallback)((id) => {
41954
42147
  setCreateImportedFiles((prev) => prev.filter((file) => file.id !== id));
41955
42148
  }, []);
41956
- const buildDraftPayload2 = (0, import_react59.useCallback)(() => {
42149
+ const buildDraftPayload2 = (0, import_react60.useCallback)(() => {
41957
42150
  const name = draft.name.trim();
41958
42151
  if (!name) {
41959
42152
  showSnackbar("Seed pack name is required.", "error");
@@ -41967,7 +42160,7 @@ ${combined}` : combined;
41967
42160
  contentType: "markdown"
41968
42161
  };
41969
42162
  }, [draft, parsedTags, showSnackbar]);
41970
- const saveDraft = (0, import_react59.useCallback)(async () => {
42163
+ const saveDraft = (0, import_react60.useCallback)(async () => {
41971
42164
  if (!selectedSeedPack) {
41972
42165
  return null;
41973
42166
  }
@@ -42685,9 +42878,9 @@ var KnowledgeHubTab = (props) => {
42685
42878
  const theme = (0, import_material50.useTheme)();
42686
42879
  const isMobile = (0, import_material50.useMediaQuery)(theme.breakpoints.down("sm"));
42687
42880
  const { seedPacksEnabled = false } = props;
42688
- const [tabIndex, setTabIndex] = (0, import_react60.useState)(0);
42881
+ const [tabIndex, setTabIndex] = (0, import_react61.useState)(0);
42689
42882
  const effectiveTabIndex = seedPacksEnabled ? tabIndex : 0;
42690
- (0, import_react60.useEffect)(() => {
42883
+ (0, import_react61.useEffect)(() => {
42691
42884
  if (!seedPacksEnabled && tabIndex !== 0) {
42692
42885
  setTabIndex(0);
42693
42886
  }
@@ -42737,7 +42930,7 @@ var KnowledgeHubTab = (props) => {
42737
42930
  var KnowledgeHubTab_default = KnowledgeHubTab;
42738
42931
 
42739
42932
  // src/management/components/StorageTab.tsx
42740
- var import_react61 = require("react");
42933
+ var import_react62 = require("react");
42741
42934
  var import_material51 = require("@mui/material");
42742
42935
  init_debugLogger();
42743
42936
  init_indexedDBService();
@@ -43040,20 +43233,20 @@ var clearEntireDatabase = async (dbName) => {
43040
43233
  };
43041
43234
  var StorageTab = ({ currentTheme }) => {
43042
43235
  const theme = (0, import_material51.useTheme)();
43043
- const [storageQuota, setStorageQuota] = (0, import_react61.useState)({
43236
+ const [storageQuota, setStorageQuota] = (0, import_react62.useState)({
43044
43237
  used: 0,
43045
43238
  quota: 0,
43046
43239
  available: 0,
43047
43240
  browserQuotaEstimate: 0
43048
43241
  });
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");
43242
+ const [storageCategories, setStorageCategories] = (0, import_react62.useState)([]);
43243
+ const [loading, setLoading] = (0, import_react62.useState)(true);
43244
+ const [clearAllDialogOpen, setClearAllDialogOpen] = (0, import_react62.useState)(false);
43245
+ const [clearCategoryDialog, setClearCategoryDialog] = (0, import_react62.useState)(null);
43246
+ const [clearing, setClearing] = (0, import_react62.useState)(false);
43247
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react62.useState)("");
43248
+ const [showSnackbar, setShowSnackbar] = (0, import_react62.useState)(false);
43249
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react62.useState)("success");
43057
43250
  const { syncEnabled, isAdvancedVectorFeaturesEnabled } = useConversationSyncStore((state) => ({
43058
43251
  syncEnabled: state.syncEnabled,
43059
43252
  isAdvancedVectorFeaturesEnabled: state.isAdvancedVectorFeaturesEnabled
@@ -43105,18 +43298,18 @@ var StorageTab = ({ currentTheme }) => {
43105
43298
  setLoading(false);
43106
43299
  }
43107
43300
  };
43108
- (0, import_react61.useEffect)(() => {
43301
+ (0, import_react62.useEffect)(() => {
43109
43302
  loadStorageData();
43110
43303
  }, []);
43111
- const totalUsed = (0, import_react61.useMemo)(() => {
43304
+ const totalUsed = (0, import_react62.useMemo)(() => {
43112
43305
  return storageCategories.reduce((sum, cat) => sum + cat.size, 0);
43113
43306
  }, [storageCategories]);
43114
- const usagePercentage = (0, import_react61.useMemo)(() => {
43307
+ const usagePercentage = (0, import_react62.useMemo)(() => {
43115
43308
  if (storageQuota.quota === 0) return 0;
43116
43309
  const percentage = Math.min(storageQuota.used / storageQuota.quota * 100, 100);
43117
43310
  return percentage > 0 && percentage < 0.1 ? 0.1 : percentage;
43118
43311
  }, [storageQuota]);
43119
- const clearableCategories = (0, import_react61.useMemo)(() => {
43312
+ const clearableCategories = (0, import_react62.useMemo)(() => {
43120
43313
  return storageCategories.filter((cat) => cat.canClear);
43121
43314
  }, [storageCategories]);
43122
43315
  const handleClearCategory = async (category) => {
@@ -43732,7 +43925,7 @@ var StorageTab = ({ currentTheme }) => {
43732
43925
  var StorageTab_default = StorageTab;
43733
43926
 
43734
43927
  // src/management/components/ProviderTab.tsx
43735
- var import_react62 = require("react");
43928
+ var import_react63 = require("react");
43736
43929
  var import_material52 = require("@mui/material");
43737
43930
  init_aiProviderStore();
43738
43931
  init_packageSettingsStore();
@@ -43746,7 +43939,7 @@ var ProviderTab = () => {
43746
43939
  const { settings: packageSettings } = usePackageSettingsStore();
43747
43940
  const theme = (0, import_material52.useTheme)();
43748
43941
  const isMobile = (0, import_material52.useMediaQuery)(theme.breakpoints.down("sm"));
43749
- const getSuggestedModel = (0, import_react62.useCallback)((type) => {
43942
+ const getSuggestedModel = (0, import_react63.useCallback)((type) => {
43750
43943
  const configuredDefault = packageSettings?.defaultModel?.trim();
43751
43944
  if (configuredDefault) {
43752
43945
  return configuredDefault;
@@ -43762,7 +43955,7 @@ var ProviderTab = () => {
43762
43955
  return "";
43763
43956
  }
43764
43957
  }, [packageSettings?.defaultModel]);
43765
- const applyDefaultModel = (0, import_react62.useCallback)((config) => {
43958
+ const applyDefaultModel = (0, import_react63.useCallback)((config) => {
43766
43959
  const normalized = { ...config };
43767
43960
  const trimmed = typeof normalized.defaultModel === "string" ? normalized.defaultModel.trim() : void 0;
43768
43961
  const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */ || normalized.type === "bandit" /* BANDIT */;
@@ -43782,7 +43975,7 @@ var ProviderTab = () => {
43782
43975
  }
43783
43976
  return normalized;
43784
43977
  }, [getSuggestedModel]);
43785
- const sanitizeConfigForSave = (0, import_react62.useCallback)((config) => {
43978
+ const sanitizeConfigForSave = (0, import_react63.useCallback)((config) => {
43786
43979
  const sanitized = { ...config };
43787
43980
  if (typeof sanitized.defaultModel === "string") {
43788
43981
  const trimmed = sanitized.defaultModel.trim();
@@ -43794,14 +43987,14 @@ var ProviderTab = () => {
43794
43987
  }
43795
43988
  return sanitized;
43796
43989
  }, []);
43797
- const [providerConfig, setProviderConfig] = (0, import_react62.useState)({
43990
+ const [providerConfig, setProviderConfig] = (0, import_react63.useState)({
43798
43991
  type: "gateway",
43799
43992
  gatewayUrl: packageSettings?.gatewayApiUrl || "",
43800
43993
  provider: "bandit"
43801
43994
  });
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");
43995
+ const [snackbarMessage, setSnackbarMessage] = (0, import_react63.useState)("");
43996
+ const [showSnackbar, setShowSnackbar] = (0, import_react63.useState)(false);
43997
+ const [snackbarSeverity, setSnackbarSeverity] = (0, import_react63.useState)("success");
43805
43998
  const saveProviderConfigToDB = async (config) => {
43806
43999
  try {
43807
44000
  const { tokenFactory: _tokenFactory, ...persistableConfig } = config;
@@ -43842,7 +44035,7 @@ var ProviderTab = () => {
43842
44035
  }
43843
44036
  return null;
43844
44037
  };
43845
- const convertAnthropicConfig = (0, import_react62.useCallback)((config) => {
44038
+ const convertAnthropicConfig = (0, import_react63.useCallback)((config) => {
43846
44039
  if (!config) return null;
43847
44040
  if (config.type !== "anthropic" /* ANTHROPIC */) {
43848
44041
  return config;
@@ -43858,7 +44051,7 @@ var ProviderTab = () => {
43858
44051
  };
43859
44052
  return converted;
43860
44053
  }, [packageSettings?.gatewayApiUrl]);
43861
- (0, import_react62.useEffect)(() => {
44054
+ (0, import_react63.useEffect)(() => {
43862
44055
  const initializeProviderConfig = async () => {
43863
44056
  const savedConfig = await loadProviderConfigFromDB();
43864
44057
  if (savedConfig) {
@@ -44328,7 +44521,7 @@ var ProviderTab = () => {
44328
44521
  };
44329
44522
 
44330
44523
  // src/management/components/MCPToolsTabV2.tsx
44331
- var import_react64 = require("react");
44524
+ var import_react65 = require("react");
44332
44525
  var import_material54 = require("@mui/material");
44333
44526
 
44334
44527
  // src/services/mcp/mcpControllerService.ts
@@ -44405,7 +44598,7 @@ async function fetchMcpHealth() {
44405
44598
  }
44406
44599
 
44407
44600
  // src/management/components/McpServersSection.tsx
44408
- var import_react63 = require("react");
44601
+ var import_react64 = require("react");
44409
44602
  var import_material53 = require("@mui/material");
44410
44603
  init_lucide_icons();
44411
44604
  init_mcpServersService();
@@ -44481,17 +44674,17 @@ var CATALOG = [
44481
44674
  }
44482
44675
  ];
44483
44676
  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)({});
44677
+ const [servers, setServers] = (0, import_react64.useState)([]);
44678
+ const [loading, setLoading] = (0, import_react64.useState)(false);
44679
+ const [error, setError] = (0, import_react64.useState)(null);
44680
+ const [form, setForm] = (0, import_react64.useState)(emptyForm);
44681
+ const [activeEntry, setActiveEntry] = (0, import_react64.useState)(null);
44682
+ const [adding, setAdding] = (0, import_react64.useState)(false);
44683
+ const [showForm, setShowForm] = (0, import_react64.useState)(false);
44684
+ const [tools, setTools] = (0, import_react64.useState)({});
44492
44685
  const reloadChatTools = useMCPToolsStore((s) => s.loadMcpServerTools);
44493
- const formRef = (0, import_react63.useRef)(null);
44494
- const refresh = (0, import_react63.useCallback)(async () => {
44686
+ const formRef = (0, import_react64.useRef)(null);
44687
+ const refresh = (0, import_react64.useCallback)(async () => {
44495
44688
  setLoading(true);
44496
44689
  setError(null);
44497
44690
  try {
@@ -44502,7 +44695,7 @@ var McpServersSection = () => {
44502
44695
  setLoading(false);
44503
44696
  }
44504
44697
  }, []);
44505
- (0, import_react63.useEffect)(() => {
44698
+ (0, import_react64.useEffect)(() => {
44506
44699
  refresh();
44507
44700
  }, [refresh]);
44508
44701
  const connectedKeys = new Set(servers.map((s) => s.url.replace(/\/+$/, "")));
@@ -44798,10 +44991,10 @@ var import_jsx_runtime54 = require("react/jsx-runtime");
44798
44991
  var MCPToolsTabV2 = () => {
44799
44992
  const { settings } = usePackageSettingsStore();
44800
44993
  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);
44994
+ const [loading, setLoading] = (0, import_react65.useState)(true);
44995
+ const [error, setError] = (0, import_react65.useState)(null);
44996
+ const [tools, setTools] = (0, import_react65.useState)([]);
44997
+ const [health, setHealth] = (0, import_react65.useState)(null);
44805
44998
  const gatewayConfigured = !!settings?.gatewayApiUrl;
44806
44999
  const refresh = async () => {
44807
45000
  setLoading(true);
@@ -44855,7 +45048,7 @@ var MCPToolsTabV2 = () => {
44855
45048
  setLoading(false);
44856
45049
  }
44857
45050
  };
44858
- (0, import_react64.useEffect)(() => {
45051
+ (0, import_react65.useEffect)(() => {
44859
45052
  if (isLoaded) {
44860
45053
  refresh();
44861
45054
  } else {
@@ -44864,7 +45057,7 @@ var MCPToolsTabV2 = () => {
44864
45057
  });
44865
45058
  }
44866
45059
  }, [isLoaded]);
44867
- const localEnabledMap = (0, import_react64.useMemo)(() => {
45060
+ const localEnabledMap = (0, import_react65.useMemo)(() => {
44868
45061
  const map23 = /* @__PURE__ */ new Map();
44869
45062
  const sortedTools = [...localTools].sort((a, b) => {
44870
45063
  if (a.isBuiltIn && !b.isBuiltIn) return -1;
@@ -44995,10 +45188,10 @@ var buildCapabilitiesUrl = (gatewayApiUrl) => {
44995
45188
  return `${trimmed}/api/capabilities`;
44996
45189
  };
44997
45190
  var Management = () => {
44998
- const navigate = (0, import_react_router_dom6.useNavigate)();
45191
+ const navigate = (0, import_react_router_dom7.useNavigate)();
44999
45192
  const notificationService2 = useNotificationService();
45000
45193
  const isMobile = (0, import_useMediaQuery2.default)("(max-width:900px)");
45001
- const [sidebarOpen, setSidebarOpen] = (0, import_react65.useState)(false);
45194
+ const [sidebarOpen, setSidebarOpen] = (0, import_react66.useState)(false);
45002
45195
  const getOptimalFabLogo = async () => {
45003
45196
  const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
45004
45197
  try {
@@ -45038,17 +45231,17 @@ var Management = () => {
45038
45231
  hasTransparentLogo,
45039
45232
  setHasTransparentLogo
45040
45233
  } = useModelStore();
45041
- const [modalOpen, setModalOpen] = (0, import_react65.useState)(false);
45234
+ const [modalOpen, setModalOpen] = (0, import_react66.useState)(false);
45042
45235
  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);
45236
+ const [fabLogo, setFabLogo] = (0, import_react66.useState)(banditHead5);
45237
+ const [tabIndex, setTabIndex] = (0, import_react66.useState)(4);
45238
+ const [logoFile, setLogoFile] = (0, import_react66.useState)(null);
45239
+ const [logoBase64, setLogoBase64] = (0, import_react66.useState)(null);
45240
+ const [brandingText, setBrandingText] = (0, import_react66.useState)("");
45241
+ const [headerMode, setHeaderMode] = (0, import_react66.useState)("logo");
45242
+ const [theme, setTheme] = (0, import_react66.useState)("bandit-dark");
45243
+ const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react66.useState)(null);
45244
+ const [presetAvatar, setPresetAvatar] = (0, import_react66.useState)(null);
45052
45245
  const showSnackbarMessage = (message, severity = "success") => {
45053
45246
  if (severity === "success") {
45054
45247
  notificationService2?.showSuccess(message);
@@ -45056,9 +45249,9 @@ var Management = () => {
45056
45249
  notificationService2?.showError(message);
45057
45250
  }
45058
45251
  };
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);
45252
+ const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react66.useState)(false);
45253
+ const [brandingLoaded, setBrandingLoaded] = (0, import_react66.useState)(false);
45254
+ const [isLoadingBranding, setIsLoadingBranding] = (0, import_react66.useState)(false);
45062
45255
  const { initModels } = useModelStore();
45063
45256
  const { settings: packageSettings } = usePackageSettingsStore();
45064
45257
  const authToken = useAuthenticationStore((state) => state.token);
@@ -45066,8 +45259,8 @@ var Management = () => {
45066
45259
  const { hasAdminDashboard, hasLimitedAdminDashboard, getCurrentTier, hasAdvancedSearch } = useFeatures();
45067
45260
  const { showAdminPanel, showLimitedAdminPanel } = useFeatureVisibility();
45068
45261
  const { provider: currentProvider, config: currentProviderConfig } = useAIProviderStore();
45069
- const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react65.useState)(false);
45070
- const [localSelectedModel, setLocalSelectedModel] = (0, import_react65.useState)({
45262
+ const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react66.useState)(false);
45263
+ const [localSelectedModel, setLocalSelectedModel] = (0, import_react66.useState)({
45071
45264
  name: "",
45072
45265
  tagline: "",
45073
45266
  systemPrompt: "",
@@ -45080,7 +45273,7 @@ var Management = () => {
45080
45273
  loadDocuments,
45081
45274
  clearAllDocuments
45082
45275
  } = useKnowledgeStore2();
45083
- (0, import_react65.useEffect)(() => {
45276
+ (0, import_react66.useEffect)(() => {
45084
45277
  if (selectedModel) {
45085
45278
  const selected = availableModels.find((m) => m.name === selectedModel);
45086
45279
  if (selected) {
@@ -45104,7 +45297,7 @@ var Management = () => {
45104
45297
  }
45105
45298
  }
45106
45299
  }, [selectedModel, availableModels]);
45107
- const loadBrandingConfig = (0, import_react65.useCallback)(async () => {
45300
+ const loadBrandingConfig = (0, import_react66.useCallback)(async () => {
45108
45301
  if (isLoadingBranding || brandingLoaded) {
45109
45302
  debugLogger.warn("Branding loading already in progress or completed, skipping");
45110
45303
  return;
@@ -45221,15 +45414,15 @@ var Management = () => {
45221
45414
  setTagline,
45222
45415
  setTheme
45223
45416
  ]);
45224
- (0, import_react65.useEffect)(() => {
45417
+ (0, import_react66.useEffect)(() => {
45225
45418
  void loadBrandingConfig();
45226
45419
  }, [loadBrandingConfig]);
45227
45420
  const handleOpenModal = () => setModalOpen(true);
45228
45421
  const handleCloseModal = () => setModalOpen(false);
45229
- (0, import_react65.useEffect)(() => {
45422
+ (0, import_react66.useEffect)(() => {
45230
45423
  getOptimalFabLogo().then(setFabLogo);
45231
45424
  }, []);
45232
- (0, import_react65.useEffect)(() => {
45425
+ (0, import_react66.useEffect)(() => {
45233
45426
  if (logoBase64) {
45234
45427
  setFabLogo(logoBase64);
45235
45428
  } else {
@@ -45682,7 +45875,7 @@ var Management = () => {
45682
45875
  reader.readAsText(file);
45683
45876
  }
45684
45877
  };
45685
- (0, import_react65.useEffect)(() => {
45878
+ (0, import_react66.useEffect)(() => {
45686
45879
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
45687
45880
  setLocalSelectedModel((prev) => ({
45688
45881
  ...prev,
@@ -45690,10 +45883,10 @@ var Management = () => {
45690
45883
  }));
45691
45884
  }
45692
45885
  }, [availableModels, localSelectedModel.selectedModel]);
45693
- (0, import_react65.useEffect)(() => {
45886
+ (0, import_react66.useEffect)(() => {
45694
45887
  loadDocuments();
45695
45888
  }, [loadDocuments]);
45696
- (0, import_react65.useEffect)(() => {
45889
+ (0, import_react66.useEffect)(() => {
45697
45890
  const gatewayApiUrl = packageSettings?.gatewayApiUrl;
45698
45891
  if (!gatewayApiUrl || gatewayApiUrl.toLowerCase().startsWith("playground://")) {
45699
45892
  setSeedPacksEnabled(false);
@@ -45736,7 +45929,7 @@ var Management = () => {
45736
45929
  isActive = false;
45737
45930
  };
45738
45931
  }, [packageSettings?.gatewayApiUrl, authToken]);
45739
- const currentTheme = (0, import_react65.useMemo)(() => {
45932
+ const currentTheme = (0, import_react66.useMemo)(() => {
45740
45933
  const baseTheme = predefinedThemes[theme] || banditDarkTheme;
45741
45934
  return (0, import_styles35.createTheme)(baseTheme, {
45742
45935
  // Management-scoped density: condenses every settings tab at once. This
@@ -45857,7 +46050,7 @@ var Management = () => {
45857
46050
  });
45858
46051
  const preferredDefaultTabIndex = navTabs.findIndex((tab) => tab.label === "Preferences");
45859
46052
  const defaultTabIndex = preferredDefaultTabIndex >= 0 ? preferredDefaultTabIndex : 0;
45860
- (0, import_react65.useEffect)(() => {
46053
+ (0, import_react66.useEffect)(() => {
45861
46054
  setTabIndex((current) => {
45862
46055
  if (current < 0 || current >= navTabs.length) {
45863
46056
  return defaultTabIndex;
@@ -46014,6 +46207,10 @@ var Management = () => {
46014
46207
  justifyContent: "space-between",
46015
46208
  px: 3,
46016
46209
  py: 1.5,
46210
+ // The native shell and installed PWAs run edge-to-edge, so the
46211
+ // sticky bar starts underneath the status bar / notch unless it
46212
+ // reserves the inset itself (chat-app-bar does the same).
46213
+ pt: "calc(12px + env(safe-area-inset-top, 0px))",
46017
46214
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(24,28,40,0.95)" : "rgba(255,255,255,0.95)",
46018
46215
  borderBottom: (theme2) => `1px solid ${theme2.palette.divider}`,
46019
46216
  backdropFilter: "blur(12px)",
@@ -46309,7 +46506,7 @@ var Management = () => {
46309
46506
  ]
46310
46507
  }
46311
46508
  ),
46312
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46509
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46313
46510
  import_material55.Fab,
46314
46511
  {
46315
46512
  "aria-label": "AI",
@@ -46345,7 +46542,7 @@ var Management = () => {
46345
46542
  )
46346
46543
  }
46347
46544
  ),
46348
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
46545
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
46349
46546
  ]
46350
46547
  }
46351
46548
  )
@@ -46354,7 +46551,7 @@ var Management = () => {
46354
46551
  var management_default = Management;
46355
46552
 
46356
46553
  // src/management/components/InterestsEditor.tsx
46357
- var import_react66 = require("react");
46554
+ var import_react67 = require("react");
46358
46555
  var import_material56 = require("@mui/material");
46359
46556
  init_preferencesStore();
46360
46557
  init_getStableQuestionPrompt();
@@ -46367,7 +46564,7 @@ var InterestsEditor = ({
46367
46564
  const updatePreference = usePreferencesStore((s) => s.updatePreference);
46368
46565
  const loadPreferences = usePreferencesStore((s) => s.loadPreferences);
46369
46566
  const isLoaded = usePreferencesStore((s) => s.isLoaded);
46370
- (0, import_react66.useEffect)(() => {
46567
+ (0, import_react67.useEffect)(() => {
46371
46568
  if (!isLoaded) {
46372
46569
  void loadPreferences();
46373
46570
  }
@@ -46399,7 +46596,7 @@ var InterestsEditor = ({
46399
46596
  var InterestsEditor_default = InterestsEditor;
46400
46597
 
46401
46598
  // src/shared/custom-element.ts
46402
- var import_react67 = __toESM(require("react"));
46599
+ var import_react68 = __toESM(require("react"));
46403
46600
  var import_client = __toESM(require("react-dom/client"));
46404
46601
  function defineCustomElement(name, Component) {
46405
46602
  if (customElements.get(name)) return;
@@ -46427,7 +46624,7 @@ function defineCustomElement(name, Component) {
46427
46624
  if (!this.root) {
46428
46625
  this.root = import_client.default.createRoot(this.mountPoint);
46429
46626
  }
46430
- this.root.render(import_react67.default.createElement(Component, props));
46627
+ this.root.render(import_react68.default.createElement(Component, props));
46431
46628
  }
46432
46629
  }
46433
46630
  customElements.define(name, ReactElement);
@@ -46636,7 +46833,7 @@ var getFeatureMatrix = () => featureFlagService.generateFeatureMatrix();
46636
46833
  init_featureFlags();
46637
46834
 
46638
46835
  // src/hooks/useVoices.ts
46639
- var import_react68 = require("react");
46836
+ var import_react69 = require("react");
46640
46837
  init_voiceStore();
46641
46838
  init_packageSettingsStore();
46642
46839
  init_authenticationStore();
@@ -46656,7 +46853,7 @@ var useVoices = () => {
46656
46853
  } = useVoiceStore();
46657
46854
  const gatewayApiUrl = usePackageSettingsStore((state) => state.settings?.gatewayApiUrl);
46658
46855
  const { token } = useAuthenticationStore();
46659
- (0, import_react68.useEffect)(() => {
46856
+ (0, import_react69.useEffect)(() => {
46660
46857
  const isAuthenticated = authenticationService2.isAuthenticated();
46661
46858
  if (gatewayApiUrl && token && isAuthenticated && !isServiceAvailable) {
46662
46859
  debugLogger.debug("Gateway API URL and JWT token available, loading voice models...");
@@ -46784,7 +46981,7 @@ var SubscriptionExpiredModal = ({
46784
46981
  };
46785
46982
 
46786
46983
  // src/guards/SubscriptionExpiredGuard.tsx
46787
- var import_react69 = require("react");
46984
+ var import_react70 = require("react");
46788
46985
  init_useFeatures();
46789
46986
  var import_jsx_runtime58 = require("react/jsx-runtime");
46790
46987
  var SubscriptionExpiredGuard = ({
@@ -46795,9 +46992,9 @@ var SubscriptionExpiredGuard = ({
46795
46992
  allowContinue = false
46796
46993
  }) => {
46797
46994
  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)(() => {
46995
+ const [showModal, setShowModal] = (0, import_react70.useState)(false);
46996
+ const [userDismissed, setUserDismissed] = (0, import_react70.useState)(false);
46997
+ (0, import_react70.useEffect)(() => {
46801
46998
  if (isExpiredTier() && !userDismissed) {
46802
46999
  setShowModal(true);
46803
47000
  } else {