@burtson-labs/bandit-engine 2.1.5 → 2.1.7

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 (36) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/{ProjectsPane-BSVOVNK7.mjs → ProjectsPane-E5D72PUG.mjs} +4 -4
  3. package/dist/{SchedulesTab-TCUOAKLH.mjs → SchedulesTab-AKJ6WFZV.mjs} +3 -3
  4. package/dist/{chat-Y7KPN54G.mjs → chat-MI4IL3WK.mjs} +7 -6
  5. package/dist/{chunk-4257FVLK.mjs → chunk-2HFSBPOE.mjs} +6 -1
  6. package/dist/chunk-2HFSBPOE.mjs.map +1 -0
  7. package/dist/{chunk-XGIQNHUO.mjs → chunk-4NHPLHXU.mjs} +816 -394
  8. package/dist/chunk-4NHPLHXU.mjs.map +1 -0
  9. package/dist/{chunk-SK7FSLCY.mjs → chunk-4NUQYUZH.mjs} +7 -2
  10. package/dist/chunk-4NUQYUZH.mjs.map +1 -0
  11. package/dist/{chunk-ZG66NJC3.mjs → chunk-5URP2E5V.mjs} +3 -6
  12. package/dist/chunk-5URP2E5V.mjs.map +1 -0
  13. package/dist/{chunk-IXD2TDA5.mjs → chunk-SQJ4OKWM.mjs} +2 -2
  14. package/dist/chunk-WBKTQJNX.mjs +21 -0
  15. package/dist/chunk-WBKTQJNX.mjs.map +1 -0
  16. package/dist/image-compare-NW5VCP4Q.mjs +74 -0
  17. package/dist/image-compare-NW5VCP4Q.mjs.map +1 -0
  18. package/dist/image-edit-acknowledgement-RZPQYKYJ.mjs +54 -0
  19. package/dist/image-edit-acknowledgement-RZPQYKYJ.mjs.map +1 -0
  20. package/dist/index.d.mts +16 -1
  21. package/dist/index.d.ts +16 -1
  22. package/dist/index.js +5758 -5120
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +365 -340
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/{schedule-confirm-card-7CMATYSP.mjs → schedule-confirm-card-D4K76HEA.mjs} +5 -5
  27. package/package.json +1 -1
  28. package/dist/chunk-4257FVLK.mjs.map +0 -1
  29. package/dist/chunk-SK7FSLCY.mjs.map +0 -1
  30. package/dist/chunk-XGIQNHUO.mjs.map +0 -1
  31. package/dist/chunk-ZG66NJC3.mjs.map +0 -1
  32. /package/dist/{ProjectsPane-BSVOVNK7.mjs.map → ProjectsPane-E5D72PUG.mjs.map} +0 -0
  33. /package/dist/{SchedulesTab-TCUOAKLH.mjs.map → SchedulesTab-AKJ6WFZV.mjs.map} +0 -0
  34. /package/dist/{chat-Y7KPN54G.mjs.map → chat-MI4IL3WK.mjs.map} +0 -0
  35. /package/dist/{chunk-IXD2TDA5.mjs.map → chunk-SQJ4OKWM.mjs.map} +0 -0
  36. /package/dist/{schedule-confirm-card-7CMATYSP.mjs.map → schedule-confirm-card-D4K76HEA.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -51,7 +51,6 @@ import {
51
51
  parseNotesJson,
52
52
  parseTranscript,
53
53
  pauseTTS,
54
- predefinedThemes,
55
54
  registry_default,
56
55
  resolveAvatar,
57
56
  resumeTTS,
@@ -81,46 +80,7 @@ import {
81
80
  vectorDatabaseService,
82
81
  vectorMigrationService,
83
82
  voiceService
84
- } from "./chunk-XGIQNHUO.mjs";
85
- import {
86
- AIProviderFactory,
87
- GatewayService,
88
- useAIProviderStore
89
- } from "./chunk-GX4FVZNA.mjs";
90
- import {
91
- DEFAULT_TIER_FEATURES,
92
- FeatureFlagContext,
93
- FeatureFlagProvider,
94
- OSS_DEFAULT_FEATURES,
95
- brandingService_default,
96
- isNativeShell,
97
- isStandalonePwa,
98
- newId,
99
- useAIQueryStore,
100
- useConversationStore,
101
- useFeatureFlag,
102
- useFeatureVisibility,
103
- useFeatures,
104
- useProjectStore
105
- } from "./chunk-IXD2TDA5.mjs";
106
- import {
107
- indexedDBService_default,
108
- models,
109
- useModelStore,
110
- usePreferencesStore
111
- } from "./chunk-KWOUXBSF.mjs";
112
- import "./chunk-HS62C62A.mjs";
113
- import {
114
- Agent,
115
- AlertTriangle,
116
- Cpu,
117
- CreditCard,
118
- Home,
119
- MessageCircle,
120
- Sparkles,
121
- Upload,
122
- Zap
123
- } from "./chunk-ZG66NJC3.mjs";
83
+ } from "./chunk-4NHPLHXU.mjs";
124
84
  import {
125
85
  ManagementEmptyState,
126
86
  ManagementPageHeader,
@@ -153,6 +113,7 @@ import {
153
113
  FilePdf,
154
114
  FileText,
155
115
  FileUp,
116
+ Folder,
156
117
  FolderOpen,
157
118
  Globe,
158
119
  Grip,
@@ -195,9 +156,49 @@ import {
195
156
  X,
196
157
  ZoomIn,
197
158
  ZoomOut
198
- } from "./chunk-SK7FSLCY.mjs";
159
+ } from "./chunk-4NUQYUZH.mjs";
160
+ import {
161
+ AIProviderFactory,
162
+ GatewayService,
163
+ useAIProviderStore
164
+ } from "./chunk-GX4FVZNA.mjs";
165
+ import {
166
+ DEFAULT_TIER_FEATURES,
167
+ FeatureFlagContext,
168
+ FeatureFlagProvider,
169
+ OSS_DEFAULT_FEATURES,
170
+ brandingService_default,
171
+ isNativeShell,
172
+ isStandalonePwa,
173
+ newId,
174
+ useAIQueryStore,
175
+ useConversationStore,
176
+ useFeatureFlag,
177
+ useFeatureVisibility,
178
+ useFeatures,
179
+ useProjectStore
180
+ } from "./chunk-SQJ4OKWM.mjs";
181
+ import {
182
+ indexedDBService_default,
183
+ models,
184
+ useModelStore,
185
+ usePreferencesStore
186
+ } from "./chunk-KWOUXBSF.mjs";
187
+ import "./chunk-WBKTQJNX.mjs";
188
+ import "./chunk-HS62C62A.mjs";
199
189
  import "./chunk-MAKXJD7A.mjs";
200
- import "./chunk-4257FVLK.mjs";
190
+ import {
191
+ Agent,
192
+ AlertTriangle,
193
+ Cpu,
194
+ CreditCard,
195
+ Home,
196
+ MessageCircle,
197
+ Sparkles,
198
+ Upload,
199
+ Zap
200
+ } from "./chunk-5URP2E5V.mjs";
201
+ import "./chunk-2HFSBPOE.mjs";
201
202
  import {
202
203
  usePackageSettingsStore
203
204
  } from "./chunk-K7SQWDNF.mjs";
@@ -4239,9 +4240,9 @@ var PersonalitiesTab = ({
4239
4240
  handleSaveModel,
4240
4241
  handleResetModel,
4241
4242
  restoreDefaultModelsAndConfig,
4242
- restoreBanditModels,
4243
4243
  showSnackbar,
4244
- createRequest
4244
+ createRequest,
4245
+ webConsole = false
4245
4246
  }) => {
4246
4247
  const theme = useTheme7();
4247
4248
  const isMobile = useMediaQuery4(theme.breakpoints.down("sm"));
@@ -4396,6 +4397,10 @@ var PersonalitiesTab = ({
4396
4397
  showSnackbar(`Added the ${mood} mood to the prompt.`, "success");
4397
4398
  }
4398
4399
  };
4400
+ const activatePersonality = (model) => {
4401
+ setSelectedModel(model.name);
4402
+ showSnackbar?.(`${model.name} now answers new chats.`, "success");
4403
+ };
4399
4404
  const handleDeletePersonality = (modelNameToDelete) => {
4400
4405
  const nameToDelete = modelNameToDelete || localSelectedModel.selectedModel;
4401
4406
  if (!nameToDelete) {
@@ -5130,6 +5135,7 @@ var PersonalitiesTab = ({
5130
5135
  ]
5131
5136
  }
5132
5137
  ),
5138
+ webConsole && availableModels.length > 0 && /* @__PURE__ */ jsx10(Typography5, { variant: "body2", color: "text.secondary", sx: { mb: 1.5 }, children: "The active personality answers new chats. Choosing one to edit, or saving one, also makes it active." }),
5133
5139
  availableModels.length === 0 ? /* @__PURE__ */ jsx10(
5134
5140
  ManagementEmptyState,
5135
5141
  {
@@ -5167,15 +5173,27 @@ var PersonalitiesTab = ({
5167
5173
  }
5168
5174
  ),
5169
5175
  /* @__PURE__ */ jsxs6(Box8, { sx: { flex: 1, minWidth: 0 }, children: [
5170
- /* @__PURE__ */ jsx10(
5171
- Typography5,
5172
- {
5173
- variant: "body2",
5174
- sx: { fontWeight: 600, lineHeight: 1.2 },
5175
- noWrap: true,
5176
- children: model.name
5177
- }
5178
- ),
5176
+ /* @__PURE__ */ jsxs6(Stack, { direction: "row", alignItems: "center", spacing: 1, sx: { minWidth: 0 }, children: [
5177
+ /* @__PURE__ */ jsx10(
5178
+ Typography5,
5179
+ {
5180
+ variant: "body2",
5181
+ sx: { fontWeight: 600, lineHeight: 1.2 },
5182
+ noWrap: true,
5183
+ children: model.name
5184
+ }
5185
+ ),
5186
+ webConsole && model.name === selectedModel && /* @__PURE__ */ jsx10(
5187
+ Chip3,
5188
+ {
5189
+ label: "Active",
5190
+ size: "small",
5191
+ color: "primary",
5192
+ variant: "outlined",
5193
+ sx: { height: 20, fontSize: "0.7rem" }
5194
+ }
5195
+ )
5196
+ ] }),
5179
5197
  /* @__PURE__ */ jsx10(
5180
5198
  Typography5,
5181
5199
  {
@@ -5196,6 +5214,19 @@ var PersonalitiesTab = ({
5196
5214
  width: { xs: "100%", sm: "auto" }
5197
5215
  },
5198
5216
  children: [
5217
+ webConsole && model.name !== selectedModel && /* @__PURE__ */ jsx10(
5218
+ Button4,
5219
+ {
5220
+ variant: "text",
5221
+ "aria-label": `Use ${model.name}`,
5222
+ onClick: () => activatePersonality(model),
5223
+ sx: {
5224
+ flex: { xs: 1, sm: "initial" },
5225
+ minHeight: { xs: 44, sm: "auto" }
5226
+ },
5227
+ children: "Use"
5228
+ }
5229
+ ),
5199
5230
  /* @__PURE__ */ jsx10(
5200
5231
  Button4,
5201
5232
  {
@@ -5487,7 +5518,8 @@ var PreferencesTab = ({
5487
5518
  packageSettings,
5488
5519
  updatePreference,
5489
5520
  handleSavePreferences,
5490
- showSnackbar
5521
+ showSnackbar,
5522
+ showDiagnostics = false
5491
5523
  }) => {
5492
5524
  const theme = useTheme8();
5493
5525
  const isMobile = useMediaQuery5(theme.breakpoints.down("sm"));
@@ -6631,7 +6663,7 @@ var PreferencesTab = ({
6631
6663
  ]
6632
6664
  }
6633
6665
  ),
6634
- /* @__PURE__ */ jsx11(ViewportDiagnostics, {})
6666
+ showDiagnostics && /* @__PURE__ */ jsx11(ViewportDiagnostics, {})
6635
6667
  ] }) });
6636
6668
  };
6637
6669
  var ViewportDiagnostics = () => {
@@ -7415,11 +7447,14 @@ var BrandingTab = ({
7415
7447
  "Failed to reset branding settings"
7416
7448
  );
7417
7449
  const handleImport = async (event) => {
7450
+ const input = event.target;
7418
7451
  try {
7419
7452
  await handleImportConfig(event);
7420
7453
  notify("Branding configuration imported", "success");
7421
7454
  } catch {
7422
7455
  notify("Failed to import branding configuration", "error");
7456
+ } finally {
7457
+ input.value = "";
7423
7458
  }
7424
7459
  };
7425
7460
  const name = brandingText.trim() || "Bandit AI";
@@ -8365,8 +8400,7 @@ var KnowledgeTab = ({
8365
8400
  addDocuments,
8366
8401
  removeDocument,
8367
8402
  loadDocuments,
8368
- clearAllDocuments,
8369
- isLimitedAdmin = false
8403
+ clearAllDocuments
8370
8404
  }) => {
8371
8405
  const muiTheme = useTheme11();
8372
8406
  const authStore = useAuthenticationStore();
@@ -8377,12 +8411,9 @@ var KnowledgeTab = ({
8377
8411
  const {
8378
8412
  isVectorEnabled,
8379
8413
  uploadDocument: uploadToVector,
8380
- searchDocuments: searchVectorDocuments,
8381
8414
  getKnowledgeDocumentsPage,
8382
8415
  downloadVectorFile,
8383
- getFilePreview,
8384
- refreshCompatibilityCheck,
8385
- initializeVectorService
8416
+ getFilePreview
8386
8417
  } = useVectorStore();
8387
8418
  const { showProcessing, hideProcessing, updateProgress, processingState } = useProcessingOverlay();
8388
8419
  const shouldUseVector = (features.isAdmin() || features.hasAdvancedSearch() || features.hasAdvancedMemories()) && isAdvancedVectorFeaturesEnabled && isVectorEnabled;
@@ -8463,7 +8494,7 @@ var KnowledgeTab = ({
8463
8494
  hiddenCount: page.hiddenCount
8464
8495
  });
8465
8496
  } catch (error) {
8466
- console.error("Failed to load vector documents:", error);
8497
+ debugLogger.error("Failed to load vector documents", { error });
8467
8498
  setVectorLoadError(error instanceof Error ? error.message : String(error));
8468
8499
  } finally {
8469
8500
  setLoadingVectorDocs(false);
@@ -8640,7 +8671,7 @@ var KnowledgeTab = ({
8640
8671
  await loadVectorDocuments();
8641
8672
  return { success: true, usedVector: true };
8642
8673
  } catch (error) {
8643
- console.error("Error uploading to vector database:", error);
8674
+ debugLogger.error("Error uploading to vector database", { error });
8644
8675
  hideProcessing();
8645
8676
  try {
8646
8677
  await addDocuments(files);
@@ -8708,7 +8739,7 @@ var KnowledgeTab = ({
8708
8739
  try {
8709
8740
  await loadDocuments();
8710
8741
  } catch (loadError) {
8711
- console.error("Failed to reload documents after upload", loadError);
8742
+ debugLogger.error("Failed to reload documents after upload", { error: loadError });
8712
8743
  }
8713
8744
  }, 100);
8714
8745
  } else {
@@ -8736,7 +8767,7 @@ var KnowledgeTab = ({
8736
8767
  );
8737
8768
  setSnackbarSeverity("error");
8738
8769
  setShowSnackbar(true);
8739
- console.error("Failed to add documents", err);
8770
+ debugLogger.error("Failed to add documents", { error: err });
8740
8771
  } finally {
8741
8772
  if (e.target) {
8742
8773
  e.target.value = "";
@@ -8779,7 +8810,7 @@ var KnowledgeTab = ({
8779
8810
  try {
8780
8811
  await loadDocuments();
8781
8812
  } catch (loadError) {
8782
- console.error("Failed to reload documents after drop", loadError);
8813
+ debugLogger.error("Failed to reload documents after drop", { error: loadError });
8783
8814
  }
8784
8815
  }, 100);
8785
8816
  } else {
@@ -8807,7 +8838,7 @@ var KnowledgeTab = ({
8807
8838
  );
8808
8839
  setSnackbarSeverity("error");
8809
8840
  setShowSnackbar(true);
8810
- console.error("Drag/drop failed", err);
8841
+ debugLogger.error("Drag/drop failed", { error: err });
8811
8842
  }
8812
8843
  };
8813
8844
  const handleDragOver = (e) => {
@@ -8838,7 +8869,7 @@ var KnowledgeTab = ({
8838
8869
  URL.revokeObjectURL(url);
8839
8870
  }
8840
8871
  } catch (error) {
8841
- console.error("Download failed:", error);
8872
+ debugLogger.error("Download failed", { error });
8842
8873
  setSnackbarMessage(
8843
8874
  `Couldn't download ${doc.name}: ${error instanceof Error ? error.message : "unknown error"}`
8844
8875
  );
@@ -8865,7 +8896,7 @@ var KnowledgeTab = ({
8865
8896
  setShowSnackbar(true);
8866
8897
  }
8867
8898
  } catch (error) {
8868
- console.error("Failed to get preview:", error);
8899
+ debugLogger.error("Failed to get preview", { error });
8869
8900
  setSnackbarMessage(
8870
8901
  `Couldn't preview ${doc.name}: ${error instanceof Error ? error.message : "unknown error"}`
8871
8902
  );
@@ -11469,6 +11500,23 @@ import {
11469
11500
  useTheme as useTheme13
11470
11501
  } from "@mui/material";
11471
11502
  import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
11503
+ var BANDIT_DATABASES = {
11504
+ conversations: { db: "bandit-conversations", store: "conversations" },
11505
+ projects: { db: "bandit-projects", store: "projects" },
11506
+ knowledge: { db: "banditKnowledge", store: "documents" },
11507
+ memories: { db: "bandit-memory-db", store: "bandit-memory" },
11508
+ config: { db: "banditConfig", store: "config" },
11509
+ queryCache: { db: "ai-query-db", store: "ai-query" }
11510
+ };
11511
+ var LEGACY_DATABASES = [
11512
+ "bandit-knowledge",
11513
+ "knowledge",
11514
+ "banditConversations",
11515
+ "banditMemories",
11516
+ "bandit-memories",
11517
+ "banditAIQuery",
11518
+ "bandit-config"
11519
+ ];
11472
11520
  var DEFAULT_DISPLAY_QUOTA_BYTES = 1024 * 1024 * 1024;
11473
11521
  var MAX_DISPLAY_QUOTA_BYTES = 5 * 1024 * 1024 * 1024;
11474
11522
  var formatBytes = (bytes) => {
@@ -11492,171 +11540,101 @@ var getStorageQuota = async () => {
11492
11540
  }
11493
11541
  return { used: 0, quota: 0 };
11494
11542
  };
11543
+ var listExistingDatabases = async () => {
11544
+ try {
11545
+ if (typeof indexedDB === "undefined" || typeof indexedDB.databases !== "function") {
11546
+ return null;
11547
+ }
11548
+ const databases = await indexedDB.databases();
11549
+ return new Set(
11550
+ databases.map((db) => db.name).filter((name) => Boolean(name))
11551
+ );
11552
+ } catch (error) {
11553
+ debugLogger.warn("Could not list databases", { error });
11554
+ return null;
11555
+ }
11556
+ };
11495
11557
  var getIndexedDBSize = async () => {
11496
- const categories = [];
11497
11558
  try {
11498
11559
  debugLogger.info("Starting IndexedDB size estimation");
11499
- try {
11500
- const databases = await indexedDB.databases();
11501
- debugLogger.info("Available IndexedDB databases:", {
11502
- databases: databases.map((db) => ({ name: db.name, version: db.version }))
11503
- });
11504
- } catch (error) {
11505
- debugLogger.warn("Could not list databases", { error });
11506
- }
11507
- const conversationDbNames = [
11508
- "bandit-conversations",
11509
- "banditConversations",
11510
- "conversations"
11511
- ];
11512
- let chatSize = { size: 0, count: 0 };
11513
- let foundConversationDb = "";
11514
- for (const dbName of conversationDbNames) {
11515
- try {
11516
- const result = await estimateStoreSize(dbName, "conversations");
11517
- if (result.count > 0) {
11518
- chatSize = result;
11519
- foundConversationDb = dbName;
11520
- debugLogger.info(`Found conversations in database: ${dbName}`);
11521
- break;
11522
- }
11523
- } catch (error) {
11524
- debugLogger.warn(`Failed to check conversations in ${dbName}`, { error });
11525
- }
11526
- }
11527
- categories.push({
11528
- name: "Chat History",
11529
- icon: MessageSquare,
11530
- size: chatSize.size,
11531
- itemCount: chatSize.count,
11532
- description: "Conversation history and messages",
11533
- stores: foundConversationDb ? [`${foundConversationDb}.conversations`] : [],
11534
- canClear: chatSize.count > 0,
11535
- clearWarning: "This will permanently delete all your chat conversations and message history."
11536
- });
11537
- debugLogger.info(`Chat History category created:`, {
11538
- itemCount: chatSize.count,
11539
- size: chatSize.size,
11540
- canClear: chatSize.count > 0,
11541
- foundDb: foundConversationDb
11542
- });
11543
- const knowledgeDbNames = ["bandit-knowledge", "banditKnowledge", "knowledge"];
11544
- let knowledgeSize = { size: 0, count: 0 };
11545
- let foundKnowledgeDb = "";
11546
- for (const dbName of knowledgeDbNames) {
11547
- try {
11548
- const result = await estimateStoreSize(dbName, "documents");
11549
- debugLogger.info(`Knowledge database ${dbName} check result:`, {
11550
- size: result.size,
11551
- count: result.count,
11552
- sizeFormatted: `${(result.size / 1024).toFixed(2)} KB`
11553
- });
11554
- if (result.count > 0) {
11555
- knowledgeSize = result;
11556
- foundKnowledgeDb = dbName;
11557
- debugLogger.info(`Found knowledge documents in database: ${dbName}`, {
11558
- totalSize: result.size,
11559
- itemCount: result.count
11560
- });
11561
- break;
11562
- }
11563
- } catch (error) {
11564
- debugLogger.warn(`Failed to check knowledge in ${dbName}`, { error });
11565
- }
11566
- }
11567
- categories.push({
11568
- name: "Knowledge Documents",
11569
- icon: FileText,
11570
- size: knowledgeSize.size,
11571
- itemCount: knowledgeSize.count,
11572
- description: "Uploaded documents and their embeddings",
11573
- stores: foundKnowledgeDb ? [`${foundKnowledgeDb}.documents`] : [],
11574
- canClear: knowledgeSize.count > 0,
11575
- clearWarning: "This will remove all uploaded documents and their AI embeddings. You will need to re-upload documents."
11576
- });
11577
- debugLogger.info(`Knowledge Documents category created:`, {
11578
- itemCount: knowledgeSize.count,
11579
- size: knowledgeSize.size,
11580
- sizeFormatted: `${(knowledgeSize.size / 1024).toFixed(2)} KB`,
11581
- canClear: knowledgeSize.count > 0,
11582
- foundDb: foundKnowledgeDb
11583
- });
11584
- const memoryDbNames = ["bandit-memory-db", "banditMemories", "bandit-memories"];
11585
- let memorySize = { size: 0, count: 0 };
11586
- let foundMemoryDb = "";
11587
- for (const dbName of memoryDbNames) {
11588
- try {
11589
- const result = await estimateStoreSize(dbName, "memories");
11590
- if (result.count > 0) {
11591
- memorySize = result;
11592
- foundMemoryDb = dbName;
11593
- debugLogger.info(`Found memories in database: ${dbName}`);
11594
- break;
11595
- }
11596
- } catch (error) {
11597
- debugLogger.warn(`Failed to check memories in ${dbName}`, { error });
11598
- }
11599
- }
11600
- categories.push({
11601
- name: "AI Memories",
11602
- icon: User,
11603
- size: memorySize.size,
11604
- itemCount: memorySize.count,
11605
- description: "AI memory entries and learned patterns",
11606
- stores: foundMemoryDb ? [`${foundMemoryDb}.memories`] : [],
11607
- canClear: memorySize.count > 0,
11608
- clearWarning: "This will delete all AI memory entries and learned conversation patterns."
11609
- });
11610
- const configDbNames = ["banditConfig", "bandit-config"];
11611
- let configSize = { size: 0, count: 0 };
11612
- let foundConfigDb = "";
11613
- for (const dbName of configDbNames) {
11614
- try {
11615
- const result = await estimateStoreSize(dbName, "config");
11616
- if (result.count > 0) {
11617
- configSize = result;
11618
- foundConfigDb = dbName;
11619
- debugLogger.info(`Found config in database: ${dbName}`);
11620
- break;
11621
- }
11622
- } catch (error) {
11623
- debugLogger.warn(`Failed to check config in ${dbName}`, { error });
11624
- }
11625
- }
11626
- categories.push({
11627
- name: "App Settings & Models",
11628
- icon: Settings,
11629
- size: configSize.size,
11630
- itemCount: configSize.count,
11631
- description: "Custom models, app settings, and user preferences",
11632
- stores: foundConfigDb ? [`${foundConfigDb}.config`] : [],
11633
- canClear: configSize.count > 0,
11634
- clearWarning: "This will delete all custom AI models, app settings, themes, and preferences. The app will reset to defaults."
11635
- });
11636
- const queryDbNames = ["banditAIQuery", "ai-query-db"];
11637
- let querySize = { size: 0, count: 0 };
11638
- let foundQueryDb = "";
11639
- for (const dbName of queryDbNames) {
11640
- try {
11641
- const result = await estimateStoreSize(dbName, "queries");
11642
- if (result.count > 0) {
11643
- querySize = result;
11644
- foundQueryDb = dbName;
11645
- debugLogger.info(`Found AI queries in database: ${dbName}`);
11646
- break;
11560
+ const existing = await listExistingDatabases();
11561
+ const measure = async (target) => existing && !existing.has(target.db) ? { size: 0, count: 0 } : estimateStoreSize(target.db, target.store);
11562
+ const location = (target) => `${target.db}.${target.store}`;
11563
+ const [conversations, projects, knowledge, memories, config, queryCache] = await Promise.all([
11564
+ measure(BANDIT_DATABASES.conversations),
11565
+ measure(BANDIT_DATABASES.projects),
11566
+ measure(BANDIT_DATABASES.knowledge),
11567
+ measure(BANDIT_DATABASES.memories),
11568
+ measure(BANDIT_DATABASES.config),
11569
+ measure(BANDIT_DATABASES.queryCache)
11570
+ ]);
11571
+ const categories = [
11572
+ {
11573
+ name: "Chat History",
11574
+ icon: MessageSquare,
11575
+ size: conversations.size,
11576
+ itemCount: conversations.count,
11577
+ description: "Conversation history and messages",
11578
+ stores: [location(BANDIT_DATABASES.conversations)],
11579
+ canClear: conversations.count > 0,
11580
+ clearWarning: "This will permanently delete all your chat conversations and message history.",
11581
+ // Through the store, so the sidebar empties with it and sync sees the deletes.
11582
+ clear: () => useConversationStore.getState().clearAllConversations()
11583
+ },
11584
+ {
11585
+ name: "Projects",
11586
+ icon: Folder,
11587
+ size: projects.size,
11588
+ itemCount: projects.count,
11589
+ description: "Project names, colours and instructions",
11590
+ stores: [location(BANDIT_DATABASES.projects)],
11591
+ canClear: projects.count > 0,
11592
+ clearWarning: "This deletes every project. Conversations in them are kept, without a project.",
11593
+ clear: async () => {
11594
+ await clearStoreRows(BANDIT_DATABASES.projects.db, BANDIT_DATABASES.projects.store);
11595
+ await useProjectStore.getState().hydrate();
11647
11596
  }
11648
- } catch (error) {
11649
- debugLogger.warn(`Failed to check queries in ${dbName}`, { error });
11597
+ },
11598
+ {
11599
+ name: "Knowledge Documents",
11600
+ icon: FileText,
11601
+ size: knowledge.size,
11602
+ itemCount: knowledge.count,
11603
+ description: "Uploaded documents and their embeddings",
11604
+ stores: [location(BANDIT_DATABASES.knowledge)],
11605
+ canClear: knowledge.count > 0,
11606
+ clearWarning: "This will remove all uploaded documents and their AI embeddings. You will need to re-upload documents."
11607
+ },
11608
+ {
11609
+ name: "AI Memories",
11610
+ icon: User,
11611
+ size: memories.size,
11612
+ itemCount: memories.count,
11613
+ description: "What Bandit remembers from your chats (this browser's copy)",
11614
+ stores: [location(BANDIT_DATABASES.memories)],
11615
+ canClear: memories.count > 0,
11616
+ clearWarning: "This will delete all AI memory entries and learned conversation patterns.",
11617
+ clear: () => useMemoryStore.getState().clearMemories()
11618
+ },
11619
+ {
11620
+ name: "App Settings & Models",
11621
+ icon: Settings,
11622
+ size: config.size,
11623
+ itemCount: config.count,
11624
+ description: "Custom models, app settings, and user preferences",
11625
+ stores: [location(BANDIT_DATABASES.config)],
11626
+ canClear: config.count > 0,
11627
+ clearWarning: "This will delete all custom AI models, app settings, themes, and preferences. The app will reset to defaults."
11650
11628
  }
11651
- }
11652
- if (querySize.count > 0) {
11629
+ ];
11630
+ if (queryCache.count > 0) {
11653
11631
  categories.push({
11654
11632
  name: "AI Query Cache",
11655
11633
  icon: User,
11656
- size: querySize.size,
11657
- itemCount: querySize.count,
11634
+ size: queryCache.size,
11635
+ itemCount: queryCache.count,
11658
11636
  description: "Cached AI query results and responses",
11659
- stores: [`${foundQueryDb}.queries`],
11637
+ stores: [location(BANDIT_DATABASES.queryCache)],
11660
11638
  canClear: true,
11661
11639
  clearWarning: "This will delete all cached AI query results."
11662
11640
  });
@@ -11666,8 +11644,7 @@ var getIndexedDBSize = async () => {
11666
11644
  categories: categories.map((cat) => ({
11667
11645
  name: cat.name,
11668
11646
  itemCount: cat.itemCount,
11669
- canClear: cat.canClear,
11670
- storesLength: cat.stores.length
11647
+ canClear: cat.canClear
11671
11648
  }))
11672
11649
  });
11673
11650
  return categories;
@@ -11723,39 +11700,37 @@ var estimateStoreSize = async (dbName, storeName) => {
11723
11700
  return { size: 0, count: 0 };
11724
11701
  }
11725
11702
  };
11703
+ var clearStoreRows = async (dbName, storeName) => {
11704
+ const storeConfigs = [{ name: storeName, keyPath: "id" }];
11705
+ const items = await indexedDBService_default.getAll(dbName, 1, storeName, storeConfigs);
11706
+ const records = Array.isArray(items) ? items : [];
11707
+ for (const rawItem of records) {
11708
+ if (rawItem && typeof rawItem === "object") {
11709
+ const record = rawItem;
11710
+ const candidate = record["id"] ?? record["key"] ?? record["name"];
11711
+ if (typeof candidate === "string" && candidate.length > 0) {
11712
+ await indexedDBService_default.delete(dbName, 1, storeName, candidate, storeConfigs);
11713
+ }
11714
+ }
11715
+ }
11716
+ debugLogger.info(`Cleared ${records.length} items from ${dbName}.${storeName}`);
11717
+ };
11726
11718
  var clearStorageCategory = async (category) => {
11727
11719
  debugLogger.info(`Clearing storage category: ${category.name}`);
11720
+ if (category.clear) {
11721
+ await category.clear();
11722
+ return;
11723
+ }
11728
11724
  for (const storeSpec of category.stores) {
11725
+ const dot = storeSpec.indexOf(".");
11726
+ const dbName = dot > 0 ? storeSpec.slice(0, dot) : "";
11727
+ const storeName = dot > 0 ? storeSpec.slice(dot + 1) : "";
11728
+ if (!dbName || !storeName) {
11729
+ debugLogger.warn(`Invalid store specification: ${storeSpec}`);
11730
+ continue;
11731
+ }
11729
11732
  try {
11730
- const [dbName, storeName] = storeSpec.split(".");
11731
- debugLogger.info(`Clearing store: ${dbName}.${storeName}`);
11732
- if (!dbName || !storeName) {
11733
- debugLogger.warn(`Invalid store specification: ${storeSpec}`);
11734
- continue;
11735
- }
11736
- const storeConfigs = [{ name: storeName, keyPath: "id" }];
11737
- const items = await indexedDBService_default.getAll(dbName, 1, storeName, storeConfigs);
11738
- const records = Array.isArray(items) ? items : [];
11739
- if (records.length > 0) {
11740
- for (const rawItem of records) {
11741
- if (rawItem && typeof rawItem === "object") {
11742
- const record = rawItem;
11743
- const candidate = record["id"] ?? record["key"] ?? record["name"];
11744
- if (typeof candidate === "string" && candidate.length > 0) {
11745
- await indexedDBService_default.delete(
11746
- dbName,
11747
- 1,
11748
- storeName,
11749
- candidate,
11750
- storeConfigs
11751
- );
11752
- }
11753
- }
11754
- }
11755
- debugLogger.info(`Cleared ${records.length} items from ${dbName}.${storeName}`);
11756
- } else {
11757
- debugLogger.info(`No items found in ${dbName}.${storeName}`);
11758
- }
11733
+ await clearStoreRows(dbName, storeName);
11759
11734
  } catch (error) {
11760
11735
  debugLogger.error(`Failed to clear store: ${storeSpec}`, { error });
11761
11736
  }
@@ -11782,7 +11757,7 @@ var clearEntireDatabase = async (dbName) => {
11782
11757
  };
11783
11758
  });
11784
11759
  };
11785
- var StorageTab = ({ currentTheme }) => {
11760
+ var StorageTab = () => {
11786
11761
  const theme = useTheme13();
11787
11762
  const [storageQuota, setStorageQuota] = useState19({
11788
11763
  used: 0,
@@ -11931,18 +11906,8 @@ var StorageTab = ({ currentTheme }) => {
11931
11906
  setClearing(true);
11932
11907
  try {
11933
11908
  const databases = [
11934
- // Current databases
11935
- "banditConfig",
11936
- "bandit-knowledge",
11937
- "bandit-conversations",
11938
- "bandit-memory-db",
11939
- // Legacy/duplicate databases
11940
- "banditConversations",
11941
- "banditKnowledge",
11942
- "banditMemories",
11943
- "banditAIQuery",
11944
- "ai-query-db",
11945
- "knowledge"
11909
+ ...Object.values(BANDIT_DATABASES).map((target) => target.db),
11910
+ ...LEGACY_DATABASES
11946
11911
  ];
11947
11912
  for (const dbName of databases) {
11948
11913
  await clearEntireDatabase(dbName);
@@ -12201,7 +12166,7 @@ var StorageTab = ({ currentTheme }) => {
12201
12166
  compact: true,
12202
12167
  icon: /* @__PURE__ */ jsx18(Database, {}),
12203
12168
  title: "No stored data found",
12204
- description: "Bandit keeps conversations, knowledge documents, memories and settings in this browser. Nothing was found, either because it's empty or the databases couldn't be read.",
12169
+ description: "Bandit keeps conversations, projects, knowledge documents, memories and settings in this browser. Nothing was found, either because it's empty or the databases couldn't be read.",
12205
12170
  action: /* @__PURE__ */ jsx18(
12206
12171
  Button10,
12207
12172
  {
@@ -12731,7 +12696,6 @@ var ProviderTab = () => {
12731
12696
  type: config.type
12732
12697
  });
12733
12698
  } catch (error) {
12734
- console.error("Failed to save provider config to IndexedDB:", error);
12735
12699
  debugLogger.error("Failed to save provider config to IndexedDB:", { error });
12736
12700
  throw error;
12737
12701
  }
@@ -14567,6 +14531,11 @@ import {
14567
14531
  import { alpha as alpha3 } from "@mui/material/styles";
14568
14532
  import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
14569
14533
  var RAIL_WIDTH = 248;
14534
+ var GROUP_HEADINGS = [
14535
+ { group: "home", heading: null },
14536
+ { group: "you", heading: "You" },
14537
+ { group: "workspace", heading: "Workspace" }
14538
+ ];
14570
14539
  var controlRadius = (theme) => `${Math.max(Number(theme.shape.borderRadius) - 2, 4)}px`;
14571
14540
  var SECTION_ICONS = {
14572
14541
  overview: Home2,
@@ -14616,8 +14585,14 @@ function Navigation({
14616
14585
  onBackToChat,
14617
14586
  onBackHover,
14618
14587
  onOpenCommandPalette,
14588
+ grouped,
14619
14589
  onAfterSelect
14620
14590
  }) {
14591
+ const lists = grouped ? GROUP_HEADINGS.map(({ group, heading }) => ({
14592
+ key: group,
14593
+ heading,
14594
+ items: sections.filter((section) => section.group === group)
14595
+ })).filter((list) => list.items.length > 0) : [{ key: "all", heading: "Workspace", items: sections }];
14621
14596
  const subheaderSx = {
14622
14597
  bgcolor: "transparent",
14623
14598
  lineHeight: "28px",
@@ -14710,14 +14685,16 @@ function Navigation({
14710
14685
  "aria-label": "Management",
14711
14686
  sx: { flex: 1, overflowY: "auto", px: 1.5, pb: 2 },
14712
14687
  children: [
14713
- /* @__PURE__ */ jsx23(
14688
+ lists.map((list, index) => /* @__PURE__ */ jsx23(
14714
14689
  List5,
14715
14690
  {
14716
14691
  component: "div",
14717
14692
  dense: true,
14718
14693
  disablePadding: true,
14719
- subheader: /* @__PURE__ */ jsx23(ListSubheader, { component: "div", disableSticky: true, sx: subheaderSx, children: "Workspace" }),
14720
- children: sections.map((section) => {
14694
+ "aria-label": list.heading ?? void 0,
14695
+ sx: index > 0 && !list.heading ? { mt: 1 } : void 0,
14696
+ subheader: list.heading ? /* @__PURE__ */ jsx23(ListSubheader, { component: "div", disableSticky: true, sx: subheaderSx, children: list.heading }) : void 0,
14697
+ children: list.items.map((section) => {
14721
14698
  const Icon = SECTION_ICONS[section.id];
14722
14699
  const selected = section.id === active;
14723
14700
  return /* @__PURE__ */ jsxs19(
@@ -14747,8 +14724,9 @@ function Navigation({
14747
14724
  section.id
14748
14725
  );
14749
14726
  })
14750
- }
14751
- ),
14727
+ },
14728
+ list.key
14729
+ )),
14752
14730
  organizationLinks && organizationLinks.length > 0 && /* @__PURE__ */ jsx23(
14753
14731
  List5,
14754
14732
  {
@@ -15157,6 +15135,11 @@ function ManagementOverview({
15157
15135
 
15158
15136
  // src/management/shell/sections.ts
15159
15137
  import { useMemo as useMemo7 } from "react";
15138
+
15139
+ // src/management/shell/console.ts
15140
+ var managementConsoleVariant = () => IS_STORE_BUILD || isNativeShell() ? "native" : "web";
15141
+
15142
+ // src/management/shell/sections.ts
15160
15143
  var MANAGEMENT_SECTIONS = [
15161
15144
  {
15162
15145
  id: "overview",
@@ -15164,7 +15147,8 @@ var MANAGEMENT_SECTIONS = [
15164
15147
  description: "This workspace at a glance: personalities, knowledge, provider and appearance.",
15165
15148
  keywords: ["home", "summary", "dashboard"],
15166
15149
  requiresAdmin: true,
15167
- requiresFeature: "limitedAdminDashboard"
15150
+ requiresFeature: "limitedAdminDashboard",
15151
+ group: "home"
15168
15152
  },
15169
15153
  {
15170
15154
  id: "personalities",
@@ -15172,7 +15156,8 @@ var MANAGEMENT_SECTIONS = [
15172
15156
  description: "The assistants people chat with: their name, prompt, model and avatar.",
15173
15157
  keywords: ["models", "assistant", "prompt", "persona", "create personality"],
15174
15158
  requiresAdmin: true,
15175
- requiresFeature: "limitedAdminDashboard"
15159
+ requiresFeature: "limitedAdminDashboard",
15160
+ group: "workspace"
15176
15161
  },
15177
15162
  {
15178
15163
  id: "knowledge",
@@ -15180,7 +15165,8 @@ var MANAGEMENT_SECTIONS = [
15180
15165
  description: "Documents Bandit can answer from, and seed packs for new workspaces.",
15181
15166
  keywords: ["documents", "upload", "files", "seed packs", "rag"],
15182
15167
  requiresAdmin: true,
15183
- requiresFeature: "limitedAdminDashboard"
15168
+ requiresFeature: "limitedAdminDashboard",
15169
+ group: "workspace"
15184
15170
  },
15185
15171
  {
15186
15172
  id: "tools",
@@ -15188,7 +15174,8 @@ var MANAGEMENT_SECTIONS = [
15188
15174
  description: "Built-in tools and connected MCP servers the assistant can call.",
15189
15175
  keywords: ["mcp", "integrations", "servers", "functions"],
15190
15176
  requiresAdmin: true,
15191
- requiresFeature: "advancedSearch"
15177
+ requiresFeature: "advancedSearch",
15178
+ group: "workspace"
15192
15179
  },
15193
15180
  {
15194
15181
  id: "provider",
@@ -15196,7 +15183,8 @@ var MANAGEMENT_SECTIONS = [
15196
15183
  description: "The model backend that powers chat: gateway, OpenAI, Ollama and others.",
15197
15184
  keywords: ["engine", "model", "api key", "gateway", "ollama", "openai"],
15198
15185
  requiresAdmin: true,
15199
- requiresFeature: "advancedSearch"
15186
+ requiresFeature: "advancedSearch",
15187
+ group: "workspace"
15200
15188
  },
15201
15189
  {
15202
15190
  id: "storage",
@@ -15204,7 +15192,8 @@ var MANAGEMENT_SECTIONS = [
15204
15192
  description: "What this browser keeps locally, and how much room it takes.",
15205
15193
  keywords: ["indexeddb", "cache", "clear", "data"],
15206
15194
  requiresAdmin: true,
15207
- requiresFeature: "limitedAdminDashboard"
15195
+ requiresFeature: "limitedAdminDashboard",
15196
+ group: "workspace"
15208
15197
  },
15209
15198
  {
15210
15199
  id: "branding",
@@ -15212,7 +15201,8 @@ var MANAGEMENT_SECTIONS = [
15212
15201
  description: "Logo, name and theme for this workspace.",
15213
15202
  keywords: ["theme", "logo", "colors", "appearance", "change theme"],
15214
15203
  requiresAdmin: true,
15215
- requiresFeature: "limitedAdminDashboard"
15204
+ requiresFeature: "limitedAdminDashboard",
15205
+ group: "workspace"
15216
15206
  },
15217
15207
  {
15218
15208
  id: "schedules",
@@ -15220,7 +15210,8 @@ var MANAGEMENT_SECTIONS = [
15220
15210
  description: "Prompts Bandit runs for you on a schedule, with results in chat and by email.",
15221
15211
  keywords: ["scheduled tasks", "recurring", "cron", "daily", "weekly", "automation", "email", "reminder"],
15222
15212
  requiresAdmin: false,
15223
- requiresFeature: "limitedAdminDashboard"
15213
+ requiresFeature: "limitedAdminDashboard",
15214
+ group: "you"
15224
15215
  },
15225
15216
  {
15226
15217
  id: "preferences",
@@ -15228,10 +15219,52 @@ var MANAGEMENT_SECTIONS = [
15228
15219
  description: "Your own settings for this device. Changes save automatically.",
15229
15220
  keywords: ["settings", "memory", "voice", "features"],
15230
15221
  requiresAdmin: false,
15231
- requiresFeature: "limitedAdminDashboard"
15222
+ requiresFeature: "limitedAdminDashboard",
15223
+ group: "you"
15232
15224
  }
15233
15225
  ];
15234
15226
  var sectionById = (id) => MANAGEMENT_SECTIONS.find((s) => s.id === id) ?? MANAGEMENT_SECTIONS[0];
15227
+ var WEB_PRESENTATION = {
15228
+ personalities: {
15229
+ description: "Named assistants, each with its own instructions and avatar. The active one answers new chats."
15230
+ },
15231
+ tools: {
15232
+ label: "Tools & integrations",
15233
+ description: "Connected MCP servers, your Bandit Crew, and the built-in capabilities Bandit may use.",
15234
+ keywords: ["mcp", "integrations", "servers", "functions", "crew", "tools"]
15235
+ },
15236
+ provider: {
15237
+ description: "The model service chat requests go to. Gateway is the default; OpenAI, Ollama and others are options."
15238
+ },
15239
+ storage: {
15240
+ label: "Local data",
15241
+ description: "What this browser stores for Bandit, and how to clear it.",
15242
+ keywords: ["indexeddb", "cache", "clear", "data", "storage", "local data"]
15243
+ },
15244
+ branding: {
15245
+ label: "Appearance",
15246
+ description: "Name, logo, accent colour and light or dark mode for this workspace.",
15247
+ keywords: ["theme", "logo", "colors", "appearance", "branding", "change theme"]
15248
+ },
15249
+ preferences: {
15250
+ description: "Your settings on this device: conversation starters, memory, voice and sync. Changes save automatically."
15251
+ }
15252
+ };
15253
+ var WEB_ORDER = [
15254
+ "overview",
15255
+ "preferences",
15256
+ "schedules",
15257
+ "personalities",
15258
+ "knowledge",
15259
+ "tools",
15260
+ "branding",
15261
+ "provider",
15262
+ "storage"
15263
+ ];
15264
+ function presentManagementSections(sections, variant) {
15265
+ if (variant === "native") return [...sections];
15266
+ return sections.map((section) => ({ ...section, ...WEB_PRESENTATION[section.id] })).sort((a, b) => WEB_ORDER.indexOf(a.id) - WEB_ORDER.indexOf(b.id));
15267
+ }
15235
15268
  function isWorkspaceAdminRole(roles) {
15236
15269
  const platformAdminRoles = /* @__PURE__ */ new Set(["admin", "platform_admin"]);
15237
15270
  return roles.map((r) => r.toLowerCase()).some((r) => platformAdminRoles.has(r) || r.endsWith("-admin"));
@@ -15256,12 +15289,15 @@ function useManagementAccess() {
15256
15289
  return useMemo7(() => {
15257
15290
  const roles = (token ? authenticationService.parseJwtClaims(token)?.roles : void 0) ?? [];
15258
15291
  return {
15259
- sections: resolveManagementSections({
15260
- roles,
15261
- limitedAdminDashboard: limited,
15262
- adminDashboard: full,
15263
- advancedSearch: advanced
15264
- }),
15292
+ sections: presentManagementSections(
15293
+ resolveManagementSections({
15294
+ roles,
15295
+ limitedAdminDashboard: limited,
15296
+ adminDashboard: full,
15297
+ advancedSearch: advanced
15298
+ }),
15299
+ managementConsoleVariant()
15300
+ ),
15265
15301
  isWorkspaceAdmin: isWorkspaceAdminRole(roles),
15266
15302
  isLimitedAdmin: limited && !full
15267
15303
  };
@@ -15270,8 +15306,8 @@ function useManagementAccess() {
15270
15306
 
15271
15307
  // src/management/management.tsx
15272
15308
  import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
15273
- var preloadChatPage = () => import("./chat-Y7KPN54G.mjs");
15274
- var SchedulesTab = lazy(() => import("./SchedulesTab-TCUOAKLH.mjs"));
15309
+ var preloadChatPage = () => import("./chat-MI4IL3WK.mjs");
15310
+ var SchedulesTab = lazy(() => import("./SchedulesTab-AKJ6WFZV.mjs"));
15275
15311
  var buildCapabilitiesUrl = (gatewayApiUrl) => {
15276
15312
  const trimmed = gatewayApiUrl.replace(/\/$/, "");
15277
15313
  if (trimmed.endsWith("/api")) {
@@ -15293,6 +15329,9 @@ var Management = ({
15293
15329
  const navigate = useNavigate2();
15294
15330
  const notificationService2 = useNotificationService();
15295
15331
  const isMobile = useMediaQuery7("(max-width:900px)");
15332
+ const consoleVariant = managementConsoleVariant();
15333
+ const webConsole = consoleVariant === "web";
15334
+ const showAssistantFab = !isMobile && !webConsole;
15296
15335
  const getOptimalFabLogo = async () => {
15297
15336
  const banditHead4 = "https://cdn.burtson.ai/images/bandit-head.png";
15298
15337
  try {
@@ -15318,16 +15357,12 @@ var Management = ({
15318
15357
  }
15319
15358
  };
15320
15359
  const {
15321
- name: modelName,
15322
15360
  setModelName,
15323
- tagline,
15324
15361
  setTagline,
15325
- systemPrompt,
15326
15362
  setSystemPrompt,
15327
15363
  availableModels,
15328
15364
  selectedModel,
15329
15365
  setSelectedModel,
15330
- saveModel,
15331
15366
  resetModel,
15332
15367
  hasTransparentLogo,
15333
15368
  setHasTransparentLogo
@@ -15335,7 +15370,7 @@ var Management = ({
15335
15370
  const [modalOpen, setModalOpen] = useState24(false);
15336
15371
  const banditHead3 = "https://cdn.burtson.ai/images/bandit-head.png";
15337
15372
  const [fabLogo, setFabLogo] = useState24(banditHead3);
15338
- const [logoFile, setLogoFile] = useState24(null);
15373
+ const [, setLogoFile] = useState24(null);
15339
15374
  const [logoBase64, setLogoBase64] = useState24(null);
15340
15375
  const [brandingText, setBrandingText] = useState24("");
15341
15376
  const [headerMode, setHeaderMode] = useState24("logo");
@@ -15524,15 +15559,13 @@ var Management = ({
15524
15559
  const handleOpenModal = () => setModalOpen(true);
15525
15560
  const handleCloseModal = () => setModalOpen(false);
15526
15561
  useEffect21(() => {
15527
- getOptimalFabLogo().then(setFabLogo);
15528
- }, []);
15529
- useEffect21(() => {
15562
+ if (!showAssistantFab) return;
15530
15563
  if (logoBase64) {
15531
15564
  setFabLogo(logoBase64);
15532
15565
  } else {
15533
15566
  getOptimalFabLogo().then(setFabLogo);
15534
15567
  }
15535
- }, [logoBase64]);
15568
+ }, [logoBase64, showAssistantFab]);
15536
15569
  const handleSaveModel = async () => {
15537
15570
  debugLogger.info("STARTING handleSaveModel", {
15538
15571
  modelName: localSelectedModel.name,
@@ -15831,7 +15864,7 @@ var Management = ({
15831
15864
  setLogoFile(null);
15832
15865
  setCustomAvatarBase64(null);
15833
15866
  setPresetAvatar(null);
15834
- getOptimalFabLogo().then(setFabLogo);
15867
+ if (showAssistantFab) getOptimalFabLogo().then(setFabLogo);
15835
15868
  try {
15836
15869
  const storeConfigs = [{ name: "config", keyPath: "id" }];
15837
15870
  const current = await indexedDBService_default.get(
@@ -15961,19 +15994,12 @@ var Management = ({
15961
15994
  debugLogger.error("Failed to restore default models and config", { error: err });
15962
15995
  }
15963
15996
  };
15964
- const restoreBanditModels = async () => {
15965
- try {
15966
- debugLogger.info("Restoring deleted Bandit models");
15967
- await useModelStore.getState().restoreDeletedBanditModels();
15968
- debugLogger.info("\u2705 Bandit models restored successfully");
15969
- } catch (err) {
15970
- debugLogger.error("Failed to restore Bandit models", { error: err });
15971
- }
15972
- };
15973
15997
  const handleImportConfig = (event) => {
15974
- if (event.target.files && event.target.files[0]) {
15975
- const file = event.target.files[0];
15998
+ const file = event.target.files?.[0];
15999
+ if (!file) return Promise.resolve();
16000
+ return new Promise((resolve, reject) => {
15976
16001
  const reader = new FileReader();
16002
+ reader.onerror = () => reject(reader.error ?? new Error("Could not read the file"));
15977
16003
  reader.onload = async function(e) {
15978
16004
  try {
15979
16005
  const data = JSON.parse(e.target?.result);
@@ -15982,7 +16008,7 @@ var Management = ({
15982
16008
  setHeaderMode(
15983
16009
  data.branding.headerMode || "logo"
15984
16010
  );
15985
- setTheme(data.branding.theme || "Dark");
16011
+ setTheme(data.branding.theme || "bandit-dark");
15986
16012
  setLogoBase64(data.branding.logoBase64 || null);
15987
16013
  setLogoFile(null);
15988
16014
  if (data.branding.hasTransparentLogo !== void 0) {
@@ -15996,21 +16022,21 @@ var Management = ({
15996
16022
  continue;
15997
16023
  }
15998
16024
  const parsedModel = model;
15999
- const modelName2 = typeof parsedModel.name === "string" ? parsedModel.name : "";
16000
- if (!modelName2) {
16025
+ const modelName = typeof parsedModel.name === "string" ? parsedModel.name : "";
16026
+ if (!modelName) {
16001
16027
  continue;
16002
16028
  }
16003
16029
  const sanitizedModel = {
16004
- name: modelName2,
16030
+ name: modelName,
16005
16031
  tagline: typeof parsedModel.tagline === "string" ? parsedModel.tagline : void 0,
16006
16032
  systemPrompt: typeof parsedModel.systemPrompt === "string" ? parsedModel.systemPrompt : void 0,
16007
16033
  selectedModel: typeof parsedModel.selectedModel === "string" ? parsedModel.selectedModel : void 0,
16008
16034
  avatarBase64: typeof parsedModel.avatarBase64 === "string" ? parsedModel.avatarBase64 : parsedModel.avatarBase64 === null ? void 0 : void 0
16009
16035
  };
16010
16036
  const entry = {
16011
- id: modelName2,
16037
+ id: modelName,
16012
16038
  model: sanitizedModel,
16013
- name: modelName2,
16039
+ name: modelName,
16014
16040
  tagline: sanitizedModel.tagline,
16015
16041
  systemPrompt: sanitizedModel.systemPrompt,
16016
16042
  // Normalize to match StoredBanditConfigRecord (string | undefined)
@@ -16064,12 +16090,14 @@ var Management = ({
16064
16090
  if (typeof initModels === "function") {
16065
16091
  await initModels();
16066
16092
  }
16093
+ resolve();
16067
16094
  } catch (e2) {
16068
16095
  debugLogger.error("Failed to import config", { error: e2 });
16096
+ reject(e2 instanceof Error ? e2 : new Error(String(e2)));
16069
16097
  }
16070
16098
  };
16071
16099
  reader.readAsText(file);
16072
- }
16100
+ });
16073
16101
  };
16074
16102
  useEffect21(() => {
16075
16103
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
@@ -16134,8 +16162,11 @@ var Management = ({
16134
16162
  }, [currentTheme, onThemeChange]);
16135
16163
  const access = useManagementAccess();
16136
16164
  const sections = useMemo8(
16137
- () => sectionOverride ? MANAGEMENT_SECTIONS.filter((s) => sectionOverride.includes(s.id)) : access.sections,
16138
- [sectionOverride, access.sections]
16165
+ () => sectionOverride ? presentManagementSections(
16166
+ MANAGEMENT_SECTIONS.filter((s) => sectionOverride.includes(s.id)),
16167
+ consoleVariant
16168
+ ) : access.sections,
16169
+ [sectionOverride, access.sections, consoleVariant]
16139
16170
  );
16140
16171
  const defaultSection = sections.some((s) => s.id === "overview") ? "overview" : sections.some((s) => s.id === "preferences") ? "preferences" : sections[0]?.id ?? "preferences";
16141
16172
  const [ownSection, setOwnSection] = useState24(null);
@@ -16148,7 +16179,7 @@ var Management = ({
16148
16179
  },
16149
16180
  [onSectionChange]
16150
16181
  );
16151
- const activeDef = sectionById(active);
16182
+ const activeDef = sections.find((s) => s.id === active) ?? sectionById(active);
16152
16183
  const [createPersonalityRequest, setCreatePersonalityRequest] = useState24(0);
16153
16184
  const [pendingUpload, setPendingUpload] = useState24(0);
16154
16185
  useEffect21(() => {
@@ -16255,6 +16286,7 @@ var Management = ({
16255
16286
  onBackToChat: () => navigate(chatPath),
16256
16287
  onBackHover: preloadChatPage,
16257
16288
  onOpenCommandPalette,
16289
+ grouped: webConsole,
16258
16290
  isMobile,
16259
16291
  children: /* @__PURE__ */ jsx25(SectionSkeleton, {})
16260
16292
  }
@@ -16273,6 +16305,7 @@ var Management = ({
16273
16305
  onBackToChat: () => navigate(chatPath),
16274
16306
  onBackHover: preloadChatPage,
16275
16307
  onOpenCommandPalette,
16308
+ grouped: webConsole,
16276
16309
  isMobile,
16277
16310
  children: [
16278
16311
  notice,
@@ -16331,15 +16364,14 @@ var Management = ({
16331
16364
  handleSaveModel,
16332
16365
  handleResetModel,
16333
16366
  restoreDefaultModelsAndConfig,
16334
- restoreBanditModels,
16335
16367
  showSnackbar: showSnackbarMessage,
16336
- createRequest: createPersonalityRequest
16368
+ createRequest: createPersonalityRequest,
16369
+ webConsole
16337
16370
  }
16338
16371
  ),
16339
16372
  active === "branding" && /* @__PURE__ */ jsx25(
16340
16373
  BrandingTab_default,
16341
16374
  {
16342
- logoFile,
16343
16375
  logoBase64,
16344
16376
  brandingText,
16345
16377
  setBrandingText,
@@ -16347,16 +16379,10 @@ var Management = ({
16347
16379
  setHeaderMode,
16348
16380
  theme,
16349
16381
  setTheme,
16350
- predefinedThemes,
16351
16382
  handleLogoUpload,
16352
16383
  handleRestoreDefaults,
16353
16384
  handleExportConfig,
16354
16385
  handleImportConfig,
16355
- handleSaveBranding: async () => {
16356
- const ok = await handleSaveBranding();
16357
- if (ok) setBrandingBaseline(brandingValue);
16358
- return ok;
16359
- },
16360
16386
  setLogoFile,
16361
16387
  setLogoBase64
16362
16388
  }
@@ -16369,12 +16395,10 @@ var Management = ({
16369
16395
  removeDocument,
16370
16396
  loadDocuments,
16371
16397
  clearAllDocuments,
16372
- currentTheme,
16373
- isLimitedAdmin: access.isLimitedAdmin,
16374
16398
  seedPacksEnabled
16375
16399
  }
16376
16400
  ),
16377
- active === "storage" && /* @__PURE__ */ jsx25(StorageTab_default, { currentTheme }),
16401
+ active === "storage" && /* @__PURE__ */ jsx25(StorageTab_default, {}),
16378
16402
  active === "preferences" && /* @__PURE__ */ jsx25(
16379
16403
  PreferencesTab_default,
16380
16404
  {
@@ -16382,7 +16406,8 @@ var Management = ({
16382
16406
  updatePreference,
16383
16407
  packageSettings,
16384
16408
  handleSavePreferences,
16385
- showSnackbar: showSnackbarMessage
16409
+ showSnackbar: showSnackbarMessage,
16410
+ showDiagnostics: !webConsole
16386
16411
  }
16387
16412
  ),
16388
16413
  active === "provider" && /* @__PURE__ */ jsx25(ProviderTab, {}),
@@ -16418,7 +16443,7 @@ var Management = ({
16418
16443
  ]
16419
16444
  }
16420
16445
  ),
16421
- !isMobile && /* @__PURE__ */ jsx25(
16446
+ showAssistantFab && /* @__PURE__ */ jsx25(
16422
16447
  Fab2,
16423
16448
  {
16424
16449
  "aria-label": "Ask the assistant",
@@ -16440,7 +16465,7 @@ var Management = ({
16440
16465
  )
16441
16466
  }
16442
16467
  ),
16443
- !isMobile && /* @__PURE__ */ jsx25(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
16468
+ showAssistantFab && /* @__PURE__ */ jsx25(chat_modal_default, { open: modalOpen, onClose: handleCloseModal })
16444
16469
  ] });
16445
16470
  };
16446
16471
  var management_default = Management;