@burtson-labs/bandit-engine 2.0.151 → 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-ZRJYLJKZ.mjs → chunk-6NYYYKYZ.mjs} +267 -81
  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-DSYE5AHW.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 +793 -597
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +10 -10
  25. package/dist/management/management.js +492 -296
  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-3HV3GM5P.mjs +0 -16
  37. package/dist/chunk-6STVJJSG.mjs.map +0 -1
  38. package/dist/chunk-CVFFNX7H.mjs.map +0 -1
  39. package/dist/chunk-DSYE5AHW.mjs.map +0 -1
  40. package/dist/chunk-ZRJYLJKZ.mjs.map +0 -1
  41. /package/dist/{chat-3HV3GM5P.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);
@@ -31677,38 +31821,33 @@ var init_chat2 = __esm({
31677
31821
  // reads as full physical height with the rounded corner visible
31678
31822
  // where it overlaps the drawer.
31679
31823
  transform: isMobile && mobileConversationsOpen ? "translateX(calc(min(calc(100vw - 56px), 360px) - 12px))" : "none",
31680
- // Square top-left + no top border: the card's edge runs unbroken
31681
- // from the very top of the screen (all surfaces share one color),
31682
- // which reads as true full height; a soft bottom-left corner keeps
31683
- // the sheet feel.
31684
- borderRadius: isMobile && mobileConversationsOpen ? "0 0 0 28px" : 0,
31685
- borderTop: isMobile && mobileConversationsOpen ? "none" : void 0,
31824
+ // Rounded card corner, positioned exactly where Claude's sits: at
31825
+ // the top of the webview, just below the OS status strip. The strip
31826
+ // itself is reserved by iOS in web-app mode — no web content can
31827
+ // draw there, so this IS the full available height.
31828
+ borderRadius: isMobile && mobileConversationsOpen ? "44px" : 0,
31686
31829
  zIndex: isMobile && mobileConversationsOpen ? theme.zIndex.modal + 1 : 0,
31687
31830
  // Hairline border so the rounded card reads even when the backdrop
31688
31831
  // is the same near-black as the shell.
31689
31832
  border: isMobile && mobileConversationsOpen ? `1px solid ${theme.palette.mode === "dark" ? "rgba(255,255,255,0.14)" : "rgba(0,0,0,0.12)"}` : "none",
31690
31833
  boxShadow: isMobile && mobileConversationsOpen ? `0 12px 40px ${theme.palette.mode === "dark" ? "rgba(0,0,0,0.55)" : "rgba(0,0,0,0.25)"}` : "none",
31691
- 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"
31692
31835
  }),
31693
31836
  onClick: isMobile && mobileConversationsOpen ? (e) => {
31694
31837
  if (e.currentTarget.contains(e.target)) {
31695
31838
  setMobileConversationsOpen(false);
31696
31839
  }
31697
31840
  } : void 0,
31841
+ style: drawerDragStyle,
31698
31842
  onTouchStart: isMobile && mobileConversationsOpen ? (e) => {
31699
31843
  if (e.currentTarget.contains(e.target)) {
31700
31844
  cardSwipeStartXRef.current = e.touches[0]?.clientX ?? null;
31845
+ drawerDragStart(e);
31701
31846
  }
31702
31847
  } : void 0,
31703
- onTouchMove: isMobile && mobileConversationsOpen ? (e) => {
31704
- const start = cardSwipeStartXRef.current;
31705
- if (start === null) return;
31706
- const dx = (e.touches[0]?.clientX ?? start) - start;
31707
- if (Math.abs(dx) > 40) {
31708
- cardSwipeStartXRef.current = null;
31709
- setMobileConversationsOpen(false);
31710
- }
31711
- } : void 0,
31848
+ onTouchMove: isMobile && mobileConversationsOpen ? drawerDragMove : void 0,
31849
+ onTouchEnd: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31850
+ onTouchCancel: isMobile && mobileConversationsOpen ? drawerDragEnd : void 0,
31712
31851
  children: [
31713
31852
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31714
31853
  chat_app_bar_default,
@@ -31721,7 +31860,13 @@ var init_chat2 = __esm({
31721
31860
  drawerOpen,
31722
31861
  setDrawerOpen,
31723
31862
  mobileConversationsOpen,
31724
- onMobileConversationsOpenChange: setMobileConversationsOpen
31863
+ onMobileConversationsOpenChange: setMobileConversationsOpen,
31864
+ mobileConversationsDrag: isMobile ? {
31865
+ style: drawerPanelDragStyle,
31866
+ onTouchStart: drawerDragStart,
31867
+ onTouchMove: drawerDragMove,
31868
+ onTouchEnd: drawerDragEnd
31869
+ } : void 0
31725
31870
  }
31726
31871
  ),
31727
31872
  isTemporaryChat && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
@@ -31877,6 +32022,53 @@ var init_chat2 = __esm({
31877
32022
  }
31878
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 });
31879
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
+ ),
31880
32072
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
31881
32073
  import_material33.Box,
31882
32074
  {
@@ -32013,7 +32205,7 @@ var init_chat2 = __esm({
32013
32205
  });
32014
32206
  if (!allowUnauthenticated && !bypassAuth && !authenticationService2.isAuthenticated()) {
32015
32207
  debugLogger.debug("User is not authenticated, redirecting to login");
32016
- 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 });
32017
32209
  }
32018
32210
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ChatContent, {});
32019
32211
  };
@@ -32544,31 +32736,31 @@ var chat_provider_default = ChatProvider;
32544
32736
  init_chat2();
32545
32737
 
32546
32738
  // src/management/management.tsx
32547
- var import_react65 = require("react");
32739
+ var import_react66 = require("react");
32548
32740
  var import_useMediaQuery2 = __toESM(require("@mui/material/useMediaQuery"));
32549
32741
  var import_styles35 = require("@mui/material/styles");
32550
32742
  init_useKnowledgeStore();
32551
32743
  init_indexedDBService();
32552
32744
  var import_material55 = require("@mui/material");
32553
- var import_react_router_dom6 = require("react-router-dom");
32745
+ var import_react_router_dom7 = require("react-router-dom");
32554
32746
 
32555
32747
  // src/modals/chat-modal/chat-modal.tsx
32556
- var import_react49 = require("react");
32748
+ var import_react50 = require("react");
32557
32749
  var import_material41 = require("@mui/material");
32558
- var import_react_router_dom5 = require("react-router-dom");
32750
+ var import_react_router_dom6 = require("react-router-dom");
32559
32751
 
32560
32752
  // src/modals/chat-modal/draggable-box.tsx
32561
- var import_react42 = __toESM(require("react"));
32753
+ var import_react43 = __toESM(require("react"));
32562
32754
  var import_material34 = require("@mui/material");
32563
32755
  var import_jsx_runtime35 = require("react/jsx-runtime");
32564
32756
  var SCROLLABLE_THRESHOLD = 200;
32565
- var DraggableBox = import_react42.default.forwardRef(
32757
+ var DraggableBox = import_react43.default.forwardRef(
32566
32758
  ({ children, fullScreen, position, setPosition, onDrag, onScrollThresholdExceeded }, ref) => {
32567
32759
  const theme = (0, import_material34.useTheme)();
32568
- const [transitionProps, setTransitionProps] = (0, import_react42.useState)("all");
32569
- const [isDragging, setIsDragging] = (0, import_react42.useState)(false);
32570
- const [isHovering, setIsHovering] = (0, import_react42.useState)(false);
32571
- (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)(() => {
32572
32764
  if (ref && typeof ref !== "function" && ref.current && !fullScreen) {
32573
32765
  const modal = ref.current;
32574
32766
  const contentHeight = modal.scrollHeight;
@@ -32644,7 +32836,7 @@ var DraggableBox = import_react42.default.forwardRef(
32644
32836
  var draggable_box_default = DraggableBox;
32645
32837
 
32646
32838
  // src/modals/chat-modal/modal-header.tsx
32647
- var import_react43 = require("react");
32839
+ var import_react44 = require("react");
32648
32840
  var import_material35 = require("@mui/material");
32649
32841
  init_lucide_icons();
32650
32842
  var import_jsx_runtime36 = require("react/jsx-runtime");
@@ -32664,7 +32856,7 @@ var ModalHeader = ({
32664
32856
  const theme = (0, import_material35.useTheme)();
32665
32857
  const isMobile = (0, import_material35.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
32666
32858
  const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead3;
32667
- const [isHovering, setIsHovering] = (0, import_react43.useState)(false);
32859
+ const [isHovering, setIsHovering] = (0, import_react44.useState)(false);
32668
32860
  const buttonStyles = {
32669
32861
  transition: "all 0.15s ease-out",
32670
32862
  borderRadius: "8px",
@@ -32862,7 +33054,7 @@ var ModalHeader = ({
32862
33054
  var modal_header_default = ModalHeader;
32863
33055
 
32864
33056
  // src/modals/chat-modal/query-input.tsx
32865
- var import_react44 = require("react");
33057
+ var import_react45 = require("react");
32866
33058
  var import_material36 = require("@mui/material");
32867
33059
  init_lucide_icons();
32868
33060
  var import_jsx_runtime37 = require("react/jsx-runtime");
@@ -32880,7 +33072,7 @@ var QueryInput = ({
32880
33072
  // Destructure endAdornment
32881
33073
  }) => {
32882
33074
  const theme = (0, import_material36.useTheme)();
32883
- const inputRef = (0, import_react44.useRef)(null);
33075
+ const inputRef = (0, import_react45.useRef)(null);
32884
33076
  const handleSend = (e, payload) => {
32885
33077
  onSend(e, payload);
32886
33078
  };
@@ -32947,7 +33139,7 @@ init_ai_response_text_field();
32947
33139
  init_indexedDBService();
32948
33140
 
32949
33141
  // src/modals/chat-modal/chat-drawer.tsx
32950
- var import_react45 = __toESM(require("react"));
33142
+ var import_react46 = __toESM(require("react"));
32951
33143
  var import_material37 = require("@mui/material");
32952
33144
  init_aiQueryStore();
32953
33145
  init_conversationStore();
@@ -32982,23 +33174,23 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
32982
33174
  const { settings: packageSettings } = usePackageSettingsStore();
32983
33175
  const provider = useAIProviderStore((state) => state.provider);
32984
33176
  const { selectedModel, availableModels } = useModelStore();
32985
- const [searchTerm, setSearchTerm] = (0, import_react45.useState)("");
32986
- const [expandedItems, setExpandedItems] = (0, import_react45.useState)(/* @__PURE__ */ new Set());
32987
- const [expandedConversations, setExpandedConversations] = (0, import_react45.useState)(/* @__PURE__ */ new Set());
32988
- const [confirmClearOpen, setConfirmClearOpen] = (0, import_react45.useState)(false);
32989
- const [infoDialogOpen, setInfoDialogOpen] = (0, import_react45.useState)(false);
32990
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react45.useState)(false);
32991
- const [contextMode, setContextMode] = (0, import_react45.useState)("local");
32992
- const [expandedSections, setExpandedSections] = (0, import_react45.useState)(/* @__PURE__ */ new Set(["history", "voice"]));
32993
- const [audioSub, setAudioSub] = (0, import_react45.useState)(new import_rxjs22.Subscription());
32994
- const [isContextSwitching, setIsContextSwitching] = (0, import_react45.useState)(false);
32995
- const [isDrawerLoading, setIsDrawerLoading] = (0, import_react45.useState)(false);
32996
- (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)(() => {
32997
33189
  if (drawerOpen && !_hasHydrated) {
32998
33190
  hydrate();
32999
33191
  }
33000
33192
  }, [drawerOpen, _hasHydrated, hydrate]);
33001
- (0, import_react45.useEffect)(() => {
33193
+ (0, import_react46.useEffect)(() => {
33002
33194
  if (!drawerOpen) {
33003
33195
  setIsDrawerLoading(false);
33004
33196
  const cleanupTimer = setTimeout(() => {
@@ -33009,7 +33201,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33009
33201
  return () => clearTimeout(cleanupTimer);
33010
33202
  }
33011
33203
  }, [drawerOpen]);
33012
- (0, import_react45.useEffect)(() => {
33204
+ (0, import_react46.useEffect)(() => {
33013
33205
  return () => {
33014
33206
  audioSub.unsubscribe();
33015
33207
  };
@@ -33056,7 +33248,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33056
33248
  const currentConversation = conversations.find((c) => c.id === currentId);
33057
33249
  const isInitialLoading = !_hasHydrated && contextMode === "main";
33058
33250
  const isContentLoading = isContextSwitching || isInitialLoading;
33059
- (0, import_react45.useEffect)(() => {
33251
+ (0, import_react46.useEffect)(() => {
33060
33252
  if (drawerOpen) {
33061
33253
  const debugTimer = setTimeout(() => {
33062
33254
  debugLogger.debug("Chat drawer loading states", {
@@ -33071,7 +33263,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33071
33263
  return () => clearTimeout(debugTimer);
33072
33264
  }
33073
33265
  }, [drawerOpen, _hasHydrated, isDrawerLoading, isContentLoading, contextMode]);
33074
- (0, import_react45.useEffect)(() => {
33266
+ (0, import_react46.useEffect)(() => {
33075
33267
  debugLogger.debug("Chat drawer voice availability check", {
33076
33268
  isServiceAvailable,
33077
33269
  ttsEnabled: preferences.ttsEnabled,
@@ -33082,14 +33274,14 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33082
33274
  storeState: "modal-chat-drawer-voice"
33083
33275
  });
33084
33276
  }, [isServiceAvailable, preferences.ttsEnabled, packageSettings?.gatewayApiUrl, isVoiceAvailable, availableVoices.length, selectedVoice]);
33085
- const activeHistory = (0, import_react45.useMemo)(() => {
33277
+ const activeHistory = (0, import_react46.useMemo)(() => {
33086
33278
  if (contextMode === "local") {
33087
33279
  return history;
33088
33280
  }
33089
33281
  return currentConversation?.history ?? [];
33090
33282
  }, [contextMode, history, currentConversation]);
33091
33283
  const effectiveContextMode = contextMode === "main" && (!currentConversation || currentConversation.history.length === 0) ? "local" : contextMode;
33092
- (0, import_react45.useEffect)(() => {
33284
+ (0, import_react46.useEffect)(() => {
33093
33285
  debugLogger.debug("Chat drawer context state", {
33094
33286
  contextMode,
33095
33287
  effectiveContextMode,
@@ -33102,13 +33294,13 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33102
33294
  storeState: "modal-chat-drawer"
33103
33295
  });
33104
33296
  }, [contextMode, effectiveContextMode, conversations.length, currentId, currentConversation, history.length, _hasHydrated]);
33105
- const filteredHistory = (0, import_react45.useMemo)(() => {
33297
+ const filteredHistory = (0, import_react46.useMemo)(() => {
33106
33298
  const filtered = activeHistory.filter(
33107
33299
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
33108
33300
  );
33109
33301
  return filtered.slice(-20);
33110
33302
  }, [activeHistory, searchTerm]);
33111
- const filteredConversations = (0, import_react45.useMemo)(() => {
33303
+ const filteredConversations = (0, import_react46.useMemo)(() => {
33112
33304
  const filtered = conversations.filter(
33113
33305
  (conversation) => conversation.name.toLowerCase().includes(searchTerm.toLowerCase()) || conversation.history.some(
33114
33306
  (entry) => entry.question.toLowerCase().includes(searchTerm.toLowerCase()) || entry.answer.toLowerCase().includes(searchTerm.toLowerCase())
@@ -33994,7 +34186,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
33994
34186
  }
33995
34187
  ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material37.List, { sx: { p: 0 }, children: [...filteredHistory].reverse().map((entry, index) => {
33996
34188
  const isExpanded = expandedItems.has(index);
33997
- 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)(
33998
34190
  import_material37.ListItem,
33999
34191
  {
34000
34192
  sx: {
@@ -34471,7 +34663,7 @@ var GenericLoader = ({
34471
34663
  var generic_loader_default = GenericLoader;
34472
34664
 
34473
34665
  // src/components/feedback/FeedbackButton.tsx
34474
- var import_react46 = require("react");
34666
+ var import_react47 = require("react");
34475
34667
  var import_material39 = require("@mui/material");
34476
34668
  var import_lucide_react15 = require("lucide-react");
34477
34669
 
@@ -34492,7 +34684,7 @@ var FeedbackButton = ({
34492
34684
  absolute = false
34493
34685
  }) => {
34494
34686
  const theme = (0, import_material39.useTheme)();
34495
- const [open, setOpen] = (0, import_react46.useState)(false);
34687
+ const [open, setOpen] = (0, import_react47.useState)(false);
34496
34688
  const handleOpen = () => setOpen(true);
34497
34689
  const handleClose = () => setOpen(false);
34498
34690
  if (inline) {
@@ -34606,7 +34798,7 @@ var FeedbackButton = ({
34606
34798
  };
34607
34799
 
34608
34800
  // src/hooks/useAiChat.ts
34609
- var import_react47 = require("react");
34801
+ var import_react48 = require("react");
34610
34802
  var import_material40 = require("@mui/material");
34611
34803
  init_aiQueryStore();
34612
34804
  init_aiProviderStore();
@@ -34618,10 +34810,10 @@ var useAIChat = () => {
34618
34810
  const provider = useAIProviderStore((state) => state.provider);
34619
34811
  const SYSTEM_PROMPT = useModelStore((state) => state.systemPrompt);
34620
34812
  const OLLAMA_MODEL = usePackageSettingsStore((state) => state.settings?.defaultModel || "");
34621
- const [fullScreen, setFullScreen] = (0, import_react47.useState)(isMobile);
34622
- const [drawerOpen, setDrawerOpen] = (0, import_react47.useState)(false);
34623
- const [showSettings, setShowSettings] = (0, import_react47.useState)(false);
34624
- 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);
34625
34817
  const {
34626
34818
  apiKey,
34627
34819
  inputValue,
@@ -34709,7 +34901,7 @@ var useAIChat = () => {
34709
34901
  }
34710
34902
  sendWithAIProvider();
34711
34903
  };
34712
- (0, import_react47.useEffect)(() => {
34904
+ (0, import_react48.useEffect)(() => {
34713
34905
  setFullScreen(isMobile);
34714
34906
  }, [isMobile]);
34715
34907
  return {
@@ -34725,12 +34917,12 @@ var useAIChat = () => {
34725
34917
  var useAiChat_default = useAIChat;
34726
34918
 
34727
34919
  // src/hooks/useDraggable.ts
34728
- var import_react48 = require("react");
34920
+ var import_react49 = require("react");
34729
34921
  var useDraggable = () => {
34730
- const modalRef = (0, import_react48.useRef)(null);
34731
- const [dragging, setDragging] = (0, import_react48.useState)(false);
34732
- const [offset, setOffset] = (0, import_react48.useState)({ x: 0, y: 0 });
34733
- 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 });
34734
34926
  const handleHeaderMouseDown = (e) => {
34735
34927
  const rect = modalRef.current?.getBoundingClientRect();
34736
34928
  if (rect) {
@@ -34738,7 +34930,7 @@ var useDraggable = () => {
34738
34930
  setDragging(true);
34739
34931
  }
34740
34932
  };
34741
- const handleHeaderMouseMove = (0, import_react48.useCallback)(
34933
+ const handleHeaderMouseMove = (0, import_react49.useCallback)(
34742
34934
  (e) => {
34743
34935
  if (dragging) {
34744
34936
  setPosition({ x: e.clientX - offset.x, y: e.clientY - offset.y });
@@ -34749,7 +34941,7 @@ var useDraggable = () => {
34749
34941
  const handleHeaderMouseUp = () => {
34750
34942
  setDragging(false);
34751
34943
  };
34752
- (0, import_react48.useEffect)(() => {
34944
+ (0, import_react49.useEffect)(() => {
34753
34945
  if (dragging) {
34754
34946
  document.addEventListener("mousemove", handleHeaderMouseMove);
34755
34947
  document.addEventListener("mouseup", handleHeaderMouseUp);
@@ -34799,9 +34991,9 @@ var modelAvatars3 = {
34799
34991
  "Bandit-Exec": `${CDN_BASE2}/avatars/exec-avatar.png`
34800
34992
  };
34801
34993
  var useOptionalNavigate = () => {
34802
- const hasLoggedRef = (0, import_react49.useRef)(false);
34994
+ const hasLoggedRef = (0, import_react50.useRef)(false);
34803
34995
  try {
34804
- return (0, import_react_router_dom5.useNavigate)();
34996
+ return (0, import_react_router_dom6.useNavigate)();
34805
34997
  } catch (error) {
34806
34998
  if (!hasLoggedRef.current) {
34807
34999
  debugLogger.debug("Navigation not available in ChatModal context", { error });
@@ -34848,17 +35040,17 @@ var ChatModal = ({
34848
35040
  handleSend
34849
35041
  } = useAiChat_default();
34850
35042
  const { modalRef, position, setPosition, handleDrag, handleHeaderMouseDown } = useDraggable_default();
34851
- const [pastedImages, setPastedImages] = (0, import_react49.useState)([]);
34852
- const [responseStarted, setResponseStarted] = (0, import_react49.useState)(false);
34853
- const [modalLogo, setModalLogo] = (0, import_react49.useState)("https://cdn.burtson.ai/logos/bandit-ai-logo.png");
34854
- const [modelAnchorEl, setModelAnchorEl] = (0, import_react49.useState)(null);
34855
- const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react49.useState)(null);
34856
- const [audioSub, setAudioSub] = (0, import_react49.useState)(new import_rxjs23.Subscription());
34857
- const [selectedTheme, setSelectedTheme] = (0, import_react49.useState)(null);
34858
- const [themeLoading, setThemeLoading] = (0, import_react49.useState)(true);
34859
- const [autoFullscreenTriggered, setAutoFullscreenTriggered] = (0, import_react49.useState)(false);
34860
- const [userHasDragged, setUserHasDragged] = (0, import_react49.useState)(false);
34861
- 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);
34862
35054
  const handleExitFullscreen = () => {
34863
35055
  setPosition({
34864
35056
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34904,7 +35096,7 @@ var ChatModal = ({
34904
35096
  const toTitleCase2 = (str) => {
34905
35097
  return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
34906
35098
  };
34907
- (0, import_react49.useEffect)(() => {
35099
+ (0, import_react50.useEffect)(() => {
34908
35100
  if (!SYSTEM_PROMPT) {
34909
35101
  const defaultModel = availableModels.length > 0 ? availableModels[0] : null;
34910
35102
  if (defaultModel) {
@@ -34912,12 +35104,12 @@ var ChatModal = ({
34912
35104
  }
34913
35105
  }
34914
35106
  }, [SYSTEM_PROMPT, availableModels, setSelectedModel]);
34915
- (0, import_react49.useEffect)(() => {
35107
+ (0, import_react50.useEffect)(() => {
34916
35108
  return () => {
34917
35109
  audioSub.unsubscribe();
34918
35110
  };
34919
35111
  }, [audioSub]);
34920
- (0, import_react49.useEffect)(() => {
35112
+ (0, import_react50.useEffect)(() => {
34921
35113
  if (open) {
34922
35114
  setPosition({
34923
35115
  x: Math.max(0, window.innerWidth / 2 - 300),
@@ -34929,7 +35121,7 @@ var ChatModal = ({
34929
35121
  getOptimalLogo().then(setModalLogo);
34930
35122
  }
34931
35123
  }, [open, setPosition]);
34932
- (0, import_react49.useEffect)(() => {
35124
+ (0, import_react50.useEffect)(() => {
34933
35125
  if (!open) return;
34934
35126
  const fetchTheme = async () => {
34935
35127
  try {
@@ -34963,7 +35155,7 @@ var ChatModal = ({
34963
35155
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
34964
35156
  };
34965
35157
  }, [open]);
34966
- (0, import_react49.useLayoutEffect)(() => {
35158
+ (0, import_react50.useLayoutEffect)(() => {
34967
35159
  const timeSinceManualToggle = Date.now() - manualFullscreenToggleTime;
34968
35160
  const manualToggleRecentlyUsed = timeSinceManualToggle < 5e3;
34969
35161
  if (modalRef.current && response && !fullScreen && !autoFullscreenTriggered && !manualToggleRecentlyUsed) {
@@ -34988,7 +35180,7 @@ var ChatModal = ({
34988
35180
  setFullScreen,
34989
35181
  setAutoFullscreenTriggered
34990
35182
  ]);
34991
- (0, import_react49.useEffect)(() => {
35183
+ (0, import_react50.useEffect)(() => {
34992
35184
  const handlePaste = (e) => {
34993
35185
  const items = e.clipboardData?.items;
34994
35186
  if (items) {
@@ -35013,7 +35205,7 @@ var ChatModal = ({
35013
35205
  document.removeEventListener("paste", handlePaste);
35014
35206
  };
35015
35207
  }, []);
35016
- (0, import_react49.useEffect)(() => {
35208
+ (0, import_react50.useEffect)(() => {
35017
35209
  if (response && !responseStarted) {
35018
35210
  setResponseStarted(true);
35019
35211
  }
@@ -35433,13 +35625,13 @@ var ChatModal = ({
35433
35625
  var chat_modal_default = ChatModal;
35434
35626
 
35435
35627
  // src/management/components/PersonalitiesTab.tsx
35436
- var import_react51 = require("react");
35628
+ var import_react52 = require("react");
35437
35629
  var import_material43 = require("@mui/material");
35438
35630
  var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"));
35439
35631
  var import_styles34 = require("@mui/material/styles");
35440
35632
 
35441
35633
  // src/components/AvatarCropper.tsx
35442
- var import_react50 = require("react");
35634
+ var import_react51 = require("react");
35443
35635
  var import_material42 = require("@mui/material");
35444
35636
  init_lucide_icons();
35445
35637
  var import_jsx_runtime42 = require("react/jsx-runtime");
@@ -35449,22 +35641,22 @@ var AvatarCropper = ({
35449
35641
  onCrop,
35450
35642
  imageFile
35451
35643
  }) => {
35452
- const canvasRef = (0, import_react50.useRef)(null);
35453
- const imageRef = (0, import_react50.useRef)(null);
35454
- const [imageSrc, setImageSrc] = (0, import_react50.useState)("");
35455
- 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)({
35456
35648
  x: 0,
35457
35649
  y: 0,
35458
35650
  scale: 1,
35459
35651
  rotation: 0
35460
35652
  });
35461
- const [isDragging, setIsDragging] = (0, import_react50.useState)(false);
35462
- const [dragStart, setDragStart] = (0, import_react50.useState)({ x: 0, y: 0 });
35463
- const [imageLoaded, setImageLoaded] = (0, import_react50.useState)(false);
35464
- 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 });
35465
35657
  const CROP_SIZE = 400;
35466
35658
  const OUTPUT_SIZE = 512;
35467
- (0, import_react50.useEffect)(() => {
35659
+ (0, import_react51.useEffect)(() => {
35468
35660
  if (imageFile && open) {
35469
35661
  const reader = new FileReader();
35470
35662
  reader.onload = (e) => {
@@ -35476,7 +35668,7 @@ var AvatarCropper = ({
35476
35668
  reader.readAsDataURL(imageFile);
35477
35669
  }
35478
35670
  }, [imageFile, open]);
35479
- const handleImageLoad = (0, import_react50.useCallback)(() => {
35671
+ const handleImageLoad = (0, import_react51.useCallback)(() => {
35480
35672
  if (imageRef.current) {
35481
35673
  const { naturalWidth, naturalHeight } = imageRef.current;
35482
35674
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -35493,7 +35685,7 @@ var AvatarCropper = ({
35493
35685
  setImageLoaded(true);
35494
35686
  }
35495
35687
  }, []);
35496
- const drawCropPreview = (0, import_react50.useCallback)(() => {
35688
+ const drawCropPreview = (0, import_react51.useCallback)(() => {
35497
35689
  const canvas = canvasRef.current;
35498
35690
  const image = imageRef.current;
35499
35691
  if (!canvas || !image || !imageLoaded) return;
@@ -35516,14 +35708,14 @@ var AvatarCropper = ({
35516
35708
  ctx.fill();
35517
35709
  ctx.restore();
35518
35710
  }, [cropSettings, imageLoaded]);
35519
- (0, import_react50.useEffect)(() => {
35711
+ (0, import_react51.useEffect)(() => {
35520
35712
  drawCropPreview();
35521
35713
  }, [drawCropPreview]);
35522
- const handleMouseDown = (0, import_react50.useCallback)((e) => {
35714
+ const handleMouseDown = (0, import_react51.useCallback)((e) => {
35523
35715
  setIsDragging(true);
35524
35716
  setDragStart({ x: e.clientX, y: e.clientY });
35525
35717
  }, []);
35526
- const handleMouseMove = (0, import_react50.useCallback)((e) => {
35718
+ const handleMouseMove = (0, import_react51.useCallback)((e) => {
35527
35719
  if (!isDragging) return;
35528
35720
  const deltaX = e.clientX - dragStart.x;
35529
35721
  const deltaY = e.clientY - dragStart.y;
@@ -35534,16 +35726,16 @@ var AvatarCropper = ({
35534
35726
  }));
35535
35727
  setDragStart({ x: e.clientX, y: e.clientY });
35536
35728
  }, [isDragging, dragStart]);
35537
- const handleMouseUp = (0, import_react50.useCallback)(() => {
35729
+ const handleMouseUp = (0, import_react51.useCallback)(() => {
35538
35730
  setIsDragging(false);
35539
35731
  }, []);
35540
- const handleClose = (0, import_react50.useCallback)(() => {
35732
+ const handleClose = (0, import_react51.useCallback)(() => {
35541
35733
  setImageSrc("");
35542
35734
  setImageLoaded(false);
35543
35735
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
35544
35736
  onClose();
35545
35737
  }, [onClose]);
35546
- const handleCrop = (0, import_react50.useCallback)(() => {
35738
+ const handleCrop = (0, import_react51.useCallback)(() => {
35547
35739
  const canvas = document.createElement("canvas");
35548
35740
  const ctx = canvas.getContext("2d");
35549
35741
  const image = imageRef.current;
@@ -35570,7 +35762,7 @@ var AvatarCropper = ({
35570
35762
  onCrop(croppedDataUrl);
35571
35763
  handleClose();
35572
35764
  }, [cropSettings, onCrop, handleClose]);
35573
- const handleScaleChange = (0, import_react50.useCallback)((value) => {
35765
+ const handleScaleChange = (0, import_react51.useCallback)((value) => {
35574
35766
  const minScale2 = Math.max(
35575
35767
  CROP_SIZE / imageNaturalSize.width,
35576
35768
  CROP_SIZE / imageNaturalSize.height
@@ -35580,7 +35772,7 @@ var AvatarCropper = ({
35580
35772
  scale: Math.max(value, minScale2)
35581
35773
  }));
35582
35774
  }, [imageNaturalSize]);
35583
- const handleRotation = (0, import_react50.useCallback)((direction) => {
35775
+ const handleRotation = (0, import_react51.useCallback)((direction) => {
35584
35776
  setCropSettings((prev) => ({
35585
35777
  ...prev,
35586
35778
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -35816,15 +36008,15 @@ var PersonalitiesTab = ({
35816
36008
  }) => {
35817
36009
  const theme = (0, import_styles34.useTheme)();
35818
36010
  const isMobile = (0, import_useMediaQuery.default)(theme.breakpoints.down("sm"));
35819
- const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react51.useState)(0);
36011
+ const [personalityTabIndex, setPersonalityTabIndex] = (0, import_react52.useState)(0);
35820
36012
  const tabWrapperStyles = isMobile ? { flexDirection: "column", gap: 0.35, fontSize: "0.78rem" } : { flexDirection: "row", gap: 0.75, fontSize: "0.95rem" };
35821
- const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react51.useState)(false);
35822
- const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react51.useState)(false);
35823
- const [personalityToDelete, setPersonalityToDelete] = (0, import_react51.useState)(null);
35824
- const [clickedChips, setClickedChips] = (0, import_react51.useState)(/* @__PURE__ */ new Set());
35825
- const [showTemplateHelp, setShowTemplateHelp] = (0, import_react51.useState)(false);
35826
- const [cropperOpen, setCropperOpen] = (0, import_react51.useState)(false);
35827
- 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);
35828
36020
  const promptTemplates = [
35829
36021
  {
35830
36022
  name: "Business Professional",
@@ -37321,7 +37513,7 @@ var PersonalitiesTab = ({
37321
37513
  var PersonalitiesTab_default = PersonalitiesTab;
37322
37514
 
37323
37515
  // src/management/components/PreferencesTab.tsx
37324
- var import_react53 = require("react");
37516
+ var import_react54 = require("react");
37325
37517
  init_memory_modal();
37326
37518
  var import_material44 = require("@mui/material");
37327
37519
  init_preferencesStore();
@@ -37332,7 +37524,7 @@ init_useFeatures();
37332
37524
  init_conversationSyncStore();
37333
37525
 
37334
37526
  // src/hooks/useGatewayQueries.ts
37335
- var import_react52 = require("react");
37527
+ var import_react53 = require("react");
37336
37528
  var import_rxjs24 = require("rxjs");
37337
37529
  var import_react_query2 = require("@tanstack/react-query");
37338
37530
  init_packageSettingsStore();
@@ -37342,7 +37534,7 @@ var useGatewayClient = () => {
37342
37534
  const settings = usePackageSettingsStore((state) => state.settings);
37343
37535
  const gatewayUrl = settings?.gatewayApiUrl;
37344
37536
  const feedbackEmail = settings?.feedbackEmail;
37345
- const service = (0, import_react52.useMemo)(() => {
37537
+ const service = (0, import_react53.useMemo)(() => {
37346
37538
  if (!gatewayUrl) {
37347
37539
  return null;
37348
37540
  }
@@ -37401,6 +37593,7 @@ var useGatewayMemory = (options) => {
37401
37593
  };
37402
37594
 
37403
37595
  // src/management/components/PreferencesTab.tsx
37596
+ init_installedApp();
37404
37597
  init_lucide_icons();
37405
37598
  var import_jsx_runtime44 = require("react/jsx-runtime");
37406
37599
  var PreferencesTab = ({
@@ -37412,16 +37605,16 @@ var PreferencesTab = ({
37412
37605
  }) => {
37413
37606
  const theme = (0, import_material44.useTheme)();
37414
37607
  const isMobile = (0, import_material44.useMediaQuery)(theme.breakpoints.down("sm"));
37415
- const [homeUrlStatus, setHomeUrlStatus] = (0, import_react53.useState)("idle");
37416
- const [homeUrlError, setHomeUrlError] = (0, import_react53.useState)("");
37417
- const [localHomeUrl, setLocalHomeUrl] = (0, import_react53.useState)(preferences.homeUrl || "");
37418
- const [importStatus, setImportStatus] = (0, import_react53.useState)("idle");
37419
- const [syncToggleLoading, setSyncToggleLoading] = (0, import_react53.useState)(false);
37420
- const [manualSyncLoading, setManualSyncLoading] = (0, import_react53.useState)(false);
37421
- const [advancedVectorToggleLoading, setAdvancedVectorToggleLoading] = (0, import_react53.useState)(false);
37422
- const [memoryModalOpen, setMemoryModalOpen] = (0, import_react53.useState)(false);
37423
- const timeoutRef = (0, import_react53.useRef)(null);
37424
- 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);
37425
37618
  const { exportPreferences, importPreferences, resetToDefaults } = usePreferencesStore();
37426
37619
  const {
37427
37620
  isServiceAvailable: isTTSSTTAvailable,
@@ -37533,7 +37726,7 @@ var PreferencesTab = ({
37533
37726
  if (!gatewayHealth) return "warning";
37534
37727
  return gatewayHealth.status?.toLowerCase() === "healthy" ? "success" : "error";
37535
37728
  })();
37536
- const handleGatewayStatusRefresh = (0, import_react53.useCallback)(() => {
37729
+ const handleGatewayStatusRefresh = (0, import_react54.useCallback)(() => {
37537
37730
  if (!gatewayConfigured) {
37538
37731
  return;
37539
37732
  }
@@ -37595,7 +37788,7 @@ var PreferencesTab = ({
37595
37788
  }
37596
37789
  return packageSettings?.homeUrl || "";
37597
37790
  };
37598
- (0, import_react53.useEffect)(() => {
37791
+ (0, import_react54.useEffect)(() => {
37599
37792
  setLocalHomeUrl(preferences.homeUrl || "");
37600
37793
  }, [preferences.homeUrl]);
37601
37794
  const validateAndSaveHomeUrl = async (url) => {
@@ -37642,7 +37835,7 @@ var PreferencesTab = ({
37642
37835
  validateAndSaveHomeUrl(value);
37643
37836
  }, 1500);
37644
37837
  };
37645
- (0, import_react53.useEffect)(() => {
37838
+ (0, import_react54.useEffect)(() => {
37646
37839
  return () => {
37647
37840
  if (timeoutRef.current) {
37648
37841
  clearTimeout(timeoutRef.current);
@@ -38250,16 +38443,15 @@ var PreferencesTab = ({
38250
38443
  ] }) });
38251
38444
  };
38252
38445
  var ViewportDiagnostics = () => {
38253
- const [metrics, setMetrics] = (0, import_react53.useState)({});
38254
- (0, import_react53.useEffect)(() => {
38446
+ const [metrics, setMetrics] = (0, import_react54.useState)({});
38447
+ (0, import_react54.useEffect)(() => {
38255
38448
  const read = () => {
38256
38449
  const probe = document.createElement("div");
38257
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;";
38258
38451
  document.body.appendChild(probe);
38259
38452
  const cs = getComputedStyle(probe);
38260
- const standalone = window.matchMedia?.("(display-mode: standalone)").matches || window.navigator.standalone === true;
38261
38453
  setMetrics({
38262
- mode: standalone ? "standalone" : "browser",
38454
+ mode: isNativeShell() ? "native" : isStandalonePwa2() ? "standalone" : "browser",
38263
38455
  "screen.height": `${window.screen.height}`,
38264
38456
  innerHeight: `${window.innerHeight}`,
38265
38457
  "docElement.clientHeight": `${document.documentElement.clientHeight}`,
@@ -38286,11 +38478,11 @@ var ViewportDiagnostics = () => {
38286
38478
  var PreferencesTab_default = PreferencesTab;
38287
38479
 
38288
38480
  // src/management/components/BrandingTab.tsx
38289
- var import_react55 = require("react");
38481
+ var import_react56 = require("react");
38290
38482
  var import_material46 = require("@mui/material");
38291
38483
 
38292
38484
  // src/components/LogoCropper.tsx
38293
- var import_react54 = require("react");
38485
+ var import_react55 = require("react");
38294
38486
  var import_material45 = require("@mui/material");
38295
38487
  init_lucide_icons();
38296
38488
  var import_jsx_runtime45 = require("react/jsx-runtime");
@@ -38305,25 +38497,25 @@ var LogoCropper = ({
38305
38497
  onCrop,
38306
38498
  imageFile
38307
38499
  }) => {
38308
- const canvasRef = (0, import_react54.useRef)(null);
38309
- const previewCanvasRef = (0, import_react54.useRef)(null);
38310
- const imageRef = (0, import_react54.useRef)(null);
38311
- const [imageSrc, setImageSrc] = (0, import_react54.useState)("");
38312
- 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)({
38313
38505
  x: 0,
38314
38506
  y: 0,
38315
38507
  scale: 1,
38316
38508
  rotation: 0
38317
38509
  });
38318
- const [isDragging, setIsDragging] = (0, import_react54.useState)(false);
38319
- const [dragStart, setDragStart] = (0, import_react54.useState)({ x: 0, y: 0 });
38320
- const [imageLoaded, setImageLoaded] = (0, import_react54.useState)(false);
38321
- const [imageNaturalSize, setImageNaturalSize] = (0, import_react54.useState)({ width: 0, height: 0 });
38322
- const [aspectRatio, setAspectRatio] = (0, import_react54.useState)("square");
38323
- 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 });
38324
38516
  const CANVAS_SIZE = 500;
38325
- const [outputSize, setOutputSize] = (0, import_react54.useState)("large");
38326
- const getCropDimensions = (0, import_react54.useCallback)(() => {
38517
+ const [outputSize, setOutputSize] = (0, import_react55.useState)("large");
38518
+ const getCropDimensions = (0, import_react55.useCallback)(() => {
38327
38519
  const maxSize = 380;
38328
38520
  switch (aspectRatio) {
38329
38521
  case "square":
@@ -38338,7 +38530,7 @@ var LogoCropper = ({
38338
38530
  return cropArea;
38339
38531
  }
38340
38532
  }, [aspectRatio, cropArea]);
38341
- (0, import_react54.useEffect)(() => {
38533
+ (0, import_react55.useEffect)(() => {
38342
38534
  if (imageFile && open) {
38343
38535
  const reader = new FileReader();
38344
38536
  reader.onload = (e) => {
@@ -38350,7 +38542,7 @@ var LogoCropper = ({
38350
38542
  reader.readAsDataURL(imageFile);
38351
38543
  }
38352
38544
  }, [imageFile, open]);
38353
- const handleImageLoad = (0, import_react54.useCallback)(() => {
38545
+ const handleImageLoad = (0, import_react55.useCallback)(() => {
38354
38546
  if (imageRef.current) {
38355
38547
  const { naturalWidth, naturalHeight } = imageRef.current;
38356
38548
  setImageNaturalSize({ width: naturalWidth, height: naturalHeight });
@@ -38368,7 +38560,7 @@ var LogoCropper = ({
38368
38560
  setImageLoaded(true);
38369
38561
  }
38370
38562
  }, [getCropDimensions]);
38371
- (0, import_react54.useEffect)(() => {
38563
+ (0, import_react55.useEffect)(() => {
38372
38564
  if (imageLoaded) {
38373
38565
  const cropDims = getCropDimensions();
38374
38566
  setCropArea(cropDims);
@@ -38382,7 +38574,7 @@ var LogoCropper = ({
38382
38574
  }));
38383
38575
  }
38384
38576
  }, [aspectRatio, imageLoaded, imageNaturalSize, getCropDimensions]);
38385
- const updatePreview = (0, import_react54.useCallback)((cropX, cropY, cropDims) => {
38577
+ const updatePreview = (0, import_react55.useCallback)((cropX, cropY, cropDims) => {
38386
38578
  const previewCanvas = previewCanvasRef.current;
38387
38579
  const mainCanvas = canvasRef.current;
38388
38580
  if (!previewCanvas || !mainCanvas) return;
@@ -38411,7 +38603,7 @@ var LogoCropper = ({
38411
38603
  previewCtx.lineWidth = 2;
38412
38604
  previewCtx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight);
38413
38605
  }, []);
38414
- const drawCropPreview = (0, import_react54.useCallback)(() => {
38606
+ const drawCropPreview = (0, import_react55.useCallback)(() => {
38415
38607
  const canvas = canvasRef.current;
38416
38608
  const image = imageRef.current;
38417
38609
  if (!canvas || !image || !imageLoaded) return;
@@ -38457,14 +38649,14 @@ var LogoCropper = ({
38457
38649
  ctx.fillRect(cropX + cropDims.width - 1, cropY + cropDims.height - cornerSize + 1, 3, cornerSize);
38458
38650
  updatePreview(cropX, cropY, cropDims);
38459
38651
  }, [cropSettings, imageLoaded, getCropDimensions, updatePreview]);
38460
- (0, import_react54.useEffect)(() => {
38652
+ (0, import_react55.useEffect)(() => {
38461
38653
  drawCropPreview();
38462
38654
  }, [drawCropPreview]);
38463
- const handleMouseDown = (0, import_react54.useCallback)((e) => {
38655
+ const handleMouseDown = (0, import_react55.useCallback)((e) => {
38464
38656
  setIsDragging(true);
38465
38657
  setDragStart({ x: e.clientX, y: e.clientY });
38466
38658
  }, []);
38467
- const handleMouseMove = (0, import_react54.useCallback)((e) => {
38659
+ const handleMouseMove = (0, import_react55.useCallback)((e) => {
38468
38660
  if (!isDragging) return;
38469
38661
  const deltaX = e.clientX - dragStart.x;
38470
38662
  const deltaY = e.clientY - dragStart.y;
@@ -38475,17 +38667,17 @@ var LogoCropper = ({
38475
38667
  }));
38476
38668
  setDragStart({ x: e.clientX, y: e.clientY });
38477
38669
  }, [isDragging, dragStart]);
38478
- const handleMouseUp = (0, import_react54.useCallback)(() => {
38670
+ const handleMouseUp = (0, import_react55.useCallback)(() => {
38479
38671
  setIsDragging(false);
38480
38672
  }, []);
38481
- const handleClose = (0, import_react54.useCallback)(() => {
38673
+ const handleClose = (0, import_react55.useCallback)(() => {
38482
38674
  setImageSrc("");
38483
38675
  setImageLoaded(false);
38484
38676
  setCropSettings({ x: 0, y: 0, scale: 1, rotation: 0 });
38485
38677
  setAspectRatio("square");
38486
38678
  onClose();
38487
38679
  }, [onClose]);
38488
- const handleCrop = (0, import_react54.useCallback)(() => {
38680
+ const handleCrop = (0, import_react55.useCallback)(() => {
38489
38681
  const image = imageRef.current;
38490
38682
  if (!image) return;
38491
38683
  const cropDims = getCropDimensions();
@@ -38538,7 +38730,7 @@ var LogoCropper = ({
38538
38730
  setAspectRatio("square");
38539
38731
  onClose();
38540
38732
  }, [cropSettings, onCrop, getCropDimensions, outputSize, onClose]);
38541
- const handleScaleChange = (0, import_react54.useCallback)((value) => {
38733
+ const handleScaleChange = (0, import_react55.useCallback)((value) => {
38542
38734
  const cropDims = getCropDimensions();
38543
38735
  const minScale2 = Math.max(
38544
38736
  cropDims.width / imageNaturalSize.width,
@@ -38549,7 +38741,7 @@ var LogoCropper = ({
38549
38741
  scale: Math.max(value, minScale2)
38550
38742
  }));
38551
38743
  }, [imageNaturalSize, getCropDimensions]);
38552
- const handleRotation = (0, import_react54.useCallback)((direction) => {
38744
+ const handleRotation = (0, import_react55.useCallback)((direction) => {
38553
38745
  setCropSettings((prev) => ({
38554
38746
  ...prev,
38555
38747
  rotation: prev.rotation + (direction === "left" ? -90 : 90)
@@ -38834,15 +39026,15 @@ var BrandingTab = ({
38834
39026
  }) => {
38835
39027
  const muiTheme = (0, import_material46.useTheme)();
38836
39028
  const isMobile = (0, import_material46.useMediaQuery)(muiTheme.breakpoints.down("sm"));
38837
- const [dragOver, setDragOver] = (0, import_react55.useState)(false);
38838
- const [saveStatus, setSaveStatus] = (0, import_react55.useState)("idle");
38839
- const [snackbarMessage, setSnackbarMessage] = (0, import_react55.useState)("");
38840
- const [showSnackbar, setShowSnackbar] = (0, import_react55.useState)(false);
38841
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react55.useState)("success");
38842
- const [cropperOpen, setCropperOpen] = (0, import_react55.useState)(false);
38843
- const [selectedImageFile, setSelectedImageFile] = (0, import_react55.useState)(null);
38844
- const fileInputRef = (0, import_react55.useRef)(null);
38845
- 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);
38846
39038
  const getDefaultLogo = () => {
38847
39039
  return muiTheme.palette.mode === "light" ? lightLogo2 : banditAiLogo;
38848
39040
  };
@@ -39469,11 +39661,11 @@ var BrandingTab = ({
39469
39661
  var BrandingTab_default = BrandingTab;
39470
39662
 
39471
39663
  // src/management/components/KnowledgeHubTab.tsx
39472
- var import_react60 = require("react");
39664
+ var import_react61 = require("react");
39473
39665
  var import_material50 = require("@mui/material");
39474
39666
 
39475
39667
  // src/management/components/KnowledgeTab.tsx
39476
- var import_react58 = require("react");
39668
+ var import_react59 = require("react");
39477
39669
  var import_uuid6 = require("uuid");
39478
39670
  var import_material48 = require("@mui/material");
39479
39671
  init_knowledge_file_modal();
@@ -39483,7 +39675,7 @@ init_authenticationStore();
39483
39675
  init_useFeatures();
39484
39676
 
39485
39677
  // src/components/shared/ProcessingOverlay.tsx
39486
- var import_react56 = require("react");
39678
+ var import_react57 = require("react");
39487
39679
  var import_material47 = require("@mui/material");
39488
39680
  var import_lucide_react16 = require("lucide-react");
39489
39681
  var import_jsx_runtime47 = require("react/jsx-runtime");
@@ -39556,17 +39748,17 @@ var ProcessingOverlay = ({
39556
39748
  customMessages
39557
39749
  }) => {
39558
39750
  const theme = (0, import_material47.useTheme)();
39559
- const [messageIndex, setMessageIndex] = (0, import_react56.useState)(0);
39560
- const [sparkles, setSparkles] = (0, import_react56.useState)([]);
39751
+ const [messageIndex, setMessageIndex] = (0, import_react57.useState)(0);
39752
+ const [sparkles, setSparkles] = (0, import_react57.useState)([]);
39561
39753
  const messages = customMessages || cleverMessages;
39562
- (0, import_react56.useEffect)(() => {
39754
+ (0, import_react57.useEffect)(() => {
39563
39755
  if (!open) return;
39564
39756
  const interval = setInterval(() => {
39565
39757
  setMessageIndex((prev) => (prev + 1) % messages.length);
39566
39758
  }, 3e3);
39567
39759
  return () => clearInterval(interval);
39568
39760
  }, [open, messages.length]);
39569
- (0, import_react56.useEffect)(() => {
39761
+ (0, import_react57.useEffect)(() => {
39570
39762
  if (!open) return;
39571
39763
  const generateSparkles = () => {
39572
39764
  const newSparkles = Array.from({ length: 5 }, (_, i) => ({
@@ -39778,16 +39970,16 @@ var ProcessingOverlay = ({
39778
39970
  var ProcessingOverlay_default = ProcessingOverlay;
39779
39971
 
39780
39972
  // src/hooks/useProcessingOverlay.ts
39781
- var import_react57 = require("react");
39973
+ var import_react58 = require("react");
39782
39974
  var useProcessingOverlay = () => {
39783
- const [processingState, setProcessingState] = (0, import_react57.useState)({
39975
+ const [processingState, setProcessingState] = (0, import_react58.useState)({
39784
39976
  isVisible: false,
39785
39977
  step: "upload",
39786
39978
  progress: 0,
39787
39979
  title: "Processing...",
39788
39980
  customMessages: void 0
39789
39981
  });
39790
- const showProcessing = (0, import_react57.useCallback)((title = "Processing...", messages) => {
39982
+ const showProcessing = (0, import_react58.useCallback)((title = "Processing...", messages) => {
39791
39983
  setProcessingState({
39792
39984
  isVisible: true,
39793
39985
  step: "upload",
@@ -39796,13 +39988,13 @@ var useProcessingOverlay = () => {
39796
39988
  customMessages: messages
39797
39989
  });
39798
39990
  }, []);
39799
- const hideProcessing = (0, import_react57.useCallback)(() => {
39991
+ const hideProcessing = (0, import_react58.useCallback)(() => {
39800
39992
  setProcessingState((prev) => ({
39801
39993
  ...prev,
39802
39994
  isVisible: false
39803
39995
  }));
39804
39996
  }, []);
39805
- const updateProgress = (0, import_react57.useCallback)((step, progress) => {
39997
+ const updateProgress = (0, import_react58.useCallback)((step, progress) => {
39806
39998
  setProcessingState((prev) => ({
39807
39999
  ...prev,
39808
40000
  step,
@@ -39954,28 +40146,28 @@ var KnowledgeTab = ({
39954
40146
  } = useVectorStore();
39955
40147
  const { showProcessing, hideProcessing, updateProgress, processingState } = useProcessingOverlay();
39956
40148
  const shouldUseVector = (features.isAdmin() || features.hasAdvancedSearch() || features.hasAdvancedMemories()) && isAdvancedVectorFeaturesEnabled && isVectorEnabled;
39957
- const [clearDocsDialogOpen, setClearDocsDialogOpen] = (0, import_react58.useState)(false);
39958
- const [selectedDoc, setSelectedDoc] = (0, import_react58.useState)(null);
39959
- const [vectorDocuments, setVectorDocuments] = (0, import_react58.useState)([]);
39960
- const [loadingVectorDocs, setLoadingVectorDocs] = (0, import_react58.useState)(false);
39961
- const [searchQuery, setSearchQuery] = (0, import_react58.useState)("");
39962
- const [selectedCategory, setSelectedCategory] = (0, import_react58.useState)("all");
39963
- const [contentSourceFilter, setContentSourceFilter] = (0, import_react58.useState)("all");
39964
- const [viewMode, setViewMode] = (0, import_react58.useState)("grid");
39965
- const [sortBy, setSortBy] = (0, import_react58.useState)("date");
39966
- const [sortOrder, setSortOrder] = (0, import_react58.useState)("desc");
39967
- const [selectedDocuments, setSelectedDocuments] = (0, import_react58.useState)([]);
39968
- const [showFilters, setShowFilters] = (0, import_react58.useState)(false);
39969
- const [uploadStatuses, setUploadStatuses] = (0, import_react58.useState)([]);
39970
- const [filterMenuAnchor, setFilterMenuAnchor] = (0, import_react58.useState)(null);
39971
- const [snackbarMessage, setSnackbarMessage] = (0, import_react58.useState)("");
39972
- const [showSnackbar, setShowSnackbar] = (0, import_react58.useState)(false);
39973
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react58.useState)("success");
39974
- 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());
39975
40167
  const hasTeam = !!(authStore.user?.teamSid || authStore.user?.teamId);
39976
- const [shareWithTeam, setShareWithTeam] = (0, import_react58.useState)(false);
39977
- const [dragActive, setDragActive] = (0, import_react58.useState)(false);
39978
- 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) => {
39979
40171
  return vectorDocs.map((doc) => {
39980
40172
  const primaryId = doc.id ?? doc.fileId ?? doc._id;
39981
40173
  const docId = typeof primaryId === "string" ? primaryId : primaryId ? JSON.stringify(primaryId) : (0, import_uuid6.v4)();
@@ -40003,7 +40195,7 @@ var KnowledgeTab = ({
40003
40195
  };
40004
40196
  });
40005
40197
  }, []);
40006
- const loadVectorDocuments = (0, import_react58.useCallback)(async () => {
40198
+ const loadVectorDocuments = (0, import_react59.useCallback)(async () => {
40007
40199
  if (!shouldUseVector) {
40008
40200
  return;
40009
40201
  }
@@ -40018,12 +40210,12 @@ var KnowledgeTab = ({
40018
40210
  setLoadingVectorDocs(false);
40019
40211
  }
40020
40212
  }, [shouldUseVector, getUserDocuments, mapVectorDocsToKnowledgeDocs]);
40021
- (0, import_react58.useEffect)(() => {
40213
+ (0, import_react59.useEffect)(() => {
40022
40214
  if (shouldUseVector) {
40023
40215
  loadVectorDocuments();
40024
40216
  }
40025
40217
  }, [shouldUseVector, loadVectorDocuments]);
40026
- const filteredAndSortedDocuments = (0, import_react58.useMemo)(() => {
40218
+ const filteredAndSortedDocuments = (0, import_react59.useMemo)(() => {
40027
40219
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40028
40220
  let filtered = sourceDocuments;
40029
40221
  if (searchQuery) {
@@ -40073,12 +40265,12 @@ var KnowledgeTab = ({
40073
40265
  });
40074
40266
  return filtered;
40075
40267
  }, [documents, vectorDocuments, shouldUseVector, searchQuery, selectedCategory, contentSourceFilter, sortBy, sortOrder]);
40076
- const categories = (0, import_react58.useMemo)(() => {
40268
+ const categories = (0, import_react59.useMemo)(() => {
40077
40269
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40078
40270
  const cats = new Set(sourceDocuments.map((doc) => getFileTypeInfo3(doc.name).category));
40079
40271
  return Array.from(cats).sort();
40080
40272
  }, [documents, vectorDocuments, shouldUseVector]);
40081
- const statistics = (0, import_react58.useMemo)(() => {
40273
+ const statistics = (0, import_react59.useMemo)(() => {
40082
40274
  const sourceDocuments = shouldUseVector ? vectorDocuments : documents;
40083
40275
  const totalSize = sourceDocuments.reduce((sum, doc) => {
40084
40276
  if (shouldUseVector && doc.size) {
@@ -41100,7 +41292,7 @@ var KnowledgeTab = ({
41100
41292
  var KnowledgeTab_default = KnowledgeTab;
41101
41293
 
41102
41294
  // src/management/components/SeedPacksTab.tsx
41103
- var import_react59 = require("react");
41295
+ var import_react60 = require("react");
41104
41296
  var import_material49 = require("@mui/material");
41105
41297
  init_packageSettingsStore();
41106
41298
  init_authenticationStore();
@@ -41709,45 +41901,45 @@ var SeedPacksTab = () => {
41709
41901
  const seedPackAdminRoles = /* @__PURE__ */ new Set(["admin", "super-user", "team_admin", "team_owner"]);
41710
41902
  const userRoles = authStore.user?.roles ?? [];
41711
41903
  const canManage = userRoles.some((role) => seedPackAdminRoles.has(role));
41712
- const [seedPacks, setSeedPacks] = (0, import_react59.useState)([]);
41713
- const [selectedSid, setSelectedSid] = (0, import_react59.useState)(null);
41714
- const [selectedSeedPack, setSelectedSeedPack] = (0, import_react59.useState)(null);
41715
- 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)({
41716
41908
  name: "",
41717
41909
  description: "",
41718
41910
  content: ""
41719
41911
  });
41720
- const [tagsInput, setTagsInput] = (0, import_react59.useState)("");
41721
- const [importedFiles, setImportedFiles] = (0, import_react59.useState)([]);
41722
- const [createImportedFiles, setCreateImportedFiles] = (0, import_react59.useState)([]);
41723
- const [previewFile, setPreviewFile] = (0, import_react59.useState)(null);
41724
- const fileInputRef = (0, import_react59.useRef)(null);
41725
- const wikiFolderInputRef = (0, import_react59.useRef)(null);
41726
- const createFileInputRef = (0, import_react59.useRef)(null);
41727
- const createWikiFolderInputRef = (0, import_react59.useRef)(null);
41728
- const [isLoadingList, setIsLoadingList] = (0, import_react59.useState)(false);
41729
- const [isLoadingDetail, setIsLoadingDetail] = (0, import_react59.useState)(false);
41730
- const [isSaving, setIsSaving] = (0, import_react59.useState)(false);
41731
- const [isPublishing, setIsPublishing] = (0, import_react59.useState)(false);
41732
- const [isArchiving, setIsArchiving] = (0, import_react59.useState)(false);
41733
- const [isDeleting, setIsDeleting] = (0, import_react59.useState)(false);
41734
- const [isCreating, setIsCreating] = (0, import_react59.useState)(false);
41735
- const [createDialogOpen, setCreateDialogOpen] = (0, import_react59.useState)(false);
41736
- const [publishDialogOpen, setPublishDialogOpen] = (0, import_react59.useState)(false);
41737
- const [archiveDialogOpen, setArchiveDialogOpen] = (0, import_react59.useState)(false);
41738
- const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react59.useState)(false);
41739
- const [newPackName, setNewPackName] = (0, import_react59.useState)("");
41740
- const [newPackDescription, setNewPackDescription] = (0, import_react59.useState)("");
41741
- const [newPackTags, setNewPackTags] = (0, import_react59.useState)("");
41742
- const [snackbarOpen, setSnackbarOpen] = (0, import_react59.useState)(false);
41743
- const [snackbarMessage, setSnackbarMessage] = (0, import_react59.useState)("");
41744
- const [snackbarSeverity, setSnackbarSeverity] = (0, import_react59.useState)("success");
41745
- const parsedTags = (0, import_react59.useMemo)(() => parseTags(tagsInput), [tagsInput]);
41746
- 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)(
41747
41939
  () => normalizeTags(selectedSeedPack?.tags),
41748
41940
  [selectedSeedPack?.tags]
41749
41941
  );
41750
- const isDirty = (0, import_react59.useMemo)(() => {
41942
+ const isDirty = (0, import_react60.useMemo)(() => {
41751
41943
  if (!selectedSeedPack) {
41752
41944
  return false;
41753
41945
  }
@@ -41758,17 +41950,17 @@ var SeedPacksTab = () => {
41758
41950
  return nameChanged || descriptionChanged || contentChanged || tagsChanged;
41759
41951
  }, [draft, parsedTags, normalizedSelectedTags, selectedSeedPack]);
41760
41952
  const isReadOnly = !canManage || selectedSeedPack?.status === "archived";
41761
- const sortedSeedPacks = (0, import_react59.useMemo)(() => {
41953
+ const sortedSeedPacks = (0, import_react60.useMemo)(() => {
41762
41954
  return [...seedPacks].sort((a, b) => getSeedPackTimestamp(b) - getSeedPackTimestamp(a));
41763
41955
  }, [seedPacks]);
41764
41956
  const scopeLabel = isTeamScope ? "Team scope" : "Personal scope";
41765
41957
  const scopeDescription = isTeamScope ? "Applies to all members of your team." : "Applies only to your account.";
41766
- const showSnackbar = (0, import_react59.useCallback)((message, severity) => {
41958
+ const showSnackbar = (0, import_react60.useCallback)((message, severity) => {
41767
41959
  setSnackbarMessage(message);
41768
41960
  setSnackbarSeverity(severity);
41769
41961
  setSnackbarOpen(true);
41770
41962
  }, []);
41771
- const hydrateDraft = (0, import_react59.useCallback)((pack) => {
41963
+ const hydrateDraft = (0, import_react60.useCallback)((pack) => {
41772
41964
  setDraft({
41773
41965
  name: pack.name ?? "",
41774
41966
  description: pack.description ?? "",
@@ -41778,14 +41970,14 @@ var SeedPacksTab = () => {
41778
41970
  setImportedFiles([]);
41779
41971
  setPreviewFile(null);
41780
41972
  }, []);
41781
- const resetCreateDialog = (0, import_react59.useCallback)(() => {
41973
+ const resetCreateDialog = (0, import_react60.useCallback)(() => {
41782
41974
  setCreateDialogOpen(false);
41783
41975
  setNewPackName("");
41784
41976
  setNewPackDescription("");
41785
41977
  setNewPackTags("");
41786
41978
  setCreateImportedFiles([]);
41787
41979
  }, []);
41788
- const refreshSeedPacks = (0, import_react59.useCallback)(
41980
+ const refreshSeedPacks = (0, import_react60.useCallback)(
41789
41981
  async (nextSelectedSid) => {
41790
41982
  if (!gatewayConfigured) {
41791
41983
  return;
@@ -41810,7 +42002,7 @@ var SeedPacksTab = () => {
41810
42002
  },
41811
42003
  [gatewayConfigured, selectedSid, showSnackbar]
41812
42004
  );
41813
- const loadSeedPackDetail = (0, import_react59.useCallback)(
42005
+ const loadSeedPackDetail = (0, import_react60.useCallback)(
41814
42006
  async (sid) => {
41815
42007
  if (!gatewayConfigured) {
41816
42008
  return;
@@ -41832,15 +42024,15 @@ var SeedPacksTab = () => {
41832
42024
  },
41833
42025
  [gatewayConfigured, hydrateDraft, showSnackbar]
41834
42026
  );
41835
- (0, import_react59.useEffect)(() => {
42027
+ (0, import_react60.useEffect)(() => {
41836
42028
  void refreshSeedPacks();
41837
42029
  }, [refreshSeedPacks, authStore.token]);
41838
- (0, import_react59.useEffect)(() => {
42030
+ (0, import_react60.useEffect)(() => {
41839
42031
  if (selectedSid) {
41840
42032
  void loadSeedPackDetail(selectedSid);
41841
42033
  }
41842
42034
  }, [selectedSid, loadSeedPackDetail]);
41843
- (0, import_react59.useEffect)(() => {
42035
+ (0, import_react60.useEffect)(() => {
41844
42036
  const setDirectoryUploadAttributes = (input) => {
41845
42037
  if (!input) {
41846
42038
  return;
@@ -41856,7 +42048,7 @@ var SeedPacksTab = () => {
41856
42048
  setSelectedSeedPack(pack);
41857
42049
  hydrateDraft(pack);
41858
42050
  };
41859
- const handleImportFiles = (0, import_react59.useCallback)(
42051
+ const handleImportFiles = (0, import_react60.useCallback)(
41860
42052
  async (files, source = "local") => {
41861
42053
  if (!files || files.length === 0) {
41862
42054
  return;
@@ -41899,24 +42091,24 @@ ${combined}` : combined;
41899
42091
  },
41900
42092
  [importedFiles, showSnackbar]
41901
42093
  );
41902
- const handleFileInputChange = (0, import_react59.useCallback)(
42094
+ const handleFileInputChange = (0, import_react60.useCallback)(
41903
42095
  async (event) => {
41904
42096
  await handleImportFiles(event.target.files, "local");
41905
42097
  event.target.value = "";
41906
42098
  },
41907
42099
  [handleImportFiles]
41908
42100
  );
41909
- const handleWikiFolderInputChange = (0, import_react59.useCallback)(
42101
+ const handleWikiFolderInputChange = (0, import_react60.useCallback)(
41910
42102
  async (event) => {
41911
42103
  await handleImportFiles(event.target.files, "azure-wiki");
41912
42104
  event.target.value = "";
41913
42105
  },
41914
42106
  [handleImportFiles]
41915
42107
  );
41916
- const handleRemoveImportedFile = (0, import_react59.useCallback)((id) => {
42108
+ const handleRemoveImportedFile = (0, import_react60.useCallback)((id) => {
41917
42109
  setImportedFiles((prev) => prev.filter((file) => file.id !== id));
41918
42110
  }, []);
41919
- const handleCreateImportFiles = (0, import_react59.useCallback)(
42111
+ const handleCreateImportFiles = (0, import_react60.useCallback)(
41920
42112
  async (files, source = "local") => {
41921
42113
  if (!files || files.length === 0) {
41922
42114
  return;
@@ -41937,24 +42129,24 @@ ${combined}` : combined;
41937
42129
  },
41938
42130
  [showSnackbar]
41939
42131
  );
41940
- const handleCreateFileInputChange = (0, import_react59.useCallback)(
42132
+ const handleCreateFileInputChange = (0, import_react60.useCallback)(
41941
42133
  async (event) => {
41942
42134
  await handleCreateImportFiles(event.target.files, "local");
41943
42135
  event.target.value = "";
41944
42136
  },
41945
42137
  [handleCreateImportFiles]
41946
42138
  );
41947
- const handleCreateWikiFolderInputChange = (0, import_react59.useCallback)(
42139
+ const handleCreateWikiFolderInputChange = (0, import_react60.useCallback)(
41948
42140
  async (event) => {
41949
42141
  await handleCreateImportFiles(event.target.files, "azure-wiki");
41950
42142
  event.target.value = "";
41951
42143
  },
41952
42144
  [handleCreateImportFiles]
41953
42145
  );
41954
- const handleRemoveCreateImportedFile = (0, import_react59.useCallback)((id) => {
42146
+ const handleRemoveCreateImportedFile = (0, import_react60.useCallback)((id) => {
41955
42147
  setCreateImportedFiles((prev) => prev.filter((file) => file.id !== id));
41956
42148
  }, []);
41957
- const buildDraftPayload2 = (0, import_react59.useCallback)(() => {
42149
+ const buildDraftPayload2 = (0, import_react60.useCallback)(() => {
41958
42150
  const name = draft.name.trim();
41959
42151
  if (!name) {
41960
42152
  showSnackbar("Seed pack name is required.", "error");
@@ -41968,7 +42160,7 @@ ${combined}` : combined;
41968
42160
  contentType: "markdown"
41969
42161
  };
41970
42162
  }, [draft, parsedTags, showSnackbar]);
41971
- const saveDraft = (0, import_react59.useCallback)(async () => {
42163
+ const saveDraft = (0, import_react60.useCallback)(async () => {
41972
42164
  if (!selectedSeedPack) {
41973
42165
  return null;
41974
42166
  }
@@ -42686,9 +42878,9 @@ var KnowledgeHubTab = (props) => {
42686
42878
  const theme = (0, import_material50.useTheme)();
42687
42879
  const isMobile = (0, import_material50.useMediaQuery)(theme.breakpoints.down("sm"));
42688
42880
  const { seedPacksEnabled = false } = props;
42689
- const [tabIndex, setTabIndex] = (0, import_react60.useState)(0);
42881
+ const [tabIndex, setTabIndex] = (0, import_react61.useState)(0);
42690
42882
  const effectiveTabIndex = seedPacksEnabled ? tabIndex : 0;
42691
- (0, import_react60.useEffect)(() => {
42883
+ (0, import_react61.useEffect)(() => {
42692
42884
  if (!seedPacksEnabled && tabIndex !== 0) {
42693
42885
  setTabIndex(0);
42694
42886
  }
@@ -42738,7 +42930,7 @@ var KnowledgeHubTab = (props) => {
42738
42930
  var KnowledgeHubTab_default = KnowledgeHubTab;
42739
42931
 
42740
42932
  // src/management/components/StorageTab.tsx
42741
- var import_react61 = require("react");
42933
+ var import_react62 = require("react");
42742
42934
  var import_material51 = require("@mui/material");
42743
42935
  init_debugLogger();
42744
42936
  init_indexedDBService();
@@ -43041,20 +43233,20 @@ var clearEntireDatabase = async (dbName) => {
43041
43233
  };
43042
43234
  var StorageTab = ({ currentTheme }) => {
43043
43235
  const theme = (0, import_material51.useTheme)();
43044
- const [storageQuota, setStorageQuota] = (0, import_react61.useState)({
43236
+ const [storageQuota, setStorageQuota] = (0, import_react62.useState)({
43045
43237
  used: 0,
43046
43238
  quota: 0,
43047
43239
  available: 0,
43048
43240
  browserQuotaEstimate: 0
43049
43241
  });
43050
- const [storageCategories, setStorageCategories] = (0, import_react61.useState)([]);
43051
- const [loading, setLoading] = (0, import_react61.useState)(true);
43052
- const [clearAllDialogOpen, setClearAllDialogOpen] = (0, import_react61.useState)(false);
43053
- const [clearCategoryDialog, setClearCategoryDialog] = (0, import_react61.useState)(null);
43054
- const [clearing, setClearing] = (0, import_react61.useState)(false);
43055
- const [snackbarMessage, setSnackbarMessage] = (0, import_react61.useState)("");
43056
- const [showSnackbar, setShowSnackbar] = (0, import_react61.useState)(false);
43057
- 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");
43058
43250
  const { syncEnabled, isAdvancedVectorFeaturesEnabled } = useConversationSyncStore((state) => ({
43059
43251
  syncEnabled: state.syncEnabled,
43060
43252
  isAdvancedVectorFeaturesEnabled: state.isAdvancedVectorFeaturesEnabled
@@ -43106,18 +43298,18 @@ var StorageTab = ({ currentTheme }) => {
43106
43298
  setLoading(false);
43107
43299
  }
43108
43300
  };
43109
- (0, import_react61.useEffect)(() => {
43301
+ (0, import_react62.useEffect)(() => {
43110
43302
  loadStorageData();
43111
43303
  }, []);
43112
- const totalUsed = (0, import_react61.useMemo)(() => {
43304
+ const totalUsed = (0, import_react62.useMemo)(() => {
43113
43305
  return storageCategories.reduce((sum, cat) => sum + cat.size, 0);
43114
43306
  }, [storageCategories]);
43115
- const usagePercentage = (0, import_react61.useMemo)(() => {
43307
+ const usagePercentage = (0, import_react62.useMemo)(() => {
43116
43308
  if (storageQuota.quota === 0) return 0;
43117
43309
  const percentage = Math.min(storageQuota.used / storageQuota.quota * 100, 100);
43118
43310
  return percentage > 0 && percentage < 0.1 ? 0.1 : percentage;
43119
43311
  }, [storageQuota]);
43120
- const clearableCategories = (0, import_react61.useMemo)(() => {
43312
+ const clearableCategories = (0, import_react62.useMemo)(() => {
43121
43313
  return storageCategories.filter((cat) => cat.canClear);
43122
43314
  }, [storageCategories]);
43123
43315
  const handleClearCategory = async (category) => {
@@ -43733,7 +43925,7 @@ var StorageTab = ({ currentTheme }) => {
43733
43925
  var StorageTab_default = StorageTab;
43734
43926
 
43735
43927
  // src/management/components/ProviderTab.tsx
43736
- var import_react62 = require("react");
43928
+ var import_react63 = require("react");
43737
43929
  var import_material52 = require("@mui/material");
43738
43930
  init_aiProviderStore();
43739
43931
  init_packageSettingsStore();
@@ -43747,7 +43939,7 @@ var ProviderTab = () => {
43747
43939
  const { settings: packageSettings } = usePackageSettingsStore();
43748
43940
  const theme = (0, import_material52.useTheme)();
43749
43941
  const isMobile = (0, import_material52.useMediaQuery)(theme.breakpoints.down("sm"));
43750
- const getSuggestedModel = (0, import_react62.useCallback)((type) => {
43942
+ const getSuggestedModel = (0, import_react63.useCallback)((type) => {
43751
43943
  const configuredDefault = packageSettings?.defaultModel?.trim();
43752
43944
  if (configuredDefault) {
43753
43945
  return configuredDefault;
@@ -43763,7 +43955,7 @@ var ProviderTab = () => {
43763
43955
  return "";
43764
43956
  }
43765
43957
  }, [packageSettings?.defaultModel]);
43766
- const applyDefaultModel = (0, import_react62.useCallback)((config) => {
43958
+ const applyDefaultModel = (0, import_react63.useCallback)((config) => {
43767
43959
  const normalized = { ...config };
43768
43960
  const trimmed = typeof normalized.defaultModel === "string" ? normalized.defaultModel.trim() : void 0;
43769
43961
  const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */ || normalized.type === "bandit" /* BANDIT */;
@@ -43783,7 +43975,7 @@ var ProviderTab = () => {
43783
43975
  }
43784
43976
  return normalized;
43785
43977
  }, [getSuggestedModel]);
43786
- const sanitizeConfigForSave = (0, import_react62.useCallback)((config) => {
43978
+ const sanitizeConfigForSave = (0, import_react63.useCallback)((config) => {
43787
43979
  const sanitized = { ...config };
43788
43980
  if (typeof sanitized.defaultModel === "string") {
43789
43981
  const trimmed = sanitized.defaultModel.trim();
@@ -43795,14 +43987,14 @@ var ProviderTab = () => {
43795
43987
  }
43796
43988
  return sanitized;
43797
43989
  }, []);
43798
- const [providerConfig, setProviderConfig] = (0, import_react62.useState)({
43990
+ const [providerConfig, setProviderConfig] = (0, import_react63.useState)({
43799
43991
  type: "gateway",
43800
43992
  gatewayUrl: packageSettings?.gatewayApiUrl || "",
43801
43993
  provider: "bandit"
43802
43994
  });
43803
- const [snackbarMessage, setSnackbarMessage] = (0, import_react62.useState)("");
43804
- const [showSnackbar, setShowSnackbar] = (0, import_react62.useState)(false);
43805
- 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");
43806
43998
  const saveProviderConfigToDB = async (config) => {
43807
43999
  try {
43808
44000
  const { tokenFactory: _tokenFactory, ...persistableConfig } = config;
@@ -43843,7 +44035,7 @@ var ProviderTab = () => {
43843
44035
  }
43844
44036
  return null;
43845
44037
  };
43846
- const convertAnthropicConfig = (0, import_react62.useCallback)((config) => {
44038
+ const convertAnthropicConfig = (0, import_react63.useCallback)((config) => {
43847
44039
  if (!config) return null;
43848
44040
  if (config.type !== "anthropic" /* ANTHROPIC */) {
43849
44041
  return config;
@@ -43859,7 +44051,7 @@ var ProviderTab = () => {
43859
44051
  };
43860
44052
  return converted;
43861
44053
  }, [packageSettings?.gatewayApiUrl]);
43862
- (0, import_react62.useEffect)(() => {
44054
+ (0, import_react63.useEffect)(() => {
43863
44055
  const initializeProviderConfig = async () => {
43864
44056
  const savedConfig = await loadProviderConfigFromDB();
43865
44057
  if (savedConfig) {
@@ -44329,7 +44521,7 @@ var ProviderTab = () => {
44329
44521
  };
44330
44522
 
44331
44523
  // src/management/components/MCPToolsTabV2.tsx
44332
- var import_react64 = require("react");
44524
+ var import_react65 = require("react");
44333
44525
  var import_material54 = require("@mui/material");
44334
44526
 
44335
44527
  // src/services/mcp/mcpControllerService.ts
@@ -44406,7 +44598,7 @@ async function fetchMcpHealth() {
44406
44598
  }
44407
44599
 
44408
44600
  // src/management/components/McpServersSection.tsx
44409
- var import_react63 = require("react");
44601
+ var import_react64 = require("react");
44410
44602
  var import_material53 = require("@mui/material");
44411
44603
  init_lucide_icons();
44412
44604
  init_mcpServersService();
@@ -44482,17 +44674,17 @@ var CATALOG = [
44482
44674
  }
44483
44675
  ];
44484
44676
  var McpServersSection = () => {
44485
- const [servers, setServers] = (0, import_react63.useState)([]);
44486
- const [loading, setLoading] = (0, import_react63.useState)(false);
44487
- const [error, setError] = (0, import_react63.useState)(null);
44488
- const [form, setForm] = (0, import_react63.useState)(emptyForm);
44489
- const [activeEntry, setActiveEntry] = (0, import_react63.useState)(null);
44490
- const [adding, setAdding] = (0, import_react63.useState)(false);
44491
- const [showForm, setShowForm] = (0, import_react63.useState)(false);
44492
- 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)({});
44493
44685
  const reloadChatTools = useMCPToolsStore((s) => s.loadMcpServerTools);
44494
- const formRef = (0, import_react63.useRef)(null);
44495
- const refresh = (0, import_react63.useCallback)(async () => {
44686
+ const formRef = (0, import_react64.useRef)(null);
44687
+ const refresh = (0, import_react64.useCallback)(async () => {
44496
44688
  setLoading(true);
44497
44689
  setError(null);
44498
44690
  try {
@@ -44503,7 +44695,7 @@ var McpServersSection = () => {
44503
44695
  setLoading(false);
44504
44696
  }
44505
44697
  }, []);
44506
- (0, import_react63.useEffect)(() => {
44698
+ (0, import_react64.useEffect)(() => {
44507
44699
  refresh();
44508
44700
  }, [refresh]);
44509
44701
  const connectedKeys = new Set(servers.map((s) => s.url.replace(/\/+$/, "")));
@@ -44799,10 +44991,10 @@ var import_jsx_runtime54 = require("react/jsx-runtime");
44799
44991
  var MCPToolsTabV2 = () => {
44800
44992
  const { settings } = usePackageSettingsStore();
44801
44993
  const { tools: localTools, loadTools, toggleTool, addTool, updateTool, isLoaded } = useMCPToolsStore();
44802
- const [loading, setLoading] = (0, import_react64.useState)(true);
44803
- const [error, setError] = (0, import_react64.useState)(null);
44804
- const [tools, setTools] = (0, import_react64.useState)([]);
44805
- 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);
44806
44998
  const gatewayConfigured = !!settings?.gatewayApiUrl;
44807
44999
  const refresh = async () => {
44808
45000
  setLoading(true);
@@ -44856,7 +45048,7 @@ var MCPToolsTabV2 = () => {
44856
45048
  setLoading(false);
44857
45049
  }
44858
45050
  };
44859
- (0, import_react64.useEffect)(() => {
45051
+ (0, import_react65.useEffect)(() => {
44860
45052
  if (isLoaded) {
44861
45053
  refresh();
44862
45054
  } else {
@@ -44865,7 +45057,7 @@ var MCPToolsTabV2 = () => {
44865
45057
  });
44866
45058
  }
44867
45059
  }, [isLoaded]);
44868
- const localEnabledMap = (0, import_react64.useMemo)(() => {
45060
+ const localEnabledMap = (0, import_react65.useMemo)(() => {
44869
45061
  const map23 = /* @__PURE__ */ new Map();
44870
45062
  const sortedTools = [...localTools].sort((a, b) => {
44871
45063
  if (a.isBuiltIn && !b.isBuiltIn) return -1;
@@ -44996,10 +45188,10 @@ var buildCapabilitiesUrl = (gatewayApiUrl) => {
44996
45188
  return `${trimmed}/api/capabilities`;
44997
45189
  };
44998
45190
  var Management = () => {
44999
- const navigate = (0, import_react_router_dom6.useNavigate)();
45191
+ const navigate = (0, import_react_router_dom7.useNavigate)();
45000
45192
  const notificationService2 = useNotificationService();
45001
45193
  const isMobile = (0, import_useMediaQuery2.default)("(max-width:900px)");
45002
- const [sidebarOpen, setSidebarOpen] = (0, import_react65.useState)(false);
45194
+ const [sidebarOpen, setSidebarOpen] = (0, import_react66.useState)(false);
45003
45195
  const getOptimalFabLogo = async () => {
45004
45196
  const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
45005
45197
  try {
@@ -45039,17 +45231,17 @@ var Management = () => {
45039
45231
  hasTransparentLogo,
45040
45232
  setHasTransparentLogo
45041
45233
  } = useModelStore();
45042
- const [modalOpen, setModalOpen] = (0, import_react65.useState)(false);
45234
+ const [modalOpen, setModalOpen] = (0, import_react66.useState)(false);
45043
45235
  const banditHead5 = "https://cdn.burtson.ai/images/bandit-head.png";
45044
- const [fabLogo, setFabLogo] = (0, import_react65.useState)(banditHead5);
45045
- const [tabIndex, setTabIndex] = (0, import_react65.useState)(4);
45046
- const [logoFile, setLogoFile] = (0, import_react65.useState)(null);
45047
- const [logoBase64, setLogoBase64] = (0, import_react65.useState)(null);
45048
- const [brandingText, setBrandingText] = (0, import_react65.useState)("");
45049
- const [headerMode, setHeaderMode] = (0, import_react65.useState)("logo");
45050
- const [theme, setTheme] = (0, import_react65.useState)("bandit-dark");
45051
- const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react65.useState)(null);
45052
- 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);
45053
45245
  const showSnackbarMessage = (message, severity = "success") => {
45054
45246
  if (severity === "success") {
45055
45247
  notificationService2?.showSuccess(message);
@@ -45057,9 +45249,9 @@ var Management = () => {
45057
45249
  notificationService2?.showError(message);
45058
45250
  }
45059
45251
  };
45060
- const [restoreDialogOpen, setRestoreDialogOpen] = (0, import_react65.useState)(false);
45061
- const [brandingLoaded, setBrandingLoaded] = (0, import_react65.useState)(false);
45062
- 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);
45063
45255
  const { initModels } = useModelStore();
45064
45256
  const { settings: packageSettings } = usePackageSettingsStore();
45065
45257
  const authToken = useAuthenticationStore((state) => state.token);
@@ -45067,8 +45259,8 @@ var Management = () => {
45067
45259
  const { hasAdminDashboard, hasLimitedAdminDashboard, getCurrentTier, hasAdvancedSearch } = useFeatures();
45068
45260
  const { showAdminPanel, showLimitedAdminPanel } = useFeatureVisibility();
45069
45261
  const { provider: currentProvider, config: currentProviderConfig } = useAIProviderStore();
45070
- const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react65.useState)(false);
45071
- const [localSelectedModel, setLocalSelectedModel] = (0, import_react65.useState)({
45262
+ const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react66.useState)(false);
45263
+ const [localSelectedModel, setLocalSelectedModel] = (0, import_react66.useState)({
45072
45264
  name: "",
45073
45265
  tagline: "",
45074
45266
  systemPrompt: "",
@@ -45081,7 +45273,7 @@ var Management = () => {
45081
45273
  loadDocuments,
45082
45274
  clearAllDocuments
45083
45275
  } = useKnowledgeStore2();
45084
- (0, import_react65.useEffect)(() => {
45276
+ (0, import_react66.useEffect)(() => {
45085
45277
  if (selectedModel) {
45086
45278
  const selected = availableModels.find((m) => m.name === selectedModel);
45087
45279
  if (selected) {
@@ -45105,7 +45297,7 @@ var Management = () => {
45105
45297
  }
45106
45298
  }
45107
45299
  }, [selectedModel, availableModels]);
45108
- const loadBrandingConfig = (0, import_react65.useCallback)(async () => {
45300
+ const loadBrandingConfig = (0, import_react66.useCallback)(async () => {
45109
45301
  if (isLoadingBranding || brandingLoaded) {
45110
45302
  debugLogger.warn("Branding loading already in progress or completed, skipping");
45111
45303
  return;
@@ -45222,15 +45414,15 @@ var Management = () => {
45222
45414
  setTagline,
45223
45415
  setTheme
45224
45416
  ]);
45225
- (0, import_react65.useEffect)(() => {
45417
+ (0, import_react66.useEffect)(() => {
45226
45418
  void loadBrandingConfig();
45227
45419
  }, [loadBrandingConfig]);
45228
45420
  const handleOpenModal = () => setModalOpen(true);
45229
45421
  const handleCloseModal = () => setModalOpen(false);
45230
- (0, import_react65.useEffect)(() => {
45422
+ (0, import_react66.useEffect)(() => {
45231
45423
  getOptimalFabLogo().then(setFabLogo);
45232
45424
  }, []);
45233
- (0, import_react65.useEffect)(() => {
45425
+ (0, import_react66.useEffect)(() => {
45234
45426
  if (logoBase64) {
45235
45427
  setFabLogo(logoBase64);
45236
45428
  } else {
@@ -45683,7 +45875,7 @@ var Management = () => {
45683
45875
  reader.readAsText(file);
45684
45876
  }
45685
45877
  };
45686
- (0, import_react65.useEffect)(() => {
45878
+ (0, import_react66.useEffect)(() => {
45687
45879
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
45688
45880
  setLocalSelectedModel((prev) => ({
45689
45881
  ...prev,
@@ -45691,10 +45883,10 @@ var Management = () => {
45691
45883
  }));
45692
45884
  }
45693
45885
  }, [availableModels, localSelectedModel.selectedModel]);
45694
- (0, import_react65.useEffect)(() => {
45886
+ (0, import_react66.useEffect)(() => {
45695
45887
  loadDocuments();
45696
45888
  }, [loadDocuments]);
45697
- (0, import_react65.useEffect)(() => {
45889
+ (0, import_react66.useEffect)(() => {
45698
45890
  const gatewayApiUrl = packageSettings?.gatewayApiUrl;
45699
45891
  if (!gatewayApiUrl || gatewayApiUrl.toLowerCase().startsWith("playground://")) {
45700
45892
  setSeedPacksEnabled(false);
@@ -45737,7 +45929,7 @@ var Management = () => {
45737
45929
  isActive = false;
45738
45930
  };
45739
45931
  }, [packageSettings?.gatewayApiUrl, authToken]);
45740
- const currentTheme = (0, import_react65.useMemo)(() => {
45932
+ const currentTheme = (0, import_react66.useMemo)(() => {
45741
45933
  const baseTheme = predefinedThemes[theme] || banditDarkTheme;
45742
45934
  return (0, import_styles35.createTheme)(baseTheme, {
45743
45935
  // Management-scoped density: condenses every settings tab at once. This
@@ -45858,7 +46050,7 @@ var Management = () => {
45858
46050
  });
45859
46051
  const preferredDefaultTabIndex = navTabs.findIndex((tab) => tab.label === "Preferences");
45860
46052
  const defaultTabIndex = preferredDefaultTabIndex >= 0 ? preferredDefaultTabIndex : 0;
45861
- (0, import_react65.useEffect)(() => {
46053
+ (0, import_react66.useEffect)(() => {
45862
46054
  setTabIndex((current) => {
45863
46055
  if (current < 0 || current >= navTabs.length) {
45864
46056
  return defaultTabIndex;
@@ -46015,6 +46207,10 @@ var Management = () => {
46015
46207
  justifyContent: "space-between",
46016
46208
  px: 3,
46017
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))",
46018
46214
  bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(24,28,40,0.95)" : "rgba(255,255,255,0.95)",
46019
46215
  borderBottom: (theme2) => `1px solid ${theme2.palette.divider}`,
46020
46216
  backdropFilter: "blur(12px)",
@@ -46310,7 +46506,7 @@ var Management = () => {
46310
46506
  ]
46311
46507
  }
46312
46508
  ),
46313
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46509
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
46314
46510
  import_material55.Fab,
46315
46511
  {
46316
46512
  "aria-label": "AI",
@@ -46346,7 +46542,7 @@ var Management = () => {
46346
46542
  )
46347
46543
  }
46348
46544
  ),
46349
- /* @__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 })
46350
46546
  ]
46351
46547
  }
46352
46548
  )
@@ -46355,7 +46551,7 @@ var Management = () => {
46355
46551
  var management_default = Management;
46356
46552
 
46357
46553
  // src/management/components/InterestsEditor.tsx
46358
- var import_react66 = require("react");
46554
+ var import_react67 = require("react");
46359
46555
  var import_material56 = require("@mui/material");
46360
46556
  init_preferencesStore();
46361
46557
  init_getStableQuestionPrompt();
@@ -46368,7 +46564,7 @@ var InterestsEditor = ({
46368
46564
  const updatePreference = usePreferencesStore((s) => s.updatePreference);
46369
46565
  const loadPreferences = usePreferencesStore((s) => s.loadPreferences);
46370
46566
  const isLoaded = usePreferencesStore((s) => s.isLoaded);
46371
- (0, import_react66.useEffect)(() => {
46567
+ (0, import_react67.useEffect)(() => {
46372
46568
  if (!isLoaded) {
46373
46569
  void loadPreferences();
46374
46570
  }
@@ -46400,7 +46596,7 @@ var InterestsEditor = ({
46400
46596
  var InterestsEditor_default = InterestsEditor;
46401
46597
 
46402
46598
  // src/shared/custom-element.ts
46403
- var import_react67 = __toESM(require("react"));
46599
+ var import_react68 = __toESM(require("react"));
46404
46600
  var import_client = __toESM(require("react-dom/client"));
46405
46601
  function defineCustomElement(name, Component) {
46406
46602
  if (customElements.get(name)) return;
@@ -46428,7 +46624,7 @@ function defineCustomElement(name, Component) {
46428
46624
  if (!this.root) {
46429
46625
  this.root = import_client.default.createRoot(this.mountPoint);
46430
46626
  }
46431
- this.root.render(import_react67.default.createElement(Component, props));
46627
+ this.root.render(import_react68.default.createElement(Component, props));
46432
46628
  }
46433
46629
  }
46434
46630
  customElements.define(name, ReactElement);
@@ -46637,7 +46833,7 @@ var getFeatureMatrix = () => featureFlagService.generateFeatureMatrix();
46637
46833
  init_featureFlags();
46638
46834
 
46639
46835
  // src/hooks/useVoices.ts
46640
- var import_react68 = require("react");
46836
+ var import_react69 = require("react");
46641
46837
  init_voiceStore();
46642
46838
  init_packageSettingsStore();
46643
46839
  init_authenticationStore();
@@ -46657,7 +46853,7 @@ var useVoices = () => {
46657
46853
  } = useVoiceStore();
46658
46854
  const gatewayApiUrl = usePackageSettingsStore((state) => state.settings?.gatewayApiUrl);
46659
46855
  const { token } = useAuthenticationStore();
46660
- (0, import_react68.useEffect)(() => {
46856
+ (0, import_react69.useEffect)(() => {
46661
46857
  const isAuthenticated = authenticationService2.isAuthenticated();
46662
46858
  if (gatewayApiUrl && token && isAuthenticated && !isServiceAvailable) {
46663
46859
  debugLogger.debug("Gateway API URL and JWT token available, loading voice models...");
@@ -46785,7 +46981,7 @@ var SubscriptionExpiredModal = ({
46785
46981
  };
46786
46982
 
46787
46983
  // src/guards/SubscriptionExpiredGuard.tsx
46788
- var import_react69 = require("react");
46984
+ var import_react70 = require("react");
46789
46985
  init_useFeatures();
46790
46986
  var import_jsx_runtime58 = require("react/jsx-runtime");
46791
46987
  var SubscriptionExpiredGuard = ({
@@ -46796,9 +46992,9 @@ var SubscriptionExpiredGuard = ({
46796
46992
  allowContinue = false
46797
46993
  }) => {
46798
46994
  const { isExpiredTier, getFullEvaluation } = useFeatures();
46799
- const [showModal, setShowModal] = (0, import_react69.useState)(false);
46800
- const [userDismissed, setUserDismissed] = (0, import_react69.useState)(false);
46801
- (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)(() => {
46802
46998
  if (isExpiredTier() && !userDismissed) {
46803
46999
  setShowModal(true);
46804
47000
  } else {