@burtson-labs/bandit-engine 2.0.42 → 2.0.49

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 (54) hide show
  1. package/README.md +7 -5
  2. package/dist/{aiProviderStore-UQI33C5E.mjs → aiProviderStore-3N3VE6D4.mjs} +2 -2
  3. package/dist/chat-647M6BRG.mjs +15 -0
  4. package/dist/chat-provider.js +45 -10
  5. package/dist/chat-provider.js.map +1 -1
  6. package/dist/chat-provider.mjs +6 -6
  7. package/dist/{chunk-UXE67LR7.mjs → chunk-6WZUQHZT.mjs} +11 -7
  8. package/dist/chunk-6WZUQHZT.mjs.map +1 -0
  9. package/dist/{chunk-EOEI74X4.mjs → chunk-7HXARU5R.mjs} +101 -37
  10. package/dist/chunk-7HXARU5R.mjs.map +1 -0
  11. package/dist/{chunk-XUBYA5I7.mjs → chunk-7ZDS33S2.mjs} +34 -6
  12. package/dist/chunk-7ZDS33S2.mjs.map +1 -0
  13. package/dist/{chunk-SBNENBUQ.mjs → chunk-AXFX2HUK.mjs} +12 -12
  14. package/dist/{chunk-SBNENBUQ.mjs.map → chunk-AXFX2HUK.mjs.map} +1 -1
  15. package/dist/{chunk-54ZQ3FSN.mjs → chunk-BENL3EF2.mjs} +7 -4
  16. package/dist/chunk-BENL3EF2.mjs.map +1 -0
  17. package/dist/{chunk-RTQDQ6TC.mjs → chunk-EHNWQ4T3.mjs} +2 -2
  18. package/dist/{chunk-KBKWVG7X.mjs → chunk-HKJTRBWC.mjs} +5 -5
  19. package/dist/{chunk-4RCAVVDN.mjs → chunk-JCLL7AGP.mjs} +63 -45
  20. package/dist/chunk-JCLL7AGP.mjs.map +1 -0
  21. package/dist/{chunk-ERV7GLY3.mjs → chunk-TVF45U7B.mjs} +5 -5
  22. package/dist/{chunk-H4PBQ5LJ.mjs → chunk-VL3CMSDO.mjs} +4 -4
  23. package/dist/cli.js +45 -45
  24. package/dist/cli.js.map +1 -1
  25. package/dist/{gateway-5yt_3QDP.d.mts → gateway-oScD5tvE.d.mts} +4 -3
  26. package/dist/{gateway-5yt_3QDP.d.ts → gateway-oScD5tvE.d.ts} +4 -3
  27. package/dist/index.d.mts +2 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +199 -76
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +10 -10
  32. package/dist/management/management.js +199 -76
  33. package/dist/management/management.js.map +1 -1
  34. package/dist/management/management.mjs +8 -8
  35. package/dist/modals/chat-modal/chat-modal.js +53 -18
  36. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  37. package/dist/modals/chat-modal/chat-modal.mjs +5 -5
  38. package/dist/{modelStore-UMJBDSEF.mjs → modelStore-XWFHNTBT.mjs} +2 -2
  39. package/dist/public-types.d.mts +2 -1
  40. package/dist/public-types.d.ts +2 -1
  41. package/package.json +2 -2
  42. package/dist/chat-XDC4SNJF.mjs +0 -15
  43. package/dist/chunk-4RCAVVDN.mjs.map +0 -1
  44. package/dist/chunk-54ZQ3FSN.mjs.map +0 -1
  45. package/dist/chunk-EOEI74X4.mjs.map +0 -1
  46. package/dist/chunk-UXE67LR7.mjs.map +0 -1
  47. package/dist/chunk-XUBYA5I7.mjs.map +0 -1
  48. /package/dist/{aiProviderStore-UQI33C5E.mjs.map → aiProviderStore-3N3VE6D4.mjs.map} +0 -0
  49. /package/dist/{chat-XDC4SNJF.mjs.map → chat-647M6BRG.mjs.map} +0 -0
  50. /package/dist/{chunk-RTQDQ6TC.mjs.map → chunk-EHNWQ4T3.mjs.map} +0 -0
  51. /package/dist/{chunk-KBKWVG7X.mjs.map → chunk-HKJTRBWC.mjs.map} +0 -0
  52. /package/dist/{chunk-ERV7GLY3.mjs.map → chunk-TVF45U7B.mjs.map} +0 -0
  53. /package/dist/{chunk-H4PBQ5LJ.mjs.map → chunk-VL3CMSDO.mjs.map} +0 -0
  54. /package/dist/{modelStore-UMJBDSEF.mjs.map → modelStore-XWFHNTBT.mjs.map} +0 -0
@@ -1655,7 +1655,7 @@ var init_gateway_service = __esm({
1655
1655
  * Chat completion using the gateway API
1656
1656
  */
1657
1657
  chat(request) {
1658
- const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
1658
+ const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider === "playground" ? "/api/playground/chat/completions" : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
1659
1659
  const fallbackEndpoint = request.provider === "bandit" ? "/completions" : null;
1660
1660
  const normalizedModel = request.provider === "bandit" ? (() => {
1661
1661
  const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
@@ -2626,6 +2626,9 @@ var init_gateway_provider = __esm({
2626
2626
  case "ollama":
2627
2627
  this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);
2628
2628
  break;
2629
+ case "playground":
2630
+ this.providerSpecificService = null;
2631
+ break;
2629
2632
  default:
2630
2633
  debugLogger.warn("Unknown provider for gateway, using generic gateway service", {
2631
2634
  provider: this.config.provider
@@ -2656,7 +2659,7 @@ var init_gateway_provider = __esm({
2656
2659
  images: request.images
2657
2660
  };
2658
2661
  }
2659
- } else if (["openai", "azure-openai", "anthropic", "bandit"].includes(this.config.provider || "")) {
2662
+ } else if (["openai", "azure-openai", "anthropic", "bandit", "playground"].includes(this.config.provider || "")) {
2660
2663
  if (lastUserMessageIndex !== -1) {
2661
2664
  const currentMessage = messages[lastUserMessageIndex];
2662
2665
  const contentArray = [
@@ -2703,7 +2706,7 @@ var init_gateway_provider = __esm({
2703
2706
  stream: request.stream,
2704
2707
  hasImages: !!(request.images && request.images.length > 0),
2705
2708
  imageCount: request.images?.length || 0,
2706
- imageStrategy: this.config.provider === "ollama" ? "message-level-array" : ["openai", "azure-openai", "anthropic"].includes(this.config.provider || "") ? "structured-content" : "top-level-fallback",
2709
+ imageStrategy: this.config.provider === "ollama" ? "message-level-array" : ["openai", "azure-openai", "anthropic", "playground"].includes(this.config.provider || "") ? "structured-content" : "top-level-fallback",
2707
2710
  finalMessages: messages.map((m) => ({
2708
2711
  role: m.role,
2709
2712
  hasImages: Array.isArray(m.images) && m.images.length > 0,
@@ -6820,6 +6823,27 @@ var init_modelStore = __esm({
6820
6823
  });
6821
6824
  }
6822
6825
  }
6826
+ (async () => {
6827
+ const storeConfigs6 = [{ name: "config", keyPath: "id" }];
6828
+ try {
6829
+ const existing = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs6);
6830
+ await indexedDBService_default.put(
6831
+ "banditConfig",
6832
+ 1,
6833
+ "config",
6834
+ {
6835
+ ...existing,
6836
+ id: "main",
6837
+ model: { ...existing?.model ?? {}, selectedModel: modelName }
6838
+ },
6839
+ storeConfigs6
6840
+ );
6841
+ } catch (err) {
6842
+ debugLogger.warn("setSelectedModel: failed to persist selected model", {
6843
+ error: err instanceof Error ? err.message : String(err)
6844
+ });
6845
+ }
6846
+ })();
6823
6847
  },
6824
6848
  saveModel: async () => {
6825
6849
  const state = get();
@@ -6829,7 +6853,8 @@ var init_modelStore = __esm({
6829
6853
  tagline: state.tagline,
6830
6854
  systemPrompt: state.systemPrompt,
6831
6855
  commands: state.commands,
6832
- avatarBase64: state.avatarBase64 ?? void 0
6856
+ // Ensure avatar changes are persisted even when cleared
6857
+ avatarBase64: state.avatarBase64 ?? null
6833
6858
  };
6834
6859
  await indexedDBService_default.put("banditConfig", 1, "config", { id: newModel.name, model: newModel }, storeConfigs6);
6835
6860
  const exists = state.availableModels.find((m) => m.name === newModel.name);
@@ -6856,7 +6881,12 @@ var init_modelStore = __esm({
6856
6881
  debugLogger.info("initModels: starting initialization");
6857
6882
  set({ isLoading: true, isInitializing: true });
6858
6883
  const storeConfigs6 = [{ name: "config", keyPath: "id" }];
6859
- const entries = await indexedDBService_default.getAll("banditConfig", 1, "config", storeConfigs6);
6884
+ const entries = await indexedDBService_default.getAll(
6885
+ "banditConfig",
6886
+ 1,
6887
+ "config",
6888
+ storeConfigs6
6889
+ );
6860
6890
  const mainEntry = entries.find((entry) => entry.id === "main");
6861
6891
  const modelEntries = entries.filter((entry) => entry.id !== "main" && entry.id !== "deletedModels");
6862
6892
  const deletedEntry = await indexedDBService_default.get("banditConfig", 1, "config", "deletedModels", storeConfigs6);
@@ -6866,13 +6896,14 @@ var init_modelStore = __esm({
6866
6896
  if (modelEntries.length > 0) {
6867
6897
  debugLogger.info("Loading models from IndexedDB");
6868
6898
  allModels = modelEntries.map((entry) => {
6869
- const modelData = entry.model?.name ? entry.model : entry;
6899
+ const modelData = entry.model ?? entry;
6870
6900
  return {
6871
6901
  name: modelData.name,
6872
6902
  tagline: modelData.tagline || "",
6873
6903
  systemPrompt: modelData.systemPrompt || "",
6874
6904
  commands: modelData.commands ?? [],
6875
- avatarBase64: modelData.avatarBase64 ?? null
6905
+ // Fall back to legacy top-level avatar when the nested model config omitted it
6906
+ avatarBase64: modelData.avatarBase64 ?? entry.avatarBase64 ?? null
6876
6907
  };
6877
6908
  }).filter((m) => m.name && !deletedModelNames.includes(m.name));
6878
6909
  const preferences = usePreferencesStore.getState().preferences;
@@ -8072,6 +8103,9 @@ function ensureDeviceId() {
8072
8103
  return (0, import_uuid4.v4)();
8073
8104
  }
8074
8105
  }
8106
+ function getPackageDefaultAdvancedKnowledgeSync() {
8107
+ return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
8108
+ }
8075
8109
  function mapConversationToDTO(conversation) {
8076
8110
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
8077
8111
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -8418,7 +8452,8 @@ function applyPreference(preference, set, getState, options) {
8418
8452
  const override = options?.override ?? {};
8419
8453
  const preferenceVectorFlag = preference.isAdvancedVectorFeaturesEnabled;
8420
8454
  const overrideVectorFlag = override.isAdvancedVectorFeaturesEnabled;
8421
- const resolvedVectorFlag = preferenceVectorFlag !== void 0 ? preferenceVectorFlag : overrideVectorFlag !== void 0 ? overrideVectorFlag : current.isAdvancedVectorFeaturesEnabled ?? false;
8455
+ const packageDefaultVectorFlag = getPackageDefaultAdvancedKnowledgeSync();
8456
+ const resolvedVectorFlag = preferenceVectorFlag !== void 0 ? preferenceVectorFlag : overrideVectorFlag !== void 0 ? overrideVectorFlag : packageDefaultVectorFlag !== void 0 ? packageDefaultVectorFlag : current.isAdvancedVectorFeaturesEnabled ?? false;
8422
8457
  set({
8423
8458
  syncEnabled: preference.syncEnabled,
8424
8459
  status: preference.syncEnabled ? "idle" : "disabled",
@@ -8522,7 +8557,7 @@ var init_conversationSyncStore = __esm({
8522
8557
  cursor: null,
8523
8558
  lastError: null,
8524
8559
  keepLocalOnly: false,
8525
- isAdvancedVectorFeaturesEnabled: false,
8560
+ isAdvancedVectorFeaturesEnabled: getPackageDefaultAdvancedKnowledgeSync() ?? false,
8526
8561
  conflicts: null,
8527
8562
  deviceId: ensureDeviceId(),
8528
8563
  pendingConversationUpserts: /* @__PURE__ */ new Set(),
@@ -8646,7 +8681,7 @@ var init_conversationSyncStore = __esm({
8646
8681
  await get().runSync({ force: true });
8647
8682
  }
8648
8683
  } catch (error) {
8649
- const message = error instanceof Error ? error.message : "Failed to update advanced vector setting";
8684
+ const message = error instanceof Error ? error.message : "Failed to update advanced knowledge setting";
8650
8685
  debugLogger.error("conversationSyncStore: setAdvancedVectorFeaturesEnabled failed", { error: message });
8651
8686
  set({ status: "error", lastError: message });
8652
8687
  throw error;
@@ -13974,7 +14009,7 @@ var init_memory_modal = __esm({
13974
14009
  children: [
13975
14010
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material8.Box, { sx: { display: "flex", alignItems: "center", gap: 0.75 }, children: [
13976
14011
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Typography, { variant: "h6", sx: { fontWeight: 600 }, children: "Memory" }),
13977
- shouldUseVectorForMemories && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Tooltip, { title: "Memories are stored in an AI vector database with semantic search capabilities", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
14012
+ shouldUseVectorForMemories && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Tooltip, { title: "Memories stay in your private knowledge space for faster, more accurate answers.", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
13978
14013
  import_material8.Typography,
13979
14014
  {
13980
14015
  variant: "caption",
@@ -13989,7 +14024,7 @@ var init_memory_modal = __esm({
13989
14024
  textTransform: "uppercase",
13990
14025
  cursor: "help"
13991
14026
  },
13992
- children: "Vector"
14027
+ children: "Synced"
13993
14028
  }
13994
14029
  ) })
13995
14030
  ] }),
@@ -14088,7 +14123,7 @@ var init_memory_modal = __esm({
14088
14123
  onClick: () => setBulkImportOpen(true),
14089
14124
  startIcon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_CloudSync.default, {}),
14090
14125
  sx: { textTransform: "none", borderRadius: 2, fontSize: "0.75rem" },
14091
- children: "Import to Vector"
14126
+ children: "Import to workspace"
14092
14127
  }
14093
14128
  ),
14094
14129
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -14330,7 +14365,7 @@ var init_memory_modal = __esm({
14330
14365
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Typography, { variant: "body2", sx: {
14331
14366
  color: (0, import_styles3.alpha)(theme.palette.text.secondary, 0.7),
14332
14367
  maxWidth: 280
14333
- }, children: selectedTab === "user" ? shouldUseVectorForMemories ? "Start by adding something you'd like me to remember. Your memories will be stored in the AI vector database for intelligent retrieval." : "Start by adding something you'd like me to remember about you or your preferences." : shouldUseVectorForMemories ? "Auto memories are created automatically based on our conversations and stored in the vector database for semantic search." : "Auto memories are created automatically based on our conversations." })
14368
+ }, children: selectedTab === "user" ? shouldUseVectorForMemories ? "Start by adding something you'd like me to remember. Your memories will be kept in a private workspace for quick recall." : "Start by adding something you'd like me to remember about you or your preferences." : shouldUseVectorForMemories ? "Auto memories are created automatically based on our conversations and kept in your private workspace for better answers." : "Auto memories are created automatically based on our conversations." })
14334
14369
  ] }) : filteredMemories.map((memory) => {
14335
14370
  const isSelected = selectedIds.includes(memory.id);
14336
14371
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react14.default.Fragment, { children: [
@@ -14602,7 +14637,7 @@ var init_memory_modal = __esm({
14602
14637
  size: "small",
14603
14638
  value: newMemory,
14604
14639
  onChange: (e) => setNewMemory(e.target.value),
14605
- placeholder: shouldUseVectorForMemories ? `Add a new ${selectedTab} memory to vector database...` : `Add a new ${selectedTab} memory...`,
14640
+ placeholder: shouldUseVectorForMemories ? `Add a new ${selectedTab} memory to your workspace...` : `Add a new ${selectedTab} memory...`,
14606
14641
  onKeyDown: (e) => {
14607
14642
  if (e.key === "Enter" && !e.shiftKey && newMemory.trim()) {
14608
14643
  e.preventDefault();
@@ -14842,15 +14877,15 @@ var init_memory_modal = __esm({
14842
14877
  gap: 1
14843
14878
  }, children: [
14844
14879
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_CloudSync.default, { color: "primary" }),
14845
- "Import Memories to Vector Database"
14880
+ "Import Memories to Secure Workspace"
14846
14881
  ] }),
14847
14882
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.DialogContent, { sx: { py: 2 }, children: !importProgress.isImporting ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material8.Box, { children: [
14848
14883
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material8.Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: [
14849
14884
  "This will import all your local memories (",
14850
14885
  entries.length,
14851
- " memories) to the vector database for enhanced semantic search capabilities."
14886
+ " memories) to your secure workspace for faster, more reliable answers."
14852
14887
  ] }),
14853
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: "\u2022 Memories will be added to your vector storage \u2022 Local memories will remain unchanged \u2022 You can switch between local and vector storage anytime" }),
14888
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material8.Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: "\u2022 Memories will be added to your synced workspace \u2022 Local memories will remain unchanged \u2022 You can switch between synced and local storage anytime" }),
14854
14889
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material8.Typography, { variant: "body2", color: "primary", sx: { fontWeight: 500 }, children: [
14855
14890
  "Ready to import ",
14856
14891
  entries.length,
@@ -19168,6 +19203,7 @@ var init_custom_logo = __esm({
19168
19203
  init_chat();
19169
19204
  init_brandingService();
19170
19205
  init_debugLogger();
19206
+ init_util();
19171
19207
  import_jsx_runtime26 = require("react/jsx-runtime");
19172
19208
  Logo = ({ visible, atTop = false }) => {
19173
19209
  const theme = (0, import_styles19.useTheme)();
@@ -19181,7 +19217,20 @@ var init_custom_logo = __esm({
19181
19217
  const brandingData = await brandingService_default.getBranding();
19182
19218
  if (brandingData) {
19183
19219
  setLogoBase64(brandingData.logoBase64 || null);
19184
- setHasTransparentLogo(brandingData.hasTransparentLogo ?? true);
19220
+ if (brandingData.logoBase64) {
19221
+ try {
19222
+ const detected = await detectTransparency(brandingData.logoBase64);
19223
+ const isPng = brandingData.logoBase64.startsWith("data:image/png");
19224
+ const finalTransparent = detected || isPng || brandingData.hasTransparentLogo === true;
19225
+ setHasTransparentLogo(finalTransparent);
19226
+ } catch {
19227
+ const isPng = brandingData.logoBase64.startsWith("data:image/png");
19228
+ const finalTransparent = brandingData.hasTransparentLogo === true || isPng;
19229
+ setHasTransparentLogo(finalTransparent);
19230
+ }
19231
+ } else {
19232
+ setHasTransparentLogo(brandingData.hasTransparentLogo ?? true);
19233
+ }
19185
19234
  }
19186
19235
  } catch (e) {
19187
19236
  debugLogger.error("Failed to load branding from service", { error: e });
@@ -19191,7 +19240,7 @@ var init_custom_logo = __esm({
19191
19240
  };
19192
19241
  loadBranding();
19193
19242
  }, []);
19194
- return logoBase64 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_jsx_runtime26.Fragment, { children: loading ? null : hasTransparentLogo ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
19243
+ return logoBase64 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_jsx_runtime26.Fragment, { children: loading ? null : hasTransparentLogo !== false ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
19195
19244
  import_material27.Box,
19196
19245
  {
19197
19246
  component: "img",
@@ -19203,7 +19252,8 @@ var init_custom_logo = __esm({
19203
19252
  maxWidth: 600,
19204
19253
  aspectRatio: "1 / 1",
19205
19254
  margin: "0 auto",
19206
- mt: atTop ? 2 : 6
19255
+ mt: atTop ? 2 : 6,
19256
+ display: "block"
19207
19257
  }
19208
19258
  }
19209
19259
  ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
@@ -19245,8 +19295,8 @@ var init_chat_scroll_to_bottom_button = __esm({
19245
19295
  drawerOpen = false,
19246
19296
  isMobile = false
19247
19297
  }) => {
19248
- const verticalBuffer = isMobile ? 36 : 56;
19249
- const bottomOffset = Math.max(inputHeight + verticalBuffer, verticalBuffer + 72);
19298
+ const verticalBuffer = isMobile ? 28 : 48;
19299
+ const bottomOffset = Math.max(inputHeight + verticalBuffer, verticalBuffer + 64);
19250
19300
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
19251
19301
  import_material28.IconButton,
19252
19302
  {
@@ -19262,9 +19312,12 @@ var init_chat_scroll_to_bottom_button = __esm({
19262
19312
  borderColor: (theme) => theme.palette.divider,
19263
19313
  zIndex: (theme) => Math.max(theme.zIndex.modal + 1, 1400),
19264
19314
  boxShadow: 3,
19265
- transition: "bottom 0.3s ease, left 0.3s ease-in-out",
19315
+ transition: "bottom 0.25s ease, left 0.3s ease-in-out, transform 0.2s ease",
19266
19316
  "&:hover": {
19267
19317
  bgcolor: (theme) => theme.palette.action.hover
19318
+ },
19319
+ "&:active": {
19320
+ transform: "translateX(-50%) translateY(1px)"
19268
19321
  }
19269
19322
  },
19270
19323
  children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ArrowDownward.default, { sx: { color: "inherit" } })
@@ -24529,6 +24582,24 @@ var init_project_header = __esm({
24529
24582
  }
24530
24583
  });
24531
24584
 
24585
+ // src/config/tooltips.ts
24586
+ var TOOLTIP_COPY, tooltip;
24587
+ var init_tooltips = __esm({
24588
+ "src/config/tooltips.ts"() {
24589
+ "use strict";
24590
+ TOOLTIP_COPY = {
24591
+ openNavigation: "Open navigation",
24592
+ closeNavigation: "Close navigation",
24593
+ manageProjects: "Manage projects",
24594
+ conversationOptions: "Open conversation options",
24595
+ closeConversationsPanel: "Close conversations panel",
24596
+ clearSearch: "Clear search",
24597
+ addProject: "Add new project"
24598
+ };
24599
+ tooltip = (key) => TOOLTIP_COPY[key];
24600
+ }
24601
+ });
24602
+
24532
24603
  // src/chat/conversation-drawer.tsx
24533
24604
  var import_react48, import_material37, import_icons_material9, import_icons_material10, import_styles27, import_jsx_runtime37, BANDIT_AVATAR, coerceOptionalString, deriveInitials, ConversationDrawer, conversation_drawer_default;
24534
24605
  var init_conversation_drawer = __esm({
@@ -24548,6 +24619,7 @@ var init_conversation_drawer = __esm({
24548
24619
  init_simple_conversation_item();
24549
24620
  init_project_header();
24550
24621
  init_debugLogger();
24622
+ init_tooltips();
24551
24623
  import_jsx_runtime37 = require("react/jsx-runtime");
24552
24624
  BANDIT_AVATAR = "https://cdn.burtson.ai/images/bandit-head.png";
24553
24625
  coerceOptionalString = (value) => {
@@ -24824,11 +24896,12 @@ var init_conversation_drawer = __esm({
24824
24896
  gap: 1
24825
24897
  },
24826
24898
  children: [
24827
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24899
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.Tooltip, { title: tooltip("manageProjects"), arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24828
24900
  import_material37.IconButton,
24829
24901
  {
24830
24902
  onClick: () => setProjectManagementOpen(true),
24831
24903
  size: "small",
24904
+ "aria-label": tooltip("manageProjects"),
24832
24905
  sx: {
24833
24906
  color: theme.palette.text.secondary,
24834
24907
  "&:hover": {
@@ -24838,12 +24911,13 @@ var init_conversation_drawer = __esm({
24838
24911
  },
24839
24912
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material9.Folder, {})
24840
24913
  }
24841
- ),
24842
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24914
+ ) }),
24915
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.Tooltip, { title: tooltip("conversationOptions"), arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24843
24916
  import_material37.IconButton,
24844
24917
  {
24845
24918
  onClick: handleMenuOpen,
24846
24919
  size: "small",
24920
+ "aria-label": tooltip("conversationOptions"),
24847
24921
  sx: {
24848
24922
  color: theme.palette.text.secondary,
24849
24923
  "&:hover": {
@@ -24853,8 +24927,8 @@ var init_conversation_drawer = __esm({
24853
24927
  },
24854
24928
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material9.MoreVert, {})
24855
24929
  }
24856
- ),
24857
- isMobile && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24930
+ ) }),
24931
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.Tooltip, { title: tooltip("closeConversationsPanel"), children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24858
24932
  import_material37.IconButton,
24859
24933
  {
24860
24934
  onClick: (e) => {
@@ -24863,6 +24937,7 @@ var init_conversation_drawer = __esm({
24863
24937
  onClose();
24864
24938
  },
24865
24939
  size: "small",
24940
+ "aria-label": tooltip("closeConversationsPanel"),
24866
24941
  sx: {
24867
24942
  color: theme.palette.text.secondary,
24868
24943
  "&:hover": {
@@ -24872,7 +24947,7 @@ var init_conversation_drawer = __esm({
24872
24947
  },
24873
24948
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material9.Close, {})
24874
24949
  }
24875
- )
24950
+ ) })
24876
24951
  ]
24877
24952
  }
24878
24953
  ),
@@ -24887,16 +24962,17 @@ var init_conversation_drawer = __esm({
24887
24962
  variant: "outlined",
24888
24963
  InputProps: {
24889
24964
  startAdornment: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.InputAdornment, { position: "start", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material9.Search, { fontSize: "small", sx: { color: theme.palette.text.secondary } }) }),
24890
- endAdornment: searchQuery && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.InputAdornment, { position: "end", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24965
+ endAdornment: searchQuery && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.InputAdornment, { position: "end", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.Tooltip, { title: tooltip("clearSearch"), children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
24891
24966
  import_material37.IconButton,
24892
24967
  {
24893
24968
  onClick: handleSearchClear,
24894
24969
  size: "small",
24895
24970
  edge: "end",
24971
+ "aria-label": tooltip("clearSearch"),
24896
24972
  sx: { color: theme.palette.text.secondary },
24897
24973
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material9.Clear, { fontSize: "small" })
24898
24974
  }
24899
- ) })
24975
+ ) }) })
24900
24976
  },
24901
24977
  sx: {
24902
24978
  "& .MuiOutlinedInput-root": {
@@ -24971,7 +25047,15 @@ var init_conversation_drawer = __esm({
24971
25047
  children: "New Project"
24972
25048
  }
24973
25049
  ),
24974
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.IconButton, { size: "small", sx: { color: theme.palette.success.main }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material10.Add, { fontSize: "small" }) })
25050
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_material37.Tooltip, { title: tooltip("addProject"), arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
25051
+ import_material37.IconButton,
25052
+ {
25053
+ size: "small",
25054
+ "aria-label": tooltip("addProject"),
25055
+ sx: { color: theme.palette.success.main },
25056
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_icons_material10.Add, { fontSize: "small" })
25057
+ }
25058
+ ) })
24975
25059
  ]
24976
25060
  }
24977
25061
  ),
@@ -26410,9 +26494,18 @@ var init_chat_app_bar = __esm({
26410
26494
  const currentModel = useModelStore((s) => s.availableModels.find((m) => m.name === selectedModel));
26411
26495
  const currentAvatar = currentModel?.avatarBase64 || modelAvatars3[selectedModel] || banditHead5;
26412
26496
  const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars3[pendingModel || ""] || banditHead5;
26497
+ const resolvedHomeUrl = preferences.homeUrl?.trim() || packageSettings?.homeUrl?.trim() || "";
26498
+ const homeTooltip = (() => {
26499
+ if (!resolvedHomeUrl) return "Home";
26500
+ try {
26501
+ return `Home (${new URL(resolvedHomeUrl).hostname})`;
26502
+ } catch {
26503
+ return "Home";
26504
+ }
26505
+ })();
26413
26506
  function goToHome() {
26414
- if (preferences.homeUrl && preferences.homeUrl.trim()) {
26415
- window.location.href = preferences.homeUrl;
26507
+ if (resolvedHomeUrl) {
26508
+ window.location.href = resolvedHomeUrl;
26416
26509
  return;
26417
26510
  }
26418
26511
  if (typeof window !== "undefined") {
@@ -26475,7 +26568,7 @@ var init_chat_app_bar = __esm({
26475
26568
  }
26476
26569
  },
26477
26570
  children: [
26478
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material40.Tooltip, { title: preferences.homeUrl && preferences.homeUrl.trim() ? `Home (${new URL(preferences.homeUrl).hostname})` : "Home", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
26571
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_material40.Tooltip, { title: homeTooltip, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
26479
26572
  import_material40.IconButton,
26480
26573
  {
26481
26574
  onClick: goToHome,
@@ -26759,9 +26852,15 @@ var init_chat_app_bar = __esm({
26759
26852
  (async () => {
26760
26853
  try {
26761
26854
  const storeConfigs6 = [{ name: "config", keyPath: "id" }];
26762
- const current = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs6);
26855
+ const current = await indexedDBService_default.get(
26856
+ "banditConfig",
26857
+ 1,
26858
+ "config",
26859
+ "main",
26860
+ storeConfigs6
26861
+ );
26763
26862
  const updated = {
26764
- ...current,
26863
+ ...current ?? {},
26765
26864
  id: "main",
26766
26865
  model: {
26767
26866
  ...current?.model || {},
@@ -26953,9 +27052,15 @@ var init_chat_app_bar = __esm({
26953
27052
  (async () => {
26954
27053
  try {
26955
27054
  const storeConfigs6 = [{ name: "config", keyPath: "id" }];
26956
- const current = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs6);
27055
+ const current = await indexedDBService_default.get(
27056
+ "banditConfig",
27057
+ 1,
27058
+ "config",
27059
+ "main",
27060
+ storeConfigs6
27061
+ );
26957
27062
  const updated = {
26958
- ...current,
27063
+ ...current ?? {},
26959
27064
  id: "main",
26960
27065
  model: {
26961
27066
  ...current?.model || {},
@@ -33740,7 +33845,7 @@ var PreferencesTab = ({
33740
33845
  await setAdvancedVectorFeaturesEnabled(enabled);
33741
33846
  if (showSnackbar) {
33742
33847
  showSnackbar(
33743
- enabled ? "Advanced vector features enabled for this account." : "Advanced vector features disabled.",
33848
+ enabled ? "Advanced knowledge sync enabled for this account." : "Advanced knowledge sync disabled.",
33744
33849
  "success"
33745
33850
  );
33746
33851
  }
@@ -34025,8 +34130,8 @@ var PreferencesTab = ({
34025
34130
  }
34026
34131
  ),
34027
34132
  label: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material19.Box, { textAlign: "left", children: [
34028
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material19.Typography, { variant: "body1", sx: { fontWeight: 600, color: "text.primary" }, children: "Advanced vector features" }),
34029
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material19.Typography, { variant: "body2", color: "text.secondary", children: "Keep semantic search, vector memories, and related context in sync across devices" })
34133
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material19.Typography, { variant: "body1", sx: { fontWeight: 600, color: "text.primary" }, children: "Advanced knowledge sync" }),
34134
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material19.Typography, { variant: "body2", color: "text.secondary", children: "Keep richer search, saved memories, and context in sync across devices" })
34030
34135
  ] }),
34031
34136
  sx: { alignSelf: { xs: "flex-start", sm: "center" } }
34032
34137
  }
@@ -34596,6 +34701,7 @@ var LogoCropper = ({
34596
34701
  canvas.width = outputWidth;
34597
34702
  canvas.height = outputHeight;
34598
34703
  ctx.save();
34704
+ ctx.clearRect(0, 0, outputWidth, outputHeight);
34599
34705
  const scaleX = outputWidth / cropDims.width;
34600
34706
  const scaleY = outputHeight / cropDims.height;
34601
34707
  ctx.translate(outputWidth / 2, outputHeight / 2);
@@ -35636,30 +35742,29 @@ var defaultSteps = [
35636
35742
  },
35637
35743
  {
35638
35744
  id: "embed",
35639
- title: "Creating Vectors",
35640
- description: "Neural networks are encoding knowledge into searchable vectors...",
35745
+ title: "Making It Searchable",
35746
+ description: "We turn the content into a private, searchable index...",
35641
35747
  icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_icons_material4.Memory, {}),
35642
35748
  duration: 10
35643
35749
  },
35644
35750
  {
35645
35751
  id: "optimize",
35646
35752
  title: "Optimizing Search",
35647
- description: "AI algorithms are organizing data for lightning-fast retrieval...",
35753
+ description: "Organizing everything for quick, reliable answers...",
35648
35754
  icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_icons_material4.AutoAwesome, {}),
35649
35755
  duration: 8
35650
35756
  }
35651
35757
  ];
35652
35758
  var cleverMessages = [
35653
- "\u{1F977} Digital ninjas are working their magic...",
35654
- "\u{1F916} AI robots are crunching your data...",
35655
- "\u26A1 Neural networks firing at maximum capacity...",
35656
- "\u{1F9E0} Machine learning models deep in thought...",
35657
- "\u{1F52E} AI wizards casting knowledge spells...",
35658
- "\u2699\uFE0F Quantum processors spinning up...",
35659
- "\u{1F680} Algorithms achieving warp speed...",
35660
- "\u{1F4AB} Creating digital memories from your content...",
35661
- "\u{1F3AF} Precision-targeting knowledge patterns...",
35662
- "\u{1F31F} Transforming text into searchable stardust..."
35759
+ "\u{1F977} Keeping your content safe while we set things up...",
35760
+ "\u{1F916} Getting everything ready for fast answers...",
35761
+ "\u26A1 Tidying the data so responses stay consistent...",
35762
+ "\u{1F9E0} Remembering the important parts for you...",
35763
+ "\u{1F512} Locking in privacy before we share results...",
35764
+ "\u{1F680} Optimizing for quick, reliable lookups...",
35765
+ "\u{1F4AB} Turning this into searchable knowledge...",
35766
+ "\u{1F3AF} Focusing on the details that matter to you...",
35767
+ "\u{1F31F} Making sure it stays available when you need it..."
35663
35768
  ];
35664
35769
  var ProcessingOverlay = ({
35665
35770
  open,
@@ -36248,16 +36353,16 @@ var KnowledgeTab = ({
36248
36353
  const handleDocumentUpload = async (files) => {
36249
36354
  if (shouldUseVector) {
36250
36355
  showProcessing(
36251
- "Uploading to Vector Database",
36356
+ "Uploading to Secure Workspace",
36252
36357
  [
36253
- "\u{1F977} Digital ninjas securing your documents...",
36254
- "\u{1F916} AI robots reading and understanding content...",
36255
- "\u26A1 Neural networks encoding knowledge vectors...",
36256
- "\u{1F9E0} Machine learning creating searchable memories...",
36257
- "\u{1F52E} AI wizards optimizing semantic search...",
36258
- "\u{1F680} Vector embeddings achieving light speed...",
36259
- "\u{1F4AB} Transforming documents into intelligent data...",
36260
- "\u{1F3AF} Precision-targeting knowledge patterns..."
36358
+ "\u{1F977} Keeping your documents private while we prepare them...",
36359
+ "\u{1F916} Reading the content so answers stay accurate...",
36360
+ "\u26A1 Turning pages into a searchable index...",
36361
+ "\u{1F9E0} Remembering highlights for quick recall...",
36362
+ "\u{1F52E} Organizing everything so search feels instant...",
36363
+ "\u{1F680} Optimizing for fast, consistent responses...",
36364
+ "\u{1F4AB} Transforming documents into trusted knowledge...",
36365
+ "\u{1F3AF} Focusing on the details that matter most..."
36261
36366
  ]
36262
36367
  );
36263
36368
  try {
@@ -36331,7 +36436,7 @@ var KnowledgeTab = ({
36331
36436
  progress: 100,
36332
36437
  status: "success"
36333
36438
  })));
36334
- const message = result.usedVector ? `Successfully uploaded ${files.length} document(s) to vector database` : result.error ? `Upload completed with warnings: ${result.error}` : `Successfully uploaded ${files.length} document(s)`;
36439
+ const message = result.usedVector ? `Successfully uploaded ${files.length} document(s) to your secure workspace` : result.error ? `Upload completed with warnings: ${result.error}` : `Successfully uploaded ${files.length} document(s)`;
36335
36440
  setSnackbarMessage(message);
36336
36441
  setSnackbarSeverity(result.error ? "warning" : "success");
36337
36442
  setShowSnackbar(true);
@@ -36392,7 +36497,7 @@ var KnowledgeTab = ({
36392
36497
  progress: 100,
36393
36498
  status: "success"
36394
36499
  })));
36395
- const message = result.usedVector ? `Successfully uploaded ${files.length} document(s) to vector database` : result.error ? `Upload completed with warnings: ${result.error}` : `Successfully uploaded ${files.length} document(s)`;
36500
+ const message = result.usedVector ? `Successfully uploaded ${files.length} document(s) to your secure workspace` : result.error ? `Upload completed with warnings: ${result.error}` : `Successfully uploaded ${files.length} document(s)`;
36396
36501
  setSnackbarMessage(message);
36397
36502
  setSnackbarSeverity(result.error ? "warning" : "success");
36398
36503
  setShowSnackbar(true);
@@ -36570,7 +36675,7 @@ var KnowledgeTab = ({
36570
36675
  shouldUseVector && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
36571
36676
  import_material23.Chip,
36572
36677
  {
36573
- label: "Vector DB",
36678
+ label: "Synced",
36574
36679
  color: "primary",
36575
36680
  size: "small",
36576
36681
  sx: { ml: 1 }
@@ -36587,7 +36692,7 @@ var KnowledgeTab = ({
36587
36692
  sx: { fontSize: { xs: "0.95rem", sm: "1rem" }, lineHeight: 1.5 },
36588
36693
  children: [
36589
36694
  "Add documents to your private knowledge base. Files are securely stored ",
36590
- shouldUseVector ? "in the vector database" : "locally in your browser",
36695
+ shouldUseVector ? "in your private workspace" : "locally in your browser",
36591
36696
  "."
36592
36697
  ]
36593
36698
  }
@@ -36923,7 +37028,7 @@ var KnowledgeTab = ({
36923
37028
  filteredAndSortedDocuments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material23.Card, { sx: { textAlign: "center", py: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material23.CardContent, { children: [
36924
37029
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Folder.default, { sx: { fontSize: 64, color: "text.secondary", mb: 2 } }),
36925
37030
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material23.Typography, { variant: "h6", color: "text.secondary", gutterBottom: true, children: "No Documents Yet" }),
36926
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material23.Typography, { variant: "body2", color: "text.secondary", children: shouldUseVector ? "Upload and embed your first document to get started with advanced vector search" : "Upload your first document to get started" })
37031
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material23.Typography, { variant: "body2", color: "text.secondary", children: shouldUseVector ? "Upload and embed your first document to get started with advanced search" : "Upload your first document to get started" })
36927
37032
  ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material23.Box, { children: [
36928
37033
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material23.Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: [
36929
37034
  "Showing ",
@@ -36932,7 +37037,7 @@ var KnowledgeTab = ({
36932
37037
  shouldUseVector ? vectorDocuments.length : documents.length,
36933
37038
  " documents",
36934
37039
  searchQuery && ` for "${searchQuery}"`,
36935
- shouldUseVector && ` (Vector Database)`
37040
+ shouldUseVector && ` (Synced workspace)`
36936
37041
  ] }),
36937
37042
  viewMode === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
36938
37043
  import_material23.Box,
@@ -39719,6 +39824,7 @@ var Management = () => {
39719
39824
  name: modelToSave.name,
39720
39825
  tagline: modelToSave.tagline,
39721
39826
  systemPrompt: modelToSave.systemPrompt,
39827
+ avatarBase64: modelToSave.avatarBase64 || void 0,
39722
39828
  selectedModel: modelToSave.name
39723
39829
  }
39724
39830
  };
@@ -39771,6 +39877,19 @@ var Management = () => {
39771
39877
  try {
39772
39878
  const storeConfigs6 = [{ name: "config", keyPath: "id" }];
39773
39879
  debugLogger.info("Saving branding data to IndexedDB");
39880
+ let finalHasTransparentLogo = hasTransparentLogo;
39881
+ if (logoBase64) {
39882
+ try {
39883
+ const detected = await detectTransparency(logoBase64);
39884
+ const isPng = logoBase64.startsWith("data:image/png");
39885
+ finalHasTransparentLogo = detected || isPng;
39886
+ debugLogger.debug("SaveBranding transparency check", { detected, isPng, finalHasTransparentLogo });
39887
+ } catch (err) {
39888
+ const isPng = logoBase64.startsWith("data:image/png");
39889
+ finalHasTransparentLogo = finalHasTransparentLogo ?? isPng ?? true;
39890
+ debugLogger.warn("SaveBranding transparency check failed, using fallback", { error: err, finalHasTransparentLogo });
39891
+ }
39892
+ }
39774
39893
  const current = await indexedDBService_default.get(
39775
39894
  "banditConfig",
39776
39895
  1,
@@ -39786,7 +39905,7 @@ var Management = () => {
39786
39905
  logoBase64,
39787
39906
  brandingText,
39788
39907
  theme,
39789
- hasTransparentLogo,
39908
+ hasTransparentLogo: finalHasTransparentLogo,
39790
39909
  userSaved: true
39791
39910
  // Mark as user-saved to protect from CDN overrides
39792
39911
  }
@@ -39825,9 +39944,11 @@ var Management = () => {
39825
39944
  setLogoBase64(base64);
39826
39945
  debugLogger.debug("Starting transparency detection for uploaded image");
39827
39946
  try {
39947
+ const isPng = base64.startsWith("data:image/png");
39828
39948
  const isTransparent = await detectTransparency(base64);
39829
- setHasTransparentLogo(isTransparent);
39830
- debugLogger.debug("Transparency detection result saved", { isTransparent });
39949
+ const finalTransparent = isTransparent || isPng;
39950
+ setHasTransparentLogo(finalTransparent);
39951
+ debugLogger.debug("Transparency detection result saved", { isTransparent, finalTransparent });
39831
39952
  } catch (err) {
39832
39953
  debugLogger.error("Failed to detect transparency", { error: err });
39833
39954
  }
@@ -40040,7 +40161,8 @@ var Management = () => {
40040
40161
  name: modelName2,
40041
40162
  tagline: typeof parsedModel.tagline === "string" ? parsedModel.tagline : void 0,
40042
40163
  systemPrompt: typeof parsedModel.systemPrompt === "string" ? parsedModel.systemPrompt : void 0,
40043
- selectedModel: typeof parsedModel.selectedModel === "string" ? parsedModel.selectedModel : void 0
40164
+ selectedModel: typeof parsedModel.selectedModel === "string" ? parsedModel.selectedModel : void 0,
40165
+ avatarBase64: typeof parsedModel.avatarBase64 === "string" ? parsedModel.avatarBase64 : parsedModel.avatarBase64 === null ? void 0 : void 0
40044
40166
  };
40045
40167
  const entry = {
40046
40168
  id: modelName2,
@@ -40048,7 +40170,8 @@ var Management = () => {
40048
40170
  name: modelName2,
40049
40171
  tagline: sanitizedModel.tagline,
40050
40172
  systemPrompt: sanitizedModel.systemPrompt,
40051
- avatarBase64: typeof parsedModel.avatarBase64 === "string" ? parsedModel.avatarBase64 : void 0
40173
+ // Normalize to match StoredBanditConfigRecord (string | undefined)
40174
+ avatarBase64: sanitizedModel.avatarBase64 ?? void 0
40052
40175
  };
40053
40176
  await indexedDBService_default.put("banditConfig", 1, "config", entry, storeConfigs6);
40054
40177
  }