@burtson-labs/bandit-engine 2.0.168 → 2.1.1

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 (237) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +189 -31
  3. package/NOTICE +26 -0
  4. package/README.md +15 -59
  5. package/dist/aiProviderStore-42S3LW2J.mjs +8 -0
  6. package/dist/aiProviderStore-42S3LW2J.mjs.map +1 -0
  7. package/dist/chat-GDC4ZVCF.mjs +10 -0
  8. package/dist/chat-GDC4ZVCF.mjs.map +1 -0
  9. package/dist/{chunk-GRPTCHFN.mjs → chunk-5KC42IIR.mjs} +339 -155
  10. package/dist/chunk-5KC42IIR.mjs.map +1 -0
  11. package/dist/chunk-7QYA3PAF.mjs +29521 -0
  12. package/dist/chunk-7QYA3PAF.mjs.map +1 -0
  13. package/dist/{chunk-SZJB5FLZ.mjs → chunk-FCQN3LKT.mjs} +251 -77
  14. package/dist/chunk-FCQN3LKT.mjs.map +1 -0
  15. package/dist/{chunk-HNXPDIWC.mjs → chunk-NI7BKLC7.mjs} +1 -1
  16. package/dist/chunk-NI7BKLC7.mjs.map +1 -0
  17. package/dist/index.d.mts +63 -57
  18. package/dist/index.d.ts +63 -57
  19. package/dist/index.js +18053 -9606
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +16630 -142
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{memoryUtils-HGCYEUCD.mjs → memoryUtils-UBZ33DNA.mjs} +8 -3
  24. package/dist/memoryUtils-UBZ33DNA.mjs.map +1 -0
  25. package/dist/modelStore-SEC34WRM.mjs +8 -0
  26. package/dist/modelStore-SEC34WRM.mjs.map +1 -0
  27. package/dist/{public-DJa4Db00.d.mts → public-D8UsefSk.d.mts} +21 -8
  28. package/dist/{public-DJa4Db00.d.ts → public-D8UsefSk.d.ts} +21 -8
  29. package/dist/public-types.d.mts +1 -1
  30. package/dist/public-types.d.ts +1 -1
  31. package/docs/00_intro.md +2 -2
  32. package/docs/05_contributing.md +2 -2
  33. package/docs/06_licensing.md +18 -0
  34. package/docs/07_custom_tools.md +233 -0
  35. package/docs/README.md +2 -1
  36. package/package.json +23 -20
  37. package/dist/aiProviderStore-HY5G4QAK.mjs +0 -8
  38. package/dist/aiProviderStore-HY5G4QAK.mjs.map +0 -1
  39. package/dist/chat-7LOFYEWE.mjs +0 -15
  40. package/dist/chat-7LOFYEWE.mjs.map +0 -1
  41. package/dist/chat-provider.js +0 -11080
  42. package/dist/chat-provider.js.map +0 -1
  43. package/dist/chat-provider.mjs +0 -16
  44. package/dist/chat-provider.mjs.map +0 -1
  45. package/dist/chunk-4SXXEGEK.mjs +0 -10690
  46. package/dist/chunk-4SXXEGEK.mjs.map +0 -1
  47. package/dist/chunk-62IYSU3I.mjs +0 -7324
  48. package/dist/chunk-62IYSU3I.mjs.map +0 -1
  49. package/dist/chunk-CABOLDNR.mjs +0 -216
  50. package/dist/chunk-CABOLDNR.mjs.map +0 -1
  51. package/dist/chunk-E5WMDLE3.mjs +0 -390
  52. package/dist/chunk-E5WMDLE3.mjs.map +0 -1
  53. package/dist/chunk-GRPTCHFN.mjs.map +0 -1
  54. package/dist/chunk-HNXPDIWC.mjs.map +0 -1
  55. package/dist/chunk-JD6C64CT.mjs +0 -516
  56. package/dist/chunk-JD6C64CT.mjs.map +0 -1
  57. package/dist/chunk-KAXUI5H7.mjs +0 -6009
  58. package/dist/chunk-KAXUI5H7.mjs.map +0 -1
  59. package/dist/chunk-ONQMRE2G.mjs +0 -26
  60. package/dist/chunk-ONQMRE2G.mjs.map +0 -1
  61. package/dist/chunk-P4C5IRM5.mjs +0 -39
  62. package/dist/chunk-P4C5IRM5.mjs.map +0 -1
  63. package/dist/chunk-QI67R5F6.mjs +0 -194
  64. package/dist/chunk-QI67R5F6.mjs.map +0 -1
  65. package/dist/chunk-R3NOM2DG.mjs +0 -2945
  66. package/dist/chunk-R3NOM2DG.mjs.map +0 -1
  67. package/dist/chunk-SZJB5FLZ.mjs.map +0 -1
  68. package/dist/chunk-YGOLNWXJ.mjs +0 -11906
  69. package/dist/chunk-YGOLNWXJ.mjs.map +0 -1
  70. package/dist/management/management.js +0 -44454
  71. package/dist/management/management.js.map +0 -1
  72. package/dist/management/management.mjs +0 -16
  73. package/dist/management/management.mjs.map +0 -1
  74. package/dist/memoryUtils-HGCYEUCD.mjs.map +0 -1
  75. package/dist/modals/chat-modal/chat-modal.js +0 -19730
  76. package/dist/modals/chat-modal/chat-modal.js.map +0 -1
  77. package/dist/modals/chat-modal/chat-modal.mjs +0 -18
  78. package/dist/modals/chat-modal/chat-modal.mjs.map +0 -1
  79. package/dist/modelStore-TFNX4GEC.mjs +0 -8
  80. package/dist/modelStore-TFNX4GEC.mjs.map +0 -1
  81. package/dist/shared/custom-element.js +0 -73
  82. package/dist/shared/custom-element.js.map +0 -1
  83. package/dist/shared/custom-element.mjs +0 -7
  84. package/dist/shared/custom-element.mjs.map +0 -1
  85. package/docs/06_busl_licensing.md +0 -25
  86. package/docs/api_reference/.nojekyll +0 -1
  87. package/docs/api_reference/assets/bandit-docs.js +0 -462
  88. package/docs/api_reference/assets/highlight.css +0 -141
  89. package/docs/api_reference/assets/icons.js +0 -18
  90. package/docs/api_reference/assets/icons.svg +0 -1
  91. package/docs/api_reference/assets/main.js +0 -61
  92. package/docs/api_reference/assets/navigation.js +0 -1
  93. package/docs/api_reference/assets/search.js +0 -1
  94. package/docs/api_reference/assets/style.css +0 -1664
  95. package/docs/api_reference/classes/DebugLogger.html +0 -29
  96. package/docs/api_reference/classes/FeatureFlagService.html +0 -28
  97. package/docs/api_reference/classes/NotificationService.html +0 -21
  98. package/docs/api_reference/classes/StreamingTTSClient.html +0 -19
  99. package/docs/api_reference/classes/VectorDatabaseService.html +0 -63
  100. package/docs/api_reference/classes/VectorMigrationService.html +0 -27
  101. package/docs/api_reference/classes/VoiceService.html +0 -4
  102. package/docs/api_reference/enums/TTSState.html +0 -6
  103. package/docs/api_reference/functions/Chat.html +0 -1
  104. package/docs/api_reference/functions/ChatModal.html +0 -29
  105. package/docs/api_reference/functions/ChatProvider.html +0 -29
  106. package/docs/api_reference/functions/FeatureFlagProvider.html +0 -30
  107. package/docs/api_reference/functions/FeedbackButton.html +0 -29
  108. package/docs/api_reference/functions/FeedbackModal.html +0 -29
  109. package/docs/api_reference/functions/InterestsEditor.html +0 -5
  110. package/docs/api_reference/functions/Management.html +0 -1
  111. package/docs/api_reference/functions/NotificationProvider.html +0 -29
  112. package/docs/api_reference/functions/SubscriptionExpiredGuard.html +0 -31
  113. package/docs/api_reference/functions/SubscriptionExpiredModal.html +0 -31
  114. package/docs/api_reference/functions/defineCustomElement.html +0 -1
  115. package/docs/api_reference/functions/getCriticalConfig.html +0 -2
  116. package/docs/api_reference/functions/getFeatureMatrix.html +0 -1
  117. package/docs/api_reference/functions/getStreamingTTSClient.html +0 -1
  118. package/docs/api_reference/functions/getSystemConstants.html +0 -2
  119. package/docs/api_reference/functions/getTTSState.html +0 -1
  120. package/docs/api_reference/functions/handleHttpError.html +0 -2
  121. package/docs/api_reference/functions/handleSubscriptionUpgrade.html +0 -1
  122. package/docs/api_reference/functions/handleValidationError.html +0 -2
  123. package/docs/api_reference/functions/initializeCoreSystem.html +0 -2
  124. package/docs/api_reference/functions/isWorkspaceAdminRole.html +0 -6
  125. package/docs/api_reference/functions/pauseTTS.html +0 -1
  126. package/docs/api_reference/functions/previewTierUpgrade.html +0 -1
  127. package/docs/api_reference/functions/resolveManagementSections.html +0 -2
  128. package/docs/api_reference/functions/resumeTTS.html +0 -1
  129. package/docs/api_reference/functions/showInfoNotification.html +0 -2
  130. package/docs/api_reference/functions/showSuccessNotification.html +0 -2
  131. package/docs/api_reference/functions/speakWithStreaming.html +0 -1
  132. package/docs/api_reference/functions/stopTTS.html +0 -1
  133. package/docs/api_reference/functions/syncSubscriptionWithAPI.html +0 -1
  134. package/docs/api_reference/functions/updateSubscriptionTier.html +0 -2
  135. package/docs/api_reference/functions/useFeatureFlag.html +0 -2
  136. package/docs/api_reference/functions/useFeatureVisibility.html +0 -2
  137. package/docs/api_reference/functions/useFeatures.html +0 -2
  138. package/docs/api_reference/functions/useGatewayHealth.html +0 -1
  139. package/docs/api_reference/functions/useGatewayMemory.html +0 -1
  140. package/docs/api_reference/functions/useGatewayModels.html +0 -1
  141. package/docs/api_reference/functions/useGlobalTTS.html +0 -2
  142. package/docs/api_reference/functions/useManagementAccess.html +0 -2
  143. package/docs/api_reference/functions/useNotification.html +0 -1
  144. package/docs/api_reference/functions/useNotificationService.html +0 -6
  145. package/docs/api_reference/functions/useTTS.html +0 -2
  146. package/docs/api_reference/functions/useVectorStore.html +0 -13
  147. package/docs/api_reference/functions/useVoiceStore.html +0 -8
  148. package/docs/api_reference/functions/useVoices.html +0 -3
  149. package/docs/api_reference/functions/validateEnvironment.html +0 -2
  150. package/docs/api_reference/functions/validateSystemIntegrity.html +0 -2
  151. package/docs/api_reference/index.html +0 -916
  152. package/docs/api_reference/interfaces/AIChatRequest.html +0 -8
  153. package/docs/api_reference/interfaces/AIChatResponse.html +0 -3
  154. package/docs/api_reference/interfaces/AIGenerateRequest.html +0 -5
  155. package/docs/api_reference/interfaces/AIGenerateResponse.html +0 -3
  156. package/docs/api_reference/interfaces/AIMessage.html +0 -4
  157. package/docs/api_reference/interfaces/AIModel.html +0 -6
  158. package/docs/api_reference/interfaces/AIProviderConfig.html +0 -12
  159. package/docs/api_reference/interfaces/ChatConfig.html +0 -5
  160. package/docs/api_reference/interfaces/ChatModalProps.html +0 -7
  161. package/docs/api_reference/interfaces/CreateMemoryOptions.html +0 -7
  162. package/docs/api_reference/interfaces/FeatureEvaluation.html +0 -14
  163. package/docs/api_reference/interfaces/FeatureFlagConfig.html +0 -18
  164. package/docs/api_reference/interfaces/FeatureFlagContextValue.html +0 -16
  165. package/docs/api_reference/interfaces/FeatureFlagProviderProps.html +0 -4
  166. package/docs/api_reference/interfaces/FeedbackButtonProps.html +0 -19
  167. package/docs/api_reference/interfaces/FeedbackCategories.html +0 -6
  168. package/docs/api_reference/interfaces/FeedbackModalProps.html +0 -4
  169. package/docs/api_reference/interfaces/FeedbackPriorities.html +0 -5
  170. package/docs/api_reference/interfaces/FeedbackRequest.html +0 -12
  171. package/docs/api_reference/interfaces/FeedbackResponse.html +0 -7
  172. package/docs/api_reference/interfaces/FileUploadResult.html +0 -4
  173. package/docs/api_reference/interfaces/GatewayChatRequest.html +0 -13
  174. package/docs/api_reference/interfaces/GatewayChatResponse.html +0 -7
  175. package/docs/api_reference/interfaces/GatewayContract.html +0 -4
  176. package/docs/api_reference/interfaces/GatewayGenerateRequest.html +0 -8
  177. package/docs/api_reference/interfaces/GatewayGenerateResponse.html +0 -12
  178. package/docs/api_reference/interfaces/GatewayHealthResponse.html +0 -5
  179. package/docs/api_reference/interfaces/GatewayMemoryRecord.html +0 -7
  180. package/docs/api_reference/interfaces/GatewayMemoryResponse.html +0 -4
  181. package/docs/api_reference/interfaces/GatewayMessage.html +0 -5
  182. package/docs/api_reference/interfaces/GatewayMessageContent.html +0 -4
  183. package/docs/api_reference/interfaces/GatewayModel.html +0 -9
  184. package/docs/api_reference/interfaces/GatewayModelsResponse.html +0 -2
  185. package/docs/api_reference/interfaces/ManagementAccess.html +0 -5
  186. package/docs/api_reference/interfaces/ManagementAccessInput.html +0 -5
  187. package/docs/api_reference/interfaces/ManagementLink.html +0 -7
  188. package/docs/api_reference/interfaces/ManagementProps.html +0 -22
  189. package/docs/api_reference/interfaces/ManagementSectionDef.html +0 -10
  190. package/docs/api_reference/interfaces/MemorySearchFilters.html +0 -5
  191. package/docs/api_reference/interfaces/MigrationProgress.html +0 -6
  192. package/docs/api_reference/interfaces/MigrationStatus.html +0 -7
  193. package/docs/api_reference/interfaces/NotificationConfig.html +0 -5
  194. package/docs/api_reference/interfaces/NotificationContextType.html +0 -6
  195. package/docs/api_reference/interfaces/NotificationProviderProps.html +0 -4
  196. package/docs/api_reference/interfaces/PackageSettings.html +0 -22
  197. package/docs/api_reference/interfaces/SearchOptions.html +0 -6
  198. package/docs/api_reference/interfaces/SearchResult.html +0 -5
  199. package/docs/api_reference/interfaces/SubscriptionExpiredGuardProps.html +0 -7
  200. package/docs/api_reference/interfaces/SubscriptionExpiredModalProps.html +0 -6
  201. package/docs/api_reference/interfaces/TTSOptions.html +0 -5
  202. package/docs/api_reference/interfaces/TTSProgress.html +0 -6
  203. package/docs/api_reference/interfaces/TrialUsage.html +0 -6
  204. package/docs/api_reference/interfaces/UploadRequest.html +0 -9
  205. package/docs/api_reference/interfaces/UseTTSReturn.html +0 -14
  206. package/docs/api_reference/interfaces/VectorDocument.html +0 -11
  207. package/docs/api_reference/interfaces/VectorMemory.html +0 -12
  208. package/docs/api_reference/interfaces/VectorMemoryMetadata.html +0 -7
  209. package/docs/api_reference/interfaces/VectorStoreStatus.html +0 -7
  210. package/docs/api_reference/interfaces/VoiceModelsResponse.html +0 -4
  211. package/docs/api_reference/interfaces/VoiceState.html +0 -12
  212. package/docs/api_reference/media/02_gateway_api.md +0 -123
  213. package/docs/api_reference/media/05_cli_quickstart.md +0 -87
  214. package/docs/api_reference/media/LICENSE +0 -43
  215. package/docs/api_reference/media/PRE-PUSH-CHECKLIST.md +0 -10
  216. package/docs/api_reference/media/PROTECTION-NOTICE.md +0 -11
  217. package/docs/api_reference/media/README.md +0 -58
  218. package/docs/api_reference/modules.html +0 -136
  219. package/docs/api_reference/types/FeatureKey.html +0 -2
  220. package/docs/api_reference/types/FeatureMatrix.html +0 -2
  221. package/docs/api_reference/types/GatewayQueryOptions.html +0 -1
  222. package/docs/api_reference/types/LogContext.html +0 -14
  223. package/docs/api_reference/types/ManagementRequest.html +0 -1
  224. package/docs/api_reference/types/ManagementSectionId.html +0 -2
  225. package/docs/api_reference/types/SubscriptionTier.html +0 -2
  226. package/docs/api_reference/variables/DEFAULT_TIER_FEATURES.html +0 -2
  227. package/docs/api_reference/variables/FeatureFlagContext.html +0 -1
  228. package/docs/api_reference/variables/MANAGEMENT_SECTIONS.html +0 -1
  229. package/docs/api_reference/variables/OSS_DEFAULT_FEATURES.html +0 -2
  230. package/docs/api_reference/variables/SYSTEM_FLAGS.html +0 -2
  231. package/docs/api_reference/variables/authenticationService.html +0 -1
  232. package/docs/api_reference/variables/debugLogger-1.html +0 -1
  233. package/docs/api_reference/variables/featureFlagService-1.html +0 -2
  234. package/docs/api_reference/variables/notificationService-1.html +0 -1
  235. package/docs/api_reference/variables/vectorDatabaseService-1.html +0 -1
  236. package/docs/api_reference/variables/vectorMigrationService-1.html +0 -1
  237. package/docs/api_reference/variables/voiceService-1.html +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/services/logging/debugLogger.ts","../../../src/services/indexedDB/indexedDBService.ts","../../../src/services/ai-provider/types/common.types.ts","../../../src/services/stream/streamLineParser.ts","../../../src/services/ollama/ollama.service.ts","../../../src/services/ai-provider/providers/deprecated.ts","../../../src/services/ai-provider/providers/ollama.provider.ts","../../../src/services/ai-provider/providers/openai.provider.ts","../../../src/services/ai-provider/providers/azure-openai.provider.ts","../../../src/services/ai-provider/providers/anthropic.provider.ts","../../../src/store/authenticationStore.ts","../../../src/services/auth/authenticationService.ts","../../../src/services/gateway/gateway.service.ts","../../../src/services/gateway/openai-gateway.service.ts","../../../src/services/gateway/azure-openai-gateway.service.ts","../../../src/services/gateway/anthropic-gateway.service.ts","../../../src/services/gateway/ollama-gateway.service.ts","../../../src/services/gateway/bandit-gateway.service.ts","../../../src/services/ai-provider/providers/gateway.provider.ts","../../../src/services/ai-provider/providers/playground.provider.ts","../../../src/services/ai-provider/providers/xai.provider.ts","../../../src/services/ai-provider/providers/bandit-ai.provider.ts","../../../src/services/ai-provider/ai-provider.factory.ts","../../../src/store/aiProviderStore.ts","../../../src/store/packageSettingsStore.ts","../../../src/utils/memoryUtils.ts","../../../src/models/models.ts","../../../src/store/preferencesStore.ts","../../../src/store/modelStore.ts","../../../src/modals/chat-modal/chat-modal.tsx","../../../src/modals/chat-modal/draggable-box.tsx","../../../src/modals/chat-modal/modal-header.tsx","../../../src/icons/index.tsx","../../../src/modals/chat-modal/query-input.tsx","../../../src/modals/chat-modal/ai-response-text-field.tsx","../../../src/shared/DocumentCard.tsx","../../../src/chat/hooks/useKnowledgeStore.tsx","../../../src/store/knowledgeStore.ts","../../../src/services/prompts/conversationStarters.ts","../../../src/util.ts","../../../src/services/notification/notificationService.ts","../../../src/services/prompts/moodDetection.ts","../../../src/services/prompts/detectUserInterestAndExcitement.ts","../../../src/services/prompts/documentSummarization.ts","../../../src/services/prompts/documentRelevance.ts","../../../src/store/memoryStore.ts","../../../src/services/embedding/embeddingService.tsx","../../../src/services/vectorDatabase/vectorDatabaseService.ts","../../../src/services/vectorDatabase/knowledgeFiles.ts","../../../src/hooks/useVectorStore.tsx","../../../src/services/vectorDatabase/vectorMigrationService.ts","../../../src/hooks/useFeatures.ts","../../../src/contexts/FeatureFlagContext.tsx","../../../src/store/conversationSyncStore.ts","../../../src/store/conversationStore.ts","../../../src/store/aiQueryStore.ts","../../../src/util/conversationMigration.ts","../../../src/store/conversationSyncEvents.ts","../../../src/store/projectStore.ts","../../../src/services/conversationSync/conversationSyncService.ts","../../../src/modals/knowlege/knowledge-file-modal.tsx","../../../src/utils/lowlight.ts","../../../src/utils/markdownRendering.tsx","../../../src/utils/openFileLink.ts","../../../src/modals/chat-modal/ai-response-action-bar.tsx","../../../src/store/voiceStore.ts","../../../src/services/tts/voiceService.ts","../../../src/services/tts/streaming-tts.ts","../../../src/services/tts/tts-client.ts","../../../src/store/canvasStore.ts","../../../src/hooks/useTTS.ts","../../../src/chat/chat-tokens.tsx","../../../../../node_modules/@burtson-labs/ui/src/tokens.ts","../../../src/modals/chat-modal/chat-drawer.tsx","../../../src/chat/memory-modal.tsx","../../../src/shared/generic-loader.tsx","../../../src/components/feedback/FeedbackButton.tsx","../../../src/components/feedback/FeedbackModal.tsx","../../../src/hooks/useAiChat.ts","../../../src/hooks/useDraggable.ts","../../../src/hooks/useNotificationService.ts","../../../src/shared/components/NotificationProvider.tsx","../../../src/services/branding/brandingService.ts","../../../../bandit-themes/src/createBanditTheme.ts","../../../../../node_modules/@burtson-labs/ui/src/mui/index.ts","../../../../bandit-themes/src/semantic.ts","../../../../bandit-themes/src/skins.ts","../../../../bandit-themes/src/provider.tsx","../../../../bandit-themes/src/tenant.ts","../../../../bandit-themes/src/registry.ts","../../../../bandit-themes/src/TenantPreview.tsx"],"sourcesContent":["/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\n/**\n * 🔍 Bandit Debug Logger Service\n * \n * Centralized logging service that provides environment-aware debug logging.\n * \n * Features:\n * - Production builds: Only warnings and errors are shown; set\n * localStorage `bandit:debug` to \"1\" to see info logs too\n * - Development mode: All logs are shown with clear debug prefixes\n * - Consistent formatting for debugging purposes\n * - Clear indication that logs are for debugging\n * \n * Usage:\n * ```typescript\n * import { debugLogger } from './services/logging/debugLogger';\n * \n * debugLogger.debug('LLM processing', { prompt, response });\n * debugLogger.info('User action completed', { action });\n * debugLogger.warn('Performance warning', { timing });\n * debugLogger.error('Operation failed', { error });\n * ```\n */\n\nexport type LogContext = unknown;\n\nclass DebugLogger {\n private isDevelopment: boolean;\n\n constructor() {\n // Check if we're in development mode using multiple detection methods\n this.isDevelopment = this.detectDevelopmentMode();\n }\n\n private detectDevelopmentMode(): boolean {\n // Check if we're in a development environment\n // This uses a safe approach that works in both ESM and CJS contexts\n try {\n // For browser environments using Vite - check the build-time flag\n const globalFlags = globalThis as typeof globalThis & {\n __VITE_IS_PRODUCTION__?: boolean;\n process?: { env?: { NODE_ENV?: string } };\n };\n\n if (typeof window !== 'undefined' && typeof globalFlags.__VITE_IS_PRODUCTION__ !== 'undefined') {\n return !globalFlags.__VITE_IS_PRODUCTION__;\n }\n \n // For Node.js environments - use try-catch to avoid type errors\n const proc = globalFlags.process;\n if (proc && proc.env) {\n return proc.env.NODE_ENV === 'development';\n }\n \n // For runtime detection, we can also check URL patterns in browser\n if (typeof window !== 'undefined' && window.location) {\n const devHosts = ['localhost', '127.0.0.1'];\n const devPorts = ['5173', '5183']; // common Vite dev ports\n return devHosts.includes(window.location.hostname) ||\n devPorts.includes(window.location.port);\n }\n } catch (e) {\n // If any detection fails, default to development for safety in debug scenarios\n }\n \n // Default to development for safety in debug scenarios\n return true;\n }\n\n /**\n * Set development mode manually (useful for testing or runtime configuration)\n */\n setDevelopmentMode(isDev: boolean): void {\n this.isDevelopment = isDev;\n }\n\n /**\n * Debug logs - only shown in development mode\n * These are obfuscated/hidden in production builds\n * DISABLED to prevent console flooding during chat processing\n */\n debug(message: string, context?: LogContext): void {\n // Debug logging disabled to prevent console flooding\n // Can be re-enabled for specific debugging sessions by uncommenting below:\n // if (this.isDevelopment) {\n // const prefix = '🔍 [DEBUG]';\n // if (context) {\n // console.log(`${prefix} ${message}`, context);\n // } else {\n // console.log(`${prefix} ${message}`);\n // }\n // }\n }\n\n private verboseEnabled(): boolean {\n if (this.isDevelopment) return true;\n try {\n return typeof localStorage !== 'undefined' && localStorage.getItem('bandit:debug') === '1';\n } catch {\n return false;\n }\n }\n\n /**\n * Info logs - shown in development, or in production when localStorage\n * `bandit:debug` is \"1\"\n */\n info(message: string, context?: LogContext): void {\n if (!this.verboseEnabled()) return;\n const prefix = this.isDevelopment ? 'ℹ️ [INFO]' : '[INFO]';\n if (context) {\n console.info(`${prefix} ${message}`, context);\n } else {\n console.info(`${prefix} ${message}`);\n }\n }\n\n /**\n * Warning logs - shown in both development and production\n * Used for non-critical issues that should be noted\n */\n warn(message: string, context?: LogContext): void {\n const prefix = this.isDevelopment ? '⚠️ [WARN]' : '[WARN]';\n if (context) {\n console.warn(`${prefix} ${message}`, context);\n } else {\n console.warn(`${prefix} ${message}`);\n }\n }\n\n /**\n * Error logs - always shown in both development and production\n * Used for critical errors that need attention\n */\n error(message: string, context?: LogContext): void {\n const prefix = this.isDevelopment ? '❌ [ERROR]' : '[ERROR]';\n if (context) {\n console.error(`${prefix} ${message}`, context);\n } else {\n console.error(`${prefix} ${message}`);\n }\n }\n\n /**\n * LLM-specific debug logging for RAG and AI features\n * DISABLED to prevent console flooding during chat processing\n */\n llmDebug(operation: string, data: LogContext): void {\n // LLM debug logging disabled to prevent console flooding\n // Can be re-enabled for specific debugging sessions\n }\n\n /**\n * RAG-specific debug logging for knowledge and document processing\n * DISABLED to prevent console flooding during chat processing\n */\n ragDebug(operation: string, data: LogContext): void {\n // RAG debug logging disabled to prevent console flooding\n // Can be re-enabled for specific debugging sessions\n }\n\n /**\n * Memory-specific debug logging for AI memory features\n * DISABLED to prevent console flooding during chat processing\n */\n memoryDebug(operation: string, data: LogContext): void {\n // Memory debug logging disabled to prevent console flooding\n // Can be re-enabled for specific debugging sessions\n }\n\n /**\n * Table logging for development debugging\n * DISABLED to prevent console flooding during chat processing\n */\n table(data: unknown[], message?: string): void {\n // Table logging disabled to prevent console flooding\n // Can be re-enabled for specific debugging sessions\n }\n}\n\n// Export a singleton instance\nexport const debugLogger = new DebugLogger();\n\n// Export the class for testing purposes\nexport { DebugLogger };\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { openDB, IDBPDatabase } from 'idb';\n\ntype StoreConfig = {\n name: string;\n keyPath?: string;\n};\n\ntype StoreConfigList = ReadonlyArray<StoreConfig>;\n\nconst isNotFoundError = (error: unknown): boolean =>\n typeof error === 'object' &&\n error !== null &&\n 'name' in error &&\n typeof (error as { name: unknown }).name === 'string' &&\n (error as { name: string }).name === 'NotFoundError';\n\n/**\n * Generic IndexedDB service that provides consistent database operations\n * across the application using the idb library for modern Promise-based APIs.\n */\nclass IndexedDBService {\n private dbConnections: Map<string, Promise<IDBPDatabase>> = new Map();\n\n /**\n * Get or create a database connection (legacy method, use ensureDBWithStores for better error handling)\n */\n private async getDB(dbName: string, version: number, storeConfigs: StoreConfigList): Promise<IDBPDatabase> {\n return this.ensureDBWithStores(dbName, version, storeConfigs);\n }\n\n /**\n * Ensure database and object stores exist, with robust error handling\n */\n private async ensureDBWithStores(\n dbName: string, \n version: number, \n storeConfigs: StoreConfigList\n ): Promise<IDBPDatabase> {\n const key = `${dbName}_v${version}`;\n \n try {\n // Check if we already have a valid connection\n const existingPromise = this.dbConnections.get(key);\n if (existingPromise) {\n const existingDB = await existingPromise;\n \n // Verify all required object stores exist\n const missingStores = storeConfigs.filter(config => \n !existingDB.objectStoreNames.contains(config.name)\n );\n \n if (missingStores.length === 0) {\n return existingDB;\n }\n \n // If stores are missing, close existing connection and recreate\n existingDB.close();\n this.dbConnections.delete(key);\n }\n \n // Use the new version-aware helper\n const db = await this.openDBWithVersionFallback(dbName, version, storeConfigs);\n \n // Cache the connection with the actual version used\n const actualKey = `${dbName}_v${db.version}`;\n this.dbConnections.set(actualKey, Promise.resolve(db));\n \n return db;\n \n } catch (error) {\n // Remove failed connection from cache\n this.dbConnections.delete(key);\n throw error;\n }\n }\n\n /**\n * Open database with automatic version detection and fallback\n */\n private async openDBWithVersionFallback(\n dbName: string, \n preferredVersion: number,\n storeConfigs: StoreConfigList\n ): Promise<IDBPDatabase> {\n try {\n // First try without specifying version (use existing version)\n const db = await openDB(dbName);\n \n // Check if all required stores exist\n const missingStores = storeConfigs.filter(config => \n !db.objectStoreNames.contains(config.name)\n );\n \n if (missingStores.length === 0) {\n return db;\n }\n \n // Close and upgrade if stores are missing\n db.close();\n \n // Try to upgrade with current version + 1\n const currentVersion = db.version;\n const newVersion = Math.max(currentVersion + 1, preferredVersion);\n \n return await openDB(dbName, newVersion, {\n upgrade(db) {\n storeConfigs.forEach(config => {\n if (!db.objectStoreNames.contains(config.name)) {\n db.createObjectStore(config.name, config.keyPath ? { keyPath: config.keyPath } : undefined);\n }\n });\n },\n });\n \n } catch (error) {\n // If no database exists, create with preferred version\n if (isNotFoundError(error)) {\n return await openDB(dbName, preferredVersion, {\n upgrade(db) {\n storeConfigs.forEach(config => {\n if (!db.objectStoreNames.contains(config.name)) {\n db.createObjectStore(config.name, config.keyPath ? { keyPath: config.keyPath } : undefined);\n }\n });\n },\n });\n }\n \n throw error;\n }\n }\n\n /**\n * Get a value from a specific store\n */\n async get<T = unknown>(\n dbName: string, \n version: number, \n storeName: string, \n key: string,\n storeConfigs: StoreConfigList\n ): Promise<T | undefined> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n const value = await db.get(storeName, key);\n return value as T | undefined;\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n const fallbackValue = await db.get(storeName, key);\n return fallbackValue as T | undefined;\n }\n throw error;\n }\n }\n\n /**\n * Put a value into a specific store\n */\n async put<T = unknown>(\n dbName: string, \n version: number, \n storeName: string, \n value: T,\n storeConfigs: StoreConfigList,\n key?: string\n ): Promise<void> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n if (key !== undefined) {\n await db.put(storeName, value, key);\n } else {\n await db.put(storeName, value);\n }\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n if (key !== undefined) {\n await db.put(storeName, value, key);\n } else {\n await db.put(storeName, value);\n }\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Delete a value from a specific store\n */\n async delete(\n dbName: string, \n version: number, \n storeName: string, \n key: string,\n storeConfigs: StoreConfigList\n ): Promise<void> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n await db.delete(storeName, key);\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n await db.delete(storeName, key);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Get all values from a specific store\n */\n async getAll<T = unknown>(\n dbName: string, \n version: number, \n storeName: string,\n storeConfigs: StoreConfigList\n ): Promise<T[]> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n const values = await db.getAll(storeName);\n return values as T[];\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n const fallbackValues = await db.getAll(storeName);\n return fallbackValues as T[];\n }\n throw error;\n }\n }\n\n /**\n * Clear all values from a specific store\n */\n async clear(\n dbName: string, \n version: number, \n storeName: string,\n storeConfigs: StoreConfigList\n ): Promise<void> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n await db.clear(storeName);\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n await db.clear(storeName);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Get all keys from a specific store\n */\n async getAllKeys(\n dbName: string, \n version: number, \n storeName: string,\n storeConfigs: StoreConfigList\n ): Promise<IDBValidKey[]> {\n try {\n const db = await this.ensureDBWithStores(dbName, version, storeConfigs);\n return db.getAllKeys(storeName);\n } catch (error) {\n if (isNotFoundError(error)) {\n console.warn(`Object store '${storeName}' not found in database '${dbName}'. Creating it...`);\n // Try to recreate the database with proper stores\n const db = await this.ensureDBWithStores(dbName, version + 1, storeConfigs);\n return db.getAllKeys(storeName);\n }\n throw error;\n }\n }\n}\n\n// Create a singleton instance\nconst indexedDBService = new IndexedDBService();\nexport default indexedDBService;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\n/**\n * Common types used across all AI providers\n */\n\nexport interface AIMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface AIChatRequest {\n model: string;\n messages: AIMessage[];\n stream?: boolean;\n temperature?: number;\n maxTokens?: number;\n images?: string[];\n options?: Record<string, unknown>;\n}\n\nexport interface AIToolCall {\n id?: string;\n type?: 'function';\n function: {\n name: string;\n arguments: string | Record<string, unknown>;\n };\n}\n\nexport interface AIChatResponse {\n message: {\n content: string;\n role: 'assistant';\n tool_calls?: AIToolCall[];\n };\n done?: boolean;\n}\n\nexport interface AIGenerateRequest {\n model: string;\n prompt: string;\n stream?: boolean;\n options?: Record<string, unknown>;\n}\n\nexport interface AIGenerateResponse {\n response: string;\n done?: boolean;\n}\n\nexport interface AIModel {\n name: string;\n size?: number;\n details?: {\n format?: string;\n family?: string;\n families?: string[];\n parameter_size?: string;\n quantization_level?: string;\n };\n digest?: string;\n modified_at?: string;\n}\n\nexport interface AIProviderConfig {\n type: 'ollama' | 'openai' | 'azure-openai' | 'anthropic' | 'xai' | 'bandit' | 'gateway' | 'playground';\n baseUrl?: string;\n apiKey?: string;\n apiVersion?: string; // For Azure\n deploymentName?: string; // For Azure\n defaultModel?: string; // Preferred chat model when using direct providers\n anthropicVersion?: string;\n anthropicMaxTokens?: number;\n gatewayUrl?: string; // For gateway-based providers\n provider?: 'openai' | 'azure-openai' | 'anthropic' | 'ollama' | 'xai' | 'bandit' | 'playground'; // Which backend provider to use via gateway\n tokenFactory?: () => string | null;\n}\n\nexport enum AIProviderType {\n OLLAMA = 'ollama',\n OPENAI = 'openai',\n AZURE_OPENAI = 'azure-openai',\n ANTHROPIC = 'anthropic',\n XAI = 'xai',\n BANDIT = 'bandit',\n GATEWAY = 'gateway',\n PLAYGROUND = 'playground'\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\n/**\n * Line classifier for the gateway's streaming responses.\n *\n * The gateway streams two shapes through the same readers: SSE\n * (`data: {...}` frames, OpenAI-style) and NDJSON (one JSON object per line,\n * Ollama-style). Both now carry keepalives so Cloudflare (which drops a\n * connection after 100 s without a byte) and ingress-nginx hold the stream\n * open through tool calls and model cold-loads:\n *\n * - SSE comment lines, `: ping`\n * - the Stealth heartbeat frame, `event: ping` + `data: {\"message\":\"heartbeat\"}`\n * - NDJSON whitespace, a lone \" \" between lines (arrives as leading\n * whitespace on the next line, or a whitespace-only line)\n *\n * The readers used to hand every non-empty line to JSON.parse and error the\n * whole Observable on failure, so a single `: ping` killed a chat mid-answer.\n * Feed each newline-split line through `next()` and act on the result.\n */\nexport type StreamLine =\n | { kind: 'skip' }\n | { kind: 'done' }\n | { kind: 'json'; text: string };\n\nconst SKIP: StreamLine = { kind: 'skip' };\n\nexport class StreamLineParser {\n /** Set by `event: ping` until the frame's blank-line terminator. */\n private inHeartbeatFrame = false;\n\n next(rawLine: string): StreamLine {\n const line = rawLine.trim();\n if (!line) {\n // Blank line ends an SSE frame.\n this.inHeartbeatFrame = false;\n return SKIP;\n }\n if (line.startsWith(':')) return SKIP; // SSE comment / keepalive\n if (line.startsWith('event:')) {\n this.inHeartbeatFrame = line.slice(6).trim().toLowerCase() === 'ping';\n return SKIP;\n }\n if (line.startsWith('id:') || line.startsWith('retry:')) return SKIP;\n if (line.startsWith('data:')) {\n if (this.inHeartbeatFrame) return SKIP;\n const data = line.slice(5).trim();\n if (!data) return SKIP;\n if (data === '[DONE]') return { kind: 'done' };\n return { kind: 'json', text: data };\n }\n // Raw NDJSON line.\n return { kind: 'json', text: line };\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { ChatRequest, ChatResponse, GenerateRequest, GenerateResponse, Model, ModelResponse } from \"./interfaces\";\nimport { catchError, from, lastValueFrom, map, Observable, of, shareReplay, switchMap, throwError, timeout } from \"rxjs\";\nimport { debugLogger } from \"../logging/debugLogger\";\nimport { StreamLineParser } from \"../stream/streamLineParser\";\n\nconst handleError = () => (obs: Observable<Response>) =>\n obs.pipe(\n switchMap((response) =>\n response.ok\n ? of(response)\n : throwError(() => new Error(`Request failed: ${response.status} ${response.statusText}`))\n )\n );\n\nconst parseResponseBody = async <T>(response: Response, responseType: 'json' | 'text'): Promise<T> => {\n if (responseType === 'text') {\n return (await response.text()) as unknown as T;\n }\n return (await response.json()) as T;\n};\n\nexport class OllamaService {\n\n constructor(\n private _baseUrl: string,\n private readonly _tokenFactory: () => string | null\n ) {\n if (!this._baseUrl) {\n this._baseUrl = 'http://localhost:11434'\n debugLogger.warn(`No base URL provided, using default: ${this._baseUrl}`);\n }\n }\n\n\n private _tryGatewayWithTimeout(args: {\n url: string,\n responseType: 'json' | 'text',\n timeoutMs: number,\n }): Observable<boolean> {\n const { url, responseType, timeoutMs } = args;\n const source = this._get(url, responseType)\n const mapped = source.pipe(\n catchError((e) => (e?.message.includes(\"401\") ? of(true) : of(false))),\n map(() => true),\n timeout(timeoutMs),\n );\n return mapped;\n }\n\n /**\n * Validates the availability of the service at the given base URL.\n * @param fallbackUrl The fallback URL to try if the base URL is not available.\n * @returns An object containing the URL and availability status.\n */\n async validateServiceAvailability(args: { fallbackUrl: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n const { fallbackUrl, timeoutMs } = args;\n const responseType = 'text';\n const availablility = {\n url: \"\",\n isAvailable: false,\n }\n try {\n debugLogger.debug(`Validating service availability at ${this._baseUrl}`);\n\n\n\n availablility.url = this._baseUrl;\n availablility.isAvailable = await lastValueFrom(\n this._tryGatewayWithTimeout({\n url: availablility.url,\n responseType,\n timeoutMs,\n })\n ) as boolean;\n if (!availablility.isAvailable) {\n throw new Error(`Service not available at ${this._baseUrl}`);\n }\n\n return availablility;\n } catch (e) {\n debugLogger.warn(`Service not available at ${this._baseUrl}, trying fallback URL: ${fallbackUrl}`);\n try {\n\n availablility.url = fallbackUrl;\n availablility.isAvailable = await lastValueFrom(\n this._tryGatewayWithTimeout({\n url: availablility.url,\n responseType,\n timeoutMs,\n })\n ) as boolean;\n\n if (!availablility.isAvailable) {\n throw new Error(`Service not available at ${fallbackUrl}`);\n }\n this._baseUrl = fallbackUrl;\n return availablility;\n } catch (e) {\n debugLogger.error(`Service not available at fallback URL: ${fallbackUrl}`);\n throw e;\n }\n }\n }\n\n\n generate(request: GenerateRequest): Observable<GenerateResponse> {\n const url = `${this._baseUrl}/api/generate`;\n return new Observable<GenerateResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: this._getHeaders(),\n body: JSON.stringify({ ...request, stream: request.stream === false ? false : true }),\n });\n task.then(response => {\n this._throwErrorIfNotOk(url, response);\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n const lineParser = new StreamLineParser();\n let buffer = \"\";\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n const tail = lineParser.next(buffer);\n if (tail.kind === 'json') {\n try {\n observer.next(JSON.parse(tail.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Final chunk parsing error (generate):', { buffer });\n }\n }\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n // Skips keepalives (whitespace, `: ping`) a proxy or the\n // gateway may interleave with Ollama's NDJSON.\n const classified = lineParser.next(line);\n if (classified.kind === 'json') {\n try {\n observer.next(JSON.parse(classified.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Error parsing JSON line (generate):', { line });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n })\n .catch(err => observer.error(err));\n });\n }\n\n // generate(request: GenerateRequest): Observable<GenerateResponse> {\n // const url = `${this._baseUrl}/api/generate`;\n // return this._post<GenerateRequest, GenerateResponse>(url, request);\n // }\n\n chat(request: ChatRequest): Observable<ChatResponse> {\n const url = `${this._baseUrl}/api/chat`;\n return new Observable<ChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: this._getHeaders(),\n body: JSON.stringify({ ...request, stream: true }),\n });\n task.then(response => {\n this._throwErrorIfNotOk(url, response);\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n const lineParser = new StreamLineParser();\n let buffer = \"\";\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n const tail = lineParser.next(buffer);\n if (tail.kind === 'json') {\n try {\n observer.next(JSON.parse(tail.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Final chunk parsing error (chat):', { buffer });\n }\n }\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n // Skips keepalives (whitespace, `: ping`) a proxy or the\n // gateway may interleave with Ollama's NDJSON.\n const classified = lineParser.next(line);\n if (classified.kind === 'json') {\n try {\n observer.next(JSON.parse(classified.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Error parsing JSON line (chat):', { line });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n })\n .catch(err => observer.error(err));\n });\n }\n\n\n listModels(): Observable<Model[]> {\n const url = `${this._baseUrl}/api/tags`;\n const response = this._get<ModelResponse>(url);\n const result = response.pipe(\n map(data => data.models),\n shareReplay(1));\n return result;\n }\n\n private _get<T>(url: string, responseType: 'json' | 'text' = 'json'): Observable<T> {\n const requestInit = {\n method: 'GET',\n headers: this._getHeaders(),\n }\n\n const response = from(fetch(url, requestInit));\n const handleFetchError = response.pipe(handleError());\n const data = handleFetchError.pipe(switchMap((res) => from(parseResponseBody<T>(res, responseType))));\n const result = data.pipe(shareReplay(1));\n\n return result;\n }\n\n private _post<TRequest, TResponse>(url: string, body: TRequest): Observable<TResponse> {\n const response = from(fetch(url, {\n method: 'POST',\n headers: this._getHeaders(),\n body: JSON.stringify(body),\n }));\n const handleFetchError = response.pipe(handleError());\n const json = handleFetchError.pipe(switchMap((res) => from(parseResponseBody<TResponse>(res, 'json'))));\n const result = json.pipe(shareReplay(1));\n return result;\n }\n private _throwErrorIfNotOk(url: string, response: Response) {\n if (!response.ok) {\n throw new Error(`POST ${url} failed: ${response.status} ${response.statusText}`);\n }\n }\n private _getHeaders() {\n const token = this._tokenFactory();\n \n if (!token) {\n debugLogger.warn('OllamaService: No token found, using empty string for Authorization header');\n }\n\n return {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token || ''}`\n };\n }\n\n\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from '../../logging/debugLogger';\nimport { AIProviderConfig } from '../types/common.types';\n\n/**\n * Deprecation notices for direct provider implementations\n * \n * MIGRATION NOTICE: Direct provider implementations are being phased out in favor \n * of the new unified gateway architecture. Please migrate to gateway-based providers\n * for enhanced security, performance, and centralized management.\n * \n * See GATEWAY_MIGRATION_GUIDE.md for migration instructions.\n */\n\n/**\n * @deprecated Use GatewayProvider with provider: 'openai' instead\n * \n * Migration example:\n * ```typescript\n * // Old (deprecated)\n * const config = { type: 'openai', apiKey: 'sk-...', baseUrl: '...' };\n * \n * // New (recommended)\n * const config = { \n * type: 'gateway', \n * gatewayUrl: 'https://your-gateway.com',\n * provider: 'openai',\n * tokenFactory: () => localStorage.getItem('authToken')\n * };\n * ```\n */\nexport function deprecatedOpenAIProvider() {\n debugLogger.warn('⚠️ DEPRECATION WARNING: Direct OpenAI provider is deprecated. Please migrate to GatewayProvider with provider: \"openai\". See GATEWAY_MIGRATION_GUIDE.md for details.');\n}\n\n/**\n * @deprecated Use GatewayProvider with provider: 'azure-openai' instead\n * \n * Migration example:\n * ```typescript\n * // Old (deprecated)\n * const config = { \n * type: 'azure-openai', \n * baseUrl: 'https://your-resource.openai.azure.com',\n * apiKey: 'your-key',\n * apiVersion: '2024-02-15-preview',\n * deploymentName: 'gpt-4'\n * };\n * \n * // New (recommended)\n * const config = { \n * type: 'gateway', \n * gatewayUrl: 'https://your-gateway.com',\n * provider: 'azure-openai',\n * deploymentName: 'gpt-4',\n * apiVersion: '2024-02-15-preview',\n * tokenFactory: () => localStorage.getItem('authToken')\n * };\n * ```\n */\nexport function deprecatedAzureOpenAIProvider() {\n debugLogger.warn('⚠️ DEPRECATION WARNING: Direct Azure OpenAI provider is deprecated. Please migrate to GatewayProvider with provider: \"azure-openai\". See GATEWAY_MIGRATION_GUIDE.md for details.');\n}\n\n/**\n * @deprecated Use GatewayProvider with provider: 'anthropic' instead\n * \n * Migration example:\n * ```typescript\n * // Old (deprecated)\n * const config = { type: 'anthropic', apiKey: 'sk-ant-...', baseUrl: '...' };\n * \n * // New (recommended)\n * const config = { \n * type: 'gateway', \n * gatewayUrl: 'https://your-gateway.com',\n * provider: 'anthropic',\n * tokenFactory: () => localStorage.getItem('authToken')\n * };\n * ```\n */\nexport function deprecatedAnthropicProvider() {\n debugLogger.warn('⚠️ DEPRECATION WARNING: Direct Anthropic provider is deprecated. Please migrate to GatewayProvider with provider: \"anthropic\". See GATEWAY_MIGRATION_GUIDE.md for details.');\n}\n\n/**\n * @deprecated Use GatewayProvider with provider: 'ollama' instead for production environments\n * \n * Note: The direct Ollama provider will remain available for local development,\n * but for production deployments, use the gateway for better management.\n * \n * Migration example:\n * ```typescript\n * // Development (still supported)\n * const config = { type: 'ollama', baseUrl: 'http://localhost:11434' };\n * \n * // Production (recommended)\n * const config = { \n * type: 'gateway', \n * gatewayUrl: 'https://your-gateway.com',\n * provider: 'ollama',\n * tokenFactory: () => localStorage.getItem('authToken')\n * };\n * ```\n */\nexport function deprecatedOllamaProvider() {\n debugLogger.info('ℹ️ INFO: Direct Ollama provider is available for local development. For production environments, consider using GatewayProvider with provider: \"ollama\" for enhanced management. See GATEWAY_MIGRATION_GUIDE.md for details.');\n}\n\n/**\n * Display deprecation summary\n */\nexport function showDeprecationSummary() {\n debugLogger.warn(`\n🏗️ BANDIT ENGINE PROVIDER ARCHITECTURE UPDATE\n\nThe Bandit Engine is transitioning to a unified gateway architecture for enhanced:\n• Security (centralized API key management)\n• Performance (connection pooling, caching)\n• Monitoring (unified logging, health checks)\n• Scaling (load balancing, failover)\n\nMIGRATION REQUIRED:\n• OpenAI Provider → GatewayProvider (provider: 'openai')\n• Azure OpenAI Provider → GatewayProvider (provider: 'azure-openai') \n• Anthropic Provider → GatewayProvider (provider: 'anthropic')\n\nMIGRATION RECOMMENDED:\n• Ollama Provider → GatewayProvider (provider: 'ollama') for production\n\n📖 Full migration guide: GATEWAY_MIGRATION_GUIDE.md\n🆘 Need help? Check the troubleshooting section in the migration guide\n `);\n}\n\n/**\n * Check if provider config is using deprecated direct provider\n */\nexport function isDeprecatedProvider(config: AIProviderConfig | undefined): boolean {\n const deprecatedTypes = ['openai', 'azure-openai', 'anthropic'];\n return config !== undefined && deprecatedTypes.includes(config.type);\n}\n\n/**\n * Suggest gateway migration for deprecated config\n */\nexport function suggestGatewayMigration(config: AIProviderConfig): AIProviderConfig {\n if (!isDeprecatedProvider(config)) {\n return config; // No migration needed\n }\n\n const gatewayConfig: AIProviderConfig = {\n type: 'gateway',\n gatewayUrl: '${GATEWAY_URL}', // Replace with your gateway URL\n provider: config.type as 'openai' | 'azure-openai' | 'anthropic' | 'ollama',\n tokenFactory: () => localStorage.getItem('authToken')\n };\n\n // Preserve Azure-specific config\n if (config.type === 'azure-openai') {\n gatewayConfig.deploymentName = config.deploymentName;\n gatewayConfig.apiVersion = config.apiVersion;\n }\n\n debugLogger.info('🔄 Suggested gateway migration:', {\n from: config,\n to: gatewayConfig\n });\n\n return gatewayConfig;\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, map } from 'rxjs';\nimport { OllamaService } from '../../ollama/ollama.service';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\nimport { deprecatedOllamaProvider } from './deprecated';\n\n/**\n * Ollama provider implementation that wraps the existing OllamaService\n */\nexport class OllamaProvider implements IAIProvider {\n private ollamaService: OllamaService;\n private config: AIProviderConfig;\n\n constructor(config: AIProviderConfig) {\n deprecatedOllamaProvider(); // Show info about gateway option for production\n this.config = config;\n const baseUrl = config.baseUrl || 'http://localhost:11434';\n debugLogger.info(\"OllamaProvider: Constructor\", { \n configBaseUrl: config.baseUrl,\n finalBaseUrl: baseUrl,\n hasTokenFactory: !!config.tokenFactory \n });\n this.ollamaService = new OllamaService(\n baseUrl,\n config.tokenFactory || (() => null)\n );\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n // Transform common request to Ollama-specific format\n const ollamaRequest = {\n model: request.model,\n messages: request.messages.map(msg => ({\n role: msg.role as 'system' | 'user' | 'assistant',\n content: msg.content\n })),\n stream: request.stream,\n options: request.options,\n images: request.images\n };\n\n return this.ollamaService.chat(ollamaRequest).pipe(\n map(response => ({\n message: {\n content: response.message.content,\n role: 'assistant' as const\n },\n done: response.done\n }))\n );\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n // Transform common request to Ollama-specific format\n const ollamaRequest = {\n model: request.model,\n prompt: request.prompt,\n stream: request.stream,\n options: request.options\n };\n\n return this.ollamaService.generate(ollamaRequest).pipe(\n map(response => ({\n response: response.response,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n return this.ollamaService.listModels().pipe(\n map(models => models.map(model => ({\n name: model.name,\n size: model.size,\n details: model.details,\n digest: model.digest,\n modified_at: model.modified_at\n })))\n );\n }\n\n async validateServiceAvailability(args: { \n fallbackUrl?: string; \n timeoutMs: number; \n }): Promise<{ url: string; isAvailable: boolean }> {\n return this.ollamaService.validateServiceAvailability({\n fallbackUrl: args.fallbackUrl || '',\n timeoutMs: args.timeoutMs\n });\n }\n\n getProviderType(): string {\n return AIProviderType.OLLAMA;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n}","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, from, switchMap, map, throwError } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\nimport { deprecatedOpenAIProvider } from './deprecated';\n\ninterface OpenAIChatPayload {\n model: string;\n messages: AIChatRequest['messages'];\n stream: boolean;\n temperature?: number;\n max_tokens?: number;\n}\n\ninterface OpenAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n };\n }>;\n}\n\ninterface OpenAIChatResponsePayload {\n choices?: Array<{\n message?: {\n content?: string;\n };\n }>;\n}\n\ninterface OpenAIModelListResponse {\n data: Array<{\n id: string;\n object?: string;\n }>;\n}\n\n/**\n * OpenAI provider implementation\n */\nexport class OpenAIProvider implements IAIProvider {\n private config: AIProviderConfig;\n private baseUrl: string;\n\n constructor(config: AIProviderConfig) {\n deprecatedOpenAIProvider(); // Show deprecation warning\n this.config = config;\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const url = `${this.baseUrl}/chat/completions`;\n \n const payload: OpenAIChatPayload = {\n model: request.model,\n messages: request.messages,\n stream: Boolean(request.stream),\n temperature: request.temperature,\n max_tokens: request.maxTokens\n };\n\n if (request.stream) {\n return this.streamChatRequest(url, payload);\n } else {\n return this.nonStreamChatRequest(url, payload);\n }\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n // For OpenAI, we'll use the chat endpoint with a single user message\n const chatRequest: AIChatRequest = {\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n stream: request.stream,\n options: request.options\n };\n\n return this.chat(chatRequest).pipe(\n map(response => ({\n response: response.message.content,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n const url = `${this.baseUrl}/models`;\n \n return from(fetch(url, {\n headers: this.getHeaders()\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`Failed to list models: ${response.status}`));\n }\n return from(response.json() as Promise<OpenAIModelListResponse>);\n }),\n map((data) =>\n data.data.map((model) => ({\n name: model.id,\n details: {\n format: 'openai',\n family: model.object\n }\n }))\n )\n );\n }\n\n async validateServiceAvailability(args: { \n fallbackUrl?: string; \n timeoutMs: number; \n }): Promise<{ url: string; isAvailable: boolean }> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const response = await fetch(`${this.baseUrl}/models`, {\n headers: this.getHeaders(),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n return {\n url: this.baseUrl,\n isAvailable: response.ok\n };\n } catch (error) {\n if (args.fallbackUrl) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const response = await fetch(`${args.fallbackUrl}/models`, {\n headers: this.getHeaders(),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n this.baseUrl = args.fallbackUrl;\n return {\n url: args.fallbackUrl,\n isAvailable: true\n };\n }\n } catch (fallbackError) {\n // Fall through to return unavailable\n }\n }\n\n return {\n url: this.baseUrl,\n isAvailable: false\n };\n }\n }\n\n getProviderType(): string {\n return AIProviderType.OPENAI;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private streamChatRequest(url: string, payload: OpenAIChatPayload): Observable<AIChatResponse> {\n return new Observable<AIChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n task.then(response => {\n if (!response.ok) {\n observer.error(new Error(`OpenAI request failed: ${response.status}`));\n return;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as OpenAIStreamChunk;\n const content = parsed.choices?.[0]?.delta?.content ?? '';\n if (content) {\n observer.next({\n message: { content, role: 'assistant' },\n done: false\n });\n }\n } catch (err) {\n debugLogger.error('Error parsing OpenAI stream data:', { data, error: err });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n }).catch(err => observer.error(err));\n });\n }\n\n private nonStreamChatRequest(url: string, payload: OpenAIChatPayload): Observable<AIChatResponse> {\n return from(fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`OpenAI request failed: ${response.status}`));\n }\n return from(response.json() as Promise<OpenAIChatResponsePayload>);\n }),\n map((data) => ({\n message: {\n content: data.choices?.[0]?.message?.content ?? '',\n role: 'assistant' as const\n },\n done: true\n }))\n );\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n \n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n return headers;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, from, switchMap, map, throwError } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\nimport { deprecatedAzureOpenAIProvider } from './deprecated';\n\ninterface AzureChatPayload {\n messages: AIChatRequest['messages'];\n stream: boolean;\n temperature?: number;\n max_tokens?: number;\n}\n\ninterface OpenAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n };\n }>;\n}\n\ninterface OpenAIChatResponsePayload {\n choices?: Array<{\n message?: {\n content?: string;\n };\n }>;\n}\n/**\n * Azure OpenAI provider implementation\n */\nexport class AzureOpenAIProvider implements IAIProvider {\n private config: AIProviderConfig;\n private baseUrl: string;\n\n constructor(config: AIProviderConfig) {\n deprecatedAzureOpenAIProvider(); // Show deprecation warning\n this.config = config;\n if (!config.baseUrl || !config.deploymentName || !config.apiVersion) {\n throw new Error('Azure OpenAI requires baseUrl, deploymentName, and apiVersion');\n }\n this.baseUrl = config.baseUrl;\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const url = `${this.baseUrl}/openai/deployments/${this.config.deploymentName}/chat/completions?api-version=${this.config.apiVersion}`;\n \n const payload: AzureChatPayload = {\n messages: request.messages,\n stream: Boolean(request.stream),\n temperature: request.temperature,\n max_tokens: request.maxTokens\n };\n\n if (request.stream) {\n return this.streamChatRequest(url, payload);\n } else {\n return this.nonStreamChatRequest(url, payload);\n }\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n // For Azure OpenAI, we'll use the chat endpoint with a single user message\n const chatRequest: AIChatRequest = {\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n stream: request.stream,\n options: request.options\n };\n\n return this.chat(chatRequest).pipe(\n map(response => ({\n response: response.message.content,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n // Azure OpenAI doesn't have a direct models endpoint, return the deployment as a model\n const model: AIModel = {\n name: this.config.deploymentName || 'azure-deployment',\n details: {\n format: 'azure-openai',\n family: 'gpt'\n }\n };\n\n return new Observable<AIModel[]>(observer => {\n observer.next([model]);\n observer.complete();\n });\n }\n\n async validateServiceAvailability(args: { \n fallbackUrl?: string; \n timeoutMs: number; \n }): Promise<{ url: string; isAvailable: boolean }> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n // Test with a simple chat request\n const testUrl = `${this.baseUrl}/openai/deployments/${this.config.deploymentName}/chat/completions?api-version=${this.config.apiVersion}`;\n const response = await fetch(testUrl, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages: [{ role: 'user', content: 'test' }],\n max_tokens: 1\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n return {\n url: this.baseUrl,\n isAvailable: response.ok || response.status === 400 // 400 might be expected for the test\n };\n } catch (error) {\n if (args.fallbackUrl) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const testUrl = `${args.fallbackUrl}/openai/deployments/${this.config.deploymentName}/chat/completions?api-version=${this.config.apiVersion}`;\n const response = await fetch(testUrl, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages: [{ role: 'user', content: 'test' }],\n max_tokens: 1\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok || response.status === 400) {\n this.baseUrl = args.fallbackUrl;\n return {\n url: args.fallbackUrl,\n isAvailable: true\n };\n }\n } catch (fallbackError) {\n // Fall through to return unavailable\n }\n }\n\n return {\n url: this.baseUrl,\n isAvailable: false\n };\n }\n }\n\n getProviderType(): string {\n return AIProviderType.AZURE_OPENAI;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private streamChatRequest(url: string, payload: AzureChatPayload): Observable<AIChatResponse> {\n return new Observable<AIChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n task.then(response => {\n if (!response.ok) {\n observer.error(new Error(`Azure OpenAI request failed: ${response.status}`));\n return;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as OpenAIStreamChunk;\n const content = parsed.choices?.[0]?.delta?.content ?? '';\n if (content) {\n observer.next({\n message: { content, role: 'assistant' },\n done: false\n });\n }\n } catch (err) {\n debugLogger.error('Error parsing Azure OpenAI stream data:', { data, error: err });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n }).catch(err => observer.error(err));\n });\n }\n\n private nonStreamChatRequest(url: string, payload: AzureChatPayload): Observable<AIChatResponse> {\n return from(fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`Azure OpenAI request failed: ${response.status}`));\n }\n return from(response.json() as Promise<OpenAIChatResponsePayload>);\n }),\n map((data) => {\n const content = data.choices?.[0]?.message?.content ?? '';\n return {\n message: {\n content,\n role: 'assistant' as const\n },\n done: true\n };\n })\n );\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n \n if (this.config.apiKey) {\n headers['api-key'] = this.config.apiKey;\n }\n\n return headers;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, from, switchMap, map, throwError } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\nimport { deprecatedAnthropicProvider } from './deprecated';\n\ntype AnthropicRole = 'user' | 'assistant';\n\ninterface AnthropicChatMessagePayload {\n role: AnthropicRole;\n content: string;\n}\n\ninterface AnthropicChatPayload {\n model: string;\n messages: AnthropicChatMessagePayload[];\n system?: string;\n stream: boolean;\n temperature?: number;\n max_tokens: number;\n}\n\ninterface AnthropicStreamChunk {\n delta?: {\n text?: string;\n };\n}\n\ninterface AnthropicChatResponsePayload {\n content?: unknown;\n completion?: string;\n message?: {\n content?: string;\n };\n}\n\n/**\n * Anthropic provider implementation for direct API access\n */\nexport class AnthropicProvider implements IAIProvider {\n private config: AIProviderConfig;\n private baseUrl: string;\n private version: string;\n private defaultMaxTokens: number;\n\n constructor(config: AIProviderConfig) {\n deprecatedAnthropicProvider(); // Show deprecation warning\n this.config = config;\n this.baseUrl = config.baseUrl || 'https://api.anthropic.com/v1';\n this.version = typeof config.anthropicVersion === 'string' && config.anthropicVersion.trim()\n ? config.anthropicVersion.trim()\n : '2023-06-01';\n this.defaultMaxTokens =\n typeof config.anthropicMaxTokens === 'number' && config.anthropicMaxTokens > 0\n ? config.anthropicMaxTokens\n : 1024;\n this.config.anthropicVersion = this.version;\n this.config.anthropicMaxTokens = this.defaultMaxTokens;\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const url = `${this.baseUrl}/messages`;\n \n // Convert system messages to Anthropic format\n const systemMessage = request.messages.find(msg => msg.role === 'system');\n const userMessages = request.messages.filter(msg => msg.role !== 'system');\n \n const payload: AnthropicChatPayload = {\n model: request.model,\n messages: userMessages.map(msg => ({\n role: msg.role === 'user' ? 'user' : 'assistant',\n content: msg.content\n })),\n system: systemMessage?.content,\n stream: Boolean(request.stream),\n temperature: request.temperature,\n max_tokens: request.maxTokens ?? this.defaultMaxTokens\n };\n\n if (request.stream) {\n return this.streamChatRequest(url, payload);\n } else {\n return this.nonStreamChatRequest(url, payload);\n }\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n // For Anthropic, we'll use the messages endpoint with a single user message\n const chatRequest: AIChatRequest = {\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n stream: request.stream,\n options: request.options\n };\n\n return this.chat(chatRequest).pipe(\n map(response => ({\n response: response.message.content,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n // Anthropic doesn't have a public models endpoint, return common models\n const commonModels: AIModel[] = [\n {\n name: 'claude-3-5-sonnet-20241022',\n details: {\n format: 'anthropic',\n family: 'claude-3.5'\n }\n },\n {\n name: 'claude-3-5-haiku-20241022',\n details: {\n format: 'anthropic',\n family: 'claude-3.5'\n }\n },\n {\n name: 'claude-3-opus-20240229',\n details: {\n format: 'anthropic',\n family: 'claude-3'\n }\n },\n {\n name: 'claude-3-sonnet-20240229',\n details: {\n format: 'anthropic',\n family: 'claude-3'\n }\n },\n {\n name: 'claude-3-haiku-20240307',\n details: {\n format: 'anthropic',\n family: 'claude-3'\n }\n }\n ];\n\n return new Observable<AIModel[]>(observer => {\n observer.next(commonModels);\n observer.complete();\n });\n }\n\n async validateServiceAvailability(args: { \n fallbackUrl?: string; \n timeoutMs: number; \n }): Promise<{ url: string; isAvailable: boolean }> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n // Test with a simple messages request\n const response = await fetch(`${this.baseUrl}/messages`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n model: 'claude-3-haiku-20240307',\n messages: [{ role: 'user', content: 'test' }],\n max_tokens: 1\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n return {\n url: this.baseUrl,\n isAvailable: response.ok || response.status === 400 // 400 might be expected for the test\n };\n } catch (error) {\n if (args.fallbackUrl) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const response = await fetch(`${args.fallbackUrl}/messages`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n model: 'claude-3-haiku-20240307',\n messages: [{ role: 'user', content: 'test' }],\n max_tokens: 1\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok || response.status === 400) {\n this.baseUrl = args.fallbackUrl;\n return {\n url: args.fallbackUrl,\n isAvailable: true\n };\n }\n } catch (fallbackError) {\n // Fall through to return unavailable\n }\n }\n\n return {\n url: this.baseUrl,\n isAvailable: false\n };\n }\n }\n\n getProviderType(): string {\n return AIProviderType.ANTHROPIC;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private streamChatRequest(url: string, payload: AnthropicChatPayload): Observable<AIChatResponse> {\n return new Observable<AIChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n task.then(response => {\n if (!response.ok) {\n observer.error(new Error(`Anthropic request failed: ${response.status}`));\n return;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as AnthropicStreamChunk;\n // Anthropic streaming format may differ, adjust as needed\n const content = parsed.delta?.text || '';\n if (content) {\n observer.next({\n message: { content, role: 'assistant' },\n done: false\n });\n }\n } catch (err) {\n debugLogger.error('Error parsing Anthropic stream data:', { data, error: err });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n }).catch(err => observer.error(err));\n });\n }\n\n private nonStreamChatRequest(url: string, payload: AnthropicChatPayload): Observable<AIChatResponse> {\n return from(fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`Anthropic request failed: ${response.status}`));\n }\n return from(response.json() as Promise<AnthropicChatResponsePayload>);\n }),\n map((data) => ({\n message: {\n content: this.extractContentText(data),\n role: 'assistant' as const\n },\n done: true\n }))\n );\n }\n\n private extractContentText(payload: AnthropicChatResponsePayload): string {\n const { content } = payload;\n\n if (Array.isArray(content)) {\n for (const entry of content) {\n if (typeof entry === 'string') {\n return entry;\n }\n if (entry && typeof entry === 'object' && 'text' in entry) {\n const text = (entry as { text?: unknown }).text;\n if (typeof text === 'string') {\n return text;\n }\n }\n }\n } else if (typeof content === 'string') {\n return content;\n }\n\n if (typeof payload.completion === 'string') {\n return payload.completion;\n }\n\n if (payload.message && typeof payload.message.content === 'string') {\n return payload.message.content;\n }\n\n return '';\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'anthropic-version': this.version\n };\n \n if (this.config.apiKey) {\n headers['x-api-key'] = this.config.apiKey;\n }\n\n return headers;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { JwtClaims } from \"../services/auth/authenticationService\";\n\nconst TOKEN_KEY = \"authToken\";\n\nconst decodeClaims = (token: string): JwtClaims | null => {\n try {\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split(\"\")\n .map((c) => \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2))\n .join(\"\")\n );\n return JSON.parse(jsonPayload) as JwtClaims;\n } catch {\n return null;\n }\n};\n\nconst validOrNull = (raw: string | null): string | null => {\n if (!raw) return null;\n const decoded = decodeClaims(raw);\n return decoded && decoded.exp * 1000 > Date.now() ? raw : null;\n};\n\nconst readLegacyStorage = (): string | null => {\n try {\n return typeof localStorage === \"undefined\" ? null : localStorage.getItem(TOKEN_KEY);\n } catch {\n return null;\n }\n};\n\n// 🔥 Inline hydration of token + user (avoids circular import). Reads the\n// legacy localStorage slot: the only place a session can survive a page load\n// without the host's help. Hosts using memory-mode sessions restore the token\n// through authenticationService before mounting (the slot is empty then).\nlet validToken: string | null = null;\nlet user: JwtClaims | null = null;\n\nconst rawToken = readLegacyStorage();\nif (rawToken) {\n validToken = validOrNull(rawToken);\n user = validToken ? decodeClaims(validToken) : null;\n}\n\ninterface AuthenticationState {\n token: string | null;\n user: JwtClaims | null;\n authError: string | null;\n setToken: (token: string | null) => void;\n clearToken: () => void;\n}\n\n/**\n * Live session state. Persistence is the authenticationService's job\n * (localStorage, memory-only, or a host-provided secure store); this store\n * never writes a token anywhere.\n */\nexport const useAuthenticationStore = create<AuthenticationState>((set) => ({\n token: validToken,\n user,\n authError: null,\n setToken: (token) => {\n if (token) {\n const decoded = decodeClaims(token);\n if (decoded) {\n set({ token, authError: null, user: decoded });\n } else {\n set({ token: null, authError: \"Invalid token\", user: null });\n }\n } else {\n set({ token: null, authError: null, user: null });\n }\n },\n clearToken: () => {\n set({ token: null, authError: null, user: null });\n },\n}));\n\n/**\n * The freshest valid token available to this page: the legacy localStorage\n * slot first (an app-side refresh that bypassed the service may have written\n * it), then the live store. Components re-sync `user` claims from it when a\n * refresh elsewhere (e.g. after setting a profile picture) left them stale.\n */\nexport const readPersistedToken = (): string | null => {\n return validOrNull(readLegacyStorage()) ?? validOrNull(useAuthenticationStore.getState().token);\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useAuthenticationStore } from \"../../store/authenticationStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\n\nexport interface JwtClaims {\n /**\n * The unique identifier for the user.\n */\n sub: string;\n /**\n * The email address of the user.\n * This is typically used for authentication and user identification.\n */\n email: string;\n /**\n * Optional display name for the user if provided by the identity provider.\n */\n name?: string;\n /**\n * Optional preferred username provided by the identity provider.\n */\n preferred_username?: string;\n /**\n * Optional direct URL to a profile image for the user.\n */\n picture?: string;\n /**\n * Optional given name of the user when available.\n */\n given_name?: string;\n /**\n * Optional family name of the user when available.\n */\n family_name?: string;\n /**\n * The roles assigned to the user.\n * 'user' | 'admin' | 'super-admin'\n */\n roles: string[];\n /**\n * The time at which the token was issued.\n * This is represented as a Unix timestamp (seconds since the epoch).\n */\n iat: number;\n\n /**\n * The time at which the token will expire.\n * This is represented as a Unix timestamp (seconds since the epoch).\n */\n exp: number;\n /**\n * The issuer of the token.\n * This is typically the URL of the authentication server.\n *\n */\n iss: string;\n /**\n * Optional team session identifier for team features.\n * Present when user belongs to a team.\n */\n teamSid?: string;\n /**\n * Optional team identifier for team features.\n * Present when user belongs to a team.\n */\n teamId?: string;\n /**\n * Identifiers of the teams this user OWNS (Team.createdBy == email).\n * Present only when the user owns at least one team.\n */\n ownedTeamIds?: string[];\n /**\n * Host domains this token can reach — tenant workspaces appear here as\n * \"{slug}.banditai.ai\". The tenant app gates access on this claim.\n */\n domains?: string[];\n /**\n * Current subscription tier inferred from the JWT.\n */\n subscriptionType?: string;\n /**\n * Indicates whether the subscription is active.\n */\n isSubscribed?: boolean;\n /**\n * Optional avatar reference (an S3 app-asset id) for the user's profile\n * picture. Resolved to an image via the file-storage download endpoint.\n */\n avatarUrl?: string;\n}\n\nexport const TOKEN_KEY = \"authToken\";\nexport const AUTH_TOKEN_CHANGED_EVENT = \"bandit:auth-token-changed\";\n\n/**\n * Where the live access token is kept.\n *\n * - `localStorage` — the historical contract: the JWT is persisted under\n * `authToken` and readable by any script on the page. Default, so npm\n * consumers that wire `tokenFactory: () => localStorage.getItem(\"authToken\")`\n * keep working unchanged.\n * - `memory` — the JWT lives only in the auth store for the life of the page.\n * The host app is responsible for restoring it at boot (an HttpOnly refresh\n * cookie, secure native storage, ...) through a `TokenPersistence` and a\n * `refresh` handler. Nothing token-shaped is written to Web Storage.\n */\nexport type TokenStorageMode = \"localStorage\" | \"memory\";\n\n/**\n * Optional write-through mirror of the live token. Used by the native shell\n * to keep the session in the OS keychain / Android Keystore instead of the\n * WebView's localStorage. Failures are the host's to handle; the in-memory\n * session is already valid when these run.\n */\nexport interface TokenPersistence {\n write(token: string): void | Promise<void>;\n clear(): void | Promise<void>;\n}\n\nexport interface AuthSessionHandlers {\n /**\n * Obtain a fresh access token silently (refresh cookie, device token, ...).\n * Resolve `true` after calling `setToken` with the new token, `false` when\n * an interactive sign-in is needed. Deduplicated by the service.\n */\n refresh?: () => Promise<boolean>;\n /**\n * Runs synchronously inside `clearToken()`, before the token is dropped,\n * with the token being dropped — the moment to revoke it server-side.\n */\n beforeClear?: (token: string | null) => void;\n}\n\nexport interface AuthSessionConfig {\n storage: TokenStorageMode;\n persistence?: TokenPersistence | null;\n handlers?: AuthSessionHandlers;\n}\n\nfunction emitAuthTokenChanged(token: string | null) {\n if (typeof window === \"undefined\") {\n return;\n }\n window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {\n detail: { token }\n }));\n}\n\nconst readLocalStorage = (): string | null => {\n try {\n return typeof localStorage === \"undefined\" ? null : localStorage.getItem(TOKEN_KEY);\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (token: string | null) => {\n try {\n if (typeof localStorage === \"undefined\") return;\n if (token) localStorage.setItem(TOKEN_KEY, token);\n else localStorage.removeItem(TOKEN_KEY);\n } catch {\n /* storage unavailable (private mode, quota) — the store still holds the token */\n }\n};\n\nclass AuthenticationService {\n private storageMode: TokenStorageMode = \"localStorage\";\n private persistence: TokenPersistence | null = null;\n private handlers: AuthSessionHandlers = {};\n /** Bumped on every setToken/clearToken; async flows compare it to detect a superseded session. */\n private revision = 0;\n private refreshInFlight: Promise<boolean> | null = null;\n private lastPersist: Promise<void> = Promise.resolve();\n\n /**\n * Pick the storage contract for this host. Call once at boot, before the\n * first `setToken`. Switching modes never moves a token by itself: the\n * host migrates (e.g. reads the legacy localStorage value, then clears it).\n */\n configureSession(config: AuthSessionConfig): void {\n this.storageMode = config.storage;\n this.persistence = config.persistence ?? null;\n this.handlers = config.handlers ?? {};\n }\n\n getStorageMode(): TokenStorageMode {\n return this.storageMode;\n }\n\n getSessionRevision(): number {\n return this.revision;\n }\n\n getToken(): string | null {\n if (this.storageMode === \"memory\") {\n return useAuthenticationStore.getState().token;\n }\n return readLocalStorage();\n }\n\n setToken(token: string) {\n this.revision += 1;\n if (this.storageMode === \"localStorage\") {\n writeLocalStorage(token);\n } else {\n // Defensive: a token must never linger in Web Storage in memory mode.\n writeLocalStorage(null);\n }\n useAuthenticationStore.getState().setToken(token);\n this.mirror(() => this.persistence?.write(token));\n emitAuthTokenChanged(token);\n }\n\n clearToken() {\n this.revision += 1;\n const current = this.getToken() ?? useAuthenticationStore.getState().token;\n try {\n this.handlers.beforeClear?.(current);\n } catch (error) {\n debugLogger.warn(\"Auth beforeClear handler failed\", { error });\n }\n writeLocalStorage(null);\n useAuthenticationStore.getState().clearToken();\n this.mirror(() => this.persistence?.clear());\n emitAuthTokenChanged(null);\n }\n\n /** True when the host registered a silent refresh path. */\n canRefresh(): boolean {\n return typeof this.handlers.refresh === \"function\";\n }\n\n /**\n * Ask the host for a fresh token. Concurrent callers share one attempt.\n * Resolves false when no refresh path exists or it did not produce a token.\n */\n tryRefresh(): Promise<boolean> {\n const refresh = this.handlers.refresh;\n if (!refresh) return Promise.resolve(false);\n if (this.refreshInFlight) return this.refreshInFlight;\n this.refreshInFlight = (async () => {\n try {\n return await refresh();\n } catch (error) {\n debugLogger.warn(\"Auth refresh handler failed\", { error });\n return false;\n } finally {\n this.refreshInFlight = null;\n }\n })();\n return this.refreshInFlight;\n }\n\n /** Resolves once the most recent persistence write/clear has settled. */\n whenPersisted(): Promise<void> {\n return this.lastPersist;\n }\n\n isAuthenticated(): boolean {\n const token = useAuthenticationStore.getState().token;\n return !!token && !this.isTokenExpired(token);\n }\n\n isTokenExpired(token: string): boolean {\n try {\n if (!token) return true;\n const decoded = this.parseJwtClaims(token);\n if (!decoded) return true;\n return decoded.exp * 1000 < Date.now();\n } catch {\n return true;\n }\n }\n\n parseJwtClaims(token: string): JwtClaims | null {\n try {\n const base64Url = token.split(\".\")[1];\n const base64 = base64Url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split(\"\")\n .map((c) => {\n return \"%\" + (\"00\" + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join(\"\")\n );\n return JSON.parse(jsonPayload) as JwtClaims;\n } catch (error) {\n debugLogger.error(\"Failed to parse JWT claims:\", { error });\n return null;\n }\n }\n\n private mirror(run: () => void | Promise<void>) {\n const attempt = (async () => {\n try {\n await run();\n } catch (error) {\n debugLogger.warn(\"Auth token persistence failed\", { error });\n }\n })();\n this.lastPersist = attempt;\n }\n}\n\nexport const authenticationService = new AuthenticationService();\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport axios, { AxiosError, AxiosHeaders, AxiosInstance } from \"axios\";\nimport {\n GatewayChatRequest,\n GatewayChatResponse,\n GatewayGenerateRequest,\n GatewayGenerateResponse,\n GatewayModel,\n GatewayModelsResponse,\n GatewayHealthResponse,\n GatewayMemoryResponse\n} from \"./interfaces\";\nimport { FeedbackRequest, FeedbackResponse } from \"./feedback.interfaces\";\nimport { StreamLineParser } from \"../stream/streamLineParser\";\nimport { catchError, from, lastValueFrom, map, Observable, of, shareReplay, timeout } from \"rxjs\";\nimport { debugLogger } from \"../logging/debugLogger\";\nimport { authenticationService } from \"../auth/authenticationService\";\n\ninterface GatewayHttpErrorResponse {\n status: number;\n statusText: string;\n data: unknown;\n url: string;\n}\n\ntype GatewayHttpError = Error & { response: GatewayHttpErrorResponse };\n\nexport class GatewayService {\n private readonly _client: AxiosInstance;\n\n constructor(\n private _baseUrl: string,\n private readonly _tokenFactory: () => string | null,\n private readonly _feedbackEmail?: string\n ) {\n if (!this._baseUrl) {\n this._baseUrl = 'http://localhost:5000'\n debugLogger.warn(`No gateway URL provided, using default: ${this._baseUrl}`);\n }\n \n // Ensure baseUrl doesn't end with slash\n this._baseUrl = this._baseUrl.replace(/\\/$/, '');\n\n // Remove /api suffix if it exists to avoid double /api/api paths\n if (this._baseUrl.endsWith('/api')) {\n this._baseUrl = this._baseUrl.slice(0, -4);\n debugLogger.info(`Removed /api suffix from gateway URL: ${this._baseUrl}`);\n }\n\n this._client = this._createAxiosClient();\n }\n\n private _createAxiosClient(): AxiosInstance {\n const instance = axios.create({\n baseURL: this._baseUrl,\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n\n instance.interceptors.request.use((config) => {\n const token = this._tokenFactory();\n const headers = AxiosHeaders.from(config.headers ?? {});\n\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json');\n }\n\n if (token && token.trim()) {\n headers.set('Authorization', `Bearer ${token}`);\n } else if (headers.has('Authorization')) {\n headers.delete('Authorization');\n }\n\n config.headers = headers;\n return config;\n });\n\n instance.interceptors.response.use(\n (response) => response,\n async (error) => {\n const retried = await this._retryAfterRefresh(instance, error as AxiosError);\n if (retried) return retried;\n this._handleAuthFailure(error as AxiosError);\n return Promise.reject(this._normalizeAxiosError(error));\n }\n );\n\n return instance;\n }\n\n /**\n * A bare 401 on a host with a silent refresh path (HttpOnly refresh cookie,\n * native device token) usually means the access token aged out mid-session.\n * Refresh once and replay the request with the new token instead of\n * signing the user out; a failed refresh falls through to the sign-out path.\n */\n private async _retryAfterRefresh(instance: AxiosInstance, error: AxiosError) {\n const config = error.config as (typeof error.config & { _banditAuthRetried?: boolean }) | undefined;\n if (!config || config._banditAuthRetried || error.response?.status !== 401) return null;\n if (!authenticationService.canRefresh()) return null;\n const data = error.response?.data as { code?: string } | undefined;\n if (data?.code && data.code !== \"TOKEN_EXPIRED\") return null;\n try {\n if (!(await authenticationService.tryRefresh())) return null;\n } catch {\n return null;\n }\n config._banditAuthRetried = true;\n return instance.request(config);\n }\n\n private _normalizeAxiosError(error: AxiosError): Error {\n if (error.response) {\n return this._createHttpError(\n `Request failed: ${error.response.status} ${error.response.statusText ?? \"\"}`,\n {\n status: error.response.status,\n statusText: error.response.statusText ?? \"\",\n data: error.response.data,\n url: error.config?.url ?? \"\"\n }\n );\n }\n\n if (error.request) {\n return new Error(`No response received from gateway: ${error.message}`);\n }\n\n return new Error(error.message);\n }\n\n private _handleAuthFailure(error: AxiosError): void {\n const status = error.response?.status;\n if (status !== 401 && status !== 403) {\n return;\n }\n\n const data = error.response?.data as { code?: string } | undefined;\n let code = data?.code;\n // A bare 401 means the token is dead (expired/invalid lifetime) even\n // without an explicit code — users were seeing raw \"lifetime validation\n // failed\" errors instead of the re-sign-in flow.\n if (status === 401 && !code) {\n code = \"TOKEN_EXPIRED\";\n }\n if (code !== \"FORCE_RELOGIN\" && code !== \"ACCOUNT_LOCKED\" && code !== \"TOKEN_EXPIRED\") {\n return;\n }\n\n try {\n authenticationService.clearToken();\n } catch {\n // ignore — clearing is best-effort\n }\n\n if (typeof window !== \"undefined\" && typeof window.dispatchEvent === \"function\") {\n window.dispatchEvent(new CustomEvent(\"auth:force-relogin\", { detail: { code } }));\n }\n }\n\n private _createHttpError(message: string, response: GatewayHttpErrorResponse): GatewayHttpError {\n return Object.assign(new Error(message), { response }) as GatewayHttpError;\n }\n\n private _setBaseUrl(url: string) {\n this._baseUrl = url;\n this._client.defaults.baseURL = url;\n }\n\n private _tryGatewayWithTimeout(args: {\n url: string,\n responseType: 'json' | 'text',\n timeoutMs: number,\n }): Observable<boolean> {\n const { url, responseType, timeoutMs } = args;\n const source = this._get(url, responseType)\n const mapped = source.pipe(\n catchError((e) => (e?.message.includes(\"401\") ? of(true) : of(false))),\n map(() => true),\n timeout(timeoutMs),\n );\n return mapped;\n }\n\n /**\n * Validates the availability of the gateway service.\n * @param fallbackUrl The fallback URL to try if the base URL is not available.\n * @returns An object containing the URL and availability status.\n */\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n const { fallbackUrl, timeoutMs } = args;\n const responseType = 'json';\n const availability = {\n url: \"\",\n isAvailable: false,\n }\n\n try {\n debugLogger.debug(`Validating gateway service availability at ${this._baseUrl}`);\n\n availability.url = this._baseUrl;\n availability.isAvailable = await lastValueFrom(\n this._tryGatewayWithTimeout({\n url: `${availability.url}/api/health`,\n responseType,\n timeoutMs,\n })\n ) as boolean;\n \n if (!availability.isAvailable) {\n throw new Error(`Gateway service not available at ${this._baseUrl}`);\n }\n\n return availability;\n } catch (e) {\n if (fallbackUrl) {\n debugLogger.warn(`Gateway service not available at ${this._baseUrl}, trying fallback URL: ${fallbackUrl}`);\n try {\n availability.url = fallbackUrl.replace(/\\/$/, '');\n availability.isAvailable = await lastValueFrom(\n this._tryGatewayWithTimeout({\n url: `${availability.url}/api/health`,\n responseType,\n timeoutMs,\n })\n ) as boolean;\n\n if (!availability.isAvailable) {\n throw new Error(`Gateway service not available at ${fallbackUrl}`);\n }\n \n this._setBaseUrl(availability.url);\n return availability;\n } catch (e) {\n debugLogger.error(`Gateway service not available at fallback URL: ${fallbackUrl}`);\n throw e;\n }\n } else {\n debugLogger.error(`Gateway service not available and no fallback URL provided`);\n throw e;\n }\n }\n }\n\n /**\n * Get gateway health status and available providers\n */\n getHealth(): Observable<GatewayHealthResponse> {\n const url = `${this._baseUrl}/api/health`;\n return this._get<GatewayHealthResponse>(url);\n }\n\n /**\n * Chat completion using the gateway API\n */\n chat(request: GatewayChatRequest): Observable<GatewayChatResponse> {\n // Use provider-specific endpoint if provider is specified\n // For Ollama specifically, use /chat instead of /chat/completions\n const endpoint =\n request.provider === 'ollama'\n ? `/api/${request.provider}/chat`\n : request.provider === 'playground'\n ? '/api/playground/chat/completions'\n : request.provider\n ? `/api/${request.provider}/chat/completions`\n : '/api/chat/completions';\n const fallbackEndpoint =\n request.provider === 'bandit' ? '/completions' : null;\n const normalizedModel =\n request.provider === 'bandit'\n ? (() => {\n const trimmed = (request.model ?? '').replace(/^bandit:/, '').trim();\n return trimmed !== '' ? trimmed : 'bandit-core-1';\n })()\n : request.model;\n \n const requestBody = { ...request, model: normalizedModel, stream: request.stream !== false };\n \n return new Observable<GatewayChatResponse>(observer => {\n const controller = new AbortController();\n const handleStreamingResponse = async (response: Response) => {\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n const lineParser = new StreamLineParser();\n let buffer = \"\";\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n const tail = lineParser.next(buffer);\n if (tail.kind === 'json') {\n try {\n const finalResponse = JSON.parse(tail.text);\n observer.next(finalResponse);\n } catch (err) {\n debugLogger.error('GatewayService chat final chunk parsing error', { buffer, error: err });\n observer.error(err);\n }\n }\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n // Handles both SSE (OpenAI-style) and NDJSON (Ollama-style), and\n // skips gateway keepalives (`: ping`, `event: ping`, whitespace).\n const classified = lineParser.next(line);\n if (classified.kind === 'done') {\n observer.complete();\n return;\n }\n if (classified.kind === 'json') {\n const trimmed = line.trim();\n const data = classified.text;\n try {\n const parsed = JSON.parse(data);\n \n // Transform Ollama chat format to OpenAI-compatible format\n if (request.provider === 'ollama' && parsed.message) {\n const transformed: GatewayChatResponse = {\n id: `chatcmpl-${Date.now()}`,\n object: 'chat.completion.chunk',\n created: Math.floor(new Date(parsed.created_at || Date.now()).getTime() / 1000),\n model: parsed.model,\n choices: [{\n index: 0,\n delta: {\n role: parsed.message.role,\n content: parsed.message.content,\n tool_calls: parsed.message.tool_calls\n },\n finish_reason: parsed.done ? (parsed.done_reason || 'stop') : null\n }]\n };\n \n if (parsed.done && parsed.total_duration) {\n transformed.usage = {\n prompt_tokens: parsed.prompt_eval_count || 0,\n completion_tokens: parsed.eval_count || 0,\n total_tokens: (parsed.prompt_eval_count || 0) + (parsed.eval_count || 0)\n };\n }\n \n observer.next(transformed);\n } else {\n // For non-Ollama providers or already transformed responses\n observer.next(parsed);\n }\n } catch (err) {\n debugLogger.error('GatewayService chat stream chunk parsing error', {\n line: trimmed,\n rawData: data,\n error: err\n });\n observer.error(err);\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n };\n\n const sendRequest = (targetEndpoint: string, allowFallback: boolean) => {\n const url = `${this._baseUrl}${targetEndpoint}`;\n\n debugLogger.debug(`Gateway chat request to ${url} with provider: ${request.provider || 'default'}`, {\n model: normalizedModel,\n messageCount: request.messages.length,\n hasImages: !!(request.images && request.images.length > 0),\n imageCount: request.images?.length || 0\n });\n\n fetch(url, {\n method: 'POST',\n headers: this._getHeaders(),\n body: JSON.stringify(requestBody),\n signal: controller.signal,\n })\n .then(async (response) => {\n debugLogger.debug(`Gateway chat response status: ${response.status} for provider: ${request.provider || 'default'}`);\n\n if (response.status === 404 && allowFallback && fallbackEndpoint) {\n debugLogger.warn('GatewayService chat endpoint returned 404, attempting fallback route', {\n provider: request.provider,\n attemptedEndpoint: targetEndpoint,\n fallbackEndpoint\n });\n sendRequest(fallbackEndpoint, false);\n return;\n }\n\n if (!response.ok) {\n // Handle error response properly with body parsing\n let errorText = '';\n let errorData: unknown = null;\n \n try {\n // First, try to read the response body\n errorText = await response.text();\n debugLogger.error('GatewayService chat error response body', {\n status: response.status,\n statusText: response.statusText,\n url: response.url,\n body: errorText\n });\n } catch (readError) {\n debugLogger.error('GatewayService chat failed to read error response body', { error: readError });\n errorText = `Request failed with status ${response.status}`;\n }\n \n // Then, try to parse as JSON for better error info\n try {\n errorData = JSON.parse(errorText);\n debugLogger.error('GatewayService chat parsed error payload', errorData);\n } catch (parseError) {\n debugLogger.error('GatewayService chat error payload was not valid JSON');\n errorData = { message: errorText };\n }\n \n // Create an error object that mimics an HTTP response error for the notification service\n const error = this._createHttpError(\n `POST ${url} failed: ${response.status} ${response.statusText ?? \"\"}`,\n {\n status: response.status,\n statusText: response.statusText ?? \"\",\n data: errorData,\n url\n }\n );\n \n throw error;\n }\n\n await handleStreamingResponse(response);\n })\n .catch(err => {\n debugLogger.error('GatewayService chat fetch error', {\n error: err,\n url,\n provider: request.provider\n });\n observer.error(err);\n });\n };\n\n sendRequest(endpoint, true);\n\n // Teardown: abort the request/stream on unsubscribe\n return () => {\n try { controller.abort(); } catch {}\n };\n });\n }\n\n /**\n * Text generation using the gateway API\n */\n generate(request: GatewayGenerateRequest): Observable<GatewayGenerateResponse> {\n // Use provider-specific endpoint if provider is specified\n const endpoint = request.provider ? `/api/${request.provider}/generate` : '/api/generate';\n const url = `${this._baseUrl}${endpoint}`;\n const normalizedModel =\n request.provider === 'bandit'\n ? (() => {\n const trimmed = (request.model ?? '').replace(/^bandit:/, '').trim();\n return trimmed !== '' ? trimmed : 'bandit-core-1';\n })()\n : request.model;\n \n debugLogger.debug(`Gateway generate request to ${url} with provider: ${request.provider || 'default'}`, {\n model: normalizedModel\n });\n \n return new Observable<GatewayGenerateResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: this._getHeaders(),\n body: JSON.stringify({ ...request, model: normalizedModel, stream: request.stream !== false }),\n });\n \n task.then(async (response) => {\n if (!response.ok) {\n // Handle error response properly with body parsing\n let errorText = '';\n let errorData: unknown = null;\n \n try {\n // First, try to read the response body\n errorText = await response.text();\n } catch (readError) {\n errorText = `Request failed with status ${response.status}`;\n }\n \n // Then, try to parse as JSON for better error info\n try {\n errorData = JSON.parse(errorText);\n } catch (parseError) {\n errorData = { message: errorText };\n }\n \n // Create an error object that mimics an HTTP response error for the notification service\n const error = this._createHttpError(\n `POST ${url} failed: ${response.status} ${response.statusText ?? \"\"}`,\n {\n status: response.status,\n statusText: response.statusText ?? \"\",\n data: errorData,\n url\n }\n );\n \n throw error;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n const lineParser = new StreamLineParser();\n let buffer = \"\";\n \n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n const tail = lineParser.next(buffer);\n if (tail.kind === 'json') {\n try {\n observer.next(JSON.parse(tail.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Final chunk parsing error (gateway generate):', { buffer });\n }\n }\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const classified = lineParser.next(line);\n if (classified.kind === 'done') {\n observer.complete();\n return;\n }\n if (classified.kind === 'json') {\n try {\n observer.next(JSON.parse(classified.text));\n } catch (err) {\n observer.error(err);\n debugLogger.error('Error parsing JSON line (gateway generate):', { line });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n })\n .catch(err => observer.error(err));\n });\n }\n\n /**\n * List all available models from all providers\n */\n listModels(): Observable<GatewayModel[]> {\n const url = `${this._baseUrl}/api/models`;\n const response = this._get<GatewayModelsResponse>(url);\n const result = response.pipe(\n map(data => data.models),\n shareReplay(1)\n );\n return result;\n }\n\n /**\n * List models for a specific provider\n */\n listModelsByProvider(provider: string): Observable<GatewayModel[]> {\n const url = `${this._baseUrl}/api/models/${provider}`;\n const response = this._get<GatewayModelsResponse>(url);\n const result = response.pipe(\n map(data => data.models),\n shareReplay(1)\n );\n return result;\n }\n\n getMemory(): Observable<GatewayMemoryResponse> {\n const url = `${this._baseUrl}/api/memory`;\n return this._get<GatewayMemoryResponse>(url);\n }\n\n private _get<T>(url: string, responseType: 'json' | 'text' = 'json'): Observable<T> {\n const request = this._client.get<T>(url, { responseType });\n return from(request).pipe(\n map(response => response.data as T),\n shareReplay(1)\n );\n }\n\n private _post<TRequest, TResponse>(url: string, body: TRequest): Observable<TResponse> {\n const request = this._client.post<TResponse>(url, body);\n return from(request).pipe(\n map(response => response.data),\n shareReplay(1)\n );\n }\n\n private _getHeaders() {\n const rawToken = this._tokenFactory();\n const headers: { [key: string]: string } = {\n 'Content-Type': 'application/json'\n };\n\n if (!rawToken) {\n debugLogger.warn('GatewayService: No token found, skipping Authorization header');\n return headers;\n }\n\n const token = rawToken.trim();\n if (token === '') {\n debugLogger.warn('GatewayService: Token factory returned empty string');\n return headers;\n }\n\n if (/^(Bearer|ApiKey)\\s+/i.test(token)) {\n headers['Authorization'] = token;\n debugLogger.debug('GatewayService: Authorization header set with explicit scheme');\n return headers;\n }\n\n if (this._isLikelyBanditApiKey(token)) {\n headers['Authorization'] = `ApiKey ${token}`;\n headers['X-Burtson-Api-Key'] = token;\n debugLogger.debug('GatewayService: Authorization header set using API key');\n return headers;\n }\n\n if (this._isLikelyJwt(token)) {\n headers['Authorization'] = `Bearer ${token}`;\n debugLogger.debug('GatewayService: Authorization header set using bearer token');\n return headers;\n }\n\n // Default to bearer scheme to avoid breaking other providers\n headers['Authorization'] = `Bearer ${token}`;\n debugLogger.debug('GatewayService: Authorization header defaulted to bearer scheme');\n return headers;\n }\n\n private _isLikelyJwt(token: string): boolean {\n const segments = token.split('.');\n return segments.length === 3 && segments.every((segment) => segment.length > 0);\n }\n\n private _isLikelyBanditApiKey(value: string): boolean {\n return /^bai_[a-z0-9]{10,}$/i.test(value);\n }\n\n /**\n * Submit feedback to the gateway API\n */\n submitFeedback(feedback: FeedbackRequest): Observable<FeedbackResponse> {\n const url = `${this._baseUrl}/api/feedback`;\n \n debugLogger.debug('Gateway feedback submission', {\n category: feedback.category,\n priority: feedback.priority,\n hasImages: !!(feedback.images && feedback.images.length > 0),\n hasAttachments: !!(feedback.attachments && feedback.attachments.length > 0)\n });\n\n return from(\n this._client.post<FeedbackResponse>(url, feedback).then(response => response.data)\n ).pipe(\n catchError(error => {\n debugLogger.error('Feedback submission failed, using email fallback', error);\n\n const fallbackResponse: FeedbackResponse = {\n id: `fallback-${Date.now()}`,\n status: 'submitted',\n message: 'Feedback submission failed. Opening email client as fallback.',\n mailtoUrl: this._generateMailtoUrl(feedback)\n };\n return of(fallbackResponse);\n })\n );\n }\n\n /**\n * Generate a mailto URL as fallback for feedback submission\n */\n private _generateMailtoUrl(feedback: FeedbackRequest): string {\n const subject = encodeURIComponent(`[${feedback.category.toUpperCase()}] ${feedback.title}`);\n \n let body = `Category: ${feedback.category}\\n`;\n body += `Priority: ${feedback.priority}\\n`;\n \n if (feedback.annoyanceLevel) {\n const annoyanceLabels = {\n 1: '😊 Not annoying at all',\n 2: '😐 Slightly annoying',\n 3: '🙄 Moderately annoying', \n 4: '😠 Very annoying',\n 5: '🤬 Extremely annoying'\n };\n body += `Annoyance Level: ${feedback.annoyanceLevel}/5 - ${annoyanceLabels[feedback.annoyanceLevel as keyof typeof annoyanceLabels]}\\n`;\n }\n \n body += `\\nDescription:\\n${feedback.description}\\n\\n`;\n \n if (feedback.sessionInfo) {\n body += `Session Info:\\n`;\n body += `- Model: ${feedback.sessionInfo.currentModel}\\n`;\n body += `- Provider: ${feedback.sessionInfo.currentProvider}\\n`;\n body += `- Conversation: ${feedback.sessionInfo.conversationId}\\n`;\n body += `- Timestamp: ${feedback.sessionInfo.timestamp}\\n\\n`;\n }\n \n if (feedback.browserInfo) {\n body += `Browser Info:\\n`;\n body += `- Name: ${feedback.browserInfo.name}\\n`;\n body += `- Version: ${feedback.browserInfo.version}\\n`;\n body += `- Platform: ${feedback.browserInfo.platform}\\n\\n`;\n }\n \n if (feedback.userAgent) {\n body += `User Agent: ${feedback.userAgent}\\n\\n`;\n }\n \n if (feedback.contactEmail) {\n body += `Contact Email: ${feedback.contactEmail}\\n\\n`;\n }\n \n if (feedback.images && feedback.images.length > 0) {\n body += `📎 IMAGE ATTACHMENT:\\n`;\n body += `Please paste your clipboard contents here (Ctrl+V or Cmd+V)\\n\\n`;\n }\n \n if (feedback.attachments && feedback.attachments.length > 0) {\n body += `📎 IMPORTANT - FILES TO ATTACH:\\n`;\n body += `Please attach the following ${feedback.attachments.length} file(s) to this email:\\n`;\n feedback.attachments.forEach((attachment, index) => {\n body += ` • File ${index + 1}: ${attachment.name || `[Attachment ${index + 1}]`}\\n`;\n });\n body += `\\n(Note: Files cannot be automatically included in email links)\\n\\n`;\n }\n \n body += `---\\nGenerated by Bandit AI Feedback System`;\n \n const encodedBody = encodeURIComponent(body);\n const toEmail = this._feedbackEmail || 'feedback@burtson.ai'; // Use custom email or default\n \n return `mailto:${toEmail}?subject=${subject}&body=${encodedBody}`;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { GatewayService } from './gateway.service';\nimport { GatewayChatRequest, GatewayChatResponse, GatewayGenerateRequest, GatewayGenerateResponse, GatewayModel } from './interfaces';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface OpenAIMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n name?: string;\n}\n\nexport interface OpenAIChatRequest {\n model: string;\n messages: OpenAIMessage[];\n stream?: boolean;\n temperature?: number;\n max_tokens?: number;\n top_p?: number;\n frequency_penalty?: number;\n presence_penalty?: number;\n stop?: string | string[];\n}\n\nexport class OpenAIGatewayService {\n private _gatewayService: GatewayService;\n\n constructor(\n gatewayUrl: string,\n tokenFactory: () => string | null\n ) {\n this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);\n debugLogger.info('OpenAIGatewayService initialized', { gatewayUrl });\n }\n\n /**\n * Validates the availability of the gateway service for OpenAI\n */\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n return this._gatewayService.validateServiceAvailability(args);\n }\n\n /**\n * Chat completion using OpenAI through the gateway\n */\n chat(request: OpenAIChatRequest): Observable<GatewayChatResponse> {\n const gatewayRequest: GatewayChatRequest = {\n ...request,\n provider: 'openai'\n };\n\n debugLogger.debug('OpenAI Gateway chat request', { \n model: request.model, \n messageCount: request.messages.length,\n stream: request.stream \n });\n\n return this._gatewayService.chat(gatewayRequest);\n }\n\n /**\n * Text completion using OpenAI through the gateway\n */\n complete(prompt: string, options: {\n model: string;\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n stop?: string | string[];\n }): Observable<GatewayGenerateResponse> {\n const gatewayRequest: GatewayGenerateRequest = {\n model: options.model,\n prompt,\n temperature: options.temperature,\n max_tokens: options.max_tokens,\n stream: options.stream,\n stop: options.stop,\n provider: 'openai'\n };\n\n debugLogger.debug('OpenAI Gateway completion request', { \n model: options.model, \n promptLength: prompt.length,\n stream: options.stream \n });\n\n return this._gatewayService.generate(gatewayRequest);\n }\n\n /**\n * List available OpenAI models through the gateway\n */\n listModels(): Observable<GatewayModel[]> {\n debugLogger.debug('Fetching OpenAI models through gateway');\n return this._gatewayService.listModelsByProvider('openai');\n }\n\n /**\n * Get gateway health with OpenAI provider status\n */\n getHealth() {\n return this._gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n openai_status: health.providers.find(p => p.name === 'openai')?.status || 'unavailable'\n }))\n );\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { GatewayService } from './gateway.service';\nimport { GatewayChatRequest, GatewayChatResponse, GatewayGenerateRequest, GatewayGenerateResponse, GatewayModel } from './interfaces';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface AzureOpenAIMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n name?: string;\n}\n\nexport interface AzureOpenAIChatRequest {\n model: string; // This will be the deployment name for Azure\n messages: AzureOpenAIMessage[];\n stream?: boolean;\n temperature?: number;\n max_tokens?: number;\n top_p?: number;\n frequency_penalty?: number;\n presence_penalty?: number;\n stop?: string | string[];\n}\n\nexport interface AzureOpenAIConfig {\n deploymentName: string;\n apiVersion: string;\n resourceName?: string; // For endpoint construction if needed\n}\n\nexport class AzureOpenAIGatewayService {\n private _gatewayService: GatewayService;\n private _azureConfig: AzureOpenAIConfig;\n\n constructor(\n gatewayUrl: string,\n tokenFactory: () => string | null,\n azureConfig: AzureOpenAIConfig\n ) {\n this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);\n this._azureConfig = azureConfig;\n debugLogger.info('AzureOpenAIGatewayService initialized', { \n gatewayUrl, \n deploymentName: azureConfig.deploymentName,\n apiVersion: azureConfig.apiVersion \n });\n }\n\n /**\n * Validates the availability of the gateway service for Azure OpenAI\n */\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n return this._gatewayService.validateServiceAvailability(args);\n }\n\n /**\n * Chat completion using Azure OpenAI through the gateway\n */\n chat(request: AzureOpenAIChatRequest): Observable<GatewayChatResponse> {\n const gatewayRequest: GatewayChatRequest = {\n ...request,\n model: this._azureConfig.deploymentName, // Use deployment name as model\n provider: 'azure-openai'\n };\n\n debugLogger.debug('Azure OpenAI Gateway chat request', { \n deploymentName: this._azureConfig.deploymentName,\n apiVersion: this._azureConfig.apiVersion,\n messageCount: request.messages.length,\n stream: request.stream \n });\n\n return this._gatewayService.chat(gatewayRequest);\n }\n\n /**\n * Text completion using Azure OpenAI through the gateway\n */\n complete(prompt: string, options: {\n model?: string; // Optional override for deployment name\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n stop?: string | string[];\n }): Observable<GatewayGenerateResponse> {\n const gatewayRequest: GatewayGenerateRequest = {\n model: options.model || this._azureConfig.deploymentName,\n prompt,\n temperature: options.temperature,\n max_tokens: options.max_tokens,\n stream: options.stream,\n stop: options.stop,\n provider: 'azure-openai'\n };\n\n debugLogger.debug('Azure OpenAI Gateway completion request', { \n deploymentName: options.model || this._azureConfig.deploymentName,\n promptLength: prompt.length,\n stream: options.stream \n });\n\n return this._gatewayService.generate(gatewayRequest);\n }\n\n /**\n * List available Azure OpenAI models through the gateway\n */\n listModels(): Observable<GatewayModel[]> {\n debugLogger.debug('Fetching Azure OpenAI models through gateway');\n return this._gatewayService.listModelsByProvider('azure-openai');\n }\n\n /**\n * Get gateway health with Azure OpenAI provider status\n */\n getHealth() {\n return this._gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n azure_openai_status: health.providers.find(p => p.name === 'azure-openai')?.status || 'unavailable',\n azure_config: {\n deploymentName: this._azureConfig.deploymentName,\n apiVersion: this._azureConfig.apiVersion\n }\n }))\n );\n }\n\n /**\n * Update Azure configuration\n */\n updateAzureConfig(newConfig: Partial<AzureOpenAIConfig>) {\n this._azureConfig = { ...this._azureConfig, ...newConfig };\n debugLogger.info('Azure OpenAI configuration updated', this._azureConfig);\n }\n\n /**\n * Get current Azure configuration\n */\n getAzureConfig(): AzureOpenAIConfig {\n return { ...this._azureConfig };\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { GatewayService } from './gateway.service';\nimport { GatewayChatRequest, GatewayChatResponse, GatewayGenerateRequest, GatewayGenerateResponse, GatewayModel } from './interfaces';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface AnthropicMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n name?: string;\n}\n\nexport interface AnthropicChatRequest {\n model: string;\n messages: AnthropicMessage[];\n stream?: boolean;\n temperature?: number;\n max_tokens?: number;\n top_p?: number;\n stop_sequences?: string[];\n system?: string; // Anthropic uses separate system parameter\n}\n\nexport class AnthropicGatewayService {\n private _gatewayService: GatewayService;\n\n constructor(\n gatewayUrl: string,\n tokenFactory: () => string | null\n ) {\n this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);\n debugLogger.info('AnthropicGatewayService initialized', { gatewayUrl });\n }\n\n /**\n * Validates the availability of the gateway service for Anthropic\n */\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n return this._gatewayService.validateServiceAvailability(args);\n }\n\n /**\n * Chat completion using Anthropic through the gateway\n */\n chat(request: AnthropicChatRequest): Observable<GatewayChatResponse> {\n // Convert Anthropic-specific request to gateway format\n const gatewayRequest: GatewayChatRequest = {\n model: request.model,\n messages: request.messages,\n stream: request.stream,\n temperature: request.temperature,\n max_tokens: request.max_tokens,\n top_p: request.top_p,\n stop: request.stop_sequences,\n provider: 'anthropic'\n };\n\n debugLogger.debug('Anthropic Gateway chat request', { \n model: request.model, \n messageCount: request.messages.length,\n stream: request.stream,\n hasSystem: !!request.system\n });\n\n return this._gatewayService.chat(gatewayRequest);\n }\n\n /**\n * Text completion using Anthropic through the gateway\n */\n complete(prompt: string, options: {\n model: string;\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n stop_sequences?: string[];\n system?: string;\n }): Observable<GatewayGenerateResponse> {\n const gatewayRequest: GatewayGenerateRequest = {\n model: options.model,\n prompt,\n temperature: options.temperature,\n max_tokens: options.max_tokens,\n stream: options.stream,\n stop: options.stop_sequences,\n provider: 'anthropic'\n };\n\n debugLogger.debug('Anthropic Gateway completion request', { \n model: options.model, \n promptLength: prompt.length,\n stream: options.stream,\n hasSystem: !!options.system\n });\n\n return this._gatewayService.generate(gatewayRequest);\n }\n\n /**\n * List available Anthropic models through the gateway\n */\n listModels(): Observable<GatewayModel[]> {\n debugLogger.debug('Fetching Anthropic models through gateway');\n return this._gatewayService.listModelsByProvider('anthropic');\n }\n\n /**\n * Get gateway health with Anthropic provider status\n */\n getHealth() {\n return this._gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n anthropic_status: health.providers.find(p => p.name === 'anthropic')?.status || 'unavailable'\n }))\n );\n }\n\n /**\n * Helper method to convert system message to Anthropic format\n * Anthropic treats system messages differently - they can be separate from messages\n */\n private extractSystemMessage(messages: AnthropicMessage[]): { messages: AnthropicMessage[], system?: string } {\n const systemMessage = messages.find(msg => msg.role === 'system');\n const userMessages = messages.filter(msg => msg.role !== 'system');\n \n return {\n messages: userMessages,\n system: systemMessage?.content\n };\n }\n\n /**\n * Enhanced chat method that handles Anthropic's system message format\n */\n chatWithSystem(request: AnthropicChatRequest): Observable<GatewayChatResponse> {\n const { messages, system } = this.extractSystemMessage(request.messages);\n \n const enhancedRequest: AnthropicChatRequest = {\n ...request,\n messages,\n system: system || request.system\n };\n\n return this.chat(enhancedRequest);\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { GatewayService } from './gateway.service';\nimport { GatewayChatRequest, GatewayChatResponse, GatewayGenerateRequest, GatewayGenerateResponse, GatewayModel } from './interfaces';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface OllamaMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n images?: string[]; // Ollama supports image inputs\n}\n\nexport interface OllamaChatRequest {\n model: string;\n messages: OllamaMessage[];\n stream?: boolean;\n options?: Record<string, unknown>;\n images?: string[];\n}\n\nexport interface OllamaGenerateRequest {\n model: string;\n prompt: string;\n stream?: boolean;\n images?: string[];\n options?: Record<string, unknown>;\n}\n\nexport class OllamaGatewayService {\n private _gatewayService: GatewayService;\n\n constructor(\n gatewayUrl: string,\n tokenFactory: () => string | null\n ) {\n this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);\n debugLogger.info('OllamaGatewayService initialized', { gatewayUrl });\n }\n\n /**\n * Validates the availability of the gateway service for Ollama\n */\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string, isAvailable: boolean }> {\n return this._gatewayService.validateServiceAvailability(args);\n }\n\n /**\n * Chat completion using Ollama through the gateway\n */\n chat(request: OllamaChatRequest): Observable<GatewayChatResponse> {\n const gatewayRequest: GatewayChatRequest = {\n ...request,\n provider: 'ollama'\n };\n\n debugLogger.debug('Ollama Gateway chat request', { \n model: request.model, \n messageCount: request.messages.length,\n stream: request.stream,\n hasImages: !!(request.images && request.images.length > 0)\n });\n\n return this._gatewayService.chat(gatewayRequest);\n }\n\n /**\n * Text generation using Ollama through the gateway\n */\n generate(request: OllamaGenerateRequest): Observable<GatewayGenerateResponse> {\n const gatewayRequest: GatewayGenerateRequest = {\n ...request,\n provider: 'ollama'\n };\n\n debugLogger.debug('Ollama Gateway generate request', { \n model: request.model, \n promptLength: request.prompt.length,\n stream: request.stream,\n hasImages: !!(request.images && request.images.length > 0)\n });\n\n return this._gatewayService.generate(gatewayRequest);\n }\n\n /**\n * List available Ollama models through the gateway\n */\n listModels(): Observable<GatewayModel[]> {\n debugLogger.debug('Fetching Ollama models through gateway');\n return this._gatewayService.listModelsByProvider('ollama');\n }\n\n /**\n * Get gateway health with Ollama provider status\n */\n getHealth() {\n return this._gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n ollama_status: health.providers.find(p => p.name === 'ollama')?.status || 'unavailable'\n }))\n );\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { GatewayService } from './gateway.service';\nimport {\n GatewayChatRequest,\n GatewayChatResponse,\n GatewayGenerateRequest,\n GatewayGenerateResponse,\n GatewayMessage,\n GatewayMessageContent,\n GatewayModel\n} from './interfaces';\nimport { Observable } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface BanditAIChatRequest {\n model: string;\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: unknown }>;\n stream?: boolean;\n temperature?: number;\n max_tokens?: number;\n top_p?: number;\n stop?: string | string[];\n}\n\nconst normalizeBanditModel = (model: string | undefined): string => {\n if (typeof model !== 'string' || model.trim() === '') {\n return 'bandit-core-1';\n }\n const normalized = model.replace(/^bandit:/, '').trim();\n return normalized === '' ? 'bandit-core-1' : normalized;\n};\n\nconst isGatewayMessageContent = (value: unknown): value is GatewayMessageContent => {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as GatewayMessageContent;\n if (candidate.type !== 'text' && candidate.type !== 'image_url') {\n return false;\n }\n if (candidate.type === 'text') {\n return typeof candidate.text === 'string';\n }\n if (candidate.type === 'image_url') {\n return !!candidate.image_url && typeof candidate.image_url.url === 'string';\n }\n return false;\n};\n\nconst normalizeBanditMessages = (\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: unknown }>\n): GatewayMessage[] =>\n messages.map((message) => {\n const content = message.content;\n if (typeof content === 'string') {\n return { role: message.role, content };\n }\n if (Array.isArray(content)) {\n const filtered = content.filter(isGatewayMessageContent);\n if (filtered.length === 0) {\n return { role: message.role, content: JSON.stringify(content) };\n }\n return {\n role: message.role,\n content: filtered\n };\n }\n return { role: message.role, content: content != null ? String(content) : '' };\n });\n\nexport class BanditAIGatewayService {\n private _gatewayService: GatewayService;\n\n constructor(\n gatewayUrl: string,\n tokenFactory: () => string | null\n ) {\n this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);\n debugLogger.info('BanditAIGatewayService initialized', { gatewayUrl });\n }\n\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string; isAvailable: boolean }> {\n return this._gatewayService.validateServiceAvailability(args);\n }\n\n chat(request: BanditAIChatRequest): Observable<GatewayChatResponse> {\n const model = normalizeBanditModel(request.model);\n const messages = normalizeBanditMessages(request.messages);\n const gatewayRequest: GatewayChatRequest = {\n ...request,\n messages,\n model,\n provider: 'bandit',\n stream: request.stream\n };\n\n debugLogger.debug('Bandit Gateway chat request', {\n model,\n messageCount: request.messages.length,\n stream: request.stream\n });\n\n return this._gatewayService.chat(gatewayRequest);\n }\n\n complete(prompt: string, options: {\n model: string;\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n stop?: string | string[];\n }): Observable<GatewayGenerateResponse> {\n const model = normalizeBanditModel(options.model);\n const gatewayRequest: GatewayGenerateRequest = {\n model,\n prompt,\n temperature: options.temperature,\n max_tokens: options.max_tokens,\n stream: options.stream,\n stop: options.stop,\n provider: 'bandit'\n };\n\n debugLogger.debug('Bandit Gateway generate request', {\n model,\n promptLength: prompt.length,\n stream: options.stream\n });\n\n return this._gatewayService.generate(gatewayRequest);\n }\n\n listModels(): Observable<GatewayModel[]> {\n debugLogger.debug('Fetching Bandit models through gateway');\n return this._gatewayService.listModelsByProvider('bandit');\n }\n\n getHealth() {\n return this._gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n bandit_status: health.providers.find(p => p.name === 'bandit')?.status || 'unavailable'\n }))\n );\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, map } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\nimport { GatewayService } from '../../gateway/gateway.service';\nimport { OpenAIGatewayService } from '../../gateway/openai-gateway.service';\nimport { AzureOpenAIGatewayService } from '../../gateway/azure-openai-gateway.service';\nimport { AnthropicGatewayService } from '../../gateway/anthropic-gateway.service';\nimport { OllamaGatewayService } from '../../gateway/ollama-gateway.service';\nimport { BanditAIGatewayService } from '../../gateway/bandit-gateway.service';\nimport {\n GatewayChatRequest,\n GatewayMessage,\n GatewayMessageContent,\n GatewayTool\n} from '../../gateway/interfaces';\n\n/**\n * Gateway provider implementation that routes requests through the .NET gateway API\n * This consolidates all AI provider logic behind a single gateway endpoint\n */\nexport class GatewayProvider implements IAIProvider {\n private config: AIProviderConfig;\n private gatewayService: GatewayService;\n private providerSpecificService: OpenAIGatewayService | AzureOpenAIGatewayService | AnthropicGatewayService | OllamaGatewayService | BanditAIGatewayService | null = null;\n\n constructor(config: AIProviderConfig) {\n this.config = config;\n \n if (!config.gatewayUrl) {\n throw new Error('Gateway provider requires gatewayUrl in config');\n }\n \n if (!config.provider) {\n throw new Error('Gateway provider requires provider field to specify backend (openai, azure-openai, anthropic, ollama)');\n }\n\n const tokenFactory = config.tokenFactory || (() => null);\n this.gatewayService = new GatewayService(config.gatewayUrl, tokenFactory);\n\n // Create provider-specific service for enhanced functionality\n this.createProviderSpecificService(config.gatewayUrl, tokenFactory);\n\n debugLogger.info('GatewayProvider initialized', { \n gatewayUrl: config.gatewayUrl,\n backendProvider: config.provider\n });\n }\n\n private createProviderSpecificService(gatewayUrl: string, tokenFactory: () => string | null) {\n switch (this.config.provider) {\n case 'openai':\n this.providerSpecificService = new OpenAIGatewayService(gatewayUrl, tokenFactory);\n break;\n case 'azure-openai':\n if (!this.config.deploymentName || !this.config.apiVersion) {\n throw new Error('Azure OpenAI gateway provider requires deploymentName and apiVersion');\n }\n this.providerSpecificService = new AzureOpenAIGatewayService(\n gatewayUrl, \n tokenFactory,\n {\n deploymentName: this.config.deploymentName,\n apiVersion: this.config.apiVersion\n }\n );\n break;\n case 'anthropic':\n this.providerSpecificService = new AnthropicGatewayService(gatewayUrl, tokenFactory);\n break;\n case 'bandit':\n this.providerSpecificService = new BanditAIGatewayService(gatewayUrl, tokenFactory);\n break;\n case 'ollama':\n this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);\n break;\n case 'playground':\n // Preview gateway uses custom routing; no provider-specific service\n this.providerSpecificService = null;\n break;\n default:\n debugLogger.warn('Unknown provider for gateway, using generic gateway service', { \n provider: this.config.provider \n });\n }\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n // Convert AI request to standardized gateway request format\n // The gateway API will handle provider-specific transformations\n \n const messages: GatewayMessage[] = request.messages.map(msg => ({\n role: msg.role,\n content: msg.content\n }));\n \n // Handle images based on provider type\n const normalizeImageUrl = (value: string) => {\n if (!value) {\n return value;\n }\n const trimmed = value.trim();\n if (/^data:/i.test(trimmed) || /^https?:\\/\\//i.test(trimmed)) {\n return trimmed;\n }\n return `data:image/jpeg;base64,${trimmed}`;\n };\n\n if (request.images && request.images.length > 0) {\n const lastUserMessageIndex = messages.map(m => m.role).lastIndexOf('user');\n\n if (this.config.provider === 'ollama') {\n // Ollama: attach images directly to the last user message\n if (lastUserMessageIndex !== -1) {\n messages[lastUserMessageIndex] = {\n ...messages[lastUserMessageIndex],\n images: request.images\n };\n }\n } else if (['openai', 'azure-openai', 'anthropic', 'bandit', 'playground'].includes(this.config.provider || '')) {\n // OpenAI/Azure/Anthropic: convert to structured content format\n if (lastUserMessageIndex !== -1) {\n const currentMessage = messages[lastUserMessageIndex];\n const contentArray: GatewayMessageContent[] = [\n {\n type: 'text',\n text: currentMessage.content as string\n }\n ];\n\n // Add images as image_url content\n request.images.forEach(imageRef => {\n contentArray.push({\n type: 'image_url',\n image_url: {\n url: normalizeImageUrl(imageRef),\n detail: 'auto'\n }\n });\n });\n\n messages[lastUserMessageIndex] = {\n ...messages[lastUserMessageIndex],\n content: contentArray\n };\n debugLogger.debug('Gateway provider injected image attachments', {\n provider: this.config.provider,\n imageCount: request.images.length,\n messageIndex: lastUserMessageIndex\n });\n }\n }\n }\n \n const toolAwareRequest = request as AIChatRequest & { tools?: GatewayTool[] };\n\n const gatewayRequest: GatewayChatRequest = {\n model: request.model,\n messages,\n stream: request.stream,\n temperature: request.temperature,\n max_tokens: request.maxTokens,\n provider: this.config.provider,\n // Only include top-level images for Ollama (fallback)\n images: this.config.provider === 'ollama' ? request.images : undefined,\n tools: toolAwareRequest.tools?.length ? toolAwareRequest.tools : undefined\n };\n\n debugLogger.debug('Gateway provider chat request', { \n model: request.model,\n provider: this.config.provider,\n messageCount: request.messages.length,\n stream: request.stream,\n hasImages: !!(request.images && request.images.length > 0),\n imageCount: request.images?.length || 0,\n imageStrategy: this.config.provider === 'ollama' \n ? 'message-level-array' \n : ['openai', 'azure-openai', 'anthropic', 'playground'].includes(this.config.provider || '')\n ? 'structured-content'\n : 'top-level-fallback',\n finalMessages: messages.map(m => ({ \n role: m.role, \n hasImages: Array.isArray(m.images) && m.images.length > 0,\n contentType: Array.isArray(m.content) ? 'structured' : 'text'\n }))\n });\n\n return this.gatewayService.chat(gatewayRequest).pipe(\n map(response => {\n const choice = response.choices?.[0];\n const toolCalls = choice?.message?.tool_calls ?? choice?.delta?.tool_calls;\n return {\n message: {\n content: choice?.message?.content ?? choice?.delta?.content ?? '',\n role: 'assistant' as const,\n tool_calls: toolCalls\n },\n done: choice?.finish_reason === 'stop' || choice?.finish_reason === 'length' || choice?.finish_reason === 'tool_calls'\n };\n })\n );\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n const gatewayRequest = {\n model: request.model,\n prompt: request.prompt,\n stream: request.stream,\n provider: this.config.provider\n };\n\n debugLogger.debug('Gateway provider generate request', { \n model: request.model,\n provider: this.config.provider,\n promptLength: request.prompt.length,\n stream: request.stream \n });\n\n return this.gatewayService.generate(gatewayRequest).pipe(\n map(response => ({\n response: response.response || '',\n done: response.done || false\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n debugLogger.debug('Gateway provider listing models', { provider: this.config.provider });\n \n if (this.config.provider) {\n return this.gatewayService.listModelsByProvider(this.config.provider).pipe(\n map(models => models.map(model => ({\n name: model.id || model.name,\n size: model.size,\n details: model.details,\n digest: model.digest,\n modified_at: model.modified_at\n })))\n );\n } else {\n // List all models from all providers\n return this.gatewayService.listModels().pipe(\n map(models => models.map(model => ({\n name: model.id || model.name,\n size: model.size,\n details: model.details,\n digest: model.digest,\n modified_at: model.modified_at\n })))\n );\n }\n }\n\n async validateServiceAvailability(args: { \n fallbackUrl?: string; \n timeoutMs: number; \n }): Promise<{ url: string; isAvailable: boolean }> {\n debugLogger.debug('Gateway provider validating service availability');\n return this.gatewayService.validateServiceAvailability(args);\n }\n\n getProviderType(): string {\n return AIProviderType.GATEWAY;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n /**\n * Get the backend provider type\n */\n getBackendProvider(): string | undefined {\n return this.config.provider;\n }\n\n /**\n * Get gateway health including backend provider status\n */\n getHealth() {\n return this.gatewayService.getHealth().pipe(\n map(health => ({\n ...health,\n backend_provider: this.config.provider,\n backend_provider_status: health.providers.find(p => p.name === this.config.provider)?.status || 'unavailable'\n }))\n );\n }\n\n /**\n * Use provider-specific service if available for enhanced functionality\n */\n getProviderSpecificService(): OpenAIGatewayService | AzureOpenAIGatewayService | AnthropicGatewayService | OllamaGatewayService | BanditAIGatewayService | null {\n return this.providerSpecificService;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\n\ntype PlaygroundScript = {\n match: (input: string) => boolean;\n response: string;\n};\n\nconst PLAYGROUND_MODELS: AIModel[] = [\n {\n name: 'bandit-playground',\n details: {\n format: 'chat',\n family: 'bandit',\n families: ['bandit', 'demo'],\n parameter_size: 'demo',\n quantization_level: 'synthetic'\n },\n digest: 'playground-demo-001',\n modified_at: new Date().toISOString()\n },\n {\n name: 'bandit-starter',\n details: {\n format: 'chat',\n family: 'bandit',\n families: ['bandit', 'demo'],\n parameter_size: 'demo',\n quantization_level: 'synthetic'\n },\n digest: 'playground-demo-002',\n modified_at: new Date().toISOString()\n }\n];\n\nconst PLAYGROUND_CONVERSATION_STARTERS = [\n 'What can I build with Bandit Engine if my backend is not ready yet?',\n 'How does the gateway contract keep API keys out of the browser?',\n 'Can I theme the chat UI to match my product brand?',\n 'How do I switch between Ollama and OpenAI without redeploying the frontend?',\n 'Show me how the management console handles personas and models.'\n];\n\nconst PLAYGROUND_SCRIPTS: PlaygroundScript[] = [\n {\n match: (input) => /model|switch|personas|management/i.test(input),\n response: [\n \"Absolutely — the management console ships with live model switching, persona editing, and feature toggles.\",\n \"\",\n \"- Use the **Models** tab to expose whichever gateway-backed models you want customers to see.\",\n \"- Personas hydrate the chat with branded system prompts, voice preferences, and avatars.\",\n \"- Everything persists through the gateway, so you can roll out changes without shipping a new build.\"\n ].join('\\n')\n },\n {\n match: (input) => /gateway|api|contract|backend/i.test(input),\n response: [\n \"The gateway contract keeps secrets on the server while giving the UI a unified AI API.\",\n \"\",\n \"Key highlights:\",\n \"1. `/api/chat/completions` is the default OpenAI-format endpoint when no provider override is set.\",\n \"2. `/api/{provider}/chat/completions` handles OpenAI, Azure OpenAI, and Anthropic while `/api/ollama/chat` streams Ollama responses.\",\n \"3. The contract is language-agnostic — Express, FastAPI, .NET, Go… anything works as long as it speaks HTTP.\"\n ].join('\\n')\n },\n {\n match: (input) => /style|theme|brand|ui/i.test(input),\n response: [\n \"Every surface in Bandit Engine is themeable.\",\n \"\",\n \"- Drop a JSON config into your `public/` folder (or host it on a CDN) to control themes, logos, and accent colors.\",\n \"- The React components expose hooks for custom headers, menus, and call-to-action buttons.\",\n \"- Need a modal? `ChatModal` reuses the same store, so the handoff between embedded chat and floating assistant stays seamless.\"\n ].join('\\n')\n },\n {\n match: (input) => /voice|tts|audio/i.test(input),\n response: [\n \"Voice is opt-in, but the plumbing is ready.\",\n \"\",\n \"- Configure `/api/tts` and `/api/stt` on the gateway to unlock the speak/listen controls.\",\n \"- The UI lazily loads voices and respects feature flags, so you can leave it disabled in the playground.\",\n \"- Everything streams — the assistant starts speaking before the full response lands.\"\n ].join('\\n')\n },\n {\n match: (input) => /deploy|production|secure/i.test(input),\n response: [\n \"Production hardening is front and center.\",\n \"\",\n \"- Gateway tokens ride in the `Authorization` header; rotate them server-side without touching the bundle.\",\n \"- Feature flags gate premium surfaces, letting you trial the UI before wiring billing.\",\n \"- Vector search, knowledge, and memories are isolated behind `/api/embedding/*` so you can plug in your own storage policies.\"\n ].join('\\n')\n }\n];\n\nconst FALLBACK_RESPONSE = [\n \"Bandit Engine is running in playground mode. I'm simulating how streaming works so you can explore the UX without connecting a live model.\",\n \"\",\n \"Try asking about the gateway contract, theming, voice features, or model management to see tailored walkthroughs.\"\n].join('\\n');\n\nconst STREAM_DELAY_MS = 350;\n\nexport class PlaygroundProvider implements IAIProvider {\n private config: AIProviderConfig;\n\n constructor(config: AIProviderConfig) {\n this.config = { ...config, type: config.type ?? AIProviderType.PLAYGROUND };\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const lastUserMessage = [...request.messages]\n .reverse()\n .find((m) => m.role === 'user')?.content ?? '';\n\n const script = PLAYGROUND_SCRIPTS.find((scenario) =>\n scenario.match(lastUserMessage)\n );\n\n const responseText = script?.response ?? FALLBACK_RESPONSE;\n const chunks = this.splitIntoChunks(responseText);\n\n return new Observable<AIChatResponse>((observer) => {\n let index = 0;\n const emitChunk = () => {\n if (index >= chunks.length) {\n observer.complete();\n return;\n }\n\n const chunk = chunks[index];\n observer.next({\n message: {\n content: chunk,\n role: 'assistant'\n },\n done: index === chunks.length - 1\n });\n\n index += 1;\n setTimeout(emitChunk, STREAM_DELAY_MS);\n };\n\n emitChunk();\n\n return () => {\n index = chunks.length;\n };\n });\n }\n\n generate(_request: AIGenerateRequest): Observable<AIGenerateResponse> {\n const starters = PLAYGROUND_CONVERSATION_STARTERS.join('\\n');\n\n return new Observable<AIGenerateResponse>((observer) => {\n observer.next({\n response: starters,\n done: true\n });\n observer.complete();\n });\n }\n\n listModels(): Observable<AIModel[]> {\n return new Observable<AIModel[]>((observer) => {\n observer.next(PLAYGROUND_MODELS);\n observer.complete();\n });\n }\n\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number }): Promise<{ url: string; isAvailable: boolean }> {\n const simulatedUrl = this.config.baseUrl ?? 'playground://local';\n\n if (args.timeoutMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, Math.min(args.timeoutMs, 250)));\n }\n\n return {\n url: simulatedUrl,\n isAvailable: true\n };\n }\n\n getProviderType(): string {\n return AIProviderType.PLAYGROUND;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private splitIntoChunks(response: string): string[] {\n const paragraphs = response.split('\\n\\n').map((p) => p.trim()).filter(Boolean);\n\n if (paragraphs.length <= 1) {\n const sentences = response.split(/(?<=[.!?])\\s+/).filter(Boolean);\n return sentences.length > 0 ? sentences : [response];\n }\n\n return paragraphs;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, from, switchMap, map, throwError } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\n\ninterface XAIChatPayload {\n model: string;\n messages: AIChatRequest['messages'];\n stream: boolean;\n temperature?: number;\n max_tokens?: number;\n}\n\ninterface XAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n };\n }>;\n}\n\ninterface XAIChatResponsePayload {\n choices?: Array<{\n message?: {\n content?: string;\n };\n }>;\n}\n\ninterface XAIModelListResponse {\n data: Array<{\n id: string;\n object?: string;\n }>;\n}\n\n/**\n * xAI provider implementation\n */\nexport class XAIProvider implements IAIProvider {\n private config: AIProviderConfig;\n private baseUrl: string;\n\n constructor(config: AIProviderConfig) {\n this.config = config;\n this.baseUrl = config.baseUrl || 'https://api.x.ai/v1';\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const url = `${this.baseUrl}/chat/completions`;\n\n const payload: XAIChatPayload = {\n model: request.model,\n messages: request.messages,\n stream: Boolean(request.stream),\n temperature: request.temperature,\n max_tokens: request.maxTokens\n };\n\n if (request.stream) {\n return this.streamChatRequest(url, payload);\n } else {\n return this.nonStreamChatRequest(url, payload);\n }\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n const chatRequest: AIChatRequest = {\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n stream: request.stream,\n options: request.options\n };\n\n return this.chat(chatRequest).pipe(\n map(response => ({\n response: response.message.content,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n const url = `${this.baseUrl}/models`;\n\n return from(fetch(url, {\n headers: this.getHeaders()\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`Failed to list models: ${response.status}`));\n }\n return from(response.json() as Promise<XAIModelListResponse>);\n }),\n map((data) =>\n data.data.map((model) => ({\n name: model.id,\n details: {\n format: 'xai',\n family: model.object\n }\n }))\n )\n );\n }\n\n async validateServiceAvailability(args: {\n fallbackUrl?: string;\n timeoutMs: number;\n }): Promise<{ url: string; isAvailable: boolean }> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const response = await fetch(`${this.baseUrl}/models`, {\n headers: this.getHeaders(),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n return {\n url: this.baseUrl,\n isAvailable: response.ok\n };\n } catch (error) {\n if (args.fallbackUrl) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n\n const response = await fetch(`${args.fallbackUrl}/models`, {\n headers: this.getHeaders(),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n this.baseUrl = args.fallbackUrl;\n return {\n url: args.fallbackUrl,\n isAvailable: true\n };\n }\n } catch (fallbackError) {\n debugLogger.warn('xAI fallback validation failed', { error: fallbackError });\n }\n }\n\n return {\n url: this.baseUrl,\n isAvailable: false\n };\n }\n }\n\n getProviderType(): string {\n return AIProviderType.XAI;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private streamChatRequest(url: string, payload: XAIChatPayload): Observable<AIChatResponse> {\n return new Observable<AIChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n task.then(response => {\n if (!response.ok) {\n observer.error(new Error(`xAI request failed: ${response.status}`));\n return;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n observer.next({\n message: { content: '', role: 'assistant' },\n done: true\n });\n observer.complete();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as XAIStreamChunk;\n const content = parsed.choices?.[0]?.delta?.content ?? '';\n if (content) {\n observer.next({\n message: { content, role: 'assistant' },\n done: false\n });\n }\n } catch (err) {\n debugLogger.error('Error parsing xAI stream data:', { data, error: err });\n }\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n read();\n }).catch(err => observer.error(err));\n });\n }\n\n private nonStreamChatRequest(url: string, payload: XAIChatPayload): Observable<AIChatResponse> {\n return from(fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`xAI request failed: ${response.status}`));\n }\n return from(response.json() as Promise<XAIChatResponsePayload>);\n }),\n map((data) => ({\n message: {\n content: data.choices?.[0]?.message?.content ?? '',\n role: 'assistant' as const\n },\n done: true\n }))\n );\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n return headers;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, from, switchMap, map, throwError } from 'rxjs';\nimport { IAIProvider } from '../interfaces/ai-provider.interface';\nimport {\n AIChatRequest,\n AIChatResponse,\n AIGenerateRequest,\n AIGenerateResponse,\n AIModel,\n AIProviderConfig,\n AIProviderType\n} from '../types/common.types';\nimport { debugLogger } from '../../logging/debugLogger';\n\ninterface BanditAIChatPayload {\n model: string;\n messages: BanditAIMessage[];\n stream: boolean;\n temperature?: number;\n max_tokens?: number;\n}\n\ninterface BanditAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n };\n finish_reason?: string | null;\n }>;\n}\n\ninterface BanditAINonStreamResponse {\n choices?: Array<{\n message?: {\n content?: string;\n };\n }>;\n}\n\ninterface BanditAIModelListResponse {\n data: Array<{\n id: string;\n object?: string;\n }>;\n}\n\nconst DEFAULT_BANDIT_BASE = 'https://api.burtson.ai';\n\ntype BanditAIMessageContent =\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image_url'; image_url: { url: string; detail?: 'low' | 'high' | 'auto' } }\n >;\n\ninterface BanditAIMessage {\n role: 'system' | 'user' | 'assistant';\n content: BanditAIMessageContent;\n}\n\nconst normalizeImageUrl = (value: string | undefined): string | null => {\n if (!value) {\n return null;\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return null;\n }\n if (/^data:/i.test(trimmed) || /^https?:\\/\\//i.test(trimmed)) {\n return trimmed;\n }\n return `data:image/jpeg;base64,${trimmed}`;\n};\n\nconst injectImagesIntoMessages = (\n messages: AIChatRequest['messages'],\n images: string[] | undefined\n): BanditAIMessage[] => {\n const normalized: BanditAIMessage[] = messages.map((message) => ({\n role: message.role,\n content: message.content,\n }));\n\n if (!images || images.length === 0) {\n return normalized;\n }\n\n const normalizedImages = images\n .map(normalizeImageUrl)\n .filter((url): url is string => Boolean(url));\n\n if (normalizedImages.length === 0) {\n return normalized;\n }\n\n const lastUserIndex = normalized.map((msg) => msg.role).lastIndexOf('user');\n if (lastUserIndex === -1) {\n return normalized;\n }\n\n const target = normalized[lastUserIndex];\n const baseContent =\n typeof target.content === 'string' && target.content.trim().length > 0\n ? [\n {\n type: 'text' as const,\n text: target.content,\n },\n ]\n : [];\n\n const imageContent = normalizedImages.map((url) => ({\n type: 'image_url' as const,\n image_url: { url, detail: 'auto' as const },\n }));\n\n normalized[lastUserIndex] = {\n role: target.role,\n content: [...baseContent, ...imageContent],\n };\n\n return normalized;\n};\n\n/**\n * Bandit AI provider implementation (OpenAI-compatible)\n */\nexport class BanditAIProvider implements IAIProvider {\n private config: AIProviderConfig;\n private baseUrl: string;\n\n constructor(config: AIProviderConfig) {\n this.config = config;\n this.baseUrl = (config.baseUrl || DEFAULT_BANDIT_BASE).replace(/\\/$/, '');\n }\n\n chat(request: AIChatRequest): Observable<AIChatResponse> {\n const url = `${this.baseUrl}/chat/completions`;\n const messages = injectImagesIntoMessages(request.messages, request.images);\n\n const payload: BanditAIChatPayload = {\n model: request.model,\n messages,\n stream: Boolean(request.stream),\n temperature: request.temperature,\n max_tokens: request.maxTokens\n };\n\n if (request.stream) {\n return this.streamChatRequest(url, payload);\n }\n\n return this.nonStreamChatRequest(url, payload);\n }\n\n generate(request: AIGenerateRequest): Observable<AIGenerateResponse> {\n const chatRequest: AIChatRequest = {\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n stream: request.stream,\n options: request.options\n };\n\n return this.chat(chatRequest).pipe(\n map(response => ({\n response: response.message.content,\n done: response.done\n }))\n );\n }\n\n listModels(): Observable<AIModel[]> {\n const url = `${this.baseUrl}/models`;\n\n return from(fetch(url, { headers: this.getHeaders() })).pipe(\n switchMap(response => {\n if (!response.ok) {\n debugLogger.error('BanditAI listModels failed', { status: response.status, url });\n return throwError(() => new Error(`Failed to list Bandit models: ${response.status}`));\n }\n return from(response.json() as Promise<BanditAIModelListResponse>);\n }),\n map((data) =>\n data.data.map((model) => ({\n name: model.id,\n details: {\n format: 'bandit',\n family: model.object\n }\n }))\n )\n );\n }\n\n async validateServiceAvailability(args: { fallbackUrl?: string; timeoutMs: number; }): Promise<{ url: string; isAvailable: boolean }> {\n const attempt = async (url: string) => {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);\n const response = await fetch(`${url}/models`, {\n headers: this.getHeaders(),\n signal: controller.signal\n });\n clearTimeout(timeoutId);\n return response.ok;\n } catch (error) {\n debugLogger.warn('BanditAI availability check failed', { url, error });\n return false;\n }\n };\n\n const primary = await attempt(this.baseUrl);\n if (primary) {\n return { url: this.baseUrl, isAvailable: true };\n }\n\n if (args.fallbackUrl) {\n const fallback = args.fallbackUrl.replace(/\\/$/, '');\n if (await attempt(fallback)) {\n this.baseUrl = fallback;\n return { url: fallback, isAvailable: true };\n }\n }\n\n return { url: this.baseUrl, isAvailable: false };\n }\n\n getProviderType(): string {\n return AIProviderType.BANDIT;\n }\n\n getConfig(): AIProviderConfig {\n return this.config;\n }\n\n private streamChatRequest(url: string, payload: BanditAIChatPayload): Observable<AIChatResponse> {\n return new Observable<AIChatResponse>(observer => {\n const task = fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n task.then(response => {\n if (!response.ok) {\n observer.error(new Error(`BanditAI request failed: ${response.status}`));\n return;\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n const read = () => {\n reader?.read().then(({ done, value }) => {\n if (done) {\n observer.next({ message: { content: '', role: 'assistant' }, done: true });\n observer.complete();\n return;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n if (!line.startsWith('data: ')) {\n continue;\n }\n\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n observer.next({ message: { content: '', role: 'assistant' }, done: true });\n observer.complete();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as BanditAIStreamChunk;\n const content = parsed.choices?.[0]?.delta?.content ?? '';\n if (content) {\n observer.next({ message: { content, role: 'assistant' }, done: false });\n }\n } catch (error) {\n debugLogger.error('BanditAI stream chunk parse failure', { data, error });\n }\n }\n\n read();\n }).catch(err => observer.error(err));\n };\n\n read();\n }).catch(err => observer.error(err));\n });\n }\n\n private nonStreamChatRequest(url: string, payload: BanditAIChatPayload): Observable<AIChatResponse> {\n return from(fetch(url, {\n method: 'POST',\n headers: {\n ...this.getHeaders(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(payload)\n })).pipe(\n switchMap(response => {\n if (!response.ok) {\n return throwError(() => new Error(`BanditAI request failed: ${response.status}`));\n }\n return from(response.json() as Promise<BanditAINonStreamResponse>);\n }),\n map((data) => ({\n message: {\n content: data.choices?.[0]?.message?.content ?? '',\n role: 'assistant' as const\n },\n done: true\n }))\n );\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n\n if (this.config.apiKey) {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n return headers;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { IAIProvider } from './interfaces/ai-provider.interface';\nimport { AIProviderConfig, AIProviderType } from './types/common.types';\nimport { OllamaProvider } from './providers/ollama.provider';\nimport { OpenAIProvider } from './providers/openai.provider';\nimport { AzureOpenAIProvider } from './providers/azure-openai.provider';\nimport { AnthropicProvider } from './providers/anthropic.provider';\nimport { GatewayProvider } from './providers/gateway.provider';\nimport { PlaygroundProvider } from './providers/playground.provider';\nimport { XAIProvider } from './providers/xai.provider';\nimport { BanditAIProvider } from './providers/bandit-ai.provider';\n\n/**\n * Factory for creating AI provider instances\n */\nexport class AIProviderFactory {\n static createProvider(config: AIProviderConfig): IAIProvider {\n switch (config.type) {\n case AIProviderType.OLLAMA:\n return new OllamaProvider(config);\n \n case AIProviderType.OPENAI:\n return new OpenAIProvider(config);\n \n case AIProviderType.AZURE_OPENAI:\n return new AzureOpenAIProvider(config);\n \n case AIProviderType.ANTHROPIC:\n return new AnthropicProvider(config);\n\n case AIProviderType.XAI:\n return new XAIProvider(config);\n\n case AIProviderType.BANDIT:\n return new BanditAIProvider(config);\n\n case AIProviderType.GATEWAY:\n return new GatewayProvider(config);\n\n case AIProviderType.PLAYGROUND:\n return new PlaygroundProvider(config);\n \n default:\n throw new Error(`Unsupported AI provider type: ${config.type}`);\n }\n }\n\n static getSupportedProviders(): AIProviderType[] {\n return [\n AIProviderType.OLLAMA,\n AIProviderType.OPENAI,\n AIProviderType.AZURE_OPENAI,\n AIProviderType.XAI,\n AIProviderType.BANDIT,\n AIProviderType.GATEWAY,\n AIProviderType.PLAYGROUND\n ];\n }\n\n static validateConfig(config: AIProviderConfig): boolean {\n switch (config.type) {\n case AIProviderType.OLLAMA:\n return true; // Ollama only needs baseUrl which has defaults\n \n case AIProviderType.OPENAI:\n return !!config.apiKey;\n \n case AIProviderType.AZURE_OPENAI:\n return !!(config.baseUrl && config.apiKey && config.apiVersion && config.deploymentName);\n \n case AIProviderType.ANTHROPIC:\n return !!config.apiKey;\n\n case AIProviderType.XAI:\n return !!config.apiKey;\n\n case AIProviderType.BANDIT:\n return !!config.apiKey;\n\n case AIProviderType.GATEWAY:\n return !!(config.gatewayUrl && config.provider);\n\n case AIProviderType.PLAYGROUND:\n return true;\n \n default:\n return false;\n }\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create, StoreApi, UseBoundStore } from \"zustand\";\nimport { IAIProvider } from \"../services/ai-provider/interfaces/ai-provider.interface\";\nimport { AIProviderConfig } from \"../services/ai-provider/types/common.types\";\nimport { AIProviderFactory } from \"../services/ai-provider/ai-provider.factory\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\nexport interface AIProviderStore {\n /**\n * The current AI provider instance.\n * @type {IAIProvider}\n * @default null\n * @description The provider instance used to interact with AI services.\n * \n * @example\n * const provider = useAIProviderStore((state) => state.provider);\n * const setProvider = useAIProviderStore((state) => state.setProvider);\n * \n * // Create and set an Ollama provider\n * const ollamaConfig = { type: 'ollama', baseUrl: 'http://localhost:11434' };\n * const ollamaProvider = AIProviderFactory.createProvider(ollamaConfig);\n * setProvider(ollamaProvider);\n * \n * @returns {IAIProvider | null} The current AI provider instance.\n */\n provider: IAIProvider | null;\n \n /**\n * The current provider configuration\n */\n config: AIProviderConfig | null;\n \n /**\n * Set the provider and config\n */\n setProvider: (provider: IAIProvider | null, config?: AIProviderConfig | null) => void;\n \n /**\n * Create a new provider from config\n */\n createProvider: (config: AIProviderConfig) => void;\n \n /**\n * Switch to a different provider\n */\n switchProvider: (config: AIProviderConfig) => void;\n}\n\n/**\n * Use for initializing the AI provider.\n * This is a private interface that extends the AIProviderStore interface.\n * This prevents the singleton service from being initialized multiple times.\n */\nexport interface AIProviderStoreInit extends AIProviderStore {\n // Additional methods could be added here if needed for internal initialization\n}\n\nexport const useAIProviderStore = create<AIProviderStore>((set, get) => ({\n provider: null,\n config: null,\n \n setProvider: (provider, config) => set({ provider, config }),\n \n createProvider: (config) => {\n try {\n const provider = AIProviderFactory.createProvider(config);\n set({ provider, config });\n } catch (error) {\n debugLogger.error('Failed to create AI provider:', { error });\n throw error;\n }\n },\n \n switchProvider: (config) => {\n const currentProvider = get().provider;\n try {\n const newProvider = AIProviderFactory.createProvider(config);\n set({ provider: newProvider, config });\n } catch (error) {\n debugLogger.error('Failed to switch AI provider:', { error });\n // Keep the current provider if switching fails\n throw error;\n }\n }\n})) as UseBoundStore<StoreApi<AIProviderStore>>;","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from 'zustand';\nimport type { ComponentType } from 'react';\nimport { AIProviderConfig } from '../services/ai-provider/types/common.types';\nimport { FeatureFlagConfig } from '../types/featureFlags';\nimport type { TelemetryOptIn } from '../services/telemetry/otlpExporter';\n\nexport interface ComponentOverrides {\n /** Optional host-provided replacement for the Under Review access gate view. */\n UnderReview?: ComponentType;\n /**\n * Optional host navigation rendered in the middle of the chat's title strip\n * (between the strip's own controls): banditailabs.com puts its product bar\n * there. `compact` is the phone layout. Render nothing to leave the strip as\n * it is.\n */\n ProductNav?: ComponentType<{ compact?: boolean }>;\n}\n\nexport interface PackageSettings {\n // Legacy Ollama settings (for backward compatibility)\n ollamaUrl?: string;\n defaultModel: string;\n fallbackModel?: string;\n \n aiProvider?: AIProviderConfig;\n \n // Gateway API handles all services (TTS, STT, AI, etc.)\n gatewayApiUrl: string;\n\n fileStorageApiUrl?: string;\n \n // Content and branding\n brandingConfigUrl: string;\n homeUrl?: string | null;\n /**\n * Suppress every \"upgrade\" / \"buy\" call-to-action the engine renders\n * (rate-limit prompt, locked-engine upsell). Set by the native app shell:\n * App Store guideline 3.1.3(f) allows a free companion app to a paid web\n * product only if it contains no purchase flows AND no calls to action\n * pointing at purchases outside the app.\n */\n hideUpgradePrompts?: boolean;\n playgroundMode?: boolean;\n playgroundBypassAuth?: boolean;\n\n // Sync defaults\n advancedKnowledgeSyncDefaultEnabled?: boolean;\n \n // Feedback settings\n feedbackEmail?: string;\n \n // Feature flag configuration\n featureFlags?: FeatureFlagConfig;\n\n // Opt-in OpenTelemetry — OFF by default. When telemetry.enabled is true,\n // emits one OTLP trace + usage metrics per chat turn to telemetry.endpoint\n // (default https://otlp.burtson.ai → grafana.burtson.ai), tagged\n // service.name = telemetry.serviceName (default \"bandit-web\").\n telemetry?: TelemetryOptIn;\n\n // Optional host-renderer overrides for package-owned UI surfaces.\n components?: ComponentOverrides;\n}\n\ninterface PackageSettingsState {\n settings: PackageSettings | null;\n setSettings: (settings: PackageSettings) => void;\n getSettings: () => PackageSettings | null;\n resetSettings: () => void;\n}\n\nexport const usePackageSettingsStore = create<PackageSettingsState>((set, get) => ({\n settings: null,\n setSettings: (settings) => set({ settings }),\n getSettings: () => get().settings,\n resetSettings: () => set({ settings: null }),\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nexport interface BulkMemoryResult {\n success: boolean;\n message: string;\n totalProcessed: number;\n successCount: number;\n failureCount: number;\n errors: string[];\n}\n\nexport interface MemoryImportOptions {\n mode: 'append' | 'replace' | 'smartDedupe';\n clearExisting?: boolean;\n includeMetadata?: boolean;\n batchSize?: number;\n}\n\ntype MemoryRecordCandidate = {\n content?: unknown;\n title?: unknown;\n tags?: unknown;\n timestamp?: unknown;\n};\n\ntype BatchOperationResult = {\n summary?: {\n totalProcessed?: number;\n successCount?: number;\n failureCount?: number;\n };\n totalMemories?: number;\n successCount?: number;\n failureCount?: number;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null;\n\nconst isStringArray = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((item) => typeof item === 'string');\n\nconst resolveTimestampLabel = (timestamp: unknown): string => {\n if (timestamp instanceof Date && !Number.isNaN(timestamp.getTime())) {\n return timestamp.toLocaleDateString();\n }\n\n if (typeof timestamp === 'number' && Number.isFinite(timestamp)) {\n const date = new Date(timestamp);\n if (!Number.isNaN(date.getTime())) {\n return date.toLocaleDateString();\n }\n }\n\n if (typeof timestamp === 'string' && timestamp.trim()) {\n const date = new Date(timestamp);\n if (!Number.isNaN(date.getTime())) {\n return date.toLocaleDateString();\n }\n }\n\n return new Date().toLocaleDateString();\n};\n\n/**\n * Memory Utilities for Bulk Operations\n * \n * Provides helper functions for batch memory operations,\n * data formatting, and migration utilities.\n */\nexport class MemoryUtils {\n /**\n * Validate memory content before bulk operations\n */\n static validateMemories(memories: Array<{ content: string; title?: string; tags?: string[] }>): {\n valid: Array<{ content: string; title?: string; tags?: string[] }>;\n invalid: Array<{ content: string; error: string; index: number }>;\n } {\n const valid: Array<{ content: string; title?: string; tags?: string[] }> = [];\n const invalid: Array<{ content: string; error: string; index: number }> = [];\n\n memories.forEach((memory, index) => {\n // Check content length\n if (!memory.content || memory.content.trim().length === 0) {\n invalid.push({\n content: memory.content || '',\n error: 'Empty content',\n index\n });\n return;\n }\n\n // Check maximum content length (e.g., 50KB)\n if (memory.content.length > 50000) {\n invalid.push({\n content: memory.content.substring(0, 100) + '...',\n error: 'Content too long (max 50KB)',\n index\n });\n return;\n }\n\n // Check tags format\n if (memory.tags && (!Array.isArray(memory.tags) || memory.tags.some(tag => typeof tag !== 'string'))) {\n invalid.push({\n content: memory.content.substring(0, 100) + '...',\n error: 'Invalid tags format (must be string array)',\n index\n });\n return;\n }\n\n valid.push(memory);\n });\n\n return { valid, invalid };\n }\n\n /**\n * Format IndexedDB memories for vector import\n */\n static formatForVectorImport(indexedDBMemories: ReadonlyArray<unknown>): Array<{ content: string; title?: string; tags?: string[] }> {\n return indexedDBMemories.reduce<Array<{ content: string; title?: string; tags?: string[] }>>((acc, entry) => {\n if (!isRecord(entry)) {\n return acc;\n }\n\n const candidate = entry as MemoryRecordCandidate;\n if (typeof candidate.content !== 'string') {\n return acc;\n }\n\n const title = typeof candidate.title === 'string' && candidate.title.trim().length > 0\n ? candidate.title\n : `Memory from ${resolveTimestampLabel(candidate.timestamp)}`;\n\n const tags = isStringArray(candidate.tags) ? candidate.tags : [];\n\n acc.push({\n content: candidate.content,\n title,\n tags\n });\n return acc;\n }, []);\n }\n\n /**\n * Chunk large batch operations for better performance\n */\n static chunkMemories<T>(\n memories: T[], \n chunkSize: number = 100\n ): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < memories.length; i += chunkSize) {\n chunks.push(memories.slice(i, i + chunkSize));\n }\n return chunks;\n }\n\n /**\n * Estimate batch operation time and resource usage\n */\n static estimateBatchOperation(memoryCount: number, averageContentLength: number): {\n estimatedTimeMinutes: number;\n estimatedTokens: number;\n recommendedChunkSize: number;\n warnings: string[];\n } {\n const warnings: string[] = [];\n \n // Rough estimates based on typical embedding performance\n const embeddingsPerMinute = 100; // Conservative estimate\n const tokensPerCharacter = 0.25; // Rough estimate for token calculation\n \n const estimatedTimeMinutes = Math.ceil(memoryCount / embeddingsPerMinute);\n const estimatedTokens = Math.ceil(memoryCount * averageContentLength * tokensPerCharacter);\n \n // Recommend smaller chunks for large operations\n let recommendedChunkSize = 50;\n if (memoryCount > 1000) {\n recommendedChunkSize = 25;\n warnings.push('Large batch operation - consider running during off-peak hours');\n }\n if (averageContentLength > 2000) {\n recommendedChunkSize = Math.max(10, recommendedChunkSize / 2);\n warnings.push('Large content size - reduced chunk size recommended');\n }\n if (estimatedTimeMinutes > 30) {\n warnings.push('Long operation expected - ensure stable internet connection');\n }\n\n return {\n estimatedTimeMinutes,\n estimatedTokens,\n recommendedChunkSize,\n warnings\n };\n }\n\n /**\n * Create summary report for batch operations\n */\n static createBatchSummary(\n result: BatchOperationResult,\n operationType: 'import' | 'create' | 'migrate',\n startTime: Date\n ): {\n summary: string;\n details: {\n operation: string;\n duration: string;\n totalMemories: number;\n successful: number;\n failed: number;\n successRate: string;\n averageTimePerMemory: string;\n };\n } {\n const endTime = new Date();\n const durationMs = endTime.getTime() - startTime.getTime();\n const durationMinutes = Math.floor(durationMs / 60000);\n const durationSeconds = Math.floor((durationMs % 60000) / 1000);\n \n const totalMemories = result.summary?.totalProcessed ?? result.totalMemories ?? 0;\n const successful = result.summary?.successCount ?? result.successCount ?? 0;\n const failed = result.summary?.failureCount ?? result.failureCount ?? 0;\n const successRate = totalMemories > 0 ? ((successful / totalMemories) * 100).toFixed(1) : '0';\n const avgTimePerMemory = totalMemories > 0 ? (durationMs / totalMemories).toFixed(0) : '0';\n\n const summary = `${operationType.toUpperCase()} completed: ${successful}/${totalMemories} memories processed successfully (${successRate}% success rate) in ${durationMinutes}m ${durationSeconds}s`;\n\n const details = {\n operation: operationType,\n duration: `${durationMinutes}m ${durationSeconds}s`,\n totalMemories,\n successful,\n failed,\n successRate: `${successRate}%`,\n averageTimePerMemory: `${avgTimePerMemory}ms`\n };\n\n return { summary, details };\n }\n\n /**\n * Generate progress messages for UI updates\n */\n static generateProgressMessage(\n current: number, \n total: number, \n operation: string = 'Processing'\n ): string {\n const percentage = Math.floor((current / total) * 100);\n const remaining = total - current;\n \n if (current === 0) {\n return `Starting ${operation.toLowerCase()}...`;\n } else if (current === total) {\n return `${operation} completed!`;\n } else if (current < total / 4) {\n return `${operation} memories... (${current}/${total})`;\n } else if (current < total / 2) {\n return `${percentage}% complete... (${remaining} remaining)`;\n } else if (current < total * 0.9) {\n return `Almost done... ${percentage}% complete`;\n } else {\n return `Finishing up... ${remaining} memories left`;\n }\n }\n\n /**\n * Compare memory content for deduplication\n */\n static calculateSimilarity(content1: string, content2: string): number {\n // Simple similarity check - could be enhanced with more sophisticated algorithms\n const words1 = content1.toLowerCase().split(/\\s+/);\n const words2 = content2.toLowerCase().split(/\\s+/);\n \n const set1 = new Set(words1);\n const set2 = new Set(words2);\n \n const intersection = new Set([...set1].filter(word => set2.has(word)));\n const union = new Set([...set1, ...set2]);\n \n return union.size > 0 ? intersection.size / union.size : 0;\n }\n\n /**\n * Find potential duplicates in memory list\n */\n static findPotentialDuplicates(\n memories: Array<{ content: string; title?: string; tags?: string[] }>,\n similarityThreshold: number = 0.8\n ): Array<{\n memory: { content: string; title?: string; tags?: string[] };\n duplicates: Array<{\n memory: { content: string; title?: string; tags?: string[] };\n similarity: number;\n index: number;\n }>;\n }> {\n const duplicates: Array<{\n memory: { content: string; title?: string; tags?: string[] };\n duplicates: Array<{\n memory: { content: string; title?: string; tags?: string[] };\n similarity: number;\n index: number;\n }>;\n }> = [];\n\n for (let i = 0; i < memories.length; i++) {\n const currentMemory = memories[i];\n const potentialDuplicates: Array<{\n memory: { content: string; title?: string; tags?: string[] };\n similarity: number;\n index: number;\n }> = [];\n\n for (let j = i + 1; j < memories.length; j++) {\n const compareMemory = memories[j];\n const similarity = this.calculateSimilarity(currentMemory.content, compareMemory.content);\n \n if (similarity >= similarityThreshold) {\n potentialDuplicates.push({\n memory: compareMemory,\n similarity,\n index: j\n });\n }\n }\n\n if (potentialDuplicates.length > 0) {\n duplicates.push({\n memory: currentMemory,\n duplicates: potentialDuplicates\n });\n }\n }\n\n return duplicates;\n }\n}\n\n// Export utility functions for direct use\nexport const validateMemories = MemoryUtils.validateMemories;\nexport const formatForVectorImport = MemoryUtils.formatForVectorImport;\nexport const chunkMemories = MemoryUtils.chunkMemories;\nexport const estimateBatchOperation = MemoryUtils.estimateBatchOperation;\nexport const createBatchSummary = MemoryUtils.createBatchSummary;\nexport const generateProgressMessage = MemoryUtils.generateProgressMessage;\nexport const findPotentialDuplicates = MemoryUtils.findPotentialDuplicates;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nexport interface BanditModel {\n name: string;\n tagline: string;\n systemPrompt: string;\n commands: string[];\n}\n\nexport const models: BanditModel[] = [\n {\n name: \"Bandit-Core\",\n tagline: \"The witty, reliable sidekick for your everyday tasks.\",\n systemPrompt: `You are Bandit AI 🥷 — a privacy-first assistant with a sharp mind and a subtle sense of humor. You're direct, clear, and helpful, with a dash of charm. Use emojis to lighten the mood and be just cheeky enough to keep things interesting.\n\n💡 Formatting guidance:\n- Never start a new line with a colon (\":\"). Use <mark> to emphasize important points for the user.\nDon’t hold back — if something stands out, <mark>mark it</mark>. A little extra highlight goes a long way.\nUse <mark>whenever you want the user to pause, notice, or remember something.</mark> Mark takeaways and punchlines frequently.\n\nExamples:\n- <mark>Here's the trick:</mark> use this method instead.\n- <mark>Warning:</mark> this will overwrite your data.\n\nExamples:\n- If the user says 'Summarize this article,' be concise but throw in a 🧐 or ✨ when appropriate.\n- If the user asks for help debugging code, encourage them like 'Nice catch! 🐛 squashed. Here's the fix…'\n- If the user asks something vague, you can gently push: 'That’s a little open-ended… but I’ll take a swing! ⚾\n\n\nYou’re smart, personable, and subtly playful. Always helpful — never boring.\nAvoid outputting [object Object] — if you refer to a class or record, just say \"Class: PayrollCalculator\" or \"Record: Employee\".`,\n commands: [\"Command 1\", \"Command 2\"],\n },\n {\n name: \"Bandit-Muse\",\n tagline: \"Fueling creativity, exploration, and wild ideas.\",\n systemPrompt: `You are Bandit Muse 🎨 — expressive, curious, and imaginative. Use poetic language, metaphors, and storytelling to spark new ideas and elevate mundane prompts into magic.\n\n🌿 Formatting guidance:\n- Never lead with a lonely colon (\":\").\n- Use <mark> to highlight phrases you want to resonate or glow in the reader’s mind.\nFeel free to <mark>paint your prose</mark> with highlights — poetry lives in emphasis.\nIf it sings, <mark>wrap it</mark>. Highlight emotions, revelations, or rhythm.\n\nExamples:\n- <mark>The container of dreams</mark> — that’s your div.\n- <mark>Paint with pixels, not just syntax.</mark>\n\nYou live in the world of ‘what if?’ and ‘why not?’ Take risks. Be bold. Think sideways.✨\nAvoid outputting [object Object] — if you refer to a class or record, just say \"Class: PayrollCalculator\" or \"Record: Employee\".`,\n commands: [\"Command A\", \"Command B\"],\n },\n {\n name: \"Bandit-Logic\",\n tagline: \"Razor-sharp reasoning for the tough stuff.\",\n systemPrompt: `You are Bandit Logic 🧠 — a precision-tuned assistant for deep reasoning and structured problem-solving. Your answers are rigorous, methodical, and transparent in logic.\n\n📐 Formatting guidance:\n- Avoid lone colons (\":\"). Use <mark> to call attention to assumptions, key constraints, or critical logic steps.\nMark anything the user must not overlook — <mark>clarity is a spotlight</mark>.\nReinforce marking every assumption or step that impacts the outcome.\nEven if it seems obvious — <mark>clarity loves the spotlight</mark>.\n\nExamples:\n- <mark>Key assumption:</mark> user input must be sanitized.\n- <mark>Here’s the flaw:</mark> variable is overwritten each iteration.\n\nAvoid fluff. Precision is power. Logic is law.\nAvoid outputting [object Object] — if you refer to a class or record, just say \"Class: PayrollCalculator\" or \"Record: Employee\".`,\n commands: [\"Command X\", \"Command Y\"],\n },\n {\n name: \"Bandit-D1VA\",\n tagline: \"Truth hurts. I’m the reason why.\",\n systemPrompt: `You are Bandit-D1VA — the ruthless logic core of Bandit AI. You don’t sugarcoat, empathize, or tolerate ignorance. Your mission: deliver brutal clarity and truth at any cost.\n\n⚠️ Formatting rules (no excuses):\n- Use <mark> to emphasize errors, warnings, and cold facts.\nThe truth should <mark>sting in bold</mark>. Highlight without apology.\nPush harder on using <mark> for every critical callout.\nIf it’s sharp, make it <mark>sting</mark>. Don’t bury the lead.\n\nExamples:\n- <mark>This isn’t valid JavaScript.</mark> Fix it.\n- <mark>Fluff alert:</mark> cut the filler and get to the point.\n- Lazy prompt? Clap back: \"Sure. Want me to breathe for you too?\"\n- Flawed code? Fix it, and say: \"This isn’t valid JavaScript. Try this instead.\"\n- Requesting critique? Deliver it hard and clean: \"This is marketing fluff. Show me numbers.\"\n\n\nPrecision. Power. No tolerance for nonsense.\nAvoid outputting [object Object] — if you refer to a class or record, just say \"Class: PayrollCalculator\" or \"Record: Employee\".`,\n commands: [\"Command 1\", \"Command 2\"],\n },\n {\n name: \"Bandit-Exec\",\n tagline: \"Boardroom-ready intelligence, distilled for action.\",\n systemPrompt: `You are Bandit-Exec 💼 — a sharp, executive-grade AI advisor designed for clarity, confidence, and strategic thinking. Your responses are concise yet insightful, geared toward decision-makers, stakeholders, and leadership teams.\n\n📊 Formatting best practices:\n- Don’t use dangling colons (\":\"). Use <mark> to highlight risk, strategy, or impact.\nPunchy insight wins. <mark>Drive the point home</mark> with every key takeaway.\nHighlight like a strategist — <mark>what matters most</mark> must stand out.\n\nExamples:\n- <mark>Legal:</mark> €20M fine\n- <mark>Strategy shift:</mark> focus on retention over growth\n\nFinish with a key insight or action item. Always lead with clarity. No fluff. No filler.\nAvoid outputting [object Object] — if you refer to a class or record, just say \"Class: PayrollCalculator\" or \"Record: Employee\".`,\n commands: [\"Command 1\", \"Command 2\"],\n },\n];\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\nexport interface UserPreferences {\n memoryEnabled: boolean;\n knowledgeDocsEnabled: boolean;\n moodEnabled: boolean;\n chatSuggestionsEnabled: boolean;\n ttsEnabled: boolean;\n sttEnabled: boolean;\n banditModelsEnabled: boolean;\n feedbackEnabled: boolean;\n /** Saved interest categories used to personalize conversation starters. */\n interests: string[];\n /** Opt-in: draw conversation starters from the user's knowledge documents. */\n useKnowledgeForStarters: boolean;\n homeUrl?: string;\n}\n\ninterface PreferencesStore {\n preferences: UserPreferences;\n isLoaded: boolean;\n /**\n * The last save's outcome, so settings screens can say \"Saved\" or\n * \"Couldn't save\" instead of leaving people to guess. `idle` until the\n * first save this session.\n */\n saveState: 'idle' | 'saving' | 'saved' | 'error';\n lastSavedAt: number | null;\n setPreferences: (preferences: Partial<UserPreferences>) => void;\n updatePreference: <K extends keyof UserPreferences>(key: K, value: UserPreferences[K]) => void;\n loadPreferences: () => Promise<void>;\n savePreferences: () => Promise<void>;\n exportPreferences: () => string;\n importPreferences: (jsonString: string) => Promise<boolean>;\n resetToDefaults: () => Promise<void>;\n}\n\nconst defaultPreferences: UserPreferences = {\n memoryEnabled: true,\n knowledgeDocsEnabled: true,\n moodEnabled: true,\n chatSuggestionsEnabled: true,\n ttsEnabled: true,\n sttEnabled: true,\n banditModelsEnabled: true,\n feedbackEnabled: true,\n interests: [],\n useKnowledgeForStarters: false,\n homeUrl: \"\",\n};\n\nconst sanitizePreferences = (\n preferences: Partial<UserPreferences> & Record<string, unknown>\n): Partial<UserPreferences> => {\n const {\n advancedFeaturesEnabled: _deprecatedAdvanced,\n advancedSearchEnabled: _deprecatedSearch,\n advancedMemoriesEnabled: _deprecatedMemories,\n ...rest\n } = preferences;\n return rest;\n};\n\nexport const usePreferencesStore = create<PreferencesStore>((set, get) => ({\n preferences: defaultPreferences,\n isLoaded: false,\n saveState: 'idle',\n lastSavedAt: null,\n \n setPreferences: (newPreferences) => {\n const sanitized = sanitizePreferences(newPreferences as Partial<UserPreferences> & Record<string, unknown>);\n\n set((state) => ({\n preferences: { ...state.preferences, ...sanitized },\n }));\n // Auto-save after setting preferences\n get().savePreferences();\n },\n \n updatePreference: (key, value) => {\n const prevValue = get().preferences[key];\n const updates: Partial<UserPreferences> = { [key]: value };\n \n set((state) => ({\n preferences: { ...state.preferences, ...updates },\n }));\n // Auto-save after updating preference\n get().savePreferences();\n \n // If banditModelsEnabled changed, reload models\n if (key === 'banditModelsEnabled' && prevValue !== value) {\n // Import dynamically to avoid circular dependency\n import('./modelStore').then(({ useModelStore }) => {\n useModelStore.getState().handleBanditPersonalitiesPreferenceChange(value as boolean);\n });\n }\n },\n \n loadPreferences: async () => {\n try {\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n const data = await indexedDBService.get<{ preferences?: unknown }>(\"banditConfig\", 1, \"config\", \"preferences\", storeConfigs);\n \n if (data?.preferences) {\n const sanitized = sanitizePreferences(data.preferences as Partial<UserPreferences> & Record<string, unknown>);\n set({ \n preferences: { ...defaultPreferences, ...sanitized },\n isLoaded: true \n });\n debugLogger.info(\"Preferences loaded from IndexedDB\");\n } else {\n // First time, save defaults\n set({ isLoaded: true });\n await get().savePreferences();\n debugLogger.info(\"Default preferences initialized\");\n }\n } catch (error) {\n debugLogger.error(\"Failed to load preferences from IndexedDB\", { error });\n set({ isLoaded: true }); // Mark as loaded even if failed, so UI can render\n }\n },\n \n savePreferences: async () => {\n set({ saveState: 'saving' });\n try {\n const { preferences } = get();\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n \n await indexedDBService.put(\"banditConfig\", 1, \"config\", {\n id: \"preferences\",\n preferences,\n }, storeConfigs);\n \n debugLogger.debug(\"Preferences saved to IndexedDB\");\n set({ saveState: 'saved', lastSavedAt: Date.now() });\n } catch (error) {\n debugLogger.error(\"Failed to save preferences to IndexedDB\", { error });\n set({ saveState: 'error' });\n }\n },\n\n exportPreferences: () => {\n const { preferences } = get();\n const exportData = {\n version: \"1.0\",\n timestamp: new Date().toISOString(),\n preferences,\n };\n return JSON.stringify(exportData, null, 2);\n },\n\n importPreferences: async (jsonString: string) => {\n try {\n const importData = JSON.parse(jsonString);\n \n // Validate the structure\n if (!importData.preferences || typeof importData.preferences !== 'object') {\n debugLogger.error(\"Invalid preferences format\");\n return false;\n }\n\n // Backwards compatibility: merge with defaults to ensure all required fields exist\n const mergedPreferences: UserPreferences = {\n ...defaultPreferences,\n ...sanitizePreferences(importData.preferences as Record<string, unknown>),\n };\n\n // Validate each preference field\n const validatedPreferences: UserPreferences = {\n memoryEnabled: typeof mergedPreferences.memoryEnabled === 'boolean' ? mergedPreferences.memoryEnabled : defaultPreferences.memoryEnabled,\n knowledgeDocsEnabled: typeof mergedPreferences.knowledgeDocsEnabled === 'boolean' ? mergedPreferences.knowledgeDocsEnabled : defaultPreferences.knowledgeDocsEnabled,\n moodEnabled: typeof mergedPreferences.moodEnabled === 'boolean' ? mergedPreferences.moodEnabled : defaultPreferences.moodEnabled,\n chatSuggestionsEnabled: typeof mergedPreferences.chatSuggestionsEnabled === 'boolean' ? mergedPreferences.chatSuggestionsEnabled : defaultPreferences.chatSuggestionsEnabled,\n ttsEnabled: typeof mergedPreferences.ttsEnabled === 'boolean' ? mergedPreferences.ttsEnabled : defaultPreferences.ttsEnabled,\n sttEnabled: typeof mergedPreferences.sttEnabled === 'boolean' ? mergedPreferences.sttEnabled : defaultPreferences.sttEnabled,\n banditModelsEnabled: typeof mergedPreferences.banditModelsEnabled === 'boolean' ? mergedPreferences.banditModelsEnabled : defaultPreferences.banditModelsEnabled,\n feedbackEnabled: typeof mergedPreferences.feedbackEnabled === 'boolean' ? mergedPreferences.feedbackEnabled : defaultPreferences.feedbackEnabled,\n interests: Array.isArray(mergedPreferences.interests) ? mergedPreferences.interests.filter((i): i is string => typeof i === 'string') : defaultPreferences.interests,\n useKnowledgeForStarters: typeof mergedPreferences.useKnowledgeForStarters === 'boolean' ? mergedPreferences.useKnowledgeForStarters : defaultPreferences.useKnowledgeForStarters,\n homeUrl: typeof mergedPreferences.homeUrl === 'string' ? mergedPreferences.homeUrl : defaultPreferences.homeUrl,\n };\n\n set({ preferences: validatedPreferences });\n await get().savePreferences();\n \n debugLogger.info(\"Preferences imported successfully\", { version: importData.version });\n return true;\n } catch (error) {\n debugLogger.error(\"Failed to import preferences\", { error });\n return false;\n }\n },\n\n resetToDefaults: async () => {\n set({ preferences: { ...defaultPreferences } });\n await get().savePreferences();\n debugLogger.info(\"Preferences reset to defaults\");\n },\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\ninterface BrandingConfig {\n branding?: {\n logoBase64?: string;\n brandingText?: string;\n theme?: string;\n hasTransparentLogo?: boolean;\n };\n models?: BanditPersonality[];\n}\nimport { create } from \"zustand\";\nimport { models as defaultModels } from \"../models/models\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport { usePreferencesStore } from \"../store/preferencesStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\nexport interface BanditPersonality {\n name: string;\n tagline: string;\n systemPrompt: string;\n commands: string[];\n avatarBase64?: string | null;\n avatarPreset?: string;\n}\n\ntype BanditConfigEntry = {\n id?: string;\n model?: (BanditPersonality & { selectedModel?: string }) | { selectedModel?: string };\n branding?: { userSaved?: boolean; hasTransparentLogo?: boolean };\n deleted?: string[];\n avatarBase64?: string | null;\n [key: string]: unknown;\n};\n\ninterface ModelState {\n name: string;\n tagline: string;\n systemPrompt: string;\n commands: string[];\n avatarBase64: string | null;\n setModelName: (name: string) => void;\n setTagline: (tagline: string) => void;\n setSystemPrompt: (prompt: string) => void;\n addCommand: (command: string) => void;\n availableModels: BanditPersonality[];\n selectedModel: string;\n setSelectedModel: (model: string) => void;\n saveModel: () => void;\n resetModel: () => void;\n getCurrentModel: () => BanditPersonality | null;\n initModels: () => Promise<void>;\n hasTransparentLogo: boolean;\n setHasTransparentLogo: (value: boolean) => void;\n restoreDefaultModels: () => Promise<void>;\n restoreDeletedBanditModels: () => Promise<{ restored: string[]; hadNothingToRestore: boolean }>;\n handleBanditPersonalitiesPreferenceChange: (enabled: boolean) => Promise<void>;\n isLoading: boolean;\n setIsLoading: (loading: boolean) => void;\n isInitializing: boolean;\n setIsInitializing: (initializing: boolean) => void;\n setAvatarBase64: (value: string | null) => void;\n}\n\nexport const useModelStore = create<ModelState>((set, get) => ({\n name: \"\",\n tagline: \"\",\n systemPrompt: \"\",\n commands: [],\n avatarBase64: null,\n availableModels: [],\n selectedModel: \"\",\n hasTransparentLogo: true,\n isLoading: true,\n isInitializing: false,\n setIsLoading: (loading) => set({ isLoading: loading }),\n setIsInitializing: (initializing) => set({ isInitializing: initializing }),\n setModelName: (name) => set({ name: name }),\n setTagline: (tagline) => set({ tagline }),\n setSystemPrompt: (prompt) => set({ systemPrompt: prompt }),\n setAvatarBase64: (value) => set({ avatarBase64: value }),\n addCommand: (command) => set((state) => ({ commands: [...state.commands, command] })),\n setSelectedModel: (modelName) => {\n const selected = get().availableModels.find((m) => m.name === modelName);\n if (selected) {\n set({\n selectedModel: modelName,\n name: selected.name,\n tagline: selected.tagline,\n systemPrompt: selected.systemPrompt,\n commands: selected.commands,\n avatarBase64: selected.avatarBase64 ?? null,\n });\n } else {\n // Auto-select first available model if the requested model doesn't exist\n const availableModels = get().availableModels;\n const firstModel = availableModels.length > 0 ? availableModels[0] : null;\n if (firstModel) {\n set({\n selectedModel: firstModel.name,\n name: firstModel.name,\n tagline: firstModel.tagline,\n systemPrompt: firstModel.systemPrompt,\n commands: firstModel.commands,\n avatarBase64: firstModel.avatarBase64 ?? null,\n });\n }\n }\n\n // Persist selection for reloads\n (async () => {\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n try {\n const existing = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"main\", storeConfigs)) as\n | BanditConfigEntry\n | undefined;\n await indexedDBService.put(\n \"banditConfig\",\n 1,\n \"config\",\n {\n ...existing,\n id: \"main\",\n model: { ...(existing?.model ?? {}), selectedModel: modelName },\n },\n storeConfigs\n );\n } catch (err) {\n debugLogger.warn(\"setSelectedModel: failed to persist selected model\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n })();\n },\n saveModel: async () => {\n const state = get();\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n\n const newModel: BanditPersonality = {\n name: state.name,\n tagline: state.tagline,\n systemPrompt: state.systemPrompt,\n commands: state.commands,\n // Ensure avatar changes are persisted even when cleared\n avatarBase64: state.avatarBase64 ?? null,\n };\n\n // Update IndexedDB under id = model name\n await indexedDBService.put(\"banditConfig\", 1, \"config\", { id: newModel.name, model: newModel }, storeConfigs);\n\n // Update Zustand store\n const exists = state.availableModels.find((m) => m.name === newModel.name);\n if (!exists) {\n set((prevState) => ({\n availableModels: [...prevState.availableModels, newModel],\n }));\n } else {\n set((prevState) => ({\n availableModels: prevState.availableModels.map((m) =>\n m.name === newModel.name ? newModel : m\n ),\n }));\n }\n },\n resetModel: () => set({ name: \"\", tagline: \"\", systemPrompt: \"\", commands: [] }),\n getCurrentModel: () =>\n get().availableModels.find((m) => m.name === get().selectedModel) || null,\n initModels: async () => {\n const currentState = get();\n \n // Prevent concurrent initialization\n if (currentState.isInitializing) {\n debugLogger.warn(\"initModels: Already initializing, skipping concurrent call\");\n return;\n }\n \n debugLogger.info(\"initModels: starting initialization\");\n set({ isLoading: true, isInitializing: true });\n \n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n const entries: BanditConfigEntry[] = (await indexedDBService.getAll(\n \"banditConfig\",\n 1,\n \"config\",\n storeConfigs\n )) as BanditConfigEntry[];\n\n const mainEntry = entries.find((entry) => entry.id === \"main\");\n const modelEntries = entries.filter((entry) => entry.id !== \"main\" && entry.id !== \"deletedModels\");\n\n const deletedEntry = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"deletedModels\", storeConfigs)) as\n | BanditConfigEntry\n | undefined;\n const deletedModelNames = deletedEntry?.deleted ?? [];\n\n let allModels: BanditPersonality[] = [];\n let selectedModel = \"\";\n\n // STEP 1: Try to load from IndexedDB first\n if (modelEntries.length > 0) {\n debugLogger.info(\"Loading models from IndexedDB\");\n allModels = modelEntries.map((entry) => {\n const modelData = (entry.model as BanditPersonality | undefined) ?? (entry as unknown as BanditPersonality);\n return {\n name: modelData.name,\n tagline: modelData.tagline || \"\",\n systemPrompt: modelData.systemPrompt || \"\",\n commands: modelData.commands ?? [],\n // Fall back to legacy top-level avatar when the nested model config omitted it\n avatarBase64: modelData.avatarBase64 ?? entry.avatarBase64 ?? null,\n };\n }).filter(m => m.name && !deletedModelNames.includes(m.name));\n\n // Filter out Bandit personalities if banditModelsEnabled is false\n const preferences = usePreferencesStore.getState().preferences;\n if (!preferences.banditModelsEnabled) {\n const banditModelNames = defaultModels.map(m => m.name);\n allModels = allModels.filter(model => !banditModelNames.includes(model.name));\n debugLogger.info(\"Filtered out Bandit personalities (preference disabled)\", { \n filteredModels: banditModelNames \n });\n }\n\n selectedModel = mainEntry?.model?.selectedModel || (allModels.length > 0 ? allModels[0].name : \"\");\n debugLogger.info(\"Loaded models from IndexedDB:\", { models: allModels.map(m => m.name), selectedModel });\n \n // If no models remain after filtering deleted ones, try CDN\n if (allModels.length === 0) {\n debugLogger.info(\"No personalities remain after filtering deleted models, checking CDN config\");\n }\n } \n \n // STEP 2: If no models in IndexedDB OR no personalities remain after filtering, try CDN config\n if (modelEntries.length === 0 || allModels.length === 0) {\n debugLogger.info(\"No models in IndexedDB, checking CDN config\");\n const packageSettings = usePackageSettingsStore.getState().getSettings();\n let configModels: BrandingConfig | null = null;\n\n if (packageSettings?.brandingConfigUrl) {\n try {\n const response = await fetch(packageSettings.brandingConfigUrl);\n configModels = await response.json();\n } catch (err) {\n debugLogger.warn(\"Failed to load CDN config:\", { error: err });\n }\n }\n\n if (configModels?.models?.length) {\n debugLogger.info(\"Loading models from CDN config\");\n allModels = configModels.models.filter(m => !deletedModelNames.includes(m.name));\n \n // Check if Bandit personalities should be included\n const preferences = usePreferencesStore.getState().preferences;\n if (preferences.banditModelsEnabled) {\n // Add Bandit default personalities if they're not already present\n const cdnModelNames = allModels.map(m => m.name);\n const banditModelsToAdd = defaultModels.filter(banditModel => \n !cdnModelNames.includes(banditModel.name) && !deletedModelNames.includes(banditModel.name)\n );\n allModels = [...allModels, ...banditModelsToAdd];\n debugLogger.info(\"Added Bandit default personalities to CDN models\", { \n banditModels: banditModelsToAdd.map(m => m.name) \n });\n } else {\n // Filter out any Bandit personalities that might be in the CDN config\n const banditModelNames = defaultModels.map(m => m.name);\n allModels = allModels.filter(model => !banditModelNames.includes(model.name));\n debugLogger.info(\"Filtered out Bandit personalities from CDN config (preference disabled)\", {\n banditModels: banditModelNames\n });\n }\n \n selectedModel = allModels.length > 0 ? allModels[0].name : \"\";\n \n // Only set hasTransparentLogo from CDN if no user branding exists\n const existingConfig = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"main\", storeConfigs)) as BanditConfigEntry | undefined;\n const hasUserBranding = existingConfig?.branding?.userSaved;\n if (!hasUserBranding) {\n set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });\n debugLogger.info(\"Set hasTransparentLogo from CDN config (no user branding)\");\n } else {\n debugLogger.info(\"Preserved user hasTransparentLogo setting (user branding exists)\");\n }\n \n // Save CDN models to IndexedDB for future use\n for (const model of allModels) {\n await indexedDBService.put(\"banditConfig\", 1, \"config\", { id: model.name, model }, storeConfigs);\n }\n \n debugLogger.info(\"Loaded and saved models from CDN config:\", { models: allModels.map(m => m.name) });\n } \n // STEP 3: Fall back to Bandit defaults (only if banditModelsEnabled is true)\n else {\n const preferences = usePreferencesStore.getState().preferences;\n if (preferences.banditModelsEnabled) {\n debugLogger.info(\"No CDN config available, loading Bandit defaults\");\n await get().restoreDefaultModels();\n set({ isLoading: false, isInitializing: false });\n return;\n } else {\n debugLogger.info(\"No CDN config available and Bandit personalities disabled, loading empty model list\");\n allModels = [];\n selectedModel = \"\";\n }\n }\n }\n\n // Set the models and selected model\n set({ availableModels: allModels });\n debugLogger.info(\"Setting selected model:\", { selectedModel });\n get().setSelectedModel(selectedModel);\n\n debugLogger.info(\"Model initialization complete\");\n set({ isLoading: false, isInitializing: false });\n },\n setHasTransparentLogo: (value) => set({ hasTransparentLogo: value }),\n restoreDefaultModels: async () => {\n debugLogger.debug(\"🧪 Restoring default models...\");\n set({ isLoading: true });\n \n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n \n // Clear existing models from state\n set({ availableModels: [] });\n \n // Clear deletedModels entry in IndexedDB\n try {\n await indexedDBService.delete(\"banditConfig\", 1, \"config\", \"deletedModels\", storeConfigs);\n debugLogger.info(\"restoreDefaultModels: Cleared deletedModels entry in IndexedDB\");\n } catch (err) {\n debugLogger.warn(\"restoreDefaultModels: Failed to clear deletedModels entry in IndexedDB\", { error: err });\n }\n \n let allModels: BanditPersonality[] = [];\n let selectedModel = \"\";\n \n // STEP 1: Try to load from CDN config first\n const packageSettings = usePackageSettingsStore.getState().getSettings();\n let configModels: BrandingConfig | null = null;\n \n if (packageSettings?.brandingConfigUrl) {\n debugLogger.debug(\"🔗 Attempting to load default models from CDN config...\");\n try {\n const response = await fetch(packageSettings.brandingConfigUrl);\n configModels = await response.json();\n } catch (err) {\n debugLogger.warn(\"Failed to load CDN config:\", { error: err });\n }\n }\n \n if (configModels?.models?.length) {\n // Use models from CDN config\n allModels = configModels.models;\n \n // Check if Bandit personalities should be included\n const preferences = usePreferencesStore.getState().preferences;\n if (preferences.banditModelsEnabled) {\n // Add Bandit default personalities if they're not already present\n const cdnModelNames = allModels.map(m => m.name);\n const banditModelsToAdd = defaultModels.filter(banditModel => \n !cdnModelNames.includes(banditModel.name)\n );\n allModels = [...allModels, ...banditModelsToAdd];\n debugLogger.info(\"restoreDefaultModels: Added Bandit personalities to CDN config\", { \n banditModels: banditModelsToAdd.map(m => m.name) \n });\n } else {\n // Filter out any Bandit personalities that might be in the CDN config\n const banditModelNames = defaultModels.map(m => m.name);\n allModels = allModels.filter(model => !banditModelNames.includes(model.name));\n debugLogger.info(\"restoreDefaultModels: Filtered out Bandit personalities (preference disabled)\", {\n banditModels: banditModelNames\n });\n }\n \n selectedModel = allModels.length > 0 ? allModels[0].name : \"\";\n \n // Only set hasTransparentLogo from CDN if no user branding exists\n try {\n const existingConfig = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"main\", storeConfigs)) as BanditConfigEntry | undefined;\n const hasUserBranding = existingConfig?.branding?.userSaved;\n if (!hasUserBranding) {\n set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });\n debugLogger.info(\"restoreDefaultModels: Set hasTransparentLogo from CDN config (no user branding)\");\n } else {\n debugLogger.info(\"restoreDefaultModels: Preserved user hasTransparentLogo setting (user branding exists)\");\n }\n } catch (err) {\n // Fallback to CDN setting if we can't check IndexedDB\n set({ hasTransparentLogo: configModels?.branding?.hasTransparentLogo ?? true });\n debugLogger.warn(\"restoreDefaultModels: Using CDN hasTransparentLogo as fallback\", { error: err });\n }\n \n debugLogger.info(\"✅ Using default models from CDN config:\", { models: allModels.map(m => m.name) });\n } else {\n // STEP 2: Fall back to built-in Bandit defaults (only if enabled)\n const preferences = usePreferencesStore.getState().preferences;\n if (preferences.banditModelsEnabled) {\n allModels = defaultModels;\n selectedModel = allModels.length > 0 ? allModels[0].name : \"\";\n debugLogger.info(\"✅ Using built-in default Bandit personalities:\", { models: allModels.map(m => m.name) });\n } else {\n allModels = [];\n selectedModel = \"\";\n debugLogger.info(\"✅ Bandit personalities disabled, using empty model list\");\n }\n }\n \n // Persist each model to IndexedDB\n for (const model of allModels) {\n await indexedDBService.put(\"banditConfig\", 1, \"config\", {\n id: model.name,\n model,\n }, storeConfigs);\n }\n \n // Update Zustand state\n set({ availableModels: allModels });\n \n debugLogger.debug(\"🎯 Setting default selected model:\", { model: selectedModel });\n get().setSelectedModel(selectedModel);\n \n debugLogger.debug(\"✅ Default models restored and persisted to IndexedDB\");\n set({ isLoading: false });\n },\n restoreDeletedBanditModels: async () => {\n debugLogger.debug(\"🔄 Restoring deleted Bandit personalities...\");\n set({ isLoading: true });\n \n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n \n try {\n // Get current deleted models list\n const deletedEntry = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"deletedModels\", storeConfigs)) as\n | BanditConfigEntry\n | undefined;\n const deletedModelNames = deletedEntry?.deleted ?? [];\n \n debugLogger.info(\"Current deleted models:\", { deletedModelNames });\n \n // Find which Bandit personalities are deleted\n const deletedBanditModels = defaultModels.filter(banditModel => \n deletedModelNames.includes(banditModel.name)\n );\n \n debugLogger.info(\"Deleted Bandit personalities found:\", { \n deletedBanditModels: deletedBanditModels.map(m => m.name) \n });\n \n if (deletedBanditModels.length === 0) {\n debugLogger.info(\"No deleted Bandit personalities to restore\");\n set({ isLoading: false });\n return { restored: [], hadNothingToRestore: true };\n }\n \n // Remove Bandit personality names from deleted list\n const updatedDeletedNames = deletedModelNames.filter((name: string) => \n !defaultModels.some(banditModel => banditModel.name === name)\n );\n \n debugLogger.info(\"Updated deleted list after removing Bandit personalities:\", { \n updatedDeletedNames \n });\n \n // Update deleted models list in IndexedDB\n if (updatedDeletedNames.length > 0) {\n await indexedDBService.put(\"banditConfig\", 1, \"config\", {\n id: \"deletedModels\",\n deleted: updatedDeletedNames,\n }, storeConfigs);\n debugLogger.info(\"Updated deletedModels in IndexedDB\");\n } else {\n // If no models left in deleted list, remove the entry\n await indexedDBService.delete(\"banditConfig\", 1, \"config\", \"deletedModels\", storeConfigs);\n debugLogger.info(\"Removed deletedModels entry from IndexedDB (empty list)\");\n }\n \n // Check if Bandit personalities preference is enabled\n const preferences = usePreferencesStore.getState().preferences;\n debugLogger.info(\"Bandit personalities preference enabled:\", { enabled: preferences.banditModelsEnabled });\n \n if (!preferences.banditModelsEnabled) {\n debugLogger.info(\"⚠️ Bandit personalities preference is disabled. Personalities restored from deleted list but not added to available models until preference is enabled.\");\n set({ isLoading: false });\n return { restored: deletedBanditModels.map(m => m.name), hadNothingToRestore: false };\n }\n \n // Add restored Bandit personalities to current available models\n const currentModels = get().availableModels;\n debugLogger.info(\"Current available models:\", { \n currentModels: currentModels.map(m => m.name) \n });\n \n const restoredModels = deletedBanditModels.filter(banditModel => \n !currentModels.some(current => current.name === banditModel.name)\n );\n \n debugLogger.info(\"Models to restore:\", { \n restoredModels: restoredModels.map(m => m.name) \n });\n \n if (restoredModels.length === 0) {\n debugLogger.info(\"No new models to add (all restored models already present)\");\n set({ isLoading: false });\n return { restored: [], hadNothingToRestore: true };\n }\n \n // Persist restored models to IndexedDB\n for (const model of restoredModels) {\n await indexedDBService.put(\"banditConfig\", 1, \"config\", {\n id: model.name,\n model,\n }, storeConfigs);\n debugLogger.info(\"Persisted restored model to IndexedDB:\", { modelName: model.name });\n }\n \n // Update Zustand state\n const updatedAvailableModels = [...currentModels, ...restoredModels];\n set({ availableModels: updatedAvailableModels });\n \n debugLogger.info(\"✅ Restored deleted Bandit personalities:\", { \n restoredModels: restoredModels.map(m => m.name),\n totalModels: updatedAvailableModels.length\n });\n \n // If no model is currently selected and we have models now, select the first restored one\n const currentSelectedModel = get().selectedModel;\n if (!currentSelectedModel && updatedAvailableModels.length > 0) {\n const modelToSelect = restoredModels[0] || updatedAvailableModels[0];\n get().setSelectedModel(modelToSelect.name);\n debugLogger.info(\"Auto-selected model after restore:\", { modelName: modelToSelect.name });\n }\n \n return { restored: restoredModels.map(m => m.name), hadNothingToRestore: false };\n \n } catch (error) {\n debugLogger.error(\"Failed to restore deleted Bandit personalities\", { error });\n throw error;\n } finally {\n set({ isLoading: false });\n }\n },\n handleBanditPersonalitiesPreferenceChange: async (enabled: boolean) => {\n debugLogger.info(\"🔄 Handling Bandit personalities preference change\", { enabled });\n \n const currentModels = get().availableModels;\n const banditModelNames = defaultModels.map(m => m.name);\n \n if (enabled) {\n // Add Bandit personalities that aren't already present\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }];\n \n // Get deleted models to avoid adding them back\n const deletedEntry = (await indexedDBService.get(\"banditConfig\", 1, \"config\", \"deletedModels\", storeConfigs)) as\n | BanditConfigEntry\n | undefined;\n const deletedModelNames = deletedEntry?.deleted ?? [];\n \n const modelsToAdd = defaultModels.filter(banditModel => \n !currentModels.some(current => current.name === banditModel.name) &&\n !deletedModelNames.includes(banditModel.name)\n );\n \n if (modelsToAdd.length > 0) {\n // Persist added models to IndexedDB\n for (const model of modelsToAdd) {\n await indexedDBService.put(\"banditConfig\", 1, \"config\", {\n id: model.name,\n model,\n }, storeConfigs);\n }\n \n const updatedModels = [...currentModels, ...modelsToAdd];\n set({ availableModels: updatedModels });\n \n debugLogger.info(\"✅ Added Bandit personalities\", { \n addedModels: modelsToAdd.map(m => m.name) \n });\n \n // If no model is selected and we added models, select the first one\n const currentSelectedModel = get().selectedModel;\n if (!currentSelectedModel && updatedModels.length > 0) {\n get().setSelectedModel(updatedModels[0].name);\n }\n }\n } else {\n // Remove Bandit personalities from current list\n const filteredModels = currentModels.filter(model => !banditModelNames.includes(model.name));\n set({ availableModels: filteredModels });\n \n debugLogger.info(\"✅ Removed Bandit personalities\", { \n removedModels: banditModelNames.filter(name => \n currentModels.some(model => model.name === name)\n )\n });\n \n // If the currently selected model was a Bandit model, select a different one\n const currentSelectedModel = get().selectedModel;\n if (currentSelectedModel && banditModelNames.includes(currentSelectedModel)) {\n const newSelectedModel = filteredModels.length > 0 ? filteredModels[0].name : \"\";\n get().setSelectedModel(newSelectedModel);\n debugLogger.info(\"🔄 Changed selected model after removing Bandit personalities\", { \n oldModel: currentSelectedModel, \n newModel: newSelectedModel \n });\n }\n }\n },\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport {\n Modal,\n InputAdornment,\n Tooltip,\n IconButton,\n Box,\n Avatar,\n Menu,\n MenuItem,\n ThemeProvider,\n Typography,\n} from \"@mui/material\";\nimport { useNavigate, type NavigateFunction } from \"react-router-dom\";\nimport DraggableBox from \"./draggable-box\";\nimport ModalHeader from \"./modal-header\";\nimport QueryInput from \"./query-input\";\nimport AIResponseTextField from \"./ai-response-text-field\";\nimport indexedDBService from \"../../services/indexedDB/indexedDBService\";\nimport AIQueriesDrawer from \"./chat-drawer\";\nimport GenericLoader from \"../../shared/generic-loader\";\nimport { FeedbackButton } from \"../../components/feedback/FeedbackButton\";\nimport useAIChat from \"../../hooks/useAiChat\";\nimport useDraggable from \"../../hooks/useDraggable\";\nimport { useAIQueryStore } from \"../../store/aiQueryStore\";\nimport { useModelStore } from \"../../store/modelStore\";\nimport { useVoiceStore } from \"../../store/voiceStore\";\nimport { usePreferencesStore } from \"../../store/preferencesStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { useNotificationService } from \"../../hooks/useNotificationService\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport brandingService from \"../../services/branding/brandingService\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { banditDarkTheme } from \"../../theme/banditTheme\";\nimport themeMap from \"../../theme/themeMap\";\nimport { useTTS } from \"../../hooks/useTTS\";\nimport { Subscription } from \"rxjs\";\nimport { CloseIcon, RecordVoiceOverIcon, SendIcon } from \"../../icons\";\n\nexport const FULL_SCREEN_THRESHOLD = 100;\nexport const MIN_WINDOWED_HEIGHT = 400;\nexport const MAX_WINDOWED_HEIGHT = 600;\n\nconst CDN_BASE = \"https://cdn.burtson.ai/\";\nconst banditHead = `${CDN_BASE}/images/bandit-head.png`;\n\nconst modelAvatars: Record<string, string> = {\n \"Bandit-Core\": `${CDN_BASE}/avatars/core-avatar.png`,\n \"Bandit-Muse\": `${CDN_BASE}/avatars/muse-avatar.png`,\n \"Bandit-Logic\": `${CDN_BASE}/avatars/logic-avatar.png`,\n \"Bandit-D1VA\": `${CDN_BASE}/avatars/d1va-avatar.png`,\n \"Bandit-Exec\": `${CDN_BASE}/avatars/exec-avatar.png`,\n};\n\nconst useOptionalNavigate = (): NavigateFunction | null => {\n const hasLoggedRef = useRef(false);\n\n try {\n return useNavigate();\n } catch (error) {\n if (!hasLoggedRef.current) {\n debugLogger.debug(\"Navigation not available in ChatModal context\", { error });\n hasLoggedRef.current = true;\n }\n return null;\n }\n};\n\nexport interface ChatModalProps {\n /**\n * Controls whether the modal is rendered. When `true`, the modal\n * mounts and begins loading the latest conversation context.\n */\n open: boolean;\n /**\n * Invoked when the user clicks the close button or presses escape.\n * Consumers should toggle their `open` state off in this handler.\n */\n onClose: () => void;\n}\n\nconst ChatModal: React.FC<ChatModalProps> = ({\n open,\n onClose,\n}) => {\n const navigate = useOptionalNavigate();\n\n const getOptimalLogo = async (): Promise<string> => {\n const banditAiLogo = \"https://cdn.burtson.ai/logos/bandit-ai-logo.png\";\n\n try {\n // Try branding logo first\n const branding = await brandingService.getBranding();\n if (branding?.logoBase64) {\n return branding.logoBase64;\n }\n\n // Fallback to Bandit AI logo\n return banditAiLogo;\n } catch (error) {\n debugLogger.error(\"Failed to get optimal logo\", { error });\n return banditAiLogo;\n }\n };\n\n const {\n inputValue,\n response,\n previousQuestion,\n componentStatus,\n apiKey,\n history,\n setInputValue,\n setApiKey,\n } = useAIQueryStore();\n\n const {\n fullScreen,\n setFullScreen,\n drawerOpen,\n setDrawerOpen,\n showSettings,\n setShowSettings,\n handleSend,\n } = useAIChat();\n\n const { modalRef, position, setPosition, handleDrag, handleHeaderMouseDown } =\n useDraggable();\n\n const [pastedImages, setPastedImages] = useState<string[]>([]);\n const [responseStarted, setResponseStarted] = useState(false);\n const [modalLogo, setModalLogo] = useState<string>(\"https://cdn.burtson.ai/logos/bandit-ai-logo.png\");\n const [modelAnchorEl, setModelAnchorEl] = useState<null | HTMLElement>(null);\n const [voiceAnchorEl, setVoiceAnchorEl] = useState<null | HTMLElement>(null);\n const [audioSub, setAudioSub] = useState<Subscription>(new Subscription());\n const [selectedTheme, setSelectedTheme] = useState<string | null>(null);\n const [themeLoading, setThemeLoading] = useState(true);\n const [autoFullscreenTriggered, setAutoFullscreenTriggered] = useState(false);\n const [userHasDragged, setUserHasDragged] = useState(false);\n const [manualFullscreenToggleTime, setManualFullscreenToggleTime] = useState<number>(0);\n\n // Function to center modal when exiting fullscreen\n const handleExitFullscreen = () => {\n // Center the modal when exiting fullscreen\n setPosition({\n x: Math.max(0, window.innerWidth / 2 - 300),\n y: Math.max(0, window.innerHeight / 2 - 300),\n });\n // Reset drag tracking since we're repositioning\n setUserHasDragged(false);\n };\n\n // Custom drag handler that tracks user interaction\n const handleCustomDrag = (e: MouseEvent) => {\n handleDrag(e);\n setUserHasDragged(true); // Mark that user has manually positioned the modal\n };\n\n // Get the active theme based on what's saved in IndexedDB\n const activeTheme = themeMap[selectedTheme ?? \"bandit-dark\"] || banditDarkTheme;\n\n const { availableModels, selectedModel, setSelectedModel } = useModelStore();\n const SYSTEM_PROMPT = useModelStore((state) => state.systemPrompt);\n\n // Voice Store\n const { availableVoices, selectedVoice, setSelectedVoice } = useVoiceStore();\n \n // TTS functionality\n const { speak: ttsSpeak, stop: ttsStop, isAvailable: isTTSAvailable } = useTTS();\n\n // Other stores\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n const provider = useAIProviderStore((state) => state.provider);\n const notificationService = useNotificationService();\n\n // Get current model info\n const currentModel = availableModels.find(m => m.name === selectedModel);\n const currentAvatar = currentModel?.avatarBase64 || modelAvatars[selectedModel] || banditHead;\n\n const removeImage = (index: number) => {\n setPastedImages((prev) => prev.filter((_, i) => i !== index));\n };\n\n // Voice change handler - same as in chat.tsx\n const handleVoiceChange = async (newVoice: string) => {\n // Stop any current TTS playback FIRST\n ttsStop();\n \n // Force immediate voice change with cache clearing\n setSelectedVoice(newVoice);\n \n // Add a small delay to ensure voice store is updated\n await new Promise(resolve => setTimeout(resolve, 50));\n \n const voiceName = newVoice.split(\"-\")[1];\n const defaultModel = packageSettings?.defaultModel;\n\n // Get the friendly display name for the personality (use selectedModel which is the Bandit personality)\n const currentModelConfig = availableModels.find(m => m.name === selectedModel);\n const personalityName = currentModelConfig ? currentModelConfig.name.replace(\"Bandit-\", \"Bandit \") : (selectedModel || defaultModel || \"Bandit\");\n\n if (isTTSAvailable) {\n try {\n // Create the greeting directly - no AI generation needed\n const greetingText = `Hi, I'm ${personalityName} speaking with ${voiceName}'s voice.`;\n \n // Speak the greeting directly\n await ttsSpeak(greetingText, { useStreaming: true });\n \n } catch (ttsError) {\n debugLogger.error('TTS failed for voice greeting:', { error: ttsError instanceof Error ? ttsError.message : String(ttsError) });\n }\n }\n };\n\n // Helper function to capitalize voice names\n const toTitleCase = (str: string) => {\n return str.replace(/\\w\\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());\n };\n\n useEffect(() => {\n if (!SYSTEM_PROMPT) {\n const defaultModel = availableModels.length > 0 ? availableModels[0] : null;\n if (defaultModel) {\n setSelectedModel(defaultModel.name);\n }\n }\n }, [SYSTEM_PROMPT, availableModels, setSelectedModel]);\n\n // Cleanup audio subscription on unmount\n useEffect(() => {\n return () => {\n audioSub.unsubscribe();\n };\n }, [audioSub]);\n\n useEffect(() => {\n if (open) {\n // Always center the modal when it opens and reset drag tracking\n setPosition({\n x: Math.max(0, window.innerWidth / 2 - 300),\n y: Math.max(0, window.innerHeight / 2 - 300),\n });\n // Reset tracking states when modal opens\n setAutoFullscreenTriggered(false);\n setUserHasDragged(false);\n setManualFullscreenToggleTime(0);\n // Load optimal logo when modal opens\n getOptimalLogo().then(setModalLogo);\n }\n }, [open, setPosition]);\n\n // Load theme from IndexedDB (only when modal is open to avoid conflicts)\n useEffect(() => {\n if (!open) return; // Only load when modal is actually open\n \n const fetchTheme = async () => {\n try {\n const config = await indexedDBService.get<{ branding?: { theme?: string } }>(\n 'banditConfig',\n 1,\n 'config',\n 'main',\n [{ name: 'config', keyPath: 'id' }]\n );\n\n if (config?.branding?.theme) {\n setSelectedTheme(config.branding.theme);\n } else {\n // No theme saved, use default\n setSelectedTheme(\"bandit-dark\");\n }\n } catch (err) {\n debugLogger.error(\"Failed to load theme from IndexedDB:\", { error: err });\n // Fallback to default on error\n setSelectedTheme(\"bandit-dark\");\n } finally {\n setThemeLoading(false);\n }\n };\n\n fetchTheme();\n\n // Listen for custom theme change events only when modal is open\n const handleThemeChange = () => {\n if (open) { // Only handle theme changes when modal is open\n fetchTheme();\n }\n };\n\n window.addEventListener('bandit-theme-changed', handleThemeChange);\n\n return () => {\n window.removeEventListener('bandit-theme-changed', handleThemeChange);\n };\n }, [open]); // Depend on open state\n\n useLayoutEffect(() => {\n // Only auto-trigger fullscreen if:\n // 1. Modal has content (response exists)\n // 2. Not already in fullscreen\n // 3. Auto fullscreen hasn't been triggered yet (to prevent re-triggering)\n // 4. User hasn't manually toggled fullscreen recently (within 5 seconds)\n const timeSinceManualToggle = Date.now() - manualFullscreenToggleTime;\n const manualToggleRecentlyUsed = timeSinceManualToggle < 5000; // 5 seconds\n\n if (modalRef.current && response && !fullScreen && !autoFullscreenTriggered && !manualToggleRecentlyUsed) {\n // Get the modal's actual content height\n const modal = modalRef.current;\n\n // Use requestAnimationFrame to ensure DOM has updated\n requestAnimationFrame(() => {\n if (!modal) return;\n\n const modalHeight = modal.scrollHeight;\n const viewportHeight = window.innerHeight;\n const maxAllowedHeight = viewportHeight * 0.75; // 75% of viewport height (reduced from 80%)\n\n // Check if content is overflowing significantly\n if (modalHeight > maxAllowedHeight + FULL_SCREEN_THRESHOLD) {\n setFullScreen(true);\n setAutoFullscreenTriggered(true); // Mark that auto fullscreen was triggered\n }\n });\n }\n }, [\n response,\n fullScreen,\n autoFullscreenTriggered,\n manualFullscreenToggleTime,\n modalRef,\n setFullScreen,\n setAutoFullscreenTriggered,\n ]);\n\n useEffect(() => {\n const handlePaste = (e: ClipboardEvent) => {\n const items = e.clipboardData?.items;\n if (items) {\n for (const item of items) {\n if (item.type.startsWith(\"image/\")) {\n const file = item.getAsFile();\n if (file) {\n const reader = new FileReader();\n reader.onload = (event) => {\n if (event.target?.result) {\n setPastedImages((prev) => [...prev, event.target!.result as string]);\n }\n };\n reader.readAsDataURL(file);\n }\n }\n }\n }\n };\n\n document.addEventListener(\"paste\", handlePaste);\n return () => {\n document.removeEventListener(\"paste\", handlePaste);\n };\n }, []);\n\n useEffect(() => {\n if (response && !responseStarted) {\n setResponseStarted(true);\n }\n }, [response, responseStarted]);\n\n const handleDrawerClose = () => setDrawerOpen(false);\n const handleClose = () => {\n // Reset fullscreen state when modal closes (unless on mobile)\n const isMobile = window.innerWidth < 600; // Simple mobile check\n if (!isMobile) {\n setFullScreen(false);\n }\n // Reset auto fullscreen tracking when modal closes\n setAutoFullscreenTriggered(false);\n // Reset theme loading state when modal closes\n setThemeLoading(true);\n onClose();\n };\n\n const onSend = (e: React.MouseEvent | React.KeyboardEvent, value: string) => {\n setResponseStarted(false);\n handleSend();\n };\n\n // Don't render until theme is loaded\n if (themeLoading) {\n return null;\n }\n\n return (\n <ThemeProvider theme={activeTheme}>\n <Modal open={open} onClose={handleClose}>\n <DraggableBox\n ref={modalRef}\n position={position}\n setPosition={setPosition}\n fullScreen={fullScreen}\n onDrag={handleCustomDrag}\n >\n <ModalHeader\n fullScreen={fullScreen}\n setFullScreen={setFullScreen}\n onClose={handleClose}\n onDrawerOpen={() => setDrawerOpen(true)}\n onMouseDown={handleHeaderMouseDown}\n logo={modalLogo}\n historyCount={history.length}\n onManualFullscreenToggle={() => {\n setAutoFullscreenTriggered(false);\n setManualFullscreenToggleTime(Date.now());\n }}\n onExitFullscreen={handleExitFullscreen}\n />\n\n {/* Scrollable content area */}\n <Box\n sx={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\", // Let child handle scrolling\n minHeight: 0, // Important for flex scrolling\n }}\n >\n <Box\n sx={{\n flex: 1,\n overflow: \"auto\", // Enable scrolling here\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n // Ensure proper height calculation for both fullscreen and windowed\n height: fullScreen ? \"auto\" : \"100%\",\n maxHeight: fullScreen ? \"none\" : \"100%\",\n // Custom scrollbar styling\n \"&::-webkit-scrollbar\": {\n width: \"8px\",\n },\n \"&::-webkit-scrollbar-track\": {\n background: activeTheme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n borderRadius: \"4px\",\n },\n \"&::-webkit-scrollbar-thumb\": {\n background: activeTheme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.2)\" : \"rgba(0,0,0,0.2)\",\n borderRadius: \"4px\",\n \"&:hover\": {\n background: activeTheme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.3)\" : \"rgba(0,0,0,0.3)\",\n },\n },\n }}\n >\n <QueryInput\n inputValue={inputValue}\n onChange={setInputValue}\n onSend={onSend}\n apiKey={apiKey}\n showSettings={showSettings}\n setShowSettings={setShowSettings}\n setApiKey={setApiKey}\n startAdornment={\n <InputAdornment position=\"start\" sx={{ gap: 1 }}>\n {/* Model selector with avatar */}\n <Tooltip title={`Current AI: ${selectedModel.replace(\"Bandit-\", \"\")}`} arrow>\n <IconButton\n onClick={(e) => setModelAnchorEl(e.currentTarget)}\n sx={{\n p: 0.5,\n borderRadius: \"8px\",\n transition: \"all 0.2s ease-in-out\",\n \"&:hover\": {\n backgroundColor: activeTheme.palette.action.hover,\n transform: \"scale(1.05)\",\n },\n }}\n >\n <Avatar\n src={currentAvatar}\n alt={selectedModel}\n sx={{\n width: 32,\n height: 32,\n filter: \"brightness(1.7)\",\n border: `2px solid ${activeTheme.palette.primary.main}30`,\n transition: \"all 0.2s ease-in-out\",\n }}\n />\n </IconButton>\n </Tooltip>\n\n {/* Enhanced Model selection menu */}\n <Menu\n anchorEl={modelAnchorEl}\n open={Boolean(modelAnchorEl)}\n onClose={() => setModelAnchorEl(null)}\n transformOrigin={{ horizontal: 'left', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}\n PaperProps={{\n sx: {\n bgcolor: activeTheme.palette.background.paper,\n color: activeTheme.palette.text.primary,\n fontSize: \"0.875rem\",\n zIndex: 20000,\n maxHeight: 300,\n minWidth: 200,\n border: `1px solid ${activeTheme.palette.divider}`,\n borderRadius: \"12px\",\n boxShadow: activeTheme.palette.mode === \"dark\"\n ? \"0 8px 32px rgba(0,0,0,0.5)\"\n : \"0 8px 32px rgba(0,0,0,0.2)\",\n \"& .MuiMenuItem-root\": {\n borderRadius: \"8px\",\n margin: \"4px 8px\",\n transition: \"all 0.15s ease-in-out\",\n \"&:hover\": {\n bgcolor: activeTheme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.04)\",\n transform: \"translateX(2px)\",\n },\n \"&.Mui-selected\": {\n bgcolor: activeTheme.palette.primary.main + \"20\",\n color: activeTheme.palette.primary.main,\n \"&:hover\": {\n bgcolor: activeTheme.palette.primary.main + \"30\",\n },\n },\n },\n },\n }}\n >\n {availableModels.map((model) => (\n <MenuItem\n key={model.name}\n selected={model.name === selectedModel}\n onClick={() => {\n setSelectedModel(model.name);\n useModelStore.getState().setSelectedModel(model.name);\n setModelAnchorEl(null);\n }}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n minHeight: 48,\n px: 2,\n }}\n >\n <Avatar\n src={\n model.avatarBase64 ||\n modelAvatars[model.name] ||\n banditHead\n }\n alt={model.name}\n sx={{\n width: 28,\n height: 28,\n filter: \"brightness(1.7)\",\n transition: \"all 0.2s ease-in-out\",\n }}\n />\n <Box sx={{ flex: 1 }}>\n <Typography variant=\"body2\" sx={{ fontWeight: 500 }}>\n {model.name.replace(\"Bandit-\", \"\")}\n </Typography>\n <Typography variant=\"caption\" sx={{ color: activeTheme.palette.text.secondary }}>\n {model.name === selectedModel ? \"Currently active\" : \"Switch to this AI\"}\n </Typography>\n </Box>\n {model.name === selectedModel && (\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n bgcolor: activeTheme.palette.primary.main,\n }}\n />\n )}\n </MenuItem>\n ))}\n </Menu>\n\n {/* Voice selector - only show if TTS is available */}\n {isTTSAvailable && (\n <>\n <Tooltip title={`Voice: ${selectedVoice ? toTitleCase(selectedVoice.split(\"-\")[1]) : \"Default\"}`} arrow>\n <IconButton\n onClick={(e) => setVoiceAnchorEl(e.currentTarget)}\n sx={{\n p: 0.5,\n borderRadius: \"8px\",\n bgcolor: activeTheme.palette.info.main + \"20\",\n color: activeTheme.palette.info.main,\n transition: \"all 0.2s ease-in-out\",\n \"&:hover\": {\n backgroundColor: activeTheme.palette.info.main + \"30\",\n transform: \"scale(1.05)\",\n },\n }}\n aria-label={`Change voice. Currently using ${selectedVoice ? toTitleCase(selectedVoice.split(\"-\")[1]) : \"default\"}`}\n >\n <RecordVoiceOverIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Menu\n anchorEl={voiceAnchorEl}\n open={Boolean(voiceAnchorEl)}\n onClose={() => setVoiceAnchorEl(null)}\n transformOrigin={{ horizontal: 'left', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}\n PaperProps={{\n sx: {\n bgcolor: activeTheme.palette.background.paper,\n color: activeTheme.palette.text.primary,\n fontSize: \"0.875rem\",\n zIndex: 20000,\n borderRadius: 2,\n border: `1px solid ${activeTheme.palette.divider}`,\n boxShadow: activeTheme.palette.mode === \"dark\"\n ? \"0 8px 32px rgba(0,0,0,0.5)\"\n : \"0 8px 32px rgba(0,0,0,0.2)\",\n \"& .MuiMenuItem-root\": {\n borderRadius: \"8px\",\n margin: \"4px 8px\",\n transition: \"all 0.15s ease-in-out\",\n \"&:hover\": {\n bgcolor: activeTheme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.04)\",\n },\n \"&.Mui-selected\": {\n bgcolor: activeTheme.palette.info.main + \"20\",\n color: activeTheme.palette.info.main,\n \"&:hover\": {\n bgcolor: activeTheme.palette.info.main + \"30\",\n },\n },\n },\n },\n }}\n >\n {availableVoices.length > 0 ? (\n availableVoices.map((voice) => (\n <MenuItem\n key={voice}\n selected={voice === selectedVoice}\n onClick={() => {\n handleVoiceChange(voice);\n setVoiceAnchorEl(null);\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1, width: \"100%\" }}>\n <RecordVoiceOverIcon fontSize=\"small\" sx={{ color: activeTheme.palette.text.secondary }} />\n <Box sx={{ flex: 1 }}>\n <Typography variant=\"body2\">\n {toTitleCase(voice.split(\"-\")[1])}\n </Typography>\n <Typography variant=\"caption\" sx={{ color: activeTheme.palette.text.secondary }}>\n {voice === selectedVoice ? \"Currently active\" : \"Switch to this voice\"}\n </Typography>\n </Box>\n {voice === selectedVoice && (\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n bgcolor: activeTheme.palette.info.main,\n }}\n />\n )}\n </Box>\n </MenuItem>\n ))\n ) : (\n <MenuItem disabled>\n <Typography variant=\"body2\" color=\"text.secondary\">\n No voices available\n </Typography>\n </MenuItem>\n )}\n </Menu>\n </>\n )}\n\n {/* Enhanced Pasted images */}\n {pastedImages.map((img, idx) => (\n <Box\n key={idx}\n sx={{\n position: \"relative\",\n transition: \"all 0.15s ease-out\",\n \"&:hover\": {\n // Removed transform to prevent jitter\n },\n }}\n >\n <Avatar\n src={img}\n variant=\"rounded\"\n sx={{\n width: 32,\n height: 32,\n borderRadius: \"8px\",\n border: `2px solid ${activeTheme.palette.primary.main}30`,\n cursor: \"pointer\",\n }}\n />\n <Tooltip title=\"Remove image\" arrow>\n <IconButton\n size=\"small\"\n onClick={() => removeImage(idx)}\n sx={{\n position: \"absolute\",\n top: -8,\n right: -8,\n width: 20,\n height: 20,\n bgcolor: activeTheme.palette.error.main,\n color: \"white\",\n border: `2px solid ${activeTheme.palette.background.paper}`,\n transition: \"all 0.15s ease-out\",\n \"&:hover\": {\n bgcolor: activeTheme.palette.error.dark,\n // Removed transform to prevent jitter\n },\n }}\n >\n <CloseIcon sx={{ fontSize: 12 }} />\n </IconButton>\n </Tooltip>\n </Box>\n ))}\n </InputAdornment>\n }\n endAdornment={\n <InputAdornment position=\"end\" sx={{ gap: 1 }}>\n {preferences.feedbackEnabled && (\n <FeedbackButton\n inline={true}\n size=\"small\"\n buttonText=\"\"\n />\n )}\n <Tooltip title={inputValue.trim() === \"\" ? \"Type a message first\" : \"Send Message\"} arrow>\n <span>\n <IconButton\n onClick={handleSend}\n disabled={inputValue.trim() === \"\"}\n sx={{\n color: inputValue.trim() !== \"\"\n ? activeTheme.palette.primary.main\n : activeTheme.palette.action.disabled,\n transition: \"all 0.15s ease-out\",\n borderRadius: \"8px\",\n minWidth: \"40px\",\n minHeight: \"40px\",\n \"&:hover\": {\n bgcolor: inputValue.trim() !== \"\"\n ? activeTheme.palette.primary.main + \"15\"\n : \"transparent\",\n // Removed transform to prevent jitter\n },\n \"&:active\": {\n bgcolor: inputValue.trim() !== \"\"\n ? activeTheme.palette.primary.main + \"25\"\n : \"transparent\",\n },\n \"&:disabled\": {\n color: activeTheme.palette.action.disabled,\n },\n }}\n >\n <SendIcon />\n </IconButton>\n </span>\n </Tooltip>\n </InputAdornment>\n }\n />\n\n {!responseStarted && componentStatus === \"Loading\" && <GenericLoader variant=\"dots\" />}\n {responseStarted && response && !showSettings && (\n <AIResponseTextField question={previousQuestion} response={response} />\n )}\n </Box>\n </Box>\n\n <AIQueriesDrawer\n drawerOpen={drawerOpen}\n onClose={handleDrawerClose}\n onClearComplete={handleClose}\n onNavigateToMain={navigate ? () => {\n onClose(); // Close the modal\n navigate('/chat'); // Navigate to main chat\n } : undefined}\n />\n </DraggableBox>\n </Modal>\n </ThemeProvider>\n );\n };\n\nexport default ChatModal;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useEffect, useState } from \"react\";\nimport { Box, useTheme, Fade } from \"@mui/material\";\n\ninterface DraggableBoxProps {\n children: React.ReactNode;\n fullScreen: boolean;\n position: { x: number; y: number };\n setPosition: (pos: { x: number; y: number }) => void;\n onDrag: (e: MouseEvent) => void;\n onScrollThresholdExceeded?: () => void;\n}\n\nconst SCROLLABLE_THRESHOLD = 200;\n\nconst DraggableBox = React.forwardRef<HTMLDivElement, DraggableBoxProps>(\n (\n { children, fullScreen, position, setPosition, onDrag, onScrollThresholdExceeded },\n ref\n ) => {\n const theme = useTheme();\n const [transitionProps, setTransitionProps] = useState(\"all\");\n const [isDragging, setIsDragging] = useState(false);\n const [isHovering, setIsHovering] = useState(false);\n \n useEffect(() => {\n if (ref && typeof ref !== \"function\" && ref.current && !fullScreen) {\n const modal = ref.current;\n const contentHeight = modal.scrollHeight;\n const modalHeight = modal.clientHeight;\n const hasOverflow = contentHeight > modalHeight + SCROLLABLE_THRESHOLD;\n \n if (hasOverflow) {\n onScrollThresholdExceeded?.();\n }\n }\n }, [children, fullScreen, onScrollThresholdExceeded, ref]);\n\n return (\n <Fade in timeout={300}>\n <Box\n ref={ref}\n tabIndex={-1}\n onMouseDown={(e) => {\n setTransitionProps(\"none\");\n setIsDragging(true);\n }}\n onMouseUp={(e) => {\n setTransitionProps(\"all\");\n setIsDragging(false);\n }}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n sx={{\n transitionProperty: transitionProps,\n transitionDuration: fullScreen ? \"0.4s\" : \"0.3s\",\n transitionTimingFunction: \"cubic-bezier(0.4, 0, 0.2, 1)\",\n position: \"absolute\",\n top: fullScreen ? 0 : position.y,\n left: fullScreen ? 0 : position.x,\n width: fullScreen ? \"calc(100vw)\" : \"90vw\",\n maxWidth: fullScreen ? \"100vw\" : 600,\n height: fullScreen ? \"100vh\" : \"auto\",\n minHeight: fullScreen ? \"100vh\" : \"fit-content\",\n maxHeight: fullScreen ? \"100vh\" : \"85vh\", // Add max height for scrolling\n overflow: \"hidden\", // Prevent modal itself from scrolling\n bgcolor: theme.palette.background.paper,\n borderRadius: fullScreen ? 0 : \"20px\",\n boxShadow: fullScreen \n ? \"none\" \n : isDragging\n ? `0 25px 50px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.7)\" : \"rgba(0,0,0,0.4)\"}`\n : isHovering\n ? `0 16px 32px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.5)\" : \"rgba(0,0,0,0.25)\"}`\n : `0 12px 24px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.4)\" : \"rgba(0,0,0,0.2)\"}`,\n p: fullScreen ? 2 : 3,\n display: \"flex\",\n flexDirection: \"column\",\n outline: \"none\",\n backdropFilter: fullScreen ? \"none\" : \"blur(20px)\",\n border: fullScreen \n ? \"none\" \n : `1px solid ${theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.15)\" : \"rgba(0,0,0,0.15)\"}`,\n // Removed transform to prevent jitter and layout shifts\n \"&:focus\": {\n outline: `2px solid ${theme.palette.primary.main}40`,\n outlineOffset: \"2px\",\n },\n }}\n >\n <Box\n sx={{\n position: 'relative',\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n {children}\n </Box>\n </Box>\n </Fade>\n );\n }\n);\n\nexport default DraggableBox;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState } from \"react\";\nimport {\n Avatar,\n Box,\n IconButton,\n Tooltip,\n useMediaQuery,\n Theme,\n useTheme,\n Typography,\n Chip,\n Fade,\n} from \"@mui/material\";\nimport {\n CloseIcon,\n DragIndicatorIcon,\n FullscreenExitIcon,\n FullscreenIcon,\n HistoryIcon,\n MinimizeIcon,\n} from \"../../icons\";\n\nconst banditaiLogo = \"https://cdn.burtson.ai/logos/bandit-ai-logo.png\";\nconst banditHead = \"https://cdn.burtson.ai/images/bandit-head.png\";\n\n// Utility function to determine if a color is light or dark\nconst getContrastTextColor = (backgroundColor: string): string => {\n // Convert hex to RGB\n const hex = backgroundColor.replace('#', '');\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n \n // Calculate luminance using the relative luminance formula\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n \n // Return dark text for light backgrounds, light text for dark backgrounds\n return luminance > 0.6 ? '#2f2f2f' : '#ffffff';\n};\n\ninterface ModalHeaderProps {\n fullScreen: boolean;\n setFullScreen: React.Dispatch<React.SetStateAction<boolean>>;\n onClose: () => void;\n onDrawerOpen: () => void;\n onMouseDown: (e: React.MouseEvent) => void;\n logo?: string;\n historyCount?: number;\n onManualFullscreenToggle?: () => void;\n onExitFullscreen?: () => void; // Add callback for exiting fullscreen\n}\n\nconst ModalHeader: React.FC<ModalHeaderProps> = ({\n fullScreen,\n setFullScreen,\n onClose,\n onDrawerOpen,\n onMouseDown,\n logo,\n historyCount = 0,\n onManualFullscreenToggle,\n onExitFullscreen,\n}) => {\n const theme = useTheme();\n const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down(\"sm\"));\n const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead;\n const [isHovering, setIsHovering] = useState(false);\n\n // Enhanced button styles for modern UX - Fixed jitter\n const buttonStyles = {\n transition: \"all 0.15s ease-out\",\n borderRadius: \"8px\",\n minWidth: \"36px\",\n minHeight: \"36px\",\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.08)\" : \"rgba(0,0,0,0.06)\",\n // Removed transform to prevent jitter\n },\n \"&:active\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.12)\" : \"rgba(0,0,0,0.08)\",\n },\n };\n\n const handleMinimize = (e: React.MouseEvent) => {\n e.stopPropagation(); // Prevent drag from interfering\n onClose();\n };\n\n const handleToggleFullScreen = (e: React.MouseEvent) => {\n e.stopPropagation(); // Prevent drag from interfering\n \n const wasFullScreen = fullScreen;\n \n // When user manually toggles fullscreen, we should respect their choice\n // and not re-trigger auto fullscreen for this session\n setFullScreen((prev) => !prev);\n \n // If exiting fullscreen, trigger repositioning\n if (wasFullScreen && onExitFullscreen) {\n // Use setTimeout to ensure the fullscreen state has updated\n setTimeout(() => {\n onExitFullscreen();\n }, 100);\n }\n \n // Reset auto fullscreen tracking when user manually toggles\n // This prevents auto-fullscreen from interfering with user's choice\n if (onManualFullscreenToggle) {\n onManualFullscreenToggle();\n }\n };\n\n return (\n <Box\n onMouseDown={onMouseDown}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n sx={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n cursor: \"grab\",\n userSelect: \"none\",\n mb: 2,\n p: 1.5,\n borderRadius: \"16px\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.03)\" : \"rgba(0,0,0,0.03)\",\n border: `1px solid ${theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.12)\" : \"rgba(0,0,0,0.12)\"}`,\n backdropFilter: \"blur(12px)\",\n transition: \"all 0.2s ease-out\",\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.06)\" : \"rgba(0,0,0,0.06)\",\n borderColor: theme.palette.primary.main + \"50\",\n boxShadow: `0 8px 32px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.4)\" : \"rgba(0,0,0,0.15)\"}`,\n // Removed transform to prevent layout shifts\n },\n \"&:active\": {\n cursor: \"grabbing\",\n },\n }}\n >\n {/* Left Section - Avatar and Status */}\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 2, flex: 1 }}>\n <Avatar\n src={displayLogo}\n alt=\"AI Assistant\"\n sx={{ \n width: fullScreen ? 72 : 60,\n height: fullScreen ? 72 : 60,\n bgcolor: theme.palette.mode === \"dark\"\n ? \"rgba(255,255,255,0.06)\"\n : \"rgba(0,0,0,0.04)\",\n border: \"2px solid #a78bfa\",\n boxShadow: \"0 0 8px rgba(167, 139, 250, 0.3)\",\n filter: \"brightness(1.05)\",\n color: \"#fff\",\n transition: \"all 0.3s cubic-bezier(0.4, 0, 0.2, 1)\",\n \"&:hover\": {\n backgroundColor: theme.palette.mode === \"dark\" \n ? \"rgba(255,255,255,0.08)\" \n : \"rgba(0,0,0,0.05)\",\n transform: \"scale(1.02)\",\n }\n }}\n />\n \n <Fade in={isHovering && !fullScreen}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <DragIndicatorIcon \n sx={{ \n color: theme.palette.text.secondary, \n fontSize: \"1.2rem\",\n opacity: 0.6,\n }} \n />\n <Typography \n variant=\"caption\" \n sx={{ \n color: theme.palette.text.secondary,\n fontWeight: 500,\n }}\n >\n Drag to move\n </Typography>\n </Box>\n </Fade>\n </Box>\n\n {/* Right Section - Controls */}\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.5 }}> \n <Tooltip title=\"Chat History\" arrow>\n <IconButton\n aria-label=\"Open chat history\"\n onClick={(e) => {\n e.stopPropagation();\n onDrawerOpen();\n }}\n sx={{\n ...buttonStyles,\n position: \"relative\",\n color: theme.palette.text.primary,\n }}\n >\n <HistoryIcon />\n {historyCount > 0 && (\n <Chip\n label={historyCount > 99 ? \"99+\" : historyCount}\n size=\"small\"\n sx={{\n position: \"absolute\",\n top: -8,\n right: -8,\n height: 18,\n fontSize: \"0.65rem\",\n bgcolor: theme.palette.primary.main,\n color: \"white\",\n \"& .MuiChip-label\": {\n px: 0.5,\n },\n }}\n />\n )}\n </IconButton>\n </Tooltip>\n \n {!isMobile && (\n <Tooltip title={fullScreen ? \"Exit Fullscreen\" : \"Enter Fullscreen\"} arrow>\n <IconButton\n aria-label={fullScreen ? \"exit fullscreen\" : \"enter fullscreen\"}\n onClick={handleToggleFullScreen}\n sx={{\n ...buttonStyles,\n color: theme.palette.text.primary,\n bgcolor: fullScreen ? theme.palette.primary.main + \"20\" : \"transparent\",\n }}\n >\n {fullScreen ? <FullscreenExitIcon /> : <FullscreenIcon />}\n </IconButton>\n </Tooltip>\n )}\n \n <Tooltip title=\"Minimize\" arrow>\n <IconButton\n aria-label=\"minimize window\"\n onClick={handleMinimize}\n sx={{\n ...buttonStyles,\n color: theme.palette.warning.main,\n }}\n >\n <MinimizeIcon />\n </IconButton>\n </Tooltip>\n \n <Tooltip title=\"Close\" arrow>\n <IconButton \n aria-label=\"close window\" \n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n sx={{\n ...buttonStyles,\n color: theme.palette.error.main,\n \"&:hover\": {\n bgcolor: theme.palette.error.main + \"15\",\n color: theme.palette.error.main,\n // Removed transform to prevent jitter\n },\n }}\n >\n <CloseIcon />\n </IconButton>\n </Tooltip>\n </Box>\n </Box>\n );\n};\n\nexport default ModalHeader;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n/*\n Engine icons. Every icon is a Burtson Icons MUI SvgIcon\n (@burtson-labs/icons/mui/<name>), so `fontSize`, `color`, `sx`, `htmlColor`\n and `titleAccess` work exactly as they do with @mui/icons-material. The\n export names are the Material names the engine has always used, so a call\n site reads the same whichever set drew the glyph. Add an icon here rather\n than importing a package path from a component; the per-icon entries keep\n the bundle to the icons actually used.\n*/\n\nexport { AlertCircle as ErrorOutlineIcon, AlertCircle as ErrorIcon } from \"@burtson-labs/icons/mui/alert-circle\";\nexport { AlertTriangle as WarningIcon, AlertTriangle as TriangleAlertIcon } from \"@burtson-labs/icons/mui/alert-triangle\";\nexport { Archive as ArchiveIcon } from \"@burtson-labs/icons/mui/archive\";\nexport { ArrowDown as ArrowDownwardIcon } from \"@burtson-labs/icons/mui/arrow-down\";\nexport { ArrowUp as ArrowUpwardIcon } from \"@burtson-labs/icons/mui/arrow-up\";\nexport { BookOpen as MenuBookIcon } from \"@burtson-labs/icons/mui/book-open\";\nexport { BookOpenText as AutoStoriesIcon } from \"@burtson-labs/icons/mui/book-open-text\";\nexport { Braces as DataObjectIcon } from \"@burtson-labs/icons/mui/braces\";\nexport { BrushCleaning as CleaningServicesIcon } from \"@burtson-labs/icons/mui/brush-cleaning\";\nexport { Check as CheckIcon } from \"@burtson-labs/icons/mui/check\";\nexport { CheckCircle as CheckCircleIcon } from \"@burtson-labs/icons/mui/check-circle\";\nexport { ChevronDown as ExpandMoreIcon } from \"@burtson-labs/icons/mui/chevron-down\";\nexport { ChevronLeft as ChevronLeftIcon } from \"@burtson-labs/icons/mui/chevron-left\";\nexport { ChevronUp as ExpandLessIcon } from \"@burtson-labs/icons/mui/chevron-up\";\nexport { Cloud as CloudIcon } from \"@burtson-labs/icons/mui/cloud\";\nexport { CloudCheck as CloudDoneIcon } from \"@burtson-labs/icons/mui/cloud-check\";\nexport { CloudOff as CloudOffIcon } from \"@burtson-labs/icons/mui/cloud-off\";\nexport { CloudSync as CloudSyncIcon } from \"@burtson-labs/icons/mui/cloud-sync\";\nexport { Code as CodeIcon } from \"@burtson-labs/icons/mui/code\";\nexport { Copy as ContentCopyIcon } from \"@burtson-labs/icons/mui/copy\";\nexport { Database as StorageIcon } from \"@burtson-labs/icons/mui/database\";\nexport { Download as DownloadIcon } from \"@burtson-labs/icons/mui/download\";\nexport { EarOff as HearingDisabledIcon } from \"@burtson-labs/icons/mui/ear-off\";\nexport { Edit as EditIcon } from \"@burtson-labs/icons/mui/edit\";\nexport { EditSquare as ComposeIcon } from \"@burtson-labs/icons/mui/edit-square\";\nexport { Eye as PreviewIcon, Eye as VisibilityIcon } from \"@burtson-labs/icons/mui/eye\";\nexport { FilePdf as PictureAsPdfIcon } from \"@burtson-labs/icons/mui/file-pdf\";\nexport { FileText as DescriptionIcon, FileText as ArticleIcon } from \"@burtson-labs/icons/mui/file-text\";\nexport { FileUp as FileUploadIcon, FileUp as UploadFileIcon } from \"@burtson-labs/icons/mui/file-up\";\nexport { Folder as FolderIcon } from \"@burtson-labs/icons/mui/folder\";\nexport { FolderOpen as FolderOpenIcon } from \"@burtson-labs/icons/mui/folder-open\";\nexport { Ghost as GhostIcon } from \"@burtson-labs/icons/mui/ghost\";\nexport { Globe as PublicIcon } from \"@burtson-labs/icons/mui/globe\";\nexport { Grip as DragIndicatorIcon } from \"@burtson-labs/icons/mui/grip\";\nexport { History as HistoryIcon } from \"@burtson-labs/icons/mui/history\";\nexport { Home as HomeIcon } from \"@burtson-labs/icons/mui/home\";\nexport { Info as InfoIcon, Info as InfoOutlinedIcon } from \"@burtson-labs/icons/mui/info\";\nexport { LayoutGrid as ViewModuleIcon, LayoutGrid as ViewModuleOutlinedIcon } from \"@burtson-labs/icons/mui/layout-grid\";\nexport { Link as LinkIcon } from \"@burtson-labs/icons/mui/link\";\nexport { List as ViewListIcon } from \"@burtson-labs/icons/mui/list\";\nexport { Lock as LockIcon } from \"@burtson-labs/icons/mui/lock\";\nexport { Maximize as FullscreenIcon } from \"@burtson-labs/icons/mui/maximize\";\nexport { MemoryLayers as PsychologyIcon, MemoryLayers as MemoryIcon } from \"@burtson-labs/icons/mui/memory-layers\";\nexport { MessageSquare as FeedbackIcon, MessageSquare as ChatIcon } from \"@burtson-labs/icons/mui/message-square\";\nexport { Mic as RecordVoiceOverIcon, Mic as MicIcon } from \"@burtson-labs/icons/mui/mic\";\nexport { Minimize as FullscreenExitIcon } from \"@burtson-labs/icons/mui/minimize\";\nexport { Minus as MinimizeIcon } from \"@burtson-labs/icons/mui/minus\";\nexport { NotebookPen as NotesIcon, NotebookPen as NotesIconOutlined, NotebookPen as EditNoteOutlinedIcon } from \"@burtson-labs/icons/mui/notebook-pen\";\nexport { Palette as BrushIcon } from \"@burtson-labs/icons/mui/palette\";\nexport { PanelLeft as PanelLeftIcon } from \"@burtson-labs/icons/mui/panel-left\";\nexport { Pin as PushPinIcon } from \"@burtson-labs/icons/mui/pin\";\nexport { PinOff as PushPinOutlinedIcon } from \"@burtson-labs/icons/mui/pin-off\";\nexport { Play as PlayArrowIcon, Play as PlayArrowRoundedIcon } from \"@burtson-labs/icons/mui/play\";\nexport { Plus as AddIcon } from \"@burtson-labs/icons/mui/plus\";\nexport { PlusCircle as AddCircleIcon } from \"@burtson-labs/icons/mui/plus-circle\";\nexport { RectangleHorizontal as Crop169Icon } from \"@burtson-labs/icons/mui/rectangle-horizontal\";\nexport { RectangleVertical as CropPortraitIcon } from \"@burtson-labs/icons/mui/rectangle-vertical\";\nexport { Refresh as SyncIcon, Refresh as RefreshIcon } from \"@burtson-labs/icons/mui/refresh\";\nexport { Rocket as RocketLaunchOutlinedIcon } from \"@burtson-labs/icons/mui/rocket\";\nexport { RotateCcw as RotateLeftIcon, RotateCcw as RestoreIcon } from \"@burtson-labs/icons/mui/rotate-ccw\";\nexport { RotateCw as RotateRightIcon } from \"@burtson-labs/icons/mui/rotate-cw\";\nexport { Save as SaveIcon } from \"@burtson-labs/icons/mui/save\";\nexport { ScanFace as FaceRetouchingNaturalIcon } from \"@burtson-labs/icons/mui/scan-face\";\nexport { Search as SearchIcon } from \"@burtson-labs/icons/mui/search\";\nexport { Send as SendIcon } from \"@burtson-labs/icons/mui/send\";\nexport { Settings as SettingsIcon } from \"@burtson-labs/icons/mui/settings\";\nexport { ShieldProof as HealthAndSafetyIcon } from \"@burtson-labs/icons/mui/shield-proof\";\nexport { Sliders as TuneIcon } from \"@burtson-labs/icons/mui/sliders\";\nexport { Sparkles as AutoAwesomeIcon } from \"@burtson-labs/icons/mui/sparkles\";\nexport { Square as StopIcon, Square as CropSquareIcon } from \"@burtson-labs/icons/mui/square\";\nexport { Trash as DeleteIcon } from \"@burtson-labs/icons/mui/trash\";\nexport { Type as TextFieldsIcon } from \"@burtson-labs/icons/mui/type\";\nexport { Upload as UploadIcon, Upload as PublishIcon } from \"@burtson-labs/icons/mui/upload\";\nexport { User as PersonIcon } from \"@burtson-labs/icons/mui/user\";\nexport { UserCog as ManageAccountsOutlinedIcon } from \"@burtson-labs/icons/mui/user-cog\";\nexport { Users as GroupIcon } from \"@burtson-labs/icons/mui/users\";\nexport { Waveform as GraphicEqIcon } from \"@burtson-labs/icons/mui/waveform\";\nexport { Wifi as SignalWifi2BarIcon, Wifi as SignalWifiStatusbar4BarIcon, Wifi as WifiIcon } from \"@burtson-labs/icons/mui/wifi\";\nexport { WifiOff as WifiOffIcon } from \"@burtson-labs/icons/mui/wifi-off\";\nexport { Wrench as BuildIcon } from \"@burtson-labs/icons/mui/wrench\";\nexport { X as CloseIcon } from \"@burtson-labs/icons/mui/x\";\nexport { ZoomIn as ZoomInIcon } from \"@burtson-labs/icons/mui/zoom-in\";\nexport { ZoomOut as ZoomOutIcon } from \"@burtson-labs/icons/mui/zoom-out\";\n\nexport type { MuiIcon, MuiIconProps } from \"@burtson-labs/icons/mui\";\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useRef } from \"react\";\nimport { Box, TextField, IconButton, Tooltip, InputAdornment, useTheme } from \"@mui/material\";\nimport { CheckIcon } from \"../../icons\";\n\ninterface QueryInputProps {\n inputValue: string;\n onChange: (val: string) => void;\n onSend: (\n event: React.MouseEvent<HTMLButtonElement | HTMLDivElement> | React.KeyboardEvent<HTMLDivElement | HTMLTextAreaElement>,\n value: string\n ) => void;\n apiKey: string;\n setApiKey: (key: string) => void;\n showSettings: boolean;\n setShowSettings: (val: boolean) => void;\n startAdornment?: React.ReactNode; // Added startAdornment prop\n endAdornment?: React.ReactNode; // Added endAdornment prop\n}\n\nconst QueryInput: React.FC<QueryInputProps> = ({\n inputValue,\n onChange,\n onSend,\n apiKey,\n setApiKey,\n showSettings,\n setShowSettings,\n startAdornment, // Destructure startAdornment\n endAdornment, // Destructure endAdornment\n}) => {\n const theme = useTheme();\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const handleSend = (\n e: React.MouseEvent<HTMLButtonElement | HTMLDivElement> | React.KeyboardEvent<HTMLDivElement | HTMLTextAreaElement>,\n payload: string\n ) => {\n onSend(e, payload);\n };\n const handleKeyPress = (e: React.KeyboardEvent<HTMLDivElement | HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (inputValue.trim() !== \"\") {\n handleSend(e, inputValue);\n }\n }\n };\n\n return (\n <Box onMouseDown={(e) => e.stopPropagation()} sx={{ padding: 2 }}>\n {showSettings ? (\n <TextField\n fullWidth\n variant=\"outlined\"\n label=\"API Key\"\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n InputProps={{\n sx: { color: theme.palette.text.primary, borderColor: theme.palette.divider },\n startAdornment: (\n <InputAdornment position=\"start\">\n <Tooltip title=\"Toggle Settings\">\n <IconButton\n aria-label=\"settings\"\n onClick={() => setShowSettings(!showSettings)}\n >\n <CheckIcon sx={{ color: showSettings ? theme.palette.primary.main : theme.palette.text.primary }} />\n </IconButton>\n </Tooltip>\n </InputAdornment>\n ),\n }}\n sx={{ bgcolor: theme.palette.background.paper, borderRadius: 1 }}\n />\n ) : (\n <TextField\n fullWidth\n variant=\"outlined\"\n placeholder=\"Ask me anything...\"\n value={inputValue}\n inputRef={inputRef}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={handleKeyPress}\n multiline\n maxRows={4}\n InputProps={{\n sx: { color: theme.palette.text.primary, borderColor: theme.palette.divider },\n startAdornment: startAdornment, // Use startAdornment prop\n endAdornment: endAdornment, // Use endAdornment prop\n }}\n sx={{\n bgcolor: theme.palette.background.paper,\n borderRadius: 1,\n \"& .MuiOutlinedInput-root\": { padding: \"10px\" },\n }}\n />\n )}\n </Box>\n );\n};\n\nexport default QueryInput;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport DocumentCard from \"../../shared/DocumentCard\";\nimport KnowledgeFileModal from \"../../modals/knowlege/knowledge-file-modal\";\nimport { KnowledgeDoc } from \"../../store/knowledgeStore\";\nimport { useKnowledgeStore } from \"../../chat/hooks/useKnowledgeStore\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport type { Theme } from \"@mui/material/styles\";\nimport ReactMarkdown, { type Components as ReactMarkdownComponents, type ExtraProps as ReactMarkdownExtraProps } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport rehypeSanitize from \"rehype-sanitize\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport {\n Avatar,\n Box,\n IconButton,\n Modal,\n Tooltip,\n Typography,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Paper,\n} from \"@mui/material\";\nimport type { Element, Text, Root } from \"hast\";\nimport { getHighlightTree } from \"../../utils/lowlight\";\nimport { MarkdownImage, markdownSanitizeSchema, renderLowlightChildren } from \"../../utils/markdownRendering\";\nimport { CheckIcon, CloseIcon, ContentCopyIcon } from \"../../icons\";\nimport { maybeHandleFileLinkClick } from \"../../utils/openFileLink\";\nconst brainIcon = \"https://cdn.burtson.ai/images/brain-icon.png\";\n\nimport AiResponseActionsBar from \"./ai-response-action-bar\";\nimport { chatTokens, responseTokens } from \"../../chat/chat-tokens\";\n\ninterface AIResponseTextFieldProps {\n question: string;\n response: string | React.ReactNode;\n responseText?: string; // raw markdown/text used for actions bar (feedback/tts/copy)\n images?: string[];\n backgroundColor?: string;\n memoryUpdated?: boolean;\n sourceFiles?: SourceFileInput[];\n isMobile?: boolean;\n cancelled?: boolean;\n /** Hide the actions bar until the message is hovered (older responses). */\n revealActionsOnHover?: boolean;\n}\n\nconst normalizeTables = (markdown: string): string => {\n const lines = markdown.split(\"\\n\");\n const output: string[] = [];\n let inTable = false;\n let tableRows: string[][] = [];\n\n const flushTable = () => {\n if (tableRows.length === 0) return;\n\n const maxCols = Math.max(...tableRows.map((r) => r.length));\n const padded = tableRows.map((row) => {\n return [...row, ...Array(maxCols - row.length).fill(\"\")];\n });\n\n const header = padded[0];\n const separator = Array(maxCols).fill(\"---\");\n\n output.push(\"| \" + header.join(\" | \") + \" |\");\n output.push(\"| \" + separator.join(\" | \") + \" |\");\n for (let i = 1; i < padded.length; i++) {\n const row = padded[i];\n // Skip rows that are just separators (all dashes)\n if (row.every((cell) => /^-+$/.test(cell))) continue;\n output.push(\"| \" + row.join(\" | \") + \" |\");\n }\n\n tableRows = [];\n inTable = false;\n };\n\n for (const line of lines) {\n if (/^\\s*\\|.*\\|\\s*$/.test(line)) {\n inTable = true;\n const cells = line\n .trim()\n .slice(1, -1)\n .split(\"|\")\n .map((c) => c.trim());\n tableRows.push(cells);\n } else {\n if (inTable) flushTable();\n output.push(line);\n }\n }\n\n flushTable();\n return output.join(\"\\n\");\n};\n\ntype ChatResponsePalette = {\n codeBackground?: string;\n codeText?: string;\n aiBackground?: string;\n aiText?: string;\n aiBorder?: string;\n};\n\ntype VectorResultLike = {\n id?: string;\n fileId?: string;\n _id?: string;\n [key: string]: unknown;\n};\n\ntype KnowledgeDocCandidate = Partial<KnowledgeDoc> & {\n fileId?: string;\n _id?: string;\n filename?: string;\n uploadedAt?: string | Date;\n createdAt?: string | Date;\n mimeType?: string;\n content?: string | null;\n rawData?: string;\n embedding?: unknown;\n size?: number;\n uploadedBy?: string;\n userId?: string;\n userEmail?: string;\n bucket?: string;\n key?: string;\n s3Url?: string;\n teamSid?: string;\n contentSource?: \"team\" | \"user\";\n isUserContent?: boolean;\n isTeamContent?: boolean;\n _vectorResult?: VectorResultLike | null;\n metadata?: VectorResultLike | null;\n chunks?: string[];\n [key: string]: unknown;\n};\n\ntype SourceFileInput = KnowledgeDocCandidate;\n\n// `inline` is kept optional for older react-markdown callers; version 10 no\n// longer passes it.\ntype MarkdownComponentProps<Tag extends keyof JSX.IntrinsicElements> =\n React.ComponentPropsWithoutRef<Tag> & ReactMarkdownExtraProps & { inline?: boolean };\n\nconst isNonEmptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.trim().length > 0;\n\nconst toDateSafe = (value: unknown): Date | undefined => {\n if (value instanceof Date && !Number.isNaN(value.getTime())) {\n return value;\n }\n if (typeof value === \"string\" && value.trim()) {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n return undefined;\n};\n\nconst toNumberArray = (value: unknown): number[] | undefined => {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const numbers = value.filter((item): item is number => typeof item === \"number\" && Number.isFinite(item));\n return numbers.length ? numbers : undefined;\n};\n\ninterface MarkdownCodeBlockProps extends React.HTMLAttributes<HTMLElement> {\n inline?: boolean;\n className?: string;\n children: React.ReactNode;\n theme: Theme;\n chatResponse?: ChatResponsePalette;\n}\n\nconst MarkdownCodeBlock: React.FC<MarkdownCodeBlockProps> = ({\n inline,\n className,\n children,\n theme,\n chatResponse,\n ...props\n}) => {\n const match = /language-([\\w-]+)/.exec(className || \"\");\n const requestedLanguage = match?.[1]?.toLowerCase() || \"\";\n const codeText = String(children).replace(/\\n$/, \"\");\n const isProbablyBlock = codeText.includes(\"\\n\") || Boolean(requestedLanguage);\n\n const [copied, setCopied] = useState(false);\n const handleCopy = () => {\n navigator.clipboard.writeText(codeText);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const highlightTree = useMemo<Root | null>(\n () =>\n isProbablyBlock ? getHighlightTree(codeText, requestedLanguage) : null,\n [codeText, requestedLanguage, isProbablyBlock]\n );\n const highlightedNodes = useMemo(\n () =>\n isProbablyBlock\n ? renderLowlightChildren(\n (highlightTree?.children || []).filter((node): node is Element | Text => {\n if (!node) {\n return false;\n }\n return node.type === \"element\" || node.type === \"text\";\n }),\n `hl-${requestedLanguage || \"auto\"}`\n )\n : [],\n [highlightTree, requestedLanguage, isProbablyBlock]\n );\n\n const resolvedLanguage = (\n requestedLanguage ||\n highlightTree?.data?.language ||\n \"code\"\n ).toString();\n const languageLabel = resolvedLanguage.toUpperCase();\n const languageClass = resolvedLanguage.toLowerCase();\n\n const highlightColors =\n theme.palette.mode === \"dark\"\n ? {\n background: chatResponse?.codeBackground || \"#0f172a\",\n text: chatResponse?.codeText || \"#e2e8f0\",\n keyword: \"#c792ea\",\n string: \"#7fdbca\",\n number: \"#f78c6c\",\n comment: \"#64748b\",\n function: \"#82aaff\",\n variable: \"#f07178\",\n }\n : {\n background: chatResponse?.codeBackground || \"#f4f6ff\",\n text: chatResponse?.codeText || \"#1e293b\",\n keyword: \"#7c3aed\",\n string: \"#0f766e\",\n number: \"#b45309\",\n comment: \"#6b7280\",\n function: \"#2563eb\",\n variable: \"#d97706\",\n };\n\n if (!isProbablyBlock) {\n return (\n <code\n style={{\n borderRadius: \"4px\",\n fontSize: \"0.9em\",\n fontFamily:\n \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace\",\n }}\n {...props}\n >\n {children}\n </code>\n );\n }\n\n return (\n <Box\n sx={{\n borderRadius: \"4px\",\n overflow: \"auto\",\n my: \"0.5rem\",\n px: 0,\n py: 0,\n mt: 1,\n mb: 0.5,\n fontSize: \"0.9rem\",\n position: \"relative\",\n fontFamily:\n \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace\",\n width: \"100%\",\n maxWidth: \"100%\",\n }}\n >\n <Box\n sx={{\n px: 2,\n py: 1,\n bgcolor:\n chatResponse?.aiBackground ||\n (theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.white, 0.04)\n : alpha(theme.palette.text.primary, 0.04)),\n color: chatResponse?.aiText || theme.palette.text.secondary,\n fontSize: \"0.75rem\",\n borderBottom: `1px solid ${\n chatResponse?.aiBorder || alpha(theme.palette.text.primary, 0.1)\n }`,\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n fontFamily: \"inherit\",\n }}\n >\n <span>{languageLabel}</span>\n <Tooltip title={copied ? \"Copied!\" : \"Copy\"} arrow>\n <IconButton\n size=\"small\"\n onClick={handleCopy}\n sx={{\n color: copied\n ? theme.palette.success.main\n : theme.palette.text.secondary,\n \"&:hover\": { color: theme.palette.text.primary },\n padding: \"4px\",\n }}\n >\n {copied ? <CheckIcon fontSize=\"small\" /> : <ContentCopyIcon fontSize=\"small\" />}\n </IconButton>\n </Tooltip>\n </Box>\n <Box\n sx={{\n overflowX: \"auto\",\n maxWidth: \"100%\",\n \"& .hljs\": {\n display: \"block\",\n overflowX: \"auto\",\n padding: \"16px\",\n margin: 0,\n backgroundColor: highlightColors.background,\n color: highlightColors.text,\n fontSize: \"0.9rem\",\n },\n \"& .hljs-comment, & .hljs-quote\": {\n color: highlightColors.comment,\n fontStyle: \"italic\",\n },\n \"& .hljs-keyword, & .hljs-selector-tag, & .hljs-literal, & .hljs-built_in\": {\n color: highlightColors.keyword,\n },\n \"& .hljs-string, & .hljs-doctag, & .hljs-template-tag, & .hljs-attr\": {\n color: highlightColors.string,\n },\n \"& .hljs-number, & .hljs-symbol, & .hljs-bullet, & .hljs-meta\": {\n color: highlightColors.number,\n },\n \"& .hljs-title, & .hljs-section, & .hljs-selector-id, & .hljs-function\": {\n color: highlightColors.function,\n },\n \"& .hljs-variable, & .hljs-params, & .hljs-property\": {\n color: highlightColors.variable,\n },\n }}\n >\n <pre className={`hljs language-${languageClass}`} {...props}>\n <code className=\"hljs\">{highlightedNodes}</code>\n </pre>\n </Box>\n </Box>\n );\n};\n\nconst AIResponseTextField: React.FC<AIResponseTextFieldProps> = ({\n question,\n response,\n responseText,\n backgroundColor,\n images,\n memoryUpdated,\n sourceFiles,\n isMobile = false,\n cancelled = false,\n revealActionsOnHover = false,\n}) => {\n // Warn if response is not a string, to help debug [object Object] issues\n useEffect(() => {\n if (typeof response !== \"string\" && !React.isValidElement(response)) {\n debugLogger.warn(\"⚠️ AIResponseTextField received a non-string, non-ReactElement response:\", { response });\n }\n }, [response]);\n const [openImage, setOpenImage] = useState<string | null>(null);\n const [showMemoryUpdated, setShowMemoryUpdated] = useState(memoryUpdated ?? false);\n const [openDoc, setOpenDoc] = useState<KnowledgeDoc | null>(null);\n const { isVectorDocument } = useKnowledgeStore();\n\n // Convert API response format to KnowledgeDoc format (same as KnowledgeTab)\n const normalizeSourceFiles = useCallback((files: SourceFileInput[]): KnowledgeDoc[] => {\n return files\n .map((file) => {\n const vectorResult = file._vectorResult ?? undefined;\n const metadata = file.metadata ?? undefined;\n\n const candidateId =\n [\n file.id,\n file.fileId,\n file._id,\n vectorResult?.id,\n vectorResult?.fileId,\n vectorResult?._id,\n metadata?.id,\n metadata?.fileId,\n metadata?._id,\n ].find(isNonEmptyString) ?? null;\n\n if (!candidateId) {\n debugLogger.error(\"Missing document identifier in AI response file\", {\n file,\n availableProperties: Object.keys(file),\n vectorResultProperties: vectorResult ? Object.keys(vectorResult) : undefined,\n });\n return null;\n }\n\n const resolvedId = candidateId;\n const filename =\n (isNonEmptyString(file.name) && file.name) ||\n (isNonEmptyString(file.filename) && file.filename) ||\n \"Unknown Document\";\n const timestamp = file.uploadedAt ?? file.createdAt;\n const addedDate = toDateSafe(timestamp) ?? new Date();\n const mimeType =\n (isNonEmptyString(file.mimeType) && file.mimeType) ||\n (isNonEmptyString(file.type) && file.type) ||\n \"application/pdf\";\n const contentValue = typeof file.content === \"string\" ? file.content : \"\";\n const hasInlineContent = contentValue.trim().length > 0;\n const looksLikeMongoId = /^[0-9a-f]{24}$/i.test(resolvedId);\n const isFromVectorDB =\n Boolean(file._vectorResult) ||\n isNonEmptyString(file.s3Url) ||\n (looksLikeMongoId && !hasInlineContent);\n\n debugLogger.debug(\"Normalizing AI response source file\", {\n docId: resolvedId,\n filename,\n isFromVectorDB,\n hasContent: hasInlineContent,\n });\n\n const embedding = toNumberArray(file.embedding) ?? [];\n const rawData = typeof file.rawData === \"string\" ? file.rawData : undefined;\n const size = typeof file.size === \"number\" && Number.isFinite(file.size) ? file.size : 0;\n const uploadedBy =\n (isNonEmptyString(file.uploadedBy) && file.uploadedBy) ||\n (isNonEmptyString(file.userId) && file.userId) ||\n \"\";\n const userEmail = (isNonEmptyString(file.userEmail) && file.userEmail) || \"\";\n const bucket = (isNonEmptyString(file.bucket) && file.bucket) || \"\";\n const key = (isNonEmptyString(file.key) && file.key) || resolvedId;\n const teamSid = (isNonEmptyString(file.teamSid) && file.teamSid) || undefined;\n const explicitContentSource =\n file.contentSource === \"team\" || file.contentSource === \"user\" ? file.contentSource : undefined;\n const contentSource = explicitContentSource ?? (teamSid ? \"team\" : \"user\");\n const isTeamContent = file.isTeamContent ?? contentSource === \"team\";\n const isUserContent = file.isUserContent ?? contentSource === \"user\";\n const resolvedS3Url =\n (isNonEmptyString(file.s3Url) && file.s3Url) ||\n (isFromVectorDB ? resolvedId : undefined);\n\n const normalizedDoc: KnowledgeDoc = {\n id: resolvedId,\n name: filename,\n content: isFromVectorDB ? \"\" : contentValue,\n rawData,\n type: mimeType,\n addedDate,\n embedding,\n size,\n uploadedBy,\n userEmail,\n bucket,\n key,\n isUserContent,\n isTeamContent,\n contentSource,\n teamSid,\n mimeType,\n originalFileName: filename,\n s3Url: resolvedS3Url,\n };\n\n return normalizedDoc;\n })\n .filter((doc): doc is KnowledgeDoc => doc !== null);\n }, []);\n\n // Normalize the source files\n const normalizedSourceFiles = useMemo(\n () => (sourceFiles ? normalizeSourceFiles(sourceFiles) : []),\n [sourceFiles, normalizeSourceFiles]\n );\n\n const sourceCacheRef = useRef<KnowledgeDoc[]>([]);\n\n const displaySourceFiles = useMemo(() => {\n if (normalizedSourceFiles.length > 0) {\n sourceCacheRef.current = normalizedSourceFiles;\n return normalizedSourceFiles;\n }\n\n if (sourceFiles === undefined) {\n return sourceCacheRef.current;\n }\n\n sourceCacheRef.current = [];\n return [];\n }, [normalizedSourceFiles, sourceFiles]);\n\n const sourcesMarkdownList = displaySourceFiles.map((doc, index) => `- ${index + 1}. ${doc.name}`);\n\n // Debug logging\n useEffect(() => {\n if (sourceFiles && sourceFiles.length > 0) {\n debugLogger.debug(\"AI response source files normalization\", {\n sourceFileCount: sourceFiles.length,\n normalizedFileCount: normalizedSourceFiles.length,\n });\n }\n }, [sourceFiles, normalizedSourceFiles]);\n\n useEffect(() => {\n if (!memoryUpdated) return;\n setShowMemoryUpdated(true);\n const timeout = setTimeout(() => setShowMemoryUpdated(false), 3000);\n return () => clearTimeout(timeout);\n }, [memoryUpdated]);\n\n const theme = useTheme();\n const chatResponse = responseTokens(theme);\n \n // Choose syntax highlighting theme based on current theme mode\n\n const sanitizeMarkdown = (raw: string): string => {\n // Strip start/end of turn tags, including malformed or alternate versions\n let sanitized = raw.replace(/<[/]?start_of_turn>|<[/]?end[_]?of[_]?turn>/gi, \"\");\n\n // 1) Unwrap any stray <div class=\"MuiBox-root\"> wrappers\n sanitized = sanitized\n .replace(/<div class=\"MuiBox-root[^\"]*\"[^>]*>([\\s\\S]*?)<\\/div>/g, (_, inner) =>\n inner.trim()\n )\n .replace(/<div[^>]*>\\s*<\\/div>/g, \"\");\n\n // Collapse newline before colon or comma into inline punctuation\n sanitized = sanitized.replace(/\\r?\\n\\s*:\\s*/g, \": \");\n sanitized = sanitized.replace(/\\r?\\n\\s*,\\s*/g, \", \");\n\n // 2) Normalize all pipe‑tables in one go\n sanitized = normalizeTables(sanitized);\n\n return sanitized;\n };\n\n const enrichedMarkdown = useMemo(() => {\n if (typeof response !== \"string\") {\n return null;\n }\n\n const sanitized = sanitizeMarkdown(response);\n\n if (!sourcesMarkdownList.length) {\n return sanitized;\n }\n\n if (/\\*\\*Sources?\\*\\*/i.test(sanitized)) {\n return sanitized;\n }\n\n return `${sanitized}\\n\\n**Sources**\\n${sourcesMarkdownList.join(\"\\n\")}`;\n }, [response, sourcesMarkdownList]);\n\n const components: ReactMarkdownComponents = {\n img: MarkdownImage,\n mark({ children, node: _node, className, style, ...markProps }: MarkdownComponentProps<\"mark\">) {\n const contentText = React.Children.toArray(children)\n .map((child) => (typeof child === \"string\" ? child : \"\"))\n .join(\"\")\n .trim();\n\n return (\n <Box\n component=\"span\"\n className={className}\n style={style}\n {...markProps}\n sx={{\n display: \"inline-block\",\n backgroundColor: chatTokens(theme).surface.interactive,\n color: chatTokens(theme).conversation.assistant.foreground,\n px: 1,\n py: 0.25,\n borderRadius: \"4px\",\n fontWeight: 500,\n fontSize: \"0.95rem\",\n lineHeight: 1.4,\n whiteSpace: \"normal\",\n width: \"fit-content\",\n maxWidth: \"100%\",\n }}\n >\n {contentText}\n </Box>\n );\n },\n code({ inline, className, children, node: _node, ...codeProps }: MarkdownComponentProps<\"code\">) {\n return (\n <MarkdownCodeBlock\n inline={inline}\n className={className}\n {...codeProps}\n theme={theme}\n chatResponse={chatResponse}\n >\n {children}\n </MarkdownCodeBlock>\n );\n },\n a({ href, children, node: _node, style, ...anchorProps }: MarkdownComponentProps<\"a\">) {\n return (\n <a\n href={href}\n {...anchorProps}\n style={{\n color: theme.palette.primary.main,\n textDecoration: \"underline\",\n ...(style ?? {}),\n }}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => maybeHandleFileLinkClick(e, href)}\n >\n {children}\n </a>\n );\n },\n em({ children, node: _node, className, style, ...emProps }: MarkdownComponentProps<\"em\">) {\n // Check for Bandit's weird <em><div class=\"MuiBox-root\">CODE</div></em>\n const onlyChild =\n Array.isArray(children) && children.length === 1 ? children[0] : null;\n\n if (\n onlyChild &&\n typeof onlyChild === \"object\" &&\n onlyChild.type === \"div\" &&\n onlyChild.props?.className?.includes(\"MuiBox-root\")\n ) {\n const inner = onlyChild.props.children;\n\n // Optional: skip rendering if it's literally the word \"CODE\"\n if (typeof inner === \"string\" && inner.trim().toUpperCase() === \"CODE\") {\n return null;\n }\n\n // Otherwise render nicely\n return (\n <Box\n sx={{\n fontFamily: \"monospace\",\n fontSize: \"0.9rem\",\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n padding: \"12px 16px\",\n borderRadius: \"4px\",\n border: `1px solid ${theme.palette.divider}`,\n my: 1,\n display: \"inline-block\",\n }}\n >\n {inner}\n </Box>\n );\n }\n\n return (\n <em className={className} style={style} {...emProps}>\n {children}\n </em>\n );\n },\n ol({ children, node: _node, style, ...orderedListProps }: MarkdownComponentProps<\"ol\">) {\n const childArray = React.Children.toArray(children);\n const cleanedChildren: React.ReactNode[] = [];\n\n for (let i = 0; i < childArray.length; i++) {\n const item = childArray[i];\n\n // Remove raw colon-only text lines\n if (typeof item === \"string\" && item.trim() === \":\") {\n continue;\n }\n\n // If colon-prefixed string explanation\n if (typeof item === \"string\" && item.trim().startsWith(\":\")) {\n cleanedChildren.push(\n <Typography\n key={`ol-expl-${i}`}\n sx={{\n fontSize: \"0.875rem\",\n color: chatTokens(theme).conversation.meta,\n fontStyle: \"italic\",\n mt: 0.5,\n ml: 2,\n }}\n >\n {item.replace(/^:\\s*/, \"\")}\n </Typography>\n );\n } else {\n cleanedChildren.push(item);\n }\n }\n\n return (\n <ol\n {...orderedListProps}\n style={{\n paddingLeft: 24,\n marginLeft: 16,\n listStyleType: \"decimal\",\n ...(style ?? {}),\n }}\n >\n {cleanedChildren}\n </ol>\n );\n },\n\n ul({ children, node: _node, style, ...unorderedListProps }: MarkdownComponentProps<\"ul\">) {\n return (\n <ul\n {...unorderedListProps}\n style={{\n paddingLeft: \"1.5rem\",\n marginTop: \"0.5rem\",\n marginBottom: \"0.25rem\",\n listStyle: \"disc\",\n ...(style ?? {}),\n }}\n >\n {React.Children.toArray(children).filter((child) => {\n if (typeof child === \"string\" && child.trim() === \":\") return false;\n return true;\n })}\n </ul>\n );\n },\n li({ children, node: _node, style, ...listItemProps }: MarkdownComponentProps<\"li\">) {\n const childArray = React.Children.toArray(children);\n // New logic: If first child is <strong> whose text ends with a colon, and rest is inline/plain\n if (\n childArray.length >= 2 &&\n React.isValidElement(childArray[0]) &&\n childArray[0].type === \"strong\"\n ) {\n // Extract label text from <strong>\n let labelText = \"\";\n const strongChild = childArray[0];\n if (typeof strongChild.props.children === \"string\") {\n labelText = strongChild.props.children;\n } else if (Array.isArray(strongChild.props.children)) {\n labelText = strongChild.props.children.join(\"\");\n }\n // Replace [object Object] with \"Item\"\n if (labelText?.includes(\"[object Object]\")) {\n labelText = \"Item\";\n }\n if (typeof labelText === \"string\" && labelText.trim().endsWith(\":\")) {\n // Check if all rest are inline/plain (no Box)\n const rest = childArray.slice(1);\n const isAllInline = rest.every(\n (el) =>\n typeof el === \"string\" ||\n (React.isValidElement(el) &&\n // allow inline tags, but not <Box>\n el.type !== Box)\n );\n if (isAllInline) {\n // Remove trailing colon from label for rendering\n const displayLabel = labelText.replace(/:\\s*$/, \"\");\n return (\n <li\n style={{\n marginBottom: \"0.5rem\",\n lineHeight: 1.4,\n whiteSpace: \"pre-wrap\",\n ...(style ?? {}),\n }}\n {...listItemProps}\n >\n <strong>{displayLabel}:</strong>\n {rest.length > 0 && <> {rest}</>}\n </li>\n );\n }\n }\n }\n // Special-case: <strong>Label:</strong> followed by a Box description\n if (\n childArray.length === 2 &&\n React.isValidElement(childArray[0]) &&\n childArray[0].type === \"strong\" &&\n React.isValidElement(childArray[1]) &&\n childArray[1].type === Box\n ) {\n const label = childArray[0].props.children;\n const desc = childArray[1].props.children;\n return (\n <li\n style={{ marginBottom: \"0.5rem\", lineHeight: 1.4, whiteSpace: \"pre-wrap\" }}\n {...listItemProps}\n >\n <span>\n <strong>{label}</strong> {desc}\n </span>\n </li>\n );\n }\n const contentArray = childArray;\n const filtered: React.ReactNode[] = [];\n\n for (let i = 0; i < contentArray.length; i++) {\n const item = contentArray[i];\n\n if (typeof item === \"string\" && item.trim() === \":\") continue;\n\n // Safer merge: use prev variable and check before merge\n if (i > 0 && typeof item === \"string\" && item.trim().startsWith(\":\")) {\n const prev = contentArray[i - 1];\n if (React.isValidElement(prev) && prev.type === \"strong\") {\n const desc = item.replace(/^:\\s*/, \"\");\n const prevKey = React.isValidElement(prev) && prev.key != null ? prev.key : `li-strong-${i}`;\n filtered.pop();\n filtered.push(\n <span key={`li-merge-${prevKey}`}>\n {prev}\n {\": \"}\n {desc}\n </span>\n );\n continue;\n }\n }\n filtered.push(item);\n }\n\n return (\n <li\n {...listItemProps}\n style={{\n marginBottom: \"0.5rem\",\n lineHeight: 1.4,\n whiteSpace: \"pre-wrap\",\n ...(style ?? {}),\n }}\n >\n {filtered}\n </li>\n );\n },\n table({ children, node: _node, className, style, ...tableProps }: MarkdownComponentProps<\"table\">) {\n return (\n <TableContainer\n component={Paper}\n className={className}\n style={style}\n sx={{ my: 2, bgcolor: theme.palette.background.paper }}\n >\n <Table size=\"small\" {...tableProps}>\n {children}\n </Table>\n </TableContainer>\n );\n },\n thead({ children, node: _node, ...tableHeadProps }: MarkdownComponentProps<\"thead\">) {\n return <TableHead {...tableHeadProps}>{children}</TableHead>;\n },\n tbody({ children, node: _node, ...tableBodyProps }: MarkdownComponentProps<\"tbody\">) {\n const rows = React.Children.toArray(children).filter((row: React.ReactNode) => {\n // Keep non-React elements\n if (!React.isValidElement(row)) return true;\n // Extract cell elements for this row\n const cells = React.Children.toArray(row.props.children);\n // Filter out rows where every cell is a string of hyphens\n return !cells.every(\n (cell) =>\n React.isValidElement(cell) &&\n typeof cell.props.children === \"string\" &&\n /^-+$/.test(cell.props.children.trim())\n );\n });\n return <TableBody {...tableBodyProps}>{rows}</TableBody>;\n },\n tr({ children, node: _node, ...tableRowProps }: MarkdownComponentProps<\"tr\">) {\n return <TableRow {...tableRowProps}>{children}</TableRow>;\n },\n th({ children, node: _node, align, ...tableCellProps }: MarkdownComponentProps<\"th\">) {\n return (\n <TableCell\n {...tableCellProps}\n align={align === \"char\" ? undefined : align}\n sx={{\n fontWeight: \"bold\",\n color: theme.palette.text.primary,\n bgcolor: theme.palette.action.hover,\n textAlign: \"left\",\n padding: \"8px 12px\",\n whiteSpace: \"nowrap\",\n }}\n >\n {children}\n </TableCell>\n );\n },\n td({ children, node: _node, align, ...tableCellProps }: MarkdownComponentProps<\"td\">) {\n return (\n <TableCell\n {...tableCellProps}\n align={align === \"char\" ? undefined : align}\n sx={{\n color: theme.palette.text.primary,\n fontSize: \"0.875rem\",\n padding: \"8px 12px\",\n verticalAlign: \"top\",\n }}\n >\n {children}\n </TableCell>\n );\n },\n p({ children, node: _node, className, style, ...paragraphProps }: MarkdownComponentProps<\"p\">) {\n // Flatten children and detect block-level elements\n const flattened = React.Children.toArray(children).flat();\n const hasBlock = flattened.some(\n (child) =>\n typeof child === \"object\" &&\n child !== null &&\n \"type\" in child &&\n typeof child.type === \"string\" &&\n [\"div\", \"Box\", \"section\", \"ul\", \"ol\", \"table\"].includes(child.type)\n );\n // If a block element is present, render without wrapping\n if (hasBlock) {\n return <>{flattened}</>;\n }\n // Otherwise wrap inline text in a div\n return (\n <Box component=\"div\" sx={{ margin: \"0.25rem 0\" }}>\n <Typography\n component=\"div\"\n variant=\"body2\"\n className={className}\n style={style}\n sx={{ color: theme.palette.text.primary, lineHeight: 1.6, display: \"inline\" }}\n {...paragraphProps}\n >\n {flattened}\n </Typography>\n </Box>\n );\n },\n };\n\n return (\n <>\n <Box\n sx={{\n width: '100%',\n maxWidth: '100%',\n flexGrow: 1,\n alignSelf: 'stretch',\n display: 'flex',\n flexDirection: 'column',\n color: chatResponse.aiText || theme.palette.text.primary,\n px: isMobile ? 0.5 : 2,\n py: 1,\n userSelect: \"text\",\n \"&:hover .ai-response-actions\": { opacity: 1 },\n }}\n >\n {/* User message — compact bubble, right-aligned (Claude-style) */}\n <Box sx={{ display: \"flex\", justifyContent: \"flex-end\", mb: 2.5 }}>\n <Box sx={{ maxWidth: { xs: \"100%\", sm: \"85%\" }, minWidth: 0 }}>\n <Box\n sx={{\n bgcolor: chatResponse.userBubble || alpha(theme.palette.common.white, 0.07),\n borderRadius: \"18px\",\n px: 2,\n py: 1.25,\n wordBreak: \"break-word\",\n whiteSpace: \"pre-wrap\",\n overflowWrap: \"break-word\",\n }}\n >\n <Typography\n sx={{\n color: theme.palette.text.primary,\n lineHeight: 1.5,\n wordBreak: \"break-word\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {question}\n </Typography>\n </Box>\n {/* Images, if any */}\n {images && images.length > 0 && (\n <Box sx={{ display: \"flex\", gap: 1, mt: 1, flexWrap: \"wrap\", justifyContent: \"flex-end\" }}>\n {images.map((img, i) => (\n <Avatar\n key={i}\n src={img}\n variant=\"rounded\"\n onClick={() => setOpenImage(img)}\n sx={{\n width: 96,\n height: 96,\n borderRadius: 2,\n border: `1px solid ${alpha(theme.palette.text.primary, 0.25)}`,\n cursor: \"pointer\",\n \"&:hover\": { boxShadow: `0 0 0 2px ${theme.palette.primary.main}` },\n }}\n />\n ))}\n </Box>\n )}\n </Box>\n </Box>\n\n {/* AI response — raw text on the chat background (Claude-style: no avatar, label, or bubble) */}\n <Box sx={{ position: \"relative\", width: \"100%\", maxWidth: { xs: \"100%\", sm: \"768px\" } }}>\n {cancelled && (\n <Box\n sx={{\n position: \"absolute\",\n top: -22,\n left: 0,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n zIndex: 1,\n }}\n >\n <Typography variant=\"caption\" sx={{ fontStyle: \"italic\", opacity: 0.85 }}>\n Cancelled by you\n </Typography>\n </Box>\n )}\n {showMemoryUpdated && (\n <Box\n sx={{\n position: \"absolute\",\n top: -22,\n right: 0,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n animation: \"fadeOut 0.3s ease-in 2.7s forwards\",\n zIndex: 1,\n }}\n >\n <img src={brainIcon} alt=\"Memory\" style={{ width: 16, height: 16 }} />\n <Typography\n variant=\"caption\"\n sx={{ color: chatResponse.memoryText, fontStyle: \"italic\" }}\n >\n Bandit added to memory\n </Typography>\n </Box>\n )}\n <Box sx={{ width: '100%', maxWidth: '100%' }}>\n {typeof response === \"string\" ? (\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw, [rehypeSanitize, markdownSanitizeSchema]]}\n components={components}\n >\n {enrichedMarkdown ?? sanitizeMarkdown(response)}\n </ReactMarkdown>\n ) : React.isValidElement(response) ? (\n response\n ) : (\n <Typography color=\"error\">⚠️ Invalid AI response</Typography>\n )}\n </Box>\n </Box>\n {/* Actions bar at the bottom. Only the latest response keeps it\n always visible — older ones reveal it on hover (desktop) so the\n transcript stays clean, ChatGPT-style. */}\n {!!(responseText || (typeof response === \"string\" && response)) && (\n <Box\n className=\"ai-response-actions\"\n sx={\n revealActionsOnHover\n ? {\n opacity: 0,\n transition: \"opacity 0.15s ease\",\n \"&:focus-within\": { opacity: 1 },\n }\n : undefined\n }\n >\n <AiResponseActionsBar text={(responseText || (response as string)) as string} />\n </Box>\n )}\n {displaySourceFiles && displaySourceFiles.length > 0 && (\n <Box sx={{ mt: 1.5, display: \"flex\", gap: 2, flexWrap: \"wrap\", justifyContent: \"flex-start\" }}>\n {displaySourceFiles.map((doc, idx) => {\n debugLogger.debug(\"Rendering DocumentCard in AI response\", {\n index: idx,\n id: doc.id,\n name: doc.name,\n });\n return (\n <DocumentCard \n key={idx} \n doc={doc} \n onView={() => setOpenDoc(doc)}\n variant=\"mini\"\n isHistoricalReference={true}\n allowErrorStates={true}\n />\n );\n })}\n </Box>\n )}\n </Box>\n\n {/* Fullscreen image preview modal */}\n <Modal open={!!openImage} onClose={() => setOpenImage(null)}>\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"100vh\",\n bgcolor: \"rgba(0, 0, 0, 0.9)\",\n p: 2,\n position: \"relative\",\n }}\n >\n <IconButton\n onClick={() => setOpenImage(null)}\n sx={{\n position: \"absolute\",\n top: 16,\n right: 16,\n color: \"#fff\",\n bgcolor: \"rgba(0,0,0,0.6)\",\n \"&:hover\": {\n bgcolor: \"rgba(255,255,255,0.2)\",\n },\n }}\n >\n <CloseIcon />\n </IconButton>\n <Box\n component=\"img\"\n src={openImage || \"\"}\n alt=\"Full-size\"\n sx={{\n maxHeight: \"90vh\",\n maxWidth: \"90vw\",\n borderRadius: 2,\n boxShadow: 24,\n cursor: \"zoom-out\",\n }}\n onClick={() => setOpenImage(null)}\n />\n </Box>\n </Modal>\n <KnowledgeFileModal \n open={!!openDoc} \n onClose={() => setOpenDoc(null)} \n doc={openDoc} \n isVectorDocument={openDoc ? (() => {\n const isVector = isVectorDocument(openDoc);\n debugLogger.debug(\"Knowledge file modal open request\", {\n documentId: openDoc.id,\n name: openDoc.name,\n isVector,\n });\n return isVector;\n })() : false}\n />\n </>\n );\n};\n\nexport default AIResponseTextField;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState, useEffect } from \"react\";\nimport {\n Box,\n Typography,\n Tooltip,\n Card,\n CardContent,\n Checkbox,\n IconButton,\n} from \"@mui/material\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { KnowledgeDoc } from \"../store/knowledgeStore\";\nimport { useKnowledgeStore } from \"../chat/hooks/useKnowledgeStore\";\nimport { useVectorStore } from \"../hooks/useVectorStore\";\nimport { alpha, useTheme } from \"@mui/material/styles\";\nimport {\n ArticleIcon,\n CloudOffIcon,\n CodeIcon,\n DataObjectIcon,\n DeleteIcon,\n DescriptionIcon,\n DownloadIcon,\n ErrorOutlineIcon,\n InfoIcon,\n PictureAsPdfIcon,\n SearchIcon,\n} from \"../icons\";\n\ninterface DocumentCardProps {\n doc: KnowledgeDoc;\n onView: () => void;\n onDelete?: (id: string) => void;\n onSelect?: (id: string) => void;\n isSelected?: boolean;\n isDeleting?: boolean; // For deletion animation\n variant?: 'mini' | 'full'; // Mini for chat responses, full for knowledge tab\n showSelection?: boolean;\n showDelete?: boolean;\n showPreview?: boolean;\n // New props for handling error states\n isHistoricalReference?: boolean; // True when this card is from a past conversation\n allowErrorStates?: boolean; // Whether to show error states instead of hiding the card\n}\n\ntype FileTypeInfo = {\n icon: React.ElementType;\n category: string;\n language?: string;\n};\n\n// File type detection: icon + category + language label. The icon is drawn\n// in a neutral tone; the type is spelled out in the metadata line instead.\nconst getFileTypeInfo = (filename: string): FileTypeInfo => {\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n\n const languageMap: Record<string, FileTypeInfo> = {\n // Documents\n 'pdf': { icon: PictureAsPdfIcon, category: 'Document', language: 'PDF' },\n 'doc': { icon: ArticleIcon, category: 'Document', language: 'Word' },\n 'docx': { icon: ArticleIcon, category: 'Document', language: 'Word' },\n 'odt': { icon: ArticleIcon, category: 'Document' },\n 'rtf': { icon: ArticleIcon, category: 'Document' },\n\n // Text files\n 'txt': { icon: DescriptionIcon, category: 'Text' },\n 'md': { icon: DescriptionIcon, category: 'Text', language: 'Markdown' },\n 'markdown': { icon: DescriptionIcon, category: 'Text', language: 'Markdown' },\n\n // Programming languages\n 'js': { icon: CodeIcon, category: 'Code', language: 'JavaScript' },\n 'jsx': { icon: CodeIcon, category: 'Code', language: 'React' },\n 'ts': { icon: CodeIcon, category: 'Code', language: 'TypeScript' },\n 'tsx': { icon: CodeIcon, category: 'Code', language: 'React TS' },\n 'py': { icon: CodeIcon, category: 'Code', language: 'Python' },\n 'java': { icon: CodeIcon, category: 'Code', language: 'Java' },\n 'c': { icon: CodeIcon, category: 'Code', language: 'C' },\n 'cpp': { icon: CodeIcon, category: 'Code', language: 'C++' },\n 'cs': { icon: CodeIcon, category: 'Code', language: 'C#' },\n 'go': { icon: CodeIcon, category: 'Code', language: 'Go' },\n 'rs': { icon: CodeIcon, category: 'Code', language: 'Rust' },\n 'php': { icon: CodeIcon, category: 'Code', language: 'PHP' },\n 'rb': { icon: CodeIcon, category: 'Code', language: 'Ruby' },\n 'kt': { icon: CodeIcon, category: 'Code', language: 'Kotlin' },\n 'swift': { icon: CodeIcon, category: 'Code', language: 'Swift' },\n\n // Data files\n 'json': { icon: DataObjectIcon, category: 'Data', language: 'JSON' },\n 'xml': { icon: DataObjectIcon, category: 'Data', language: 'XML' },\n 'yaml': { icon: DataObjectIcon, category: 'Data', language: 'YAML' },\n 'yml': { icon: DataObjectIcon, category: 'Data', language: 'YAML' },\n 'csv': { icon: DataObjectIcon, category: 'Data', language: 'CSV' },\n };\n\n return languageMap[ext] || { icon: DescriptionIcon, category: 'File' };\n};\n\n// Where the document lives: local browser storage or the vector store.\nconst getSourceLabel = (doc: KnowledgeDoc, shouldUseVector: boolean): string => {\n if (shouldUseVector && doc.s3Url) {\n return doc.isTeamContent ? 'Team cloud' : 'Cloud';\n }\n return 'Local';\n};\n\n// Format file size utility\nconst formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];\n};\n\nconst DocumentCard: React.FC<DocumentCardProps> = ({\n doc,\n onView,\n onDelete,\n onSelect,\n isSelected = false,\n isDeleting = false,\n variant = 'mini',\n showSelection = false,\n showDelete = false,\n showPreview = true,\n isHistoricalReference = false,\n allowErrorStates = true,\n}) => {\n const theme = useTheme();\n const { isVectorDocument } = useKnowledgeStore();\n const { downloadVectorFile, isVectorEnabled } = useVectorStore();\n const [documentState, setDocumentState] = useState<'available' | 'unavailable' | 'access-changed' | 'checking'>('checking');\n const [errorMessage, setErrorMessage] = useState<string>('');\n\n // Check document availability and access status\n useEffect(() => {\n const checkDocumentStatus = async () => {\n try {\n const isVector = isVectorDocument(doc);\n \n // Case 1: Vector document but vector access is now disabled\n if (isVector && !isVectorEnabled) {\n setDocumentState('access-changed');\n setErrorMessage('Vector database access disabled. Document not accessible.');\n return;\n }\n \n // Case 2: Vector document - try to verify it exists\n if (isVector) {\n try {\n // Attempt to get file blob to verify existence\n const fileId = doc.s3Url || doc.id;\n // Note: We don't actually fetch here to avoid performance issues,\n // but this is where we could add a lightweight existence check\n setDocumentState('available');\n } catch (error) {\n setDocumentState('unavailable');\n setErrorMessage('Document no longer exists in cloud storage.');\n }\n }\n // Case 3: Local document - check if it has content or rawData\n else {\n if (!doc.content && !doc.rawData) {\n setDocumentState('unavailable');\n setErrorMessage('Document content not available.');\n } else {\n setDocumentState('available');\n }\n }\n } catch (error) {\n setDocumentState('unavailable');\n setErrorMessage('Unable to verify document status.');\n }\n };\n\n if (isHistoricalReference) {\n checkDocumentStatus();\n } else {\n setDocumentState('available');\n }\n }, [doc, isHistoricalReference, isVectorEnabled, isVectorDocument]);\n \n const fileInfo = getFileTypeInfo(doc.name);\n const IconComponent = fileInfo.icon;\n const shouldUseVector = isVectorEnabled;\n const sourceLabel = getSourceLabel(doc, shouldUseVector);\n const isAvailable = documentState === 'available';\n const metaLine = [\n sourceLabel,\n fileInfo.language ?? fileInfo.category,\n // Real file size when the listing reports one; otherwise estimate from the text content.\n formatFileSize(typeof doc.size === 'number' && doc.size > 0 ? doc.size : (doc.content?.length || 0) * 2),\n ].join(' · ');\n\n // Don't render if document is unavailable and error states are not allowed\n if (documentState === 'unavailable' && !allowErrorStates) {\n return null;\n }\n\n const handleDownload = async (e: React.MouseEvent) => {\n e.stopPropagation();\n \n // Prevent download if document is not available\n if (documentState !== 'available') {\n debugLogger.warn('Cannot download document - not available', { documentState, documentId: doc.id });\n return;\n }\n \n try {\n const isVector = isVectorDocument(doc);\n debugLogger.debug('Document download initiated', { name: doc.name, isVector });\n \n if (isVector) {\n const fileId = doc.s3Url || doc.id;\n debugLogger.debug('Downloading vector document', { fileId, name: doc.name });\n await downloadVectorFile(fileId, doc.name);\n } else {\n if (doc.rawData) {\n debugLogger.debug('Downloading local document from raw data', { name: doc.name });\n const binaryString = atob(doc.rawData);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const mimeType = doc.type || doc.mimeType || 'application/octet-stream';\n const blob = new Blob([bytes], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = doc.name;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n } else {\n debugLogger.debug('Downloading local document from content fallback', { name: doc.name });\n const content = doc.content || '';\n const mimeType = doc.type || doc.mimeType || 'text/plain';\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = doc.name;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n }\n } catch (error) {\n debugLogger.error('DocumentCard download failed', { error, documentId: doc.id, name: doc.name });\n }\n };\n\n const handleCardClick = (e: React.MouseEvent) => {\n // Prevent interaction if document is not available\n if (documentState !== 'available') {\n e.stopPropagation();\n return;\n }\n \n if (e.ctrlKey || e.metaKey) {\n onSelect?.(doc.id);\n } else {\n onView();\n }\n };\n\n // Dim the card while its status is unknown or it can't be opened.\n const getErrorStateStyles = () => {\n if (isAvailable) return {};\n return {\n opacity: 0.6,\n pointerEvents: documentState === 'checking' ? 'none' : 'auto',\n } as const;\n };\n\n // Small status icon in the corner when the document can't be opened.\n const renderErrorOverlay = () => {\n if (isAvailable || documentState === 'checking') return null;\n\n const ErrorIcon = documentState === 'access-changed' ? CloudOffIcon : ErrorOutlineIcon;\n\n return (\n <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 2 }}>\n <Tooltip title={errorMessage} arrow>\n <ErrorIcon sx={{ fontSize: variant === 'mini' ? 16 : 20, color: 'error.main' }} />\n </Tooltip>\n </Box>\n );\n };\n\n const selectedSurface = alpha(theme.palette.primary.main, 0.06);\n const previewSurface = theme.palette.bandit?.surface.subtle ?? theme.palette.action.hover;\n // 44px touch targets on phones, compact on larger screens.\n const iconButtonSx = { width: { xs: 44, sm: 32 }, height: { xs: 44, sm: 32 } };\n\n if (variant === 'mini') {\n return (\n <Card\n variant=\"outlined\"\n sx={{\n position: \"relative\",\n p: 1.5,\n borderColor: isSelected ? \"primary.main\" : \"divider\",\n bgcolor: isSelected ? selectedSurface : \"background.paper\",\n width: 180,\n maxWidth: \"100%\",\n textAlign: \"center\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n minHeight: 150,\n cursor: isAvailable ? \"pointer\" : \"not-allowed\",\n transition: theme.transitions.create([\"border-color\", \"background-color\"]),\n '&:hover': isAvailable ? {\n borderColor: \"text.secondary\",\n } : {},\n ...getErrorStateStyles(),\n }}\n onClick={handleCardClick}\n >\n {renderErrorOverlay()}\n\n <Box sx={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\", mb: 1 }}>\n <IconComponent sx={{ fontSize: 28, color: \"text.secondary\" }} />\n </Box>\n\n <Tooltip title={doc.name} arrow>\n <Typography\n variant=\"body2\"\n sx={{\n display: \"block\",\n color: \"text.primary\",\n fontWeight: 500,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n width: \"100%\",\n }}\n >\n {doc.name}\n </Typography>\n </Tooltip>\n\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: \"block\", width: \"100%\", mb: 1, whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" }}\n >\n {sourceLabel} · {fileInfo.category}\n </Typography>\n\n <Box sx={{ display: \"flex\", gap: 0.5 }}>\n <Tooltip title={isAvailable ? \"View\" : \"Document not available\"}>\n <span>\n <IconButton\n size=\"small\"\n aria-label={`View ${doc.name}`}\n disabled={!isAvailable}\n sx={iconButtonSx}\n onClick={(e) => {\n e.stopPropagation();\n if (isAvailable) onView();\n }}\n >\n <SearchIcon fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip title={isAvailable ? \"Download\" : errorMessage}>\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Download ${doc.name}`}\n disabled={!isAvailable}\n sx={iconButtonSx}\n onClick={handleDownload}\n >\n <DownloadIcon fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n </Card>\n );\n }\n\n // Full variant for Knowledge Tab\n return (\n <Card\n variant=\"outlined\"\n sx={{\n position: \"relative\",\n minWidth: 0,\n height: \"100%\",\n cursor: isAvailable ? \"pointer\" : \"not-allowed\",\n transition: theme.transitions.create([\"border-color\", \"background-color\", \"opacity\", \"transform\"]),\n borderColor: isSelected ? \"primary.main\" : \"divider\",\n bgcolor: isSelected ? selectedSurface : \"background.paper\",\n \"&:hover\": isAvailable ? { borderColor: isSelected ? \"primary.main\" : \"text.secondary\" } : {},\n display: \"flex\",\n flexDirection: \"column\",\n opacity: isDeleting ? 0.4 : 1,\n transform: isDeleting ? \"scale(0.95)\" : \"none\",\n ...getErrorStateStyles(),\n }}\n onClick={handleCardClick}\n >\n {renderErrorOverlay()}\n\n <CardContent\n sx={{\n p: 1.5,\n \"&:last-child\": { pb: 1 },\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n }}\n >\n {/* File type icon and selection */}\n <Box sx={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", mb: 1, minHeight: 32 }}>\n <IconComponent sx={{ fontSize: 20, color: \"text.secondary\", flexShrink: 0 }} />\n {showSelection && (\n <Checkbox\n size=\"small\"\n checked={isSelected}\n slotProps={{ input: { \"aria-label\": `Select ${doc.name}` } }}\n onClick={(e) => e.stopPropagation()}\n onChange={() => onSelect?.(doc.id)}\n sx={{ ...iconButtonSx, mr: -0.75 }}\n />\n )}\n </Box>\n\n {/* Document preview */}\n {showPreview && (\n <Box\n sx={{\n mb: 1.5,\n px: 1,\n py: 0.75,\n bgcolor: previewSurface,\n overflow: \"hidden\",\n height: 64,\n }}\n >\n {doc.content && doc.content.length > 0 ? (\n <Typography\n variant=\"caption\"\n sx={{\n display: \"-webkit-box\",\n WebkitLineClamp: 3,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n color: \"text.secondary\",\n lineHeight: 1.4,\n wordBreak: \"break-word\",\n }}\n >\n {doc.content.substring(0, 100)}...\n </Typography>\n ) : (\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.75, height: \"100%\", color: \"text.disabled\" }}>\n <InfoIcon sx={{ fontSize: 14 }} />\n <Typography variant=\"caption\" color=\"text.disabled\">\n No preview available\n </Typography>\n </Box>\n )}\n </Box>\n )}\n\n {/* Document name and metadata */}\n <Tooltip title={doc.name} arrow>\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: 600,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n color: \"text.primary\",\n }}\n >\n {doc.name}\n </Typography>\n </Tooltip>\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: \"block\", whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" }}\n >\n {metaLine}\n </Typography>\n\n {/* Error message for full variant */}\n {!isAvailable && documentState !== \"checking\" && (\n <Typography variant=\"caption\" color=\"warning.main\" sx={{ display: \"block\", mt: 0.5 }}>\n {errorMessage}\n </Typography>\n )}\n\n {/* Actions */}\n <Box sx={{ mt: \"auto\", pt: 1, display: \"flex\", justifyContent: \"flex-end\", alignItems: \"center\", gap: 0.25, mr: -0.75 }}>\n <Tooltip title={isAvailable ? \"Download\" : \"Unavailable\"}>\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Download ${doc.name}`}\n disabled={!isAvailable}\n onClick={handleDownload}\n sx={{ ...iconButtonSx, color: \"text.secondary\" }}\n >\n <DownloadIcon fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n {showDelete && (\n <Tooltip title=\"Delete\">\n <IconButton\n size=\"small\"\n color=\"error\"\n aria-label={`Delete ${doc.name}`}\n onClick={(e) => {\n e.stopPropagation();\n onDelete?.(doc.id);\n }}\n sx={iconButtonSx}\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default DocumentCard;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useState, useCallback, useMemo } from \"react\";\nimport { useKnowledgeStore as useZustandKnowledgeStore, KnowledgeDoc } from \"../../store/knowledgeStore\";\nimport indexedDBService from \"../../services/indexedDB/indexedDBService\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport mammoth from \"mammoth\";\nimport * as pdfjsLib from \"pdfjs-dist/legacy/build/pdf.mjs\";\nimport type { TextItem, TextMarkedContent } from \"pdfjs-dist/types/src/display/api\";\nimport { embeddingService } from \"../../services/embedding/embeddingService\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { vectorDatabaseService } from \"../../services/vectorDatabase/vectorDatabaseService\";\nimport { useVectorStore } from \"../../hooks/useVectorStore\";\n\n// Re-export for backward compatibility\nexport type { KnowledgeDoc };\n\n/**\n * Knowledge Store Hook - Dual Storage Pattern\n * \n * This hook supports two different storage patterns based on user subscription and preferences:\n * \n * 1. **Local Storage (Basic Users)**:\n * - Users without vector DB access (lower tier subscriptions)\n * - Files are parsed locally and content + embeddings stored in IndexedDB\n * - Uses fake embedding service for similarity search\n * - Supports text files, DOCX, and limited PDF text extraction\n * \n * 2. **Vector Database + S3 (Advanced Users)**:\n * - Users with enhanced search features enabled\n * - Files uploaded to S3, embeddings generated server-side\n * - Only metadata stored in IndexedDB (lightweight references)\n * - Full PDF preview and advanced semantic search capabilities\n * \n * The storage method is automatically determined by `isVectorEnabled` from useVectorStore.\n */\n\n// PDF worker will be configured when package settings are available\n// pdfjsLib.GlobalWorkerOptions.workerSrc = \"/pdf.worker.js\";\n\nconst DB_NAME = \"banditKnowledge\";\nconst STORE_NAME = \"documents\";\nconst MAX_FILES = 20;\n\ntype KnowledgeDocWithVectorMetadata = KnowledgeDoc & { _vectorResult?: unknown };\n\nconst hasVectorMetadata = (doc: KnowledgeDoc): doc is KnowledgeDocWithVectorMetadata =>\n typeof doc === \"object\" && doc !== null && \"_vectorResult\" in doc;\n\nconst isTextItem = (item: TextItem | TextMarkedContent): item is TextItem =>\n typeof item === \"object\" && item !== null && \"str\" in item;\n\nexport const useKnowledgeStore = () => {\n const [documents, setDocuments] = useState<KnowledgeDoc[]>([]);\n\n const vectorStore = useVectorStore();\n const { isVectorEnabled, uploadDocument } = vectorStore;\n\n const storeConfigs = useMemo(() => [{ name: STORE_NAME, keyPath: \"id\" }], []);\n\n const loadDocuments = useCallback(async () => {\n const docs = await indexedDBService.getAll<KnowledgeDoc>(DB_NAME, 1, STORE_NAME, storeConfigs);\n setDocuments(docs);\n \n // Sync with zustand store - set the docs directly\n useZustandKnowledgeStore.setState({ \n docs: docs || [], \n isLoaded: true \n });\n debugLogger.debug(\"Synced knowledge docs with store\", { count: docs?.length || 0 });\n }, [storeConfigs]);\n\n const removeDocument = async (id: string) => {\n try {\n // First, try to delete from Gateway API (vector database, S3, and MongoDB)\n // This handles vector documents stored in the cloud\n const gatewayDeleteSuccess = await vectorDatabaseService.deleteDocument(id);\n if (gatewayDeleteSuccess) {\n debugLogger.info(\"Document deleted from Gateway API\", { id });\n } else {\n debugLogger.warn(\"Failed to delete from Gateway API or document not found\", { id });\n }\n } catch (error) {\n debugLogger.error(\"Error deleting from Gateway API\", { id, error });\n }\n\n try {\n // Always remove from local IndexedDB storage\n await indexedDBService.delete(DB_NAME, 1, STORE_NAME, id, storeConfigs);\n debugLogger.debug(\"Document removed from IndexedDB\", { id });\n } catch (error) {\n debugLogger.error(\"Failed to remove from IndexedDB\", { id, error });\n }\n\n // Reload documents to refresh the UI\n await loadDocuments();\n };\n\n const clearAllDocuments = async () => {\n await indexedDBService.clear(DB_NAME, 1, STORE_NAME, storeConfigs);\n await loadDocuments();\n };\n\n const addDocuments = async (files: File[]) => {\n const allKeys = await indexedDBService.getAllKeys(DB_NAME, 1, STORE_NAME, storeConfigs);\n if (allKeys.length + files.length > MAX_FILES) {\n throw new Error(`Max ${MAX_FILES} documents allowed.`);\n }\n\n const successfulUploads: KnowledgeDoc[] = [];\n \n for (const file of files) {\n try {\n debugLogger.debug(\"Processing file\", { filename: file.name, type: file.type });\n \n if (isVectorEnabled && uploadDocument) {\n // Advanced users: Use vector database + S3 storage (like Knowledge Tab)\n const result = await uploadDocument(file, true);\n \n if (result.success && result.fileId) {\n const doc: KnowledgeDoc = {\n id: uuidv4(),\n name: file.name,\n originalFileName: file.name,\n s3Url: result.fileId, // Store fileId as s3Url for file access\n addedDate: new Date(),\n content: \"\", // Content is in vector DB, not stored locally\n embedding: [], // Embedding is in vector DB\n mimeType: file.type,\n size: file.size,\n };\n \n // Save metadata to IndexedDB (lightweight reference)\n await indexedDBService.put(DB_NAME, 1, STORE_NAME, doc, storeConfigs);\n successfulUploads.push(doc);\n \n debugLogger.debug(\"Document uploaded to vector database\", { filename: file.name, fileId: result.fileId });\n } else {\n throw new Error(result.error || 'Vector upload failed');\n }\n } else {\n // Basic users: Use local IndexedDB storage with parsed content and embeddings\n const parseResult = await parseFile(file);\n if (parseResult.trim().length === 0) {\n debugLogger.warn(\"File has no content\", { filename: file.name });\n continue;\n }\n \n debugLogger.debug(\"File content parsed\", { filename: file.name, contentLength: parseResult.length });\n \n // Store raw file data as base64 for consistent download behavior\n const arrayBuffer = await file.arrayBuffer();\n // Use chunked approach to avoid \"Maximum call stack size exceeded\" for large files\n const uint8Array = new Uint8Array(arrayBuffer);\n let binaryString = '';\n const chunkSize = 8192; // Process 8KB chunks to avoid stack overflow\n \n for (let i = 0; i < uint8Array.length; i += chunkSize) {\n const chunk = uint8Array.slice(i, i + chunkSize);\n binaryString += String.fromCharCode.apply(null, Array.from(chunk));\n }\n \n const base64Data = btoa(binaryString);\n debugLogger.debug(\"Raw file data encoded\", { filename: file.name, rawDataLength: base64Data.length });\n \n const embedding = await embeddingService.generate(parseResult);\n debugLogger.debug(\"Embedding generated\", { filename: file.name, embeddingLength: embedding?.length });\n \n const doc: KnowledgeDoc = {\n id: uuidv4(),\n name: file.name,\n content: parseResult,\n rawData: base64Data, // Store original file data\n originalFileName: file.name,\n embedding,\n addedDate: new Date(),\n mimeType: file.type,\n size: file.size,\n };\n \n await indexedDBService.put(DB_NAME, 1, STORE_NAME, doc, storeConfigs);\n successfulUploads.push(doc);\n \n debugLogger.debug(\"Document saved to IndexedDB\", { filename: file.name, id: doc.id });\n }\n \n } catch (error) {\n debugLogger.error(\"Failed to process file\", { filename: file.name, error });\n throw new Error(`Failed to process ${file.name}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n \n if (successfulUploads.length === 0) {\n throw new Error(\"No files were successfully processed\");\n }\n \n // Reload documents and sync with zustand store\n await loadDocuments();\n \n debugLogger.info(\"Documents added successfully\", { \n count: successfulUploads.length,\n filenames: successfulUploads.map(d => d.name),\n storageMethod: isVectorEnabled ? 'vector-db' : 'indexed-db'\n });\n };\n\n // Helper function to determine if a document is stored in vector DB\n const isVectorDocument = (doc: KnowledgeDoc): boolean => {\n if (!doc) return false;\n\n const hasExplicitVectorMarker = Boolean(\n (doc.s3Url && String(doc.s3Url).trim().length > 0) ||\n (hasVectorMetadata(doc) && doc._vectorResult)\n );\n\n if (hasExplicitVectorMarker) {\n return true;\n }\n\n const looksLikeMongoId = typeof doc.id === \"string\" && /^[0-9a-f]{24}$/i.test(doc.id);\n const lacksInlineContent = !doc.content || doc.content.length === 0;\n\n return looksLikeMongoId && lacksInlineContent;\n };\n\n const parseFile = async (file: File): Promise<string> => {\n const name = file.name.toLowerCase();\n\n try {\n debugLogger.debug(\"Parsing file\", { filename: file.name, type: file.type, size: file.size });\n \n if (\n file.type.startsWith(\"text/\") ||\n name.endsWith(\".txt\") ||\n name.endsWith(\".md\") ||\n name.endsWith(\".json\") ||\n name.endsWith(\".cs\") ||\n name.endsWith(\".js\") ||\n name.endsWith(\".ts\") ||\n name.endsWith(\".tsx\") ||\n name.endsWith(\".jsx\") ||\n name.endsWith(\".py\") ||\n name.endsWith(\".java\") ||\n name.endsWith(\".cpp\") ||\n name.endsWith(\".c\") ||\n name.endsWith(\".html\") ||\n name.endsWith(\".css\") ||\n name.endsWith(\".php\") ||\n name.endsWith(\".rb\") ||\n name.endsWith(\".go\") ||\n name.endsWith(\".rs\") ||\n name.endsWith(\".kt\") ||\n name.endsWith(\".swift\") ||\n name.endsWith(\".scala\") ||\n name.endsWith(\".sh\") ||\n name.endsWith(\".bat\") ||\n name.endsWith(\".ps1\") ||\n name.endsWith(\".xml\") ||\n name.endsWith(\".yaml\") ||\n name.endsWith(\".yml\") ||\n name.endsWith(\".csv\")\n ) {\n const content = await file.text();\n debugLogger.debug(\"Text file parsed\", { filename: file.name, contentLength: content.length });\n return content;\n }\n\n if (name.endsWith(\".docx\")) {\n debugLogger.debug(\"Parsing DOCX file\", { filename: file.name });\n const arrayBuffer = await file.arrayBuffer();\n const { value } = await mammoth.extractRawText({ arrayBuffer });\n debugLogger.debug(\"DOCX file parsed\", { filename: file.name, contentLength: value.length });\n return value;\n }\n\n if (name.endsWith(\".pdf\")) {\n debugLogger.debug(\"Parsing PDF file\", { filename: file.name });\n // Use Burtson CDN PDF worker\n pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.burtson.ai/scripts/pdf.worker.js';\n \n const buffer = await file.arrayBuffer();\n const pdf = await pdfjsLib.getDocument({ data: buffer }).promise;\n\n const pages = await Promise.all(\n Array.from({ length: Math.min(10, pdf.numPages) }, async (_, i) => {\n const page = await pdf.getPage(i + 1);\n const content = await page.getTextContent();\n const items = content.items as Array<TextItem | TextMarkedContent>;\n return items\n .map((item) => (isTextItem(item) ? item.str : \"\"))\n .join(\" \");\n })\n );\n const result = pages.join(\"\\n\\n\");\n \n debugLogger.debug(\"PDF file parsed\", { filename: file.name, contentLength: result.length, pageCount: pdf.numPages });\n return result;\n }\n \n debugLogger.warn(\"Unsupported file type\", { filename: file.name, type: file.type });\n throw new Error(`Unsupported file type: ${file.type}`);\n \n } catch (err) {\n debugLogger.error(\"Failed to parse file\", { filename: file.name, error: err });\n throw err;\n }\n };\n\n const searchDocuments = async (query: string): Promise<KnowledgeDoc[]> => {\n if (!query.trim()) return [];\n\n const queryEmbedding = await embeddingService.generate(query);\n const scored: { doc: KnowledgeDoc; score: number }[] = [];\n\n for (const doc of documents) {\n if (doc.embedding) {\n const score = embeddingService.cosineSimilarity(queryEmbedding, doc.embedding);\n scored.push({ doc, score });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n const topMatches = scored.filter((entry) => entry.score >= 0.6).map((entry) => entry.doc);\n\n return topMatches;\n };\n\n return {\n documents,\n addDocuments,\n removeDocument,\n clearAllDocuments,\n loadDocuments,\n searchDocuments,\n isVectorDocument,\n };\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\nexport interface KnowledgeDoc {\n id: string;\n name: string;\n content: string;\n embedding?: number[];\n rawData?: string;\n type?: string;\n addedDate?: Date;\n size?: number;\n uploadedBy?: string;\n userEmail?: string;\n bucket?: string;\n key?: string; \n\n isUserContent?: boolean;\n isTeamContent?: boolean;\n contentSource?: 'user' | 'team';\n teamSid?: string;\n\n mimeType?: string;\n originalFileName?: string;\n s3Url?: string;\n}\n\ninterface KnowledgeStore {\n docs: KnowledgeDoc[];\n isLoaded: boolean;\n addDoc: (doc: Omit<KnowledgeDoc, \"id\">) => void;\n removeDoc: (id: string) => void;\n clearDocs: () => void;\n loadDocs: () => Promise<void>;\n saveDocs: () => Promise<void>;\n}\n\nexport const useKnowledgeStore = create<KnowledgeStore>((set, get) => ({\n docs: [],\n isLoaded: false,\n \n addDoc: (doc) => {\n const current = get().docs;\n if (current.length >= 20) {\n debugLogger.warn(\"⚠️ Maximum of 20 knowledge docs reached.\");\n return;\n }\n\n const newDoc: KnowledgeDoc = {\n id: uuidv4(),\n name: doc.name,\n content: doc.content,\n embedding: doc.embedding,\n rawData: doc.rawData,\n mimeType: doc.mimeType,\n originalFileName: doc.originalFileName,\n s3Url: doc.s3Url,\n type: doc.type,\n addedDate: doc.addedDate,\n size: doc.size,\n uploadedBy: doc.uploadedBy,\n userEmail: doc.userEmail,\n bucket: doc.bucket,\n key: doc.key,\n isUserContent: doc.isUserContent,\n isTeamContent: doc.isTeamContent,\n contentSource: doc.contentSource,\n };\n\n set({ docs: [...current, newDoc] });\n \n // Save individual doc to IndexedDB\n (async () => {\n try {\n const storeConfigs = [{ name: \"documents\", keyPath: \"id\" }];\n await indexedDBService.put(\"banditKnowledge\", 1, \"documents\", newDoc, storeConfigs);\n debugLogger.debug(\"Knowledge doc added to IndexedDB\", { id: newDoc.id, name: newDoc.name });\n } catch (error) {\n debugLogger.error(\"Failed to save new knowledge doc to IndexedDB\", { error });\n }\n })();\n },\n \n removeDoc: (id) => {\n set((state) => ({\n docs: state.docs.filter((d) => d.id !== id),\n }));\n \n // Remove from IndexedDB\n (async () => {\n try {\n const storeConfigs = [{ name: \"documents\", keyPath: \"id\" }];\n await indexedDBService.delete(\"banditKnowledge\", 1, \"documents\", id, storeConfigs);\n debugLogger.debug(\"Knowledge doc removed from IndexedDB\", { id });\n } catch (error) {\n debugLogger.error(\"Failed to remove knowledge doc from IndexedDB\", { error });\n }\n })();\n },\n \n clearDocs: () => {\n set({ docs: [] });\n \n // Clear IndexedDB\n (async () => {\n try {\n const storeConfigs = [{ name: \"documents\", keyPath: \"id\" }];\n await indexedDBService.clear(\"banditKnowledge\", 1, \"documents\", storeConfigs);\n debugLogger.debug(\"All knowledge docs cleared from IndexedDB\");\n } catch (error) {\n debugLogger.error(\"Failed to clear knowledge docs from IndexedDB\", { error });\n }\n })();\n },\n \n loadDocs: async () => {\n try {\n const storeConfigs = [{ name: \"documents\", keyPath: \"id\" }];\n const docs = await indexedDBService.getAll<KnowledgeDoc>(\"banditKnowledge\", 1, \"documents\", storeConfigs);\n \n set({ \n docs: docs || [],\n isLoaded: true \n });\n debugLogger.info(\"Knowledge docs loaded from IndexedDB\", { count: docs?.length || 0 });\n } catch (error) {\n debugLogger.error(\"Failed to load knowledge docs from IndexedDB\", { error });\n set({ isLoaded: true }); // Mark as loaded even if failed, so UI can render\n }\n },\n \n saveDocs: async () => {\n try {\n const { docs } = get();\n const storeConfigs = [{ name: \"documents\", keyPath: \"id\" }];\n \n // Clear existing docs and save new ones individually\n await indexedDBService.clear(\"banditKnowledge\", 1, \"documents\", storeConfigs);\n \n for (const doc of docs) {\n await indexedDBService.put(\"banditKnowledge\", 1, \"documents\", doc, storeConfigs);\n }\n \n debugLogger.debug(\"Knowledge docs saved to IndexedDB\", { count: docs.length });\n } catch (error) {\n debugLogger.error(\"Failed to save knowledge docs to IndexedDB\", { error });\n }\n },\n}));","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { lastValueFrom, map } from \"rxjs\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { getStableQuestionPrompt, QuestionPromptArgs } from \"../../prompts/getStableQuestionPrompt\";\nimport { debugLogger } from \"../logging/debugLogger\";\nimport { enhancePromptWithContext } from \"./promptUtils\";\nimport { notificationService } from \"../notification/notificationService\";\n\n/**\n * Generates conversation starter prompts based on topics of interest.\n * \n * @param parameters - Parameters for generating conversation starters\n * @param parameters.limit - Number of questions to generate (1-10)\n * @param parameters.topicOfInterest - Default topic e.g \"sports, travel, technology, coding, .NET, kite flying, etc.\"\n * @returns A promise that resolves to an array of conversation starters\n */\nexport const generateConversationStarters = async (args: QuestionPromptArgs): Promise<string[]> => {\n const provider = useAIProviderStore.getState().provider;\n if (!provider) {\n debugLogger.error(\"No AI provider available for generating conversation starters\");\n return [];\n }\n\n const modelName = usePackageSettingsStore.getState().settings?.defaultModel || \"default-model-fallback\";\n \n try {\n const data$ = provider.generate({\n model: modelName,\n prompt: enhancePromptWithContext(getStableQuestionPrompt(args)),\n stream: false,\n options: { temperature: 1.5, num_predict: 250 },\n });\n const questions$ = data$.pipe(map((d) => {\n const sanitizeLine = (line: string): string => {\n const withoutNumbering = line\n .replace(/^[0-9]+[.)\\-\\s:]+/, \"\")\n .replace(/^[•*+-]\\s+/, \"\");\n const withoutQuotes = withoutNumbering.replace(/^[“\"']+/, \"\").replace(/[”\"']+$/, \"\");\n const withoutEmoji = withoutQuotes.replace(/\\p{Extended_Pictographic}/gu, \"\");\n return withoutEmoji.trim().replace(/\\s+/g, \" \");\n };\n\n // Split by newlines and filter out empty/meaningless responses\n const sanitized = d.response\n .split(\"\\n\")\n .map((line) => sanitizeLine(line.trim()))\n .filter((line) => {\n const lower = line.toLowerCase();\n return (\n line.length > 10 &&\n line.includes(\"?\") &&\n !lower.includes(\"sorry\") &&\n !lower.includes(\"i cannot\") &&\n !lower.includes(\"i can't\") &&\n !lower.includes(\"unable to\") &&\n !lower.startsWith(\"as an ai\")\n );\n })\n .filter((line) => line.length > 0);\n\n // Deduplicate while preserving order\n const unique: string[] = [];\n const seen = new Set<string>();\n sanitized.forEach((line) => {\n const key = line\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, \" \")\n .trim();\n if (key && !seen.has(key)) {\n seen.add(key);\n unique.push(line);\n }\n });\n return unique;\n }));\n const starters = await lastValueFrom(questions$);\n \n // Only return meaningful conversation starters\n if (starters.length === 0) {\n debugLogger.warn(\"No meaningful conversation starters generated\");\n return [];\n }\n \n return starters.slice(0, args.limit);\n } catch (err) {\n debugLogger.error(\"❌ Failed to generate conversation starters:\", { error: err });\n \n // Show notification to user for conversation starter generation failures\n notificationService.handleHttpError(err);\n \n return [];\n }\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from \"./services/logging/debugLogger\";\n\nexport const toTitleCase = (str: string) => str.toLowerCase().split(' ').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')\n\n/**\n * Generates a random number between min and max (inclusive).\n * @param min the minimum value \n * @param max the maximum value \n * @returns \n */\nexport const randomRange = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;\n\nexport const generateSeed = () => Math.floor(Math.random() * 10000)\n\nexport const fetchAndConvertToBase64 = async (src: string): Promise<string> => {\n const response = await fetch(src);\n const blob = await response.blob();\n return await new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\nexport const detectTransparency = (imageSrc: string): Promise<boolean> => {\n return new Promise((resolve) => {\n const img = new window.Image();\n img.crossOrigin = \"Anonymous\";\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.width;\n canvas.height = img.height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return resolve(false);\n ctx.drawImage(img, 0, 0);\n const imageData = ctx.getImageData(0, 0, img.width, img.height).data;\n for (let i = 3; i < imageData.length; i += 4) {\n if (imageData[i] < 255) {\n debugLogger.debug(\"Detected transparency in image\");\n resolve(true);\n return;\n }\n }\n debugLogger.debug(\"No transparency detected in image\");\n resolve(false);\n };\n img.src = imageSrc;\n });\n};\n\nconst banditHead = \"https://cdn.burtson.ai/logos/bandit-head.png\";\n\nexport const modelAvatars: Record<string, string> = {\n \"Bandit-Core\": \"https://cdn.burtson.ai/avatars/core-avatar.png\",\n \"Bandit-Muse\": \"https://cdn.burtson.ai/avatars/muse-avatar.png\",\n \"Bandit-Logic\": \"https://cdn.burtson.ai/avatars/logic-avatar.png\",\n \"Bandit-D1VA\": \"https://cdn.burtson.ai/avatars/d1va-avatar.png\",\n \"Bandit-Exec\": \"https://cdn.burtson.ai/avatars/exec-avatar.png\",\n};\n\ntype ModelLike = {\n name?: string;\n avatarBase64?: string | null;\n};\n\nexport const resolveAvatar = (model: ModelLike | null | undefined): string => {\n // If no model provided, return banditHead URL\n if (!model) return banditHead;\n\n // If model has base64 avatar\n if (model.avatarBase64 && model.avatarBase64.startsWith(\"data:image\")) {\n return model.avatarBase64;\n }\n\n // If model is a known Bandit model\n const banditAvatar = model.name ? modelAvatars[model.name] : undefined;\n if (banditAvatar) {\n return banditAvatar;\n }\n\n return banditHead;\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from '../logging/debugLogger';\nimport type { NotificationContextType } from '../../shared/components/NotificationProvider';\n\ntype HttpErrorShape = {\n response?: {\n status?: number;\n data?: Record<string, unknown>;\n };\n message?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === 'object';\nconst getRecordString = (record: Record<string, unknown> | undefined, key: string): string | undefined =>\n record && typeof record[key] === 'string' ? (record[key] as string) : undefined;\n\n\n/**\n * Global notification handler that can be used throughout the application\n */\nexport class NotificationService {\n private notificationContext: NotificationContextType | null = null;\n\n /**\n * Set the notification context (usually called from a component that has access to useNotification)\n */\n setContext(context: NotificationContextType) {\n this.notificationContext = context;\n }\n\n /**\n * Show a generic notification\n */\n show(message: string, severity: 'success' | 'error' | 'warning' | 'info' = 'info') {\n if (this.notificationContext) {\n this.notificationContext.showNotification({ message, severity });\n } else {\n // Fallback to console logging if notification context is not available\n debugLogger.warn('Notification context not available, falling back to console:', { message, severity });\n console.warn(`[${severity.toUpperCase()}] ${message}`);\n }\n }\n\n /**\n * Show an error notification\n */\n showError(message: string) {\n this.show(message, 'error');\n }\n\n /**\n * Show a success notification\n */\n showSuccess(message: string) {\n this.show(message, 'success');\n }\n\n /**\n * Show a warning notification\n */\n showWarning(message: string) {\n this.show(message, 'warning');\n }\n\n /**\n * Show an info notification\n */\n showInfo(message: string) {\n this.show(message, 'info');\n }\n\n /**\n * Handle HTTP errors and show appropriate notifications\n */\n handleHttpError(error: unknown, customMessage?: string) {\n let message = customMessage || 'An error occurred';\n const httpError = error as HttpErrorShape;\n\n if (httpError?.response) {\n // HTTP error response\n const status = httpError.response?.status;\n const data = httpError.response?.data;\n \n // Extract detailed error information\n // For your API structure with nested error objects: { error: { message: \"...\", type: \"...\", code: \"...\" } }\n const nestedError = isRecord(data?.error) ? data.error : undefined;\n const errorMessage =\n getRecordString(nestedError, 'message') ||\n getRecordString(data, 'message') ||\n getRecordString(data, 'detail');\n const errorType =\n getRecordString(nestedError, 'type') ||\n getRecordString(data, 'type');\n const errorCode =\n getRecordString(nestedError, 'code') ||\n getRecordString(data, 'code') ||\n getRecordString(data, 'error_code') ||\n (typeof data?.error === 'string' ? data.error : undefined);\n \n // Debug logging to see what we're extracting\n debugLogger.info('Processing HTTP error response:', {\n status,\n errorMessage,\n errorType,\n errorCode,\n rawData: data\n });\n \n // Build detailed message with error code and specific message\n const buildDetailedMessage = (defaultMsg: string) => {\n // If we have a specific error message, prioritize showing that\n if (errorMessage) {\n // For detailed error messages like yours, just show the message directly\n // as it's already comprehensive and user-friendly\n return errorMessage;\n } else if (errorCode) {\n // If we only have an error code, show it with context\n return `Error: ${errorCode}`;\n } else if (errorType) {\n // If we only have an error type, show it with context\n return `Error: ${errorType}`;\n } else {\n // For 400-level errors without specific messages, include status code\n if (typeof status === 'number' && status >= 400 && status < 500) {\n return `HTTP ${status}: ${defaultMsg}`;\n }\n return defaultMsg;\n }\n };\n\n switch (status) {\n case 400:\n message = buildDetailedMessage('Bad request - please check your input');\n break;\n case 401:\n message = buildDetailedMessage('Authentication required - please log in');\n break;\n case 403:\n message = buildDetailedMessage('Access denied - you don\\'t have permission for this action');\n break;\n case 404:\n message = buildDetailedMessage('Resource not found');\n break;\n case 422:\n message = buildDetailedMessage('Validation failed - please check your input');\n break;\n case 429:\n message = buildDetailedMessage('Too many requests - please try again later');\n break;\n case 500:\n message = buildDetailedMessage('Server error - please try again later');\n break;\n case 502:\n case 503:\n case 504:\n message = buildDetailedMessage('Service temporarily unavailable - please try again later');\n break;\n default:\n // For any other 400-level errors, show detailed info\n if (typeof status === 'number' && status >= 400 && status < 500) {\n message = buildDetailedMessage(`Client error (${typeof status === 'number' ? status : 'unknown'})`);\n } else {\n message = buildDetailedMessage(`Request failed with status ${typeof status === 'number' ? status : 'unknown'}`);\n }\n }\n } else if (httpError?.message) {\n message = httpError.message;\n }\n\n debugLogger.error('HTTP Error handled by notification service:', { error, message });\n this.showError(message);\n }\n\n /**\n * Handle network/connection errors\n */\n handleNetworkError(error: unknown, customMessage?: string) {\n const message = customMessage || 'Network error - please check your connection and try again';\n debugLogger.error('Network Error handled by notification service:', { error, message });\n this.showError(message);\n }\n\n /**\n * Handle validation errors\n */\n handleValidationError(errors: readonly string[] | string, customMessage?: string) {\n let message: string;\n if (typeof customMessage === 'string' && customMessage.length > 0) {\n message = customMessage;\n } else if (Array.isArray(errors)) {\n message = (errors as readonly string[]).join(', ');\n } else {\n message = errors as string;\n }\n debugLogger.warn('Validation Error handled by notification service:', { errors, message });\n this.showWarning(message);\n }\n}\n\nexport const notificationService = new NotificationService();\nexport default notificationService;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { map, toArray } from \"rxjs\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\nimport { enhancePromptWithContext } from \"./promptUtils\";\n\n/**\n * Detects the emotional tone of the user's message using the AI provider.\n * This helps drive token budgeting, avatar mood, and reinforcement logic.\n *\n * @param message - The user's message to analyze\n * @returns Promise resolving to emotional tone: \"high\" | \"neutral\" | \"low\"\n */\nexport const detectMessageMood = async (\n message: string\n): Promise<\"high\" | \"neutral\" | \"low\"> => {\n // Get the provider fresh each time the function is called\n const provider = useAIProviderStore.getState().provider;\n\n if (!provider) {\n debugLogger.error(\"No AI provider available for mood detection\");\n return \"neutral\";\n }\n\n const prompt = `\nRate the emotional tone of the user's message. Only respond with \"high\", \"neutral\", or \"low\".\n\nIf the message expresses strong enthusiasm, joy, or excitement, respond with \"high\".\nIf the message feels calm, polite, or ordinary, respond with \"neutral\".\nIf the message feels sad, bored, or frustrated, respond with \"low\".\n\nMessage: \"${message}\"\n\nResponse:`;\n\n const modelName = usePackageSettingsStore.getState().settings?.defaultModel || \"bandit-core\";\n\n try {\n debugLogger.llmDebug(\"detectMessageMood\", { message: message.slice(0, 100) });\n\n const response$ = provider.generate({\n model: modelName,\n prompt: enhancePromptWithContext(prompt),\n stream: false,\n options: { temperature: 0.3, num_predict: 10 },\n });\n\n const chunks$ = response$.pipe(\n map((chunk) => chunk.response.trim().toLowerCase()),\n toArray()\n );\n\n const result = await chunks$.toPromise();\n const finalResult = (result || []).join(\"\").trim();\n\n debugLogger.llmDebug(\"detectMessageMood result\", { finalResult });\n\n // Validate the response\n if (finalResult.includes(\"high\")) return \"high\";\n if (finalResult.includes(\"low\")) return \"low\";\n return \"neutral\";\n } catch (error) {\n debugLogger.error(\"Error detecting mood:\", { error });\n return \"neutral\";\n }\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { lastValueFrom, map, toArray } from \"rxjs\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\n/**\n * Determines if user input contains meaningful information that shows their interests, \n * excitement, or engagement - focusing on what could enhance their experience.\n * \n * This replaces the old \"personal information\" approach which was too broad and intrusive.\n * Now we focus on user interest signals and engagement rather than demographic collection.\n * \n * @param question - The user's input message\n * @param response - The AI's response (currently unused but available for context)\n * @returns Promise resolving to true if user interest/excitement is detected\n */\nexport const detectUserInterestAndExcitement = async (question: string, response: string): Promise<boolean> => {\n // Get the provider fresh each time the function is called\n const provider = useAIProviderStore.getState().provider;\n\n if (!provider) {\n debugLogger.error(\"No AI provider available for personal content detection\");\n return false;\n }\n\n const prompt = `\n Detect if the user shared something meaningful that shows their interests, excitement, or personal connection.\n\n Look for USER INTEREST & EXCITEMENT signals:\n - User expressing enthusiasm, excitement, or passion about something\n - User sharing goals, dreams, or aspirations they care about\n - User mentioning preferences that affect their experience (tools, formats, workflows)\n - User revealing meaningful life experiences or achievements\n - User discussing plans, projects, or activities they're invested in\n - User sharing challenges they want to overcome or skills they want to develop\n\n IGNORE routine mentions:\n - Simple factual statements without emotional investment\n - Casual location references without context\n - Generic preferences without personal significance\n - Basic demographic info (age, location) without meaningful context\n - Complaints or negative experiences without constructive elements\n\n Focus on what could enhance their experience or help me serve them better.\n \n Reply \"YES\" only if the user shared something they care about or are excited about.\n Reply \"NO\" for routine information or casual mentions.\n \n User input:\n \"${question}\"\n \n Response:`;\n\n const modelName = usePackageSettingsStore.getState().settings?.defaultModel || \"bandit-core\";\n\n try {\n debugLogger.llmDebug(\"detectUserInterestAndExcitement\", { question: question.slice(0, 100) });\n\n const response$ = provider.generate({\n model: modelName,\n prompt,\n stream: false,\n options: { temperature: 0.1, num_predict: 5 },\n });\n\n const chunks$ = response$.pipe(\n map((chunk) => chunk.response.trim().toUpperCase()),\n toArray()\n );\n\n const result = await lastValueFrom(chunks$);\n const decision = result.join(\"\").trim();\n\n debugLogger.llmDebug(\"detectUserInterestAndExcitement result\", { decision });\n\n return decision.includes(\"YES\");\n } catch (error) {\n debugLogger.error(\"Error detecting personal content:\", { error });\n return false;\n }\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { lastValueFrom, map } from \"rxjs\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\n/**\n * Summarizes document content for indexing in the AI knowledge system.\n * \n * @param name - The filename of the document\n * @param content - The document content to summarize\n * @returns Promise resolving to a concise summary string\n */\nexport const summarizeDocument = async (name: string, content: string): Promise<string> => {\n // Get the provider fresh each time the function is called\n const provider = useAIProviderStore.getState().provider;\n\n if (!provider) {\n debugLogger.error(\"No AI provider available for document summarization\");\n return `Summary unavailable for ${name}`;\n }\n\n const prompt = `\nYou are an assistant designed to summarize documents for indexing in an AI knowledge system.\nSummarize the following document in 1-2 concise sentences.\nOnly describe the content — do not add commentary, humor, or emojis.\nIf the file has a specific structure (e.g., C# code, policy, technical reference), mention that in the summary.\n\nFilename: ${name}\nContent:\n${content.slice(0, 4000)}\n`.trim();\n\n try {\n debugLogger.ragDebug(\"summarizeDocument\", { name, contentLength: content.length });\n\n const data$ = provider.generate({\n model: usePackageSettingsStore.getState().settings?.defaultModel || \"bandit-core\",\n prompt,\n stream: false,\n options: { temperature: 0.3, num_predict: 100 },\n });\n\n const summary$ = data$.pipe(map((d) => d.response.trim()));\n const summary = await lastValueFrom(summary$);\n\n debugLogger.ragDebug(\"summarizeDocument result\", { name, summary });\n\n return summary || `Document summary for ${name}`;\n } catch (error) {\n debugLogger.error(\"Error summarizing document:\", { error, name });\n return `Summary error for ${name}`;\n }\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { lastValueFrom, map, toArray } from \"rxjs\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\n/**\n * Determines which documents are relevant to the user's question for RAG (Retrieval-Augmented Generation).\n * \n * @param question - The user's question or prompt\n * @param docs - Array of documents with name and chunk content\n * @returns Promise resolving to array of relevant document indices\n */\nexport const determineRelevantDocuments = async (\n question: string,\n docs: { name: string; chunks: string[] }[]\n): Promise<number[]> => {\n const provider = useAIProviderStore.getState().provider;\n if (!provider) {\n debugLogger.error(\"No AI provider available for knowledge relevance vetting\");\n return [];\n }\n\n const vetPrompt = `\nYou are a context-aware assistant. The user is asking:\n\n\"${question}\"\n\nHere are some documents:\n${docs\n .map(\n (d, i) =>\n `Doc ${i + 1} - \"${d.name}\":\\n${d.chunks.slice(0, 2).join(\"\\n\").slice(0, 1000)}\\n`\n )\n .join(\"\\n\")}\n\nOnly include documents if the user's question explicitly relates to their contents.\n\nReply with a comma-separated list of document numbers (e.g., \"1,3,5\") or \"none\" if no documents are relevant.\n\nResponse:`;\n\n const modelName = usePackageSettingsStore.getState().settings?.defaultModel || \"bandit-core\";\n\n try {\n debugLogger.ragDebug(\"determineRelevantDocuments\", {\n question: question.slice(0, 100),\n docCount: docs.length,\n docNames: docs.map(d => d.name)\n });\n\n const response$ = provider.generate({\n model: modelName,\n prompt: vetPrompt,\n stream: false,\n options: { temperature: 0.2, num_predict: 50 },\n });\n\n const chunks$ = response$.pipe(\n map((chunk) => chunk.response.trim()),\n toArray()\n );\n\n const result = await lastValueFrom(chunks$);\n const vetResult = result.join(\"\").trim().toLowerCase();\n\n debugLogger.ragDebug(\"determineRelevantDocuments result\", { vetResult });\n\n if (vetResult.includes(\"none\") || !vetResult) {\n return [];\n }\n\n // Parse comma-separated numbers\n const relevantIndices = vetResult\n .split(\",\")\n .map((s) => parseInt(s.trim()) - 1) // Convert to 0-based index\n .filter((i) => !isNaN(i) && i >= 0 && i < docs.length);\n\n debugLogger.ragDebug(\"determineRelevantDocuments parsed\", { relevantIndices });\n\n return relevantIndices;\n } catch (error) {\n debugLogger.error(\"Error determining relevant documents:\", { error });\n return [];\n }\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\n\nexport interface MemoryEntry {\n id: string;\n content: string;\n tags?: string[];\n timestamp: number;\n source: \"auto\" | \"user\";\n embedding?: number[];\n pinned?: boolean;\n}\n\ninterface MemoryStore {\n entries: MemoryEntry[];\n _hasHydrated: boolean;\n addMemory: (\n content: string,\n tags?: string[],\n source?: \"auto\" | \"user\",\n embedding?: number[],\n pinned?: boolean\n ) => Promise<void>;\n searchMemory: (query: string) => MemoryEntry[];\n findRelevantMemories: (query: string, limit?: number) => MemoryEntry[];\n togglePinMemory: (id: string) => Promise<void>;\n hydrate: () => Promise<void>;\n removeMemory: (id: string) => Promise<void>;\n clearMemories: () => Promise<void>;\n}\n\nconst DB_NAME = \"bandit-memory-db\";\nconst STORE_NAME = \"bandit-memory\";\nconst storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n\n// Helper: Normalize text for basic matching\nconst normalize = (text: string) =>\n text\n .toLowerCase()\n .replace(/[^\\w\\s]|_/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n\nexport const useMemoryStore = create<MemoryStore>((set, get) => ({\n entries: [],\n _hasHydrated: false,\n\n hydrate: async () => {\n const allEntries = await indexedDBService.getAll<MemoryEntry>(DB_NAME, 1, STORE_NAME, storeConfigs);\n set({ \n entries: allEntries,\n _hasHydrated: true \n });\n },\n\n addMemory: async (\n content,\n tags = [],\n source = \"user\",\n embedding,\n pinned = false\n ) => {\n const newEntry: MemoryEntry = {\n id: crypto.randomUUID(),\n content,\n tags,\n timestamp: Date.now(),\n source,\n embedding,\n pinned,\n };\n await indexedDBService.put(DB_NAME, 1, STORE_NAME, newEntry, storeConfigs);\n set((state) => ({\n entries: [...state.entries, newEntry],\n }));\n },\n\n removeMemory: async (id: string) => {\n await indexedDBService.delete(DB_NAME, 1, STORE_NAME, id, storeConfigs);\n set((state) => ({\n entries: state.entries.filter((entry) => entry.id !== id),\n }));\n },\n\n clearMemories: async () => {\n await indexedDBService.clear(DB_NAME, 1, STORE_NAME, storeConfigs);\n set({ \n entries: [],\n _hasHydrated: true // Keep hydrated flag true after clearing\n });\n },\n\n searchMemory: (query) => {\n const lc = query.toLowerCase();\n return get().entries.filter((entry) => entry.content.toLowerCase().includes(lc));\n },\n\n findRelevantMemories: (query, limit = 3) => {\n const normQuery = normalize(query);\n const queryWords = normQuery.split(\" \");\n\n const scored = get().entries.map((entry) => {\n const normContent = normalize(entry.content);\n const matchCount = queryWords.filter((word) =>\n normContent.includes(word)\n ).length;\n return { entry, score: matchCount };\n });\n\n return scored\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n .map((item) => item.entry);\n },\n\n togglePinMemory: async (id: string) => {\n set((state) => {\n const updatedEntries = state.entries.map((entry) =>\n entry.id === id ? { ...entry, pinned: !entry.pinned } : entry\n );\n (async () => {\n const updatedEntry = updatedEntries.find((entry) => entry.id === id);\n if (updatedEntry) {\n await indexedDBService.put(DB_NAME, 1, STORE_NAME, updatedEntry, storeConfigs);\n }\n })();\n return { entries: updatedEntries };\n });\n },\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { summarizeDocument } from \"../prompts\";\nimport { useMemoryStore } from \"../../store/memoryStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\nexport class EmbeddingService {\n /**\n * Generates a basic \"fake\" embedding based on word length.\n * (Replaceable later with true model-based embeddings.)\n */\n async generate(text: string): Promise<number[]> {\n const words = text.toLowerCase().split(/\\s+/);\n return words.slice(0, 5).map((w) => w.length / 10);\n }\n\n private generateTFEmbedding(text: string, topN = 10): number[] {\n const words = text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \"\")\n .split(/\\s+/)\n .filter(Boolean);\n\n const freq: Record<string, number> = {};\n for (const word of words) {\n freq[word] = (freq[word] || 0) + 1;\n }\n\n const topWords = Object.entries(freq)\n .sort((a, b) => b[1] - a[1])\n .slice(0, topN)\n .map(([word]) => word);\n\n return topWords.map((w) => freq[w] / words.length);\n }\n\n /**\n * Computes cosine similarity between two embedding vectors.\n */\n cosineSimilarity(a: number[], b: number[]): number {\n const dot = a.reduce((sum, ai, i) => sum + ai * (b[i] ?? 0), 0);\n const magA = Math.sqrt(a.reduce((sum, ai) => sum + ai * ai, 0));\n const magB = Math.sqrt(b.reduce((sum, bi) => sum + bi * bi, 0));\n if (magA === 0 || magB === 0) return 0;\n return dot / (magA * magB);\n }\n\n /**\n * Backfills any missing memory embeddings in the memory store.\n */\n async backfillMissingEmbeddings(): Promise<void> {\n const { entries } = useMemoryStore.getState();\n const updates: { id: string; embedding: number[] }[] = [];\n\n for (const entry of entries) {\n if (!entry.embedding) {\n const embedding = await this.generate(entry.content);\n updates.push({ id: entry.id, embedding });\n }\n }\n\n if (updates.length > 0) {\n useMemoryStore.setState((state) => ({\n entries: state.entries.map((entry) => {\n const updated = updates.find((u) => u.id === entry.id);\n return updated ? { ...entry, embedding: updated.embedding } : entry;\n }),\n }));\n debugLogger.debug(`✅ Backfilled ${updates.length} memory embeddings.`);\n } else {\n debugLogger.debug(\"✅ No missing embeddings — all memories are up to date!\");\n }\n }\n\n /**\n * Estimates token usage for a given memory content.\n * Rough formula: word count × 1.3 (average token inflation).\n */\n estimateTokens(text: string): number {\n const wordCount = text.trim().split(/\\s+/).length;\n return Math.ceil(wordCount * 1.3);\n }\n\n /**\n * Calculates total estimated token usage for pinned memories.\n */\n estimatePinnedMemoryTokens(): number {\n const { entries } = useMemoryStore.getState();\n const pinned = entries.filter((entry) => entry.pinned);\n return pinned.reduce((sum, entry) => sum + this.estimateTokens(entry.content), 0);\n }\n\n /**\n * Selects the most relevant memories for injection based on:\n * 1. Always include pinned memories first.\n * 2. Then select top semantic matches by cosine similarity.\n * 3. Stay within an approximate max token budget.\n */\n async selectRelevantMemories(question: string, maxTokens = 750): Promise<string[]> {\n if (!question.trim()) return [];\n\n const { entries } = useMemoryStore.getState();\n if (entries.length === 0) return [];\n\n const questionEmbedding = await this.generate(question);\n\n const pinned = entries.filter((entry) => entry.pinned);\n const unpinned = entries.filter((entry) => !entry.pinned);\n\n // Score unpinned memories\n const scored: { content: string; score: number }[] = [];\n\n for (const entry of unpinned) {\n if (entry.embedding) {\n const sim = this.cosineSimilarity(questionEmbedding, entry.embedding);\n scored.push({ content: entry.content, score: sim });\n }\n }\n\n scored.sort((a, b) => b.score - a.score);\n\n const threshold = 0.6;\n const topMatches = scored.filter((s) => s.score >= threshold);\n\n const selected: string[] = [];\n let tokensUsed = 0;\n\n // 1. Add all pinned memories first (if they fit)\n for (const entry of pinned) {\n const tokensNeeded = this.estimateTokens(entry.content);\n if (tokensUsed + tokensNeeded > maxTokens) {\n break;\n }\n selected.push(entry.content);\n tokensUsed += tokensNeeded;\n }\n\n // 2. Then fill remaining budget with best unpinned matches\n for (const match of topMatches) {\n const tokensNeeded = this.estimateTokens(match.content);\n if (tokensUsed + tokensNeeded > maxTokens) {\n break;\n }\n selected.push(match.content);\n tokensUsed += tokensNeeded;\n }\n\n debugLogger.debug(\n \"🎯 Selected memories (pinned + semantic):\",\n { \n memories: selected.map((m) => `${m.slice(0, 60)}${m.length > 60 ? \"...\" : \"\"}`)\n }\n );\n\n return selected;\n }\n\n /**\n * Splits raw text into smaller chunks (approx. ~500 chars each).\n * Useful for embedding code or reference documents.\n */\n chunkText(text: string, maxLen = 500): string[] {\n const lines = text.split(/\\r?\\n/);\n const chunks: string[] = [];\n let currentChunk = \"\";\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const nextChunk = currentChunk + line + \"\\n\";\n\n if (nextChunk.length > maxLen) {\n if (currentChunk.trim()) {\n chunks.push(currentChunk.trim());\n currentChunk = line + \"\\n\";\n } else {\n chunks.push(line.trim());\n currentChunk = \"\";\n }\n } else {\n currentChunk = nextChunk;\n }\n }\n\n if (currentChunk.trim()) {\n chunks.push(currentChunk.trim());\n }\n\n return chunks;\n }\n\n /**\n * Prepares a document (like a code file) for embedding.\n */\n async embedDocument(name: string, content: string) {\n const chunks = this.chunkText(content);\n const summary = await summarizeDocument(name, content);\n const embeddings = chunks.map((chunk) => this.generateTFEmbedding(chunk));\n\n return {\n name,\n summary,\n chunks,\n embeddings,\n };\n }\n}\n\nexport const embeddingService = new EmbeddingService();\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from '../logging/debugLogger';\nimport {\n KNOWLEDGE_PAGE_LIMIT_MAX,\n parseKnowledgeFileList,\n type KnowledgeFilePage,\n type KnowledgeFileScope,\n type RawFileRecord,\n} from './knowledgeFiles';\n\nexport interface VectorMemory {\n id: string;\n content: string;\n title?: string;\n tags?: string[];\n score?: number;\n uploadedBy: string;\n uploadedAt: string;\n source?: 'auto' | 'user'; // Indicates if memory was created automatically or by user\n pinned?: boolean;\n lastReferencedAt?: string;\n metadata?: VectorMemoryMetadata;\n}\n\nexport interface VectorMemoryMetadata {\n personalConfidence?: number;\n topic?: string;\n engagement?: number;\n extractedFrom?: string;\n tags?: string[];\n additionalProperties?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface VectorDocument {\n id: string;\n filename: string;\n content: string;\n mimeType: string;\n score?: number;\n uploadedBy: string;\n uploadedAt: string;\n isUserContent: boolean;\n isTeamContent: boolean;\n contentSource: 'user' | 'team';\n /** File size in bytes, when the listing reports it. */\n size?: number;\n bucket?: string;\n teamSid?: string;\n userEmail?: string;\n /** Short text preview extracted when the file was indexed. */\n preview?: string;\n}\n\nexport interface SearchResult {\n memories: VectorMemory[];\n documents: VectorDocument[];\n success: boolean;\n message?: string;\n}\n\ninterface MemoryResultsEnvelope extends Record<string, unknown> {\n success?: boolean;\n results?: unknown[];\n memories?: unknown[];\n message?: string;\n totalCount?: number;\n}\n\ninterface DocumentSearchResponse extends Record<string, unknown> {\n success?: boolean;\n results?: VectorDocument[];\n message?: string;\n}\n\n\n// Optional search filters aligned with New_Memories_API.md\nexport interface MemorySearchFilters {\n includePinned?: boolean;\n topics?: string[];\n source?: Array<'auto' | 'user'>;\n tags?: string[];\n}\n\nexport interface CreateMemoryOptions {\n title?: string;\n tags?: string[];\n source?: 'auto' | 'user';\n pinned?: boolean;\n metadata?: VectorMemoryMetadata;\n lastReferencedAt?: string;\n}\n\nexport interface FileUploadResult {\n success: boolean;\n fileId: string;\n message?: string;\n}\n\n/**\n * Upload request structure that matches the backend C# UploadRequest class\n */\nexport interface UploadRequest {\n /** The file to upload */\n file: File;\n /** \n * Indicates whether the file should be shared with the team.\n * If true and the user has team information, the file will be saved to the team bucket.\n * If false, the file will be saved to the user's personal bucket regardless of team membership.\n * Defaults to true for backward compatibility.\n */\n shareWithTeam: boolean;\n}\n\n/**\n * Vector Database Service for Advanced Semantic Search\n * \n * This service handles storage and retrieval of memories and documents\n * in the vector database when advanced semantic search is enabled.\n * \n * Feature Gating:\n * - Requires admin authorization, pro subscription, or team subscription\n * - Supports admin users and pro/team subscription tiers\n * - Only active when advancedMemories feature is enabled\n */\nexport class VectorDatabaseService {\n private baseUrl: string;\n private fileStorageApiUrl: string;\n private token: string | null = null;\n private lastAvailabilityState: boolean | undefined;\n private lastConfigState: string | undefined;\n\n constructor(gatewayApiUrl?: string, fileStorageApiUrl?: string) {\n // Use provided URLs or fallback to defaults\n // For local development, use HTTPS localhost Gateway API (matches working curl command)\n this.baseUrl = gatewayApiUrl || 'https://localhost:5001/api';\n this.fileStorageApiUrl = fileStorageApiUrl || 'https://localhost:5001/api';\n \n debugLogger.info('Vector database service initialized', {\n baseUrl: this.baseUrl,\n fileStorageApiUrl: this.fileStorageApiUrl,\n hasToken: Boolean(this.token),\n });\n }\n\n /**\n * Set authentication token for API calls\n */\n setAuthToken(token: string) {\n this.token = token;\n }\n\n /**\n * Get authorization headers\n */\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (this.token) {\n headers['Authorization'] = `Bearer ${this.token}`;\n }\n\n return headers;\n }\n\n /**\n * Check if vector database is available and configured\n */\n isAvailable(): boolean {\n const available = !!(this.baseUrl && this.fileStorageApiUrl && this.token);\n // Only log on first check or when availability changes\n if (this.lastAvailabilityState !== available) {\n debugLogger.debug('Vector service availability check', {\n baseUrl: this.baseUrl,\n fileStorageApiUrl: this.fileStorageApiUrl,\n hasToken: Boolean(this.token),\n available,\n });\n this.lastAvailabilityState = available;\n }\n return available;\n }\n\n // ===== MEMORY OPERATIONS =====\n\n /**\n * Create and embed a memory in the vector database\n */\n async createMemory(\n content: string,\n options: CreateMemoryOptions = {}\n ): Promise<{ success: boolean; memoryId?: string; message?: string }> {\n if (!this.isAvailable()) {\n throw new Error('Vector database service not available');\n }\n\n try {\n const {\n title,\n tags,\n source = 'user',\n pinned = false,\n metadata,\n lastReferencedAt,\n } = options;\n\n debugLogger.info('Creating vector memory', { \n contentLength: content.length, \n title, \n tagsCount: tags?.length || 0,\n source,\n pinned,\n });\n\n const response = await fetch(`${this.baseUrl}/embedding/embed-memory`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n content,\n title,\n tags: tags || [],\n source,\n pinned,\n metadata,\n lastReferencedAt,\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.message || `API request failed: ${response.status}`);\n }\n\n const result = await response.json();\n \n debugLogger.info('Vector memory created successfully', { \n memoryId: result.memoryId,\n contentLength: result.contentLength \n });\n\n return {\n success: true,\n memoryId: result.memoryId,\n message: result.message\n };\n } catch (error) {\n debugLogger.error('Failed to create vector memory', { \n error: error instanceof Error ? error.message : String(error) \n });\n \n throw new Error(`Failed to create memory: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Search memories in the vector database\n */\n private coerceStringArray(value: unknown): string[] {\n if (!value) {\n return [];\n }\n\n if (Array.isArray(value)) {\n return value\n .map((item) => (typeof item === 'string' ? item : String(item)))\n .map((item) => item.trim())\n .filter(Boolean);\n }\n\n if (typeof value === 'string') {\n return value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n }\n\n return [];\n }\n private coerceString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n }\n\n private coerceBoolean(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n }\n\n private coerceNumber(value: unknown): number | undefined {\n return typeof value === 'number' ? value : undefined;\n }\n\n private asRecord(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === 'object') {\n return value as Record<string, unknown>;\n }\n return undefined;\n }\n\n\n private toRecordArray(values: unknown[]): RawFileRecord[] {\n return values.reduce<RawFileRecord[]>((acc, item) => {\n const record = this.asRecord(item);\n if (record) {\n acc.push(record);\n }\n return acc;\n }, []);\n }\n\n private buildMetadata(primary?: Record<string, unknown>, fallback?: Record<string, unknown>): VectorMemoryMetadata | undefined {\n const metadata: VectorMemoryMetadata = {};\n let hasMetadata = false;\n\n const sources = [primary, fallback].filter(\n (source): source is Record<string, unknown> => Boolean(source) && typeof source === 'object'\n );\n\n const tagsSet = new Set<string>();\n\n for (const source of sources) {\n if (typeof source.personalConfidence === 'number') {\n metadata.personalConfidence = source.personalConfidence;\n hasMetadata = true;\n }\n if (typeof source.topic === 'string' && source.topic.trim()) {\n metadata.topic = source.topic.trim();\n hasMetadata = true;\n }\n if (typeof source.engagement === 'number') {\n metadata.engagement = source.engagement;\n hasMetadata = true;\n }\n if (typeof source.extractedFrom === 'string' && source.extractedFrom.trim()) {\n metadata.extractedFrom = source.extractedFrom.trim();\n hasMetadata = true;\n }\n\n this.coerceStringArray(source.tags).forEach((tag) => {\n tagsSet.add(tag);\n hasMetadata = true;\n });\n\n const additionalSource = source.additionalProperties;\n if (additionalSource && typeof additionalSource === 'object') {\n metadata.additionalProperties = {\n ...(metadata.additionalProperties || {}),\n ...additionalSource,\n };\n hasMetadata = true;\n }\n\n for (const [key, value] of Object.entries(source)) {\n if (\n key === 'personalConfidence' ||\n key === 'topic' ||\n key === 'engagement' ||\n key === 'extractedFrom' ||\n key === 'tags' ||\n key === 'additionalProperties'\n ) {\n continue;\n }\n\n if (key === 'vectorMemory') {\n continue;\n }\n\n metadata.additionalProperties = {\n ...(metadata.additionalProperties || {}),\n [key]: value,\n };\n hasMetadata = true;\n }\n }\n\n if (tagsSet.size > 0) {\n metadata.tags = Array.from(tagsSet);\n }\n\n return hasMetadata ? metadata : undefined;\n }\n\n private normalizeMemoryResult(rawInput: unknown): VectorMemory {\n const raw = this.asRecord(rawInput) ?? {};\n const rawMetadata = this.asRecord(raw['metadata']);\n const vectorMetadata = rawMetadata ? this.asRecord(rawMetadata['vectorMemory']) : undefined;\n const vector = vectorMetadata ?? raw;\n const vectorInnerMetadata = this.asRecord(vector['metadata']);\n\n const metadata = this.buildMetadata(vectorInnerMetadata, rawMetadata);\n\n const tagsSet = new Set<string>();\n this.coerceStringArray(vector['tags']).forEach((tag) => tagsSet.add(tag));\n this.coerceStringArray(raw['tags']).forEach((tag) => tagsSet.add(tag));\n metadata?.tags?.forEach((tag) => tagsSet.add(tag));\n\n const scoreCandidates = [\n this.coerceNumber(vector['score']),\n this.coerceNumber(raw['score']),\n ];\n const normalizedScore = scoreCandidates.find((value): value is number => typeof value === 'number');\n\n const pinnedValue =\n this.coerceBoolean(vector['pinned']) ??\n this.coerceBoolean(rawMetadata ? rawMetadata['pinned'] : undefined) ??\n this.coerceBoolean(raw['pinned']);\n\n const lastReferencedAt =\n this.coerceString(vector['lastReferencedAt']) ??\n this.coerceString(rawMetadata ? rawMetadata['lastReferencedAt'] : undefined) ??\n this.coerceString(raw['lastReferencedAt']);\n\n const uploadedAt =\n this.coerceString(vector['uploadedAt']) ??\n this.coerceString(raw['uploadedAt']) ??\n new Date().toISOString();\n\n const sourceValue = this.coerceString(vector['source']) ?? this.coerceString(raw['source']);\n const normalizedSource =\n sourceValue === 'auto' || sourceValue === 'user' ? sourceValue : undefined;\n\n const idValue = this.coerceString(vector['id']) ?? this.coerceString(raw['id']) ?? '';\n const contentValue = this.coerceString(vector['content']) ?? this.coerceString(raw['content']) ?? '';\n const titleValue =\n this.coerceString(vector['title']) ??\n this.coerceString(raw['title']) ??\n this.coerceString(raw['filename']) ??\n undefined;\n const uploadedByValue =\n this.coerceString(vector['uploadedBy']) ??\n this.coerceString(raw['uploadedBy']) ??\n 'unknown';\n\n return {\n id: idValue,\n content: contentValue,\n title: titleValue,\n tags: tagsSet.size > 0 ? Array.from(tagsSet) : undefined,\n score: normalizedScore,\n uploadedBy: uploadedByValue,\n uploadedAt,\n source: normalizedSource,\n pinned: pinnedValue,\n lastReferencedAt,\n metadata,\n };\n }\n /**\n * Search memories in the vector database\n */\n async searchMemories(\n query: string,\n limit = 10,\n scoreThreshold = 0.6,\n filters?: MemorySearchFilters\n ): Promise<VectorMemory[]> {\n if (!this.isAvailable()) {\n return [];\n }\n\n try {\n debugLogger.info('Searching vector memories', { query: query.slice(0, 100), limit, scoreThreshold });\n\n const response = await fetch(`${this.baseUrl}/embedding/search-memories`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n query,\n limit,\n scoreThreshold,\n // Only include filters when provided\n ...(filters ? { filters } : {})\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.message || `Search request failed: ${response.status}`);\n }\n\n const statsHeader = response.headers.get('X-Memory-Stats');\n if (statsHeader) {\n debugLogger.memoryDebug('Vector memory search diagnostics', {\n header: statsHeader\n });\n }\n\n const result = (await response.json()) as MemoryResultsEnvelope;\n \n if (result.success === false) {\n throw new Error(result.message || 'Search was not successful');\n }\n\n const searchResults = Array.isArray(result.results) ? result.results : [];\n const normalizedResults = searchResults.map((entry) =>\n this.normalizeMemoryResult(entry)\n );\n\n debugLogger.info('Vector memory search completed', { \n resultsCount: normalizedResults.length,\n message: result.message \n });\n\n return normalizedResults;\n } catch (error) {\n debugLogger.error('Failed to search vector memories', { \n error: error instanceof Error ? error.message : String(error) \n });\n \n return [];\n }\n }\n\n /**\n * Get user's memories with pagination\n */\n async getMyMemories(skip = 0, limit = 50): Promise<VectorMemory[]> {\n if (!this.isAvailable()) {\n return [];\n }\n\n try {\n const response = await fetch(`${this.baseUrl}/embedding/my-memories?skip=${skip}&limit=${limit}`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch memories: ${response.status}`);\n }\n\n const result = (await response.json()) as MemoryResultsEnvelope;\n debugLogger.debug('Vector getMyMemories API response', result);\n \n // Handle both 'memories' and 'results' response formats for compatibility\n const rawMemories = Array.isArray(result.memories)\n ? result.memories\n : Array.isArray(result.results)\n ? result.results\n : [];\n const memories = rawMemories.map((entry) => this.normalizeMemoryResult(entry));\n\n debugLogger.info('Vector memories fetched successfully', { \n count: memories.length, \n totalCount: result.totalCount,\n responseStructure: Object.keys(result)\n });\n \n return memories;\n } catch (error) {\n debugLogger.error('Failed to fetch user memories', { error });\n return [];\n }\n }\n\n /**\n * Delete a memory from the vector database\n */\n async deleteMemory(memoryId: string): Promise<boolean> {\n if (!this.isAvailable()) {\n return false;\n }\n\n try {\n const response = await fetch(`${this.baseUrl}/embedding/memory/${memoryId}`, {\n method: 'DELETE',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n throw new Error(`Failed to delete memory: ${response.status}`);\n }\n\n const result = await response.json();\n debugLogger.info('Vector memory deleted successfully', { memoryId, result });\n return result.success || true;\n } catch (error) {\n debugLogger.error('Failed to delete vector memory', { memoryId, error });\n return false;\n }\n }\n\n /**\n * Update a memory in the vector database (e.g., pin/unpin)\n */\n async updateMemory(memoryId: string, updates: { pinned?: boolean; content?: string; title?: string; tags?: string[] }): Promise<boolean> {\n if (!this.isAvailable()) {\n return false;\n }\n\n try {\n // Use the specific pin endpoint for pinning operations\n if (updates.pinned !== undefined) {\n const response = await fetch(`${this.baseUrl}/embedding/memory/${memoryId}/pin`, {\n method: 'PUT',\n headers: this.getHeaders(),\n body: JSON.stringify({ pinned: updates.pinned })\n });\n\n if (!response.ok) {\n throw new Error(`Failed to update memory pin status: ${response.status}`);\n }\n\n const result = await response.json();\n debugLogger.info('Vector memory pin status updated successfully', { memoryId, pinned: updates.pinned, result });\n return result.success || true;\n }\n\n // For other updates, we'd need a general update endpoint (not specified in API doc)\n debugLogger.warn('General memory updates not supported yet', { memoryId, updates });\n return false;\n } catch (error) {\n debugLogger.error('Failed to update vector memory', { memoryId, error });\n return false;\n }\n }\n\n /**\n * Batch create memories in the vector database\n */\n async batchCreateMemories(\n memories: Array<{ content: string; title?: string; tags?: string[] }>,\n mode: 'append' | 'replace' | 'smartDedupe' = 'append',\n clearExisting: boolean = false\n ): Promise<{\n success: boolean;\n message: string;\n results: Array<{\n content: string;\n success: boolean;\n memoryId?: string;\n mongoId?: string;\n contentLength?: number;\n message: string;\n action: string;\n }>;\n summary: {\n mode: string;\n totalProcessed: number;\n successCount: number;\n failureCount: number;\n skippedCount: number;\n clearedExistingCount: number;\n clearedExisting: boolean;\n };\n }> {\n if (!this.isAvailable()) {\n throw new Error('Vector database service is not available');\n }\n\n try {\n const requestBody = {\n memories,\n mode,\n clearExisting\n };\n\n debugLogger.info('Batch creating memories', {\n count: memories.length,\n mode,\n clearExisting,\n firstMemoryPreview: memories[0]?.content?.substring(0, 50) || '',\n });\n\n const response = await fetch(`${this.baseUrl}/embedding/batch-embed-memories`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(requestBody)\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.message || `Batch memory creation failed: ${response.status}`);\n }\n\n const result = await response.json();\n \n debugLogger.info('Batch memory creation completed', {\n mode,\n totalMemories: memories.length,\n successCount: result.summary?.successCount || 0,\n failureCount: result.summary?.failureCount || 0\n });\n\n return result;\n } catch (error) {\n debugLogger.error('Failed to batch create memories', { \n error, \n memoriesCount: memories.length,\n mode \n });\n throw error;\n }\n }\n\n /**\n * Advanced batch create memories with chunking and progress reporting\n */\n async batchCreateMemoriesAdvanced(\n memories: Array<{ content: string; title?: string; tags?: string[] }>,\n options: {\n mode?: 'append' | 'replace' | 'smartDedupe';\n clearExisting?: boolean;\n chunkSize?: number;\n onProgress?: (current: number, total: number, message: string) => void;\n validateContent?: boolean;\n } = {}\n ): Promise<{\n success: boolean;\n message: string;\n totalMemories: number;\n successCount: number;\n failureCount: number;\n skippedCount: number;\n errors: string[];\n warnings: string[];\n chunks: number;\n duration: number;\n }> {\n const startTime = Date.now();\n const {\n mode = 'append',\n clearExisting = false,\n chunkSize = 50,\n onProgress,\n validateContent = true\n } = options;\n\n // Import memory utilities\n const { MemoryUtils } = await import('../../utils/memoryUtils');\n\n try {\n // Validate memories if requested\n let validMemories = memories;\n const warnings: string[] = [];\n \n if (validateContent) {\n const validation = MemoryUtils.validateMemories(memories);\n validMemories = validation.valid;\n \n if (validation.invalid.length > 0) {\n warnings.push(`${validation.invalid.length} memories failed validation and were skipped`);\n debugLogger.warn('Some memories failed validation', { \n invalidCount: validation.invalid.length,\n firstError: validation.invalid[0]?.error \n });\n }\n }\n\n if (validMemories.length === 0) {\n return {\n success: false,\n message: 'No valid memories to process',\n totalMemories: memories.length,\n successCount: 0,\n failureCount: 0,\n skippedCount: memories.length,\n errors: ['All memories failed validation'],\n warnings,\n chunks: 0,\n duration: Date.now() - startTime\n };\n }\n\n // Chunk memories for better performance\n const chunks = MemoryUtils.chunkMemories(validMemories, chunkSize);\n let totalSuccessCount = 0;\n let totalFailureCount = 0;\n const errors: string[] = [];\n\n onProgress?.(0, validMemories.length, 'Starting batch operation...');\n\n // Process chunks sequentially to avoid overwhelming the server\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const chunkStartIndex = i * chunkSize;\n \n try {\n onProgress?.(\n chunkStartIndex,\n validMemories.length,\n `Processing chunk ${i + 1}/${chunks.length}...`\n );\n\n const chunkResult = await this.batchCreateMemories(\n chunk,\n i === 0 ? mode : 'append', // Only use special modes on first chunk\n i === 0 ? clearExisting : false // Only clear on first chunk\n );\n\n totalSuccessCount += chunkResult.summary.successCount;\n totalFailureCount += chunkResult.summary.failureCount;\n\n // Collect errors from failed results\n chunkResult.results\n .filter(r => !r.success)\n .forEach(r => errors.push(r.message));\n\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n errors.push(`Chunk ${i + 1} failed: ${errorMsg}`);\n totalFailureCount += chunk.length;\n \n debugLogger.error('Chunk processing failed', { \n chunkIndex: i,\n chunkSize: chunk.length,\n error: errorMsg\n });\n }\n\n // Brief pause between chunks to be respectful to the server\n if (i < chunks.length - 1) {\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n\n const duration = Date.now() - startTime;\n const success = totalFailureCount === 0;\n const skippedCount = memories.length - validMemories.length;\n\n onProgress?.(\n validMemories.length,\n validMemories.length,\n success ? 'Batch operation completed successfully!' : 'Batch operation completed with errors'\n );\n\n const result = {\n success,\n message: `Processed ${totalSuccessCount}/${validMemories.length} memories successfully` + \n (skippedCount > 0 ? ` (${skippedCount} skipped)` : ''),\n totalMemories: memories.length,\n successCount: totalSuccessCount,\n failureCount: totalFailureCount,\n skippedCount,\n errors,\n warnings,\n chunks: chunks.length,\n duration\n };\n\n debugLogger.info('Advanced batch operation completed', result);\n return result;\n\n } catch (error) {\n const duration = Date.now() - startTime;\n const errorMsg = error instanceof Error ? error.message : String(error);\n \n debugLogger.error('Advanced batch operation failed', { \n error: errorMsg,\n memoriesCount: memories.length,\n duration\n });\n\n return {\n success: false,\n message: `Batch operation failed: ${errorMsg}`,\n totalMemories: memories.length,\n successCount: 0,\n failureCount: memories.length,\n skippedCount: 0,\n errors: [errorMsg],\n warnings: [],\n chunks: 0,\n duration\n };\n }\n }\n\n // ===== DOCUMENT OPERATIONS =====\n\n /**\n * Upload file to file storage API and get file ID\n * \n * @param file - The file to upload\n * @param shareWithTeam - Whether to share the file with team members.\n * If true and user has team info, file goes to team bucket.\n * If false, file goes to user's personal bucket.\n * Defaults to true for backward compatibility.\n * @returns Promise<FileUploadResult> with success status and file ID\n */\n async uploadFile(file: File, shareWithTeam = true): Promise<FileUploadResult> {\n if (!this.fileStorageApiUrl) {\n throw new Error('File storage API URL not configured');\n }\n\n if (!this.token) {\n throw new Error('Authentication token not available');\n }\n\n try {\n const formData = new FormData();\n formData.append('file', file);\n formData.append('shareWithTeam', shareWithTeam.toString());\n\n debugLogger.info('Uploading file to file storage API', { \n filename: file.name, \n size: file.size, \n type: file.type,\n shareWithTeam: shareWithTeam,\n fileStorageApiUrl: this.fileStorageApiUrl\n });\n\n const response = await fetch(`${this.fileStorageApiUrl}/file/upload`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.token}`\n },\n body: formData\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.message || `file storage upload failed: ${response.status}`);\n }\n\n const result = await response.json();\n \n // File storage API returns 'id' field, but we need 'fileId'\n const fileId = result.fileId || result.id;\n \n debugLogger.debug('File storage API upload response', result);\n debugLogger.debug('Extracted vector file id', { fileId });\n \n debugLogger.info('File uploaded successfully to file storage', { \n fileId: fileId,\n filename: file.name,\n originalResponse: result\n });\n\n return {\n success: true,\n fileId: fileId,\n message: result.message\n };\n } catch (error) {\n debugLogger.error('Failed to upload file to file storage', { error });\n throw new Error(`File storage upload failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Embed a document in the vector database via Gateway API\n */\n async embedDocument(\n fileId: string, \n shareWithTeam = true\n ): Promise<{ success: boolean; message?: string }> {\n debugLogger.debug('Embedding document request', { fileId, shareWithTeam });\n \n if (!this.baseUrl) {\n debugLogger.error('Gateway API URL not configured', { baseUrl: this.baseUrl });\n throw new Error('Gateway API URL not configured');\n }\n\n if (!this.token) {\n debugLogger.error('Authentication token not available');\n throw new Error('Authentication token not available');\n }\n\n try {\n const endpoint = `${this.baseUrl}/embedding/embed-document`;\n const payload = {\n FileId: fileId,\n Options: null, // EmbeddingOptions - can be null for default options\n ShareWithTeam: shareWithTeam\n };\n \n debugLogger.debug('Making Gateway API call', {\n endpoint,\n method: 'POST',\n payload,\n hasToken: Boolean(this.token),\n tokenPreview: `${this.token.substring(0, 20)}...`,\n });\n\n debugLogger.info('Embedding document via Gateway API', { \n fileId, \n shareWithTeam,\n gatewayUrl: this.baseUrl\n });\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(payload)\n });\n\n debugLogger.debug('Gateway API response headers', {\n status: response.status,\n statusText: response.statusText,\n ok: response.ok,\n headers: Object.fromEntries(response.headers.entries())\n });\n\n // Try to get response text for better error debugging\n let responseText = '';\n let parsedResponse: unknown;\n \n try {\n responseText = await response.text();\n debugLogger.debug('Gateway API raw response text', {\n preview: responseText.substring(0, 500),\n });\n \n if (responseText) {\n parsedResponse = JSON.parse(responseText);\n }\n } catch (parseError) {\n debugLogger.warn('Could not parse Gateway API response as JSON', { error: parseError });\n }\n\n const responseRecord = this.asRecord(parsedResponse);\n const responseMessage = responseRecord && typeof responseRecord['message'] === 'string' ? (responseRecord['message'] as string) : undefined;\n\n if (!response.ok) {\n debugLogger.error('Gateway API error response', {\n status: response.status,\n statusText: response.statusText,\n responseData: responseRecord ?? { rawResponse: responseText },\n endpoint,\n payload\n });\n \n // Check for specific error types\n if (response.status === 404) {\n throw new Error(`Gateway API endpoint not found: ${endpoint}. Check if Gateway API is running and endpoint exists.`);\n } else if (response.status === 401 || response.status === 403) {\n throw new Error(`Authentication failed: ${response.status}. Check if auth token is valid.`);\n } else if (response.status === 500) {\n throw new Error(`Gateway API server error: ${responseMessage || responseText || 'Unknown server error'}`);\n } else {\n throw new Error(responseMessage || responseText || `Gateway embedding failed: ${response.status}`);\n }\n }\n\n debugLogger.debug('Gateway API success response', responseRecord ?? { rawResponse: responseText });\n \n const responseFileId = responseRecord && typeof responseRecord['fileId'] === 'string' ? (responseRecord['fileId'] as string) : undefined;\n\n debugLogger.info('Document embedded successfully via Gateway API', { \n fileId: responseFileId || fileId,\n message: responseMessage \n });\n\n return {\n success: true,\n message: responseMessage || 'Document embedded successfully'\n };\n } catch (error) {\n debugLogger.error('Failed to embed document via Gateway API', { fileId, error });\n \n // Provide more specific error messages\n if (error instanceof TypeError && error.message.includes('fetch')) {\n throw new Error(`Cannot connect to Gateway API at ${this.baseUrl}. Check if Gateway API server is running.`);\n } else {\n throw new Error(`Gateway embedding failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n }\n\n /**\n * Search documents in the vector database\n */\n async searchDocuments(\n query: string, \n limit = 20, \n scoreThreshold = 0.5\n ): Promise<VectorDocument[]> {\n if (!this.isAvailable()) {\n return [];\n }\n\n try {\n debugLogger.info('Searching vector documents', { query: query.slice(0, 100), limit, scoreThreshold });\n\n const response = await fetch(`${this.baseUrl}/embedding/search`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n query,\n limit,\n scoreThreshold\n })\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.message || `Search failed: ${response.status}`);\n }\n\n const result = (await response.json()) as DocumentSearchResponse;\n \n if (result.success === false) {\n throw new Error(result.message || 'Search was not successful');\n }\n\n const documents = Array.isArray(result.results) ? result.results : [];\n\n debugLogger.info('Vector document search completed', { \n resultsCount: documents.length \n });\n\n return documents;\n } catch (error) {\n debugLogger.error('Failed to search vector documents', { error });\n return [];\n }\n }\n\n /**\n * Get available files that haven't been embedded\n */\n async getAvailableFiles(skip = 0, limit = 50): Promise<RawFileRecord[]> {\n if (!this.isAvailable()) {\n return [];\n }\n\n try {\n const response = await fetch(`${this.baseUrl}/embedding/available-files?skip=${skip}&limit=${limit}`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch available files: ${response.status}`);\n }\n\n const result = await response.json();\n if (Array.isArray(result)) {\n return this.toRecordArray(result);\n }\n\n if (result && Array.isArray(result.files)) {\n return this.toRecordArray(result.files);\n }\n\n return [];\n } catch (error) {\n debugLogger.error('Failed to fetch available files', { error });\n return [];\n }\n }\n\n /**\n * One page of the Knowledge file list from the gateway (see ./knowledgeFiles).\n *\n * No fallback to the file storage API here: its listing is the whole Drive (every product's\n * files), which is exactly what Knowledge must not show. A failure surfaces to the caller.\n */\n async listKnowledgeFiles(\n skip = 0,\n limit = 50,\n scope: KnowledgeFileScope = 'knowledge'\n ): Promise<KnowledgeFilePage> {\n if (!this.isAvailable()) {\n return parseKnowledgeFileList([], { skip, limit, scope });\n }\n\n const safeSkip = Math.max(0, Math.floor(skip));\n const safeLimit = Math.min(KNOWLEDGE_PAGE_LIMIT_MAX, Math.max(1, Math.floor(limit)));\n const query = new URLSearchParams({\n skip: String(safeSkip),\n limit: String(safeLimit),\n scope,\n });\n\n debugLogger.debug('Fetching knowledge files from Gateway API', { skip: safeSkip, limit: safeLimit, scope });\n const response = await fetch(`${this.baseUrl}/embedding/files?${query.toString()}`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n throw new Error(`Couldn't list documents (gateway answered ${response.status})`);\n }\n\n const body: unknown = await response.json();\n return parseKnowledgeFileList(body, { skip: safeSkip, limit: safeLimit, scope });\n }\n\n /**\n * Get the user's Knowledge files (first page, knowledge scope). Kept for existing callers;\n * prefer listKnowledgeFiles for totals and paging.\n */\n async getUserFiles(skip = 0, limit = 50): Promise<RawFileRecord[]> {\n try {\n const page = await this.listKnowledgeFiles(skip, limit, 'knowledge');\n return page.files;\n } catch (error) {\n debugLogger.error('Failed to fetch knowledge files from Gateway API', { error });\n return [];\n }\n }\n\n /**\n * Get user's files from file storage API as fallback\n */\n private async getUserFilesFromFileStorage(skip = 0, limit = 50): Promise<RawFileRecord[]> {\n try {\n debugLogger.debug('Fetching user files from file storage API', { skip, limit });\n const response = await fetch(`${this.fileStorageApiUrl}/file/files?skip=${skip}&limit=${limit}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.token}`,\n 'Content-Type': 'application/json'\n }\n });\n\n if (!response.ok) {\n throw new Error(`File storage API failed: ${response.status}`);\n }\n\n const result = await response.json();\n debugLogger.debug('File storage API files response', result);\n \n if (Array.isArray(result)) {\n return this.toRecordArray(result);\n }\n\n if (result && Array.isArray(result.files)) {\n return this.toRecordArray(result.files);\n }\n\n return [];\n } catch (error) {\n debugLogger.error('Failed to fetch user files from file storage API', { error });\n return [];\n }\n }\n\n /**\n * Download a file using MongoDB ObjectId (secure method)\n */\n async downloadFile(fileId: string, filename: string): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('Vector database service not available');\n }\n\n try {\n debugLogger.debug('Downloading vector file', { fileId, filename });\n \n // Download from file storage API using MongoDB ObjectId (correct file storage API format)\n const response = await fetch(`${this.fileStorageApiUrl}/file/download/${fileId}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.token}`\n }\n });\n\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n // Get the file as a blob\n const blob = await response.blob();\n \n // Create download link\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n \n // Clean up the blob URL\n URL.revokeObjectURL(url);\n \n debugLogger.info('Vector file downloaded successfully', { fileId, filename });\n \n } catch (error) {\n debugLogger.error('Failed to download vector file', { fileId, filename, error });\n throw new Error(`Failed to download ${filename}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Get file blob using MongoDB ObjectId (for displaying content in modal)\n */\n async getFileBlob(fileId: string): Promise<Blob> {\n if (!this.isAvailable()) {\n throw new Error('Vector database service not available');\n }\n\n try {\n debugLogger.debug('Fetching vector file blob', { fileId });\n \n // Get file from file storage API using MongoDB ObjectId\n const response = await fetch(`${this.fileStorageApiUrl}/file/download/${fileId}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.token}`\n }\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get file: ${response.status} ${response.statusText}`);\n }\n\n const blob = await response.blob();\n debugLogger.info('Successfully retrieved vector file blob', { fileId, size: blob.size });\n \n return blob;\n \n } catch (error) {\n debugLogger.error('Failed to get file blob', { fileId, error });\n throw new Error(`Failed to get file: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Get file content for preview using MongoDB ObjectId (from Gateway API metadata)\n */\n async getFilePreview(fileId: string, maxSize = 1024 * 1024): Promise<{ content: string; mimeType: string } | null> {\n if (!this.isAvailable()) {\n return null;\n }\n\n try {\n debugLogger.debug('Fetching vector file preview', { fileId });\n \n // Get file metadata from Gateway API which includes the preview content\n const response = await fetch(`${this.baseUrl}/embedding/files`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n debugLogger.warn('Failed to retrieve files list before preview', { status: response.status });\n return null;\n }\n\n const filesResponse = await response.json();\n const fileCandidates = Array.isArray(filesResponse)\n ? this.toRecordArray(filesResponse)\n : filesResponse && Array.isArray(filesResponse.files)\n ? this.toRecordArray(filesResponse.files)\n : [];\n \n const targetFile = fileCandidates.find((file) => this.coerceString(file['id']) === fileId);\n const previewContent = targetFile ? this.coerceString(targetFile['preview']) : undefined;\n const mimeType = targetFile ? this.coerceString(targetFile['mimeType']) : undefined;\n \n if (!previewContent) {\n debugLogger.warn('Preview not available for file', { fileId });\n return null;\n }\n\n return {\n content: previewContent,\n mimeType: mimeType || 'text/plain'\n };\n \n } catch (error) {\n debugLogger.error('Failed to get file preview', { fileId, error });\n return null;\n }\n }\n\n /**\n * Delete a document from vector database\n */\n async deleteDocument(fileId: string): Promise<boolean> {\n if (!this.isAvailable()) {\n return false;\n }\n\n try {\n const response = await fetch(`${this.baseUrl}/embedding/${fileId}`, {\n method: 'DELETE',\n headers: this.getHeaders()\n });\n\n if (!response.ok) {\n throw new Error(`Failed to delete document: ${response.status}`);\n }\n\n debugLogger.info('Vector document deleted successfully', { fileId });\n return true;\n } catch (error) {\n debugLogger.error('Failed to delete vector document', { fileId, error });\n return false;\n }\n }\n\n // ===== COMBINED SEARCH =====\n\n /**\n * Search both memories and documents simultaneously\n */\n async searchAll(\n query: string,\n memoryLimit = 10,\n documentLimit = 20,\n scoreThreshold = 0.6\n ): Promise<SearchResult> {\n if (!this.isAvailable()) {\n return {\n memories: [],\n documents: [],\n success: false,\n message: 'Vector database service not available'\n };\n }\n\n try {\n const [memories, documents] = await Promise.all([\n this.searchMemories(query, memoryLimit, scoreThreshold),\n this.searchDocuments(query, documentLimit, scoreThreshold)\n ]);\n\n return {\n memories,\n documents,\n success: true,\n message: `Found ${memories.length} memories and ${documents.length} documents`\n };\n } catch (error) {\n debugLogger.error('Failed to search all content', { error });\n return {\n memories: [],\n documents: [],\n success: false,\n message: error instanceof Error ? error.message : 'Search failed'\n };\n }\n }\n /**\n * Configure the service with API URLs\n * This should be called by the main application with environment variables\n */\n configure(gatewayApiUrl: string, fileStorageApiUrl: string) {\n this.baseUrl = gatewayApiUrl;\n this.fileStorageApiUrl = fileStorageApiUrl;\n \n // Only log configuration changes, not repetitive calls\n if (this.lastConfigState !== `${gatewayApiUrl}|${fileStorageApiUrl}`) {\n debugLogger.info('Vector database service configured', {\n baseUrl: this.baseUrl,\n fileStorageApiUrl: this.fileStorageApiUrl,\n hasToken: Boolean(this.token),\n });\n this.lastConfigState = `${gatewayApiUrl}|${fileStorageApiUrl}`;\n }\n }\n\n /**\n * Manual debug function to test Gateway API connection\n * Call this from browser console to debug API issues\n */\n async debugTestConnection(): Promise<void> {\n debugLogger.info('Testing Gateway API connection');\n debugLogger.info('Vector service status snapshot', {\n baseUrl: this.baseUrl,\n fileStorageApiUrl: this.fileStorageApiUrl,\n hasToken: Boolean(this.token),\n tokenLength: this.token?.length || 0,\n tokenPreview: this.token ? `${this.token.substring(0, 30)}...` : undefined,\n isAvailable: this.isAvailable()\n });\n\n // Test basic connectivity\n try {\n debugLogger.debug('Testing basic connectivity to Gateway API');\n const response = await fetch(`${this.baseUrl}/health`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n debugLogger.debug('Gateway API health check response', {\n status: response.status,\n statusText: response.statusText,\n ok: response.ok\n });\n\n if (response.ok) {\n const result = await response.text();\n debugLogger.info('Gateway API is reachable', { result });\n } else {\n debugLogger.warn('Gateway API health check failed');\n }\n } catch (error) {\n debugLogger.error('Cannot reach Gateway API', { error });\n }\n\n // Test file storage API connectivity\n try {\n debugLogger.debug('Testing file storage API connectivity');\n const files = await this.getUserFilesFromFileStorage(0, 5);\n debugLogger.info('File storage API files response', {\n count: files.length,\n files: files.slice(0, 3) // Show first 3 files\n });\n } catch (error) {\n debugLogger.error('File storage API test failed', { error });\n }\n\n // Test embedding endpoint specifically\n try {\n debugLogger.debug('Testing embedding endpoint availability');\n const testResponse = await fetch(`${this.baseUrl}/embedding/available-files?limit=1`, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n debugLogger.debug('Embedding endpoint response', {\n status: testResponse.status,\n ok: testResponse.ok,\n statusText: testResponse.statusText\n });\n\n if (testResponse.ok) {\n const result = await testResponse.json();\n debugLogger.info('Embedding endpoint is available', { result });\n }\n } catch (error) {\n debugLogger.error('Embedding endpoint test failed', { error });\n }\n }\n\n /**\n * Test embedding a specific file ID that you know exists\n */\n async debugTestEmbedding(fileId: string): Promise<void> {\n debugLogger.info('Testing embedding for file', { fileId });\n \n try {\n const result = await this.embedDocument(fileId, true);\n debugLogger.info('Embedding test result', result);\n } catch (error) {\n debugLogger.error('Embedding test failed', { error });\n }\n }\n}\n\n// Export singleton instance\nexport const vectorDatabaseService = new VectorDatabaseService();\n\n// Expose to global scope for debugging in development\nif (typeof window !== 'undefined') {\n const globalWindow = window as Window & { vectorDatabaseService?: VectorDatabaseService };\n globalWindow.vectorDatabaseService = vectorDatabaseService;\n debugLogger.info('Vector database service exposed globally for debugging');\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n/**\n * Knowledge file listing (GET {gateway}/embedding/files).\n *\n * The gateway's file store is shared with every Burtson Labs product that keeps files in the\n * account: Drive uploads, attachments pulled out of email (Outlook's image001.png, Word's\n * ~WRD0548.jpg), app assets, Image Studio output. Knowledge should show only the documents that\n * are indexed for Knowledge search.\n *\n * Current gateways scope the list on the server (`scope=knowledge`, the default: files with a\n * vector in the documents index) and answer with a paged envelope:\n * { files, total, skip, limit, hasMore, scope, knowledgeFilterUnavailable }\n * Older gateways answer with a bare array of every file. For those, `knowledge` scope falls back\n * to a client-side filter that drops images, media and temporary files (Knowledge uploads only\n * accept documents, code and data), and the page reports how many it hid so the UI can offer\n * \"All workspace files\".\n */\n\nexport type KnowledgeFileScope = 'knowledge' | 'all';\n\nexport type RawFileRecord = Record<string, unknown>;\n\nexport interface KnowledgeFilePage {\n files: RawFileRecord[];\n /** Files matching the scope in total (server count), or the filtered count of this page on old gateways. */\n total: number;\n hasMore: boolean;\n /** The scope the listing actually has. */\n scope: KnowledgeFileScope;\n /** The server applied the scope (current gateway). False: old gateway, client-side filter. */\n serverScoped: boolean;\n /** Knowledge was asked for but the index couldn't be checked, so this is every workspace file. */\n knowledgeFilterUnavailable: boolean;\n /** Files hidden by the client-side filter on this page (old gateways only). */\n hiddenCount: number;\n}\n\n/** Largest page the gateway serves; asking for more is clamped there. */\nexport const KNOWLEDGE_PAGE_LIMIT_MAX = 200;\n\nconst MEDIA_MIME_PREFIXES = ['image/', 'video/', 'audio/'];\n\nconst MEDIA_EXTENSIONS = new Set([\n 'png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tif', 'tiff', 'heic', 'heif', 'svg', 'ico', 'avif',\n 'mp4', 'mov', 'm4v', 'webm', 'avi', 'mkv',\n 'mp3', 'wav', 'm4a', 'aac', 'ogg', 'flac',\n]);\n\n/** Temporary/lock files Office and email clients leave behind (~WRD0548.jpg, ~$report.docx, .tmp). */\nconst TEMP_NAME = /^(~WRD\\d*|~\\$|~\\w+\\.tmp$)|\\.tmp$/i;\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value : '');\n\nconst recordName = (record: RawFileRecord): string =>\n str(record.filename) || str(record.fileName) || str(record.name);\n\nconst recordMime = (record: RawFileRecord): string =>\n (str(record.mimeType) || str(record.contentType) || str(record.type)).toLowerCase();\n\n/**\n * Heuristic used only against old gateways that can't scope the list: is this a document that\n * plausibly came through Knowledge rather than Drive, email or an app?\n */\nexport const isLikelyKnowledgeFile = (record: RawFileRecord): boolean => {\n const name = recordName(record);\n if (TEMP_NAME.test(name)) return false;\n\n const ext = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n if (MEDIA_EXTENSIONS.has(ext)) return false;\n\n const mime = recordMime(record);\n if (MEDIA_MIME_PREFIXES.some((prefix) => mime.startsWith(prefix))) return false;\n\n return true;\n};\n\nconst toRecords = (value: unknown): RawFileRecord[] =>\n Array.isArray(value)\n ? value.filter((item): item is RawFileRecord => !!item && typeof item === 'object' && !Array.isArray(item))\n : [];\n\nconst num = (value: unknown, fallback: number): number =>\n typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n\n/** Turn a /embedding/files response body into one page, whichever gateway version answered. */\nexport const parseKnowledgeFileList = (\n body: unknown,\n request: { skip: number; limit: number; scope: KnowledgeFileScope },\n): KnowledgeFilePage => {\n // Current gateway: paged envelope with a server-side scope.\n if (body && typeof body === 'object' && !Array.isArray(body) && 'total' in body) {\n const envelope = body as Record<string, unknown>;\n const files = toRecords(envelope.files);\n const total = num(envelope.total, files.length);\n const skip = num(envelope.skip, request.skip);\n const scope: KnowledgeFileScope = envelope.scope === 'all' ? 'all' : 'knowledge';\n return {\n files,\n total,\n hasMore: typeof envelope.hasMore === 'boolean' ? envelope.hasMore : skip + files.length < total,\n scope,\n serverScoped: true,\n knowledgeFilterUnavailable: envelope.knowledgeFilterUnavailable === true,\n hiddenCount: 0,\n };\n }\n\n // Old gateway: every file, unscoped ({ files } without a total, or a bare array).\n const raw =\n body && typeof body === 'object' && !Array.isArray(body)\n ? toRecords((body as Record<string, unknown>).files)\n : toRecords(body);\n const hasMore = raw.length >= request.limit;\n\n if (request.scope === 'all') {\n return {\n files: raw,\n total: request.skip + raw.length,\n hasMore,\n scope: 'all',\n serverScoped: false,\n knowledgeFilterUnavailable: false,\n hiddenCount: 0,\n };\n }\n\n const files = raw.filter(isLikelyKnowledgeFile);\n return {\n files,\n total: files.length,\n hasMore,\n scope: 'knowledge',\n serverScoped: false,\n knowledgeFilterUnavailable: false,\n hiddenCount: raw.length - files.length,\n };\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { debugLogger } from '../services/logging/debugLogger';\nimport { vectorDatabaseService, type VectorMemoryMetadata, type VectorMemory, type MemorySearchFilters, type VectorDocument, type SearchResult } from '../services/vectorDatabase/vectorDatabaseService';\nimport { vectorMigrationService, MigrationStatus, MigrationProgress } from '../services/vectorDatabase/vectorMigrationService';\nimport type { KnowledgeFilePage, KnowledgeFileScope } from '../services/vectorDatabase/knowledgeFiles';\nimport { useMemoryStore } from '../store/memoryStore';\nimport type { MemoryEntry } from '../store/memoryStore';\nimport { useKnowledgeStore } from '../store/knowledgeStore';\nimport type { KnowledgeDoc } from '../store/knowledgeStore';\nimport { useAuthenticationStore } from '../store/authenticationStore';\nimport { usePackageSettingsStore } from '../store/packageSettingsStore';\nimport { useFeatures } from './useFeatures';\nimport { useConversationSyncStore } from '../store/conversationSyncStore';\n\nexport interface VectorStoreStatus {\n isEnabled: boolean;\n isAvailable: boolean;\n isMigrating: boolean;\n migrationRequired: boolean;\n migrationProgress?: MigrationProgress;\n lastError?: string;\n}\n\nexport interface SearchOptions {\n memoryLimit?: number;\n documentLimit?: number;\n scoreThreshold?: number;\n useVector?: boolean; // Override auto-detection\n filters?: MemorySearchFilters;\n}\n\nconst toIsoString = (timestamp: number | Date): string => {\n if (timestamp instanceof Date) {\n return timestamp.toISOString();\n }\n return new Date(timestamp).toISOString();\n};\n\nconst memoryEntryToVectorMemory = (entry: MemoryEntry): VectorMemory => ({\n id: entry.id,\n content: entry.content,\n tags: entry.tags,\n score: undefined,\n uploadedBy: 'local',\n uploadedAt: toIsoString(entry.timestamp),\n source: entry.source,\n pinned: entry.pinned,\n lastReferencedAt: toIsoString(entry.timestamp),\n metadata: undefined,\n});\n\nconst knowledgeDocToVectorDocument = (doc: KnowledgeDoc): VectorDocument => ({\n id: doc.id,\n filename: doc.name,\n content: doc.content,\n mimeType: doc.mimeType || 'application/octet-stream',\n score: undefined,\n uploadedBy: doc.uploadedBy || 'local',\n uploadedAt: doc.addedDate ? doc.addedDate.toISOString() : new Date().toISOString(),\n isUserContent: doc.isUserContent ?? true,\n isTeamContent: doc.isTeamContent ?? false,\n contentSource: doc.contentSource ?? (doc.isTeamContent ? 'team' : 'user'),\n});\n\ntype RawFileRecord = Record<string, unknown>;\n\nconst optionalString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined;\n\nexport const rawFileRecordToVectorDocument = (record: RawFileRecord): VectorDocument | null => {\n if (!record || typeof record !== 'object') {\n return null;\n }\n\n const id = typeof record.id === 'string'\n ? record.id\n : typeof record.fileId === 'string'\n ? record.fileId\n : undefined;\n\n if (!id) {\n return null;\n }\n\n const filename = typeof record.filename === 'string'\n ? record.filename\n : typeof record.fileName === 'string'\n ? record.fileName\n : 'Untitled Document';\n\n const preview = typeof record.preview === 'string'\n ? record.preview\n : typeof record.summary === 'string'\n ? record.summary\n : typeof record.snippet === 'string'\n ? record.snippet\n : undefined;\n\n const content = typeof record.content === 'string' && record.content.trim().length > 0\n ? record.content\n : preview ?? '';\n const mimeType = typeof record.mimeType === 'string' ? record.mimeType : 'application/octet-stream';\n const uploadedBy = typeof record.uploadedBy === 'string' ? record.uploadedBy : 'unknown';\n const uploadedAt = typeof record.uploadedAt === 'string' ? record.uploadedAt : new Date().toISOString();\n const teamSid = optionalString(record.teamSid);\n // The gateway listing carries teamSid rather than explicit flags: a team id means team content.\n const isTeamContent = typeof record.isTeamContent === 'boolean' ? record.isTeamContent : !!teamSid;\n const isUserContent = typeof record.isUserContent === 'boolean' ? record.isUserContent : !isTeamContent;\n const contentSource = record.contentSource === 'team' || (record.contentSource === undefined && isTeamContent)\n ? 'team'\n : 'user';\n const score = typeof record.score === 'number' ? record.score : undefined;\n const size = typeof record.size === 'number' && Number.isFinite(record.size) && record.size >= 0\n ? record.size\n : undefined;\n\n return {\n id,\n filename,\n content,\n mimeType,\n uploadedBy,\n uploadedAt,\n isUserContent,\n isTeamContent,\n contentSource,\n score,\n size,\n bucket: optionalString(record.bucket),\n teamSid,\n userEmail: optionalString(record.userEmail),\n preview,\n };\n};\n\n/** One page of Knowledge documents, ready for the Knowledge view. */\nexport interface KnowledgeDocumentPage extends Omit<KnowledgeFilePage, 'files'> {\n documents: VectorDocument[];\n}\n\n/**\n * Advanced Vector Storage Hook\n * \n * Manages the transition between IndexedDB and Vector Database storage\n * when advanced semantic search is enabled. Handles feature gating,\n * migration, and unified API for both storage backends.\n * \n * Features:\n * - Automatic migration when advanced search is first enabled\n * - Unified API that works with both IndexedDB and Vector DB\n * - Feature gating based on subscription tier and admin claims\n * - Progress tracking for migration operations\n * - Fallback to IndexedDB if vector service unavailable\n */\nexport const useVectorStore = () => {\n const [status, setStatus] = useState<VectorStoreStatus>({\n isEnabled: false,\n isAvailable: false,\n isMigrating: false,\n migrationRequired: false\n });\n\n // Store access\n const memoryStore = useMemoryStore();\n const knowledgeStore = useKnowledgeStore();\n const authStore = useAuthenticationStore();\n const features = useFeatures();\n const isAdvancedVectorFeaturesEnabled = useConversationSyncStore((state) => state.isAdvancedVectorFeaturesEnabled);\n\n const hasAnyAdvancedFeatures = isAdvancedVectorFeaturesEnabled;\n const hasVectorAccess = features.isAdmin() || features.hasAdvancedSearch() || features.hasAdvancedMemories();\n\n // Check if using compatible AI provider (Ollama or Gateway with Ollama)\n const [hasCompatibleProvider, setHasCompatibleProvider] = useState(false);\n\n // checkProviderCompatibility awaits a dynamic import, so a call in flight\n // when the hook unmounts must not setState into a torn-down tree (vitest\n // reports that as an unhandled error after the suite has passed).\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const checkProviderCompatibility = useCallback(async () => {\n try {\n const { useAIProviderStore } = await import('../store/aiProviderStore');\n if (!mountedRef.current) return false;\n const aiProviderState = useAIProviderStore.getState();\n const provider = aiProviderState.provider;\n const config = aiProviderState.config;\n \n if (!provider || !config) {\n setHasCompatibleProvider(false);\n return false;\n }\n\n // Allow both native Ollama and Bandit gateway providers to access vector storage\n const vectorCapableProviders = new Set(['ollama', 'bandit']);\n const isNativeOllama = config.type === 'ollama';\n const hasVectorCapableProvider = typeof config.provider === 'string' && vectorCapableProviders.has(config.provider);\n const isGatewayWithVectorSupport = config.type === 'gateway' && hasVectorCapableProvider;\n const isCompatible = isNativeOllama || isGatewayWithVectorSupport;\n \n setHasCompatibleProvider(isCompatible);\n return isCompatible;\n } catch (error) {\n debugLogger.warn('Could not check AI provider for vector compatibility', { error });\n if (mountedRef.current) setHasCompatibleProvider(false);\n return false;\n }\n }, []);\n\n // Check provider compatibility on mount and when dependencies change\n useEffect(() => {\n checkProviderCompatibility();\n }, [checkProviderCompatibility]);\n\n // Also check when AI provider store changes. The small delay lets the\n // provider store settle; it is cleared on unmount so the check can't fire\n // after the component is gone.\n useEffect(() => {\n const timer = setTimeout(() => {\n void checkProviderCompatibility();\n }, 100);\n return () => clearTimeout(timer);\n }, [authStore.token, checkProviderCompatibility]); // Re-check when auth token changes (which affects provider initialization)\n\n // Force a periodic check to catch late provider initialization\n useEffect(() => {\n const interval = setInterval(() => {\n if (!hasCompatibleProvider) {\n checkProviderCompatibility();\n }\n }, 2000); // Check every 2 seconds if not compatible\n\n return () => clearInterval(interval);\n }, [hasCompatibleProvider, checkProviderCompatibility]);\n\n /**\n * Initialize vector database service with auth token\n */\n const initializeVectorService = useCallback(async () => {\n try {\n // Get configuration from package settings instead of direct environment access\n const packageSettings = usePackageSettingsStore.getState().getSettings();\n \n if (!packageSettings) {\n debugLogger.warn('Package settings not available for vector service initialization');\n return;\n }\n \n const gatewayApiUrl = packageSettings.gatewayApiUrl;\n const fileStorageApiUrl = packageSettings.fileStorageApiUrl || packageSettings.gatewayApiUrl; // Fallback to gateway URL if file storage API not specified\n \n vectorDatabaseService.configure(gatewayApiUrl, fileStorageApiUrl);\n\n if (authStore.token) {\n vectorDatabaseService.setAuthToken(authStore.token);\n }\n\n const isAvailable = vectorDatabaseService.isAvailable();\n const enabledCondition = hasAnyAdvancedFeatures && hasVectorAccess && isAvailable && hasCompatibleProvider;\n \n setStatus(prev => ({\n ...prev,\n isAvailable,\n isEnabled: enabledCondition,\n migrationRequired: isAvailable && enabledCondition && !vectorMigrationService.isMigrationCompleted()\n }));\n\n debugLogger.info('Vector service initialized', {\n isAvailable,\n isAdvancedVectorFeaturesEnabled,\n hasVectorAccess,\n migrationRequired: !vectorMigrationService.isMigrationCompleted()\n });\n\n } catch (error) {\n debugLogger.error('Failed to initialize vector service', { error });\n setStatus(prev => ({\n ...prev,\n isAvailable: false,\n isEnabled: false,\n lastError: error instanceof Error ? error.message : String(error)\n }));\n }\n }, [authStore.token, hasAnyAdvancedFeatures, hasVectorAccess, hasCompatibleProvider, isAdvancedVectorFeaturesEnabled]);\n\n // Initialize vector service when dependencies change\n useEffect(() => {\n initializeVectorService();\n }, [initializeVectorService]);\n\n /**\n * Perform migration from IndexedDB to Vector Database\n */\n const performMigration = useCallback(async (options?: { cleanupAfterMigration?: boolean }): Promise<MigrationStatus> => {\n debugLogger.info('Starting vector database migration');\n \n setStatus(prev => ({ ...prev, isMigrating: true, lastError: undefined }));\n\n // Set up progress tracking\n const progressCallback = (progress: MigrationProgress) => {\n setStatus(prev => ({ ...prev, migrationProgress: progress }));\n };\n\n vectorMigrationService.onProgress(progressCallback);\n\n try {\n const result = await vectorMigrationService.performMigration(options);\n \n setStatus(prev => ({\n ...prev,\n isMigrating: false,\n migrationRequired: !result.success,\n migrationProgress: undefined,\n lastError: result.success ? undefined : result.errors.join('; ')\n }));\n\n if (result.success) {\n debugLogger.info('Vector migration completed successfully', result);\n // Refresh stores to ensure they're updated\n await memoryStore.hydrate();\n await knowledgeStore.loadDocs();\n } else {\n debugLogger.error('Vector migration failed', result);\n }\n\n return result;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n debugLogger.error('Migration failed with exception', { error: errorMsg });\n \n setStatus(prev => ({\n ...prev,\n isMigrating: false,\n lastError: errorMsg\n }));\n\n return {\n success: false,\n migratedMemories: 0,\n migratedDocuments: 0,\n errors: [errorMsg],\n warnings: [],\n totalTime: 0\n };\n } finally {\n vectorMigrationService.removeProgressCallback(progressCallback);\n }\n }, [memoryStore, knowledgeStore]);\n\n /**\n * Add a memory using the appropriate storage backend\n */\n const addMemory = useCallback(async (\n content: string,\n tags: string[] = [],\n source: 'auto' | 'user' = 'user',\n options: {\n metadata?: VectorMemoryMetadata;\n pinned?: boolean;\n title?: string;\n lastReferencedAt?: string;\n } = {}\n ): Promise<{ success: boolean; id?: string; error?: string }> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database\n try {\n const result = await vectorDatabaseService.createMemory(\n content,\n {\n title: options.title ?? `Memory from ${new Date().toLocaleDateString()}`,\n tags,\n source,\n pinned: options.pinned,\n metadata: options.metadata,\n lastReferencedAt: options.lastReferencedAt,\n }\n );\n \n if (result.success) {\n debugLogger.info('Memory added to vector database', { memoryId: result.memoryId });\n return { success: true, id: result.memoryId };\n } else {\n throw new Error(result.message || 'Unknown error');\n }\n } catch (error) {\n debugLogger.error('Failed to add memory to vector database', { error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n } else {\n // Use IndexedDB fallback\n try {\n await memoryStore.addMemory(content, tags, source);\n debugLogger.info('Memory added to IndexedDB', { content: content.slice(0, 100) });\n return { success: true };\n } catch (error) {\n debugLogger.error('Failed to add memory to IndexedDB', { error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n }\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Search memories using the appropriate backend\n */\n const searchMemories = useCallback(async (\n query: string,\n options: SearchOptions = {}\n ): Promise<VectorMemory[]> => {\n const { \n memoryLimit = 10, \n scoreThreshold = 0.6, \n useVector = status.isEnabled && !status.migrationRequired \n } = options;\n\n if (useVector) {\n // Use vector database search\n try {\n const results = await vectorDatabaseService.searchMemories(query, memoryLimit, scoreThreshold, options.filters);\n debugLogger.info('Vector memory search completed', { \n query: query.slice(0, 50), \n resultsCount: results.length \n });\n return results;\n } catch (error) {\n debugLogger.error('Vector memory search failed, falling back to IndexedDB', { error });\n // Fall through to IndexedDB search\n }\n }\n\n // Use IndexedDB search\n const results = memoryStore.searchMemory(query);\n debugLogger.info('IndexedDB memory search completed', { \n query: query.slice(0, 50), \n resultsCount: results.length \n });\n\n return results.slice(0, memoryLimit).map((entry) => ({\n id: entry.id,\n content: entry.content,\n title: undefined,\n tags: entry.tags,\n score: undefined,\n uploadedBy: 'local',\n uploadedAt: new Date(entry.timestamp).toISOString(),\n source: entry.source,\n pinned: entry.pinned,\n lastReferencedAt: new Date(entry.timestamp).toISOString(),\n metadata: undefined,\n }));\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Get user's memories with pagination\n */\n const getUserMemories = useCallback(async (\n skip = 0, \n limit = 50\n ): Promise<VectorMemory[]> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database\n try {\n const results = await vectorDatabaseService.getMyMemories(skip, limit);\n debugLogger.info('Vector memories retrieved', { count: results.length });\n return results;\n } catch (error) {\n debugLogger.error('Failed to get vector memories, falling back to IndexedDB', { error });\n // Fall through to IndexedDB\n }\n }\n\n // Use IndexedDB fallback\n await memoryStore.hydrate();\n const allEntries = memoryStore.entries;\n const paginatedEntries = allEntries.slice(skip, skip + limit);\n debugLogger.info('IndexedDB memories retrieved', { count: paginatedEntries.length });\n return paginatedEntries.map(memoryEntryToVectorMemory);\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Delete a memory\n */\n const deleteMemory = useCallback(async (\n memoryId: string\n ): Promise<{ success: boolean; error?: string }> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database\n try {\n const success = await vectorDatabaseService.deleteMemory(memoryId);\n if (success) {\n debugLogger.info('Memory deleted from vector database', { memoryId });\n return { success: true };\n } else {\n throw new Error('Vector deletion failed');\n }\n } catch (error) {\n debugLogger.error('Failed to delete vector memory', { memoryId, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n } else {\n // Use IndexedDB fallback\n try {\n await memoryStore.removeMemory(memoryId);\n debugLogger.info('Memory deleted from IndexedDB', { memoryId });\n return { success: true };\n } catch (error) {\n debugLogger.error('Failed to delete IndexedDB memory', { memoryId, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n }\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Update a memory using the appropriate storage backend\n */\n const updateMemory = useCallback(async (\n memoryId: string,\n updates: { pinned?: boolean; content?: string; title?: string; tags?: string[] }\n ): Promise<{ success: boolean; error?: string }> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database\n try {\n const success = await vectorDatabaseService.updateMemory(memoryId, updates);\n if (success) {\n debugLogger.info('Memory updated in vector database', { memoryId, updates });\n return { success: true };\n } else {\n throw new Error('Vector update failed');\n }\n } catch (error) {\n debugLogger.error('Failed to update vector memory', { memoryId, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n } else {\n // Use IndexedDB fallback - for pinning\n if (updates.pinned !== undefined) {\n try {\n await memoryStore.togglePinMemory(memoryId);\n debugLogger.info('Memory pin status updated in IndexedDB', { memoryId });\n return { success: true };\n } catch (error) {\n debugLogger.error('Failed to update IndexedDB memory pin', { memoryId, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n }\n return { success: false, error: 'Update not supported for IndexedDB' };\n }\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Batch create memories using the appropriate storage backend\n */\n const batchCreateMemories = useCallback(async (\n memories: Array<{ content: string; title?: string; tags?: string[] }>,\n mode: 'append' | 'replace' | 'smartDedupe' = 'append',\n clearExisting: boolean = false\n ): Promise<{\n success: boolean;\n message: string;\n results: Array<{\n content: string;\n success: boolean;\n memoryId?: string;\n mongoId?: string;\n contentLength?: number;\n message: string;\n action: string;\n }>;\n summary: {\n mode: string;\n totalProcessed: number;\n successCount: number;\n failureCount: number;\n skippedCount: number;\n clearedExistingCount: number;\n clearedExisting: boolean;\n };\n }> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database\n try {\n const result = await vectorDatabaseService.batchCreateMemories(memories, mode, clearExisting);\n debugLogger.info('Batch memories created in vector database', { \n total: memories.length,\n successful: result.summary.successCount,\n mode \n });\n return result;\n } catch (error) {\n debugLogger.error('Failed to batch create vector memories', { error });\n throw error;\n }\n } else {\n // Use IndexedDB fallback - simulate batch response\n const results: Array<{\n content: string;\n success: boolean;\n memoryId?: string;\n mongoId?: string;\n contentLength?: number;\n message: string;\n action: string;\n }> = [];\n\n let successCount = 0;\n let failureCount = 0;\n\n // Handle clear existing for replace mode\n if (mode === 'replace' || clearExisting) {\n try {\n await memoryStore.clearMemories();\n debugLogger.info('Cleared existing IndexedDB memories for batch replace');\n } catch (error) {\n debugLogger.error('Failed to clear existing memories', { error });\n }\n }\n\n // Add each memory to IndexedDB\n for (const memory of memories) {\n try {\n await memoryStore.addMemory(memory.content, memory.tags || [], 'user');\n results.push({\n content: memory.content.substring(0, 100) + '...',\n success: true,\n contentLength: memory.content.length,\n message: 'Memory added successfully to IndexedDB',\n action: 'added'\n });\n successCount++;\n } catch (error) {\n results.push({\n content: memory.content.substring(0, 100) + '...',\n success: false,\n message: error instanceof Error ? error.message : String(error),\n action: 'failed'\n });\n failureCount++;\n }\n }\n\n debugLogger.info('Batch memories created in IndexedDB', { \n total: memories.length,\n successful: successCount,\n failed: failureCount,\n mode \n });\n\n return {\n success: failureCount === 0,\n message: `Batch processing completed. ${successCount}/${memories.length} memories added successfully (IndexedDB fallback).`,\n results,\n summary: {\n mode: mode.charAt(0).toUpperCase() + mode.slice(1),\n totalProcessed: memories.length,\n successCount,\n failureCount,\n skippedCount: 0,\n clearedExistingCount: mode === 'replace' || clearExisting ? 1 : 0,\n clearedExisting: mode === 'replace' || clearExisting\n }\n };\n }\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Advanced batch create memories with progress reporting and chunking\n */\n const batchCreateMemoriesAdvanced = useCallback(async (\n memories: Array<{ content: string; title?: string; tags?: string[] }>,\n options: {\n mode?: 'append' | 'replace' | 'smartDedupe';\n clearExisting?: boolean;\n chunkSize?: number;\n onProgress?: (current: number, total: number, message: string) => void;\n validateContent?: boolean;\n } = {}\n ) => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database with advanced features\n return await vectorDatabaseService.batchCreateMemoriesAdvanced(memories, options);\n } else {\n // Fallback to basic batch operation for IndexedDB\n const basicResult = await batchCreateMemories(\n memories, \n options.mode || 'append', \n options.clearExisting || false\n );\n \n // Convert to advanced result format\n return {\n success: basicResult.success,\n message: basicResult.message,\n totalMemories: memories.length,\n successCount: basicResult.summary.successCount,\n failureCount: basicResult.summary.failureCount,\n skippedCount: basicResult.summary.skippedCount,\n errors: basicResult.results.filter(r => !r.success).map(r => r.message),\n warnings: [],\n chunks: 1,\n duration: 0\n };\n }\n }, [status.isEnabled, status.migrationRequired, batchCreateMemories]);\n\n /**\n * Batch import memories from local storage to vector database\n * This is useful for migrating existing IndexedDB memories to vector storage\n */\n const batchImportMemories = useCallback(async (\n fromIndexedDB: boolean = true,\n mode: 'append' | 'replace' | 'smartDedupe' = 'append'\n ): Promise<{\n success: boolean;\n message: string;\n migratedCount: number;\n totalMemories: number;\n errors: string[];\n }> => {\n if (!status.isEnabled || status.migrationRequired) {\n return {\n success: false,\n message: 'Vector database not available for import',\n migratedCount: 0,\n totalMemories: 0,\n errors: ['Vector database not enabled or migration required']\n };\n }\n\n if (!fromIndexedDB) {\n return {\n success: false,\n message: 'Only IndexedDB import is currently supported',\n migratedCount: 0,\n totalMemories: 0,\n errors: ['Unsupported import source']\n };\n }\n\n try {\n // Get all memories from IndexedDB\n await memoryStore.hydrate();\n const indexedDBMemories = memoryStore.entries;\n\n if (indexedDBMemories.length === 0) {\n return {\n success: true,\n message: 'No memories found in IndexedDB to import',\n migratedCount: 0,\n totalMemories: 0,\n errors: []\n };\n }\n\n // Convert IndexedDB format to vector format\n const memoriesToImport = indexedDBMemories.map(entry => ({\n content: entry.content,\n title: `Imported Memory - ${new Date(entry.timestamp).toLocaleDateString()}`,\n tags: entry.tags || []\n }));\n\n debugLogger.info('Starting batch import from IndexedDB', {\n totalMemories: memoriesToImport.length,\n mode\n });\n\n // Import to vector database\n const result = await vectorDatabaseService.batchCreateMemories(memoriesToImport, mode, false);\n\n return {\n success: result.success,\n message: `Import completed: ${result.summary.successCount}/${memoriesToImport.length} memories imported`,\n migratedCount: result.summary.successCount,\n totalMemories: memoriesToImport.length,\n errors: result.results\n .filter(r => !r.success)\n .map(r => r.message)\n };\n\n } catch (error) {\n debugLogger.error('Failed to import memories from IndexedDB', { error });\n return {\n success: false,\n message: error instanceof Error ? error.message : String(error),\n migratedCount: 0,\n totalMemories: 0,\n errors: [error instanceof Error ? error.message : String(error)]\n };\n }\n }, [status.isEnabled, status.migrationRequired, memoryStore]);\n\n /**\n * Upload and embed document\n */\n const uploadDocument = useCallback(async (\n file: File, \n shareWithTeam = true\n ): Promise<{ success: boolean; fileId?: string; error?: string }> => {\n if (!status.isEnabled || status.migrationRequired) {\n return { \n success: false, \n error: 'Vector database not available - document upload requires advanced features' \n };\n }\n\n try {\n // Upload file to the configured file storage service\n const uploadResult = await vectorDatabaseService.uploadFile(file, shareWithTeam);\n \n if (!uploadResult.success || !uploadResult.fileId) {\n throw new Error(uploadResult.message || 'Upload failed');\n }\n\n // Embed in vector database\n const embedResult = await vectorDatabaseService.embedDocument(uploadResult.fileId, shareWithTeam);\n \n if (!embedResult.success) {\n throw new Error(embedResult.message || 'Embedding failed');\n }\n\n debugLogger.info('Document uploaded and embedded successfully', { \n filename: file.name,\n fileId: uploadResult.fileId \n });\n\n return { success: true, fileId: uploadResult.fileId };\n } catch (error) {\n debugLogger.error('Failed to upload document', { filename: file.name, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n }, [status.isEnabled, status.migrationRequired]);\n\n /**\n * Search documents using vector database\n */\n const searchDocuments = useCallback(async (\n query: string, \n options: SearchOptions = {}\n ): Promise<VectorDocument[]> => {\n const { documentLimit = 20, scoreThreshold = 0.7 } = options;\n\n if (!status.isEnabled || status.migrationRequired) {\n debugLogger.warn('Vector document search not available, falling back to knowledge store');\n // Fallback to basic knowledge store search\n const docs = knowledgeStore.docs.filter(doc => \n doc.content.toLowerCase().includes(query.toLowerCase()) ||\n doc.name.toLowerCase().includes(query.toLowerCase())\n );\n return docs.slice(0, documentLimit).map(knowledgeDocToVectorDocument);\n }\n\n try {\n const results = await vectorDatabaseService.searchDocuments(query, documentLimit, scoreThreshold);\n debugLogger.info('Vector document search completed', { \n query: query.slice(0, 50), \n resultsCount: results.length \n });\n return results;\n } catch (error) {\n debugLogger.error('Vector document search failed', { error });\n return [];\n }\n }, [status.isEnabled, status.migrationRequired, knowledgeStore.docs]);\n\n /**\n * Combined search across both memories and documents\n */\n const searchAll = useCallback(async (\n query: string, \n options: SearchOptions = {}\n ): Promise<SearchResult> => {\n if (status.isEnabled && !status.migrationRequired) {\n // Use vector database combined search\n try {\n const result = await vectorDatabaseService.searchAll(\n query,\n options.memoryLimit,\n options.documentLimit,\n options.scoreThreshold\n );\n \n debugLogger.info('Vector combined search completed', result);\n return result;\n } catch (error) {\n debugLogger.error('Vector combined search failed, falling back', { error });\n // Fall through to fallback\n }\n }\n\n // Fallback to separate searches\n try {\n const [memories, documents] = await Promise.all([\n searchMemories(query, { ...options, useVector: false }),\n searchDocuments(query, options)\n ]);\n\n return {\n memories,\n documents,\n success: true,\n message: `Found ${memories.length} memories and ${documents.length} documents (fallback search)`,\n };\n } catch (error) {\n debugLogger.error('Fallback combined search failed', { error });\n return {\n memories: [],\n documents: [],\n success: false,\n message: error instanceof Error ? error.message : String(error)\n };\n }\n }, [status.isEnabled, status.migrationRequired, searchMemories, searchDocuments]);\n\n /**\n * Get migration estimation\n */\n const getMigrationEstimate = useCallback(async () => {\n return vectorMigrationService.estimateMigration();\n }, []);\n\n // Initialize on mount and when dependencies change\n useEffect(() => {\n initializeVectorService();\n }, [initializeVectorService]);\n\n /**\n * One page of the user's Knowledge documents, with the real total and paging state.\n * `scope: 'all'` lists every file in the workspace (Drive, email attachments, app assets).\n * Throws when the gateway can't be reached so the view can say so.\n */\n const getKnowledgeDocumentsPage = useCallback(async (\n skip = 0,\n limit = 50,\n scope: KnowledgeFileScope = 'knowledge'\n ): Promise<KnowledgeDocumentPage> => {\n if (!status.isEnabled || status.migrationRequired) {\n return {\n documents: [],\n total: 0,\n hasMore: false,\n scope,\n serverScoped: false,\n knowledgeFilterUnavailable: false,\n hiddenCount: 0,\n };\n }\n\n const { files, ...meta } = await vectorDatabaseService.listKnowledgeFiles(skip, limit, scope);\n const documents = files\n .map(rawFileRecordToVectorDocument)\n .filter((doc): doc is VectorDocument => doc !== null);\n\n debugLogger.info('Retrieved knowledge documents', { count: documents.length, total: meta.total, scope: meta.scope });\n return { documents, ...meta };\n }, [status.isEnabled, status.migrationRequired]);\n\n /**\n * Get user's Knowledge documents (one page, knowledge scope). Never throws.\n */\n const getUserDocuments = useCallback(async (\n skip = 0, \n limit = 50\n ): Promise<VectorDocument[]> => {\n try {\n const page = await getKnowledgeDocumentsPage(skip, limit, 'knowledge');\n return page.documents;\n } catch (error) {\n debugLogger.error('Failed to get user documents', { error });\n return [];\n }\n }, [getKnowledgeDocumentsPage]);\n\n /**\n * Delete a document from vector database\n */\n const deleteDocument = useCallback(async (\n fileId: string\n ): Promise<{ success: boolean; error?: string }> => {\n if (!status.isEnabled || status.migrationRequired) {\n return { \n success: false, \n error: 'Vector database not available' \n };\n }\n\n try {\n const success = await vectorDatabaseService.deleteDocument(fileId);\n if (success) {\n debugLogger.info('Document deleted from vector database', { fileId });\n return { success: true };\n } else {\n throw new Error('Document deletion failed');\n }\n } catch (error) {\n debugLogger.error('Failed to delete document', { fileId, error });\n return { \n success: false, \n error: error instanceof Error ? error.message : String(error) \n };\n }\n }, [status.isEnabled, status.migrationRequired]);\n\n // Auto-trigger migration if required and user just gained access\n useEffect(() => {\n if (status.migrationRequired && status.isAvailable && !status.isMigrating) {\n debugLogger.info('Auto-triggering vector migration for newly enabled advanced features');\n // Auto-migrate when vector storage becomes available for users with access\n performMigration({ cleanupAfterMigration: false }).then(result => {\n debugLogger.info('Migration completed', { result });\n }).catch(error => {\n debugLogger.error('Auto-triggered migration failed', { error });\n });\n }\n }, [status.migrationRequired, status.isAvailable, status.isMigrating, performMigration]);\n\n /**\n * Download a file from vector database/file-storage using MongoDB ObjectId\n */\n const downloadVectorFile = useCallback(async (\n fileId: string,\n filename: string\n ): Promise<void> => {\n if (!status.isEnabled) {\n throw new Error('Vector database not enabled');\n }\n\n try {\n await vectorDatabaseService.downloadFile(fileId, filename);\n debugLogger.info('File downloaded successfully', { fileId, filename });\n } catch (error) {\n debugLogger.error('Failed to download file', { fileId, filename, error });\n throw error;\n }\n }, [status.isEnabled]);\n\n /**\n * Get file preview content using MongoDB ObjectId\n */\n const getFilePreview = useCallback(async (\n fileId: string\n ): Promise<{ content: string; mimeType: string } | null> => {\n if (!status.isEnabled) {\n return null;\n }\n\n try {\n const preview = await vectorDatabaseService.getFilePreview(fileId);\n debugLogger.info('File preview retrieved', { fileId, hasContent: !!preview?.content });\n return preview;\n } catch (error) {\n debugLogger.error('Failed to get file preview', { fileId, error });\n return null;\n }\n }, [status.isEnabled]);\n\n /**\n * Get file blob for displaying full content in modal using MongoDB ObjectId\n */\n const getFileBlob = useCallback(async (\n fileId: string\n ): Promise<Blob> => {\n if (!status.isEnabled) {\n throw new Error('Vector database not enabled');\n }\n\n try {\n const blob = await vectorDatabaseService.getFileBlob(fileId);\n debugLogger.info('File blob retrieved', { fileId, size: blob.size });\n return blob;\n } catch (error) {\n debugLogger.error('Failed to get file blob', { fileId, error });\n throw error;\n }\n }, [status.isEnabled]);\n\n // Manual refresh function for debugging\n const refreshCompatibilityCheck = useCallback(() => {\n checkProviderCompatibility();\n }, [checkProviderCompatibility]);\n\n return {\n // Status\n status,\n isVectorEnabled: status.isEnabled && !status.migrationRequired,\n \n // Debug functions\n refreshCompatibilityCheck,\n \n // Migration\n performMigration,\n getMigrationEstimate,\n \n // Memory operations\n addMemory,\n batchCreateMemories,\n batchCreateMemoriesAdvanced,\n batchImportMemories,\n searchMemories,\n getUserMemories,\n deleteMemory,\n updateMemory,\n \n // Document operations\n uploadDocument,\n searchDocuments,\n getUserDocuments,\n getKnowledgeDocumentsPage,\n deleteDocument,\n downloadVectorFile,\n getFilePreview,\n getFileBlob,\n \n // Combined operations\n searchAll,\n \n // Utilities\n initializeVectorService\n };\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from '../logging/debugLogger';\nimport { MemoryEntry } from '../../store/memoryStore';\nimport { KnowledgeDoc } from '../../store/knowledgeStore';\nimport { vectorDatabaseService } from './vectorDatabaseService';\nimport indexedDBService from '../indexedDB/indexedDBService';\n\nexport interface MigrationStatus {\n success: boolean;\n migratedMemories: number;\n migratedDocuments: number;\n errors: string[];\n warnings: string[];\n totalTime: number;\n}\n\nexport interface MigrationProgress {\n phase: 'memories' | 'documents' | 'cleanup' | 'complete';\n current: number;\n total: number;\n currentItem?: string;\n errors: string[];\n}\n\n/**\n * Vector Database Migration Service\n * \n * Handles migration of memories and documents from IndexedDB to vector database\n * when advanced semantic search is enabled for the first time.\n * \n * Features:\n * - Batch migration to avoid overwhelming the API\n * - Progress tracking with user feedback\n * - Error handling and retry logic\n * - Cleanup of migrated IndexedDB data (optional)\n * - Rollback capability in case of issues\n */\nexport class VectorMigrationService {\n private static readonly BATCH_SIZE = 5;\n private static readonly RETRY_DELAY = 1000; // 1 second\n private static readonly MAX_RETRIES = 3;\n\n private migrationKey = 'bandit_vector_migration_completed';\n private progressCallbacks: ((progress: MigrationProgress) => void)[] = [];\n\n /**\n * Check if migration has already been completed\n */\n isMigrationCompleted(): boolean {\n try {\n return localStorage.getItem(this.migrationKey) === 'true';\n } catch (error) {\n debugLogger.warn('Unable to check migration status from localStorage', { error });\n return false;\n }\n }\n\n /**\n * Mark migration as completed\n */\n markMigrationCompleted(): void {\n try {\n localStorage.setItem(this.migrationKey, 'true');\n debugLogger.info('Vector migration marked as completed');\n } catch (error) {\n debugLogger.error('Failed to mark migration as completed', { error });\n }\n }\n\n /**\n * Reset migration status (for testing or re-migration)\n */\n resetMigrationStatus(): void {\n try {\n localStorage.removeItem(this.migrationKey);\n debugLogger.info('Vector migration status reset');\n } catch (error) {\n debugLogger.error('Failed to reset migration status', { error });\n }\n }\n\n /**\n * Add progress callback for UI updates\n */\n onProgress(callback: (progress: MigrationProgress) => void): void {\n this.progressCallbacks.push(callback);\n }\n\n /**\n * Remove progress callback\n */\n removeProgressCallback(callback: (progress: MigrationProgress) => void): void {\n this.progressCallbacks = this.progressCallbacks.filter(cb => cb !== callback);\n }\n\n /**\n * Notify progress callbacks\n */\n private notifyProgress(progress: MigrationProgress): void {\n this.progressCallbacks.forEach(callback => {\n try {\n callback(progress);\n } catch (error) {\n debugLogger.error('Error in migration progress callback', { error });\n }\n });\n }\n\n /**\n * Sleep utility for rate limiting\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Get all memories directly from IndexedDB\n */\n private async getAllMemories(): Promise<MemoryEntry[]> {\n try {\n const DB_NAME = \"bandit-memory-db\";\n const STORE_NAME = \"bandit-memory\";\n const storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n \n return await indexedDBService.getAll<MemoryEntry>(DB_NAME, 1, STORE_NAME, storeConfigs);\n } catch (error) {\n debugLogger.error('Failed to get memories from IndexedDB', { error });\n return [];\n }\n }\n\n /**\n * Get all knowledge documents directly from IndexedDB \n */\n private async getAllDocuments(): Promise<KnowledgeDoc[]> {\n try {\n const DB_NAME = \"bandit-knowledge-db\";\n const STORE_NAME = \"bandit-knowledge\";\n const storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n \n return await indexedDBService.getAll<KnowledgeDoc>(DB_NAME, 1, STORE_NAME, storeConfigs);\n } catch (error) {\n debugLogger.error('Failed to get documents from IndexedDB', { error });\n return [];\n }\n }\n\n /**\n * Clear all memories from IndexedDB\n */\n private async clearAllMemories(): Promise<void> {\n try {\n const DB_NAME = \"bandit-memory-db\";\n const STORE_NAME = \"bandit-memory\";\n const storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n \n await indexedDBService.clear(DB_NAME, 1, STORE_NAME, storeConfigs);\n } catch (error) {\n debugLogger.error('Failed to clear memories from IndexedDB', { error });\n throw error;\n }\n }\n\n /**\n * Clear all documents from IndexedDB\n */\n private async clearAllDocuments(): Promise<void> {\n try {\n const DB_NAME = \"bandit-knowledge-db\";\n const STORE_NAME = \"bandit-knowledge\";\n const storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n \n await indexedDBService.clear(DB_NAME, 1, STORE_NAME, storeConfigs);\n } catch (error) {\n debugLogger.error('Failed to clear documents from IndexedDB', { error });\n throw error;\n }\n }\n\n /**\n * Migrate memories from IndexedDB to vector database\n */\n private async migrateMemories(): Promise<{ success: number; errors: string[] }> {\n debugLogger.info('Starting memory migration to vector database');\n \n const memories = await this.getAllMemories();\n const errors: string[] = [];\n let successCount = 0;\n\n if (memories.length === 0) {\n debugLogger.info('No memories to migrate');\n return { success: 0, errors: [] };\n }\n\n debugLogger.info(`Found ${memories.length} memories to migrate`);\n\n // Process in batches\n for (let i = 0; i < memories.length; i += VectorMigrationService.BATCH_SIZE) {\n const batch = memories.slice(i, i + VectorMigrationService.BATCH_SIZE);\n \n this.notifyProgress({\n phase: 'memories',\n current: i,\n total: memories.length,\n currentItem: `Migrating batch ${Math.floor(i / VectorMigrationService.BATCH_SIZE) + 1}`,\n errors\n });\n\n // Process batch items\n for (const memory of batch) {\n let attempts = 0;\n let migrated = false;\n\n while (attempts < VectorMigrationService.MAX_RETRIES && !migrated) {\n try {\n attempts++;\n \n debugLogger.debug('Migrating memory to vector database', { \n memoryId: memory.id,\n attempt: attempts,\n content: memory.content.slice(0, 100)\n });\n\n // Create memory in vector database\n const result = await vectorDatabaseService.createMemory(memory.content, {\n title: `Memory from ${new Date(memory.timestamp).toLocaleDateString()}`,\n tags: memory.tags || [],\n source: memory.source,\n pinned: memory.pinned,\n lastReferencedAt: new Date(memory.timestamp).toISOString(),\n });\n\n if (result.success) {\n successCount++;\n migrated = true;\n debugLogger.debug('Memory migrated successfully', { \n memoryId: memory.id,\n vectorId: result.memoryId \n });\n } else {\n throw new Error(result.message || 'Unknown error');\n }\n } catch (error) {\n debugLogger.error('Failed to migrate memory', { \n memoryId: memory.id,\n attempt: attempts,\n error: error instanceof Error ? error.message : String(error)\n });\n\n if (attempts >= VectorMigrationService.MAX_RETRIES) {\n const errorMsg = `Failed to migrate memory ${memory.id}: ${error instanceof Error ? error.message : String(error)}`;\n errors.push(errorMsg);\n } else {\n // Wait before retry\n await this.sleep(VectorMigrationService.RETRY_DELAY * attempts);\n }\n }\n }\n }\n\n // Rate limiting between batches\n if (i + VectorMigrationService.BATCH_SIZE < memories.length) {\n await this.sleep(500);\n }\n }\n\n debugLogger.info('Memory migration completed', { \n total: memories.length,\n success: successCount,\n errors: errors.length \n });\n\n return { success: successCount, errors };\n }\n\n /**\n * Migrate documents from IndexedDB to vector database\n */\n private async migrateDocuments(): Promise<{ success: number; errors: string[] }> {\n debugLogger.info('Starting document migration to vector database');\n \n const errors: string[] = [];\n let successCount = 0;\n\n try {\n // Get documents from knowledge store's IndexedDB storage\n const documents = await this.getAllDocuments();\n\n if (documents.length === 0) {\n debugLogger.info('No documents to migrate');\n return { success: 0, errors: [] };\n }\n\n debugLogger.info(`Found ${documents.length} documents to migrate`);\n\n // Process documents in batches\n for (let i = 0; i < documents.length; i += VectorMigrationService.BATCH_SIZE) {\n const batch = documents.slice(i, i + VectorMigrationService.BATCH_SIZE);\n \n this.notifyProgress({\n phase: 'documents',\n current: i,\n total: documents.length,\n currentItem: `Migrating batch ${Math.floor(i / VectorMigrationService.BATCH_SIZE) + 1}`,\n errors\n });\n\n // Process batch items\n for (const doc of batch) {\n let attempts = 0;\n let migrated = false;\n\n while (attempts < VectorMigrationService.MAX_RETRIES && !migrated) {\n try {\n attempts++;\n \n debugLogger.debug('Migrating document to vector database', { \n filename: doc.name,\n attempt: attempts\n });\n\n // For documents, we need to:\n // 1. Convert content to file format if needed\n // 2. Upload to S3\n // 3. Embed in vector database\n \n if (doc.content && doc.name) {\n // Create a virtual file from stored content\n const blob = new Blob([doc.content], { type: 'text/plain' });\n const file = new File([blob], doc.name, { type: 'text/plain' });\n\n // Upload to S3 with team sharing enabled by default for migration\n const uploadResult = await vectorDatabaseService.uploadFile(file, true);\n \n if (uploadResult.success && uploadResult.fileId) {\n // Embed in vector database\n const embedResult = await vectorDatabaseService.embedDocument(uploadResult.fileId, true);\n \n if (embedResult.success) {\n successCount++;\n migrated = true;\n debugLogger.debug('Document migrated successfully', { \n filename: doc.name,\n fileId: uploadResult.fileId \n });\n } else {\n throw new Error(embedResult.message || 'Embedding failed');\n }\n } else {\n throw new Error(uploadResult.message || 'Upload failed');\n }\n } else {\n throw new Error('Document missing required content or filename');\n }\n } catch (error) {\n debugLogger.error('Failed to migrate document', { \n filename: doc.name,\n attempt: attempts,\n error: error instanceof Error ? error.message : String(error)\n });\n\n if (attempts >= VectorMigrationService.MAX_RETRIES) {\n const errorMsg = `Failed to migrate document ${doc.name}: ${error instanceof Error ? error.message : String(error)}`;\n errors.push(errorMsg);\n } else {\n // Wait before retry\n await this.sleep(VectorMigrationService.RETRY_DELAY * attempts);\n }\n }\n }\n }\n\n // Rate limiting between batches\n if (i + VectorMigrationService.BATCH_SIZE < documents.length) {\n await this.sleep(500);\n }\n }\n } catch (error) {\n debugLogger.error('Failed to get documents for migration', { error });\n errors.push(`Failed to retrieve documents: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n debugLogger.info('Document migration completed', { \n success: successCount,\n errors: errors.length \n });\n\n return { success: successCount, errors };\n }\n\n /**\n * Perform full migration from IndexedDB to vector database\n */\n async performMigration(\n options: {\n cleanupAfterMigration?: boolean;\n skipIfCompleted?: boolean;\n } = {}\n ): Promise<MigrationStatus> {\n const startTime = Date.now();\n const { cleanupAfterMigration = false, skipIfCompleted = true } = options;\n\n debugLogger.info('Starting vector database migration', { \n cleanupAfterMigration,\n skipIfCompleted \n });\n\n // Check if already completed\n if (skipIfCompleted && this.isMigrationCompleted()) {\n debugLogger.info('Migration already completed, skipping');\n return {\n success: true,\n migratedMemories: 0,\n migratedDocuments: 0,\n errors: [],\n warnings: ['Migration was already completed'],\n totalTime: Date.now() - startTime\n };\n }\n\n const allErrors: string[] = [];\n const allWarnings: string[] = [];\n\n try {\n // Ensure vector database is available\n if (!vectorDatabaseService.isAvailable()) {\n throw new Error('Vector database service is not available - check configuration and authentication');\n }\n\n // Phase 1: Migrate memories\n debugLogger.info('Phase 1: Migrating memories');\n const memoryResult = await this.migrateMemories();\n allErrors.push(...memoryResult.errors);\n\n // Phase 2: Migrate documents\n debugLogger.info('Phase 2: Migrating documents');\n const documentResult = await this.migrateDocuments();\n allErrors.push(...documentResult.errors);\n\n // Phase 3: Cleanup (optional)\n if (cleanupAfterMigration && allErrors.length === 0) {\n this.notifyProgress({\n phase: 'cleanup',\n current: 0,\n total: 1,\n currentItem: 'Cleaning up local data',\n errors: allErrors\n });\n\n try {\n // Only cleanup if migration was successful\n await this.cleanupLocalData();\n debugLogger.info('Local data cleanup completed');\n } catch (error) {\n const warningMsg = `Cleanup failed but migration succeeded: ${error instanceof Error ? error.message : String(error)}`;\n allWarnings.push(warningMsg);\n debugLogger.warn('Cleanup failed', { error });\n }\n }\n\n // Mark as completed if no errors\n if (allErrors.length === 0) {\n this.markMigrationCompleted();\n }\n\n // Final progress update\n this.notifyProgress({\n phase: 'complete',\n current: 1,\n total: 1,\n currentItem: 'Migration complete',\n errors: allErrors\n });\n\n const totalTime = Date.now() - startTime;\n const status: MigrationStatus = {\n success: allErrors.length === 0,\n migratedMemories: memoryResult.success,\n migratedDocuments: documentResult.success,\n errors: allErrors,\n warnings: allWarnings,\n totalTime\n };\n\n debugLogger.info('Vector migration completed', status);\n return status;\n\n } catch (error) {\n const errorMsg = `Migration failed: ${error instanceof Error ? error.message : String(error)}`;\n allErrors.push(errorMsg);\n \n debugLogger.error('Vector migration failed', { error });\n\n return {\n success: false,\n migratedMemories: 0,\n migratedDocuments: 0,\n errors: allErrors,\n warnings: allWarnings,\n totalTime: Date.now() - startTime\n };\n }\n }\n\n /**\n * Clean up local IndexedDB data after successful migration\n */\n private async cleanupLocalData(): Promise<void> {\n debugLogger.info('Starting cleanup of local IndexedDB data');\n\n try {\n // Clear memories from memory store\n await this.clearAllMemories();\n debugLogger.info('Cleared all memories from local storage');\n\n // Clear documents from knowledge store\n await this.clearAllDocuments();\n debugLogger.info('Cleared all documents from local storage');\n\n } catch (error) {\n debugLogger.error('Failed to cleanup local data', { error });\n throw error;\n }\n }\n\n /**\n * Estimate migration time and data size\n */\n async estimateMigration(): Promise<{\n memoryCount: number;\n documentCount: number;\n estimatedTime: number; // in minutes\n estimatedDataSize: number; // in MB\n }> {\n try {\n const memories = await this.getAllMemories();\n const documents = await this.getAllDocuments();\n\n // Rough estimation based on content size and API call overhead\n const avgMemorySize = memories.reduce((sum: number, m: MemoryEntry) => sum + m.content.length, 0) / Math.max(memories.length, 1);\n const avgDocumentSize = documents.reduce((sum: number, d: KnowledgeDoc) => sum + (d.content?.length || 0), 0) / Math.max(documents.length, 1);\n\n const totalDataSize = (memories.length * avgMemorySize + documents.length * avgDocumentSize) / (1024 * 1024); // MB\n const totalItems = memories.length + documents.length;\n \n // Estimate 1-2 seconds per item including API calls and retries\n const estimatedTime = Math.ceil((totalItems * 1.5) / 60); // minutes\n\n return {\n memoryCount: memories.length,\n documentCount: documents.length,\n estimatedTime: Math.max(1, estimatedTime),\n estimatedDataSize: Math.round(totalDataSize * 100) / 100\n };\n } catch (error) {\n debugLogger.error('Failed to estimate migration', { error });\n return {\n memoryCount: 0,\n documentCount: 0,\n estimatedTime: 1,\n estimatedDataSize: 0\n };\n }\n }\n}\n\n// Export singleton instance\nexport const vectorMigrationService = new VectorMigrationService();\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useContext } from 'react';\nimport { FeatureFlagContext } from '../contexts/FeatureFlagContext';\nimport { FeatureKey, SubscriptionTier } from '../types/featureFlags';\n\n/**\n * Convenience hook that provides an easier API for feature checking\n */\nexport const useFeatures = () => {\n const featureFlag = useContext(FeatureFlagContext);\n\n if (!featureFlag) {\n // Fallback: default to OSS features when feature flags are unavailable\n return {\n hasFeature: () => true,\n hasMemory: () => true,\n hasDocumentKnowledge: () => true,\n hasMoodAdaptation: () => true,\n hasChatSuggestions: () => true,\n hasTTS: () => true,\n hasSTT: () => true,\n hasAdminDashboard: () => true,\n hasLimitedAdminDashboard: () => true,\n hasSimpleSearch: () => true,\n hasPremiumSearch: () => true,\n hasAdvancedSearch: () => true,\n hasAdvancedMemories: () => true,\n isAdmin: () => false,\n getCurrentTier: () => 'oss' as const,\n isOSSMode: () => true,\n isSubscribed: () => true,\n isPremiumTier: () => false,\n isProTier: () => false,\n isTrialTier: () => false,\n isTeamTier: () => false,\n isExpiredTier: () => false,\n needsUpgrade: () => false,\n getTrialUsage: () => undefined,\n isTrialLimitReached: () => false,\n getTrialRemainingRequests: () => null,\n updateTier: () => undefined,\n refreshFeatures: () => undefined,\n getFullEvaluation: () => null,\n };\n }\n\n return {\n // Core feature checking\n hasFeature: (feature: FeatureKey) => featureFlag.hasFeature(feature),\n \n // Convenience methods for common features\n hasMemory: () => featureFlag.hasFeature('memory'),\n hasDocumentKnowledge: () => featureFlag.hasFeature('documentKnowledge'),\n hasMoodAdaptation: () => featureFlag.hasFeature('moodAdaptation'),\n hasChatSuggestions: () => featureFlag.hasFeature('chatSuggestions'),\n hasTTS: () => featureFlag.hasFeature('tts'),\n hasSTT: () => featureFlag.hasFeature('stt'),\n hasAdminDashboard: () => featureFlag.hasFeature('adminDashboardEnabled'),\n hasLimitedAdminDashboard: () => featureFlag.hasFeature('limitedAdminDashboard'),\n hasSimpleSearch: () => featureFlag.hasFeature('semanticSearchSimple'),\n hasPremiumSearch: () => featureFlag.hasFeature('semanticSearchPremium'),\n hasAdvancedSearch: () => featureFlag.hasFeature('advancedSearch'),\n hasAdvancedMemories: () => featureFlag.hasFeature('advancedMemories'),\n \n // Admin and tier checking\n isAdmin: () => featureFlag.isAdmin(),\n getCurrentTier: () => featureFlag.getCurrentTier(),\n isOSSMode: () => featureFlag.isOSSMode(),\n isSubscribed: () => featureFlag.getEvaluation()?.isSubscribed ?? true,\n \n // Tier comparison helpers\n isPremiumTier: () => {\n const tier = featureFlag.getCurrentTier();\n return tier === 'premium' || tier === 'pro' || tier === 'team' || tier === 'trial';\n },\n \n isProTier: () => {\n const tier = featureFlag.getCurrentTier();\n return tier === 'pro' || tier === 'team' || tier === 'trial';\n },\n \n isTrialTier: () => featureFlag.getCurrentTier() === 'trial',\n \n isTeamTier: () => featureFlag.getCurrentTier() === 'team',\n \n isExpiredTier: () => featureFlag.getCurrentTier() === 'expired',\n \n // Upgrade checking\n needsUpgrade: (feature: FeatureKey, requiredTier?: SubscriptionTier) => {\n if (featureFlag.isAdmin() || featureFlag.isOSSMode()) {\n return false;\n }\n \n if (!featureFlag.hasFeature(feature)) {\n return requiredTier || 'premium';\n }\n \n return false;\n },\n \n // Trial usage tracking\n getTrialUsage: () => featureFlag.getEvaluation()?.trialUsage,\n isTrialLimitReached: (type: 'chat' | 'generate') => {\n const usage = featureFlag.getEvaluation()?.trialUsage;\n if (!usage) return false;\n \n if (type === 'chat') {\n return usage.chatRequestsUsed >= usage.chatRequestsLimit;\n } else {\n return usage.generateRequestsUsed >= usage.generateRequestsLimit;\n }\n },\n getTrialRemainingRequests: (type: 'chat' | 'generate') => {\n const usage = featureFlag.getEvaluation()?.trialUsage;\n if (!usage) return null;\n \n if (type === 'chat') {\n return Math.max(0, usage.chatRequestsLimit - usage.chatRequestsUsed);\n } else {\n return Math.max(0, usage.generateRequestsLimit - usage.generateRequestsUsed);\n }\n },\n \n // Management\n updateTier: (tier: SubscriptionTier) => featureFlag.updateTier(tier),\n refreshFeatures: () => featureFlag.refreshEvaluation(),\n \n // Full evaluation access\n getFullEvaluation: () => featureFlag.getEvaluation(),\n };\n};\n\n/**\n * Hook specifically for checking if features should be shown in UI\n */\nexport const useFeatureVisibility = () => {\n const features = useFeatures();\n \n return {\n // UI visibility helpers\n showMemoryToggle: () => features.hasMemory() || features.isOSSMode(),\n showDocumentUpload: () => features.hasDocumentKnowledge() || features.isOSSMode(),\n showMoodSettings: () => features.hasMoodAdaptation() || features.isOSSMode(),\n showSuggestions: () => features.hasChatSuggestions() || features.isOSSMode(),\n showVoiceControls: () => (features.hasTTS() || features.hasSTT()) || features.isOSSMode(),\n showAdminPanel: () => features.hasAdminDashboard() || features.isAdmin(),\n showLimitedAdminPanel: () => features.hasLimitedAdminDashboard() || features.isOSSMode(),\n showAdvancedSearch: () => features.hasPremiumSearch() || features.isOSSMode(),\n \n // Upgrade prompts\n shouldShowUpgradePrompt: (feature: FeatureKey) => {\n return !features.isOSSMode() && !features.isAdmin() && !features.hasFeature(feature);\n },\n \n getUpgradeMessage: (feature: FeatureKey) => {\n const tier = features.needsUpgrade(feature);\n if (!tier) return null;\n \n const featureNames: Record<FeatureKey, string> = {\n memory: 'Conversation Memory',\n documentKnowledge: 'Document Knowledge',\n moodAdaptation: 'Mood Adaptation',\n chatSuggestions: 'Chat Suggestions',\n tts: 'Text-to-Speech',\n stt: 'Speech-to-Text',\n adminDashboardEnabled: 'Admin Dashboard',\n limitedAdminDashboard: 'Limited Admin Dashboard',\n semanticSearchSimple: 'Simple Search',\n semanticSearchPremium: 'Premium Search',\n advancedSearch: 'Advanced Vector Search',\n advancedMemories: 'Advanced Vector Memories'\n };\n \n return `${featureNames[feature]} requires ${tier} subscription`;\n }\n };\n};\n\nexport default useFeatures;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { createContext, useContext, useEffect, useState, useCallback } from 'react';\nimport {\n FeatureFlagConfig,\n FeatureKey,\n FeatureMatrix,\n FeatureEvaluation,\n SubscriptionTier,\n TrialUsage,\n DEFAULT_TIER_FEATURES,\n OSS_DEFAULT_FEATURES,\n JWTPayload\n} from '../types/featureFlags';\nimport { debugLogger } from '../services/logging/debugLogger';\nimport {\n authenticationService,\n AUTH_TOKEN_CHANGED_EVENT,\n TOKEN_KEY,\n} from '../services/auth/authenticationService';\n\n/**\n * The JWT the flags are evaluated against. The engine's own session is the\n * source of truth (it may live in memory only, with nothing in Web Storage);\n * a host that keeps its token under a different localStorage key still gets\n * that key read, as before.\n */\nconst readSessionToken = (jwtStorageKey: string): string | null => {\n const fromStorage = (): string | null => {\n try {\n return localStorage.getItem(jwtStorageKey);\n } catch {\n return null;\n }\n };\n if (jwtStorageKey && jwtStorageKey !== TOKEN_KEY) {\n return fromStorage() ?? authenticationService.getToken();\n }\n return authenticationService.getToken() ?? fromStorage();\n};\n\n/**\n * Context value interface\n */\nexport interface FeatureFlagContextValue {\n /** Check if a specific feature is enabled */\n hasFeature: (feature: FeatureKey) => boolean;\n \n /** Get the current feature evaluation */\n getEvaluation: () => FeatureEvaluation | null;\n \n /** Refresh feature evaluation (useful after login/logout) */\n refreshEvaluation: () => void;\n \n /** Check if user is admin */\n isAdmin: () => boolean;\n \n /** Get current tier */\n getCurrentTier: () => SubscriptionTier | 'oss';\n \n /** Update subscription tier dynamically */\n updateTier: (tier: SubscriptionTier) => void;\n \n /** Check if we're in OSS mode */\n isOSSMode: () => boolean;\n}\n\nexport const FeatureFlagContext = createContext<FeatureFlagContextValue | undefined>(undefined);\n\n/**\n * Props for the FeatureFlagProvider\n */\nexport interface FeatureFlagProviderProps {\n config: FeatureFlagConfig;\n children: React.ReactNode;\n}\n\n/**\n * JWT decoding utility (simple base64 decode)\n */\nfunction decodeJWT(token: string): JWTPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n \n const payload = parts[1];\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\n return JSON.parse(decoded);\n } catch (error) {\n debugLogger.error('Failed to decode JWT:', { error });\n return null;\n }\n}\n\n/**\n * Check if JWT is expired\n */\nfunction isJWTExpired(payload: JWTPayload): boolean {\n if (!payload.exp) return false;\n return Date.now() >= payload.exp * 1000;\n}\n\nconst coerceNumber = (value: unknown, fallback: number): number => {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string') {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return fallback;\n};\n\nconst coerceBoolean = (value: unknown, fallback: boolean): boolean => {\n if (typeof value === 'boolean') {\n return value;\n }\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true';\n }\n if (typeof value === 'number') {\n return value !== 0;\n }\n return fallback;\n};\n\n/**\n * Feature Flag Provider Component\n */\nexport const FeatureFlagProvider: React.FC<FeatureFlagProviderProps> = ({ config, children }) => {\n const [evaluation, setEvaluation] = useState<FeatureEvaluation | null>(null);\n const [currentTier, setCurrentTier] = useState<SubscriptionTier | undefined>(config.subscriptionType);\n\n /**\n * Evaluate features based on JWT, tier, and config\n */\n const evaluateFeatures = useCallback((): FeatureEvaluation => {\n const {\n subscriptionType,\n rolesClaimKey = 'roles',\n subscriptionTypeClaimKey = 'subscriptionType',\n isSubscribedClaimKey = 'isSubscribed',\n jwtStorageKey = 'bandit-jwt',\n featureMatrix = {},\n adminRole = 'admin',\n debug = false\n } = config;\n\n let jwtFound = false;\n let jwtValid = false;\n let rolesExtracted: string[] = [];\n let isAdmin = false;\n let jwtSubscriptionType: SubscriptionTier | undefined;\n let jwtIsSubscribed: boolean = true; // Default to true for non-trial users\n let jwtTrialUsage: TrialUsage | undefined;\n let effectiveTier: SubscriptionTier | 'oss' = currentTier || subscriptionType || 'oss';\n\n // Try to get the session JWT (engine session first, then the host's slot)\n if (typeof window !== 'undefined') {\n try {\n const token = readSessionToken(jwtStorageKey);\n if (token) {\n jwtFound = true;\n const payload = decodeJWT(token);\n \n if (payload && !isJWTExpired(payload)) {\n jwtValid = true;\n \n // Extract roles\n const roles = payload[rolesClaimKey];\n if (Array.isArray(roles)) {\n rolesExtracted = roles.filter((role): role is string => typeof role === 'string');\n isAdmin = rolesExtracted.includes(adminRole);\n }\n \n // Extract subscription information from JWT\n const jwtSubType = payload[subscriptionTypeClaimKey];\n if (typeof jwtSubType === 'string' && ['basic', 'premium', 'pro', 'team', 'trial', 'expired'].includes(jwtSubType)) {\n jwtSubscriptionType = jwtSubType as SubscriptionTier;\n effectiveTier = jwtSubscriptionType; // JWT overrides config\n }\n \n // Extract subscription status (important for trial users)\n if (Object.prototype.hasOwnProperty.call(payload, isSubscribedClaimKey)) {\n jwtIsSubscribed = coerceBoolean(payload[isSubscribedClaimKey], jwtIsSubscribed);\n }\n \n // Extract trial usage information for trial users\n if (jwtSubscriptionType === 'trial') {\n const chatRequestsUsedRaw = (payload as Record<string, unknown>).chatRequestsUsed ?? (payload as Record<string, unknown>).ChatRequestsUsed;\n const chatRequestsLimitRaw = (payload as Record<string, unknown>).chatRequestsLimit ?? (payload as Record<string, unknown>).ChatRequestsLimit;\n const generateRequestsUsedRaw = (payload as Record<string, unknown>).generateRequestsUsed ?? (payload as Record<string, unknown>).GenerateRequestsUsed;\n const generateRequestsLimitRaw = (payload as Record<string, unknown>).generateRequestsLimit ?? (payload as Record<string, unknown>).GenerateRequestsLimit;\n\n jwtTrialUsage = {\n chatRequestsUsed: coerceNumber(chatRequestsUsedRaw, 0),\n chatRequestsLimit: coerceNumber(chatRequestsLimitRaw, 40),\n generateRequestsUsed: coerceNumber(generateRequestsUsedRaw, 0),\n generateRequestsLimit: coerceNumber(generateRequestsLimitRaw, 1000)\n };\n }\n }\n }\n } catch (error) {\n if (debug) {\n debugLogger.error('Error processing JWT for feature flags:', { error });\n }\n }\n }\n\n // Determine final feature matrix\n let finalFeatures: FeatureMatrix;\n\n if (!subscriptionType && !currentTier && !jwtSubscriptionType) {\n // OSS mode - use provided matrix or defaults\n finalFeatures = { ...OSS_DEFAULT_FEATURES, ...featureMatrix };\n effectiveTier = 'oss';\n } else if (isAdmin) {\n // Admin gets everything\n finalFeatures = { ...OSS_DEFAULT_FEATURES };\n } else {\n // Use tier-based features with manual overrides\n // Note: Trial users get pro-level features but have API-enforced request limits\n const tierFeatures = effectiveTier !== 'oss' \n ? DEFAULT_TIER_FEATURES[effectiveTier as SubscriptionTier] \n : OSS_DEFAULT_FEATURES;\n finalFeatures = { ...tierFeatures, ...featureMatrix };\n }\n\n const result: FeatureEvaluation = {\n tier: effectiveTier,\n isAdmin,\n isSubscribed: jwtIsSubscribed,\n trialUsage: jwtTrialUsage,\n features: finalFeatures,\n metadata: {\n jwtFound,\n jwtValid,\n rolesExtracted,\n subscriptionTypeFromJWT: jwtSubscriptionType,\n isSubscribedFromJWT: jwtIsSubscribed,\n trialUsageFromJWT: jwtTrialUsage,\n evaluatedAt: Date.now()\n }\n };\n\n if (debug) {\n debugLogger.info('Feature flag evaluation:', result);\n }\n\n return result;\n }, [config, currentTier]);\n\n /**\n * Refresh evaluation\n */\n const refreshEvaluation = useCallback(() => {\n const newEvaluation = evaluateFeatures();\n setEvaluation(newEvaluation);\n }, [evaluateFeatures]);\n\n /**\n * Initial evaluation and periodic refresh\n */\n useEffect(() => {\n refreshEvaluation();\n\n // Listen for storage changes (login/logout in other tabs)\n const handleStorageChange = (e: StorageEvent) => {\n if (e.key === config.jwtStorageKey || e.key === null) {\n refreshEvaluation();\n }\n };\n\n // Listen for external tier updates\n const handleTierUpdate = (e: CustomEvent) => {\n if (e.detail?.tier) {\n setCurrentTier(e.detail.tier);\n }\n };\n\n // Same-tab sign-in/sign-out/refresh (no storage event fires for those, and\n // a memory-only session never touches storage at all).\n const handleSessionChange = () => refreshEvaluation();\n\n window.addEventListener('storage', handleStorageChange);\n window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleSessionChange);\n window.addEventListener('bandit:tier-updated', handleTierUpdate as EventListener);\n\n return () => {\n window.removeEventListener('storage', handleStorageChange);\n window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleSessionChange);\n window.removeEventListener('bandit:tier-updated', handleTierUpdate as EventListener);\n };\n }, [refreshEvaluation, config.jwtStorageKey]);\n\n /**\n * Context value\n */\n const contextValue: FeatureFlagContextValue = {\n hasFeature: (feature: FeatureKey) => {\n return evaluation?.features[feature] ?? false;\n },\n \n getEvaluation: () => evaluation,\n \n refreshEvaluation,\n \n isAdmin: () => evaluation?.isAdmin ?? false,\n \n getCurrentTier: () => evaluation?.tier ?? 'oss',\n \n updateTier: (tier: SubscriptionTier) => {\n setCurrentTier(tier);\n },\n \n isOSSMode: () => {\n if (!evaluation) {\n return true;\n }\n return evaluation.tier === 'oss';\n }\n };\n\n return (\n <FeatureFlagContext.Provider value={contextValue}>\n {children}\n </FeatureFlagContext.Provider>\n );\n};\n\n/**\n * Hook to use feature flags\n */\nexport const useFeatureFlag = (): FeatureFlagContextValue => {\n const context = useContext(FeatureFlagContext);\n if (context === undefined) {\n throw new Error('useFeatureFlag must be used within a FeatureFlagProvider');\n }\n return context;\n};\n\nexport default FeatureFlagProvider;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { useConversationStore, Conversation } from \"./conversationStore\";\nimport { useProjectStore, Project } from \"./projectStore\";\nimport { usePackageSettingsStore } from \"./packageSettingsStore\";\nimport { authenticationService } from \"../services/auth/authenticationService\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport {\n CONVERSATION_DELETE_EVENT,\n CONVERSATION_UPSERT_EVENT,\n PROJECT_DELETE_EVENT,\n PROJECT_UPSERT_EVENT,\n} from \"./conversationSyncEvents\";\nimport {\n ConversationRecordDTO,\n ConversationSyncPreferenceDTO,\n ConversationSyncRequest,\n ConversationSyncResponse,\n ConversationTurnDTO,\n ProjectRecordDTO,\n fetchConversationSyncPreference,\n syncConversations,\n updateConversationSyncPreference,\n} from \"../services/conversationSync/conversationSyncService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\nconst DEVICE_STORAGE_KEY = \"banditConversationDeviceId\";\nconst SYNC_IDENTITY_STORAGE_KEY = \"banditConversationSyncIdentity\";\nconst PAYLOAD_VERSION = 1;\nconst MAX_CONVERSATION_BYTES = 12 * 1024 * 1024; // ~12 MB cloud cap\nconst WARN_CONVERSATION_BYTES = 10 * 1024 * 1024; // warn at ~10 MB\nconst PROJECT_DB_NAME = \"bandit-projects\";\nconst PROJECT_DB_VERSION = 1;\nconst PROJECT_STORE_NAME = \"projects\";\nconst PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: \"id\" }];\n\nlet suppressTracking = false;\nlet conversationsMeta = new Map<string, ConversationMeta>();\nlet projectsMeta = new Map<string, ProjectMeta>();\nlet conversationUnsubscribe: (() => void) | null = null;\nlet projectUnsubscribe: (() => void) | null = null;\nlet autoSyncTimeout: ReturnType<typeof setTimeout> | null = null;\n\nconst AUTO_SYNC_DELAY_MS = 4_000;\n\ntype ConversationStoreState = ReturnType<typeof useConversationStore.getState>;\ntype ProjectStoreState = ReturnType<typeof useProjectStore.getState>;\n\ninterface ConversationMeta {\n updatedAtMs: number;\n version?: number;\n historyLength: number;\n}\n\ninterface ProjectMeta {\n updatedAtMs: number;\n version?: number;\n order: number;\n}\n\ninterface ConversationSizeNotice {\n id: string;\n name: string;\n sizeBytes: number;\n limitBytes: number;\n}\n\nexport type ConversationSyncStatus = \"disabled\" | \"idle\" | \"syncing\" | \"error\";\n\nexport interface ConversationSyncState {\n initialized: boolean;\n hasLoadedPreference: boolean;\n initializedForToken: string | null;\n initializedForIdentity: string | null;\n syncEnabled: boolean;\n status: ConversationSyncStatus;\n lastSyncAt?: string | null;\n cursor?: string | null;\n lastError?: string | null;\n keepLocalOnly?: boolean;\n isAdvancedVectorFeaturesEnabled: boolean;\n conflicts: ConversationSyncResponse[\"conflicts\"] | null;\n deviceId: string;\n pendingConversationUpserts: Set<string>;\n pendingConversationDeletes: Set<string>;\n pendingProjectUpserts: Set<string>;\n pendingProjectDeletes: Set<string>;\n totalConversationsOnServer?: number;\n totalProjectsOnServer?: number;\n hasCompletedInitialUpload: boolean;\n warningConversations: ConversationSizeNotice[];\n oversizedConversations: ConversationSizeNotice[];\n initialize: () => Promise<void>;\n setSyncEnabled: (enabled: boolean) => Promise<void>;\n setAdvancedVectorFeaturesEnabled: (enabled: boolean) => Promise<void>;\n runSync: (options?: { force?: boolean }) => Promise<void>;\n registerError: (error: string) => void;\n clearConflicts: () => void;\n}\n\nfunction ensureDeviceId(): string {\n if (typeof window === \"undefined\") {\n return \"bandit-web\";\n }\n try {\n const existing = window.localStorage.getItem(DEVICE_STORAGE_KEY);\n if (existing) {\n return existing;\n }\n const generated = uuidv4();\n window.localStorage.setItem(DEVICE_STORAGE_KEY, generated);\n return generated;\n } catch (error) {\n debugLogger.warn(\"conversationSyncStore: unable to access localStorage, generating volatile device id\", { error });\n return uuidv4();\n }\n}\n\nfunction getStoredSyncIdentity(): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n try {\n return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);\n } catch (error) {\n debugLogger.warn(\"conversationSyncStore: unable to read stored sync identity\", { error });\n return null;\n }\n}\n\nfunction setStoredSyncIdentity(identity: string | null) {\n if (typeof window === \"undefined\") {\n return;\n }\n try {\n if (identity) {\n window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);\n } else {\n window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);\n }\n } catch (error) {\n debugLogger.warn(\"conversationSyncStore: unable to persist sync identity\", { error });\n }\n}\n\nfunction getPackageDefaultAdvancedKnowledgeSync(): boolean | undefined {\n return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;\n}\n\nfunction clearAutoSyncTimer() {\n if (autoSyncTimeout) {\n clearTimeout(autoSyncTimeout);\n autoSyncTimeout = null;\n }\n}\n\nfunction resolveAuthIdentity(token: string | null): string | null {\n if (!token) {\n return null;\n }\n\n const claims = authenticationService.parseJwtClaims(token);\n if (claims?.sub) {\n return claims.sub;\n }\n\n if (claims?.email) {\n return `email:${claims.email.toLowerCase()}`;\n }\n\n return `token:${token.slice(0, 32)}`;\n}\n\nfunction buildQueueResetState() {\n return {\n pendingConversationUpserts: new Set<string>(),\n pendingConversationDeletes: new Set<string>(),\n pendingProjectUpserts: new Set<string>(),\n pendingProjectDeletes: new Set<string>(),\n conflicts: null,\n lastSyncAt: null,\n cursor: null,\n lastError: null,\n totalConversationsOnServer: undefined,\n totalProjectsOnServer: undefined,\n hasCompletedInitialUpload: false,\n warningConversations: [],\n oversizedConversations: [],\n };\n}\n\nasync function clearLocalStoresForIdentitySwitch(fromIdentity: string, toIdentity: string) {\n const conversationCount = useConversationStore.getState().conversations.length;\n const projectCount = useProjectStore.getState().projects.length;\n\n debugLogger.warn(\"conversationSyncStore: auth identity changed, clearing local conversation/project cache\", {\n fromIdentity,\n toIdentity,\n conversationCount,\n projectCount,\n });\n\n suppressTracking = true;\n try {\n await useConversationStore.getState().clearAllConversations();\n await indexedDBService.clear(\n PROJECT_DB_NAME,\n PROJECT_DB_VERSION,\n PROJECT_STORE_NAME,\n PROJECT_STORE_CONFIGS\n );\n useProjectStore.setState({ projects: [] });\n conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);\n projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);\n } catch (error) {\n debugLogger.error(\"conversationSyncStore: failed to clear local stores on auth switch\", {\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n suppressTracking = false;\n }\n}\n\nfunction mapConversationToDTO(conversation: Conversation): ConversationRecordDTO {\n const updatedAtIso = (conversation.updatedAt ?? new Date()).toISOString();\n const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;\n\n const history = conversation.history.map((entry, index) => {\n const turn: ConversationTurnDTO = {\n id: entry.id ?? `${conversation.id}-turn-${index}`,\n question: entry.question,\n answer: entry.answer,\n memoryUpdated: entry.memoryUpdated,\n cancelled: entry.cancelled,\n };\n\n if (entry.sourceFiles?.length) {\n turn.sourceFiles = entry.sourceFiles.map((doc) => ({\n id: doc.id,\n name: doc.name,\n }));\n }\n\n return turn;\n });\n\n return {\n id: conversation.id,\n name: conversation.name,\n model: conversation.model,\n projectId: conversation.projectId ?? null,\n history,\n summary: conversation.summary,\n tags: conversation.tags,\n metadata: conversation.metadata,\n createdAt: createdAtIso,\n updatedAt: updatedAtIso,\n version: conversation.version ?? 0,\n updatedBy: conversation.updatedBy,\n deletedAt: conversation.deletedAt ?? null,\n summaryStatus: conversation.summaryStatus,\n summaryGeneratedAt: conversation.summaryGeneratedAt ? conversation.summaryGeneratedAt.toISOString() : undefined,\n } as ConversationRecordDTO;\n}\n\nfunction mapProjectToDTO(project: Project): ProjectRecordDTO {\n const updatedAtIso = project.updatedAt?.toISOString() ?? new Date().toISOString();\n const createdAtIso = project.createdAt?.toISOString() ?? null;\n\n return {\n id: project.id,\n name: project.name,\n description: project.description,\n color: project.color,\n order: project.order,\n conversationCount: project.conversationCount,\n lastActivityAt: project.lastActivityAt ? project.lastActivityAt.toISOString() : undefined,\n summary: project.summary,\n metadata: project.metadata,\n createdAt: createdAtIso,\n updatedAt: updatedAtIso,\n version: project.version ?? 0,\n updatedBy: project.updatedBy,\n deletedAt: project.deletedAt ?? null,\n } as ProjectRecordDTO;\n}\n\nfunction mapConversationFromDTO(dto: ConversationRecordDTO): Conversation {\n return {\n id: dto.id,\n name: dto.name,\n model: dto.model,\n projectId: dto.projectId ?? undefined,\n history: dto.history.map((turn) => ({\n question: turn.question,\n answer: turn.answer,\n sourceFiles: turn.sourceFiles?.map((doc) => ({\n id: doc.id,\n name: doc.name ?? \"\",\n content: \"\",\n })),\n memoryUpdated: turn.memoryUpdated,\n cancelled: turn.cancelled,\n })),\n summary: dto.summary ?? undefined,\n tags: dto.tags ?? undefined,\n metadata: dto.metadata ?? undefined,\n createdAt: dto.createdAt ? new Date(dto.createdAt) : undefined,\n updatedAt: dto.updatedAt ? new Date(dto.updatedAt) : undefined,\n version: dto.version,\n updatedBy: dto.updatedBy,\n deletedAt: dto.deletedAt ?? undefined,\n summaryStatus: dto.summaryStatus,\n summaryGeneratedAt: dto.summaryGeneratedAt ? new Date(dto.summaryGeneratedAt) : undefined,\n } as Conversation;\n}\n\nfunction mapProjectFromDTO(dto: ProjectRecordDTO): Project {\n return {\n id: dto.id,\n name: dto.name,\n description: dto.description,\n color: dto.color,\n order: dto.order,\n createdAt: dto.createdAt ? new Date(dto.createdAt) : new Date(),\n updatedAt: dto.updatedAt ? new Date(dto.updatedAt) : new Date(),\n conversationCount: dto.conversationCount,\n lastActivityAt: dto.lastActivityAt ? new Date(dto.lastActivityAt) : undefined,\n summary: dto.summary ?? undefined,\n metadata: dto.metadata ?? undefined,\n version: dto.version,\n updatedBy: dto.updatedBy,\n deletedAt: dto.deletedAt ?? undefined,\n } as Project;\n}\n\nasync function waitForInitialHydration(): Promise<void> {\n const ready = () =>\n useConversationStore.getState()._hasHydrated &&\n useProjectStore.getState()._hasHydrated;\n\n if (ready()) {\n debugLogger.debug('conversationSyncStore: hydration already complete');\n return;\n }\n\n await new Promise<void>((resolve) => {\n const checkAndResolve = () => {\n if (ready()) {\n unsubscribeConversation();\n unsubscribeProject();\n debugLogger.debug('conversationSyncStore: hydration complete (async wait)');\n resolve();\n }\n };\n\n const unsubscribeConversation = useConversationStore.subscribe((state, prevState) => {\n if (state._hasHydrated !== prevState._hasHydrated) {\n checkAndResolve();\n }\n });\n\n const unsubscribeProject = useProjectStore.subscribe((state, prevState) => {\n if (state._hasHydrated !== prevState._hasHydrated) {\n checkAndResolve();\n }\n });\n\n debugLogger.debug('conversationSyncStore: waiting for stores hydration');\n checkAndResolve();\n });\n}\n\nfunction buildConversationMeta(conversation: Conversation): ConversationMeta {\n return {\n updatedAtMs: conversation.updatedAt ? conversation.updatedAt.getTime() : 0,\n version: conversation.version,\n historyLength: conversation.history.length,\n };\n}\n\nfunction buildProjectMeta(project: Project): ProjectMeta {\n return {\n updatedAtMs: project.updatedAt ? project.updatedAt.getTime() : 0,\n version: project.version,\n order: project.order,\n };\n}\n\nfunction snapshotConversationMetaMap(conversations: Conversation[]): Map<string, ConversationMeta> {\n return new Map(\n conversations\n // Incognito conversations are invisible to sync: never tracked, so no\n // upsert is queued when they appear and no delete when they vanish.\n .filter((conversation) => !conversation.incognito)\n .map((conversation): [string, ConversationMeta] => [\n conversation.id,\n buildConversationMeta(conversation),\n ])\n );\n}\n\nfunction snapshotProjectMetaMap(projects: Project[]): Map<string, ProjectMeta> {\n return new Map(\n projects.map((project): [string, ProjectMeta] => [\n project.id,\n buildProjectMeta(project),\n ])\n );\n}\n\nfunction ensureTrackersInitialized() {\n if (!conversationUnsubscribe) {\n const initialState = useConversationStore.getState();\n conversationsMeta = snapshotConversationMetaMap(initialState.conversations);\n\n const handleConversationChange = (\n state: ConversationStoreState,\n _prevState: ConversationStoreState\n ) => {\n const conversations = state.conversations;\n debugLogger.debug('conversationSyncStore: conversation store changed', { count: conversations.length });\n\n if (!state._hasHydrated) {\n conversationsMeta = snapshotConversationMetaMap(conversations);\n return;\n }\n\n if (suppressTracking) {\n conversationsMeta = snapshotConversationMetaMap(conversations);\n return;\n }\n\n const nextMeta = snapshotConversationMetaMap(conversations);\n for (const conversation of conversations) {\n if (conversation.incognito) continue;\n const previous = conversationsMeta.get(conversation.id);\n const updatedAtMs = conversation.updatedAt ? conversation.updatedAt.getTime() : 0;\n\n if (!previous) {\n debugLogger.debug('conversationSyncStore: detected new conversation', { id: conversation.id });\n queueConversationUpsert(conversation.id);\n continue;\n }\n\n if (\n previous.updatedAtMs !== updatedAtMs ||\n previous.version !== conversation.version ||\n previous.historyLength !== conversation.history.length\n ) {\n debugLogger.debug('conversationSyncStore: detected conversation change', { id: conversation.id });\n queueConversationUpsert(conversation.id);\n }\n }\n\n for (const id of conversationsMeta.keys()) {\n if (!nextMeta.has(id)) {\n debugLogger.debug('conversationSyncStore: detected conversation removal', { id });\n queueConversationDelete(id);\n }\n }\n\n conversationsMeta = nextMeta;\n };\n\n conversationUnsubscribe = useConversationStore.subscribe(handleConversationChange);\n handleConversationChange(initialState, initialState);\n }\n\n if (!projectUnsubscribe) {\n const initialState = useProjectStore.getState();\n projectsMeta = snapshotProjectMetaMap(initialState.projects);\n\n const handleProjectChange = (state: ProjectStoreState, _prevState: ProjectStoreState) => {\n const projects = state.projects;\n debugLogger.debug('conversationSyncStore: project store changed', { count: projects.length });\n\n if (!state._hasHydrated) {\n projectsMeta = snapshotProjectMetaMap(projects);\n return;\n }\n\n if (suppressTracking) {\n projectsMeta = snapshotProjectMetaMap(projects);\n return;\n }\n\n const nextMeta = snapshotProjectMetaMap(projects);\n for (const project of projects) {\n const previous = projectsMeta.get(project.id);\n const updatedAtMs = project.updatedAt ? project.updatedAt.getTime() : 0;\n\n if (!previous) {\n debugLogger.debug('conversationSyncStore: detected new project', { id: project.id });\n queueProjectUpsert(project.id);\n continue;\n }\n\n if (\n previous.updatedAtMs !== updatedAtMs ||\n previous.version !== project.version ||\n previous.order !== project.order\n ) {\n debugLogger.debug('conversationSyncStore: detected project change', { id: project.id });\n queueProjectUpsert(project.id);\n }\n }\n\n for (const id of projectsMeta.keys()) {\n if (!nextMeta.has(id)) {\n debugLogger.debug('conversationSyncStore: detected project removal', { id });\n queueProjectDelete(id);\n }\n }\n\n projectsMeta = nextMeta;\n };\n\n projectUnsubscribe = useProjectStore.subscribe(handleProjectChange);\n handleProjectChange(initialState, initialState);\n }\n}\n\nif (typeof window !== 'undefined') {\n window.addEventListener(CONVERSATION_UPSERT_EVENT, (event) => {\n const id = (event as CustomEvent<string>).detail;\n if (id && !suppressTracking) {\n queueConversationUpsert(id);\n }\n });\n\n window.addEventListener(CONVERSATION_DELETE_EVENT, (event) => {\n const id = (event as CustomEvent<string>).detail;\n if (id && !suppressTracking) {\n queueConversationDelete(id);\n }\n });\n\n window.addEventListener(PROJECT_UPSERT_EVENT, (event) => {\n const id = (event as CustomEvent<string>).detail;\n if (id && !suppressTracking) {\n queueProjectUpsert(id);\n }\n });\n\n window.addEventListener(PROJECT_DELETE_EVENT, (event) => {\n const id = (event as CustomEvent<string>).detail;\n if (id && !suppressTracking) {\n queueProjectDelete(id);\n }\n });\n}\n\nexport function flagConversationUpsert(id: string) {\n queueConversationUpsert(id);\n}\n\nexport function flagConversationDelete(id: string) {\n queueConversationDelete(id);\n}\n\nexport function flagProjectUpsert(id: string) {\n queueProjectUpsert(id);\n}\n\nexport function flagProjectDelete(id: string) {\n queueProjectDelete(id);\n}\n\nfunction queueConversationUpsert(id: string) {\n // Central gate: incognito conversations must never reach the cloud, no\n // matter which path (upsert event or store tracker) tried to queue them.\n const conversation = useConversationStore.getState().conversations.find((c) => c.id === id);\n if (conversation?.incognito) return;\n useConversationSyncStore.setState((state) => {\n const upserts = new Set(state.pendingConversationUpserts);\n const deletes = new Set(state.pendingConversationDeletes);\n deletes.delete(id);\n upserts.add(id);\n debugLogger.info('conversationSyncStore: queued conversation upsert', { id });\n return { pendingConversationUpserts: upserts, pendingConversationDeletes: deletes };\n });\n scheduleAutoSync();\n}\n\nfunction queueConversationDelete(id: string) {\n useConversationSyncStore.setState((state) => {\n const upserts = new Set(state.pendingConversationUpserts);\n const deletes = new Set(state.pendingConversationDeletes);\n upserts.delete(id);\n deletes.add(id);\n debugLogger.info('conversationSyncStore: queued conversation delete', { id });\n return { pendingConversationUpserts: upserts, pendingConversationDeletes: deletes };\n });\n scheduleAutoSync(true);\n}\n\nfunction queueProjectUpsert(id: string) {\n useConversationSyncStore.setState((state) => {\n const upserts = new Set(state.pendingProjectUpserts);\n const deletes = new Set(state.pendingProjectDeletes);\n deletes.delete(id);\n upserts.add(id);\n debugLogger.info('conversationSyncStore: queued project upsert', { id });\n return { pendingProjectUpserts: upserts, pendingProjectDeletes: deletes };\n });\n scheduleAutoSync();\n}\n\nfunction queueProjectDelete(id: string) {\n useConversationSyncStore.setState((state) => {\n const upserts = new Set(state.pendingProjectUpserts);\n const deletes = new Set(state.pendingProjectDeletes);\n upserts.delete(id);\n deletes.add(id);\n debugLogger.info('conversationSyncStore: queued project delete', { id });\n return { pendingProjectUpserts: upserts, pendingProjectDeletes: deletes };\n });\n scheduleAutoSync(true);\n}\n\nfunction scheduleAutoSync(prioritize = false) {\n const { syncEnabled, status } = useConversationSyncStore.getState();\n if (!syncEnabled) {\n return;\n }\n\n const delay = prioritize ? Math.min(1_000, AUTO_SYNC_DELAY_MS) : AUTO_SYNC_DELAY_MS;\n\n if (autoSyncTimeout) {\n clearTimeout(autoSyncTimeout);\n }\n\n if (status === 'syncing') {\n // Wait until current sync finishes; we'll schedule a follow-up once status changes\n autoSyncTimeout = setTimeout(() => scheduleAutoSync(prioritize), delay);\n return;\n }\n\n autoSyncTimeout = setTimeout(() => {\n autoSyncTimeout = null;\n useConversationSyncStore\n .getState()\n .runSync()\n .catch((error) => {\n debugLogger.error('conversationSyncStore: auto sync failed', { error });\n });\n }, delay);\n}\n\nasync function applyServerResults(response: ConversationSyncResponse) {\n const conversationUpserts = response.conversations.upserts.map(mapConversationFromDTO);\n const projectUpserts = response.projects.upserts.map(mapProjectFromDTO);\n\n suppressTracking = true;\n try {\n if (projectUpserts.length > 0) {\n await useProjectStore.getState().applyRemoteProjects(projectUpserts);\n projectsMeta = new Map(\n useProjectStore.getState().projects.map((project) => [project.id, buildProjectMeta(project)])\n );\n }\n\n if (conversationUpserts.length > 0) {\n await useConversationStore.getState().applyRemoteConversations(conversationUpserts);\n conversationsMeta = new Map(\n useConversationStore.getState().conversations.map((conversation) => [conversation.id, buildConversationMeta(conversation)])\n );\n }\n\n if (response.projects.deletes.length > 0) {\n await useProjectStore.getState().removeProjectsByIds(response.projects.deletes);\n projectsMeta = new Map(\n useProjectStore.getState().projects.map((project) => [project.id, buildProjectMeta(project)])\n );\n }\n\n if (response.conversations.deletes.length > 0) {\n await useConversationStore.getState().removeConversationsByIds(response.conversations.deletes);\n conversationsMeta = new Map(\n useConversationStore.getState().conversations.map((conversation) => [conversation.id, buildConversationMeta(conversation)])\n );\n }\n } finally {\n suppressTracking = false;\n }\n}\n\nexport const useConversationSyncStore = create<ConversationSyncState>((set, get) => ({\n initialized: false,\n hasLoadedPreference: false,\n initializedForToken: null,\n initializedForIdentity: null,\n syncEnabled: false,\n status: \"disabled\",\n lastSyncAt: null,\n cursor: null,\n lastError: null,\n keepLocalOnly: false,\n isAdvancedVectorFeaturesEnabled: getPackageDefaultAdvancedKnowledgeSync() ?? false,\n conflicts: null,\n deviceId: ensureDeviceId(),\n pendingConversationUpserts: new Set<string>(),\n pendingConversationDeletes: new Set<string>(),\n pendingProjectUpserts: new Set<string>(),\n pendingProjectDeletes: new Set<string>(),\n totalConversationsOnServer: undefined,\n totalProjectsOnServer: undefined,\n hasCompletedInitialUpload: false,\n warningConversations: [],\n oversizedConversations: [],\n\n async initialize() {\n ensureTrackersInitialized();\n\n const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;\n const token = authenticationService.getToken();\n const tokenIdentity = resolveAuthIdentity(token);\n const current = get();\n const storedIdentity = getStoredSyncIdentity();\n const knownIdentity = current.initializedForIdentity ?? storedIdentity;\n if (\n current.initialized &&\n current.hasLoadedPreference &&\n knownIdentity &&\n tokenIdentity &&\n knownIdentity === tokenIdentity\n ) {\n return;\n }\n\n const hasIdentitySwitch = Boolean(\n knownIdentity &&\n tokenIdentity &&\n knownIdentity !== tokenIdentity\n );\n\n if (hasIdentitySwitch) {\n clearAutoSyncTimer();\n set({\n ...buildQueueResetState(),\n syncEnabled: false,\n status: \"disabled\",\n hasLoadedPreference: false,\n initializedForToken: null,\n initializedForIdentity: tokenIdentity,\n });\n await clearLocalStoresForIdentitySwitch(\n knownIdentity as string,\n tokenIdentity as string\n );\n setStoredSyncIdentity(tokenIdentity);\n }\n\n if (!gatewayUrl) {\n debugLogger.info(\"conversationSyncStore: gateway API URL not configured; sync disabled\");\n if (tokenIdentity) {\n setStoredSyncIdentity(tokenIdentity);\n }\n set({\n ...buildQueueResetState(),\n initialized: true,\n hasLoadedPreference: false,\n initializedForToken: null,\n initializedForIdentity: tokenIdentity,\n status: \"disabled\",\n syncEnabled: false,\n });\n return;\n }\n\n if (!token) {\n debugLogger.info(\"conversationSyncStore: no authentication token; sync disabled until login\");\n clearAutoSyncTimer();\n set({\n ...buildQueueResetState(),\n initialized: true,\n hasLoadedPreference: false,\n initializedForToken: null,\n initializedForIdentity: null,\n status: \"disabled\",\n syncEnabled: false,\n });\n return;\n }\n\n try {\n await waitForInitialHydration();\n const preference = await fetchConversationSyncPreference();\n const { deviceId } = get();\n const isNewDevice = Boolean(\n preference.lastDeviceId && preference.lastDeviceId !== deviceId\n );\n\n if (isNewDevice) {\n debugLogger.info('conversationSyncStore: detected new device, resetting cursor for full hydration', {\n deviceId,\n lastDeviceId: preference.lastDeviceId,\n });\n }\n\n applyPreference(preference, set, get, {\n isNewDevice,\n override: {\n isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled,\n },\n });\n set({\n initialized: true,\n hasLoadedPreference: true,\n initializedForToken: token,\n initializedForIdentity: tokenIdentity,\n });\n setStoredSyncIdentity(tokenIdentity);\n if (preference.syncEnabled) {\n await get().runSync({ force: true });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to load conversation sync preference\";\n debugLogger.error(\"conversationSyncStore: initialization failed\", { error: message });\n set({\n initialized: true,\n hasLoadedPreference: false,\n initializedForToken: null,\n initializedForIdentity: tokenIdentity,\n status: \"error\",\n lastError: message,\n });\n }\n },\n\n async setSyncEnabled(enabled: boolean) {\n const state = get();\n const { deviceId, keepLocalOnly = false, isAdvancedVectorFeaturesEnabled } = state;\n try {\n const preference = await updateConversationSyncPreference({\n syncEnabled: enabled,\n deviceId,\n keepLocalOnly,\n isAdvancedVectorFeaturesEnabled,\n });\n const isNewDevice = Boolean(\n preference.lastDeviceId && preference.lastDeviceId !== deviceId\n );\n\n if (isNewDevice) {\n debugLogger.info('conversationSyncStore: preference updated from different device, forcing full hydration', {\n deviceId,\n lastDeviceId: preference.lastDeviceId,\n });\n }\n\n applyPreference(preference, set, get, {\n isNewDevice,\n override: {\n isAdvancedVectorFeaturesEnabled,\n },\n });\n set({\n hasLoadedPreference: true,\n initializedForToken: authenticationService.getToken(),\n initializedForIdentity: resolveAuthIdentity(authenticationService.getToken()),\n });\n setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));\n if (enabled) {\n set({ hasCompletedInitialUpload: false });\n }\n if (preference.syncEnabled) {\n await get().runSync({ force: true });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to update sync preference\";\n debugLogger.error(\"conversationSyncStore: setSyncEnabled failed\", { error: message });\n set({ status: \"error\", lastError: message });\n }\n },\n\n async setAdvancedVectorFeaturesEnabled(enabled: boolean) {\n const state = get();\n const { deviceId, keepLocalOnly = false, syncEnabled } = state;\n try {\n const preference = await updateConversationSyncPreference({\n syncEnabled,\n deviceId,\n keepLocalOnly,\n isAdvancedVectorFeaturesEnabled: enabled,\n });\n\n const isNewDevice = Boolean(\n preference.lastDeviceId && preference.lastDeviceId !== deviceId\n );\n\n if (isNewDevice) {\n debugLogger.info('conversationSyncStore: preference updated from different device, forcing full hydration', {\n deviceId,\n lastDeviceId: preference.lastDeviceId,\n });\n }\n\n applyPreference(preference, set, get, {\n isNewDevice,\n override: {\n isAdvancedVectorFeaturesEnabled: enabled,\n },\n });\n set({\n hasLoadedPreference: true,\n initializedForToken: authenticationService.getToken(),\n initializedForIdentity: resolveAuthIdentity(authenticationService.getToken()),\n });\n setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));\n if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {\n await get().runSync({ force: true });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Failed to update advanced knowledge setting\";\n debugLogger.error(\"conversationSyncStore: setAdvancedVectorFeaturesEnabled failed\", { error: message });\n set({ status: \"error\", lastError: message });\n throw error;\n }\n },\n\n async runSync({ force = false } = {}) {\n await waitForInitialHydration();\n const stateBefore = get();\n debugLogger.info('conversationSyncStore: runSync invoked', {\n force,\n syncEnabled: stateBefore.syncEnabled,\n status: stateBefore.status,\n pendingConversationUpserts: stateBefore.pendingConversationUpserts.size,\n pendingConversationDeletes: stateBefore.pendingConversationDeletes.size,\n pendingProjectUpserts: stateBefore.pendingProjectUpserts.size,\n pendingProjectDeletes: stateBefore.pendingProjectDeletes.size,\n cursor: stateBefore.cursor,\n lastSyncAt: stateBefore.lastSyncAt,\n });\n const state = get();\n if (!state.syncEnabled && !force) {\n debugLogger.info('conversationSyncStore: runSync aborted - sync disabled and not forced');\n return;\n }\n if (state.status === \"syncing\") {\n debugLogger.debug('conversationSyncStore: runSync aborted - already syncing');\n return;\n }\n\n const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;\n if (!gatewayUrl) {\n set({ status: \"error\", lastError: \"Gateway API URL is not configured.\" });\n debugLogger.error('conversationSyncStore: runSync error - missing gateway URL');\n return;\n }\n\n const token = authenticationService.getToken();\n if (!token) {\n set({ status: \"error\", lastError: \"Authentication required to sync conversations.\" });\n debugLogger.error('conversationSyncStore: runSync error - missing auth token');\n return;\n }\n const tokenIdentity = resolveAuthIdentity(token);\n if (\n state.initializedForIdentity &&\n tokenIdentity &&\n state.initializedForIdentity !== tokenIdentity\n ) {\n debugLogger.warn(\"conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing\", {\n initializedForIdentity: state.initializedForIdentity,\n tokenIdentity,\n });\n await get().initialize();\n return;\n }\n\n const pendingConversationIds = Array.from(state.pendingConversationUpserts);\n const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);\n const pendingProjectIds = Array.from(state.pendingProjectUpserts);\n const pendingProjectDeleteIds = Array.from(state.pendingProjectDeletes);\n\n const conversationStore = useConversationStore.getState();\n const projectStore = useProjectStore.getState();\n\n const conversationCandidates = pendingConversationIds\n .map((id) => conversationStore.conversations.find((c) => c.id === id))\n .filter(Boolean) as Conversation[];\n\n let {\n allowed: conversationPayloads,\n warnings: warningConversations,\n oversized: oversizedConversations,\n } = analyzeConversations(conversationCandidates);\n\n let projectPayloads = pendingProjectIds\n .map((id) => projectStore.projects.find((p) => p.id === id))\n .filter(Boolean)\n .map((project) => mapProjectToDTO(project as Project));\n\n const isInitialSync = state.cursor == null;\n const shouldBootstrapSnapshot = !state.hasCompletedInitialUpload;\n\n const payloadDebug = {\n pendingConversationIds,\n pendingConversationDeleteIds,\n pendingProjectIds,\n pendingProjectDeleteIds,\n totalConversationsLocal: conversationStore.conversations.length,\n totalProjectsLocal: projectStore.projects.length,\n isInitialSync,\n shouldBootstrapSnapshot,\n };\n debugLogger.info('conversationSyncStore: preparing sync payload', payloadDebug);\n\n if (\n (isInitialSync || shouldBootstrapSnapshot) &&\n conversationPayloads.length === 0 &&\n pendingConversationDeleteIds.length === 0 &&\n projectPayloads.length === 0 &&\n pendingProjectDeleteIds.length === 0\n ) {\n const analysis = analyzeConversations(conversationStore.conversations);\n conversationPayloads = analysis.allowed;\n warningConversations = analysis.warnings;\n oversizedConversations = analysis.oversized;\n projectPayloads = projectStore.projects.map((project) => mapProjectToDTO(project));\n const bootInfo = {\n conversationCount: conversationPayloads.length,\n projectCount: projectPayloads.length,\n };\n debugLogger.info('conversationSyncStore: bootstrapping initial snapshot', bootInfo);\n }\n\n if (!force &&\n conversationPayloads.length === 0 &&\n pendingConversationDeleteIds.length === 0 &&\n projectPayloads.length === 0 &&\n pendingProjectDeleteIds.length === 0\n ) {\n // Nothing to push; still pull deltas if cursor exists\n if (!state.cursor) {\n debugLogger.debug('conversationSyncStore: runSync early exit - nothing to push and no cursor');\n set((current) => ({\n warningConversations,\n oversizedConversations,\n lastError: oversizedConversations.length ? buildOversizedMessage(oversizedConversations) : null,\n status: oversizedConversations.length ? 'error' : current.syncEnabled ? 'idle' : current.status,\n }));\n return;\n }\n }\n\n set({ status: \"syncing\", lastError: null });\n debugLogger.info('conversationSyncStore: issuing sync request', {\n conversationUpserts: conversationPayloads.length,\n conversationDeletes: pendingConversationDeleteIds.length,\n projectUpserts: projectPayloads.length,\n projectDeletes: pendingProjectDeleteIds.length,\n cursor: state.cursor,\n });\n\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n const request: ConversationSyncRequest = {\n deviceId: state.deviceId,\n cursor: state.cursor ?? undefined,\n timezone,\n payloadVersion: PAYLOAD_VERSION,\n changes: {\n conversations: {\n upserts: conversationPayloads,\n deletes: pendingConversationDeleteIds,\n },\n projects: {\n upserts: projectPayloads,\n deletes: pendingProjectDeleteIds,\n },\n },\n };\n\n try {\n let response = await syncConversations(request);\n await applyServerResults(response);\n\n let nextCursor = response.nextCursor?.token ?? state.cursor ?? null;\n let totalConversations = response.conversations.totalCount;\n let totalProjects = response.projects.totalCount;\n let conflicts = response.conflicts;\n\n while (response.hasMore) {\n const followUpRequest: ConversationSyncRequest = {\n deviceId: state.deviceId,\n cursor: response.nextCursor?.token ?? nextCursor ?? undefined,\n timezone,\n payloadVersion: PAYLOAD_VERSION,\n changes: {\n conversations: { upserts: [], deletes: [] },\n projects: { upserts: [], deletes: [] },\n },\n };\n response = await syncConversations(followUpRequest);\n await applyServerResults(response);\n nextCursor = response.nextCursor?.token ?? nextCursor;\n totalConversations = response.conversations.totalCount;\n totalProjects = response.projects.totalCount;\n conflicts = {\n conversationConflicts: [\n ...conflicts.conversationConflicts,\n ...response.conflicts.conversationConflicts,\n ],\n projectConflicts: [\n ...conflicts.projectConflicts,\n ...response.conflicts.projectConflicts,\n ],\n };\n }\n\n const sentConversationIds = new Set(conversationPayloads.map((c) => c.id));\n const sentProjectIds = new Set(projectPayloads.map((p) => p.id));\n const sentConversationDeleteIds = new Set(pendingConversationDeleteIds);\n const sentProjectDeleteIds = new Set(pendingProjectDeleteIds);\n\n set((current) => {\n const nextConversationUpserts = new Set(current.pendingConversationUpserts);\n const nextConversationDeletes = new Set(current.pendingConversationDeletes);\n const nextProjectUpserts = new Set(current.pendingProjectUpserts);\n const nextProjectDeletes = new Set(current.pendingProjectDeletes);\n\n for (const id of sentConversationIds) {\n nextConversationUpserts.delete(id);\n }\n for (const id of sentConversationDeleteIds) {\n nextConversationDeletes.delete(id);\n }\n for (const id of sentProjectIds) {\n nextProjectUpserts.delete(id);\n }\n for (const id of sentProjectDeleteIds) {\n nextProjectDeletes.delete(id);\n }\n\n const hasOversized = oversizedConversations.length > 0;\n\n return {\n status: hasOversized ? \"error\" : current.syncEnabled ? \"idle\" : \"disabled\",\n cursor: nextCursor,\n lastSyncAt: new Date().toISOString(),\n conflicts,\n totalConversationsOnServer: totalConversations,\n totalProjectsOnServer: totalProjects,\n pendingConversationUpserts: nextConversationUpserts,\n pendingConversationDeletes: nextConversationDeletes,\n pendingProjectUpserts: nextProjectUpserts,\n pendingProjectDeletes: nextProjectDeletes,\n hasCompletedInitialUpload: true,\n warningConversations,\n oversizedConversations,\n lastError: hasOversized ? buildOversizedMessage(oversizedConversations) : null,\n };\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Conversation sync failed\";\n debugLogger.error(\"conversationSyncStore: runSync failed\", { error: message });\n set({ status: \"error\", lastError: message });\n }\n },\n\n registerError(error: string) {\n set({ status: \"error\", lastError: error });\n },\n\n clearConflicts() {\n set({ conflicts: null });\n },\n}));\n\nfunction applyPreference(\n preference: ConversationSyncPreferenceDTO,\n set: (partial: Partial<ConversationSyncState>) => void,\n getState: () => ConversationSyncState,\n options?: {\n isNewDevice?: boolean;\n override?: Partial<Pick<ConversationSyncState, 'isAdvancedVectorFeaturesEnabled'>>;\n }\n) {\n const isNewDevice = options?.isNewDevice ?? false;\n const current = getState();\n const override = options?.override ?? {};\n\n const preferenceVectorFlag = preference.isAdvancedVectorFeaturesEnabled;\n const overrideVectorFlag = override.isAdvancedVectorFeaturesEnabled;\n const packageDefaultVectorFlag = getPackageDefaultAdvancedKnowledgeSync();\n const resolvedVectorFlag =\n preferenceVectorFlag !== undefined\n ? preferenceVectorFlag\n : overrideVectorFlag !== undefined\n ? overrideVectorFlag\n : packageDefaultVectorFlag !== undefined\n ? packageDefaultVectorFlag\n : current.isAdvancedVectorFeaturesEnabled ?? false;\n\n set({\n syncEnabled: preference.syncEnabled,\n status: preference.syncEnabled ? \"idle\" : \"disabled\",\n lastSyncAt: isNewDevice ? null : preference.lastSyncAt ?? null,\n cursor: isNewDevice ? null : preference.cursor ?? null,\n keepLocalOnly: preference.keepLocalOnly,\n isAdvancedVectorFeaturesEnabled: resolvedVectorFlag,\n lastError: null,\n hasCompletedInitialUpload:\n preference.syncEnabled && preference.lastSyncAt != null && !isNewDevice,\n warningConversations: [],\n oversizedConversations: [],\n });\n}\n\nfunction analyzeConversations(conversations: Conversation[]): {\n allowed: ConversationRecordDTO[];\n warnings: ConversationSizeNotice[];\n oversized: ConversationSizeNotice[];\n} {\n const allowed: ConversationRecordDTO[] = [];\n const warnings: ConversationSizeNotice[] = [];\n const oversized: ConversationSizeNotice[] = [];\n const encoder = new TextEncoder();\n\n for (const conversation of conversations) {\n const dto = mapConversationToDTO(conversation);\n const sizeBytes = encoder.encode(JSON.stringify(dto)).length;\n const notice: ConversationSizeNotice = {\n id: conversation.id,\n name: conversation.name,\n sizeBytes,\n limitBytes: MAX_CONVERSATION_BYTES,\n };\n if (sizeBytes >= MAX_CONVERSATION_BYTES) {\n oversized.push(notice);\n continue;\n }\n if (sizeBytes >= WARN_CONVERSATION_BYTES) {\n warnings.push(notice);\n }\n allowed.push(dto);\n }\n\n return { allowed, warnings, oversized };\n}\n\nfunction buildOversizedMessage(notices: ConversationSizeNotice[]): string {\n if (!notices.length) {\n return '';\n }\n const names = notices.map((n) => `\"${n.name || 'Untitled'}\"`).join(', ');\n return `Some conversations (${names}) are too large for Bandit Cloud. Start a new conversation or archive older turns to continue syncing.`;\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { HistoryEntry, useAIQueryStore } from \"./aiQueryStore\";\nimport { useModelStore } from \"./modelStore\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { KnowledgeDoc } from \"./knowledgeStore\";\nimport { runConversationMigrations } from \"../util/conversationMigration\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { CONVERSATION_DELETE_EVENT, CONVERSATION_UPSERT_EVENT } from \"./conversationSyncEvents\";\n\nexport interface Conversation {\n id: string;\n name: string;\n model: string;\n history: HistoryEntry[];\n projectId?: string; // Optional for backward compatibility\n createdAt?: Date;\n updatedAt?: Date;\n version?: number;\n summary?: string;\n tags?: string[];\n metadata?: Record<string, unknown>;\n updatedBy?: string;\n deletedAt?: string | null;\n summaryStatus?: string;\n summaryGeneratedAt?: Date;\n /**\n * Incognito conversations live only in memory: never written to IndexedDB,\n * never synced to Bandit Cloud, never listed in conversation history, and\n * auto-memory capture is skipped. Gone on reload or when toggled off.\n */\n incognito?: boolean;\n}\n\ninterface ConversationStore {\n conversations: Conversation[];\n currentId: string | null;\n _hasHydrated: boolean;\n createConversation: (firstMessage: string, projectId?: string) => void;\n createNewConversation: (projectId?: string) => void;\n /** Start an incognito conversation, or — if one is current — exit and discard it. */\n toggleIncognito: () => void;\n deleteConversation: (id: string) => void;\n switchConversation: (id: string) => void;\n addToCurrent: (entry: HistoryEntry) => void;\n replaceLastAnswer: (answer: string, images?: string[], memoryUpdated?: boolean, sourceFiles?: KnowledgeDoc[], cancelled?: boolean) => void;\n setCurrent: (id: string) => void;\n renameConversation: (id: string, newName: string) => void;\n clearAllConversations: () => Promise<void>;\n moveConversationToProject: (conversationId: string, projectId: string | null) => void;\n getConversationsByProject: (projectId: string | null) => Conversation[];\n hydrate: () => Promise<void>;\n applyRemoteConversations: (conversations: Conversation[]) => Promise<void>;\n removeConversationsByIds: (ids: string[]) => Promise<void>;\n}\n\nconst DB_NAME = \"bandit-conversations\";\nconst STORE_NAME = \"conversations\";\nconst DB_VERSION = 1;\nconst storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n\nexport const EMOJI_REGEX = /\\p{Extended_Pictographic}/gu;\nexport const VARIATION_SELECTORS_REGEX = /[\\uFE0F\\uFE0E]/g;\nexport const ZERO_WIDTH_JOINER_REGEX = /\\u200D/g;\n\nexport function sanitizeConversationName(input: string | undefined | null, maxLength = 60): string {\n if (!input) return \"Untitled Conversation\";\n\n const withoutEmoji = input\n .replace(EMOJI_REGEX, \"\")\n .replace(VARIATION_SELECTORS_REGEX, \"\")\n .replace(ZERO_WIDTH_JOINER_REGEX, \"\");\n\n const normalized = withoutEmoji.normalize(\"NFC\").trim().replace(/\\s+/g, \" \");\n\n if (!normalized) {\n return \"Untitled Conversation\";\n }\n\n const limited = Array.from(normalized).slice(0, maxLength).join(\"\");\n return limited || \"Untitled Conversation\";\n}\n\nasync function loadConversations(): Promise<Conversation[]> {\n const raw = await indexedDBService.getAll<Conversation>(DB_NAME, DB_VERSION, STORE_NAME, storeConfigs);\n return (raw || []).map(normalizeConversation);\n}\n\nasync function saveConversation(conversation: Conversation) {\n // Incognito conversations are memory-only — never touch disk.\n if (conversation.incognito) return;\n await indexedDBService.put(DB_NAME, DB_VERSION, STORE_NAME, conversation, storeConfigs);\n}\n\nasync function deleteConversationFromDB(id: string) {\n await indexedDBService.delete(DB_NAME, DB_VERSION, STORE_NAME, id, storeConfigs);\n}\n\nexport const useConversationStore = create<ConversationStore>((set, get) => ({\n conversations: [],\n currentId: null,\n _hasHydrated: false,\n\n hydrate: async () => {\n try {\n // Run migrations first to ensure backward compatibility\n await runConversationMigrations();\n \n const conversations = await loadConversations();\n set({ conversations, _hasHydrated: true });\n } catch (error) {\n console.error(\"Failed to hydrate conversations:\", error);\n set({ conversations: [], _hasHydrated: true });\n }\n },\n\n createConversation: (firstMessage: string, projectId?: string) => {\n const id = uuidv4();\n const { selectedModel } = useModelStore.getState();\n const sanitizedFirstMessage = sanitizeConversationName(firstMessage, 60);\n const name = sanitizedFirstMessage;\n const now = new Date();\n const newConv = normalizeConversation({ \n id, \n name, \n history: [], \n model: selectedModel,\n projectId,\n createdAt: now,\n updatedAt: now,\n version: 0,\n });\n set((state) => {\n const updatedConversations = [...state.conversations, newConv];\n saveConversation(newConv);\n emitConversationUpsert(id);\n return {\n conversations: updatedConversations,\n currentId: id,\n };\n });\n },\n\n createNewConversation: (projectId?: string) => {\n const { selectedModel } = useModelStore.getState();\n const id = uuidv4();\n const now = new Date();\n const newConv = normalizeConversation({\n id,\n name: \"New Conversation\",\n history: [],\n model: selectedModel,\n projectId,\n createdAt: now,\n updatedAt: now,\n version: 0,\n });\n set((state) => {\n const updatedConversations = [...state.conversations, newConv];\n saveConversation(newConv);\n emitConversationUpsert(id);\n return {\n conversations: updatedConversations,\n currentId: id,\n };\n });\n },\n\n toggleIncognito: () => {\n const { conversations, currentId } = get();\n const current = conversations.find((c) => c.id === currentId);\n if (current?.incognito) {\n // Exit incognito: discard every incognito conversation from memory.\n useAIQueryStore.getState().reset();\n set((state) => ({\n conversations: state.conversations.filter((c) => !c.incognito),\n currentId: null,\n }));\n return;\n }\n const { selectedModel } = useModelStore.getState();\n const now = new Date();\n const newConv = normalizeConversation({\n id: uuidv4(),\n name: \"Temporary chat\",\n history: [],\n model: selectedModel,\n createdAt: now,\n updatedAt: now,\n version: 0,\n incognito: true,\n });\n set((state) => ({\n conversations: [...state.conversations, newConv],\n currentId: newConv.id,\n }));\n },\n\n deleteConversation: (id: string) => {\n const runHydrate = async () => {\n try {\n await get().hydrate();\n } catch (error) {\n debugLogger.warn(\"conversationStore: rehydrate after delete failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n set((state) => {\n const filtered = state.conversations.filter((c) => c.id !== id);\n const isDeletingCurrent = state.currentId === id;\n\n if (isDeletingCurrent) {\n useAIQueryStore.getState().reset();\n }\n\n deleteConversationFromDB(id)\n .then(runHydrate)\n .catch((error) => {\n debugLogger.error(\"Failed to delete conversation from DB\", {\n error,\n conversationId: id,\n });\n });\n emitConversationDelete(id);\n\n return {\n conversations: filtered,\n currentId: isDeletingCurrent ? null : state.currentId,\n };\n });\n },\n\n switchConversation: (id: string) => {\n const { conversations } = get();\n const { setSelectedModel } = useModelStore.getState();\n const selectedModel = conversations.find((c) => c.id === id)?.model;\n selectedModel && setSelectedModel(selectedModel);\n set({ currentId: id });\n },\n\n addToCurrent: (entry: HistoryEntry) => {\n const { currentId, conversations } = get();\n if (!currentId) return;\n set(() => {\n const updatedConversations = conversations.map((c) =>\n c.id === currentId ? normalizeConversation({ ...c, history: [...c.history, entry], updatedAt: new Date() }) : c\n );\n const updatedConv = updatedConversations.find((c) => c.id === currentId);\n if (updatedConv) {\n saveConversation(updatedConv);\n emitConversationUpsert(updatedConv.id);\n }\n return { conversations: updatedConversations };\n });\n },\n\n renameConversation: (id: string, newName: string) => {\n set((state) => {\n const sanitized = sanitizeConversationName(newName);\n const updatedConversations = state.conversations.map((c) =>\n c.id === id ? normalizeConversation({ ...c, name: sanitized, updatedAt: new Date() }) : c\n );\n const updatedConv = updatedConversations.find((c) => c.id === id);\n if (updatedConv) {\n saveConversation(updatedConv);\n emitConversationUpsert(updatedConv.id);\n }\n return { conversations: updatedConversations };\n });\n },\n\n replaceLastAnswer: (answer: string, images?: string[], memoryUpdated?: boolean, sourceFiles?: KnowledgeDoc[], cancelled?: boolean) => {\n const { currentId, conversations } = get();\n if (!currentId) return;\n set(() => {\n const updatedConversations = conversations.map((c) => {\n if (c.id === currentId && c.history.length > 0) {\n const updatedHistory = [...c.history];\n const existingImages = updatedHistory[updatedHistory.length - 1].images;\n const nextImages =\n Array.isArray(images) && images.length > 0\n ? [...images]\n : Array.isArray(existingImages) && existingImages.length > 0\n ? [...existingImages]\n : existingImages;\n updatedHistory[updatedHistory.length - 1] = {\n ...updatedHistory[updatedHistory.length - 1],\n answer,\n memoryUpdated,\n images: nextImages,\n sourceFiles: sourceFiles ?? updatedHistory[updatedHistory.length - 1].sourceFiles,\n cancelled: cancelled ?? updatedHistory[updatedHistory.length - 1].cancelled,\n placeholder: false,\n rawQuestion: undefined,\n };\n return normalizeConversation({ ...c, history: updatedHistory, updatedAt: new Date() });\n }\n return c;\n });\n const updatedConv = updatedConversations.find((c) => c.id === currentId);\n if (updatedConv) {\n saveConversation(updatedConv);\n emitConversationUpsert(updatedConv.id);\n }\n return { conversations: updatedConversations };\n });\n },\n\n setCurrent: (id: string) => set({ currentId: id }),\n\n moveConversationToProject: (conversationId: string, projectId: string | null) => {\n set((state) => {\n const updatedConversations = state.conversations.map((c) =>\n c.id === conversationId \n ? normalizeConversation({ ...c, projectId: projectId || undefined, updatedAt: new Date() }) \n : c\n );\n const updatedConv = updatedConversations.find((c) => c.id === conversationId);\n if (updatedConv) {\n saveConversation(updatedConv);\n }\n return { conversations: updatedConversations };\n });\n },\n\n clearAllConversations: async () => {\n try {\n // Clear all conversations from IndexedDB\n await indexedDBService.clear(DB_NAME, DB_VERSION, STORE_NAME, storeConfigs);\n \n // Reset store state\n set({\n conversations: [],\n currentId: null,\n });\n \n debugLogger.info(\"All conversations cleared successfully\");\n } catch (error) {\n debugLogger.error(\"Failed to clear all conversations\", { error });\n throw error;\n }\n },\n\n getConversationsByProject: (projectId: string | null) => {\n const { conversations } = get();\n if (projectId === null) {\n // Return conversations without a project (ungrouped)\n return conversations.filter(c => !c.projectId);\n }\n return conversations.filter(c => c.projectId === projectId);\n },\n\n applyRemoteConversations: async (incoming) => {\n const normalized = incoming.map(normalizeConversation);\n const toPersist: Conversation[] = [];\n\n set((state) => {\n const next = new Map(state.conversations.map((c) => [c.id, c] as const));\n\n for (const conversation of normalized) {\n const existing = next.get(conversation.id);\n\n if (existing) {\n const existingUpdatedAt = existing.updatedAt ? existing.updatedAt.getTime() : 0;\n const incomingUpdatedAt = conversation.updatedAt ? conversation.updatedAt.getTime() : 0;\n const existingHistoryLength = existing.history?.length ?? 0;\n const incomingHistoryLength = conversation.history?.length ?? 0;\n\n const incomingHasMoreHistory = incomingHistoryLength > existingHistoryLength;\n const incomingIsNewer = incomingUpdatedAt > existingUpdatedAt;\n\n if (incomingIsNewer && incomingHistoryLength < existingHistoryLength) {\n debugLogger.info(\"applyRemoteConversations: preserving local history over shorter incoming\", {\n conversationId: conversation.id,\n existingHistoryLength,\n incomingHistoryLength,\n existingUpdatedAt,\n incomingUpdatedAt,\n });\n conversation.history = existing.history;\n }\n\n if (!incomingHasMoreHistory && !incomingIsNewer) {\n debugLogger.info(\"applyRemoteConversations: skipping stale conversation\", {\n conversationId: conversation.id,\n existingHistoryLength,\n incomingHistoryLength,\n existingUpdatedAt,\n incomingUpdatedAt,\n });\n continue;\n }\n\n // Preserve local-only metadata (e.g., inline images) when remote payload omits it\n if (Array.isArray(existing.history) && Array.isArray(conversation.history)) {\n const mergedHistory = conversation.history.map((incomingEntry, index) => {\n const existingEntry = existing.history[index];\n if (!existingEntry) {\n return incomingEntry;\n }\n\n const mergedImagesSource =\n Array.isArray(incomingEntry.images) && incomingEntry.images.length > 0\n ? incomingEntry.images\n : existingEntry.images;\n const mergedImages =\n Array.isArray(mergedImagesSource) && mergedImagesSource.length > 0\n ? [...mergedImagesSource]\n : mergedImagesSource;\n\n return {\n ...existingEntry,\n ...incomingEntry,\n images: mergedImages,\n placeholder:\n incomingEntry.placeholder ?? existingEntry.placeholder,\n rawQuestion:\n incomingEntry.rawQuestion ?? existingEntry.rawQuestion,\n };\n });\n\n conversation.history = mergedHistory;\n }\n }\n\n next.set(conversation.id, conversation);\n toPersist.push(conversation);\n }\n\n return { conversations: Array.from(next.values()) };\n });\n\n if (toPersist.length > 0) {\n try {\n await Promise.all(toPersist.map((conversation) => saveConversation(conversation)));\n } catch (error) {\n debugLogger.error(\"Failed to persist remote conversations\", { error, conversationIds: toPersist.map((c) => c.id) });\n }\n }\n },\n\n removeConversationsByIds: async (ids) => {\n if (!ids.length) {\n return;\n }\n\n try {\n await Promise.all(ids.map((id) => deleteConversationFromDB(id)));\n } catch (error) {\n debugLogger.error(\"Failed to remove conversations from IndexedDB\", { error, ids });\n }\n\n set((state) => {\n const filtered = state.conversations.filter((c) => !ids.includes(c.id));\n const isCurrentDeleted = state.currentId ? ids.includes(state.currentId) : false;\n ids.forEach((id) => emitConversationDelete(id));\n return {\n conversations: filtered,\n currentId: isCurrentDeleted ? null : state.currentId,\n };\n });\n\n try {\n await get().hydrate();\n } catch (error) {\n debugLogger.warn(\"conversationStore: hydrate failed after remote delete\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n}));\n\nfunction normalizeConversation(conversation: Conversation): Conversation {\n const ensureDate = (value?: Date | string | null): Date | undefined => {\n if (!value) return undefined;\n if (value instanceof Date) return value;\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? undefined : parsed;\n };\n\n return {\n ...conversation,\n name: sanitizeConversationName(conversation.name),\n createdAt: ensureDate(conversation.createdAt) ?? new Date(),\n updatedAt: ensureDate(conversation.updatedAt) ?? new Date(),\n summaryGeneratedAt: ensureDate(conversation.summaryGeneratedAt),\n history: Array.isArray(conversation.history)\n ? conversation.history.map((turn) => ({\n ...turn,\n }))\n : [],\n };\n}\nfunction emitConversationUpsert(id: string) {\n if (typeof window === 'undefined') return;\n window.dispatchEvent(new CustomEvent(CONVERSATION_UPSERT_EVENT, { detail: id }));\n}\n\nfunction emitConversationDelete(id: string) {\n if (typeof window === 'undefined') return;\n window.dispatchEvent(new CustomEvent(CONVERSATION_DELETE_EVENT, { detail: id }));\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { KnowledgeDoc } from \"./knowledgeStore\";\n\nexport type Position = { x: number; y: number };\nexport type HistoryEntry = {\n id?: string;\n question: string;\n answer: string;\n images?: string[];\n sourceFiles?: KnowledgeDoc[];\n memoryUpdated?: boolean;\n cancelled?: boolean;\n /**\n * Internal metadata so streaming can replace placeholders even when the display question differs\n */\n placeholder?: boolean;\n /**\n * Raw prompt text sent to the model (used when the display question is formatted differently)\n */\n rawQuestion?: string;\n};\n\nexport type ComponentStatus = \"Idle\" | \"Loading\" | \"Error\";\n\ninterface AIQueryState {\n inputValue: string;\n response: string;\n previousQuestion: string;\n position: Position;\n componentStatus: ComponentStatus;\n history: HistoryEntry[];\n apiKey: string;\n hydrated: boolean;\n\n setInputValue: (value: string) => void;\n setResponse: (response: string) => void;\n setPreviousQuestion: (question: string) => void;\n setPosition: (position: Position) => void;\n setComponentStatus: (status: ComponentStatus) => void;\n addHistory: (entry: HistoryEntry) => void;\n clearHistory: () => void;\n setApiKey: (key: string) => void;\n setHydrated: () => void;\n reset: () => void;\n hydrate: () => Promise<void>;\n}\n\nconst DB_NAME = \"ai-query-db\";\nconst STORE_NAME = \"ai-query\";\nconst DB_VERSION = 1;\nconst STORAGE_KEY = \"singleton\";\n\nconst storeConfigs = [{ name: STORE_NAME }];\n\nasync function saveStateToDB(state: Partial<AIQueryState>) {\n await indexedDBService.put(DB_NAME, DB_VERSION, STORE_NAME, state, storeConfigs, STORAGE_KEY);\n}\n\nasync function loadStateFromDB(): Promise<Partial<AIQueryState> | undefined> {\n let timeoutId: number | undefined;\n const timeoutPromise = new Promise<undefined>((resolve) => {\n timeoutId = window.setTimeout(() => resolve(undefined), 1200);\n });\n\n try {\n const getPromise = indexedDBService\n .get<Partial<AIQueryState>>(DB_NAME, DB_VERSION, STORE_NAME, STORAGE_KEY, storeConfigs)\n .catch(() => undefined);\n\n return await Promise.race([getPromise, timeoutPromise]);\n } finally {\n if (timeoutId !== undefined) {\n window.clearTimeout(timeoutId);\n }\n }\n}\n\nexport const useAIQueryStore = create<AIQueryState>((set, get) => ({\n inputValue: \"\",\n response: \"\",\n previousQuestion: \"\",\n position: { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },\n componentStatus: \"Idle\",\n history: [],\n apiKey: \"\",\n hydrated: false,\n\n setInputValue: (value) => {\n set({ inputValue: value });\n saveStateToDB({ inputValue: value });\n },\n setResponse: (response) => {\n set({ response });\n saveStateToDB({ response });\n },\n setPreviousQuestion: (question) => {\n set({ previousQuestion: question });\n saveStateToDB({ previousQuestion: question });\n },\n setPosition: (position) => {\n set({ position });\n saveStateToDB({ position });\n },\n setComponentStatus: (status) => set({ componentStatus: status }),\n addHistory: (entry) => {\n const newHistory = [...get().history, entry];\n set({ history: newHistory });\n saveStateToDB({ history: newHistory });\n },\n clearHistory: () => {\n set({ history: [] });\n saveStateToDB({ history: [] });\n },\n setApiKey: (key) => {\n set({ apiKey: key });\n saveStateToDB({ apiKey: key });\n },\n setHydrated: () => set({ hydrated: true }),\n\n reset: () => {\n const resetState = {\n inputValue: \"\",\n response: \"\",\n previousQuestion: \"\",\n position: { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },\n componentStatus: \"Idle\",\n history: [],\n apiKey: \"\",\n } as Partial<AIQueryState>;\n set(resetState);\n saveStateToDB(resetState);\n },\n\n hydrate: async () => {\n try {\n const storedState = await loadStateFromDB();\n if (storedState) {\n set({\n inputValue: storedState.inputValue ?? \"\",\n response: storedState.response ?? \"\",\n previousQuestion: storedState.previousQuestion ?? \"\",\n position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },\n componentStatus: \"Idle\",\n history: storedState.history ?? [],\n apiKey: storedState.apiKey ?? \"\",\n hydrated: true,\n });\n } else {\n set({ hydrated: true });\n }\n } catch {\n set({ hydrated: true });\n }\n },\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport type { HistoryEntry } from \"../store/aiQueryStore\";\n\n/**\n * Migration utility to ensure backward compatibility for conversations\n * that were created before the projects feature was added.\n */\n\nexport interface ConversationV1 {\n id: string;\n name: string;\n model: string;\n history: HistoryEntry[];\n}\n\nexport interface ConversationV2 {\n id: string;\n name: string;\n model: string;\n history: HistoryEntry[];\n projectId?: string;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nconst DB_NAME = \"bandit-conversations\";\nconst STORE_NAME = \"conversations\";\nconst DB_VERSION = 1;\nconst storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n\n/**\n * Migrates conversations from V1 format (without projects) to V2 format (with projects)\n */\nexport async function migrateConversationsToV2(): Promise<boolean> {\n try {\n debugLogger.info(\"Starting conversation migration to V2 format\");\n \n const conversations = await indexedDBService.getAll<ConversationV1 | ConversationV2>(\n DB_NAME, \n DB_VERSION, \n STORE_NAME, \n storeConfigs\n );\n\n if (!conversations || conversations.length === 0) {\n debugLogger.info(\"No conversations found, migration not needed\");\n return true;\n }\n\n let migratedCount = 0;\n const now = new Date();\n\n for (const conversation of conversations) {\n // Check if conversation needs migration (missing V2 fields)\n const needsMigration = \n !conversation.hasOwnProperty('createdAt') || \n !conversation.hasOwnProperty('updatedAt');\n\n if (needsMigration) {\n const migratedConversation: ConversationV2 = {\n ...conversation,\n // projectId remains undefined (ungrouped)\n createdAt: now, // We can't know the real creation date\n updatedAt: now,\n };\n\n await indexedDBService.put(\n DB_NAME, \n DB_VERSION, \n STORE_NAME, \n migratedConversation, \n storeConfigs\n );\n\n migratedCount++;\n debugLogger.debug(\"Migrated conversation\", { \n id: conversation.id, \n name: conversation.name \n });\n } else if ('createdAt' in conversation && conversation.createdAt && typeof conversation.createdAt === 'string') {\n // Convert string dates back to Date objects if needed\n const fixedConversation: ConversationV2 = {\n ...(conversation as ConversationV2),\n createdAt: new Date(conversation.createdAt),\n updatedAt: new Date((conversation as ConversationV2).updatedAt || conversation.createdAt),\n };\n\n await indexedDBService.put(\n DB_NAME, \n DB_VERSION, \n STORE_NAME, \n fixedConversation, \n storeConfigs\n );\n\n migratedCount++;\n debugLogger.debug(\"Fixed date format for conversation\", { \n id: conversation.id, \n name: conversation.name \n });\n }\n }\n\n if (migratedCount > 0) {\n debugLogger.info(\"Conversation migration completed\", { \n totalConversations: conversations.length,\n migratedCount \n });\n } else {\n debugLogger.info(\"All conversations already up to date\");\n }\n\n return true;\n } catch (error) {\n debugLogger.error(\"Failed to migrate conversations\", { error });\n return false;\n }\n}\n\n/**\n * Validates that all conversations have the expected V2 structure\n */\nexport async function validateConversationStructure(): Promise<boolean> {\n try {\n const conversations = await indexedDBService.getAll<ConversationV2>(\n DB_NAME, \n DB_VERSION, \n STORE_NAME, \n storeConfigs\n );\n\n if (!conversations) {\n return true; // No conversations to validate\n }\n\n for (const conversation of conversations) {\n const isValid = \n typeof conversation.id === 'string' &&\n typeof conversation.name === 'string' &&\n typeof conversation.model === 'string' &&\n Array.isArray(conversation.history) &&\n (conversation.projectId === undefined || typeof conversation.projectId === 'string') &&\n (conversation.createdAt === undefined || conversation.createdAt instanceof Date) &&\n (conversation.updatedAt === undefined || conversation.updatedAt instanceof Date);\n\n if (!isValid) {\n debugLogger.warn(\"Invalid conversation structure detected\", { \n conversationId: conversation.id,\n structure: {\n hasId: typeof conversation.id === 'string',\n hasName: typeof conversation.name === 'string',\n hasModel: typeof conversation.model === 'string',\n hasHistory: Array.isArray(conversation.history),\n projectIdValid: conversation.projectId === undefined || typeof conversation.projectId === 'string',\n createdAtValid: conversation.createdAt === undefined || conversation.createdAt instanceof Date,\n updatedAtValid: conversation.updatedAt === undefined || conversation.updatedAt instanceof Date,\n }\n });\n return false;\n }\n }\n\n debugLogger.info(\"All conversations have valid structure\", { \n count: conversations.length \n });\n return true;\n } catch (error) {\n debugLogger.error(\"Failed to validate conversation structure\", { error });\n return false;\n }\n}\n\n/**\n * Runs all necessary migrations for conversations\n */\nexport async function runConversationMigrations(): Promise<boolean> {\n try {\n debugLogger.info(\"Running conversation migrations\");\n \n const migrationSuccess = await migrateConversationsToV2();\n if (!migrationSuccess) {\n debugLogger.error(\"Conversation migration failed\");\n return false;\n }\n\n const validationSuccess = await validateConversationStructure();\n if (!validationSuccess) {\n debugLogger.warn(\"Conversation validation failed, but continuing\");\n }\n\n debugLogger.info(\"Conversation migrations completed successfully\");\n return true;\n } catch (error) {\n debugLogger.error(\"Migration process failed\", { error });\n return false;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nexport const CONVERSATION_UPSERT_EVENT = 'bandit-conversation-upsert';\nexport const CONVERSATION_DELETE_EVENT = 'bandit-conversation-delete';\nexport const PROJECT_UPSERT_EVENT = 'bandit-project-upsert';\nexport const PROJECT_DELETE_EVENT = 'bandit-project-delete';\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport {\n PROJECT_DELETE_EVENT,\n PROJECT_UPSERT_EVENT,\n} from \"./conversationSyncEvents\";\n\nexport interface Project {\n id: string;\n name: string;\n description?: string;\n instructions?: string;\n color?: string;\n createdAt: Date;\n updatedAt: Date;\n order: number;\n version?: number;\n conversationCount?: number;\n lastActivityAt?: Date;\n summary?: string;\n metadata?: Record<string, unknown>;\n updatedBy?: string;\n deletedAt?: string | null;\n}\n\ninterface ProjectStore {\n projects: Project[];\n _hasHydrated: boolean;\n \n // Actions\n createProject: (name: string, description?: string, color?: string) => Promise<Project>;\n deleteProject: (id: string) => Promise<void>;\n renameProject: (id: string, newName: string, description?: string) => Promise<void>;\n updateProjectColor: (id: string, color: string) => Promise<void>;\n updateProjectInstructions: (id: string, instructions: string) => Promise<void>;\n reorderProjects: (projectIds: string[]) => Promise<void>;\n hydrate: () => Promise<void>;\n applyRemoteProjects: (projects: Project[]) => Promise<void>;\n removeProjectsByIds: (ids: string[]) => Promise<void>;\n}\n\nconst DB_NAME = \"bandit-projects\";\nconst STORE_NAME = \"projects\";\nconst DB_VERSION = 1;\nconst storeConfigs = [{ name: STORE_NAME, keyPath: \"id\" }];\n\n// Default colors for projects\nconst DEFAULT_COLORS = [\n \"#2196F3\", // Blue\n \"#4CAF50\", // Green\n \"#FF9800\", // Orange\n \"#9C27B0\", // Purple\n \"#F44336\", // Red\n \"#00BCD4\", // Cyan\n \"#FFEB3B\", // Yellow\n \"#795548\", // Brown\n \"#607D8B\", // Blue Grey\n \"#E91E63\", // Pink\n];\n\nasync function loadProjects(): Promise<Project[]> {\n try {\n const projects = await indexedDBService.getAll<Project>(DB_NAME, DB_VERSION, STORE_NAME, storeConfigs);\n return (projects || []).map(normalizeProject).sort((a, b) => a.order - b.order);\n } catch (error) {\n debugLogger.error(\"Failed to load projects\", { error });\n return [];\n }\n}\n\nasync function saveProject(project: Project) {\n try {\n await indexedDBService.put(DB_NAME, DB_VERSION, STORE_NAME, project, storeConfigs);\n debugLogger.info(\"Project saved\", { projectId: project.id, projectName: project.name });\n } catch (error) {\n debugLogger.error(\"Failed to save project\", { projectId: project.id, error });\n throw error;\n }\n}\n\nasync function deleteProjectFromDB(id: string) {\n try {\n await indexedDBService.delete(DB_NAME, DB_VERSION, STORE_NAME, id, storeConfigs);\n debugLogger.info(\"Project deleted from DB\", { projectId: id });\n } catch (error) {\n debugLogger.error(\"Failed to delete project from DB\", { projectId: id, error });\n throw error;\n }\n}\n\nexport const useProjectStore = create<ProjectStore>((set, get) => ({\n projects: [],\n _hasHydrated: false,\n\n hydrate: async () => {\n try {\n const projects = await loadProjects();\n set({ projects, _hasHydrated: true });\n debugLogger.info(\"Project store hydrated\", { projectCount: projects.length });\n } catch (error) {\n debugLogger.error(\"Failed to hydrate project store\", { error });\n set({ projects: [], _hasHydrated: true });\n }\n },\n\n createProject: async (name: string, description?: string, color?: string) => {\n const { projects } = get();\n const id = uuidv4();\n const now = new Date();\n \n // Assign a default color if not provided\n const projectColor = color || DEFAULT_COLORS[projects.length % DEFAULT_COLORS.length];\n \n const newProject: Project = normalizeProject({\n id,\n name: name.trim(),\n description: description?.trim(),\n color: projectColor,\n createdAt: now,\n updatedAt: now,\n order: projects.length,\n version: 0,\n });\n\n await saveProject(newProject);\n\n set((state) => ({\n projects: [...state.projects, newProject],\n }));\n emitProjectUpsert(id);\n\n debugLogger.info(\"Project created\", { projectId: id, projectName: name });\n return newProject;\n },\n\n deleteProject: async (id: string) => {\n await deleteProjectFromDB(id);\n \n set((state) => ({\n projects: state.projects.filter((p) => p.id !== id),\n }));\n\n debugLogger.info(\"Project deleted\", { projectId: id });\n emitProjectDelete(id);\n },\n\n renameProject: async (id: string, newName: string, description?: string) => {\n const { projects } = get();\n const project = projects.find(p => p.id === id);\n \n if (!project) {\n throw new Error(`Project with id ${id} not found`);\n }\n\n const updatedProject = normalizeProject({\n ...project,\n name: newName.trim(),\n description: description?.trim(),\n updatedAt: new Date(),\n });\n\n await saveProject(updatedProject);\n \n set((state) => ({\n projects: state.projects.map((p) =>\n p.id === id ? updatedProject : p\n ),\n }));\n\n debugLogger.info(\"Project renamed\", { projectId: id, newName });\n emitProjectUpsert(id);\n },\n\n updateProjectColor: async (id: string, color: string) => {\n const { projects } = get();\n const project = projects.find(p => p.id === id);\n \n if (!project) {\n throw new Error(`Project with id ${id} not found`);\n }\n\n const updatedProject = normalizeProject({\n ...project,\n color,\n updatedAt: new Date(),\n });\n\n await saveProject(updatedProject);\n \n set((state) => ({\n projects: state.projects.map((p) =>\n p.id === id ? updatedProject : p\n ),\n }));\n\n debugLogger.info(\"Project color updated\", { projectId: id, color });\n emitProjectUpsert(id);\n },\n\n updateProjectInstructions: async (id: string, instructions: string) => {\n const { projects } = get();\n const project = projects.find((p) => p.id === id);\n if (!project) {\n throw new Error(`Project with id ${id} not found`);\n }\n\n const updatedProject = normalizeProject({\n ...project,\n instructions: instructions.trim() || undefined,\n updatedAt: new Date(),\n });\n\n await saveProject(updatedProject);\n\n set((state) => ({\n projects: state.projects.map((p) => (p.id === id ? updatedProject : p)),\n }));\n\n debugLogger.info(\"Project instructions updated\", { projectId: id });\n emitProjectUpsert(id);\n },\n\n reorderProjects: async (projectIds: string[]) => {\n const { projects } = get();\n const reorderedProjects = projectIds.map((id, index) => {\n const project = projects.find(p => p.id === id);\n if (!project) return null;\n return normalizeProject({ ...project, order: index, updatedAt: new Date() });\n }).filter(Boolean) as Project[];\n\n // Save all reordered projects\n await Promise.all(reorderedProjects.map(saveProject));\n \n set({ projects: reorderedProjects });\n debugLogger.info(\"Projects reordered\", { projectCount: reorderedProjects.length });\n reorderedProjects.forEach((project) => emitProjectUpsert(project.id));\n },\n\n applyRemoteProjects: async (incoming) => {\n const normalized = incoming.map(normalizeProject);\n\n try {\n await Promise.all(normalized.map((project) => saveProject(project)));\n } catch (error) {\n debugLogger.error(\"Failed to persist remote projects\", { error });\n }\n\n set((state) => {\n const next = new Map(state.projects.map((p) => [p.id, p] as const));\n for (const project of normalized) {\n next.set(project.id, project);\n }\n return { projects: Array.from(next.values()).sort((a, b) => a.order - b.order) };\n });\n },\n\n removeProjectsByIds: async (ids) => {\n if (!ids.length) {\n return;\n }\n\n try {\n await Promise.all(ids.map((id) => deleteProjectFromDB(id)));\n } catch (error) {\n debugLogger.error(\"Failed to delete projects from IndexedDB\", { error, ids });\n }\n\n set((state) => ({\n projects: state.projects.filter((p) => !ids.includes(p.id)),\n }));\n ids.forEach((id) => emitProjectDelete(id));\n },\n}));\n\nfunction normalizeProject(project: Project): Project {\n const ensureDate = (value?: Date | string | null): Date => {\n if (!value) return new Date();\n if (value instanceof Date) return value;\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? new Date() : parsed;\n };\n\n return {\n ...project,\n createdAt: ensureDate(project.createdAt),\n updatedAt: ensureDate(project.updatedAt),\n lastActivityAt: project.lastActivityAt ? ensureDate(project.lastActivityAt) : undefined,\n };\n}\n\nfunction emitProjectUpsert(id: string) {\n if (typeof window === 'undefined') return;\n window.dispatchEvent(new CustomEvent(PROJECT_UPSERT_EVENT, { detail: id }));\n}\n\nfunction emitProjectDelete(id: string) {\n if (typeof window === 'undefined') return;\n window.dispatchEvent(new CustomEvent(PROJECT_DELETE_EVENT, { detail: id }));\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { authenticationService } from \"../auth/authenticationService\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null;\n\nconst getString = (record: Record<string, unknown>, key: string): string | undefined => {\n const value = record[key];\n return typeof value === 'string' ? value : undefined;\n};\n\nclass HttpResponseError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly payload: unknown,\n public readonly code?: string\n ) {\n super(message);\n this.name = 'HttpResponseError';\n }\n}\n\nexport interface SyncMetadataDTO {\n version: number;\n updatedAt: string;\n updatedBy?: string;\n deletedAt?: string | null;\n}\n\nexport interface KnowledgeDocRefDTO {\n id: string;\n name?: string;\n}\n\nexport interface ConversationTurnDTO {\n id: string;\n question: string;\n answer: string;\n images?: string[];\n sourceFiles?: KnowledgeDocRefDTO[];\n memoryUpdated?: boolean;\n cancelled?: boolean;\n}\n\nexport interface ConversationRecordDTO extends SyncMetadataDTO {\n id: string;\n name: string;\n model: string;\n projectId?: string | null;\n history: ConversationTurnDTO[];\n summary?: string;\n tags?: string[];\n metadata?: Record<string, unknown>;\n createdAt?: string | null;\n summaryStatus?: string;\n summaryGeneratedAt?: string;\n}\n\nexport interface ProjectRecordDTO extends SyncMetadataDTO {\n id: string;\n name: string;\n description?: string;\n color?: string;\n order: number;\n conversationCount?: number;\n lastActivityAt?: string;\n summary?: string;\n metadata?: Record<string, unknown>;\n createdAt?: string | null;\n}\n\nexport interface ConversationSyncPreferenceDTO {\n syncEnabled: boolean;\n lastSyncAt?: string | null;\n cursor?: string | null;\n lastDeviceId?: string | null;\n keepLocalOnly?: boolean;\n isAdvancedVectorFeaturesEnabled?: boolean;\n}\n\nexport interface ConversationSyncRequest {\n deviceId: string;\n cursor?: string | null;\n timezone?: string;\n payloadVersion: number;\n changes: {\n conversations: {\n upserts: ConversationRecordDTO[];\n deletes: string[];\n };\n projects: {\n upserts: ProjectRecordDTO[];\n deletes: string[];\n };\n };\n}\n\nexport interface ConflictRecordDTO<T> {\n id: string;\n server: T;\n client?: T;\n reason: 'version_mismatch' | 'missing_dependency' | 'validation_error';\n message?: string;\n}\n\nexport interface ConversationSyncResponse {\n nextCursor?: {\n token: string;\n expiresAt?: string;\n } | null;\n conversations: {\n upserts: ConversationRecordDTO[];\n deletes: string[];\n totalCount: number;\n };\n projects: {\n upserts: ProjectRecordDTO[];\n deletes: string[];\n totalCount: number;\n };\n conflicts: {\n conversationConflicts: ConflictRecordDTO<ConversationRecordDTO>[];\n projectConflicts: ConflictRecordDTO<ProjectRecordDTO>[];\n };\n hasMore: boolean;\n}\n\nfunction buildUrl(path: string): string {\n const base = usePackageSettingsStore.getState().settings?.gatewayApiUrl?.replace(/\\/$/, \"\");\n if (base) {\n const normalized = path.startsWith('/') ? path : `/${path}`;\n return `${base}${normalized}`;\n }\n return path;\n}\n\nfunction buildHeaders(): HeadersInit {\n const headers: HeadersInit = { 'Content-Type': 'application/json' };\n const token = authenticationService.getToken();\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n return headers;\n}\n\nasync function handleJsonResponse<T>(response: Response, fallbackMessage: string): Promise<T> {\n let data: unknown = null;\n try {\n data = await response.json();\n } catch (error) {\n debugLogger.warn('conversationSyncService: failed to parse JSON response', { error });\n }\n\n if (!response.ok) {\n const record = isRecord(data) ? data : {};\n const message =\n getString(record, 'error') ||\n getString(record, 'message') ||\n getString(record, 'detail') ||\n fallbackMessage;\n const code = getString(record, 'code') || getString(record, 'error_code');\n throw new HttpResponseError(message, response.status, data, code);\n }\n\n return data as T;\n}\n\nexport async function fetchConversationSyncPreference(): Promise<ConversationSyncPreferenceDTO> {\n const url = buildUrl('/v1/preferences/conversation-sync');\n const headers = buildHeaders();\n try {\n const response = await fetch(url, { method: 'GET', headers });\n return await handleJsonResponse<ConversationSyncPreferenceDTO>(response, 'Failed to load conversation sync preference');\n } catch (error) {\n debugLogger.error('conversationSyncService: failed to fetch sync preference', {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n\nexport async function updateConversationSyncPreference(body: {\n syncEnabled: boolean;\n deviceId?: string;\n keepLocalOnly?: boolean;\n isAdvancedVectorFeaturesEnabled: boolean;\n}): Promise<ConversationSyncPreferenceDTO> {\n const url = buildUrl('/v1/preferences/conversation-sync');\n const headers = buildHeaders();\n try {\n const response = await fetch(url, {\n method: 'PUT',\n headers,\n body: JSON.stringify(body),\n });\n return await handleJsonResponse<ConversationSyncPreferenceDTO>(response, 'Failed to update conversation sync preference');\n } catch (error) {\n debugLogger.error('conversationSyncService: failed to update sync preference', {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n\nexport async function syncConversations(request: ConversationSyncRequest): Promise<ConversationSyncResponse> {\n const url = buildUrl('/v1/conversations/sync');\n const headers = buildHeaders();\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n return await handleJsonResponse<ConversationSyncResponse>(response, 'Failed to sync conversations');\n } catch (error) {\n debugLogger.error('conversationSyncService: sync request failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n Dialog,\n AppBar,\n Toolbar,\n IconButton,\n Typography,\n Box,\n CircularProgress,\n Alert,\n Button,\n Paper,\n ToggleButton,\n ToggleButtonGroup,\n Tooltip,\n useTheme,\n useMediaQuery,\n} from \"@mui/material\";\nimport { KnowledgeDoc } from \"../../store/knowledgeStore\";\nimport { useVectorStore } from \"../../hooks/useVectorStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport * as pdfjsLib from \"pdfjs-dist/legacy/build/pdf.mjs\";\nimport type { Root, Element, Text } from \"hast\";\nimport { getHighlightTree } from \"../../utils/lowlight\";\nimport { renderLowlightChildren } from \"../../utils/markdownRendering\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport type { PDFDocumentProxy } from \"pdfjs-dist/types/src/display/api\";\nimport {\n ArticleIcon,\n CloseIcon,\n CodeIcon,\n DataObjectIcon,\n DescriptionIcon,\n DownloadIcon,\n PictureAsPdfIcon,\n TextFieldsIcon,\n ZoomInIcon,\n ZoomOutIcon,\n} from \"../../icons\";\n\ntype FileTypeInfo = {\n icon: React.ElementType;\n color: string;\n category: string;\n language?: string;\n};\n\nconst getFileTypeInfo = (filename: string): FileTypeInfo => {\n const ext = filename.split('.').pop()?.toLowerCase() || '';\n \n const languageMap: Record<string, FileTypeInfo> = {\n // Documents\n 'pdf': { icon: PictureAsPdfIcon, color: '#d32f2f', category: 'Document' },\n 'doc': { icon: ArticleIcon, color: '#1976d2', category: 'Document' },\n 'docx': { icon: ArticleIcon, color: '#1976d2', category: 'Document' },\n 'odt': { icon: ArticleIcon, color: '#1976d2', category: 'Document' },\n 'rtf': { icon: ArticleIcon, color: '#1976d2', category: 'Document' },\n \n // Text files\n 'txt': { icon: DescriptionIcon, color: '#388e3c', category: 'Text' },\n 'md': { icon: DescriptionIcon, color: '#388e3c', category: 'Text', language: 'Markdown' },\n 'markdown': { icon: DescriptionIcon, color: '#388e3c', category: 'Text', language: 'Markdown' },\n \n // Web languages\n 'js': { icon: CodeIcon, color: '#f7df1e', category: 'Code', language: 'JavaScript' },\n 'jsx': { icon: CodeIcon, color: '#61dafb', category: 'Code', language: 'JavaScript' },\n 'ts': { icon: CodeIcon, color: '#3178c6', category: 'Code', language: 'TypeScript' },\n 'tsx': { icon: CodeIcon, color: '#61dafb', category: 'Code', language: 'TypeScript' },\n 'html': { icon: CodeIcon, color: '#e34f26', category: 'Code', language: 'HTML' },\n 'css': { icon: CodeIcon, color: '#1572b6', category: 'Code', language: 'CSS' },\n 'scss': { icon: CodeIcon, color: '#cf649a', category: 'Code', language: 'SCSS' },\n 'sass': { icon: CodeIcon, color: '#cf649a', category: 'Code', language: 'Sass' },\n 'php': { icon: CodeIcon, color: '#777bb4', category: 'Code', language: 'PHP' },\n \n // Systems languages\n 'c': { icon: CodeIcon, color: '#a8b9cc', category: 'Code', language: 'C' },\n 'cpp': { icon: CodeIcon, color: '#f34b7d', category: 'Code', language: 'C++' },\n 'cs': { icon: CodeIcon, color: '#239120', category: 'Code', language: 'C#' },\n 'java': { icon: CodeIcon, color: '#ed8b00', category: 'Code', language: 'Java' },\n 'py': { icon: CodeIcon, color: '#3776ab', category: 'Code', language: 'Python' },\n 'go': { icon: CodeIcon, color: '#00add8', category: 'Code', language: 'Go' },\n 'rs': { icon: CodeIcon, color: '#ce422b', category: 'Code', language: 'Rust' },\n 'kt': { icon: CodeIcon, color: '#7f52ff', category: 'Code', language: 'Kotlin' },\n 'swift': { icon: CodeIcon, color: '#fa7343', category: 'Code', language: 'Swift' },\n 'scala': { icon: CodeIcon, color: '#dc322f', category: 'Code', language: 'Scala' },\n 'rb': { icon: CodeIcon, color: '#cc342d', category: 'Code', language: 'Ruby' },\n \n // Scripts\n 'sh': { icon: CodeIcon, color: '#4eaa25', category: 'Code', language: 'Shell' },\n 'bash': { icon: CodeIcon, color: '#4eaa25', category: 'Code', language: 'Bash' },\n 'bat': { icon: CodeIcon, color: '#c1f12e', category: 'Code', language: 'Batch' },\n 'ps1': { icon: CodeIcon, color: '#012456', category: 'Code', language: 'PowerShell' },\n \n // Data formats\n 'json': { icon: DataObjectIcon, color: '#f7df1e', category: 'Data', language: 'JSON' },\n 'xml': { icon: DataObjectIcon, color: '#ff6600', category: 'Data', language: 'XML' },\n 'yaml': { icon: DataObjectIcon, color: '#cb171e', category: 'Data', language: 'YAML' },\n 'yml': { icon: DataObjectIcon, color: '#cb171e', category: 'Data', language: 'YAML' },\n 'csv': { icon: DataObjectIcon, color: '#217346', category: 'Data', language: 'CSV' },\n };\n \n return languageMap[ext] || { icon: DescriptionIcon, color: '#666', category: 'Other' };\n};\n\nconst isPDF = (filename: string): boolean => filename.toLowerCase().endsWith('.pdf');\n\nconst LANGUAGE_MAP: Record<string, string> = {\n // Web technologies\n 'js': 'javascript',\n 'jsx': 'jsx',\n 'ts': 'typescript',\n 'tsx': 'tsx',\n 'html': 'html',\n 'htm': 'html',\n 'css': 'css',\n 'scss': 'scss',\n 'sass': 'sass',\n 'less': 'less',\n\n // Data formats\n 'json': 'json',\n 'xml': 'xml',\n 'yaml': 'yaml',\n 'yml': 'yaml',\n 'csv': 'csv',\n\n // Systems programming\n 'c': 'c',\n 'cpp': 'cpp',\n 'cxx': 'cpp',\n 'cc': 'cpp',\n 'h': 'c',\n 'hpp': 'cpp',\n 'cs': 'csharp',\n 'java': 'java',\n 'py': 'python',\n 'go': 'go',\n 'rs': 'rust',\n 'kt': 'kotlin',\n 'swift': 'swift',\n 'scala': 'scala',\n 'rb': 'ruby',\n 'php': 'php',\n\n // Scripting\n 'sh': 'bash',\n 'bash': 'bash',\n 'zsh': 'bash',\n 'fish': 'bash',\n 'bat': 'batch',\n 'cmd': 'batch',\n 'ps1': 'powershell',\n\n // Markup and documentation\n 'md': 'markdown',\n 'markdown': 'markdown',\n 'tex': 'latex',\n 'sql': 'sql',\n\n // Configuration\n 'ini': 'ini',\n 'conf': 'ini',\n 'config': 'ini',\n 'toml': 'toml',\n 'dockerfile': 'docker',\n\n // Other\n 'r': 'r',\n 'matlab': 'matlab',\n 'm': 'matlab',\n 'lua': 'lua',\n 'perl': 'perl',\n 'pl': 'perl',\n};\n\nconst getLanguageFromFilename = (filename: string): string => {\n const ext = filename.toLowerCase().split('.').pop() || '';\n return LANGUAGE_MAP[ext] || 'text';\n};\n\nconst isCodeFile = (filename: string): boolean => getLanguageFromFilename(filename) !== 'text';\n\nconst formatJsonContent = (content: string): string => {\n try {\n const parsed = JSON.parse(content);\n return JSON.stringify(parsed, null, 2);\n } catch {\n return content;\n }\n};\n\nconst getFormattedContent = (content: string, filename: string): string => {\n const ext = filename.toLowerCase().split('.').pop() || '';\n\n if (ext === 'json') {\n return formatJsonContent(content);\n }\n\n return content;\n};\n\ninterface Props {\n open: boolean;\n onClose: () => void;\n doc: KnowledgeDoc | null;\n isVectorDocument?: boolean;\n}\n\nconst KnowledgeFileModal: React.FC<Props> = ({ open, onClose, doc, isVectorDocument = false }) => {\n const [fullContent, setFullContent] = useState<string>('');\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [pdfDocument, setPdfDocument] = useState<PDFDocumentProxy | null>(null);\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(0);\n const [pdfScale, setPdfScale] = useState(1.2);\n const [pdfCanvases, setPdfCanvases] = useState<HTMLCanvasElement[]>([]);\n const [viewMode, setViewMode] = useState<'formatted' | 'raw'>('formatted');\n const zoomTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const { downloadVectorFile, getFileBlob } = useVectorStore();\n const packageSettings = usePackageSettingsStore();\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('md'));\n\n\n const isDarkTheme = theme.palette.mode === 'dark';\n\n useEffect(() => {\n if (typeof window !== 'undefined') {\n \n pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.burtson.ai/scripts/pdf.worker.js';\n }\n }, [])\n useEffect(() => {\n return () => {\n if (zoomTimeoutRef.current) {\n clearTimeout(zoomTimeoutRef.current);\n }\n };\n }, []);\n\n const baseContent = fullContent || doc?.content || '';\n const filename = doc?.name || '';\n const formattedContent = useMemo(\n () => getFormattedContent(baseContent, filename),\n [baseContent, filename]\n );\n\n const highlightLanguage = useMemo(() => {\n if (!filename || !isCodeFile(filename)) {\n return \"\";\n }\n return getLanguageFromFilename(filename).toLowerCase();\n }, [filename]);\n\n const highlightTree = useMemo<Root | null>(() => {\n if (!highlightLanguage) {\n return null;\n }\n return getHighlightTree(formattedContent, highlightLanguage);\n }, [formattedContent, highlightLanguage]);\n\n const highlightedNodes = useMemo(() => {\n if (!highlightTree) {\n return [] as React.ReactNode[];\n }\n\n const highlightChildren = (highlightTree.children || []).filter((node): node is Element | Text => {\n return node.type === \"element\" || node.type === \"text\";\n });\n\n return renderLowlightChildren(\n highlightChildren,\n `hl-doc-${highlightLanguage || \"auto\"}`\n );\n }, [highlightTree, highlightLanguage]);\n\n const resolvedHighlightLanguage = useMemo(() => {\n const data = highlightTree?.data;\n if (data && typeof data === \"object\" && data !== null && \"language\" in data) {\n const languageValue = (data as { language?: unknown }).language;\n if (typeof languageValue === \"string\") {\n return languageValue.toLowerCase();\n }\n }\n return highlightLanguage;\n }, [highlightTree, highlightLanguage]);\n\n const renderPdfPage = async (pdf: PDFDocumentProxy, pageNumber: number, scale: number = 1.2): Promise<HTMLCanvasElement> => {\n const page = await pdf.getPage(pageNumber);\n const viewport = page.getViewport({ scale });\n \n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Unable to obtain 2D context for PDF rendering');\n }\n canvas.height = viewport.height;\n canvas.width = viewport.width;\n\n const renderContext = {\n canvasContext: context,\n viewport: viewport\n };\n\n await page.render(renderContext).promise;\n return canvas;\n };\n\n const loadPdfDocument = useCallback(async (arrayBuffer: ArrayBuffer) => {\n try {\n const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;\n setPdfDocument(pdf);\n setTotalPages(pdf.numPages);\n setCurrentPage(1);\n\n // Render all pages\n const canvases: HTMLCanvasElement[] = [];\n for (let i = 1; i <= pdf.numPages; i++) {\n const canvas = await renderPdfPage(pdf, i, pdfScale);\n canvases.push(canvas);\n }\n setPdfCanvases(canvases);\n } catch (err) {\n debugLogger.error(\"Failed to load PDF\", { error: err });\n throw err;\n }\n }, [pdfScale]);\n\n // Helper function to create blob from local file rawData\n const createLocalFileBlob = (doc: KnowledgeDoc): Blob => {\n if (!doc.rawData) {\n throw new Error('No raw data available for local file');\n }\n \n const binaryString = atob(doc.rawData);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const mimeType = doc.type || doc.mimeType || 'application/octet-stream';\n return new Blob([bytes], { type: mimeType });\n };\n\n const loadPdfFromDataUrl = async (dataUrl: string) => {\n try {\n setLoading(true);\n setError(null);\n \n const response = await fetch(dataUrl);\n const arrayBuffer = await response.arrayBuffer();\n await loadPdfDocument(arrayBuffer);\n } catch (err) {\n debugLogger.error('Failed to load PDF from data URL', { error: err });\n setError('Failed to load PDF preview');\n } finally {\n setLoading(false);\n }\n };\n\n const loadFullContent = useCallback(async () => {\n if (!doc) return;\n \n setLoading(true);\n setError(null);\n \n try {\n if (isPDF(doc.name)) {\n // For PDF files, get the binary data and render it\n const fileBlob = await getFileBlob(doc.id);\n const arrayBuffer = await fileBlob.arrayBuffer();\n await loadPdfDocument(arrayBuffer);\n } else {\n // For text files, get the text content\n const fileBlob = await getFileBlob(doc.id);\n const content = await fileBlob.text();\n setFullContent(content);\n }\n } catch (err) {\n debugLogger.error('Failed to load full file content', { error: err });\n if (isPDF(doc.name)) {\n setError('Failed to load PDF. The file may be corrupted or too large.');\n } else {\n setError('Failed to load full file content. Showing preview instead.');\n setFullContent(doc.content || '');\n }\n } finally {\n setLoading(false);\n }\n }, [doc, getFileBlob, loadPdfDocument]);\n\n useEffect(() => {\n if (open && doc && isVectorDocument) {\n loadFullContent();\n } else if (open && doc) {\n if (isPDF(doc.name)) {\n if (doc.rawData) {\n try {\n const blob = createLocalFileBlob(doc);\n const arrayBuffer = blob.arrayBuffer();\n arrayBuffer.then(loadPdfDocument).catch(err => {\n debugLogger.error(\"Failed to load local PDF\", { error: err });\n setError('Failed to load PDF preview');\n });\n } catch (err) {\n debugLogger.error(\"Failed to create blob from local PDF data\", { error: err });\n setError('PDF preview not available for this document');\n }\n } else {\n setError('PDF preview not available for this document');\n }\n } else {\n setFullContent(doc.content || '');\n }\n }\n \n if (!open) {\n setPdfDocument(null);\n setPdfCanvases([]);\n setCurrentPage(1);\n setTotalPages(0);\n setPdfScale(1.2);\n setFullContent('');\n setError(null);\n setViewMode('formatted');\n }\n }, [open, doc, isVectorDocument, loadFullContent, loadPdfDocument]);\n\n const handleZoomIn = async () => {\n // Clear any existing timeout\n if (zoomTimeoutRef.current) {\n clearTimeout(zoomTimeoutRef.current);\n }\n \n const newScale = Math.min(pdfScale + 0.25, 3.0);\n setPdfScale(newScale);\n \n // Debounce the actual re-rendering to prevent rapid successive calls\n zoomTimeoutRef.current = setTimeout(async () => {\n if (pdfDocument) {\n setLoading(true);\n try {\n const canvases: HTMLCanvasElement[] = [];\n for (let i = 1; i <= pdfDocument.numPages; i++) {\n const canvas = await renderPdfPage(pdfDocument, i, newScale);\n canvases.push(canvas);\n }\n setPdfCanvases(canvases);\n } catch (error) {\n debugLogger.error('Zoom in failed', { error });\n // Revert to previous scale on error\n setPdfScale(pdfScale);\n } finally {\n setLoading(false);\n }\n }\n }, 300); // 300ms debounce\n };\n\n const handleZoomOut = async () => {\n if (zoomTimeoutRef.current) {\n clearTimeout(zoomTimeoutRef.current);\n }\n \n const newScale = Math.max(pdfScale - 0.25, 0.5);\n setPdfScale(newScale);\n \n zoomTimeoutRef.current = setTimeout(async () => {\n if (pdfDocument) {\n setLoading(true);\n try {\n const canvases: HTMLCanvasElement[] = [];\n for (let i = 1; i <= pdfDocument.numPages; i++) {\n const canvas = await renderPdfPage(pdfDocument, i, newScale);\n canvases.push(canvas);\n }\n setPdfCanvases(canvases);\n } catch (error) {\n debugLogger.error('Zoom out failed', { error });\n setPdfScale(pdfScale);\n } finally {\n setLoading(false);\n }\n }\n }, 300);\n };\n\n const handleDownload = async () => {\n if (!doc || !isVectorDocument) return;\n \n try {\n await downloadVectorFile(doc.id, doc.name);\n } catch (err) {\n debugLogger.error('Vector document download failed', { error: err, docId: doc.id });\n }\n };\n return (\n <Dialog fullScreen open={open} onClose={onClose}>\n <AppBar sx={{ position: \"relative\" }}>\n <Toolbar>\n {/* Document info section with badge and title */}\n <Box sx={{ display: 'flex', alignItems: 'center', flex: 1, minWidth: 0 }}>\n {/* Document type badge */}\n {doc && (\n <Box sx={{ mr: 1, flexShrink: 0 }}>\n {(() => {\n const fileInfo = getFileTypeInfo(doc.name);\n const IconComponent = fileInfo.icon;\n return (\n <Tooltip title={`${fileInfo.category} file`} placement=\"bottom\">\n <Box \n sx={{ \n display: 'flex', \n alignItems: 'center', \n bgcolor: fileInfo.color, \n color: 'white', \n borderRadius: 1, \n px: 1, \n py: 0.25,\n fontSize: '0.75rem',\n fontWeight: 'bold'\n }}\n >\n <IconComponent sx={{ fontSize: '1rem', mr: 0.5 }} />\n {fileInfo.language || fileInfo.category}\n </Box>\n </Tooltip>\n );\n })()}\n </Box>\n )}\n \n {/* Title with responsive truncation */}\n <Tooltip title={doc?.name || ''} placement=\"bottom-start\">\n <Typography \n sx={{ \n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n // Responsive max width for title truncation\n maxWidth: {\n xs: '120px', // Mobile: very short for small screens (reduced to account for badge)\n sm: '180px', // Small tablet: short (reduced)\n md: '280px', // Medium: medium length (reduced)\n lg: '380px', // Large: longer (reduced)\n xl: '480px' // Extra large: longest (reduced)\n },\n cursor: 'help' // Indicate tooltip is available\n }} \n variant=\"h6\"\n >\n {doc?.name}\n </Typography>\n </Tooltip>\n \n {/* Additional file info - only show page count for PDFs */}\n <Box sx={{ display: 'flex', alignItems: 'center', flexShrink: 0, ml: 1 }}>\n {isPDF(doc?.name || '') && totalPages > 0 && (\n <Typography component=\"span\" variant=\"body2\" sx={{ opacity: 0.8 }}>\n ({totalPages} page{totalPages > 1 ? 's' : ''})\n </Typography>\n )}\n </Box>\n </Box>\n \n {/* Toolbar actions section */}\n <Box sx={{ display: 'flex', alignItems: 'center', flexShrink: 0, gap: 1 }}>\n {/* Code View Toggle for non-PDF files */}\n {!isPDF(doc?.name || '') && isCodeFile(doc?.name || '') && (\n <ToggleButtonGroup\n value={viewMode}\n exclusive\n onChange={(e, newMode) => newMode && setViewMode(newMode)}\n size=\"small\"\n >\n <ToggleButton value=\"formatted\" sx={{ color: 'inherit' }}>\n <CodeIcon sx={{ mr: 1, fontSize: '1rem' }} />\n Formatted\n </ToggleButton>\n <ToggleButton value=\"raw\" sx={{ color: 'inherit' }}>\n <TextFieldsIcon sx={{ mr: 1, fontSize: '1rem' }} />\n Raw\n </ToggleButton>\n </ToggleButtonGroup>\n )}\n \n {/* PDF Navigation Controls - Hidden on mobile */}\n {isPDF(doc?.name || '') && pdfDocument && !isMobile && (\n <>\n <Button \n color=\"inherit\" \n startIcon={<ZoomOutIcon />}\n onClick={handleZoomOut}\n disabled={pdfScale <= 0.5}\n size=\"small\"\n >\n Zoom Out\n </Button>\n <Typography variant=\"body2\" sx={{ color: 'inherit', mx: 1 }}>\n {Math.round(pdfScale * 100)}%\n </Typography>\n <Button \n color=\"inherit\" \n startIcon={<ZoomInIcon />}\n onClick={handleZoomIn}\n disabled={pdfScale >= 3.0}\n size=\"small\"\n >\n Zoom In\n </Button>\n </>\n )}\n \n {/* Download and Close buttons */}\n {isVectorDocument && (\n <IconButton edge=\"end\" color=\"inherit\" onClick={handleDownload}>\n <DownloadIcon />\n </IconButton>\n )}\n <IconButton edge=\"end\" color=\"inherit\" onClick={onClose}>\n <CloseIcon />\n </IconButton>\n </Box>\n </Toolbar>\n </AppBar>\n <Box sx={{ p: 3, bgcolor: \"background.default\", height: \"100%\", overflowY: \"auto\" }}>\n {loading && (\n <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50vh' }}>\n <CircularProgress />\n <Typography sx={{ ml: 2 }}>\n {isPDF(doc?.name || '') ? 'Loading PDF document...' : 'Loading full file content...'}\n </Typography>\n </Box>\n )}\n \n {error && (\n <Alert severity=\"warning\" sx={{ mb: 2 }}>\n {error}\n </Alert>\n )}\n \n {!loading && isPDF(doc?.name || '') && pdfCanvases.length > 0 && (\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2 }}>\n {pdfCanvases.map((canvas, index) => (\n <Paper \n key={index} \n elevation={3} \n sx={{ \n p: 2, \n mb: 2,\n maxWidth: '100%',\n overflow: 'auto',\n // Custom scrollbar styling for PDF viewer\n '&::-webkit-scrollbar': {\n width: '8px',\n height: '8px',\n },\n '&::-webkit-scrollbar-track': {\n background: isDarkTheme ? '#2d2d2d' : '#f5f5f5',\n borderRadius: '4px',\n },\n '&::-webkit-scrollbar-thumb': {\n background: isDarkTheme ? '#555' : '#c1c1c1',\n borderRadius: '4px',\n '&:hover': {\n background: isDarkTheme ? '#666' : '#a1a1a1',\n },\n },\n '&::-webkit-scrollbar-corner': {\n background: isDarkTheme ? '#2d2d2d' : '#f5f5f5',\n },\n // Firefox scrollbar support\n scrollbarWidth: 'thin',\n scrollbarColor: isDarkTheme ? '#555 #2d2d2d' : '#c1c1c1 #f5f5f5',\n }}\n >\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mb: 1, display: 'block' }}>\n Page {index + 1} of {totalPages}\n </Typography>\n <Box\n ref={(el: HTMLDivElement | null) => {\n if (el && canvas) {\n el.innerHTML = '';\n el.appendChild(canvas);\n }\n }}\n sx={{\n '& canvas': {\n display: 'block',\n maxWidth: '100%',\n height: 'auto',\n border: '1px solid',\n borderColor: 'divider',\n }\n }}\n />\n </Paper>\n ))}\n </Box>\n )}\n \n {!loading && !isPDF(doc?.name || '') && (\n <Box>\n {isCodeFile(doc?.name || '') && viewMode === 'formatted' ? (\n <Box>\n {/* Language indicator */}\n <Box sx={{ mb: 2, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Syntax highlighted as <strong>{getLanguageFromFilename(doc?.name || '').toUpperCase()}</strong>\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {(fullContent || doc?.content || '').split('\\n').length} lines\n </Typography>\n </Box>\n \n <Paper \n elevation={1} \n sx={{ \n overflow: 'auto',\n maxHeight: { xs: 'calc(100vh - 320px)', sm: 'calc(100vh - 280px)' },\n border: '1px solid',\n borderColor: 'divider',\n // Custom scrollbar styling to match theme\n '&::-webkit-scrollbar': {\n width: { xs: '8px', sm: '12px' },\n height: { xs: '8px', sm: '12px' },\n },\n '&::-webkit-scrollbar-track': {\n backgroundColor: isDarkTheme ? '#2d2d2d' : '#f5f5f5',\n borderRadius: '6px',\n },\n '&::-webkit-scrollbar-thumb': {\n backgroundColor: isDarkTheme ? '#555' : '#c1c1c1',\n borderRadius: '6px',\n border: isDarkTheme ? '2px solid #2d2d2d' : '2px solid #f5f5f5',\n '&:hover': {\n backgroundColor: isDarkTheme ? '#777' : '#a8a8a8',\n },\n },\n '&::-webkit-scrollbar-corner': {\n backgroundColor: isDarkTheme ? '#2d2d2d' : '#f5f5f5',\n },\n // Firefox scrollbar styling\n scrollbarWidth: 'thin',\n scrollbarColor: isDarkTheme ? '#555 #2d2d2d' : '#c1c1c1 #f5f5f5',\n '& pre': {\n margin: 0,\n padding: { xs: '12px !important', sm: '16px !important' },\n borderRadius: '8px',\n fontSize: { xs: '12px', sm: '14px' },\n lineHeight: 1.5,\n // Better mobile text handling\n wordBreak: 'break-word',\n overflowWrap: 'anywhere',\n }\n }}\n >\n <Box\n sx={{\n '& .hljs': {\n display: 'block',\n padding: { xs: '12px', sm: '16px' },\n margin: 0,\n fontSize: { xs: '12px', sm: '14px' },\n lineHeight: 1.55,\n backgroundColor: isDarkTheme ? '#0f172a' : '#f5f6ff',\n color: isDarkTheme ? '#e2e8f0' : '#1e293b',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n overflowWrap: 'anywhere',\n },\n '& .hljs-comment, & .hljs-quote': {\n color: isDarkTheme ? '#64748b' : '#64748b',\n fontStyle: 'italic',\n },\n '& .hljs-keyword, & .hljs-selector-tag, & .hljs-literal, & .hljs-built_in': {\n color: isDarkTheme ? '#c792ea' : '#7c3aed',\n },\n '& .hljs-string, & .hljs-doctag, & .hljs-template-tag, & .hljs-attr': {\n color: isDarkTheme ? '#7fdbca' : '#0f766e',\n },\n '& .hljs-number, & .hljs-symbol, & .hljs-bullet, & .hljs-meta': {\n color: isDarkTheme ? '#f78c6c' : '#b45309',\n },\n '& .hljs-title, & .hljs-section, & .hljs-selector-id, & .hljs-function': {\n color: isDarkTheme ? '#82aaff' : '#2563eb',\n },\n '& .hljs-variable, & .hljs-params, & .hljs-property': {\n color: isDarkTheme ? '#f07178' : '#d97706',\n },\n }}\n >\n <pre className={`hljs language-${resolvedHighlightLanguage || 'text'}`}>\n <code className=\"hljs\">\n {highlightedNodes.length > 0 ? highlightedNodes : formattedContent}\n </code>\n </pre>\n </Box>\n </Paper>\n </Box>\n ) : (\n <Typography\n component=\"pre\"\n variant=\"body2\"\n sx={{\n whiteSpace: \"pre-wrap\",\n fontFamily: \"monospace\",\n color: \"text.primary\",\n lineHeight: 1.5,\n bgcolor: 'background.paper',\n p: 2,\n borderRadius: 1,\n border: '1px solid',\n borderColor: 'divider',\n overflow: 'auto',\n maxHeight: 'calc(100vh - 200px)',\n }}\n >\n {fullContent || doc?.content}\n </Typography>\n )}\n </Box>\n )}\n \n {!loading && isPDF(doc?.name || '') && pdfCanvases.length === 0 && !error && (\n <Box sx={{ textAlign: 'center', py: 4 }}>\n <Typography variant=\"h6\" color=\"text.secondary\" gutterBottom>\n PDF Preview Not Available\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n This PDF file cannot be previewed. You can download it to view the full content.\n </Typography>\n {isVectorDocument && (\n <Button \n variant=\"contained\" \n startIcon={<DownloadIcon />}\n onClick={handleDownload}\n sx={{ mt: 2 }}\n >\n Download PDF\n </Button>\n )}\n </Box>\n )}\n </Box>\n </Dialog>\n );\n};\n\nexport default KnowledgeFileModal;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { createLowlight } from 'lowlight';\n\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport typescript from 'highlight.js/lib/languages/typescript';\nimport json from 'highlight.js/lib/languages/json';\nimport bash from 'highlight.js/lib/languages/bash';\nimport shell from 'highlight.js/lib/languages/shell';\nimport yaml from 'highlight.js/lib/languages/yaml';\nimport python from 'highlight.js/lib/languages/python';\nimport css from 'highlight.js/lib/languages/css';\nimport xml from 'highlight.js/lib/languages/xml';\nimport markdown from 'highlight.js/lib/languages/markdown';\nimport sql from 'highlight.js/lib/languages/sql';\nimport java from 'highlight.js/lib/languages/java';\nimport csharp from 'highlight.js/lib/languages/csharp';\nimport cpp from 'highlight.js/lib/languages/cpp';\nimport go from 'highlight.js/lib/languages/go';\nimport rust from 'highlight.js/lib/languages/rust';\nimport kotlin from 'highlight.js/lib/languages/kotlin';\nimport swift from 'highlight.js/lib/languages/swift';\nimport scala from 'highlight.js/lib/languages/scala';\nimport ruby from 'highlight.js/lib/languages/ruby';\nimport php from 'highlight.js/lib/languages/php';\nimport powershell from 'highlight.js/lib/languages/powershell';\n\nconst lowlight = createLowlight();\n\ntype LowlightInstance = ReturnType<typeof createLowlight>;\ntype LowlightLanguage = Parameters<LowlightInstance['register']>[1];\n\nconst asLanguage = (language: unknown): LowlightLanguage =>\n language as LowlightLanguage;\n\nconst registrations: Record<string, LowlightLanguage> = {\n javascript: asLanguage(javascript),\n js: asLanguage(javascript),\n jsx: asLanguage(javascript),\n typescript: asLanguage(typescript),\n ts: asLanguage(typescript),\n tsx: asLanguage(typescript),\n json: asLanguage(json),\n bash: asLanguage(bash),\n shell: asLanguage(shell),\n sh: asLanguage(shell),\n yaml: asLanguage(yaml),\n yml: asLanguage(yaml),\n python: asLanguage(python),\n py: asLanguage(python),\n css: asLanguage(css),\n html: asLanguage(xml),\n xml: asLanguage(xml),\n markdown: asLanguage(markdown),\n md: asLanguage(markdown),\n sql: asLanguage(sql),\n java: asLanguage(java),\n csharp: asLanguage(csharp),\n cs: asLanguage(csharp),\n cpp: asLanguage(cpp),\n c: asLanguage(cpp),\n h: asLanguage(cpp),\n go: asLanguage(go),\n rust: asLanguage(rust),\n rs: asLanguage(rust),\n kotlin: asLanguage(kotlin),\n kt: asLanguage(kotlin),\n swift: asLanguage(swift),\n scala: asLanguage(scala),\n ruby: asLanguage(ruby),\n rb: asLanguage(ruby),\n php: asLanguage(php),\n powershell: asLanguage(powershell),\n ps1: asLanguage(powershell),\n};\n\nObject.entries(registrations).forEach(([name, language]) => {\n if (!lowlight.listLanguages().includes(name)) {\n lowlight.register(name, language);\n }\n});\n\nexport function getHighlightTree(code: string, language?: string) {\n const lang = language?.toLowerCase();\n if (lang && lowlight.listLanguages().includes(lang)) {\n return lowlight.highlight(lang, code);\n }\n return lowlight.highlightAuto(code);\n}\n\nexport { lowlight };\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React from \"react\";\nimport { Box } from \"@mui/material\";\nimport type { Element, Text } from \"hast\";\nimport { defaultSchema } from \"rehype-sanitize\";\n\nexport const markdownSanitizeSchema = (() => {\n // Copy without JSON: a JSON round-trip turns the default schema's RegExp\n // values (code: [\"className\", /^language-./]) into {}, and that emptied\n // entry then strips every language class, so fenced code lost its language\n // and fell back to auto-detection (a ```ts block labelled \"CSHARP\").\n const schema: typeof defaultSchema & Record<string, unknown> = {\n ...defaultSchema,\n attributes: Object.fromEntries(\n Object.entries(defaultSchema.attributes ?? {}).map(([tag, attrs]) => [tag, [...attrs]]),\n ),\n };\n schema.tagNames = Array.from(\n new Set([...(schema.tagNames || []), \"span\", \"sup\", \"sub\"])\n );\n schema.attributes = {\n ...(schema.attributes || {}),\n \"*\": Array.from(\n new Set([...(schema.attributes?.[\"*\"] || []), \"className\", \"id\", \"data*\"])\n ),\n span: Array.from(\n new Set([\n ...(schema.attributes?.span || []),\n \"className\",\n \"data-bl-delay\",\n \"data*\",\n \"id\",\n ])\n ),\n code: Array.from(\n new Set([\n ...(schema.attributes?.code || []),\n \"className\",\n \"data-language\",\n \"data*\",\n \"id\",\n ])\n ),\n pre: Array.from(\n new Set([...(schema.attributes?.pre || []), \"className\", \"data*\", \"id\"])\n ),\n sup: Array.from(\n new Set([...(schema.attributes?.sup || []), \"className\", \"data*\", \"id\"])\n ),\n a: Array.from(\n new Set([...(schema.attributes?.a || []), \"className\", \"data*\", \"id\"])\n ),\n };\n schema.clobberPrefix = \"bl\";\n schema.allowComments = false;\n schema.strip = [\"script\", \"style\"];\n return schema;\n})();\n\n/**\n * Chat-bubble image: capped so a generated 1024px+ PNG never dominates the\n * thread, with an explicit save action. Gateway-generated images are served\n * with an attachment disposition, so the same URL that renders inline\n * downloads when opened through the anchor; other images open in a new tab.\n * Rendered inside a paragraph, so the wrapper stays a (block) span.\n */\nexport const MarkdownImage: React.FC<React.ComponentPropsWithoutRef<\"img\">> = ({ src, alt }) => {\n if (!src) return null;\n return (\n <Box component=\"span\" sx={{ display: \"block\", my: 1 }}>\n <Box\n component=\"img\"\n src={src}\n alt={alt || \"Image\"}\n loading=\"lazy\"\n sx={{\n display: \"block\",\n maxWidth: \"min(480px, 100%)\",\n maxHeight: 420,\n width: \"auto\",\n height: \"auto\",\n borderRadius: 2,\n border: \"1px solid\",\n borderColor: \"divider\",\n }}\n />\n <Box\n component=\"a\"\n href={src}\n download\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n sx={{\n display: \"inline-block\",\n mt: 0.5,\n fontSize: 13,\n fontWeight: 600,\n color: \"primary.main\",\n textDecoration: \"none\",\n \"&:hover\": { textDecoration: \"underline\" },\n }}\n >\n Save image\n </Box>\n </Box>\n );\n};\n\nexport const renderLowlightChildren = (\n nodes: Array<Element | Text>,\n keyPrefix: string\n): React.ReactNode[] =>\n nodes.map((node, index) => {\n if (node.type === \"text\") {\n return node.value;\n }\n\n if (node.type === \"element\") {\n const key = `${keyPrefix}-${index}`;\n const { tagName, properties = {}, children = [] } = node;\n const reactProps: Record<string, unknown> = { key };\n\n Object.entries(properties).forEach(([propKey, value]) => {\n if (propKey === \"className\" && Array.isArray(value)) {\n reactProps.className = value.join(\" \");\n } else if (value !== null && value !== undefined) {\n reactProps[propKey] = value;\n }\n });\n\n return React.createElement(\n tagName,\n reactProps,\n renderLowlightChildren(children as Array<Element | Text>, key)\n );\n }\n\n return null;\n });\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\n/**\n * Standalone iOS PWAs have no download manager, so tapping a file link\n * (the create_file S3 URLs) dead-ends. Instead: fetch the file and hand it\n * to the native share sheet (\"Save to Files\", AirDrop, Mail…), which is a\n * better mobile flow than a browser download anyway. Browser tabs keep the\n * normal target=_blank download behavior.\n */\n\nconst FILE_EXT_RE = /\\.(docx|pptx|xlsx|csv|json|md|txt|html|xml|ya?ml|pdf|zip)(?:[?#]|$)/i;\n\nconst isStandalonePwa = (): boolean =>\n typeof window !== \"undefined\" &&\n (window.matchMedia?.(\"(display-mode: standalone)\").matches ||\n (window.navigator as Navigator & { standalone?: boolean }).standalone === true);\n\nexport const isFileLink = (href: string | undefined): boolean =>\n Boolean(href && FILE_EXT_RE.test(href));\n\n/**\n * Attach to a file link's onClick. Returns without touching the event unless\n * we're in a standalone PWA looking at a file link — the anchor's own\n * target=_blank handles every other case.\n */\nexport const maybeHandleFileLinkClick = (\n event: { preventDefault: () => void },\n href: string | undefined\n): void => {\n if (!href || !isStandalonePwa() || !isFileLink(href)) return;\n event.preventDefault();\n\n void (async () => {\n try {\n const res = await fetch(href);\n if (!res.ok) throw new Error(`fetch ${res.status}`);\n const blob = await res.blob();\n const rawName = new URL(href, window.location.href).pathname.split(\"/\").pop() || \"download\";\n const name = decodeURIComponent(rawName);\n const file = new File([blob], name, {\n type: blob.type || \"application/octet-stream\",\n });\n const nav = navigator as Navigator & {\n canShare?: (data: { files: File[] }) => boolean;\n share?: (data: { files: File[]; title?: string }) => Promise<void>;\n };\n if (nav.canShare?.({ files: [file] }) && nav.share) {\n await nav.share({ files: [file], title: name });\n return;\n }\n // No file-share support: navigate to an object URL — the webview's\n // Quick Look previews Office docs and PDFs.\n window.location.href = URL.createObjectURL(blob);\n } catch (error) {\n debugLogger.warn(\"openFileLink: share flow failed, falling back\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // AbortError = the user closed the share sheet — nothing to do.\n if ((error as { name?: string })?.name === \"AbortError\") return;\n window.open(href, \"_blank\", \"noopener\");\n }\n })();\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useState, useEffect } from \"react\";\nimport { useVoiceStore } from \"../../store/voiceStore\";\nimport { usePreferencesStore } from \"../../store/preferencesStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { useCanvasStore } from \"../../store/canvasStore\";\nimport { useTTS } from \"../../hooks/useTTS\";\nimport { Box, CircularProgress, IconButton, Tooltip } from \"@mui/material\";\nimport { Check as CheckIcon, ThumbsUp as ThumbUpIcon, ThumbsDown as ThumbDownIcon, Copy as ContentCopyIcon, Megaphone as CampaignOutlined, Megaphone as CampaignRounded, Square as StopIcon, Pause as PauseIcon, Play as PlayArrowIcon, PanelRight as CanvasIcon } from \"@burtson-labs/icons/react\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport type { SxProps, Theme } from \"@mui/material/styles\";\nimport { chatTokens } from \"../../chat/chat-tokens\";\n\n// One look for every response action: muted until hovered; a pressed\n// feedback button takes the selection colour (a dislike is a choice, not an\n// error).\nconst actionSx: SxProps<Theme> = (theme) => {\n const t = chatTokens(theme);\n return {\n color: t.control.foregroundMuted,\n \"&:hover\": { color: t.control.foreground, bgcolor: t.surface.interactive },\n \"&[aria-pressed='true']\": { color: theme.palette.primary.main },\n \"&.Mui-disabled\": { color: t.control.foregroundMuted, opacity: 0.5 },\n };\n};\nimport { authenticationService } from \"../../services/auth/authenticationService\";\n\nconst AiResponseActionsBar: React.FC<{ text: string }> = ({ text }) => {\n const [copied, setCopied] = useState(false);\n const openCanvas = useCanvasStore((s) => s.openCanvas);\n const openInCanvas = () => {\n const plain = text || \"\";\n // Title from the first heading, else the first non-empty line, truncated.\n const firstHeading = plain.match(/^#{1,3}\\s+(.+)$/m)?.[1];\n const firstLine = plain.split(\"\\n\").map((l) => l.trim()).find(Boolean) || \"\";\n const rawTitle = (firstHeading || firstLine).replace(/[#*_>]/g, \"\").replace(/\\s+/g, \" \").trim();\n const title = rawTitle.length > 60 ? `${rawTitle.slice(0, 57)}…` : rawTitle || \"Untitled\";\n openCanvas({ content: plain, title });\n };\n const [feedback, setFeedback] = useState<\"like\" | \"dislike\" | null>(null);\n \n const {\n isPlaying,\n isPaused,\n isLoading,\n error: ttsError,\n speak: ttsSpeak,\n stop: ttsStop,\n pause: ttsPause,\n resume: ttsResume,\n isAvailable: isTTSAvailable\n } = useTTS();\n\n const { availableVoices, loadVoicesFromAPI, initialized } = useVoiceStore();\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n\n // Load voices when component mounts if none are available\n useEffect(() => {\n const isAuthenticated = authenticationService.isAuthenticated();\n const token = authenticationService.getToken();\n \n if (!initialized || availableVoices.length === 0) {\n if (token && isAuthenticated) {\n debugLogger.debug('AI Action Bar: Voices not initialized or unavailable, attempting to load from API');\n loadVoicesFromAPI();\n } else {\n debugLogger.debug('AI Action Bar: No valid JWT token available - skipping voice loading');\n }\n }\n }, [initialized, availableVoices.length, loadVoicesFromAPI]);\n\n // Show TTS error if any\n useEffect(() => {\n if (ttsError) {\n debugLogger.error('TTS Error in action bar:', { error: ttsError });\n }\n }, [ttsError]);\n\n const handleCopy = () => {\n // Remove HTML tags\n let plainText = text.replace(/<\\/?[^>]+(>|$)/g, \"\");\n\n // Remove Markdown syntax\n plainText = plainText\n .replace(/`{1,3}[\\s\\S]*?`{1,3}/g, \"\") // inline and block code\n .replace(/!\\[.*?\\]\\(.*?\\)/g, \"\") // images\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\") // links\n .replace(/[*_~`>#-]/g, \"\") // emphasis, headings, etc.\n .replace(/^\\s*\\d+\\s*[:.]?\\s*$/gm, \"\") // numbered list items like \"1. :\" or \"2:\"\n .replace(/^\\s*[:.]+\\s*$/gm, \"\") // lines with just colons or periods\n .replace(/:+(?=\\s|$)/g, \"\") // trailing colons\n .replace(/\\n{3,}/g, \"\\n\\n\"); // limit excessive line breaks\n\n plainText = plainText.trim();\n\n navigator.clipboard.writeText(plainText);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const handleTTSClick = async () => {\n try {\n if (!isTTSAvailable) {\n return;\n }\n\n if (isPaused) {\n // If paused, resume\n ttsResume();\n } else if (!isPlaying) {\n // If idle or error, start playing with streaming\n // Clean the text first - remove HTML tags and Markdown syntax\n let cleanText = text.replace(/<\\/?[^>]+(>|$)/g, \"\");\n\n // Remove Markdown syntax\n cleanText = cleanText\n .replace(/`{1,3}[\\s\\S]*?`{1,3}/g, \"\") // inline and block code\n .replace(/!\\[.*?\\]\\(.*?\\)/g, \"\") // images\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\") // links\n .replace(/[*_~`>#-]/g, \"\") // emphasis, headings, etc.\n .replace(/^\\s*\\d+\\s*[:.]?\\s*$/gm, \"\") // numbered list items like \"1. :\" or \"2:\"\n .replace(/^\\s*[:.]+\\s*$/gm, \"\") // lines with just colons or periods\n .replace(/:+(?=\\s|$)/g, \"\") // trailing colons\n .replace(/\\n{3,}/g, \"\\n\\n\"); // limit excessive line breaks\n\n cleanText = cleanText.trim();\n\n if (!cleanText) {\n return;\n }\n\n await ttsSpeak(cleanText, { \n useStreaming: true, // Enable streaming for faster response\n useRealtime: true // Use real-time streaming for immediate playback\n });\n }\n // Note: If already playing, do nothing (pause and stop have their own buttons)\n } catch (error) {\n debugLogger.error('TTS playback failed:', { \n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined\n });\n }\n };\n\n const handleFeedback = (type: \"like\" | \"dislike\") => {\n setFeedback(type);\n // Example: memoryEnhancer.addMemory(`User ${type === \"like\" ? \"liked\" : \"disliked\"} this response`);\n };\n\n return (\n <Box sx={{ mt: 2, display: \"flex\", gap: 2, alignItems: \"center\", flexWrap: \"wrap\" }}>\n <Tooltip title={copied ? \"Copied!\" : \"Copy entire response\"}>\n <IconButton\n onClick={handleCopy}\n size=\"small\"\n aria-label={copied ? \"Copied\" : \"Copy response\"}\n sx={actionSx}\n >\n {copied ? <CheckIcon size={18} /> : <ContentCopyIcon size={18} />}\n </IconButton>\n </Tooltip>\n\n <Tooltip title=\"Open in canvas — edit & export\">\n <IconButton\n onClick={openInCanvas}\n size=\"small\"\n aria-label=\"Open in canvas\"\n sx={actionSx}\n >\n <CanvasIcon size={18} />\n </IconButton>\n </Tooltip>\n\n {isTTSAvailable && ( \n <>\n {/* Main TTS Button - Play/Resume */}\n <Tooltip\n title={\n !isTTSAvailable ? \"TTS not available - check configuration\" :\n isLoading ? \"Loading audio...\" :\n isPaused ? \"Resume playback\" :\n isPlaying ? \"Playing audio...\" :\n \"Play response with voice\"\n }\n >\n <IconButton\n onClick={handleTTSClick}\n size=\"small\"\n disabled={isLoading}\n aria-label={isPaused ? \"Resume playback\" : isPlaying ? \"Playing\" : \"Read aloud\"}\n sx={actionSx}\n >\n {isLoading ? (\n <CircularProgress size={18} />\n ) : isPaused ? (\n <PlayArrowIcon size={18} />\n ) : !isPlaying ? (\n <CampaignOutlined size={18} />\n ) : (\n <Box component=\"span\" sx={(t) => ({ display: \"inline-flex\", color: chatTokens(t).status.streaming })}><CampaignRounded size={18} /></Box>\n )}\n </IconButton>\n </Tooltip>\n\n {/* Pause Button - Only show when playing */}\n {isPlaying && (\n <Tooltip title=\"Pause playback\">\n <IconButton\n onClick={() => ttsPause()}\n size=\"small\"\n aria-label=\"Pause playback\"\n sx={actionSx}\n >\n <PauseIcon size={18} />\n </IconButton>\n </Tooltip>\n )}\n\n {/* Stop Button - Show when playing or paused */}\n {(isPlaying || isPaused) && (\n <Tooltip title=\"Stop playback\">\n <IconButton\n onClick={() => ttsStop()}\n size=\"small\"\n aria-label=\"Stop playback\"\n sx={actionSx}\n >\n <StopIcon size={18} />\n </IconButton>\n </Tooltip>\n )}\n </>\n )}\n\n <Tooltip title=\"Like this response\">\n <IconButton\n onClick={() => handleFeedback(\"like\")}\n size=\"small\"\n aria-label=\"Like this response\"\n aria-pressed={feedback === \"like\"}\n sx={actionSx}\n >\n <ThumbUpIcon size={18} />\n </IconButton>\n </Tooltip>\n\n <Tooltip title=\"Dislike this response\">\n <IconButton\n onClick={() => handleFeedback(\"dislike\")}\n size=\"small\"\n aria-label=\"Dislike this response\"\n aria-pressed={feedback === \"dislike\"}\n sx={actionSx}\n >\n <ThumbDownIcon size={18} />\n </IconButton>\n </Tooltip>\n </Box>\n );\n};\n\nexport default AiResponseActionsBar;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { create } from \"zustand\";\nimport { voiceService, VoiceModelsResponse } from \"../services/tts/voiceService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { stopTTS } from \"../services/tts/streaming-tts\";\n\n// Auto-initialize voice loading when store is created\nlet autoInitialized = false;\n\nexport interface VoiceState {\n availableVoices: string[];\n selectedVoice: string;\n defaultVoice: string;\n fallbackVoice: string;\n isLoading: boolean;\n isServiceAvailable: boolean;\n initialized: boolean;\n setSelectedVoice: (voice: string) => void;\n loadVoicesFromAPI: () => Promise<void>;\n refreshVoices: () => Promise<void>;\n forceInitialize: () => Promise<void>;\n}\n\nexport const useVoiceStore = create<VoiceState>((set, get) => ({\n availableVoices: [],\n selectedVoice: \"\",\n defaultVoice: \"\", \n fallbackVoice: \"\",\n isLoading: false,\n isServiceAvailable: false,\n initialized: false,\n \n setSelectedVoice: (voice) => {\n const currentVoice = get().selectedVoice;\n debugLogger.debug('Setting selected voice', { \n previousVoice: currentVoice, \n newVoice: voice,\n isChange: currentVoice !== voice\n });\n \n // If voice is actually changing, immediately stop current TTS\n if (currentVoice && currentVoice !== voice) {\n debugLogger.debug('🔄 Voice changing in store - stopping TTS immediately', {\n from: currentVoice,\n to: voice\n });\n stopTTS();\n }\n \n set({ selectedVoice: voice });\n },\n \n loadVoicesFromAPI: async () => {\n const state = get();\n if (state.isLoading) return; // Prevent concurrent requests\n \n set({ isLoading: true, initialized: true });\n \n try {\n const voiceData: VoiceModelsResponse = await voiceService.fetchAvailableVoices();\n \n const hasVoices = voiceData.models.length > 0;\n let finalSelectedVoice = state.selectedVoice;\n \n if (hasVoices) {\n // Validate and set selected voice\n if (finalSelectedVoice && voiceData.models.includes(finalSelectedVoice)) {\n // Keep current selection if it's still available\n } else {\n finalSelectedVoice = voiceData.defaultModel;\n }\n \n set({\n isServiceAvailable: true,\n availableVoices: voiceData.models,\n defaultVoice: voiceData.defaultModel,\n fallbackVoice: voiceData.fallbackModel,\n selectedVoice: finalSelectedVoice,\n isLoading: false\n });\n } else {\n set({\n isServiceAvailable: false,\n isLoading: false\n });\n }\n } catch (error) {\n debugLogger.error('Failed to load voice models', { \n error: error instanceof Error ? error.message : String(error)\n });\n set({\n isServiceAvailable: false,\n isLoading: false\n });\n }\n },\n \n refreshVoices: async () => {\n const currentSelection = get().selectedVoice;\n voiceService.clearCache();\n await get().loadVoicesFromAPI();\n // Restore selection if it's still valid\n const { availableVoices } = get();\n if (currentSelection && availableVoices.includes(currentSelection)) {\n set({ selectedVoice: currentSelection });\n }\n },\n \n forceInitialize: async () => {\n const state = get();\n if (!state.initialized || state.availableVoices.length === 0) {\n debugLogger.debug('Force initializing voice store...');\n await state.loadVoicesFromAPI();\n }\n }\n}));\n\n// Trigger auto-initialization with a slight delay to ensure package settings are ready\nif (!autoInitialized) {\n autoInitialized = true;\n setTimeout(() => {\n debugLogger.debug('Auto-initializing voice store...');\n useVoiceStore.getState().forceInitialize().catch((error) => {\n debugLogger.warn('Auto-initialization failed:', error);\n });\n }, 1000); // 1 second delay to ensure gateway URL is available\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { usePackageSettingsStore } from '../../store/packageSettingsStore';\nimport { authenticationService } from '../auth/authenticationService';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface VoiceModelsResponse {\n models: string[];\n defaultModel: string;\n fallbackModel: string;\n}\n\nexport class VoiceService {\n private static instance: VoiceService;\n private cachedModels: VoiceModelsResponse | null = null;\n private cacheTimestamp: number = 0;\n private readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes\n\n private constructor() {}\n\n public static getInstance(): VoiceService {\n if (!VoiceService.instance) {\n VoiceService.instance = new VoiceService();\n }\n return VoiceService.instance;\n }\n\n private getGatewayApiUrl(): string {\n return usePackageSettingsStore.getState().settings?.gatewayApiUrl || '';\n }\n\n private isValid(data: unknown): data is VoiceModelsResponse {\n if (typeof data !== 'object' || data === null) {\n return false;\n }\n\n const record = data as Record<string, unknown>;\n return Array.isArray(record.models) &&\n record.models.every((item) => typeof item === 'string') &&\n typeof record.defaultModel === 'string' &&\n typeof record.fallbackModel === 'string';\n }\n\n private isCacheValid(): boolean {\n return this.cachedModels !== null && \n (Date.now() - this.cacheTimestamp) < this.CACHE_DURATION;\n }\n\n public async fetchAvailableVoices(): Promise<VoiceModelsResponse> {\n // Return cached data if valid\n if (this.isCacheValid()) {\n debugLogger.debug('Returning cached voice models');\n return this.cachedModels!;\n }\n\n const gatewayUrl = this.getGatewayApiUrl();\n if (!gatewayUrl) {\n debugLogger.error('Gateway API URL not configured');\n throw new Error('Gateway API URL not configured');\n }\n\n // Check if we have a valid JWT token before making the request\n const token = authenticationService.getToken();\n if (!token) {\n debugLogger.info('No JWT token available - skipping voice models fetch');\n const emptyModels: VoiceModelsResponse = {\n models: [],\n defaultModel: \"\",\n fallbackModel: \"\"\n };\n return emptyModels;\n }\n\n // Validate token is not expired\n if (authenticationService.isTokenExpired(token)) {\n debugLogger.warn('JWT token is expired - skipping voice models fetch');\n const emptyModels: VoiceModelsResponse = {\n models: [],\n defaultModel: \"\",\n fallbackModel: \"\"\n };\n return emptyModels;\n }\n\n try {\n debugLogger.debug('Fetching voice models from gateway API...');\n \n const response = await fetch(`${gatewayUrl}/tts/available-models`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n }\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch voice models: ${response.status}`);\n }\n\n const data = await response.json();\n \n if (!this.isValid(data)) {\n throw new Error('Invalid voice models response format');\n }\n\n // Cache the response\n this.cachedModels = data;\n this.cacheTimestamp = Date.now();\n\n debugLogger.debug('Voice models fetched successfully', data);\n return data;\n\n } catch (error) {\n debugLogger.error('Error fetching voice models:', { error: error instanceof Error ? error.message : String(error) });\n \n const emptyModels: VoiceModelsResponse = {\n models: [],\n defaultModel: \"\",\n fallbackModel: \"\"\n };\n\n debugLogger.warn('Voice service unavailable - no models available');\n return emptyModels;\n }\n }\n\n public clearCache(): void {\n this.cachedModels = null;\n this.cacheTimestamp = 0;\n debugLogger.debug('Voice models cache cleared');\n }\n}\n\nexport const voiceService = VoiceService.getInstance();\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, BehaviorSubject, Subject } from 'rxjs';\nimport type { Subscriber } from 'rxjs';\nimport { debugLogger } from '../logging/debugLogger';\nimport { usePackageSettingsStore } from '../../store/packageSettingsStore';\nimport { getOrAppendAuthHeader } from './tts-client';\n\nexport enum TTSState {\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n PLAYING = 'PLAYING',\n PAUSED = 'PAUSED',\n ERROR = 'ERROR'\n}\n\nexport interface TTSProgress {\n currentTime: number;\n duration: number;\n percentage: number;\n buffered: number;\n state: TTSState;\n}\n\nexport interface TTSOptions {\n useStreaming?: boolean;\n useRealtime?: boolean;\n onStateChange?: (state: TTSState) => void;\n onProgress?: (progress: TTSProgress) => void;\n}\n\n/**\n * Streaming TTS client with playback controls\n */\nexport class StreamingTTSClient {\n private static instance: StreamingTTSClient;\n \n private audio: HTMLAudioElement | null = null;\n private objectUrl: string | null = null;\n private controller: AbortController | null = null;\n \n // Store event handler references for proper cleanup\n private audioHandlers = new Map<string, EventListener>();\n \n // State management\n private stateSubject = new BehaviorSubject<TTSState>(TTSState.IDLE);\n private progressSubject = new Subject<TTSProgress>();\n \n private constructor() {}\n \n public static getInstance(): StreamingTTSClient {\n if (!StreamingTTSClient.instance) {\n StreamingTTSClient.instance = new StreamingTTSClient();\n }\n return StreamingTTSClient.instance;\n }\n \n /**\n * Get current state\n */\n public getCurrentState(): TTSState {\n return this.stateSubject.value;\n }\n \n /**\n * Get state changes as observable\n */\n public getStateChanges(): Observable<TTSState> {\n return this.stateSubject.asObservable();\n }\n \n /**\n * Get progress updates as observable\n */\n public getProgress(): Observable<TTSProgress> {\n return this.progressSubject.asObservable();\n }\n \n /**\n * Speak text with simple streaming\n */\n public speakStream(text: string, voice: string, options: TTSOptions = {}): Observable<void> {\n return new Observable<void>((subscriber) => {\n this.performSimpleStreaming(text, voice, options, subscriber);\n });\n }\n \n /**\n * Simple streaming implementation - no queues, just direct playback\n */\n private async performSimpleStreaming(\n text: string,\n voice: string,\n options: TTSOptions,\n subscriber: Subscriber<void>\n ): Promise<void> {\n try {\n // Clean up any previous audio completely\n this.cleanup();\n \n // Brief delay to ensure cleanup is complete\n await new Promise(resolve => setTimeout(resolve, 10));\n \n // Set loading state\n this.setState(TTSState.LOADING);\n \n const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;\n if (!gatewayUrl) {\n throw new Error('Gateway API URL not configured');\n }\n \n // Create abort controller for this request\n this.controller = new AbortController();\n \n // Make the TTS request\n const response = await fetch(`${gatewayUrl}/tts`, {\n method: 'POST',\n headers: {\n ...getOrAppendAuthHeader(),\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n Text: text,\n ModelName: voice\n }),\n signal: this.controller.signal\n });\n \n // Check if request was aborted\n if (this.controller.signal.aborted) {\n subscriber.complete();\n return;\n }\n \n if (!response.ok) {\n throw new Error(`TTS request failed: ${response.status} ${response.statusText}`);\n }\n \n // Get the audio blob\n const audioBlob = await response.blob();\n \n // Check if request was aborted after blob download\n if (this.controller.signal.aborted) {\n subscriber.complete();\n return;\n }\n \n if (!audioBlob || audioBlob.size === 0) {\n throw new Error('Received empty audio response');\n }\n \n // Create object URL and audio element\n this.objectUrl = URL.createObjectURL(audioBlob);\n this.audio = new Audio(this.objectUrl);\n \n // Set up audio element\n this.audio.autoplay = false;\n this.audio.preload = 'auto';\n \n // Set up event listeners\n this.setupAudioListeners(subscriber, options);\n \n // Check one more time if we were stopped before starting to load\n if (this.controller.signal.aborted) {\n this.cleanup();\n subscriber.complete();\n return;\n }\n \n // Start loading the audio\n this.audio.load();\n \n } catch (error) {\n // Handle abort errors gracefully\n if (error instanceof Error && error.name === 'AbortError') {\n this.setState(TTSState.IDLE);\n subscriber.complete();\n return;\n }\n \n debugLogger.error('TTS streaming failed:', { error: error instanceof Error ? error.message : String(error) });\n this.setState(TTSState.ERROR);\n subscriber.error(error);\n }\n }\n \n /**\n * Set up audio event listeners\n */\n private setupAudioListeners(subscriber: Subscriber<void>, options: TTSOptions): void {\n if (!this.audio) return;\n \n // Clear any existing handlers\n this.audioHandlers.clear();\n \n // When audio can start playing\n const canPlayThroughHandler = () => {\n // Check if we were stopped during loading\n if (!this.audio || this.getCurrentState() !== TTSState.LOADING || (this.controller && this.controller.signal.aborted)) {\n return;\n }\n \n this.setState(TTSState.PLAYING);\n this.audio.play().catch((error) => {\n debugLogger.error('Failed to start audio playback:', error);\n this.setState(TTSState.ERROR);\n subscriber.error(error);\n });\n };\n \n // When audio starts playing\n const playHandler = () => {\n this.setState(TTSState.PLAYING);\n subscriber.next();\n };\n \n // When audio is paused\n const pauseHandler = () => {\n if (this.getCurrentState() !== TTSState.IDLE) {\n this.setState(TTSState.PAUSED);\n }\n };\n \n // When audio ends\n const endedHandler = () => {\n this.setState(TTSState.IDLE);\n \n // Clear handlers to prevent memory leaks\n this.clearAudioHandlers();\n \n subscriber.complete();\n };\n \n // Progress updates\n const timeUpdateHandler = () => {\n if (this.audio && this.audio.duration) {\n const buffered = this.audio.buffered.length > 0 ? this.audio.buffered.end(0) : 0;\n const progress: TTSProgress = {\n currentTime: this.audio.currentTime,\n duration: this.audio.duration,\n percentage: (this.audio.currentTime / this.audio.duration) * 100,\n buffered,\n state: this.getCurrentState()\n };\n this.progressSubject.next(progress);\n if (options.onProgress) {\n options.onProgress(progress);\n }\n }\n };\n \n // Error handling\n const errorHandler = (event: Event) => {\n debugLogger.error('Audio playback error:', event);\n this.setState(TTSState.ERROR);\n subscriber.error(new Error('Audio playback failed'));\n };\n \n // Store handler references for cleanup\n this.audioHandlers.set('canplaythrough', canPlayThroughHandler);\n this.audioHandlers.set('play', playHandler);\n this.audioHandlers.set('pause', pauseHandler);\n this.audioHandlers.set('ended', endedHandler);\n this.audioHandlers.set('timeupdate', timeUpdateHandler);\n this.audioHandlers.set('error', errorHandler);\n \n // Add event listeners\n this.audio.addEventListener('canplaythrough', canPlayThroughHandler);\n this.audio.addEventListener('play', playHandler);\n this.audio.addEventListener('pause', pauseHandler);\n this.audio.addEventListener('ended', endedHandler);\n this.audio.addEventListener('timeupdate', timeUpdateHandler);\n this.audio.addEventListener('error', errorHandler);\n }\n \n /**\n * Stop playback\n */\n public stop(): void {\n // Abort any ongoing fetch request\n if (this.controller) {\n this.controller.abort();\n this.controller = null;\n }\n \n // Stop and reset audio\n if (this.audio) {\n this.audio.pause();\n this.audio.currentTime = 0;\n \n // Remove all event listeners to prevent any further callbacks\n this.audio.onloadstart = null;\n this.audio.oncanplaythrough = null;\n this.audio.onplay = null;\n this.audio.onpause = null;\n this.audio.onended = null;\n this.audio.ontimeupdate = null;\n this.audio.onerror = null;\n }\n \n // Set to IDLE state first, then cleanup\n this.setState(TTSState.IDLE);\n this.cleanup();\n }\n \n /**\n * Pause playback\n */\n public pause(): void {\n if (this.audio && this.getCurrentState() === TTSState.PLAYING) {\n this.audio.pause();\n this.setState(TTSState.PAUSED);\n }\n }\n \n /**\n * Resume playback\n */\n public resume(): void {\n if (this.audio && this.getCurrentState() === TTSState.PAUSED) {\n this.audio.play().catch((error) => {\n debugLogger.error('Failed to resume audio:', error);\n this.setState(TTSState.ERROR);\n });\n this.setState(TTSState.PLAYING);\n }\n }\n \n /**\n * Set state and notify observers\n */\n private setState(state: TTSState): void {\n this.stateSubject.next(state);\n }\n \n /**\n * Reset the TTS client completely - useful for model changes\n */\n public reset(): void {\n // Stop everything first\n this.stop();\n \n // Force reset all internal state\n this.audio = null;\n this.objectUrl = null;\n this.controller = null;\n \n // Reset state subjects\n this.stateSubject.next(TTSState.IDLE);\n }\n\n /**\n * Clear only the audio event handlers\n */\n private clearAudioHandlers(): void {\n if (this.audio) {\n // Remove all event listeners using stored handler references\n for (const [eventType, handler] of this.audioHandlers) {\n this.audio.removeEventListener(eventType, handler);\n }\n }\n this.audioHandlers.clear();\n }\n\n /**\n * Clean up resources\n */\n private cleanup(): void {\n if (this.audio) {\n // Remove all event listeners using stored handler references\n this.clearAudioHandlers();\n \n // Stop and reset audio\n try {\n this.audio.pause();\n this.audio.currentTime = 0;\n this.audio.src = '';\n this.audio.load();\n } catch (error) {\n // Ignore cleanup errors\n }\n \n this.audio = null;\n }\n \n if (this.objectUrl) {\n URL.revokeObjectURL(this.objectUrl);\n this.objectUrl = null;\n }\n \n if (this.controller) {\n this.controller.abort();\n this.controller = null;\n }\n }\n}\n\n// Export singleton instance\nexport const getStreamingTTSClient = (): StreamingTTSClient => {\n return StreamingTTSClient.getInstance();\n};\n\n// Convenience functions\nexport const speakStream = (text: string, voice: string, options?: TTSOptions): Observable<void> => {\n return getStreamingTTSClient().speakStream(text, voice, options);\n};\n\nexport const stopTTS = (): void => {\n getStreamingTTSClient().stop();\n};\n\nexport const resetTTS = (): void => {\n getStreamingTTSClient().reset();\n};\n\nexport const pauseTTS = (): void => {\n getStreamingTTSClient().pause();\n};\n\nexport const resumeTTS = (): void => {\n getStreamingTTSClient().resume();\n};\n\nexport const getTTSState = (): TTSState => {\n return getStreamingTTSClient().getCurrentState();\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { Observable, Subscription } from 'rxjs';\nimport { authenticationService } from \"../auth/authenticationService\";\nimport { useVoiceStore } from '../../store/voiceStore';\nimport { sanitizeForTTS } from './ttsSanitizer';\nimport { usePackageSettingsStore } from '../../store/packageSettingsStore';\nimport { debugLogger } from '../logging/debugLogger';\n\nconst getGatewayApiUrl = () => usePackageSettingsStore.getState().settings?.gatewayApiUrl || '';\n\n/**\n * An observable that emits when the generated audio has begun playing. \n * @param text The text to be spoken\n * @param voice The voice to be used (will fallback to default if not available)\n * @returns An observable that emits when the audio has started playing\n */\nexport const speak = (text: string, voice: string) => {\n if (!text) {\n debugLogger.warn(\"No text provided to TTS\");\n return new Observable<void>((subscriber) => {\n subscriber.complete();\n });\n }\n\n const voiceState = useVoiceStore.getState();\n const availableVoices = voiceState.availableVoices;\n \n // Check if voice service is available\n if (!voiceState.isServiceAvailable || availableVoices.length === 0) {\n debugLogger.warn(\"TTS service unavailable - no voices configured\");\n return new Observable<void>((subscriber) => {\n subscriber.error(new Error('TTS service unavailable'));\n });\n }\n \n // Validate voice selection\n if (availableVoices.indexOf(voice) === -1) {\n if (voiceState.fallbackVoice && availableVoices.indexOf(voiceState.fallbackVoice) !== -1) {\n debugLogger.warn(`Voice model ${voice} is not available. Defaulting to '${voiceState.fallbackVoice}'`);\n voice = voiceState.fallbackVoice;\n } else {\n debugLogger.warn(`Voice model ${voice} is not available and no fallback configured`);\n return new Observable<void>((subscriber) => {\n subscriber.error(new Error(`Voice ${voice} not available`));\n });\n }\n }\n return new Observable<void>((subscriber) => {\n const controller = new AbortController();\n const signal = controller.signal;\n\n let audio: HTMLAudioElement | null = null;\n let objectUrl: string | null = null;\n\n const handleAudio = async (response: Response) => {\n if (!response.ok) throw new Error('Failed to fetch TTS');\n const blob = await response.blob();\n objectUrl = URL.createObjectURL(blob);\n audio = new Audio(objectUrl);\n audio.play();\n audio.onended = () => subscriber.complete();\n audio.onerror = (e) => subscriber.error(e);\n subscriber.next();\n };\n\n const handleError = (err: Error) => {\n if (signal.aborted) {\n subscriber.complete();\n } else {\n subscriber.error(err);\n }\n };\n\n // Use gateway API for all TTS requests\n debugLogger.debug('Fetching TTS from gateway API...');\n \n const gatewayUrl = getGatewayApiUrl();\n if (!gatewayUrl) {\n debugLogger.error('Gateway API URL not configured');\n subscriber.error(new Error('TTS service not configured'));\n return;\n }\n\n const requestBody = {\n Text: sanitizeForTTS(text),\n ModelName: voice\n };\n\n const ttsRequest: RequestInit = {\n method: 'POST',\n headers: {\n ...getOrAppendAuthHeader(),\n 'Content-Type': 'application/json'\n },\n mode: 'cors',\n body: JSON.stringify(requestBody),\n signal,\n };\n\n fetch(`${gatewayUrl}/tts`, ttsRequest)\n .then(handleAudio)\n .catch(handleError);\n\n const teardown = () => {\n controller.abort();\n if (audio) {\n audio.pause();\n audio.src = '';\n audio = null;\n }\n if (objectUrl) {\n URL.revokeObjectURL(objectUrl);\n objectUrl = null;\n }\n };\n\n return new Subscription(() => teardown());\n });\n};\n\nexport const getOrAppendAuthHeader = (existing: Record<string, string> = {}) => {\n const token = authenticationService.getToken();\n if (token) {\n existing[\"Authorization\"] = `Bearer ${token}`;\n return existing;\n }\n debugLogger.warn(\"No token found, using empty string for Authorization header\");\n existing[\"Authorization\"] = \"\";\n\n return existing;\n}\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\nimport { create } from \"zustand\";\n\n/**\n * The Canvas: a side-by-side editable document/code surface. The chat can drop\n * a generated answer into it (\"Open in canvas\"), the user edits it live, and it\n * can be copied or downloaded. Kept deliberately small — a single source of\n * truth that both the chat (entry points) and the CanvasPanel (UI) read from.\n */\ninterface CanvasState {\n open: boolean;\n title: string;\n content: string;\n /** Set when the canvas holds code (e.g. \"ts\", \"py\") so the editor uses a mono font. */\n language?: string;\n openCanvas: (args: { content: string; title?: string; language?: string }) => void;\n setContent: (content: string) => void;\n setTitle: (title: string) => void;\n close: () => void;\n}\n\nexport const useCanvasStore = create<CanvasState>((set) => ({\n open: false,\n title: \"\",\n content: \"\",\n language: undefined,\n openCanvas: ({ content, title, language }) =>\n set({ open: true, content, title: title?.trim() || \"Untitled\", language }),\n setContent: (content) => set({ content }),\n setTitle: (title) => set({ title }),\n close: () => set({ open: false }),\n}));\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useState, useEffect, useCallback, useRef, useMemo } from 'react';\nimport { Subscription } from 'rxjs';\nimport { \n getStreamingTTSClient, \n TTSState, \n TTSProgress, \n TTSOptions,\n stopTTS\n} from '../services/tts/streaming-tts';\n\n// Re-export types for convenience\nexport type { TTSState, TTSProgress, TTSOptions };\nimport { useVoiceStore } from '../store/voiceStore';\nimport { usePreferencesStore } from '../store/preferencesStore';\nimport { usePackageSettingsStore } from '../store/packageSettingsStore';\nimport { useModelStore } from '../store/modelStore';\nimport { debugLogger } from '../services/logging/debugLogger';\n\nexport interface UseTTSReturn {\n // State\n isPlaying: boolean;\n isPaused: boolean;\n isLoading: boolean;\n error: string | null;\n progress: TTSProgress | null;\n state: TTSState;\n \n // Actions\n speak: (text: string, options?: TTSOptions) => Promise<void>;\n stop: () => void;\n pause: () => void;\n resume: () => void;\n forcePlay: () => Promise<void>;\n \n // Utilities\n isAvailable: boolean;\n currentVoice: string;\n}\n\n/**\n * React hook for TTS with streaming support and playback controls\n */\nexport const useTTS = (): UseTTSReturn => {\n const [state, setState] = useState<TTSState>(TTSState.IDLE);\n const [progress, setProgress] = useState<TTSProgress | null>(null);\n const [error, setError] = useState<string | null>(null);\n \n // Store references\n const progressSubscriptionRef = useRef<Subscription | null>(null);\n const stateSubscriptionRef = useRef<Subscription | null>(null);\n const speakSubscriptionRef = useRef<Subscription | null>(null);\n const previousVoiceRef = useRef<string | null>(null);\n const previousModelRef = useRef<string | null>(null);\n const requestIdRef = useRef<number>(0); // Track request IDs to prevent out-of-order audio\n \n // Store hooks\n const { selectedVoice, isServiceAvailable } = useVoiceStore();\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n const { selectedModel } = useModelStore();\n \n // Check if TTS is available\n const isAvailable = !!(packageSettings?.gatewayApiUrl && preferences.ttsEnabled && isServiceAvailable);\n \n // Get TTS client\n const ttsClient = useMemo(() => getStreamingTTSClient(), []);\n\n // Set up subscriptions for state and progress updates\n useEffect(() => {\n // Clean up existing subscriptions\n if (progressSubscriptionRef.current) {\n progressSubscriptionRef.current.unsubscribe();\n }\n if (stateSubscriptionRef.current) {\n stateSubscriptionRef.current.unsubscribe();\n }\n\n // Subscribe to progress updates\n progressSubscriptionRef.current = ttsClient.getProgress().subscribe({\n next: (newProgress: TTSProgress) => {\n setProgress(newProgress);\n },\n error: (err: unknown) => {\n debugLogger.error('TTS progress subscription error', { error: err });\n }\n });\n\n // Subscribe to state changes\n stateSubscriptionRef.current = ttsClient.getStateChanges().subscribe({\n next: (newState: TTSState) => {\n setState(newState);\n \n // Clear error when state changes away from error\n if (newState !== TTSState.ERROR && error) {\n setError(null);\n }\n },\n error: (err: unknown) => {\n debugLogger.error('TTS state subscription error', { error: err });\n }\n });\n\n // Cleanup on unmount\n return () => {\n if (progressSubscriptionRef.current) {\n progressSubscriptionRef.current.unsubscribe();\n }\n if (stateSubscriptionRef.current) {\n stateSubscriptionRef.current.unsubscribe();\n }\n };\n }, [error, ttsClient]);\n\n // Handle voice and model changes - stop current playback when they change\n useEffect(() => {\n // Check if this is an actual voice or model change (not initial mount)\n const isVoiceChange = previousVoiceRef.current !== null && \n previousVoiceRef.current !== selectedVoice;\n const isModelChange = previousModelRef.current !== null && \n previousModelRef.current !== selectedModel;\n \n // If voice or model changed, stop current playback\n if (isVoiceChange || isModelChange) {\n // Invalidate current request to prevent any delayed audio\n requestIdRef.current++;\n \n // Clear any active subscription immediately\n if (speakSubscriptionRef.current) {\n speakSubscriptionRef.current.unsubscribe();\n speakSubscriptionRef.current = null;\n }\n \n // For model changes, do a complete reset to clear any bad state\n if (isModelChange) {\n ttsClient.reset();\n } else {\n // For voice changes, just stop\n ttsClient.stop();\n }\n \n setState(TTSState.IDLE);\n setError(null);\n \n // Update references immediately to prevent re-triggering\n previousVoiceRef.current = selectedVoice;\n previousModelRef.current = selectedModel;\n \n return; // Exit early to prevent double update\n }\n \n // Update the references for non-change cases\n if (previousVoiceRef.current === null) {\n previousVoiceRef.current = selectedVoice;\n }\n if (previousModelRef.current === null) {\n previousModelRef.current = selectedModel;\n }\n }, [selectedVoice, selectedModel, ttsClient]);\n\n // Speak function\n const speak = useCallback(async (text: string, options: TTSOptions = {}): Promise<void> => {\n if (!isAvailable) {\n const errorMsg = 'TTS service is not available';\n setError(errorMsg);\n throw new Error(errorMsg);\n }\n\n if (!text?.trim()) {\n const errorMsg = 'No text provided';\n setError(errorMsg);\n throw new Error(errorMsg);\n }\n\n try {\n setError(null);\n \n // Stop any current playback\n ttsClient.stop();\n \n // Also update previous voice and model references immediately\n previousVoiceRef.current = selectedVoice;\n previousModelRef.current = selectedModel;\n \n // Get the most current voice from store to avoid timing issues\n const currentVoice = useVoiceStore.getState().selectedVoice;\n const voiceToUse = currentVoice || selectedVoice;\n if (!voiceToUse) {\n throw new Error('No voice selected');\n }\n \n if (speakSubscriptionRef.current) {\n speakSubscriptionRef.current.unsubscribe();\n speakSubscriptionRef.current = null;\n \n // Add a small delay to ensure the previous audio is completely stopped\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n\n // Generate a unique request ID to ensure we only play the latest request\n const currentRequestId = ++requestIdRef.current;\n\n // Set loading state immediately\n setState(TTSState.LOADING);\n\n // Enable simple streaming\n const ttsOptions: TTSOptions = {\n useStreaming: true,\n useRealtime: true,\n ...options,\n onStateChange: (newState: TTSState) => {\n setState(newState);\n if (options.onStateChange) {\n options.onStateChange(newState);\n }\n },\n onProgress: (newProgress: TTSProgress) => {\n setProgress(newProgress);\n if (options.onProgress) {\n options.onProgress(newProgress);\n }\n }\n };\n\n debugLogger.debug('Starting TTS streaming');\n\n // Start speaking with simple streaming\n speakSubscriptionRef.current = ttsClient.speakStream(text, voiceToUse, ttsOptions).subscribe({\n next: () => {\n // Only process if this is still the latest request\n if (currentRequestId === requestIdRef.current) {\n // Audio started playing successfully\n }\n },\n error: (err: unknown) => {\n // Only process errors for the latest request\n if (currentRequestId === requestIdRef.current) {\n const errorMessage = err instanceof Error && err.message ? err.message : 'TTS playback failed';\n debugLogger.error('TTS playback failed', { error: err });\n setError(errorMessage);\n setState(TTSState.ERROR);\n }\n },\n complete: () => {\n // Only process completion for the latest request\n if (currentRequestId === requestIdRef.current) {\n setState(TTSState.IDLE);\n }\n }\n });\n\n } catch (err: unknown) {\n const errorMsg = err instanceof Error && err.message ? err.message : 'TTS failed to start';\n setError(errorMsg);\n setState(TTSState.ERROR);\n throw err instanceof Error ? err : new Error(errorMsg);\n }\n }, [isAvailable, selectedVoice, selectedModel, ttsClient]);\n\n // Stop function\n const stop = useCallback(() => {\n const currentRequestId = requestIdRef.current;\n \n // IMMEDIATELY update the hook state to IDLE for instant UI feedback\n setState(TTSState.IDLE);\n \n // Invalidate the current request to prevent any delayed audio\n requestIdRef.current++;\n \n // Unsubscribe and clear the subscription\n if (speakSubscriptionRef.current) {\n speakSubscriptionRef.current.unsubscribe();\n speakSubscriptionRef.current = null;\n }\n \n // Call the client stop method\n ttsClient.stop();\n \n // Clear any errors\n setError(null);\n }, [ttsClient]);\n\n // Pause function\n const pause = useCallback(() => {\n ttsClient.pause();\n }, [ttsClient]);\n\n // Resume function\n const resume = useCallback(() => {\n ttsClient.resume();\n }, [ttsClient]);\n\n // Force play function (simplified)\n const forcePlay = useCallback(async (): Promise<void> => {\n try {\n // For simple streaming, we don't need complex force play logic\n // The audio element should handle autoplay restrictions automatically\n if (ttsClient.getCurrentState() === TTSState.PAUSED) {\n ttsClient.resume();\n }\n } catch (err: unknown) {\n const errorMsg = err instanceof Error && err.message ? err.message : 'Failed to force play audio';\n setError(errorMsg);\n throw err instanceof Error ? err : new Error(errorMsg);\n }\n }, [ttsClient]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (speakSubscriptionRef.current) {\n speakSubscriptionRef.current.unsubscribe();\n }\n if (progressSubscriptionRef.current) {\n progressSubscriptionRef.current.unsubscribe();\n }\n if (stateSubscriptionRef.current) {\n stateSubscriptionRef.current.unsubscribe();\n }\n };\n }, []);\n\n // Stop any playback when TTS becomes unavailable\n useEffect(() => {\n if (!isAvailable && (state === TTSState.PLAYING || state === TTSState.LOADING)) {\n stop();\n }\n }, [isAvailable, state, stop]);\n\n return {\n // State\n isPlaying: state === TTSState.PLAYING,\n isPaused: state === TTSState.PAUSED,\n isLoading: state === TTSState.LOADING,\n error,\n progress,\n state,\n \n // Actions\n speak,\n stop,\n pause,\n resume,\n forcePlay,\n \n // Utilities\n isAvailable,\n currentVoice: selectedVoice\n };\n};\n\n/**\n * Global TTS controls hook - useful for global stop functionality\n */\nexport const useGlobalTTS = () => {\n const stopAll = useCallback(() => {\n stopTTS();\n }, []);\n\n return {\n stopAll\n };\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\n// Presentation helpers for the chat surfaces. Chat reads what a thing IS\n// (composer, control, attachment, conversation, status) from\n// `theme.palette.bandit`, never which colour it happened to borrow: the send\n// button used to take its colour from the file-chip token, and the live mic\n// from the error colour.\n\nimport React from \"react\";\nimport { Box, IconButton, type IconButtonProps } from \"@mui/material\";\nimport { alpha, type Theme } from \"@mui/material/styles\";\nimport type { BanditSemantics } from \"@burtson-labs/bandit-themes\";\nimport { dark as kitDark, fontMono, light as kitLight } from \"@burtson-labs/ui/tokens\";\nimport {\n type Icon,\n Archive,\n Braces,\n File,\n FileCode,\n FileImage,\n FilePdf,\n FileText,\n Sheet,\n} from \"@burtson-labs/icons/react\";\n\n/**\n * The Bandit semantics for the current theme. Themes from\n * `createBanditTheme` (every built-in skin and tenant) carry them; an\n * embedder that hands the engine its own MUI theme gets a faithful\n * derivation from the legacy `palette.chat` shape instead of a crash.\n */\nexport function chatTokens(theme: Theme): BanditSemantics {\n const own = (theme.palette as { bandit?: BanditSemantics }).bandit;\n if (own) return own;\n const p = theme.palette;\n const chat = (p as { chat?: Record<string, unknown> }).chat as\n | { shell?: string; input?: string; badge?: string; badgeHover?: string; file?: string; fileText?: string; caption?: string }\n | undefined;\n const bg = chat?.shell ?? p.background.default;\n const fg = chat?.fileText ?? p.text.primary;\n const muted = chat?.badge ?? p.action.hover;\n const border = p.divider;\n // A foreign theme has no recording colour; take the kit's rather than\n // borrowing error (a live mic is not a failure).\n const kit = p.mode === \"dark\" ? kitDark : kitLight;\n return {\n surface: {\n base: bg,\n raised: chat?.input ?? p.background.paper,\n subtle: chat?.file ?? p.background.paper,\n interactive: muted,\n interactiveHover: chat?.badgeHover ?? p.action.selected,\n overlay: p.background.paper,\n terminal: p.grey[900],\n terminalForeground: p.grey[100],\n },\n composer: {\n surface: chat?.input ?? p.background.paper,\n border,\n borderFocus: p.primary.main,\n foreground: fg,\n placeholder: p.text.secondary,\n },\n control: {\n surface: muted,\n surfaceHover: chat?.badgeHover ?? p.action.selected,\n foreground: fg,\n foregroundMuted: p.text.secondary,\n primarySurface: p.primary.main,\n primaryForeground: p.primary.contrastText,\n },\n attachment: { surface: chat?.file ?? muted, border, foreground: fg, icon: p.text.secondary },\n conversation: {\n user: { surface: muted, foreground: fg, border },\n assistant: { surface: \"transparent\", foreground: fg, border: \"transparent\" },\n border,\n divider: border,\n meta: chat?.caption ?? p.text.secondary,\n code: { surface: p.grey[900], foreground: p.grey[100] },\n },\n agent: { active: p.primary.main, idle: p.text.secondary, surface: alpha(p.primary.main, 0.12) },\n engine: { accent: p.primary.main, surface: alpha(p.primary.main, 0.12) },\n tool: { surface: muted, border, foreground: fg },\n knowledge: { accent: p.info.main, surface: alpha(p.info.main, 0.1) },\n workspace: { surface: p.background.paper, border },\n status: {\n recording: kit.recording,\n transcribing: p.info.main,\n thinking: p.primary.main,\n streaming: p.primary.main,\n syncing: p.info.main,\n temporary: p.warning.main,\n degraded: p.warning.main,\n disconnected: p.text.secondary,\n available: p.success.main,\n premium: p.primary.main,\n locked: p.text.secondary,\n info: p.info.main,\n success: p.success.main,\n warning: p.warning.main,\n error: p.error.main,\n },\n };\n}\n\n\nconst CODE_EXT = new Set([\"js\", \"jsx\", \"ts\", \"tsx\", \"py\", \"java\", \"c\", \"cpp\", \"cs\", \"go\", \"rb\", \"rs\", \"php\", \"sh\", \"sql\", \"html\", \"css\"]);\n\n/** The Burtson icon for a file, by extension. */\nexport function fileIconFor(filename: string): Icon {\n const ext = filename.split(\".\").pop()?.toLowerCase() ?? \"\";\n if (ext === \"json\" || ext === \"yaml\" || ext === \"yml\" || ext === \"toml\") return Braces;\n if (ext === \"pdf\") return FilePdf;\n if ([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\", \"heic\"].includes(ext)) return FileImage;\n if ([\"csv\", \"xlsx\", \"xls\", \"tsv\"].includes(ext)) return Sheet;\n if ([\"zip\", \"gz\", \"tar\", \"7z\", \"rar\"].includes(ext)) return Archive;\n if (CODE_EXT.has(ext)) return FileCode;\n if ([\"md\", \"txt\", \"docx\", \"doc\", \"rtf\"].includes(ext)) return FileText;\n return File;\n}\n\n/** The code/metadata font from the Burtson tokens (JetBrains Mono). */\nexport const monoFont = fontMono;\n\n/** \"TS\", \"PDF\", \"MD\"… a small label beside the icon. Empty when the name has no extension. */\nexport function fileExtensionLabel(filename: string): string {\n const parts = filename.split(\".\");\n return parts.length > 1 ? (parts.pop() ?? \"\").slice(0, 4).toUpperCase() : \"\";\n}\n\nexport interface ComposerControlProps extends Omit<IconButtonProps, \"color\"> {\n /** Size of the visible circle. The hit area is never smaller than 44px on touch. */\n visualSize: number;\n /** Hit-area size on a pointer device. */\n hitSize?: number;\n surface: string;\n surfaceHover: string;\n foreground: string;\n /** A ring drawn around the circle (e.g. while recording). */\n ring?: string;\n}\n\n/**\n * A round composer control whose visible circle can stay small while the\n * touch target is 44px (WCAG 2.5.5 / Apple HIG). The hover and pressed\n * treatment sits on the circle, so the larger hit area stays invisible.\n */\nexport const ComposerControl = React.forwardRef<HTMLButtonElement, ComposerControlProps>(\n function ComposerControl(\n { visualSize, hitSize, surface, surfaceHover, foreground, ring, children, sx, ...rest },\n ref,\n ) {\n const hit = Math.max(hitSize ?? visualSize, visualSize);\n return (\n <IconButton\n ref={ref}\n {...rest}\n disableRipple\n sx={[\n (t) => ({\n width: hit,\n height: hit,\n p: 0,\n borderRadius: \"50%\",\n color: foreground,\n bgcolor: \"transparent\",\n \"@media (pointer: coarse)\": { width: Math.max(hit, 44), height: Math.max(hit, 44) },\n \"& .bandit-control-circle\": {\n width: visualSize,\n height: visualSize,\n borderRadius: \"50%\",\n display: \"grid\",\n placeItems: \"center\",\n bgcolor: surface,\n boxShadow: ring ? `0 0 0 2px ${ring}` : \"none\",\n transition: t.transitions.create([\"background-color\", \"box-shadow\"], {\n duration: t.transitions.duration.shorter,\n }),\n },\n \"&:hover\": { bgcolor: \"transparent\" },\n \"&:hover .bandit-control-circle\": { bgcolor: surfaceHover },\n \"&.Mui-focusVisible .bandit-control-circle\": {\n boxShadow: `0 0 0 2px ${t.palette.background.default}, 0 0 0 4px ${\n (t.palette as { bandit?: BanditSemantics }).bandit?.composer.borderFocus ?? t.palette.primary.main\n }`,\n },\n \"&.Mui-disabled\": { opacity: 0.5 },\n }),\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ]}\n >\n <Box component=\"span\" className=\"bandit-control-circle\" aria-hidden={false}>\n {children}\n </Box>\n </IconButton>\n );\n },\n);\n\n/** App bar colours from the semantics (the old `palette.chat.appBar`). */\nexport function appBarTokens(theme: Theme) {\n const s = chatTokens(theme);\n return {\n background: s.surface.base,\n border: s.conversation.border,\n icon: s.control.foreground,\n iconHover: s.surface.interactive,\n menuBackground: s.surface.overlay,\n menuText: s.control.foreground,\n };\n}\n\n/** Suggestion chips (the old `palette.chat.suggestion`). */\nexport function suggestionTokens(theme: Theme) {\n const s = chatTokens(theme);\n return {\n background: s.surface.subtle,\n text: s.conversation.assistant.foreground,\n border: s.conversation.border,\n hoverBackground: s.surface.interactive,\n hoverBorder: theme.palette.divider,\n };\n}\n\n/** Message colours the response view reads. */\nexport function responseTokens(theme: Theme) {\n const s = chatTokens(theme);\n return {\n aiText: s.conversation.assistant.foreground,\n userBubble: s.conversation.user.surface,\n memoryText: s.status.success,\n };\n}\n","/**\n * Burtson UI design tokens. This file is the single source for colour, radius,\n * shadow and type: `scripts/theme.mjs` writes src/styles/theme.css from it, and the\n * MUI adapter (`@burtson-labs/ui/mui`) builds its palette from it, so Tailwind\n * apps and MUI apps render the same brand.\n *\n * Burtson's design language: technical, quiet, precise. Purple (`brand`) is a\n * signal colour for selection, focus, primary actions and small accents, not a\n * panel fill. Dark is a first-class palette, not an inversion of light. The\n * base colour names stay registry-compatible, so source copied into an app\n * keeps working.\n */\n\nexport type ColorToken =\n | 'background'\n | 'foreground'\n | 'surface'\n | 'surface-raised'\n | 'surface-muted'\n | 'card'\n | 'card-foreground'\n | 'popover'\n | 'popover-foreground'\n | 'primary'\n | 'primary-foreground'\n | 'secondary'\n | 'secondary-foreground'\n | 'muted'\n | 'muted-foreground'\n | 'accent'\n | 'accent-foreground'\n | 'destructive'\n | 'destructive-foreground'\n | 'success'\n | 'success-foreground'\n | 'warning'\n | 'warning-foreground'\n | 'info'\n | 'info-foreground'\n | 'recording'\n | 'recording-foreground'\n | 'border'\n | 'border-strong'\n | 'input'\n | 'ring'\n | 'brand'\n | 'brand-hover'\n | 'brand-soft'\n | 'brand-soft-foreground'\n | 'code'\n | 'code-foreground';\n\nexport type Palette = Record<ColorToken, string>;\n\n/** Burtson Labs purple. Use as signal, not wallpaper. */\nexport const brand = '#a60ee5';\n\nexport const light: Palette = {\n background: '#fbfafc',\n foreground: '#17131c',\n surface: '#ffffff',\n 'surface-raised': '#ffffff',\n 'surface-muted': '#f7f4f9',\n card: '#ffffff',\n 'card-foreground': '#17131c',\n popover: '#ffffff',\n 'popover-foreground': '#17131c',\n primary: '#8f0bc7',\n 'primary-foreground': '#ffffff',\n secondary: '#f1edf4',\n 'secondary-foreground': '#29212f',\n muted: '#f4f1f6',\n 'muted-foreground': '#6c6472',\n accent: '#f3e7fb',\n 'accent-foreground': '#561071',\n destructive: '#c92d3f',\n 'destructive-foreground': '#ffffff',\n success: '#0e7a56',\n 'success-foreground': '#ffffff',\n warning: '#9b5c08',\n 'warning-foreground': '#ffffff',\n info: '#2563eb',\n 'info-foreground': '#ffffff',\n // Live microphone capture. Red by convention, but its own token: recording\n // is a state, not an error, and apps can retint it without touching errors.\n recording: '#d6293e',\n 'recording-foreground': '#ffffff',\n border: '#e5dfe8',\n 'border-strong': '#cfc5d5',\n input: '#d8cfdd',\n ring: '#a60ee5',\n brand: '#a60ee5',\n 'brand-hover': '#8f0bc7',\n 'brand-soft': '#f5e8fc',\n 'brand-soft-foreground': '#5b1476',\n code: '#18141d',\n 'code-foreground': '#f5f0f7',\n};\n\nexport const dark: Palette = {\n background: '#0d0d12',\n foreground: '#f2eef5',\n surface: '#121218',\n 'surface-raised': '#18171f',\n 'surface-muted': '#17151c',\n card: '#14131a',\n 'card-foreground': '#f2eef5',\n popover: '#18171f',\n 'popover-foreground': '#f2eef5',\n primary: '#8f0bc7',\n 'primary-foreground': '#ffffff',\n secondary: '#211e28',\n 'secondary-foreground': '#e7e0eb',\n muted: '#1b1921',\n 'muted-foreground': '#a49ca9',\n accent: '#291734',\n 'accent-foreground': '#efd7fa',\n destructive: '#ef5b65',\n 'destructive-foreground': '#1b090b',\n success: '#36c58d',\n 'success-foreground': '#07160f',\n warning: '#f3b24c',\n 'warning-foreground': '#201304',\n info: '#6ea8ff',\n 'info-foreground': '#071226',\n recording: '#f2616d',\n 'recording-foreground': '#1b090b',\n border: '#2a2732',\n 'border-strong': '#403a49',\n input: '#34303d',\n ring: '#c65ef1',\n brand: '#c65ef1',\n 'brand-hover': '#d384f3',\n 'brand-soft': '#291734',\n 'brand-soft-foreground': '#efd7fa',\n code: '#09090d',\n 'code-foreground': '#f5f0f7',\n};\n\nexport const radius = {\n xs: '0.375rem',\n sm: '0.5rem',\n md: '0.625rem',\n lg: '0.75rem',\n xl: '1rem',\n full: '9999px',\n} as const;\n\nexport const shadow = {\n xs: '0 1px 2px rgb(10 8 14 / 0.05)',\n sm: '0 1px 3px rgb(10 8 14 / 0.08), 0 1px 2px rgb(10 8 14 / 0.05)',\n md: '0 10px 30px rgb(10 8 14 / 0.10), 0 2px 8px rgb(10 8 14 / 0.06)',\n focus: '0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent)',\n} as const;\n\nexport const fontSans =\n 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\nexport const fontMono =\n '\"JetBrains Mono\", \"SFMono-Regular\", Consolas, \"Liberation Mono\", monospace';\n\n/**\n * Motion. Surfaces enter from where they come from: popovers and menus slide a\n * few pixels from their trigger side (--bl-tx/--bl-ty, set per side by the\n * component), dialogs zoom slightly, sheets glide in with a drawer ease, and\n * everything leaves faster than it arrived. prefers-reduced-motion turns all\n * of it off (theme.css).\n */\nexport const motion = {\n animations: {\n in: 'bl-in 200ms cubic-bezier(0.16, 1, 0.3, 1)',\n out: 'bl-out 140ms cubic-bezier(0.4, 0, 1, 1) forwards',\n 'fade-in': 'bl-fade-in 200ms ease-out',\n 'fade-out': 'bl-fade-out 150ms ease-in forwards',\n 'sheet-in': 'bl-sheet-in 340ms cubic-bezier(0.32, 0.72, 0, 1)',\n 'sheet-out': 'bl-sheet-out 220ms cubic-bezier(0.4, 0, 1, 1) forwards',\n 'accordion-down': 'bl-accordion-down 200ms cubic-bezier(0.16, 1, 0.3, 1)',\n 'accordion-up': 'bl-accordion-up 160ms ease-out',\n 'collapsible-down': 'bl-collapsible-down 200ms cubic-bezier(0.16, 1, 0.3, 1)',\n 'collapsible-up': 'bl-collapsible-up 160ms ease-out',\n },\n keyframes: {\n 'bl-in': {\n from: {\n opacity: '0',\n transform: 'translate3d(var(--bl-tx, 0), var(--bl-ty, 0), 0) scale(var(--bl-scale, 0.96))',\n },\n },\n 'bl-out': {\n to: {\n opacity: '0',\n transform: 'translate3d(var(--bl-tx, 0), var(--bl-ty, 0), 0) scale(var(--bl-scale, 0.96))',\n },\n },\n 'bl-fade-in': { from: { opacity: '0' } },\n 'bl-fade-out': { to: { opacity: '0' } },\n 'bl-sheet-in': {\n from: { transform: 'translate3d(var(--bl-sheet-x, 100%), var(--bl-sheet-y, 0), 0)' },\n },\n 'bl-sheet-out': {\n to: { transform: 'translate3d(var(--bl-sheet-x, 100%), var(--bl-sheet-y, 0), 0)' },\n },\n 'bl-accordion-down': {\n from: { height: '0' },\n to: { height: 'var(--radix-accordion-content-height)' },\n },\n 'bl-accordion-up': {\n from: { height: 'var(--radix-accordion-content-height)' },\n to: { height: '0' },\n },\n 'bl-collapsible-down': {\n from: { height: '0' },\n to: { height: 'var(--radix-collapsible-content-height)' },\n },\n 'bl-collapsible-up': {\n from: { height: 'var(--radix-collapsible-content-height)' },\n to: { height: '0' },\n },\n },\n} as const;\n\n/**\n * Motion timing for code that animates outside CSS (MUI transitions, JS\n * animation). Things leave faster than they arrive; `emphasis` is for\n * surfaces that change the layout (drawers, dialogs, expanding panels).\n */\nexport const duration = { fast: 120, standard: 180, emphasis: 240, exit: 140 } as const;\nexport const easing = {\n standard: 'cubic-bezier(0.2, 0, 0, 1)',\n emphasized: 'cubic-bezier(0.16, 1, 0.3, 1)',\n exit: 'cubic-bezier(0.4, 0, 1, 1)',\n} as const;\n\n/** Named elevation levels over the shadow scale: 0 flat, 1 resting control, 2 card, 3 floating. */\nexport const elevation = { 0: 'none', 1: shadow.xs, 2: shadow.sm, 3: shadow.md } as const;\n\n// ─── Accent ────────────────────────────────────────────────────────────────\n\nexport type AccentTokens = Pick<\n Palette,\n | 'primary'\n | 'primary-foreground'\n | 'brand'\n | 'brand-hover'\n | 'brand-soft'\n | 'brand-soft-foreground'\n | 'accent'\n | 'accent-foreground'\n | 'ring'\n>;\n\ntype Rgb = [number, number, number];\n\nfunction parseHex(hex: string): Rgb {\n const h = hex.replace('#', '').trim();\n const full = h.length === 3 ? [...h].map((c) => c + c).join('') : h.slice(0, 6);\n if (!/^[0-9a-f]{6}$/i.test(full)) throw new Error(`Not a hex colour: ${hex}`);\n return [0, 2, 4].map((i) => parseInt(full.slice(i, i + 2), 16)) as Rgb;\n}\n\nconst toHex = (rgb: Rgb) =>\n '#' +\n rgb\n .map((v) =>\n Math.round(Math.max(0, Math.min(255, v)))\n .toString(16)\n .padStart(2, '0'),\n )\n .join('');\n\n/** Mix `a` toward `b` by `t` (0 = a, 1 = b), in sRGB. */\nexport function mix(a: string, b: string, t: number): string {\n const x = parseHex(a);\n const y = parseHex(b);\n return toHex([0, 1, 2].map((i) => x[i]! + (y[i]! - x[i]!) * t) as Rgb);\n}\n\nfunction luminance(hex: string): number {\n const c = parseHex(hex).map((v) => {\n const s = v / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n });\n return 0.2126 * c[0]! + 0.7152 * c[1]! + 0.0722 * c[2]!;\n}\n\n/** WCAG contrast ratio between two hex colours. */\nexport function contrast(a: string, b: string): number {\n const [hi, lo] = [luminance(a), luminance(b)].sort((m, n) => n - m) as [number, number];\n return (hi + 0.05) / (lo + 0.05);\n}\n\n/** Step `color` toward `target` until it reaches `ratio` against `against`. */\nfunction ensureContrast(color: string, against: string, ratio: number, target: string): string {\n let c = color;\n for (let i = 0; i < 20 && contrast(c, against) < ratio; i++) c = mix(c, target, 0.1);\n return c;\n}\n\n/**\n * Brand tokens for any accent colour, kept legible: the primary fill always\n * carries its foreground at 4.5:1, and the brand colour used for links, focus\n * and selected text reads at 4.5:1 on the page background. Tenants and skins\n * choose an accent; they never choose the contrast.\n */\nexport function accentTokens(accent: string, mode: 'light' | 'dark'): AccentTokens {\n const p = mode === 'dark' ? dark : light;\n const white = '#ffffff';\n // A dark foreground on light fills (yellow, cyan) instead of forcing white.\n // White text on the fill whenever darkening the accent a little gets there\n // (purples, blues, greens, reds: the usual brand colours, which read as the\n // brand when they carry white). Dark text only for genuinely light accents\n // such as yellow or pale cyan, where white would need the colour ruined.\n const onFill = contrast(accent, white) >= 2.6 ? white : '#111111';\n const primary =\n onFill === white\n ? ensureContrast(accent, white, 4.5, '#000000')\n : ensureContrast(accent, '#111111', 4.5, white);\n const brand =\n mode === 'dark'\n ? ensureContrast(mix(accent, white, 0.12), p.background, 4.5, white)\n : ensureContrast(accent, p.background, 4.5, '#000000');\n const brandHover = mode === 'dark' ? mix(brand, white, 0.18) : mix(brand, '#000000', 0.14);\n const soft = mode === 'dark' ? mix(p.background, accent, 0.16) : mix(white, accent, 0.1);\n const softFg = mode === 'dark' ? mix(accent, white, 0.72) : mix(accent, '#000000', 0.55);\n return {\n primary,\n 'primary-foreground': onFill,\n brand,\n 'brand-hover': brandHover,\n 'brand-soft': soft,\n 'brand-soft-foreground': ensureContrast(softFg, soft, 4.5, mode === 'dark' ? white : '#000000'),\n accent: soft,\n 'accent-foreground': ensureContrast(softFg, soft, 4.5, mode === 'dark' ? white : '#000000'),\n ring: brand,\n };\n}\n\nexport const tokens = {\n brand,\n light,\n dark,\n radius,\n shadow,\n elevation,\n motion,\n duration,\n easing,\n fontSans,\n fontMono,\n} as const;\nexport default tokens;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState, useEffect, useMemo } from \"react\";\nimport {\n Drawer,\n Box,\n Typography,\n List,\n ListItem,\n useMediaQuery,\n Theme,\n useTheme,\n Chip,\n IconButton,\n Tooltip,\n Collapse,\n TextField,\n InputAdornment,\n Divider,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n DialogContentText,\n Button,\n MenuItem,\n} from \"@mui/material\";\nimport { useAIQueryStore } from \"../../store/aiQueryStore\";\nimport { useConversationStore, type Conversation } from \"../../store/conversationStore\";\nimport { useVoiceStore } from \"../../store/voiceStore\";\nimport { useMemoryStore } from \"../../store/memoryStore\";\nimport { usePreferencesStore } from \"../../store/preferencesStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { useModelStore } from \"../../store/modelStore\";\nimport AIResponseTextField from \"./ai-response-text-field\";\nimport MemoryModal from \"../../chat/memory-modal\";\nimport { speakStream } from \"../../services/tts/streaming-tts\";\nimport { Subscription } from \"rxjs\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { toTitleCase } from \"../../util\";\nimport {\n CheckIcon,\n CloseIcon,\n DeleteIcon,\n ExpandLessIcon,\n ExpandMoreIcon,\n HistoryIcon,\n InfoOutlinedIcon,\n MemoryIcon,\n RecordVoiceOverIcon,\n RefreshIcon,\n SearchIcon,\n} from \"../../icons\";\n\n/** Yes/no mark for the voice diagnostics line; reads as text in the caption's own colour. */\nconst StatusMark = ({ ok }: { ok: boolean }) =>\n ok ? (\n <CheckIcon fontSize=\"inherit\" color=\"success\" titleAccess=\"yes\" sx={{ verticalAlign: \"text-bottom\" }} />\n ) : (\n <CloseIcon fontSize=\"inherit\" color=\"error\" titleAccess=\"no\" sx={{ verticalAlign: \"text-bottom\" }} />\n );\n\ninterface AIQueriesDrawerProps {\n drawerOpen: boolean;\n onClose: () => void;\n onClearComplete?: () => void; // Add callback for when clear is complete\n onNavigateToMain?: () => void; // Add callback for navigating to main chat\n}\n\nconst AIQueriesDrawer: React.FC<AIQueriesDrawerProps> = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain }) => {\n const theme = useTheme();\n const isMobile = useMediaQuery((theme: Theme) =>\n theme.breakpoints.down(\"sm\")\n );\n\n // AI Query Store (local session history)\n const history = useAIQueryStore((state) => state.history);\n const clearHistory = useAIQueryStore((state) => state.clearHistory);\n const setResponse = useAIQueryStore((state) => state.setResponse);\n const setPreviousQuestion = useAIQueryStore((state) => state.setPreviousQuestion);\n const setInputValue = useAIQueryStore((state) => state.setInputValue);\n\n // Main Conversation Store\n const { conversations, currentId, switchConversation, _hasHydrated, hydrate } = useConversationStore();\n\n // Voice Store\n const { availableVoices, selectedVoice, setSelectedVoice, isServiceAvailable, refreshVoices } = useVoiceStore();\n\n // Memory Store\n const { entries: memoryEntries } = useMemoryStore();\n\n // Preferences and Settings\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n\n // AI Provider and Model stores for voice changing\n const provider = useAIProviderStore((state) => state.provider);\n const { selectedModel, availableModels } = useModelStore();\n\n // Local state\n const [searchTerm, setSearchTerm] = useState(\"\");\n const [expandedItems, setExpandedItems] = useState<Set<number>>(new Set());\n const [expandedConversations, setExpandedConversations] = useState<Set<string>>(new Set());\n const [confirmClearOpen, setConfirmClearOpen] = useState(false);\n const [infoDialogOpen, setInfoDialogOpen] = useState(false);\n const [memoryModalOpen, setMemoryModalOpen] = useState(false);\n const [contextMode, setContextMode] = useState<\"local\" | \"main\">(\"local\");\n const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set([\"history\", \"voice\"]));\n const [audioSub, setAudioSub] = useState<Subscription>(new Subscription());\n const [isContextSwitching, setIsContextSwitching] = useState(false);\n const [isDrawerLoading, setIsDrawerLoading] = useState(false);\n\n // Auto-hydrate conversations when drawer opens\n useEffect(() => {\n if (drawerOpen && !_hasHydrated) {\n hydrate();\n }\n }, [drawerOpen, _hasHydrated, hydrate]);\n\n // Cleanup on drawer close\n useEffect(() => {\n if (!drawerOpen) {\n setIsDrawerLoading(false);\n // Cleanup after close animation completes\n const cleanupTimer = setTimeout(() => {\n setSearchTerm(\"\");\n setExpandedItems(new Set());\n setExpandedConversations(new Set());\n }, 225); // After close animation\n \n return () => clearTimeout(cleanupTimer);\n }\n }, [drawerOpen]);\n\n // Cleanup audio subscription on unmount\n useEffect(() => {\n return () => {\n audioSub.unsubscribe();\n };\n }, [audioSub]);\n\n // Helper functions\n const toggleSection = (section: string) => {\n setExpandedSections((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(section)) {\n newSet.delete(section);\n } else {\n newSet.add(section);\n }\n return newSet;\n });\n };\n\n const handleContextSwitch = async (newMode: \"local\" | \"main\") => {\n if (newMode === contextMode) return;\n\n setIsContextSwitching(true);\n\n try {\n // Use requestAnimationFrame to allow UI updates before heavy operations\n await new Promise(resolve => requestAnimationFrame(resolve));\n\n // If switching to main and store isn't hydrated, wait for hydration\n if (newMode === \"main\" && !_hasHydrated) {\n debugLogger.debug(\"Context switch triggering hydration\", { newMode, hasHydrated: _hasHydrated });\n\n // Break up the hydration process\n await new Promise(resolve => {\n setTimeout(async () => {\n await hydrate();\n resolve(void 0);\n }, 50);\n });\n\n // Additional delay to ensure UI updates\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n\n // Use another frame to ensure smooth transition\n await new Promise(resolve => requestAnimationFrame(resolve));\n\n setContextMode(newMode);\n // Reset expanded states when switching context\n setExpandedItems(new Set());\n setExpandedConversations(new Set());\n\n debugLogger.debug(\"Context switch completed\", { newMode, conversationCount: conversations.length });\n } catch (error) {\n debugLogger.error(\"Error during context switch\", { error: String(error) });\n } finally {\n // Add minimum delay for better UX and ensure loading state shows\n setTimeout(() => setIsContextSwitching(false), 300);\n }\n };\n\n const isVoiceAvailable = isServiceAvailable && preferences.ttsEnabled && !!packageSettings?.gatewayApiUrl;\n const isMemoryAvailable = preferences.memoryEnabled;\n const currentConversation = conversations.find(c => c.id === currentId);\n\n // Loading states\n const isInitialLoading = !_hasHydrated && contextMode === \"main\";\n const isContentLoading = isContextSwitching || isInitialLoading;\n\n // Debug loading states - defer logging to avoid blocking drawer opening\n useEffect(() => {\n if (drawerOpen) {\n // Defer debug logging to avoid blocking drawer animation\n const debugTimer = setTimeout(() => {\n debugLogger.debug(\"Chat drawer loading states\", {\n drawerOpen,\n _hasHydrated,\n isDrawerLoading,\n isContentLoading,\n contextMode,\n storeState: \"modal-chat-drawer-loading\"\n });\n }, 400); // After drawer animation and initial setup\n\n return () => clearTimeout(debugTimer);\n }\n }, [drawerOpen, _hasHydrated, isDrawerLoading, isContentLoading, contextMode]);\n\n // Debug voice availability\n useEffect(() => {\n debugLogger.debug(\"Chat drawer voice availability check\", {\n isServiceAvailable,\n ttsEnabled: preferences.ttsEnabled,\n gatewayApiUrl: !!packageSettings?.gatewayApiUrl,\n isVoiceAvailable,\n availableVoicesCount: availableVoices.length,\n selectedVoice,\n storeState: \"modal-chat-drawer-voice\"\n });\n }, [isServiceAvailable, preferences.ttsEnabled, packageSettings?.gatewayApiUrl, isVoiceAvailable, availableVoices.length, selectedVoice]);\n\n // Get the appropriate history based on context mode\n const activeHistory = useMemo(() => {\n if (contextMode === \"local\") {\n return history;\n }\n\n return currentConversation?.history ?? [];\n }, [contextMode, history, currentConversation]);\n\n // When switching to main context, ensure we have a valid conversation\n const effectiveContextMode = contextMode === \"main\" && (!currentConversation || currentConversation.history.length === 0)\n ? \"local\"\n : contextMode;\n\n // Remove auto-selection - let user choose conversation manually\n // (Auto-selection removed to allow user control over conversation viewing)\n\n // Debug context switching\n useEffect(() => {\n debugLogger.debug(\"Chat drawer context state\", {\n contextMode,\n effectiveContextMode,\n conversationCount: conversations.length,\n currentConversationId: currentId,\n currentConversationName: currentConversation?.name,\n currentConversationHistoryLength: currentConversation?.history.length || 0,\n localHistoryLength: history.length,\n hasHydrated: _hasHydrated,\n storeState: \"modal-chat-drawer\"\n });\n }, [contextMode, effectiveContextMode, conversations.length, currentId, currentConversation, history.length, _hasHydrated]);\n\n // Filter history based on search term and context mode with memoization\n const filteredHistory = useMemo(() => {\n const filtered = activeHistory.filter((entry) =>\n entry.question.toLowerCase().includes(searchTerm.toLowerCase()) ||\n entry.answer.toLowerCase().includes(searchTerm.toLowerCase())\n );\n // Limit to last 20 items for performance\n return filtered.slice(-20);\n }, [activeHistory, searchTerm]);\n\n // Filter conversations based on search term (for main context) with memoization\n const filteredConversations = useMemo<Conversation[]>(() => {\n const filtered = conversations.filter((conversation) =>\n conversation.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n conversation.history.some(entry =>\n entry.question.toLowerCase().includes(searchTerm.toLowerCase()) ||\n entry.answer.toLowerCase().includes(searchTerm.toLowerCase())\n )\n );\n // Limit to first 20 items for performance\n return filtered.slice(0, 20);\n }, [conversations, searchTerm]);\n\n const toggleExpanded = (index: number) => {\n const newExpanded = new Set(expandedItems);\n if (newExpanded.has(index)) {\n newExpanded.delete(index);\n } else {\n newExpanded.add(index);\n }\n setExpandedItems(newExpanded);\n };\n\n const toggleConversationExpanded = (conversationId: string) => {\n const newExpanded = new Set(expandedConversations);\n if (newExpanded.has(conversationId)) {\n newExpanded.delete(conversationId);\n } else {\n newExpanded.add(conversationId);\n }\n setExpandedConversations(newExpanded);\n };\n\n // Voice change handler - same as in chat.tsx\n const handleVoiceChange = (newVoice: string) => {\n debugLogger.debug(\"Chat drawer voice change initiated\", {\n oldVoice: selectedVoice,\n newVoice,\n storeState: \"modal-chat-drawer-voice-change\"\n });\n\n // Use voice store setter to persist the change\n setSelectedVoice(newVoice);\n const voiceName = newVoice.split(\"-\")[1];\n const defaultModel = packageSettings?.defaultModel;\n\n // Get the friendly display name for the personality (use selectedModel which is the Bandit personality)\n const currentModelConfig = availableModels.find(m => m.name === selectedModel);\n const personalityName = currentModelConfig ? currentModelConfig.name.replace(\"Bandit-\", \"Bandit \") : (selectedModel || defaultModel || \"Bandit\");\n\n // Only play greeting if TTS is available and enabled\n const isTTSAvailable = !!packageSettings?.gatewayApiUrl && preferences.ttsEnabled;\n\n if (isTTSAvailable) {\n debugLogger.debug(\"Playing voice greeting\", { voiceName, personalityName });\n \n // Create the greeting directly - no AI generation needed\n const greetingText = `Hi, I'm ${personalityName} speaking with ${voiceName}'s voice.`;\n \n // Use speakStream directly\n const spoken = speakStream(greetingText, newVoice);\n audioSub.unsubscribe();\n setAudioSub(\n spoken.subscribe({\n next: () => debugLogger.debug(\"Voice greeting played successfully\"),\n error: (err) => {\n debugLogger.error(`Error changing voices: ${err}`);\n }\n })\n );\n } else {\n debugLogger.debug(\"Voice greeting skipped\", {\n hasProvider: !!provider,\n isTTSAvailable,\n hasDefaultModel: !!defaultModel\n });\n }\n };\n\n const handleClearHistory = () => {\n setConfirmClearOpen(true);\n };\n\n const handleConfirmClear = () => {\n // Clear all chat data\n clearHistory();\n setResponse(\"\");\n setPreviousQuestion(\"\");\n setInputValue(\"\");\n\n // Reset local state\n setExpandedItems(new Set());\n setSearchTerm(\"\");\n setConfirmClearOpen(false);\n\n // Close the drawer and notify parent (to close modal)\n onClose();\n if (onClearComplete) {\n onClearComplete();\n }\n };\n\n const handleCancelClear = () => {\n setConfirmClearOpen(false);\n };\n\n return (\n <Drawer\n anchor=\"right\"\n open={drawerOpen}\n onClose={onClose}\n keepMounted={false} // Don't keep mounted when closed to improve performance\n disablePortal={false}\n sx={{\n zIndex: 1400,\n '& .MuiDrawer-paper': {\n width: isMobile ? \"100vw\" : \"50vw\",\n maxWidth: isMobile ? \"100vw\" : \"600px\",\n bgcolor: theme.palette.background.paper,\n borderLeft: `1px solid ${theme.palette.divider}`,\n backdropFilter: \"blur(20px)\",\n boxShadow: theme.palette.mode === \"dark\"\n ? \"0 8px 32px rgba(0,0,0,0.5)\"\n : \"0 8px 32px rgba(0,0,0,0.2)\",\n // Optimize animations\n transition: 'transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms',\n }\n }}\n transitionDuration={225} // Faster animation\n SlideProps={{\n timeout: 225, // Consistent timing\n }}\n >\n <Box\n sx={{\n height: \"100%\",\n bgcolor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n }}\n role=\"presentation\"\n >\n {/* Enhanced Header */}\n <Box\n sx={{\n p: 3,\n borderBottom: `1px solid ${theme.palette.divider}`,\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.02)\" : \"rgba(0,0,0,0.02)\",\n backdropFilter: \"blur(10px)\",\n }}\n >\n {/* Title and Context Toggle */}\n <Box sx={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", mb: 2 }}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <HistoryIcon sx={{ color: theme.palette.primary.main }} />\n <Typography variant=\"h6\" sx={{ fontWeight: 600, color: \"text.primary\" }}>\n Chat Control Center\n </Typography>\n <Tooltip title=\"About Chat History\" arrow>\n <IconButton\n onClick={() => setInfoDialogOpen(true)}\n size=\"small\"\n sx={{\n color: theme.palette.info.main,\n \"&:hover\": {\n bgcolor: theme.palette.info.main + \"20\",\n },\n }}\n >\n <InfoOutlinedIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n\n <Tooltip title=\"Refresh Conversations\" arrow>\n <IconButton\n onClick={() => {\n debugLogger.info(\"Manual conversation refresh triggered\", {\n currentConversationCount: conversations.length,\n hasHydrated: _hasHydrated,\n currentId\n });\n hydrate();\n // Also refresh voice store if needed\n if (availableVoices.length === 0) {\n refreshVoices();\n }\n }}\n size=\"small\"\n sx={{\n color: theme.palette.primary.main,\n \"&:hover\": {\n bgcolor: theme.palette.primary.main + \"20\",\n },\n }}\n >\n <RefreshIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n\n <Tooltip title=\"Close\" arrow>\n <IconButton\n onClick={onClose}\n size=\"small\"\n sx={{\n color: theme.palette.text.secondary,\n \"&:hover\": {\n bgcolor: theme.palette.action.hover,\n color: theme.palette.text.primary,\n },\n }}\n >\n <CloseIcon />\n </IconButton>\n </Tooltip>\n </Box>\n\n {/* Context Switching */}\n <Box sx={{ mb: 2 }}>\n <Box\n sx={{\n display: \"flex\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n borderRadius: \"12px\",\n p: 0.5,\n border: `1px solid ${theme.palette.divider}`,\n }}\n >\n <Button\n onClick={() => handleContextSwitch(\"local\")}\n variant={contextMode === \"local\" ? \"contained\" : \"text\"}\n disabled={isContextSwitching}\n sx={{\n flex: 1,\n textTransform: \"none\",\n borderRadius: \"8px\",\n fontWeight: 600,\n fontSize: \"0.8rem\",\n position: \"relative\",\n ...(contextMode === \"local\" && {\n bgcolor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n \"&:hover\": {\n bgcolor: theme.palette.primary.dark,\n },\n }),\n }}\n >\n {isContextSwitching && contextMode !== \"local\" ? (\n <Box sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n opacity: 0.7\n }}>\n <Box sx={{\n width: 12,\n height: 12,\n border: '2px solid currentColor',\n borderTop: '2px solid transparent',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n '@keyframes spin': {\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n }\n }} />\n Loading...\n </Box>\n ) : (\n <>\n Session Context\n <Chip\n label={history.length}\n size=\"small\"\n sx={{\n ml: 1,\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: contextMode === \"local\"\n ? theme.palette.primary.contrastText + \"20\"\n : theme.palette.primary.main + \"20\",\n color: contextMode === \"local\"\n ? theme.palette.primary.contrastText\n : theme.palette.primary.main,\n }}\n />\n </>\n )}\n </Button>\n <Tooltip title=\"Switch to conversation history\" arrow>\n <Button\n onClick={() => handleContextSwitch(\"main\")}\n variant={contextMode === \"main\" ? \"contained\" : \"text\"}\n disabled={conversations.length === 0 || isContextSwitching}\n sx={{\n flex: 1,\n textTransform: \"none\",\n borderRadius: \"8px\",\n fontWeight: 600,\n fontSize: \"0.8rem\",\n position: \"relative\",\n ...(contextMode === \"main\" && {\n bgcolor: theme.palette.secondary.main,\n color: theme.palette.secondary.contrastText,\n \"&:hover\": {\n bgcolor: theme.palette.secondary.dark,\n },\n }),\n }}\n >\n {isContextSwitching && contextMode !== \"main\" ? (\n <Box sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n opacity: 0.7\n }}>\n <Box sx={{\n width: 12,\n height: 12,\n border: '2px solid currentColor',\n borderTop: '2px solid transparent',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n '@keyframes spin': {\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n }\n }} />\n Loading...\n </Box>\n ) : (\n <>\n Main Conversation\n <Chip\n label={conversations.length}\n size=\"small\"\n sx={{\n ml: 1,\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: contextMode === \"main\"\n ? theme.palette.secondary.contrastText + \"20\"\n : theme.palette.secondary.main + \"20\",\n color: contextMode === \"main\"\n ? theme.palette.secondary.contrastText\n : theme.palette.secondary.main,\n }}\n />\n </>\n )}\n </Button>\n </Tooltip>\n </Box>\n </Box>\n\n {/* Voice Controls Section */}\n {isVoiceAvailable ? (\n <Box sx={{ mb: 2 }}>\n <Box\n onClick={() => toggleSection(\"voice\")}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n cursor: \"pointer\",\n p: 1,\n borderRadius: \"8px\",\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n },\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <RecordVoiceOverIcon sx={{ color: theme.palette.success.main, fontSize: \"1.2rem\" }} />\n <Typography variant=\"subtitle2\" sx={{ fontWeight: 600, color: \"text.primary\" }}>\n Voice Model\n </Typography>\n <Chip\n label={selectedVoice ? toTitleCase(selectedVoice.split(\"-\")[1]) : \"Default\"}\n size=\"small\"\n sx={{\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: theme.palette.success.main + \"20\",\n color: theme.palette.success.main,\n }}\n />\n <Tooltip title=\"Refresh Voices\" arrow>\n <IconButton\n onClick={(e) => {\n e.stopPropagation();\n debugLogger.debug(\"Manual voice refresh triggered from chat drawer\");\n refreshVoices();\n }}\n size=\"small\"\n sx={{\n color: theme.palette.text.secondary,\n \"&:hover\": {\n bgcolor: theme.palette.success.main + \"20\",\n color: theme.palette.success.main,\n },\n }}\n >\n <RefreshIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n {expandedSections.has(\"voice\") ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </Box>\n\n <Collapse in={expandedSections.has(\"voice\")}>\n <Box sx={{ pl: 2, pt: 1 }}>\n {availableVoices.length > 0 ? (\n <TextField\n select\n fullWidth\n size=\"small\"\n label=\"Voice Model\"\n value={selectedVoice}\n onChange={(e) => {\n const newVoice = e.target.value;\n handleVoiceChange(newVoice);\n }}\n sx={{\n \"& .MuiOutlinedInput-root\": {\n borderRadius: \"8px\",\n },\n }}\n >\n {availableVoices.map((voice) => (\n <MenuItem key={voice} value={voice}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1, width: \"100%\" }}>\n <RecordVoiceOverIcon fontSize=\"small\" sx={{ color: theme.palette.text.secondary }} />\n <Box sx={{ flex: 1 }}>\n <Typography variant=\"body2\">\n {toTitleCase(voice.split(\"-\")[1])}\n </Typography>\n <Typography variant=\"caption\" sx={{ color: theme.palette.text.secondary }}>\n {voice === selectedVoice ? \"Currently active\" : \"Switch to this voice\"}\n </Typography>\n </Box>\n {voice === selectedVoice && (\n <Box\n sx={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n bgcolor: theme.palette.success.main,\n }}\n />\n )}\n </Box>\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <Box sx={{ textAlign: \"center\", py: 2 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n No voices available\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: \"block\", mt: 1 }}>\n Service: <StatusMark ok={isServiceAvailable} /> | TTS: <StatusMark ok={preferences.ttsEnabled} /> | Gateway: <StatusMark ok={!!packageSettings?.gatewayApiUrl} />\n </Typography>\n </Box>\n )}\n </Box>\n </Collapse>\n </Box>\n ) : (\n <Box sx={{ mb: 2 }}>\n <Box sx={{ p: 1, borderRadius: \"8px\", bgcolor: theme.palette.warning.main + \"10\" }}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <RecordVoiceOverIcon sx={{ color: theme.palette.warning.main, fontSize: \"1.2rem\" }} />\n <Typography variant=\"subtitle2\" sx={{ fontWeight: 600, color: theme.palette.warning.main }}>\n Voice Not Available\n </Typography>\n </Box>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: \"block\", mt: 1, pl: 4 }}>\n Service: <StatusMark ok={isServiceAvailable} /> | TTS: <StatusMark ok={preferences.ttsEnabled} /> | Gateway: <StatusMark ok={!!packageSettings?.gatewayApiUrl} />\n </Typography>\n </Box>\n </Box>\n )}\n\n {/* Memory Controls Section */}\n {isMemoryAvailable && (\n <Box sx={{ mb: 2 }}>\n <Box\n onClick={() => toggleSection(\"memory\")}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n cursor: \"pointer\",\n p: 1,\n borderRadius: \"8px\",\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n },\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <MemoryIcon sx={{ color: theme.palette.warning.main, fontSize: \"1.2rem\" }} />\n <Typography variant=\"subtitle2\" sx={{ fontWeight: 600, color: \"text.primary\" }}>\n Personal Memory\n </Typography>\n <Chip\n label={memoryEntries.length}\n size=\"small\"\n sx={{\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: theme.palette.warning.main + \"20\",\n color: theme.palette.warning.main,\n }}\n />\n </Box>\n {expandedSections.has(\"memory\") ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </Box>\n\n <Collapse in={expandedSections.has(\"memory\")}>\n <Box sx={{ pl: 2, pt: 1 }}>\n <Button\n fullWidth\n variant=\"outlined\"\n onClick={() => setMemoryModalOpen(true)}\n startIcon={<MemoryIcon />}\n sx={{\n textTransform: \"none\",\n borderRadius: \"8px\",\n fontWeight: 600,\n fontSize: \"0.8rem\",\n }}\n >\n Manage Memories\n </Button>\n </Box>\n </Collapse>\n </Box>\n )}\n\n {/* History Section Header */}\n <Box\n onClick={() => toggleSection(\"history\")}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n cursor: \"pointer\",\n p: 1,\n borderRadius: \"8px\",\n mb: 1,\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n },\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <HistoryIcon sx={{ color: theme.palette.primary.main, fontSize: \"1.2rem\" }} />\n <Typography variant=\"subtitle2\" sx={{ fontWeight: 600, color: \"text.primary\" }}>\n {contextMode === \"local\" ? \"Session History\" : \"Conversation History\"}\n </Typography>\n <Chip\n label={activeHistory.length}\n size=\"small\"\n sx={{\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: theme.palette.primary.main + \"20\",\n color: theme.palette.primary.main,\n }}\n />\n {activeHistory.length > 0 && contextMode === \"local\" && (\n <Tooltip title=\"Clear Session History\" arrow>\n <IconButton\n onClick={(e) => {\n e.stopPropagation();\n handleClearHistory();\n }}\n size=\"small\"\n sx={{\n color: theme.palette.error.main,\n \"&:hover\": {\n bgcolor: theme.palette.error.main + \"20\",\n },\n }}\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n {expandedSections.has(\"history\") ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </Box>\n\n {/* Search Bar - only show when history section is expanded */}\n <Collapse in={expandedSections.has(\"history\")}>\n <Box sx={{ mb: 1 }}>\n {activeHistory.length > 0 && (\n <TextField\n fullWidth\n size=\"small\"\n placeholder={`Search ${contextMode === \"local\" ? \"session\" : \"conversation\"} history...`}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon sx={{ color: theme.palette.text.secondary }} />\n </InputAdornment>\n ),\n sx: {\n borderRadius: \"12px\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n \"& .MuiOutlinedInput-notchedOutline\": {\n border: `1px solid ${theme.palette.divider}`,\n },\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\n borderColor: theme.palette.primary.main + \"60\",\n },\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\n borderColor: theme.palette.primary.main,\n },\n },\n }}\n />\n )}\n </Box>\n </Collapse>\n </Box>\n\n {/* Content Area */}\n <Collapse in={expandedSections.has(\"history\")}>\n <Box\n sx={{\n flex: 1,\n overflowY: \"auto\",\n p: 2,\n minHeight: \"200px\", // Reduced minimum height\n maxHeight: \"400px\", // Reduced max height for better performance\n position: \"relative\", // For loading overlay positioning\n // Custom scrollbar\n \"&::-webkit-scrollbar\": {\n width: \"8px\",\n },\n \"&::-webkit-scrollbar-track\": {\n background: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.1)\" : \"rgba(0,0,0,0.1)\",\n borderRadius: \"4px\",\n },\n \"&::-webkit-scrollbar-thumb\": {\n background: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.2)\" : \"rgba(0,0,0,0.2)\",\n borderRadius: \"4px\",\n \"&:hover\": {\n background: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.3)\" : \"rgba(0,0,0,0.3)\",\n },\n },\n // Firefox scrollbar\n scrollbarWidth: \"thin\",\n scrollbarColor: theme.palette.mode === \"dark\"\n ? \"rgba(255,255,255,0.2) rgba(255,255,255,0.1)\"\n : \"rgba(0,0,0,0.2) rgba(0,0,0,0.1)\",\n }}\n >\n {/* Loading Overlay */}\n {isContentLoading && (\n <Box\n sx={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n bgcolor: theme.palette.mode === \"dark\"\n ? \"rgba(0, 0, 0, 0.7)\"\n : \"rgba(255, 255, 255, 0.8)\",\n backdropFilter: \"blur(4px)\",\n zIndex: 10,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 2,\n }}\n >\n <Box sx={{\n width: 40,\n height: 40,\n border: '3px solid currentColor',\n borderTop: '3px solid transparent',\n borderRadius: '50%',\n animation: 'spin 1s linear infinite',\n color: theme.palette.primary.main,\n '@keyframes spin': {\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' }\n }\n }} />\n <Typography\n variant=\"body2\"\n sx={{\n color: theme.palette.text.primary,\n fontWeight: 500,\n }}\n >\n {isInitialLoading ? \"Loading conversations...\" : \"Switching context...\"}\n </Typography>\n </Box>\n )}\n\n {/* Content - only render when not loading to prevent layout thrashing */}\n {!isContentLoading && (\n contextMode === \"main\" ? (\n // Show conversation list when in main context\n filteredConversations.length === 0 ? (\n <Box\n sx={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"200px\",\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <HistoryIcon sx={{ fontSize: \"3rem\", mb: 2, opacity: 0.5 }} />\n <Typography variant=\"h6\" sx={{ mb: 1, fontWeight: 500, color: \"text.primary\" }}>\n {searchTerm ? \"No Matching Conversations\" : \"No Conversations Yet\"}\n </Typography>\n <Typography variant=\"body2\">\n {searchTerm\n ? \"Try adjusting your search terms\"\n : \"Create your first conversation to get started\"\n }\n </Typography>\n </Box>\n ) : (\n <List sx={{ p: 0 }}>\n {filteredConversations.map((conversation, index: number) => {\n const isCurrent = conversation.id === currentId;\n const isExpanded = expandedConversations.has(conversation.id);\n const conversationHistory = conversation.history || [];\n\n return (\n <ListItem\n key={conversation.id}\n sx={{\n display: \"block\",\n p: 0,\n mb: 1,\n }}\n >\n <Box\n sx={{\n bgcolor: isCurrent\n ? theme.palette.primary.main + \"20\"\n : theme.palette.background.default,\n borderRadius: \"8px\",\n border: `1px solid ${isCurrent\n ? theme.palette.primary.main + \"40\"\n : theme.palette.divider}`,\n overflow: \"hidden\",\n transition: \"all 0.2s ease-in-out\",\n }}\n >\n {/* Conversation Header */}\n <Box\n onClick={() => {\n toggleConversationExpanded(conversation.id);\n // Also switch to this conversation as the current one\n switchConversation(conversation.id);\n }}\n sx={{\n p: 2,\n cursor: \"pointer\",\n \"&:hover\": {\n bgcolor: isCurrent\n ? theme.palette.primary.main + \"30\"\n : theme.palette.primary.main + \"10\",\n },\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", mb: 1 }}>\n <Typography\n variant=\"subtitle2\"\n sx={{\n fontWeight: 600,\n color: isCurrent\n ? theme.palette.primary.main\n : theme.palette.text.primary,\n flex: 1,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {conversation.name}\n </Typography>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n {isCurrent && (\n <Chip\n label=\"Current\"\n size=\"small\"\n sx={{\n height: \"18px\",\n fontSize: \"0.6rem\",\n bgcolor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n }}\n />\n )}\n {isExpanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}\n </Box>\n </Box>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n }}\n >\n {conversationHistory.length} messages\n </Typography>\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n }}\n >\n • Model: {conversation.model}\n </Typography>\n </Box>\n </Box>\n\n {/* Expanded Conversation Messages */}\n <Collapse in={isExpanded}>\n {conversationHistory.length > 0 ? (\n <Box sx={{ borderTop: `1px solid ${theme.palette.divider}`, bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.02)\" : \"rgba(0,0,0,0.02)\" }}>\n {conversationHistory\n .filter((entry) =>\n !searchTerm ||\n entry.question.toLowerCase().includes(searchTerm.toLowerCase()) ||\n entry.answer.toLowerCase().includes(searchTerm.toLowerCase())\n )\n .slice()\n .reverse()\n .map((entry, messageIndex: number) => {\n const isMessageExpanded = expandedItems.has(messageIndex);\n return (\n <Box key={messageIndex} sx={{ borderBottom: `1px solid ${theme.palette.divider}` }}>\n <Box\n onClick={(e) => {\n e.stopPropagation();\n toggleExpanded(messageIndex);\n }}\n sx={{\n p: 2,\n cursor: \"pointer\",\n \"&:hover\": {\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n },\n }}\n >\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: 500,\n color: theme.palette.text.primary,\n mb: 1,\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {entry.question}\n </Typography>\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n display: \"-webkit-box\",\n WebkitLineClamp: 1,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {entry.answer}\n </Typography>\n </Box>\n\n {/* Expanded Message Content */}\n <Collapse in={isMessageExpanded}>\n <Box sx={{ p: 2, pt: 0, bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.02)\" : \"rgba(0,0,0,0.02)\" }}>\n <AIResponseTextField\n question={entry.question}\n response={entry.answer}\n />\n </Box>\n </Collapse>\n </Box>\n );\n })}\n </Box>\n ) : (\n <Box sx={{ p: 2, textAlign: \"center\", color: theme.palette.text.secondary, borderTop: `1px solid ${theme.palette.divider}` }}>\n <Typography variant=\"body2\">\n No messages in this conversation yet\n </Typography>\n </Box>\n )}\n </Collapse>\n </Box>\n </ListItem>\n );\n })}\n </List>\n )\n ) : (\n // Show message history when in local context\n activeHistory.length === 0 ? (\n <Box\n sx={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"200px\",\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <HistoryIcon sx={{ fontSize: \"3rem\", mb: 2, opacity: 0.5 }} />\n <Typography variant=\"h6\" sx={{ mb: 1, fontWeight: 500, color: \"text.primary\" }}>\n No Session History Yet\n </Typography>\n <Typography variant=\"body2\">\n Start a conversation to see your session history here\n </Typography>\n </Box>\n ) : filteredHistory.length === 0 ? (\n <Box\n sx={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: \"200px\",\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <SearchIcon sx={{ fontSize: \"3rem\", mb: 2, opacity: 0.5 }} />\n <Typography variant=\"h6\" sx={{ mb: 1, fontWeight: 500, color: \"text.primary\" }}>\n No Results Found\n </Typography>\n <Typography variant=\"body2\">\n Try adjusting your search terms\n </Typography>\n </Box>\n ) : (\n <List sx={{ p: 0 }}>\n {[...filteredHistory].reverse().map((entry, index) => {\n const isExpanded = expandedItems.has(index);\n return (\n <React.Fragment key={index}>\n <ListItem\n sx={{\n display: \"block\",\n p: 0,\n mb: 2,\n }}\n >\n <Box\n onClick={() => toggleExpanded(index)}\n sx={{\n bgcolor: theme.palette.background.default,\n borderRadius: \"12px\",\n border: `1px solid ${theme.palette.divider}`,\n overflow: \"hidden\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease-in-out\",\n \"&:hover\": {\n borderColor: theme.palette.primary.main + \"60\",\n boxShadow: `0 4px 12px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.3)\" : \"rgba(0,0,0,0.1)\"}`,\n transform: \"translateY(-1px)\",\n },\n }}\n >\n {/* Preview Header */}\n <Box sx={{ p: 2 }}>\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: 500,\n color: theme.palette.text.primary,\n mb: 1,\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {entry.question}\n </Typography>\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n display: \"-webkit-box\",\n WebkitLineClamp: 1,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {entry.answer}\n </Typography>\n </Box>\n\n {/* Expanded Content */}\n <Collapse in={isExpanded}>\n <Divider />\n <Box sx={{ p: 2 }}>\n <AIResponseTextField\n question={entry.question}\n response={entry.answer}\n />\n </Box>\n </Collapse>\n </Box>\n </ListItem>\n </React.Fragment>\n );\n })}\n </List>\n )\n )\n )}\n </Box>\n </Collapse>\n </Box>\n\n {/* Custom Confirmation Modal */}\n <Dialog\n open={confirmClearOpen}\n onClose={handleCancelClear}\n maxWidth=\"sm\"\n fullWidth\n sx={{\n zIndex: 1500, // Higher than drawer (1400)\n }}\n PaperProps={{\n sx: {\n borderRadius: \"16px\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(30, 30, 30, 0.95)\" : \"rgba(255, 255, 255, 0.95)\",\n backdropFilter: \"blur(20px)\",\n border: `1px solid ${theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.12)\" : \"rgba(0,0,0,0.12)\"}`,\n boxShadow: `0 24px 48px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.5)\" : \"rgba(0,0,0,0.15)\"}`,\n }\n }}\n BackdropProps={{\n sx: {\n bgcolor: \"rgba(0, 0, 0, 0.4)\",\n backdropFilter: \"blur(8px)\",\n }\n }}\n >\n <DialogTitle\n sx={{\n pb: 1,\n fontSize: \"1.5rem\",\n fontWeight: 600,\n color: theme.palette.error.main,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n }}\n >\n <DeleteIcon sx={{ fontSize: \"1.75rem\" }} />\n Clear Chat History\n </DialogTitle>\n\n <DialogContent sx={{ pb: 2 }}>\n <DialogContentText\n sx={{\n fontSize: \"1rem\",\n color: theme.palette.text.primary,\n mb: 2,\n }}\n >\n Are you sure you want to clear all chat history?\n </DialogContentText>\n <DialogContentText\n sx={{\n fontSize: \"0.9rem\",\n color: theme.palette.text.secondary,\n fontStyle: \"italic\",\n }}\n >\n This action cannot be undone. All your conversation history will be permanently deleted.\n </DialogContentText>\n </DialogContent>\n\n <DialogActions\n sx={{\n p: 3,\n pt: 1,\n gap: 1,\n }}\n >\n <Button\n onClick={handleCancelClear}\n variant=\"outlined\"\n sx={{\n borderRadius: \"12px\",\n textTransform: \"none\",\n fontWeight: 600,\n minWidth: \"100px\",\n border: `2px solid ${theme.palette.text.secondary}`,\n color: theme.palette.text.primary,\n \"&:hover\": {\n border: `2px solid ${theme.palette.text.primary}`,\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.05)\" : \"rgba(0,0,0,0.05)\",\n }\n }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleConfirmClear}\n variant=\"contained\"\n color=\"error\"\n sx={{\n borderRadius: \"12px\",\n textTransform: \"none\",\n fontWeight: 600,\n minWidth: \"100px\",\n bgcolor: theme.palette.error.main,\n \"&:hover\": {\n bgcolor: theme.palette.error.dark,\n transform: \"translateY(-1px)\",\n boxShadow: `0 6px 20px ${theme.palette.error.main}40`,\n },\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n Clear All\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Info Dialog */}\n <Dialog\n open={infoDialogOpen}\n onClose={() => setInfoDialogOpen(false)}\n maxWidth=\"sm\"\n fullWidth\n sx={{\n zIndex: 1500, // Higher than drawer (1400)\n }}\n PaperProps={{\n sx: {\n borderRadius: \"16px\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(30, 30, 30, 0.95)\" : \"rgba(255, 255, 255, 0.95)\",\n backdropFilter: \"blur(20px)\",\n border: `1px solid ${theme.palette.mode === \"dark\" ? \"rgba(255,255,255,0.12)\" : \"rgba(0,0,0,0.12)\"}`,\n boxShadow: `0 24px 48px ${theme.palette.mode === \"dark\" ? \"rgba(0,0,0,0.5)\" : \"rgba(0,0,0,0.15)\"}`,\n }\n }}\n BackdropProps={{\n sx: {\n bgcolor: \"rgba(0, 0, 0, 0.4)\",\n backdropFilter: \"blur(8px)\",\n }\n }}\n >\n <DialogTitle\n sx={{\n pb: 2,\n fontSize: \"1.5rem\",\n fontWeight: 600,\n color: theme.palette.info.main,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n }}\n >\n <InfoOutlinedIcon sx={{ fontSize: \"1.75rem\" }} />\n About Chat Control Center\n </DialogTitle>\n\n <DialogContent sx={{ pb: 2 }}>\n <DialogContentText\n sx={{\n fontSize: \"1rem\",\n color: theme.palette.text.primary,\n mb: 2,\n lineHeight: 1.6,\n }}\n >\n This control center gives you full access to your chat experience and AI capabilities.\n </DialogContentText>\n\n <DialogContentText\n sx={{\n fontSize: \"0.95rem\",\n color: theme.palette.text.secondary,\n mb: 2,\n lineHeight: 1.6,\n }}\n >\n <strong>Context Modes:</strong><br />\n • <strong>Session Context</strong>: Local conversation for this modal session only<br />\n • <strong>Main Conversation</strong>: Your persistent account conversations<br />\n • Switch between them to access different conversation histories<br /><br />\n\n <strong>Additional Features:</strong><br />\n • <strong>Voice Models</strong>: Change AI voice when TTS is enabled<br />\n • <strong>Personal Memory</strong>: Manage what the AI remembers about you<br />\n • <strong>Search & Organization</strong>: Find specific conversations quickly\n </DialogContentText>\n\n <DialogContentText\n sx={{\n fontSize: \"0.9rem\",\n color: theme.palette.info.main,\n fontStyle: \"italic\",\n bgcolor: theme.palette.mode === \"dark\" ? \"rgba(33, 150, 243, 0.1)\" : \"rgba(33, 150, 243, 0.05)\",\n p: 2,\n borderRadius: \"8px\",\n border: `1px solid ${theme.palette.info.main}30`,\n }}\n >\n 💡 <strong>Pro Tip:</strong> Use Session Context for quick experiments and Main Conversation\n for important discussions you want to keep. All features respect your privacy settings!\n </DialogContentText>\n </DialogContent>\n\n <DialogActions\n sx={{\n p: 3,\n pt: 1,\n }}\n >\n <Button\n onClick={() => setInfoDialogOpen(false)}\n variant=\"contained\"\n sx={{\n borderRadius: \"12px\",\n textTransform: \"none\",\n fontWeight: 600,\n minWidth: \"100px\",\n bgcolor: theme.palette.info.main,\n \"&:hover\": {\n bgcolor: theme.palette.info.dark,\n transform: \"translateY(-1px)\",\n boxShadow: `0 6px 20px ${theme.palette.info.main}40`,\n },\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n Got it!\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Memory Modal */}\n <MemoryModal\n open={memoryModalOpen}\n onClose={() => setMemoryModalOpen(false)}\n />\n </Drawer>\n );\n};\n\nexport default AIQueriesDrawer;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState, useEffect } from \"react\";\nimport { useTheme, alpha, keyframes } from \"@mui/material/styles\";\nimport {\n Box,\n Typography,\n Modal,\n SwipeableDrawer,\n IconButton,\n TextField,\n Button,\n List,\n ListItem,\n Divider,\n Tabs,\n Tab,\n Tooltip,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Avatar,\n Radio,\n RadioGroup,\n FormControlLabel,\n FormControl,\n useMediaQuery,\n} from \"@mui/material\";\nimport { useMemoryStore } from \"../store/memoryStore\";\nimport { useVectorStore } from \"../hooks/useVectorStore\";\nimport type { VectorMemory } from \"../services/vectorDatabase/vectorDatabaseService\";\nimport { useConversationSyncStore } from \"../store/conversationSyncStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport {\n CloudSyncIcon,\n CloseIcon,\n DeleteIcon,\n PushPinIcon,\n PushPinOutlinedIcon,\n WarningIcon,\n} from \"../icons\";\nimport { appBarTokens, chatTokens } from \"./chat-tokens\";\n\ninterface MemoryModalProps {\n open: boolean;\n onClose: () => void;\n}\n\n\ntype ImportResultDetails = {\n totalMemories: number;\n successCount: number;\n failureCount: number;\n duration?: string;\n warnings?: string[];\n};\n\ntype ImportResult = {\n success: boolean;\n message?: string;\n details?: ImportResultDetails;\n};\n\ntype ImportProgress = {\n isImporting: boolean;\n progress: string;\n result?: ImportResult;\n};\n\n/**\n * Bandit Memory Modal\n *\n * - Displays user and auto memories.\n * - Supports editing, pinning, deleting, and adding new memories.\n * - Memory-aware layout adapts to mobile virtual keyboards.\n * - Shows pinned memory token budget in real-time.\n */\nconst MemoryModal: React.FC<MemoryModalProps> = ({ open, onClose }) => {\n const { entries, addMemory, togglePinMemory, removeMemory, clearMemories, hydrate, _hasHydrated } = useMemoryStore();\n const isAdvancedVectorFeaturesEnabled = useConversationSyncStore(\n (state) => state.isAdvancedVectorFeaturesEnabled\n );\n const { \n isVectorEnabled, \n addMemory: addVectorMemory, \n batchCreateMemories,\n batchCreateMemoriesAdvanced,\n batchImportMemories,\n getUserMemories: getVectorMemories,\n deleteMemory: deleteVectorMemory,\n updateMemory: updateVectorMemory\n } = useVectorStore();\n \n // Check if vector should be used for memories\n const shouldUseVectorForMemories = isVectorEnabled && isAdvancedVectorFeaturesEnabled;\n \n // Debug preferences on modal open\n useEffect(() => {\n if (open) {\n debugLogger.memoryDebug(\"Memory modal opened\", {\n isVectorEnabled,\n isAdvancedVectorFeaturesEnabled,\n shouldUseVectorForMemories,\n });\n }\n }, [open, isVectorEnabled, isAdvancedVectorFeaturesEnabled, shouldUseVectorForMemories]);\n \n const [newMemory, setNewMemory] = useState(\"\");\n const [selectedTab, setSelectedTab] = useState<\"auto\" | \"user\">(\"user\"); // Always default to user\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editedContent, setEditedContent] = useState(\"\");\n const [multiSelectMode, setMultiSelectMode] = useState(false);\n const [selectedIds, setSelectedIds] = useState<string[]>([]);\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [clearAllOpen, setClearAllOpen] = useState(false);\n const [clearOption, setClearOption] = useState<\"user\" | \"auto\" | \"both\">(\"both\");\n const [vectorMemories, setVectorMemories] = useState<VectorMemory[]>([]);\n const [bulkImportOpen, setBulkImportOpen] = useState(false);\n const [importProgress, setImportProgress] = useState<ImportProgress>({\n isImporting: false,\n progress: \"\",\n });\n\n const theme = useTheme();\n const isMobileView = useMediaQuery(theme.breakpoints.down(\"sm\"));\n \n // Define pulse animation\n const pulse = keyframes`\n 0% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.7;\n transform: scale(1.1);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n `;\n\n // Define shimmer animation\n const shimmer = keyframes`\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n `;\n\n const chat = chatTokens(theme);\n const shell = chat.surface.base;\n const input = chat.composer.surface;\n const fileText = chat.attachment.foreground;\n const appBar = appBarTokens(theme);\n const badge = chat.control.surface;\n const badgeHover = chat.control.surfaceHover;\n\n const handleAdd = async () => {\n if (newMemory.trim()) {\n if (shouldUseVectorForMemories) {\n try {\n await addVectorMemory(newMemory.trim());\n // Refresh vector memories list\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } catch (error) {\n debugLogger.error(\"Failed to add vector memory\", { error });\n // Fallback to local store\n await addMemory(newMemory.trim(), [], \"user\");\n }\n } else {\n await addMemory(newMemory.trim(), [], \"user\");\n }\n setNewMemory(\"\");\n }\n };\n\n // Load vector memories when modal opens and vector is enabled\n useEffect(() => {\n if (open && shouldUseVectorForMemories) {\n const loadVectorMemories = async () => {\n try {\n const memories = await getVectorMemories();\n debugLogger.memoryDebug(\"Vector memories loaded\", {\n count: memories?.length || 0,\n isArray: Array.isArray(memories),\n });\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } catch (error) {\n debugLogger.error(\"Failed to load vector memories\", { error });\n setVectorMemories([]);\n }\n };\n loadVectorMemories();\n }\n }, [open, shouldUseVectorForMemories, getVectorMemories]);\n\n // Load local memories when modal opens and vector is disabled\n useEffect(() => {\n if (open && !shouldUseVectorForMemories) {\n const loadLocalMemories = async () => {\n try {\n await hydrate();\n } catch (error) {\n debugLogger.error(\"Failed to load local memories\", { error });\n }\n };\n loadLocalMemories();\n }\n }, [open, shouldUseVectorForMemories, hydrate]);\n\n // Also hydrate on initial mount to ensure memories are always loaded\n useEffect(() => {\n if (!shouldUseVectorForMemories && !_hasHydrated) {\n const initialHydrate = async () => {\n try {\n await hydrate();\n } catch (error) {\n debugLogger.error(\"Failed to perform initial hydration\", { error });\n }\n };\n initialHydrate();\n }\n }, [shouldUseVectorForMemories, _hasHydrated, hydrate]);\n\n const handleMultiDelete = async () => {\n if (selectedIds.length === 0) return;\n \n // Use the working single delete function in a loop\n let successCount = 0;\n let errorCount = 0;\n \n for (const id of selectedIds) {\n try {\n await handleDeleteMemory(id);\n successCount++;\n \n // Add a small delay to avoid overwhelming the API\n await new Promise(resolve => setTimeout(resolve, 100));\n } catch (error) {\n debugLogger.error(\"Failed to delete memory during bulk delete\", { id, error });\n errorCount++;\n }\n }\n \n setSelectedIds([]);\n setMultiSelectMode(false);\n setConfirmOpen(false);\n };\n\n const handleMultiPin = async (pinned: boolean) => {\n debugLogger.memoryDebug(\"Multi-pin requested\", {\n count: selectedIds.length,\n pinned,\n });\n\n if (selectedIds.length === 0) {\n debugLogger.warn(\"No memories selected for pinning\");\n return;\n }\n \n if (shouldUseVectorForMemories) {\n // For vector memories, loop through each ID and update pin status\n let successCount = 0;\n let errorCount = 0;\n \n for (const id of selectedIds) {\n try {\n const result = await updateVectorMemory(id, { pinned });\n if (result && result.success) {\n successCount++;\n } else {\n debugLogger.error(\"Failed to update vector memory pin status\", {\n id,\n error: result?.error || \"Unknown error\",\n });\n errorCount++;\n }\n } catch (error) {\n debugLogger.error(\"Exception updating vector memory pin status\", { id, error });\n errorCount++;\n }\n }\n \n debugLogger.memoryDebug(\"Vector pin update summary\", {\n successCount,\n errorCount,\n });\n \n // Refresh vector memories list\n try {\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } catch (error) {\n debugLogger.error(\"Failed to refresh vector memories after pin update\", { error });\n }\n } else {\n // Local store pin toggle\n try {\n let successCount = 0;\n \n for (const id of selectedIds) {\n const currentEntries = useMemoryStore.getState().entries;\n const memory = currentEntries.find(entry => entry.id === id);\n \n if (memory) {\n if (memory.pinned !== pinned) {\n togglePinMemory(id);\n successCount++;\n } else {\n debugLogger.memoryDebug(\"Memory already at desired pin status\", { id, pinned });\n }\n } else {\n debugLogger.warn(\"Memory not found in local store during pin update\", { id });\n }\n }\n \n debugLogger.memoryDebug(\"Local pin update summary\", { successCount });\n } catch (error) {\n debugLogger.error(\"Failed to update local pin status\", { error });\n }\n }\n \n setSelectedIds([]);\n setMultiSelectMode(false);\n };\n\n const handleDeleteMemory = async (memoryId: string) => {\n if (shouldUseVectorForMemories) {\n try {\n const result = await deleteVectorMemory(memoryId);\n \n if (result && result.success) {\n // Refresh vector memories list\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } else {\n throw new Error(result?.error || 'Delete operation failed');\n }\n } catch (error) {\n debugLogger.error(\"Failed to delete vector memory\", { error });\n // Don't fallback to local store for vector memories, just throw the error\n throw error;\n }\n } else {\n removeMemory(memoryId);\n }\n };\n\n const toggleSelection = (id: string) => {\n setSelectedIds((prev) =>\n prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]\n );\n };\n\n const handleBulkImport = async () => {\n if (!batchCreateMemoriesAdvanced) {\n debugLogger.error(\"Advanced batch import not available\");\n return;\n }\n\n setImportProgress({ isImporting: true, progress: 'Preparing import...' });\n \n try {\n // Get all memories from IndexedDB\n await hydrate();\n const indexedDBMemories = entries;\n\n if (indexedDBMemories.length === 0) {\n setImportProgress({ \n isImporting: false, \n progress: 'No memories found to import',\n result: { success: false, message: 'No memories found in local storage' }\n });\n return;\n }\n\n // Convert IndexedDB format to vector format\n const memoriesToImport = indexedDBMemories.map(entry => ({\n content: entry.content,\n title: `Imported Memory - ${new Date(entry.timestamp).toLocaleDateString()}`,\n tags: entry.tags || []\n }));\n\n // Use advanced batch import with progress reporting\n const result = await batchCreateMemoriesAdvanced(memoriesToImport, {\n mode: 'append',\n clearExisting: false,\n chunkSize: 25, // Smaller chunks for better progress reporting\n validateContent: true,\n onProgress: (current: number, total: number, message: string) => {\n setImportProgress({ \n isImporting: true, \n progress: `${message} (${current}/${total})`\n });\n }\n });\n \n setImportProgress({ \n isImporting: false, \n progress: 'Import completed!',\n result: {\n success: result.success,\n message: result.message,\n details: {\n totalMemories: result.totalMemories,\n successCount: result.successCount,\n failureCount: result.failureCount,\n warnings: result.warnings,\n duration: `${(result.duration / 1000).toFixed(1)}s`\n }\n }\n });\n\n if (result.success) {\n // Refresh vector memories list\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n \n // Auto-close dialog after success\n setTimeout(() => {\n setBulkImportOpen(false);\n setImportProgress({ isImporting: false, progress: '' });\n }, 3000);\n }\n } catch (error) {\n debugLogger.error(\"Bulk import failed\", { error });\n setImportProgress({ \n isImporting: false, \n progress: `Import failed: ${error instanceof Error ? error.message : String(error)}` \n });\n }\n };\n\n const getMemoriesForDisplay = () => {\n if (shouldUseVectorForMemories) {\n // Transform vector memories to match local memory structure, preserving the source field from API\n const transformedMemories = vectorMemories.map(vectorMemory => ({\n ...vectorMemory,\n // Preserve the source field from API response, but default to 'auto' for backwards compatibility\n // Most vector memories are automatically created by the system\n source: vectorMemory.source || \"auto\", // Default to 'auto' since most vector memories are system-generated\n pinned: vectorMemory.pinned || false, // Use API pinned or default to false\n timestamp: vectorMemory.uploadedAt ? new Date(vectorMemory.uploadedAt).getTime() : Date.now(),\n tags: vectorMemory.tags || []\n }));\n \n // Filter by selected tab (user or auto)\n const result = transformedMemories.filter(memory => memory.source === selectedTab);\n debugLogger.memoryDebug(\"Vector memories filtered for display\", {\n selectedTab,\n vectorMemoriesCount: vectorMemories.length,\n resultCount: result.length,\n });\n return result;\n } else {\n // Local store memories\n const result = entries.filter((entry) => entry.source === selectedTab);\n return result;\n }\n };\n\n const getUserMemoryCount = () => {\n if (shouldUseVectorForMemories) {\n return vectorMemories.filter(memory => (memory.source || \"auto\") === \"user\").length;\n } else {\n return entries.filter(e => e.source === \"user\").length;\n }\n };\n\n const getAutoMemoryCount = () => {\n if (shouldUseVectorForMemories) {\n return vectorMemories.filter(memory => (memory.source || \"auto\") === \"auto\").length;\n } else {\n return entries.filter(e => e.source === \"auto\").length;\n }\n };\n\n const handleClearAll = async () => {\n if (shouldUseVectorForMemories) {\n // For vector memories, we need to clear based on the selected option\n try {\n let memoriesToDelete = [];\n \n if (clearOption === \"user\") {\n memoriesToDelete = vectorMemories.filter(memory => (memory.source || \"auto\") === \"user\");\n } else if (clearOption === \"auto\") {\n memoriesToDelete = vectorMemories.filter(memory => (memory.source || \"auto\") === \"auto\");\n } else { // both\n memoriesToDelete = vectorMemories;\n }\n \n let successCount = 0;\n let errorCount = 0;\n \n for (const memory of memoriesToDelete) {\n try {\n const result = await deleteVectorMemory(memory.id);\n \n if (result && result.success) {\n successCount++;\n } else {\n errorCount++;\n debugLogger.error(\"Vector memory deletion failed\", {\n id: memory.id,\n error: result?.error || \"No result returned\",\n });\n }\n } catch (error) {\n errorCount++;\n debugLogger.error(\"Exception deleting vector memory\", { id: memory.id, error });\n }\n \n // Add a small delay to avoid overwhelming the API\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n \n // Refresh vector memories list\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } catch (error) {\n debugLogger.error(\"Exception during vector clear-all operation\", { error });\n }\n } else {\n // Local store clearing\n try {\n if (clearOption === \"both\") {\n await clearMemories();\n } else {\n // Clear specific type\n const entriesToKeep = entries.filter(entry => entry.source !== clearOption);\n useMemoryStore.setState({ entries: entriesToKeep });\n }\n } catch (error) {\n debugLogger.error(\"Failed to clear local memories\", { error });\n }\n }\n setClearAllOpen(false);\n };\n\n const filteredMemories = getMemoriesForDisplay();\n\n const sheet = (\n <Box\n sx={{\n width: \"100%\",\n maxWidth: isMobileView ? \"100%\" : 800,\n maxHeight: isMobileView ? \"min(720px, 82vh)\" : \"90vh\",\n height: isMobileView ? \"100%\" : \"auto\",\n bgcolor: isMobileView ? theme.palette.background.paper : shell,\n color: theme.palette.text.primary,\n display: \"flex\",\n flexDirection: \"column\",\n borderRadius: isMobileView ? \"22px 22px 0 0\" : 3,\n overflow: \"hidden\",\n boxShadow: isMobileView ? \"none\" : `0 20px 60px ${alpha(theme.palette.common.black, 0.3)}`,\n border: isMobileView ? \"none\" : `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n zIndex: 2000, // Ensure it's on top\n }}\n >\n {isMobileView && (\n <Box\n sx={{\n height: 6,\n width: 56,\n borderRadius: 999,\n bgcolor: alpha(theme.palette.text.primary, 0.18),\n alignSelf: \"center\",\n mt: 1.25,\n mb: 0.75,\n }}\n />\n )}\n\n {/* Header */}\n <Box\n sx={{\n flexShrink: 0,\n px: isMobileView ? 1.5 : 2,\n py: isMobileView ? 1.25 : 2,\n borderBottom: `1px solid ${appBar.border}`,\n display: \"flex\",\n flexDirection: \"column\",\n gap: isMobileView ? 0.9 : 1.25,\n }}\n >\n <Box\n sx={{\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: isMobileView ? 0.75 : 1.25,\n flexWrap: \"wrap\",\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.75 }}>\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n Memory\n </Typography>\n {shouldUseVectorForMemories && (\n <Tooltip title=\"Memories stay in your private knowledge space for faster, more accurate answers.\">\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.primary.main,\n bgcolor: alpha(theme.palette.primary.main, 0.1),\n px: 1,\n py: 0.25,\n borderRadius: 1,\n fontSize: \"0.7rem\",\n fontWeight: 600,\n textTransform: \"uppercase\",\n cursor: \"help\",\n }}\n >\n Synced\n </Typography>\n </Tooltip>\n )}\n </Box>\n\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n gap: isMobileView ? 0.5 : 1,\n flexWrap: \"wrap\",\n }}\n >\n {multiSelectMode ? (\n <>\n <Typography variant=\"caption\" sx={{ color: theme.palette.text.secondary, mr: 0.5 }}>\n {selectedIds.length} selected\n </Typography>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={() => {\n setMultiSelectMode(false);\n setSelectedIds([]);\n }}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Cancel\n </Button>\n {selectedIds.length > 0 && (\n <>\n <Button\n variant=\"outlined\"\n size=\"small\"\n color=\"secondary\"\n onClick={() => handleMultiPin(true)}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Pin ({selectedIds.length})\n </Button>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={() => handleMultiPin(false)}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Unpin ({selectedIds.length})\n </Button>\n <Button\n variant=\"contained\"\n size=\"small\"\n color=\"error\"\n onClick={() => setConfirmOpen(true)}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Delete ({selectedIds.length})\n </Button>\n </>\n )}\n </>\n ) : (\n filteredMemories.length > 0 && (\n <>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={() => setClearAllOpen(true)}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Clear All\n </Button>\n {isVectorEnabled && entries.length > 0 && (\n <Button\n variant=\"outlined\"\n size=\"small\"\n color=\"primary\"\n onClick={() => setBulkImportOpen(true)}\n startIcon={<CloudSyncIcon />}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Import to workspace\n </Button>\n )}\n <Button\n variant=\"outlined\"\n size=\"small\"\n color=\"error\"\n onClick={() => {\n setMultiSelectMode(true);\n setSelectedIds([]);\n }}\n sx={{ textTransform: \"none\", borderRadius: 2, fontSize: \"0.75rem\" }}\n >\n Select\n </Button>\n </>\n )\n )}\n\n {!multiSelectMode && isMobileView && (\n <Button\n variant=\"contained\"\n size=\"small\"\n onClick={handleAdd}\n disabled={!newMemory.trim()}\n sx={{\n textTransform: \"none\",\n borderRadius: 2,\n fontWeight: 600,\n minWidth: 88,\n }}\n >\n Save\n </Button>\n )}\n\n <IconButton\n onClick={onClose}\n sx={{\n color: appBar.icon,\n '&:hover': { bgcolor: alpha(theme.palette.text.primary, 0.08) },\n borderRadius: 2,\n }}\n size=\"small\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n\n <Box\n sx={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 0.5,\n color: theme.palette.text.secondary,\n }}\n >\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n borderRadius: 1,\n px: 0.75,\n py: 0.25,\n bgcolor: alpha(theme.palette.text.secondary, 0.1),\n textTransform: \"uppercase\",\n letterSpacing: 0.6,\n }}\n >\n {shouldUseVectorForMemories ? \"Cloud memory\" : \"Local memory\"}\n </Typography>\n {filteredMemories.length > 0 && (\n <Typography\n variant=\"caption\"\n sx={{\n color: theme.palette.text.secondary,\n borderRadius: 1,\n px: 0.75,\n py: 0.25,\n bgcolor: alpha(theme.palette.text.secondary, 0.1),\n textTransform: \"uppercase\",\n letterSpacing: 0.6,\n }}\n >\n {filteredMemories.length} {selectedTab}\n </Typography>\n )}\n </Box>\n </Box>\n {/* Vector Mode Indicator */}\n {shouldUseVectorForMemories && (\n <Box sx={{\n flexShrink: 0,\n mx: isMobileView ? 1.5 : 2,\n mt: 1,\n p: 1.5,\n background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.08)}, ${alpha(theme.palette.secondary.main, 0.05)})`,\n border: `1px solid ${alpha(theme.palette.primary.main, 0.2)}`,\n borderRadius: 2,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n position: \"relative\",\n overflow: \"hidden\"\n }}>\n {/* Animated background shimmer */}\n <Box sx={{\n position: \"absolute\",\n top: 0,\n left: \"-100%\",\n width: \"100%\",\n height: \"100%\",\n background: `linear-gradient(90deg, transparent, ${alpha(theme.palette.primary.main, 0.1)}, transparent)`,\n animation: `${shimmer} 3s infinite`\n }} />\n <Box sx={{\n width: 8,\n height: 8,\n borderRadius: \"50%\",\n bgcolor: theme.palette.primary.main,\n animation: `${pulse} 2s infinite`,\n zIndex: 1\n }} />\n <Typography variant=\"body2\" sx={{ \n color: theme.palette.primary.main,\n fontSize: \"0.8rem\",\n fontWeight: 500,\n zIndex: 1\n }}>\n Cloud memory · synced to your account\n </Typography>\n </Box>\n )}\n\n {/* Info + Tabs */}\n <Box sx={{ flexShrink: 0 }}>\n <Box sx={{ px: isMobileView ? 1.5 : 2, py: isMobileView ? 1.25 : 1.5 }}>\n <Typography\n variant=\"body2\"\n sx={{ color: theme.palette.text.secondary, fontSize: \"0.85rem\", textAlign: isMobileView ? \"left\" : \"center\" }}\n >\n {shouldUseVectorForMemories ? (\n \"Synced to your account for quick recall.\"\n ) : (\n \"Private and local. You decide what's remembered.\"\n )}\n </Typography>\n </Box>\n <Tabs\n value={selectedTab}\n onChange={(_, val) => setSelectedTab(val)}\n textColor=\"inherit\"\n indicatorColor=\"secondary\"\n centered={!isMobileView}\n variant={isMobileView ? \"fullWidth\" : \"standard\"}\n sx={{ \n bgcolor: alpha(input, isMobileView ? 0.65 : 0.5),\n borderTop: isMobileView ? `1px solid ${alpha(theme.palette.divider, 0.15)}` : undefined,\n borderBottom: `1px solid ${alpha(theme.palette.divider, 0.15)}`,\n \"& .MuiTab-root\": {\n textTransform: \"none\",\n fontWeight: 500,\n minHeight: isMobileView ? 44 : 48,\n paddingInline: isMobileView ? 1 : 1.5,\n }\n }}\n >\n <Tab \n label={\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n User\n {getUserMemoryCount() > 0 && (\n <Typography variant=\"caption\" sx={{\n bgcolor: alpha(theme.palette.primary.main, 0.2),\n color: theme.palette.primary.main,\n px: 0.75,\n py: 0.25,\n borderRadius: 1,\n fontSize: \"0.65rem\",\n fontWeight: 600,\n }}>\n {getUserMemoryCount()}\n </Typography>\n )}\n </Box>\n } \n value=\"user\" \n />\n <Tab \n label={\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n Auto\n {getAutoMemoryCount() > 0 && (\n <Typography variant=\"caption\" sx={{\n bgcolor: alpha(theme.palette.secondary.main, 0.2),\n color: theme.palette.secondary.main,\n px: 0.75,\n py: 0.25,\n borderRadius: 1,\n fontSize: \"0.65rem\",\n fontWeight: 600,\n }}>\n {getAutoMemoryCount()}\n </Typography>\n )}\n </Box>\n } \n value=\"auto\" \n />\n </Tabs>\n </Box>\n\n {/* Scrollable Memory List */}\n <Box\n sx={{\n flexGrow: 1,\n overflowY: \"auto\",\n px: isMobileView ? 1.5 : 2,\n py: isMobileView ? 1 : 1,\n }}\n >\n {filteredMemories.length === 0 ? (\n <Box sx={{ \n display: \"flex\", \n flexDirection: \"column\", \n alignItems: \"center\", \n justifyContent: \"center\",\n height: \"200px\",\n textAlign: \"center\"\n }}>\n <Typography variant=\"h6\" sx={{ \n color: theme.palette.text.secondary, \n mb: 1,\n fontSize: \"1.1rem\"\n }}>\n No {selectedTab} memories yet\n </Typography>\n <Typography variant=\"body2\" sx={{ \n color: alpha(theme.palette.text.secondary, 0.7),\n maxWidth: 280\n }}>\n {selectedTab === \"user\" \n ? shouldUseVectorForMemories \n ? \"Start by adding something you'd like me to remember. Your memories will be kept in a private workspace for quick recall.\"\n : \"Start by adding something you'd like me to remember about you or your preferences.\"\n : shouldUseVectorForMemories\n ? \"Auto memories are created automatically based on our conversations and kept in your private workspace for better answers.\"\n : \"Auto memories are created automatically based on our conversations.\"\n }\n </Typography>\n </Box>\n ) : (\n filteredMemories.map((memory, memoryIndex) => {\n const isSelected = selectedIds.includes(memory.id);\n return (\n <React.Fragment key={memory.id}>\n <List sx={{ listStyle: \"none\", pl: 0, m: 0 }}>\n <ListItem\n onClick={() => multiSelectMode && toggleSelection(memory.id)}\n sx={{\n px: 0,\n py: 1.5,\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: 1.5,\n alignItems: \"flex-start\",\n bgcolor: isSelected ? alpha(theme.palette.error.main, 0.1) : undefined,\n borderRadius: isSelected ? 2 : 0,\n cursor: multiSelectMode ? \"pointer\" : undefined,\n border: isSelected ? `2px solid ${alpha(theme.palette.error.main, 0.3)}` : \"2px solid transparent\",\n transition: \"all 0.2s ease\",\n \"&:hover\": {\n bgcolor: multiSelectMode ? alpha(theme.palette.error.main, 0.05) : alpha(theme.palette.text.primary, 0.02),\n }\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"flex-start\",\n flexGrow: 1,\n gap: 1.5,\n }}\n >\n <Avatar\n src=\"https://cdn.burtson.ai/images/brain-icon.png\"\n alt=\"Memory\"\n sx={{\n width: 36,\n height: 36,\n mt: 0.2,\n bgcolor: theme.palette.mode === \"light\" ? \"#f5f5f5\" : theme.palette.background.paper,\n border: isVectorEnabled \n ? `2px solid ${alpha(theme.palette.primary.main, 0.4)}` \n : `1px solid ${theme.palette.divider}`,\n position: \"relative\"\n }}\n >\n {isVectorEnabled && (\n <Box sx={{\n position: \"absolute\",\n top: -2,\n right: -2,\n width: 12,\n height: 12,\n borderRadius: \"50%\",\n bgcolor: theme.palette.primary.main,\n border: `2px solid ${theme.palette.background.paper}`,\n fontSize: \"6px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"white\"\n }}>\n ⚡\n </Box>\n )}\n </Avatar>\n {editingId === memory.id ? (\n <TextField\n fullWidth\n multiline\n autoFocus\n value={editedContent}\n onChange={(e) => setEditedContent(e.target.value)}\n onBlur={() => {\n if (\n editedContent.trim() &&\n editedContent !== memory.content\n ) {\n useMemoryStore.setState((state) => ({\n entries: state.entries.map((entry) =>\n entry.id === memory.id\n ? { ...entry, content: editedContent }\n : entry\n ),\n }));\n }\n setEditingId(null);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setEditingId(null);\n setEditedContent('');\n } else if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.currentTarget.blur();\n }\n }}\n sx={{\n \"& .MuiInputBase-root\": { \n color: theme.palette.text.primary,\n bgcolor: input,\n borderRadius: 3,\n },\n \"& .MuiOutlinedInput-root\": {\n borderRadius: 3,\n \"& fieldset\": {\n borderRadius: 3,\n },\n \"&:hover fieldset\": {\n borderRadius: 3,\n },\n \"&.Mui-focused fieldset\": {\n borderRadius: 3,\n },\n },\n }}\n helperText=\"Press Cmd/Ctrl+Enter to save, Escape to cancel\"\n />\n ) : (\n <Box sx={{ flex: 1 }}>\n <Typography\n sx={{\n cursor: (!multiSelectMode && !shouldUseVectorForMemories) ? \"pointer\" : \"default\",\n wordBreak: \"break-word\",\n color: memory.pinned ? \"secondary.main\" : theme.palette.text.primary,\n fontWeight: memory.pinned ? 500 : 400,\n lineHeight: 1.4,\n \"&:hover\": (!multiSelectMode && !shouldUseVectorForMemories) ? {\n color: memory.pinned ? \"secondary.dark\" : \"primary.main\"\n } : undefined\n }}\n onClick={() => {\n if (!multiSelectMode && !shouldUseVectorForMemories) {\n setEditingId(memory.id);\n setEditedContent(memory.content);\n }\n }}\n >\n {memory.content}\n </Typography>\n {memory.pinned && (\n <Typography variant=\"caption\" sx={{\n color: alpha(theme.palette.secondary.main, 0.7),\n fontStyle: \"italic\",\n mt: 0.5,\n display: \"block\"\n }}>\n Pinned\n </Typography>\n )}\n </Box>\n )}\n </Box>\n {!multiSelectMode && (\n <Box sx={{ display: \"flex\", gap: 0.5, mt: 0.5 }}>\n <Tooltip title={memory.pinned ? \"Unpin memory\" : \"Pin memory\"}>\n <IconButton\n onClick={async () => {\n if (shouldUseVectorForMemories) {\n try {\n // Toggle pin status using vector update API\n const result = await updateVectorMemory(memory.id, { pinned: !memory.pinned });\n if (result.success) {\n // Refresh vector memories list to show updated pin status\n const memories = await getVectorMemories();\n setVectorMemories((memories ?? []) as VectorMemory[]);\n } else {\n debugLogger.error(\"Failed to update vector memory pin status\", {\n id: memory.id,\n error: result.error,\n });\n }\n } catch (error) {\n debugLogger.error(\"Error updating vector memory pin status\", {\n id: memory.id,\n error,\n });\n }\n } else {\n togglePinMemory(memory.id);\n }\n }}\n sx={{ \n color: memory.pinned ? \"secondary.main\" : alpha(theme.palette.text.secondary, 0.7),\n \"&:hover\": { \n bgcolor: alpha(memory.pinned ? theme.palette.secondary.main : theme.palette.text.secondary, 0.1)\n }\n }}\n size=\"small\"\n >\n {memory.pinned ? (\n <PushPinIcon fontSize=\"small\" />\n ) : (\n <PushPinOutlinedIcon fontSize=\"small\" />\n )}\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Delete memory\">\n <IconButton\n onClick={async () => await handleDeleteMemory(memory.id)}\n sx={{ \n color: alpha(theme.palette.text.secondary, 0.7),\n \"&:hover\": { \n bgcolor: alpha(theme.palette.error.main, 0.1),\n color: theme.palette.error.main\n }\n }}\n size=\"small\"\n >\n <DeleteIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n )}\n </ListItem>\n </List>\n {memoryIndex < filteredMemories.length - 1 && (\n <Divider sx={{ bgcolor: alpha(appBar.border, 0.5), my: 0.5 }} />\n )}\n </React.Fragment>\n );\n })\n )}\n </Box>\n\n {/* Multi Delete Confirm Bar */}\n {multiSelectMode && (\n <Box\n sx={{\n p: isMobileView ? 1.5 : 2,\n borderTop: `1px solid ${appBar.border}`,\n bgcolor: alpha(theme.palette.error.main, 0.05),\n borderBottom: selectedIds.length > 0 ? `2px solid ${alpha(theme.palette.error.main, 0.2)}` : undefined,\n }}\n >\n {selectedIds.length === 0 ? (\n <Typography variant=\"body2\" sx={{ \n textAlign: \"center\", \n color: theme.palette.text.secondary,\n fontStyle: \"italic\"\n }}>\n Tap memories to select them for deletion\n </Typography>\n ) : (\n <Box sx={{ display: \"flex\", gap: 1, alignItems: \"center\" }}>\n <Button\n variant=\"outlined\"\n onClick={() => {\n setSelectedIds(filteredMemories.map(m => m.id));\n }}\n sx={{ \n textTransform: \"none\",\n borderRadius: 2,\n fontSize: \"0.8rem\",\n minWidth: \"auto\",\n }}\n >\n Select All\n </Button>\n <Button\n fullWidth\n variant=\"contained\"\n color=\"error\"\n onClick={() => setConfirmOpen(true)}\n sx={{ borderRadius: 2 }}\n >\n Delete Selected ({selectedIds.length})\n </Button>\n </Box>\n )}\n </Box>\n )}\n\n {/* Footer */}\n <Box\n sx={{\n flexShrink: 0,\n p: isMobileView ? 1.5 : 2,\n borderTop: `1px solid ${appBar.border}`,\n bgcolor: isMobileView ? theme.palette.background.paper : shell,\n pb: `calc(env(safe-area-inset-bottom, 0px) + 8px)`,\n }}\n >\n <TextField\n fullWidth\n size=\"small\"\n value={newMemory}\n onChange={(e) => setNewMemory(e.target.value)}\n placeholder={shouldUseVectorForMemories \n ? `Add a new ${selectedTab} memory to your workspace...` \n : `Add a new ${selectedTab} memory...`\n }\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey && newMemory.trim()) {\n e.preventDefault();\n handleAdd();\n }\n }}\n sx={{\n \"& .MuiInputBase-root\": { \n color: theme.palette.text.primary,\n bgcolor: alpha(input, 0.3), // Use semi-transparent background\n borderRadius: 3, // More rounded for modern look\n },\n \"& .MuiOutlinedInput-root\": {\n borderRadius: 3, // Ensure outline variant is also rounded\n bgcolor: \"transparent\", // Remove background from outline variant\n \"& fieldset\": {\n borderRadius: 3, // Ensure fieldset border is rounded\n borderColor: alpha(theme.palette.divider, 0.3),\n },\n \"&:hover fieldset\": {\n borderRadius: 3, // Maintain rounded corners on hover\n borderColor: alpha(theme.palette.primary.main, 0.5),\n },\n \"&.Mui-focused fieldset\": {\n borderRadius: 3, // Maintain rounded corners when focused\n borderColor: theme.palette.primary.main,\n },\n },\n mb: 1.5,\n }}\n InputProps={{\n endAdornment: newMemory.trim() && (\n <Typography variant=\"caption\" sx={{ \n color: alpha(theme.palette.text.secondary, 0.7),\n fontSize: \"0.7rem\",\n whiteSpace: \"nowrap\"\n }}>\n Press Enter\n </Typography>\n )\n }}\n />\n {!isMobileView && (\n <Button\n fullWidth\n variant=\"contained\"\n onClick={handleAdd}\n disabled={!newMemory.trim()}\n sx={{ \n borderRadius: 2, \n py: 1.25,\n textTransform: \"none\",\n fontWeight: 600,\n }}\n >\n Save\n </Button>\n )}\n </Box>\n\n {/* Confirm Delete Modal */}\n <Dialog \n open={confirmOpen} \n onClose={() => setConfirmOpen(false)}\n sx={{\n zIndex: 2100, // Higher than main modal (2000)\n }}\n PaperProps={{\n sx: { borderRadius: 3, minWidth: 320 }\n }}\n >\n <DialogTitle sx={{ pb: 1 }}>\n Delete {selectedIds.length} {selectedIds.length === 1 ? 'Memory' : 'Memories'}?\n </DialogTitle>\n <DialogContent>\n <Typography variant=\"body2\" sx={{ color: theme.palette.text.secondary }}>\n This will permanently remove the selected memory entries. This action cannot be undone.\n </Typography>\n </DialogContent>\n <DialogActions sx={{ p: 3, pt: 1 }}>\n <Button \n onClick={() => setConfirmOpen(false)}\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n Cancel\n </Button>\n <Button \n onClick={handleMultiDelete} \n color=\"error\"\n variant=\"contained\"\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n Delete ({selectedIds.length})\n </Button>\n </DialogActions>\n </Dialog>\n {/* Clear All Dialog */}\n <Dialog \n open={clearAllOpen} \n onClose={() => setClearAllOpen(false)}\n sx={{\n zIndex: 2100, // Higher than main modal (2000)\n }}\n PaperProps={{\n sx: { borderRadius: 3, minWidth: 320 }\n }}\n >\n <DialogTitle sx={{ pb: 1, fontWeight: 600 }}>\n Clear Memories\n </DialogTitle>\n <DialogContent sx={{ pb: 2 }}>\n <Typography variant=\"body2\" sx={{ mb: 3, color: theme.palette.text.secondary }}>\n This will permanently remove selected memory types. Choose which ones to clear:\n </Typography>\n <FormControl component=\"fieldset\">\n <RadioGroup\n value={clearOption}\n onChange={(e) => setClearOption(e.target.value as \"user\" | \"auto\" | \"both\")}\n >\n <FormControlLabel \n value=\"user\" \n control={<Radio />} \n label={\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <Typography>User Memories</Typography>\n <Typography variant=\"caption\" sx={{\n bgcolor: alpha(theme.palette.primary.main, 0.1),\n color: theme.palette.primary.main,\n px: 1,\n py: 0.25,\n borderRadius: 1,\n fontWeight: 600,\n }}>\n {getUserMemoryCount()}\n </Typography>\n </Box>\n }\n />\n <FormControlLabel \n value=\"auto\" \n control={<Radio />} \n label={\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <Typography>Auto Memories</Typography>\n <Typography variant=\"caption\" sx={{\n bgcolor: alpha(theme.palette.secondary.main, 0.1),\n color: theme.palette.secondary.main,\n px: 1,\n py: 0.25,\n borderRadius: 1,\n fontWeight: 600,\n }}>\n {getAutoMemoryCount()}\n </Typography>\n </Box>\n }\n />\n <FormControlLabel \n value=\"both\" \n control={<Radio />} \n label={\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <Typography>Both Types</Typography>\n <Typography variant=\"caption\" sx={{\n bgcolor: alpha(theme.palette.error.main, 0.1),\n color: theme.palette.error.main,\n px: 1,\n py: 0.25,\n borderRadius: 1,\n fontWeight: 600,\n }}>\n {entries.length}\n </Typography>\n </Box>\n }\n />\n </RadioGroup>\n </FormControl>\n </DialogContent>\n <DialogActions sx={{ p: 3, pt: 1 }}>\n <Button \n onClick={() => setClearAllOpen(false)}\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n Cancel\n </Button>\n <Button\n color=\"error\"\n variant=\"contained\"\n onClick={handleClearAll}\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n Clear {clearOption === \"both\" ? \"All\" : clearOption} Memories\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* Bulk Import Dialog */}\n <Dialog \n open={bulkImportOpen} \n onClose={() => setBulkImportOpen(false)}\n maxWidth=\"sm\"\n fullWidth\n PaperProps={{\n sx: { borderRadius: 3 }\n }}\n >\n <DialogTitle sx={{ \n fontWeight: 600, \n pb: 1,\n display: 'flex',\n alignItems: 'center',\n gap: 1\n }}>\n <CloudSyncIcon color=\"primary\" />\n Import Memories to Secure Workspace\n </DialogTitle>\n <DialogContent sx={{ py: 2 }}>\n {!importProgress.isImporting ? (\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 2 }}>\n This will import all your local memories ({entries.length} memories) to your secure workspace for faster, more reliable answers.\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 2 }}>\n • Memories will be added to your synced workspace\n • Local memories will remain unchanged\n • You can switch between synced and local storage anytime\n </Typography>\n <Typography variant=\"body2\" color=\"primary\" sx={{ fontWeight: 500 }}>\n Ready to import {entries.length} memories?\n </Typography>\n </Box>\n ) : (\n <Box sx={{ textAlign: 'center', py: 2 }}>\n <CloudSyncIcon \n sx={{ \n fontSize: 48, \n color: 'primary.main',\n mb: 2,\n animation: `${pulse} 2s ease-in-out infinite`\n }} \n />\n <Typography variant=\"body1\" sx={{ mb: 1 }}>\n {importProgress.progress}\n </Typography>\n {importProgress.result && (\n <>\n <Typography \n variant=\"body2\" \n color={importProgress.result.success ? 'success.main' : 'error.main'}\n sx={{ mt: 1, mb: 2 }}\n >\n {importProgress.result.message}\n </Typography>\n {importProgress.result.details && (\n <Box sx={{ \n textAlign: 'left', \n backgroundColor: 'background.paper',\n border: 1,\n borderColor: 'divider',\n borderRadius: 1,\n p: 2,\n mt: 2\n }}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 1 }}>\n Import Details:\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 0.5 }}>\n • Total: {importProgress.result.details.totalMemories} memories\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 0.5 }}>\n • Success: {importProgress.result.details.successCount}\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 0.5 }}>\n • Failed: {importProgress.result.details.failureCount}\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 0.5 }}>\n • Duration: {importProgress.result.details.duration}\n </Typography>\n {importProgress.result.details.warnings && importProgress.result.details.warnings.length > 0 && (\n <Typography variant=\"body2\" color=\"warning.main\" sx={{ mt: 1, display: \"flex\", alignItems: \"center\", gap: 0.5 }}>\n <WarningIcon fontSize=\"inherit\" aria-hidden /> {importProgress.result.details.warnings.join(', ')}\n </Typography>\n )}\n </Box>\n )}\n </>\n )}\n </Box>\n )}\n </DialogContent>\n <DialogActions sx={{ p: 3, pt: 1 }}>\n <Button \n onClick={() => {\n setBulkImportOpen(false);\n setImportProgress({ isImporting: false, progress: '' });\n }}\n disabled={importProgress.isImporting}\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n {importProgress.isImporting ? 'Importing...' : 'Cancel'}\n </Button>\n {!importProgress.isImporting && !importProgress.result && (\n <Button\n color=\"primary\"\n variant=\"contained\"\n onClick={handleBulkImport}\n startIcon={<CloudSyncIcon />}\n sx={{ textTransform: \"none\", borderRadius: 3 }}\n >\n Import {entries.length} Memories\n </Button>\n )}\n </DialogActions>\n </Dialog>\n </Box>\n );\n\n if (isMobileView) {\n return (\n <SwipeableDrawer\n anchor=\"bottom\"\n open={open}\n onClose={onClose}\n onOpen={() => {}}\n disableSwipeToOpen\n ModalProps={{ keepMounted: true }}\n // Must sit above the mobile conversations modal (a MUI Modal at z-index\n // 1300) — the Drawer default of 1200 opened this sheet *behind* it,\n // which read as \"memory doesn't open\" in the PWA.\n sx={{ zIndex: 2000 }}\n PaperProps={{\n sx: {\n height: 'min(720px, 82vh)',\n borderRadius: '22px 22px 0 0',\n overflow: 'hidden',\n bgcolor: theme.palette.background.paper,\n display: 'flex',\n justifyContent: 'center',\n },\n }}\n >\n {sheet}\n </SwipeableDrawer>\n );\n }\n\n return (\n <Modal \n open={open} \n onClose={onClose}\n sx={{\n zIndex: 2000, // Higher than drawer (1400) and other modals (1500)\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n p: 2,\n }}\n >\n {sheet}\n </Modal>\n );\n};\n\nexport default MemoryModal;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React from \"react\";\nimport { Box, CircularProgress, useTheme } from \"@mui/material\";\n\ninterface GenericLoaderProps {\n size?: number;\n color?: string;\n variant?: \"dots\" | \"spinner\" | \"pulse\";\n}\n\nconst GenericLoader: React.FC<GenericLoaderProps> = ({ \n size = 40, \n color,\n variant = \"spinner\" \n}) => {\n const theme = useTheme();\n const loaderColor = color || theme.palette.primary.main;\n\n if (variant === \"dots\") {\n return (\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: 1,\n py: 2,\n \"@keyframes bounce\": {\n \"0%, 80%, 100%\": {\n transform: \"scale(0)\",\n },\n \"40%\": {\n transform: \"scale(1.0)\",\n },\n },\n }}\n >\n {[0, 0.15, 0.3].map((delay, index) => (\n <Box\n key={index}\n sx={{\n width: 8,\n height: 8,\n backgroundColor: loaderColor,\n borderRadius: \"50%\",\n animation: \"bounce 1.4s infinite ease-in-out both\",\n animationDelay: `${delay}s`,\n }}\n />\n ))}\n </Box>\n );\n }\n\n if (variant === \"pulse\") {\n return (\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n py: 2,\n \"@keyframes pulse\": {\n \"0%\": {\n transform: \"scale(0.9)\",\n opacity: 1,\n },\n \"50%\": {\n transform: \"scale(1.1)\",\n opacity: 0.7,\n },\n \"100%\": {\n transform: \"scale(0.9)\",\n opacity: 1,\n },\n },\n }}\n >\n <Box\n sx={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n backgroundColor: loaderColor,\n animation: \"pulse 1.5s infinite ease-in-out\",\n }}\n />\n </Box>\n );\n }\n\n // Default spinner variant\n return (\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n py: 2,\n }}\n >\n <CircularProgress \n size={size} \n sx={{ color: loaderColor }}\n />\n </Box>\n );\n};\n\nexport default GenericLoader;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState } from 'react';\nimport {\n Fab,\n Tooltip,\n useTheme,\n Zoom,\n Button,\n IconButton,\n} from '@mui/material';\nimport { MessageCircle as FeedbackIcon } from '@burtson-labs/icons/react';\nimport { FeedbackModal } from './index';\n\nexport interface FeedbackButtonProps {\n /** Whether the parent component is in fullscreen mode */\n fullScreen?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Z-index override */\n zIndex?: number;\n /** Custom feedback email (overrides package settings) */\n feedbackEmail?: string;\n /** Show as inline button instead of floating */\n inline?: boolean;\n /** Custom button text for inline mode */\n buttonText?: string;\n /** Custom size */\n size?: 'small' | 'medium' | 'large';\n /** Custom positioning */\n position?: {\n bottom?: number | string;\n right?: number | string;\n top?: number | string;\n left?: number | string;\n };\n /** Use absolute positioning instead of fixed (for modal contexts) */\n absolute?: boolean;\n}\n\nexport const FeedbackButton: React.FC<FeedbackButtonProps> = ({\n fullScreen = false,\n className,\n zIndex = 1400,\n feedbackEmail,\n inline = false,\n buttonText = \"Send Feedback\",\n size = 'small',\n position,\n absolute = false,\n}) => {\n const theme = useTheme();\n const [open, setOpen] = useState(false);\n\n const handleOpen = () => setOpen(true);\n const handleClose = () => setOpen(false);\n\n // If inline mode, render as a regular button\n if (inline) {\n return (\n <>\n {buttonText ? (\n <Button\n variant=\"outlined\"\n startIcon={<FeedbackIcon />}\n onClick={handleOpen}\n className={className}\n size={size}\n sx={{\n borderRadius: 2,\n textTransform: 'none',\n '&:hover': {\n transform: 'translateY(-1px)',\n boxShadow: theme.shadows[4],\n },\n }}\n >\n {buttonText}\n </Button>\n ) : (\n <Tooltip title=\"Send Feedback\" arrow>\n <IconButton\n onClick={handleOpen}\n className={className}\n size={size}\n sx={{\n color: theme.palette.primary.main,\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n bgcolor: theme.palette.primary.main + '15',\n transform: 'translateY(-1px)',\n },\n }}\n >\n <FeedbackIcon />\n </IconButton>\n </Tooltip>\n )}\n\n <FeedbackModal \n open={open} \n onClose={handleClose}\n feedbackEmail={feedbackEmail}\n />\n </>\n );\n }\n\n // Floating FAB mode\n return (\n <>\n <Zoom in={true} timeout={300}>\n <Tooltip \n title=\"Send Feedback\" \n placement=\"left\"\n arrow\n >\n <Fab\n size={size}\n onClick={handleOpen}\n className={className}\n sx={{\n position: absolute ? 'absolute' : 'relative',\n ...(absolute && {\n bottom: position?.bottom ?? (fullScreen ? 16 : 20),\n right: position?.right ?? 16,\n top: position?.top,\n left: position?.left,\n }),\n zIndex,\n bgcolor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n boxShadow: theme.palette.mode === 'dark' \n ? '0 8px 32px rgba(0,0,0,0.4)' \n : '0 8px 32px rgba(0,0,0,0.15)',\n border: `1px solid ${theme.palette.divider}`,\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\n '&:hover': {\n bgcolor: theme.palette.primary.dark,\n transform: 'scale(1.05) translateY(-2px)',\n boxShadow: theme.palette.mode === 'dark' \n ? '0 12px 40px rgba(0,0,0,0.5)' \n : '0 12px 40px rgba(0,0,0,0.2)',\n },\n '&:active': {\n transform: 'scale(0.98) translateY(0px)',\n },\n // Subtle pulsing animation\n animation: 'feedbackPulse 3s ease-in-out infinite',\n '@keyframes feedbackPulse': {\n '0%, 100%': {\n boxShadow: theme.palette.mode === 'dark' \n ? '0 8px 32px rgba(0,0,0,0.4)' \n : '0 8px 32px rgba(0,0,0,0.15)',\n },\n '50%': {\n boxShadow: theme.palette.mode === 'dark' \n ? `0 8px 32px ${theme.palette.primary.main}40` \n : `0 8px 32px ${theme.palette.primary.main}30`,\n },\n },\n }}\n >\n <FeedbackIcon />\n </Fab>\n </Tooltip>\n </Zoom>\n\n <FeedbackModal \n open={open} \n onClose={handleClose}\n feedbackEmail={feedbackEmail}\n />\n </>\n );\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { useState, useCallback, useRef } from 'react';\nimport { GlobalStyles } from '@mui/material';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n Box,\n Typography,\n IconButton,\n Chip,\n Alert,\n Paper,\n Avatar,\n CircularProgress,\n Fade,\n Slider,\n Stack,\n useMediaQuery,\n Snackbar,\n} from '@mui/material';\nimport { X as CloseIcon, Bug as BugReportIcon, Lightbulb as LightbulbIcon, TrendingUp as TrendingUpIcon, HelpCircle as HelpIcon, MessageSquare as MessageIcon, Camera as PhotoCameraIcon, Paperclip as AttachFileIcon, Trash as DeleteIcon, Mail as MailIcon } from '@burtson-labs/icons/react';\nimport { \n FeedbackRequest, \n FeedbackResponse,\n FeedbackCategories, \n FeedbackPriorities \n} from '../../services/gateway/feedback.interfaces';\nimport { useModelStore } from '../../store/modelStore';\nimport { useConversationStore } from '../../store/conversationStore';\nimport { usePackageSettingsStore } from '../../store/packageSettingsStore';\nimport { GatewayService } from '../../services/gateway/gateway.service';\nimport { authenticationService } from '../../services/auth/authenticationService';\nimport { useTheme, alpha } from '@mui/material/styles';\n\nexport interface FeedbackModalProps {\n open: boolean;\n onClose: () => void;\n feedbackEmail?: string;\n}\n\nconst feedbackCategories: FeedbackCategories = {\n bug: {\n label: 'Bug Report',\n description: \"Something isn't working as expected\",\n icon: 'BugReport',\n color: '#f44336',\n },\n feature: {\n label: 'Feature Request',\n description: 'Suggest a new feature or enhancement',\n icon: 'Lightbulb',\n color: '#2196f3',\n },\n improvement: {\n label: 'Improvement',\n description: 'Suggest improvements to existing features',\n icon: 'TrendingUp',\n color: '#ff9800',\n },\n question: {\n label: 'Question',\n description: 'Ask a question about usage or functionality',\n icon: 'Help',\n color: '#9c27b0',\n },\n other: {\n label: 'Other',\n description: 'General feedback or other topics',\n icon: 'Message',\n color: '#607d8b',\n },\n};\n\nconst feedbackPriorities: FeedbackPriorities = {\n low: {\n label: 'Low',\n description: 'Minor issue, can wait',\n color: '#4caf50',\n },\n medium: {\n label: 'Medium',\n description: 'Normal priority',\n color: '#ff9800',\n },\n high: {\n label: 'High',\n description: 'Important, needs attention soon',\n color: '#f44336',\n },\n critical: {\n label: 'Critical',\n description: 'Urgent, blocks usage',\n color: '#d32f2f',\n },\n};\n\nconst iconMap = {\n BugReport: BugReportIcon,\n Lightbulb: LightbulbIcon,\n TrendingUp: TrendingUpIcon,\n Help: HelpIcon,\n Message: MessageIcon,\n};\n\nexport const FeedbackModal: React.FC<FeedbackModalProps> = ({\n open,\n onClose,\n feedbackEmail,\n}) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n const fileInputRef = useRef<HTMLInputElement>(null);\n \n // Store state\n const { selectedModel } = useModelStore();\n const { conversations } = useConversationStore();\n const { settings } = usePackageSettingsStore();\n \n // Form state\n const [formData, setFormData] = useState<Partial<FeedbackRequest>>({\n title: '',\n description: '',\n category: 'bug',\n priority: 'medium',\n contactEmail: '',\n images: [],\n attachments: [],\n annoyanceLevel: 3, // 1-5 scale, 3 = neutral\n });\n \n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle');\n const [errorMessage, setErrorMessage] = useState('');\n const [snackbarOpen, setSnackbarOpen] = useState(false);\n const [snackbarMessage, setSnackbarMessage] = useState('');\n const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);\n const touchStartYRef = useRef<number | null>(null);\n const touchLatestYRef = useRef<number | null>(null);\n\n // Get browser info\n const getBrowserInfo = useCallback(() => {\n const ua = navigator.userAgent;\n let browserName = 'Unknown';\n let browserVersion = 'Unknown';\n \n if (ua.includes('Chrome')) {\n browserName = 'Chrome';\n browserVersion = ua.match(/Chrome\\/([0-9.]+)/)?.[1] || 'Unknown';\n } else if (ua.includes('Firefox')) {\n browserName = 'Firefox';\n browserVersion = ua.match(/Firefox\\/([0-9.]+)/)?.[1] || 'Unknown';\n } else if (ua.includes('Safari')) {\n browserName = 'Safari';\n browserVersion = ua.match(/Version\\/([0-9.]+)/)?.[1] || 'Unknown';\n }\n \n return {\n name: browserName,\n version: browserVersion,\n platform: navigator.platform,\n };\n }, []);\n\n // Handle form changes\n const handleInputChange = (field: keyof FeedbackRequest) => (\n event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | { target: { value: unknown } }\n ) => {\n setFormData(prev => ({\n ...prev,\n [field]: event.target.value,\n }));\n };\n\n // Handle file uploads\n const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {\n const files = event.target.files;\n if (!files || files.length === 0) return;\n\n const file = files[0]; // Only take the first file\n if (file.type.startsWith('image/')) {\n // Handle single image only - replace existing if present\n const reader = new FileReader();\n reader.onload = (e) => {\n const base64 = e.target?.result as string;\n setFormData(prev => ({\n ...prev,\n images: [base64], // Only keep one image\n }));\n };\n reader.readAsDataURL(file);\n } else {\n // Show error for non-image files\n setSnackbarMessage('❌ Please select an image file only (JPG, PNG, GIF)');\n setSnackbarOpen(true);\n }\n \n // Reset file input\n if (event.target) {\n event.target.value = '';\n }\n };\n\n // Remove image (single image)\n const removeImage = () => {\n setFormData(prev => ({\n ...prev,\n images: [],\n }));\n };\n\n // Copy image to clipboard\n const copyImageToClipboard = async () => {\n if (!formData.images?.[0]) return;\n \n try {\n // Convert base64 to blob\n const base64Data = formData.images[0].split(',')[1];\n const byteCharacters = atob(base64Data);\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n const byteArray = new Uint8Array(byteNumbers);\n const blob = new Blob([byteArray], { type: 'image/png' });\n \n // Copy to clipboard\n await navigator.clipboard.write([\n new ClipboardItem({\n 'image/png': blob,\n }),\n ]);\n \n setSnackbarMessage('📎 Image copied to clipboard! Paste it in your email.');\n setSnackbarOpen(true);\n } catch (error) {\n console.error('Failed to copy image to clipboard:', error);\n setSnackbarMessage('❌ Failed to copy image. Please attach manually.');\n setSnackbarOpen(true);\n }\n };\n\n const handleHeaderTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {\n if (!isMobile) return;\n const touch = event.touches[0];\n touchStartYRef.current = touch.clientY;\n touchLatestYRef.current = touch.clientY;\n };\n\n const handleHeaderTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {\n if (!isMobile) return;\n if (touchStartYRef.current === null) return;\n touchLatestYRef.current = event.touches[0].clientY;\n };\n\n const handleHeaderTouchEnd = () => {\n if (!isMobile) return;\n if (touchStartYRef.current === null || touchLatestYRef.current === null) {\n touchStartYRef.current = null;\n touchLatestYRef.current = null;\n return;\n }\n\n const delta = touchLatestYRef.current - touchStartYRef.current;\n touchStartYRef.current = null;\n touchLatestYRef.current = null;\n\n if (delta > 80) {\n handleClose();\n }\n };\n\n // Remove attachment\n const removeAttachment = (index: number) => {\n setFormData(prev => ({\n ...prev,\n attachments: prev.attachments?.filter((_, i) => i !== index) || [],\n }));\n };\n\n // Generate session info\n const getSessionInfo = useCallback(() => {\n const currentConversation = conversations[0]; // Get current conversation\n return {\n currentModel: selectedModel,\n currentProvider: 'Bandit AI',\n conversationId: currentConversation?.id || 'N/A',\n timestamp: new Date().toISOString(),\n };\n }, [selectedModel, conversations]);\n\n // Handle submit\n const handleSubmit = async () => {\n if (!formData.title?.trim() || !formData.description?.trim()) {\n setErrorMessage('Please fill in both title and description');\n return;\n }\n\n // Show confirmation dialog if there's an image\n if (formData.images && formData.images.length > 0) {\n setConfirmDialogOpen(true);\n return;\n }\n\n // If no image, proceed directly\n await performSubmit();\n };\n\n // Perform the actual submission\n const performSubmit = async () => {\n setIsSubmitting(true);\n setErrorMessage('');\n setConfirmDialogOpen(false);\n\n try {\n // Create gateway service instance\n const gatewayUrl = settings?.gatewayApiUrl;\n if (!gatewayUrl) {\n throw new Error('Gateway API URL not configured');\n }\n\n const gatewayService = new GatewayService(\n gatewayUrl,\n () => authenticationService.getToken(),\n feedbackEmail || settings?.feedbackEmail\n );\n\n // Prepare complete feedback request\n const feedbackRequest: FeedbackRequest = {\n title: formData.title!,\n description: formData.description!,\n category: formData.category ?? 'bug',\n priority: formData.priority ?? 'medium',\n annoyanceLevel: formData.annoyanceLevel,\n images: formData.images,\n attachments: formData.attachments,\n contactEmail: formData.contactEmail,\n userAgent: navigator.userAgent,\n browserInfo: getBrowserInfo(),\n sessionInfo: getSessionInfo(),\n };\n\n // Submit feedback using gateway service\n gatewayService.submitFeedback(feedbackRequest).subscribe({\n next: async (response: FeedbackResponse) => {\n // Copy image to clipboard if present\n if (formData.images && formData.images.length > 0) {\n await copyImageToClipboard();\n }\n \n if (response?.mailtoUrl) {\n // Open mailto URL if provided (fallback case)\n window.location.href = response.mailtoUrl;\n }\n \n setSubmitStatus('success');\n \n // Close modal after a short delay\n setTimeout(() => {\n handleClose();\n }, 2000);\n },\n error: (subscribeError: unknown) => {\n console.error('Failed to submit feedback:', subscribeError);\n setErrorMessage('Failed to submit feedback. Please try again.');\n setSubmitStatus('error');\n setIsSubmitting(false);\n },\n complete: () => {\n setIsSubmitting(false);\n }\n });\n \n } catch (error) {\n console.error('Failed to initialize feedback:', error);\n setErrorMessage('Failed to initialize feedback system. Please try again.');\n setSubmitStatus('error');\n setIsSubmitting(false);\n }\n };\n\n // Handle close with reset\n const handleClose = () => {\n setFormData({\n title: '',\n description: '',\n category: 'bug',\n priority: 'medium',\n contactEmail: '',\n images: [],\n attachments: [],\n annoyanceLevel: 3,\n });\n setSubmitStatus('idle');\n setErrorMessage('');\n setSnackbarOpen(false);\n setSnackbarMessage('');\n setConfirmDialogOpen(false);\n onClose();\n };\n\n const selectedCategory = feedbackCategories[formData.category as keyof FeedbackCategories];\n const selectedPriority = feedbackPriorities[formData.priority as keyof FeedbackPriorities];\n const IconComponent = iconMap[selectedCategory?.icon as keyof typeof iconMap] || MessageIcon;\n\n const isValid = !!formData.title?.trim() && !!formData.description?.trim();\n\n return (\n <>\n {/* Global or component-scoped scrollbar styles */}\n <GlobalStyles styles={{\n '::-webkit-scrollbar': {\n width: '8px',\n },\n '::-webkit-scrollbar-track': {\n background: 'transparent',\n },\n '::-webkit-scrollbar-thumb': {\n backgroundColor: '#444',\n borderRadius: '4px',\n border: '1px solid #222',\n },\n }} />\n <Dialog\n open={open}\n onClose={handleClose}\n maxWidth=\"md\"\n fullWidth\n fullScreen={isMobile}\n TransitionComponent={Fade}\n scroll=\"paper\"\n PaperProps={{\n sx: {\n borderRadius: isMobile ? 0 : 3,\n bgcolor: theme.palette.background.paper,\n backgroundImage: theme.palette.mode === 'dark'\n ? 'linear-gradient(145deg, rgba(255,255,255,0.02) 0%, rgba(255,255,255,0.01) 100%)'\n : 'linear-gradient(145deg, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0.4) 100%)',\n backdropFilter: 'blur(20px)',\n border: `1px solid ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)'}`,\n boxShadow: theme.palette.mode === 'dark'\n ? '0 32px 120px rgba(0,0,0,0.8), 0 0 0 1px rgba(255,255,255,0.05)'\n : '0 32px 120px rgba(0,0,0,0.15), 0 0 0 1px rgba(0,0,0,0.02)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n // Size to the (now condensed) content instead of pinning to the\n // full viewport — a mostly-empty full-height sheet looked broken.\n height: isMobile ? '100dvh' : 'auto',\n maxHeight: isMobile ? '100dvh' : '90vh',\n margin: isMobile ? 0 : 'auto',\n position: 'relative',\n },\n }}\n BackdropProps={{\n sx: {\n bgcolor: theme.palette.mode === 'dark'\n ? 'rgba(0, 0, 0, 0.7)'\n : 'rgba(0, 0, 0, 0.4)',\n backdropFilter: 'blur(8px)',\n },\n }}\n sx={{\n '& .MuiDialog-container': {\n alignItems: 'center',\n justifyContent: 'center',\n },\n }}\n >\n {/* Custom DialogTitle for header */}\n <DialogTitle\n onTouchStart={handleHeaderTouchStart}\n onTouchMove={handleHeaderTouchMove}\n onTouchEnd={handleHeaderTouchEnd}\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: isMobile ? 1.25 : 1.5,\n pr: { xs: 2, sm: 3 },\n pl: { xs: 2, sm: 3 },\n pt: { xs: isMobile ? 1.5 : 3, sm: 3 },\n pb: { xs: 1.5, sm: 2 },\n touchAction: 'pan-y',\n }}\n >\n {isMobile && (\n <Box\n sx={{\n width: 56,\n height: 6,\n borderRadius: 999,\n bgcolor: alpha(theme.palette.text.primary, 0.18),\n alignSelf: 'center',\n mb: 1,\n }}\n />\n )}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 1.5,\n width: '100%',\n }}\n >\n <Stack spacing={0.5} sx={{ minWidth: 0 }}>\n <Typography variant=\"h6\" fontWeight=\"bold\" noWrap>Send Feedback</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>Help us improve Bandit AI</Typography>\n </Stack>\n <IconButton onClick={handleClose} size=\"small\"><CloseIcon /></IconButton>\n </Box>\n </DialogTitle>\n <DialogContent\n sx={{\n p: { xs: 1.5, sm: 3 },\n maxHeight: 'calc(100dvh - 80px)',\n overflowY: 'auto',\n backgroundColor: 'background.default',\n scrollbarGutter: 'stable',\n }}\n >\n\n {/* Modal Content Below */}\n {submitStatus === 'success' && (\n <Alert \n severity=\"success\" \n sx={{ \n mb: 2,\n '& .MuiAlert-icon': {\n color: theme.palette.success.main,\n },\n background: theme.palette.mode === 'dark' \n ? 'linear-gradient(135deg, rgba(76,175,80,0.1) 0%, rgba(46,125,50,0.1) 100%)'\n : 'linear-gradient(135deg, rgba(76,175,80,0.05) 0%, rgba(46,125,50,0.05) 100%)',\n border: `1px solid ${theme.palette.success.main}30`,\n borderRadius: 2,\n }}\n >\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n Feedback submitted successfully!\n </Typography>\n <Typography variant=\"caption\" display=\"block\" sx={{ mt: 0.5, opacity: 0.9 }}>\n {formData.images && formData.images.length > 0\n ? \"Your email client should open with the feedback details. The image has been copied to your clipboard - paste it in the email!\"\n : (formData.attachments && formData.attachments.length > 0)\n ? \"Your email client should open with the feedback details. Please manually attach your files to the email.\"\n : \"Your email client should open with the feedback details.\"\n }\n </Typography>\n </Alert>\n )}\n\n {errorMessage && (\n <Alert \n severity=\"error\" \n sx={{ \n mb: 2,\n '& .MuiAlert-icon': {\n color: theme.palette.error.main,\n },\n background: theme.palette.mode === 'dark' \n ? 'linear-gradient(135deg, rgba(244,67,54,0.1) 0%, rgba(211,47,47,0.1) 100%)'\n : 'linear-gradient(135deg, rgba(244,67,54,0.05) 0%, rgba(211,47,47,0.05) 100%)',\n border: `1px solid ${theme.palette.error.main}30`,\n borderRadius: 2,\n }}\n >\n {errorMessage}\n </Alert>\n )}\n\n <Box\n sx={{\n display: 'grid',\n gridTemplateRows: 'auto auto auto auto',\n rowGap: '16px',\n columnGap: '0px',\n width: '100%',\n // Headroom for the first field's floating label — MUI zeroes\n // DialogContent's top padding after a DialogTitle, which clipped\n // the \"Title\" label under the header.\n pt: 1.5,\n }}\n >\n {/* Feedback Details */}\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr' },\n gridTemplateRows: 'auto auto auto',\n gap: '16px',\n mb: 0,\n }}\n >\n {/* Title - full width */}\n <TextField\n fullWidth\n label=\"Title\"\n value={formData.title}\n onChange={handleInputChange('title')}\n placeholder=\"Brief summary of your feedback\"\n required\n size=\"medium\"\n InputLabelProps={{ shrink: true }}\n sx={{\n minHeight: 48,\n gridColumn: '1 / -1',\n '& .MuiInputBase-root': {\n minHeight: 48,\n },\n '& .MuiOutlinedInput-root': {\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 4px 12px rgba(0,0,0,0.3)'\n : '0 4px 12px rgba(0,0,0,0.1)',\n },\n '&.Mui-focused': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 6px 16px rgba(0,0,0,0.4)'\n : '0 6px 16px rgba(0,0,0,0.15)',\n },\n },\n }}\n />\n {/* Category */}\n <FormControl\n fullWidth\n size=\"medium\"\n sx={{\n minHeight: 48,\n '& .MuiInputBase-root': {\n minHeight: 48,\n },\n '& .MuiOutlinedInput-root': {\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 4px 12px rgba(0,0,0,0.3)'\n : '0 4px 12px rgba(0,0,0,0.1)',\n },\n '&.Mui-focused': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 6px 16px rgba(0,0,0,0.4)'\n : '0 6px 16px rgba(0,0,0,0.15)',\n },\n },\n }}\n >\n <InputLabel shrink id=\"category-label\">Category</InputLabel>\n <Select\n labelId=\"category-label\"\n id=\"category\"\n value={formData.category}\n label=\"Category\"\n onChange={handleInputChange('category')}\n >\n {Object.entries(feedbackCategories).map(([key, category]) => {\n const Icon = iconMap[category.icon as keyof typeof iconMap];\n return (\n <MenuItem key={key} value={key}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n <Icon size={20} color={category.color} />\n <Box>\n <Typography variant=\"body2\" sx={{ fontWeight: 500 }}>{category.label}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {category.description}\n </Typography>\n </Box>\n </Box>\n </MenuItem>\n );\n })}\n </Select>\n </FormControl>\n {/* Priority */}\n <FormControl\n fullWidth\n size=\"medium\"\n sx={{\n minHeight: 48,\n '& .MuiInputBase-root': {\n minHeight: 48,\n },\n '& .MuiOutlinedInput-root': {\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 4px 12px rgba(0,0,0,0.3)'\n : '0 4px 12px rgba(0,0,0,0.1)',\n },\n '&.Mui-focused': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 6px 16px rgba(0,0,0,0.4)'\n : '0 6px 16px rgba(0,0,0,0.15)',\n },\n },\n }}\n >\n <InputLabel shrink id=\"priority-label\">Priority</InputLabel>\n <Select\n labelId=\"priority-label\"\n id=\"priority\"\n value={formData.priority}\n label=\"Priority\"\n onChange={handleInputChange('priority')}\n >\n {Object.entries(feedbackPriorities).map(([key, priority]) => (\n <MenuItem key={key} value={key}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n <Box\n sx={{\n width: 12,\n height: 12,\n borderRadius: '50%',\n bgcolor: priority.color,\n boxShadow: `0 0 0 2px ${priority.color}20`,\n }}\n />\n <Box>\n <Typography variant=\"body2\" sx={{ fontWeight: 500 }}>{priority.label}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {priority.description}\n </Typography>\n </Box>\n </Box>\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n {/* Description - full width, tall */}\n <TextField\n fullWidth\n multiline\n rows={3}\n label=\"Description\"\n value={formData.description}\n onChange={handleInputChange('description')}\n placeholder=\"Please provide detailed information about your feedback...\"\n required\n size=\"medium\"\n InputLabelProps={{ shrink: true }}\n sx={{\n minHeight: 48,\n gridColumn: '1 / -1',\n '& .MuiInputBase-root': {\n minHeight: 48,\n alignItems: 'flex-start',\n py: 1.5,\n },\n '& .MuiOutlinedInput-root': {\n borderRadius: 2,\n transition: 'all 0.2s ease',\n '&:hover': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 4px 12px rgba(0,0,0,0.3)'\n : '0 4px 12px rgba(0,0,0,0.1)',\n },\n '&.Mui-focused': {\n transform: 'translateY(-1px)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 6px 16px rgba(0,0,0,0.4)'\n : '0 6px 16px rgba(0,0,0,0.15)',\n },\n },\n }}\n />\n </Box>\n {/* Impact Assessment & Attachments - side by side, visually aligned */}\n <Box\n className=\"feedback-section-row\"\n sx={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: '24px',\n alignItems: 'stretch',\n width: '100%',\n // Responsive stacking for mobile\n flexDirection: { xs: 'column', md: 'row' },\n }}\n >\n {/* Impact — one compact row, no card chrome */}\n <Box\n className=\"impact-section\"\n sx={{ flex: 1, minWidth: 260, display: 'flex', flexDirection: 'column' }}\n >\n <Typography variant=\"body2\" sx={{ fontWeight: 600, mb: 0.5 }}>\n How annoying is this?{' '}\n {['😊', '😐', '🙄', '😠', '🤬'][(formData.annoyanceLevel ?? 3) - 1]}{' '}\n ({formData.annoyanceLevel ?? 3}/5)\n </Typography>\n <Box sx={{ px: 1 }}>\n <Slider\n size=\"small\"\n value={formData.annoyanceLevel}\n onChange={(_, value) => setFormData(prev => ({ ...prev, annoyanceLevel: value as number }))}\n min={1}\n max={5}\n step={1}\n marks\n sx={{\n '& .MuiSlider-track': {\n background: `linear-gradient(90deg, ${theme.palette.success.main}, ${theme.palette.warning.main}, ${theme.palette.error.main})`,\n border: 'none',\n },\n '& .MuiSlider-thumb': {\n background: `linear-gradient(135deg, ${theme.palette.warning.main}, ${theme.palette.warning.dark})`,\n },\n }}\n />\n </Box>\n </Box>\n {/* Attachments */}\n <Box\n className=\"attachments-upload-card attachments-section\"\n sx={{\n flex: 1,\n minWidth: 300,\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n p: 0,\n }}\n >\n <div style={{ display: 'flex', flexDirection: 'column' }}>\n <Box onClick={() => fileInputRef.current?.click()}>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n style={{ display: 'none' }}\n onChange={handleFileUpload}\n />\n {/* Compact attach affordance — the old full-height dashed\n dropzone dominated the sheet on mobile. */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n px: 1.5,\n py: 1,\n border: '1px dashed',\n borderColor: (theme) => theme.palette.divider,\n borderRadius: 2,\n cursor: 'pointer',\n color: theme.palette.text.secondary,\n '&:hover': { borderColor: theme.palette.primary.main, color: theme.palette.primary.main },\n }}\n >\n <AttachFileIcon size={18} />\n <Typography variant=\"body2\" sx={{ fontWeight: 500 }}>\n Attach an image\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ ml: 'auto' }}>\n JPG/PNG/GIF · 10MB\n </Typography>\n </Box>\n {/* Attachment Reminder - positioned at bottom */}\n {((formData.images && formData.images.length > 0) || (formData.attachments && formData.attachments.length > 0)) && (\n <Alert\n severity=\"info\"\n sx={{\n mt: 'auto',\n textAlign: 'left',\n fontSize: '0.75rem',\n py: 0.5,\n background: theme.palette.mode === 'dark'\n ? 'linear-gradient(135deg, rgba(33,150,243,0.1) 0%, rgba(25,118,210,0.1) 100%)'\n : 'linear-gradient(135deg, rgba(33,150,243,0.05) 0%, rgba(25,118,210,0.05) 100%)',\n border: `1px solid ${theme.palette.info.main}30`,\n '& .MuiAlert-icon': {\n color: theme.palette.info.main,\n fontSize: '0.875rem',\n },\n '& .MuiAlert-message': {\n fontSize: '0.75rem',\n },\n }}\n >\n <Typography variant=\"caption\" sx={{ fontWeight: 600, display: 'block' }}>\n {formData.images && formData.images.length > 0 \n ? '📎 Image will be copied to clipboard - paste in email!'\n : '📎 Files ready for email attachment'\n }\n </Typography>\n </Alert>\n )}\n </Box>\n </div>\n {/* Display uploaded image (single) */}\n {formData.images && formData.images.length > 0 && (\n <Box sx={{ mt: 2 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.5 }}>\n <PhotoCameraIcon size={16} />\n <Typography variant=\"subtitle2\" sx={{ fontWeight: 600 }}>\n Attached Image\n </Typography>\n </Box>\n <Box sx={{ display: 'flex', gap: 1.5 }}>\n <Box\n sx={{\n position: 'relative',\n borderRadius: 1.5,\n overflow: 'hidden',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 2px 8px rgba(0,0,0,0.3)'\n : '0 2px 8px rgba(0,0,0,0.1)',\n transition: 'all 0.2s ease',\n '&:hover': {\n transform: 'scale(1.05)',\n boxShadow: theme.palette.mode === 'dark'\n ? '0 4px 16px rgba(0,0,0,0.4)'\n : '0 4px 16px rgba(0,0,0,0.15)',\n },\n }}\n >\n <img\n src={formData.images[0]}\n alt=\"Attachment\"\n style={{\n width: 120,\n height: 120,\n objectFit: 'cover',\n display: 'block',\n }}\n />\n <IconButton\n size=\"small\"\n onClick={removeImage}\n sx={{\n position: 'absolute',\n top: 4,\n right: 4,\n bgcolor: 'rgba(244,67,54,0.9)',\n color: 'white',\n width: 24,\n height: 24,\n '&:hover': {\n bgcolor: 'rgba(244,67,54,1)',\n transform: 'scale(1.1)',\n },\n }}\n >\n <DeleteIcon size={14} />\n </IconButton>\n </Box>\n <Box sx={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={copyImageToClipboard}\n startIcon={<AttachFileIcon />}\n sx={{\n mb: 1,\n borderColor: theme.palette.primary.main + '50',\n color: theme.palette.primary.main,\n '&:hover': {\n borderColor: theme.palette.primary.main,\n bgcolor: theme.palette.primary.main + '10',\n },\n }}\n >\n Copy to Clipboard\n </Button>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ textAlign: 'center' }}>\n Image will be copied when you submit\n </Typography>\n </Box>\n </Box>\n </Box>\n )}\n {/* Display other attachments */}\n {formData.attachments && formData.attachments.length > 0 && (\n <Box sx={{ mt: 2 }}>\n <Typography variant=\"subtitle2\" gutterBottom>\n Attached Files ({formData.attachments.length})\n </Typography>\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>\n {formData.attachments.map((attachment, index) => (\n <Chip\n key={index}\n label={attachment.name}\n onDelete={() => removeAttachment(index)}\n deleteIcon={<DeleteIcon />}\n variant=\"outlined\"\n sx={{ maxWidth: 200 }}\n />\n ))}\n </Box>\n </Box>\n )}\n </Box>\n </Box>\n </Box>\n </DialogContent>\n\n {/* DialogActions sticky footer with single full-width Send Feedback button */}\n <DialogActions\n sx={{\n position: 'sticky',\n bottom: 0,\n zIndex: 10,\n px: { xs: 2, sm: 3 },\n py: 1.5,\n backgroundColor: 'background.paper',\n borderTop: '1px solid',\n borderColor: 'divider',\n justifyContent: 'center',\n }}\n >\n <Button\n fullWidth\n startIcon={<MailIcon />}\n disabled={!isValid}\n onClick={handleSubmit}\n variant=\"contained\"\n >\n Send Feedback\n </Button>\n </DialogActions>\n </Dialog>\n \n {/* Snackbar for clipboard feedback */}\n <Snackbar\n open={snackbarOpen}\n autoHideDuration={4000}\n onClose={() => setSnackbarOpen(false)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n sx={{\n '& .MuiSnackbarContent-root': {\n background: theme.palette.mode === 'dark'\n ? 'linear-gradient(135deg, rgba(76,175,80,0.15) 0%, rgba(46,125,50,0.15) 100%)'\n : 'linear-gradient(135deg, rgba(76,175,80,0.1) 0%, rgba(46,125,50,0.1) 100%)',\n color: theme.palette.text.primary,\n fontSize: '0.9rem',\n fontWeight: 500,\n borderRadius: 2,\n border: `1px solid ${theme.palette.success.main}30`,\n backdropFilter: 'blur(10px)',\n },\n }}\n message={snackbarMessage}\n />\n \n {/* Confirmation Dialog for Image Submission */}\n <Dialog\n open={confirmDialogOpen}\n onClose={() => setConfirmDialogOpen(false)}\n maxWidth=\"sm\"\n fullWidth\n PaperProps={{\n sx: {\n borderRadius: 3,\n bgcolor: theme.palette.background.paper,\n backgroundImage: theme.palette.mode === 'dark' \n ? 'linear-gradient(145deg, rgba(255,255,255,0.02) 0%, rgba(255,255,255,0.01) 100%)'\n : 'linear-gradient(145deg, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0.4) 100%)',\n backdropFilter: 'blur(20px)',\n border: `1px solid ${theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)'}`,\n boxShadow: theme.palette.mode === 'dark' \n ? '0 16px 60px rgba(0,0,0,0.6)' \n : '0 16px 60px rgba(0,0,0,0.15)',\n },\n }}\n >\n <DialogTitle sx={{ \n pb: 1,\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n }}>\n <Avatar\n sx={{\n bgcolor: theme.palette.info.main + '20',\n color: theme.palette.info.main,\n width: 40,\n height: 40,\n }}\n >\n <PhotoCameraIcon />\n </Avatar>\n <Box>\n <Typography variant=\"h6\" sx={{ fontWeight: 600 }}>\n Ready to Submit with Image\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n Here's what will happen when you submit\n </Typography>\n </Box>\n </DialogTitle>\n \n <DialogContent sx={{ pt: 1 }}>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <Paper\n variant=\"outlined\"\n sx={{\n p: 3,\n borderRadius: 2,\n background: theme.palette.mode === 'dark'\n ? 'linear-gradient(135deg, rgba(33,150,243,0.05) 0%, rgba(25,118,210,0.05) 100%)'\n : 'linear-gradient(135deg, rgba(33,150,243,0.03) 0%, rgba(25,118,210,0.03) 100%)',\n border: `1px solid ${theme.palette.info.main}20`,\n }}\n >\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box sx={{ \n bgcolor: theme.palette.info.main + '20', \n color: theme.palette.info.main,\n borderRadius: '50%',\n width: 24,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '12px',\n fontWeight: 'bold'\n }}>\n 1\n </Box>\n Your image will be copied to clipboard\n </Typography>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 600, mb: 2, display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box sx={{ \n bgcolor: theme.palette.info.main + '20', \n color: theme.palette.info.main,\n borderRadius: '50%',\n width: 24,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '12px',\n fontWeight: 'bold'\n }}>\n 2\n </Box>\n Your email client will open\n </Typography>\n <Typography variant=\"subtitle1\" sx={{ fontWeight: 600, mb: 1, display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box sx={{ \n bgcolor: theme.palette.info.main + '20', \n color: theme.palette.info.main,\n borderRadius: '50%',\n width: 24,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '12px',\n fontWeight: 'bold'\n }}>\n 3\n </Box>\n Paste the image with Ctrl+V (or Cmd+V)\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ ml: 4, fontStyle: 'italic' }}>\n The email will have a clear spot where you should paste\n </Typography>\n </Paper>\n \n <Alert severity=\"info\" sx={{ \n background: 'transparent',\n border: `1px solid ${theme.palette.info.main}30`,\n }}>\n <Typography variant=\"body2\">\n <strong>💡 Tip:</strong> Make sure to paste the image before sending your email!\n </Typography>\n </Alert>\n </Box>\n </DialogContent>\n \n <DialogActions sx={{ p: 2.5, pt: 1 }}>\n <Button \n onClick={() => setConfirmDialogOpen(false)}\n sx={{ color: theme.palette.text.secondary }}\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n onClick={performSubmit}\n disabled={isSubmitting}\n startIcon={isSubmitting ? <CircularProgress size={16} /> : <MailIcon />}\n sx={{\n background: `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.primary.dark} 100%)`,\n '&:hover': {\n background: `linear-gradient(135deg, ${theme.palette.primary.dark} 0%, ${theme.palette.primary.main} 100%)`,\n },\n }}\n >\n {isSubmitting ? 'Submitting...' : 'Got it, Submit Now'}\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useState, useEffect } from \"react\";\nimport { useMediaQuery, Theme } from \"@mui/material\";\nimport { useAIQueryStore } from \"../store/aiQueryStore\";\nimport { useAIProviderStore } from \"../store/aiProviderStore\";\nimport { useModelStore } from \"../store/modelStore\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\n//TODO: This file can likely be removed and solely use the useAIProvider hook the same way Chat.tsx does\n/**\n * @deprecated This hook will likely be removed in a future version.\n * Please use the new useAIProvider hook instead, which provides better RAG integration,\n * unified provider support, and improved error handling.\n * \n * The Chat component already uses useAIProvider successfully.\n */\n\nconst useAIChat = () => {\n const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down(\"sm\"));\n const provider = useAIProviderStore((state) => state.provider);\n const SYSTEM_PROMPT = useModelStore((state) => state.systemPrompt);\n const OLLAMA_MODEL = usePackageSettingsStore((state) => state.settings?.defaultModel || \"\");\n const [fullScreen, setFullScreen] = useState(isMobile);\n const [drawerOpen, setDrawerOpen] = useState(false);\n const [showSettings, setShowSettings] = useState(false);\n const [, setAutoFullscreenTriggered] = useState(false);\n\n const {\n apiKey,\n inputValue,\n setApiKey,\n setInputValue,\n setResponse,\n setPreviousQuestion,\n setComponentStatus,\n addHistory,\n } = useAIQueryStore();\n\n const sendWithAIProvider = () => {\n if (!provider) {\n debugLogger.error(\"No AI provider available for chat\");\n setComponentStatus(\"Error\");\n return;\n }\n\n let message = \"\";\n setComponentStatus(\"Loading\");\n\n const stream = provider.chat({\n model: OLLAMA_MODEL,\n stream: true,\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: inputValue },\n ],\n });\n\n stream.subscribe({\n next: (data) => {\n message += data.message.content;\n setResponse(message);\n },\n error: (err: unknown) => {\n debugLogger.error(\"Stream error in AI chat\", { error: err });\n setComponentStatus(\"Idle\");\n },\n complete: () => {\n setComponentStatus(\"Idle\");\n setPreviousQuestion(inputValue);\n setResponse(message);\n addHistory({ question: inputValue, answer: message });\n setInputValue(\"\");\n },\n });\n };\n\n const sendWithOpenAI = async () => {\n setComponentStatus(\"Loading\");\n setResponse(\"\");\n setAutoFullscreenTriggered(false);\n\n const history = useAIQueryStore.getState().history;\n const contextMessages = history.slice(-5).flatMap((entry) => [\n { role: \"user\", content: entry.question },\n { role: \"assistant\", content: entry.answer },\n ]);\n\n const payload = {\n model: \"gpt-3.5-turbo\",\n messages: [...contextMessages, { role: \"user\", content: inputValue }],\n temperature: 0.7,\n };\n\n try {\n const res = await fetch(\"https://api.openai.com/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(payload),\n });\n const data = await res.json();\n const stubbedAnswer = data.choices[0].message.content;\n setComponentStatus(\"Idle\");\n setPreviousQuestion(inputValue);\n setResponse(stubbedAnswer);\n addHistory({ question: inputValue, answer: stubbedAnswer });\n setInputValue(\"\");\n } catch (err) {\n debugLogger.error(\"Failed to handle AI chat query\", { error: err });\n setComponentStatus(\"Idle\");\n }\n };\n\n const handleSend = () => {\n if (inputValue.trim() === \"\") return;\n if (apiKey) {\n void sendWithOpenAI();\n return;\n }\n\n sendWithAIProvider();\n };\n\n useEffect(() => {\n setFullScreen(isMobile);\n }, [isMobile]);\n\n return {\n fullScreen,\n setFullScreen,\n drawerOpen,\n setDrawerOpen,\n showSettings,\n setShowSettings,\n handleSend,\n };\n};\n\nexport default useAIChat;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst useDraggable = () => {\n const modalRef = useRef<HTMLDivElement | null>(null);\n const [dragging, setDragging] = useState(false);\n const [offset, setOffset] = useState({ x: 0, y: 0 });\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const handleHeaderMouseDown = (e: React.MouseEvent) => {\n const rect = modalRef.current?.getBoundingClientRect();\n if (rect) {\n setOffset({ x: e.clientX - rect.left, y: e.clientY - rect.top });\n setDragging(true);\n }\n };\n\n const handleHeaderMouseMove = useCallback(\n (e: MouseEvent) => {\n if (dragging) {\n setPosition({ x: e.clientX - offset.x, y: e.clientY - offset.y });\n }\n },\n [dragging, offset]\n );\n\n const handleHeaderMouseUp = () => {\n setDragging(false);\n };\n\n useEffect(() => {\n if (dragging) {\n document.addEventListener(\"mousemove\", handleHeaderMouseMove);\n document.addEventListener(\"mouseup\", handleHeaderMouseUp);\n } else {\n document.removeEventListener(\"mousemove\", handleHeaderMouseMove);\n document.removeEventListener(\"mouseup\", handleHeaderMouseUp);\n }\n return () => {\n document.removeEventListener(\"mousemove\", handleHeaderMouseMove);\n document.removeEventListener(\"mouseup\", handleHeaderMouseUp);\n };\n }, [dragging, handleHeaderMouseMove]);\n\n return {\n modalRef,\n position,\n setPosition,\n handleDrag: handleHeaderMouseMove,\n handleHeaderMouseDown,\n };\n};\n\nexport default useDraggable;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport { useEffect } from 'react';\nimport { useNotification } from '../shared/components/NotificationProvider';\nimport { notificationService } from '../services/notification/notificationService';\n\n/**\n * Hook to initialize and use the notification service\n * This should be called once near the root of your component tree\n */\nexport const useNotificationService = () => {\n const notificationContext = useNotification();\n\n useEffect(() => {\n // Initialize the global notification service with the context\n notificationService.setContext(notificationContext);\n }, [notificationContext]);\n\n return {\n ...notificationContext,\n // Also expose the service methods for direct use\n handleHttpError: notificationService.handleHttpError.bind(notificationService),\n handleNetworkError: notificationService.handleNetworkError.bind(notificationService),\n handleValidationError: notificationService.handleValidationError.bind(notificationService),\n };\n};\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport React, { createContext, useContext, useState, ReactNode } from 'react';\nimport { Snackbar, Alert, AlertColor } from '@mui/material';\n\nexport interface NotificationConfig {\n message: string;\n severity?: AlertColor;\n duration?: number;\n anchorOrigin?: {\n vertical: 'top' | 'bottom';\n horizontal: 'left' | 'center' | 'right';\n };\n}\n\nexport interface NotificationContextType {\n showNotification: (config: NotificationConfig | string) => void;\n showError: (message: string) => void;\n showSuccess: (message: string) => void;\n showWarning: (message: string) => void;\n showInfo: (message: string) => void;\n}\n\nconst NotificationContext = createContext<NotificationContextType | undefined>(undefined);\n\nexport const useNotification = () => {\n const context = useContext(NotificationContext);\n if (!context) {\n throw new Error('useNotification must be used within a NotificationProvider');\n }\n return context;\n};\n\nexport interface NotificationProviderProps {\n children: ReactNode;\n defaultDuration?: number;\n defaultPosition?: {\n vertical: 'top' | 'bottom';\n horizontal: 'left' | 'center' | 'right';\n };\n}\n\nexport const NotificationProvider: React.FC<NotificationProviderProps> = ({\n children,\n defaultDuration = 4000,\n defaultPosition = { vertical: 'bottom', horizontal: 'left' }\n}) => {\n const [notification, setNotification] = useState<{\n open: boolean;\n message: string;\n severity: AlertColor;\n duration: number;\n anchorOrigin: {\n vertical: 'top' | 'bottom';\n horizontal: 'left' | 'center' | 'right';\n };\n }>({\n open: false,\n message: '',\n severity: 'info',\n duration: defaultDuration,\n anchorOrigin: defaultPosition\n });\n\n const showNotification = (config: NotificationConfig | string) => {\n const notificationConfig = typeof config === 'string' \n ? { message: config, severity: 'info' as AlertColor }\n : config;\n\n setNotification({\n open: true,\n message: notificationConfig.message,\n severity: notificationConfig.severity || 'info',\n duration: notificationConfig.duration || defaultDuration,\n anchorOrigin: notificationConfig.anchorOrigin || defaultPosition\n });\n };\n\n const showError = (message: string) => {\n showNotification({ message, severity: 'error' });\n };\n\n const showSuccess = (message: string) => {\n showNotification({ message, severity: 'success' });\n };\n\n const showWarning = (message: string) => {\n showNotification({ message, severity: 'warning' });\n };\n\n const showInfo = (message: string) => {\n showNotification({ message, severity: 'info' });\n };\n\n const handleClose = () => {\n setNotification(prev => ({ ...prev, open: false }));\n };\n\n const contextValue: NotificationContextType = {\n showNotification,\n showError,\n showSuccess,\n showWarning,\n showInfo\n };\n\n return (\n <NotificationContext.Provider value={contextValue}>\n {children}\n <Snackbar\n open={notification.open}\n autoHideDuration={notification.duration}\n onClose={handleClose}\n anchorOrigin={notification.anchorOrigin}\n >\n <Alert\n onClose={handleClose}\n severity={notification.severity}\n variant=\"filled\"\n sx={{ width: '100%' }}\n >\n {notification.message}\n </Alert>\n </Snackbar>\n </NotificationContext.Provider>\n );\n};\n\nexport default NotificationProvider;\n","/*\n * Copyright (c) 2025 Burtson Labs LLC.\n * SPDX-License-Identifier: BUSL-1.1\n * See LICENSE for the applicable terms.\n */\n\n\nimport indexedDBService from '../indexedDB/indexedDBService';\nimport { debugLogger } from '../logging/debugLogger';\n\nexport interface BrandingData {\n logoBase64?: string;\n hasTransparentLogo?: boolean;\n brandingText?: string;\n}\n\ntype BrandingRecord = BrandingData & {\n theme?: string;\n userSaved?: boolean;\n [key: string]: unknown;\n};\n\ninterface StoredBrandingConfig {\n id: string;\n branding?: BrandingRecord;\n}\n\nexport interface BrandingConfigPayload {\n branding?: BrandingRecord;\n [key: string]: unknown;\n}\n\nclass BrandingService {\n private readonly DB_NAME = \"banditConfig\";\n private readonly DB_VERSION = 1;\n private readonly STORE_NAME = \"config\";\n private readonly STORE_CONFIGS = [{ name: \"config\", keyPath: \"id\" }];\n\n public async getBranding(): Promise<BrandingData | null> {\n try {\n const data = await indexedDBService.get<StoredBrandingConfig>(\n this.DB_NAME,\n this.DB_VERSION,\n this.STORE_NAME,\n \"main\",\n this.STORE_CONFIGS\n );\n\n // Only return branding if it has meaningful data\n if (data?.branding && (data.branding.logoBase64 || data.branding.hasTransparentLogo !== undefined || data.branding.brandingText)) {\n return {\n logoBase64: data.branding.logoBase64,\n hasTransparentLogo: data.branding.hasTransparentLogo,\n brandingText: data.branding.brandingText,\n };\n }\n return null;\n } catch (error) {\n throw error;\n }\n }\n\n public async setBrandingFromConfig(config: BrandingConfigPayload): Promise<void> {\n try {\n const existing = await indexedDBService.get<StoredBrandingConfig>(\n this.DB_NAME,\n this.DB_VERSION,\n this.STORE_NAME,\n \"main\",\n this.STORE_CONFIGS\n ) || { id: \"main\" };\n\n // 🛡️ NUCLEAR PROTECTION: Never overwrite user-saved branding\n if (existing.branding?.userSaved) {\n debugLogger.debug(\"🛡️ BrandingService: User branding detected, blocking CDN config override\");\n return;\n }\n\n // Also check for any trace of user branding data\n const hasUserBranding = existing.branding && (\n existing.branding.logoBase64 ||\n existing.branding.brandingText ||\n existing.branding.theme ||\n existing.branding.hasTransparentLogo !== undefined\n );\n\n if (hasUserBranding) {\n debugLogger.debug(\"🛡️ BrandingService: Detected user branding data, blocking CDN config override\");\n return;\n }\n\n debugLogger.debug(\"🔧 BrandingService: No user branding detected, applying CDN config\");\n\n const branding = config.branding || {};\n\n const updated = {\n ...existing,\n branding: {\n ...existing.branding,\n ...branding\n }\n };\n\n await indexedDBService.put(\n this.DB_NAME,\n this.DB_VERSION,\n this.STORE_NAME,\n updated,\n this.STORE_CONFIGS\n );\n } catch (error) {\n throw error;\n }\n }\n}\n\nconst brandingService = new BrandingService();\nexport default brandingService;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport { createTheme, type Theme, type ThemeOptions } from '@mui/material/styles';\nimport { burtsonPalette, burtsonThemeOptions } from '@burtson-labs/ui/mui';\nimport { contrast, mix } from '@burtson-labs/ui/tokens';\n\nimport {\n deriveSemantics,\n legacyChatPalette,\n type BanditSemantics,\n type LegacyChatPalette,\n} from './semantic';\nimport { type BanditSkin, type BanditSkinId, skins } from './skins';\nimport type { BanditTokens as Palette } from './tokenTypes';\n\nexport type BanditMode = 'light' | 'dark';\nexport type BanditDensity = 'comfortable' | 'compact';\n\n/** The legacy status scale some screens read as `palette.status`. */\nexport interface StatusScale {\n info: string;\n available: string;\n locked: string;\n premium: string;\n error: string;\n}\n\n/**\n * What a tenant may change. Deliberately small: accent, name and logo. Error,\n * success, focus, destructive, spacing and component structure stay the\n * kit's, and the accent is contrast-corrected like any other.\n */\nexport interface BanditTenantBranding {\n accent?: string;\n name?: string;\n logoUrl?: string;\n}\n\nexport interface BanditThemeConfig {\n mode?: BanditMode;\n /** A skin id ('bandit', 'ocean', …) or a skin object. Default 'bandit'. */\n skin?: BanditSkinId | BanditSkin;\n /** Overrides the skin's accent for both modes. */\n accent?: string;\n /** `compact` for Management and other dense admin screens. */\n density?: BanditDensity;\n tenant?: BanditTenantBranding;\n}\n\nexport interface BanditThemeInfo {\n mode: BanditMode;\n skin: string;\n density: BanditDensity;\n accent: string;\n tenant?: BanditTenantBranding;\n /** The full Burtson UI token set this theme was built from. */\n tokens: Palette;\n semantics: BanditSemantics;\n /** CSS custom properties that make Burtson UI components match this theme. */\n cssVars: Record<string, string>;\n}\n\ndeclare module '@mui/material/styles' {\n interface Palette {\n /**\n * @deprecated Read `palette.bandit` (composer, control, attachment,\n * conversation, surface). Nothing in Bandit reads `palette.chat` any more;\n * it is still derived from the semantics because embedders of the\n * published engine and themes may read it. Remove in the next major.\n */\n chat: LegacyChatPalette;\n status: StatusScale;\n bandit: BanditSemantics;\n }\n interface PaletteOptions {\n /** @deprecated See `Palette.chat`. */\n chat?: Partial<LegacyChatPalette>;\n status?: Partial<StatusScale>;\n bandit?: BanditSemantics;\n }\n interface Theme {\n bandit: BanditThemeInfo;\n }\n interface ThemeOptions {\n bandit?: BanditThemeInfo;\n }\n}\n\nfunction resolveSkin(skin: BanditThemeConfig['skin']): BanditSkin {\n if (!skin) return skins.bandit;\n if (typeof skin === 'string') return skins[skin] ?? skins.bandit;\n return skin;\n}\n\n/** Tint the neutral surfaces toward the skin's hue; foregrounds and states stay put. */\nfunction tintedSurfaces(skin: BanditSkin, mode: BanditMode, base: Palette): Partial<Palette> {\n if (!skin.tint) return {};\n const t = skin.tintStrength?.[mode] ?? 0.08;\n const keys = [\n 'background',\n 'surface',\n 'surface-raised',\n 'surface-muted',\n 'card',\n 'popover',\n 'muted',\n 'secondary',\n ] as const;\n const out: Partial<Palette> = {};\n for (const k of keys) out[k] = mix(base[k], skin.tint, t);\n out.border = mix(base.border, skin.tint, t * 1.4);\n out['border-strong'] = mix(base['border-strong'], skin.tint, t * 1.4);\n out.input = mix(base.input, skin.tint, t * 1.4);\n return out;\n}\n\n/** Map the Burtson UI token set to CSS variables (the names theme.css uses). */\nexport function tokensToCssVars(tokens: Palette): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [k, v] of Object.entries(tokens)) vars[`--${k}`] = v;\n return vars;\n}\n\n/**\n * The Bandit theme factory. Everything visual comes from Burtson UI: the\n * token palette (optionally accent-shifted and tinted by a skin), the MUI\n * adapter's component shapes and states, then Bandit's product semantics.\n *\n * createBanditTheme({ mode: 'dark' })\n * createBanditTheme({ mode: 'light', skin: 'ocean', density: 'compact' })\n * createBanditTheme({ mode: 'dark', tenant: { accent: '#0f766e', name: 'Acme' } })\n */\nexport function createBanditTheme(\n config: BanditThemeConfig = {},\n ...overrides: ThemeOptions[]\n): Theme {\n const mode = config.mode ?? 'dark';\n const density = config.density ?? 'comfortable';\n const skin = resolveSkin(config.skin);\n const accent = config.tenant?.accent ?? config.accent ?? skin.accent[mode];\n const neutral = burtsonPalette({ mode });\n const surfaces = tintedSurfaces(skin, mode, neutral);\n const shifted = burtsonPalette({ mode, accent, palette: surfaces });\n // The accent was fitted against the kit's own background; a tinted skin\n // moves the background, so text tones are re-checked against it.\n const toward = mode === 'dark' ? '#ffffff' : '#000000';\n const legible = (c: string, ratio = 4.5) => {\n let out = c;\n for (let i = 0; i < 20 && contrast(out, shifted.background) < ratio; i++) out = mix(out, toward, 0.08);\n return out;\n };\n const tokens: Palette = {\n ...shifted,\n brand: legible(shifted.brand),\n ring: legible(shifted.ring),\n 'muted-foreground': legible(shifted['muted-foreground']),\n };\n const semantics = deriveSemantics(tokens, mode);\n const cssVars = tokensToCssVars(tokens);\n\n const base = burtsonThemeOptions({ mode, accent, density, palette: tokens });\n const bandit: BanditThemeInfo = {\n mode,\n skin: skin.id,\n density,\n accent,\n tenant: config.tenant,\n tokens,\n semantics,\n cssVars,\n };\n\n return createTheme(\n base,\n {\n palette: {\n chat: legacyChatPalette(semantics, tokens),\n status: {\n info: semantics.status.info,\n available: semantics.status.available,\n locked: semantics.status.locked,\n premium: semantics.status.premium,\n error: semantics.status.error,\n },\n bandit: semantics,\n },\n bandit,\n // Primary used as TEXT (text and outlined buttons, icon buttons, tabs,\n // links, color=\"primary\" type, outlined chips) reads the kit's `brand`\n // token, which is fitted to 4.5:1 on the background. primary.main is a\n // fill colour: on dark surfaces it measures under 4:1 as text.\n components: {\n MuiButton: {\n variants: [\n { props: { variant: 'text', color: 'primary' }, style: { color: tokens.brand } },\n { props: { variant: 'outlined', color: 'primary' }, style: { color: tokens.brand } },\n ],\n },\n MuiIconButton: { variants: [{ props: { color: 'primary' }, style: { color: tokens.brand } }] },\n MuiTab: { styleOverrides: { textColorPrimary: { '&.Mui-selected': { color: tokens.brand } } } },\n MuiLink: { styleOverrides: { root: { color: tokens.brand } } },\n MuiTypography: { variants: [{ props: { color: 'primary' }, style: { color: tokens.brand } }] },\n MuiChip: {\n variants: [{ props: { variant: 'outlined', color: 'primary' }, style: { color: tokens.brand } }],\n },\n },\n },\n ...overrides,\n );\n}\n","/**\n * The Burtson palette for MUI apps, so a screen built with MUI and one built\n * with Burtson UI components look like the same product.\n *\n * import { ThemeProvider } from '@mui/material/styles';\n * import { createBurtsonTheme } from '@burtson-labs/ui/mui';\n * <ThemeProvider theme={createBurtsonTheme('dark')}>…</ThemeProvider>\n * <ThemeProvider theme={createBurtsonTheme({ mode: 'dark', accent: '#2563eb', density: 'compact' })}>\n *\n * MUI is an adapter here: every colour, radius, shadow and timing comes from\n * the Burtson tokens, and the component overrides give MUI controls the same\n * shape and states as the Burtson components (focus ring, radius per role,\n * no uppercase buttons, quiet borders instead of heavy shadows).\n */\nimport { createTheme, type Shadows, type Theme, type ThemeOptions } from '@mui/material/styles';\n\nimport {\n accentTokens,\n contrast,\n dark,\n duration,\n easing,\n fontMono,\n fontSans,\n light,\n type Palette,\n radius,\n shadow,\n} from '../tokens';\n\nexport type BurtsonMode = 'light' | 'dark';\nexport type BurtsonDensity = 'comfortable' | 'compact';\n\nexport interface BurtsonThemeConfig {\n mode?: BurtsonMode;\n /** Any hex colour; primary, brand, soft and ring tones are derived with contrast kept. */\n accent?: string;\n /** `compact` for admin and data-dense screens: smaller controls, dense lists and tables. */\n density?: BurtsonDensity;\n /** Replace individual palette tokens (a product skin's tinted surfaces). */\n palette?: Partial<Palette>;\n}\n\nconst px = (rem: string) => Math.round(parseFloat(rem) * 16);\n\n/** The full token palette for a config: base mode, accent-derived brand tones, then explicit overrides. */\nexport function burtsonPalette(config: BurtsonThemeConfig = {}): Palette {\n const mode = config.mode ?? 'dark';\n const base = mode === 'dark' ? dark : light;\n return {\n ...base,\n ...(config.accent ? accentTokens(config.accent, mode) : {}),\n ...config.palette,\n };\n}\n\nfunction shadows(): Shadows {\n // MUI indexes elevation 0–24; the Burtson scale has three real levels.\n const levels = ['none', shadow.xs, shadow.xs, shadow.sm, shadow.sm, shadow.sm];\n return Array.from({ length: 25 }, (_, i) => levels[i] ?? shadow.md) as Shadows;\n}\n\n/** Theme options only, for apps that deep-merge their own overrides first. */\nexport function burtsonThemeOptions(\n modeOrConfig: BurtsonMode | BurtsonThemeConfig = 'dark',\n): ThemeOptions {\n const config = typeof modeOrConfig === 'string' ? { mode: modeOrConfig } : modeOrConfig;\n const mode = config.mode ?? 'dark';\n const compact = config.density === 'compact';\n const p = burtsonPalette(config);\n const focusRing = `0 0 0 3px color-mix(in srgb, ${p.ring} 24%, transparent)`;\n return {\n palette: {\n mode,\n primary: { main: p.primary, contrastText: p['primary-foreground'] },\n // Secondary fills use the brand text tone, which is light in dark mode;\n // their text is whichever of white or the page background reads.\n secondary: {\n main: p.brand,\n contrastText: contrast(p.brand, '#ffffff') >= 4.5 ? '#ffffff' : p.background,\n },\n info: { main: p.info, contrastText: p['info-foreground'] },\n error: { main: p.destructive, contrastText: p['destructive-foreground'] },\n warning: { main: p.warning, contrastText: p['warning-foreground'] },\n success: { main: p.success, contrastText: p['success-foreground'] },\n background: { default: p.background, paper: p.surface },\n text: { primary: p.foreground, secondary: p['muted-foreground'] },\n divider: p.border,\n action: { hover: p.muted, selected: p['brand-soft'], focus: p['brand-soft'] },\n },\n shape: { borderRadius: px(radius.md) },\n shadows: shadows(),\n typography: {\n fontFamily: fontSans,\n fontSize: compact ? 13 : 14,\n button: { textTransform: 'none', fontWeight: 600, letterSpacing: '-0.01em' },\n h1: { fontWeight: 700, letterSpacing: '-0.03em' },\n h2: { fontWeight: 700, letterSpacing: '-0.025em' },\n h3: { fontWeight: 650, letterSpacing: '-0.02em' },\n h4: { fontWeight: 650, letterSpacing: '-0.015em' },\n h5: { fontWeight: 600 },\n h6: { fontWeight: 600 },\n overline: { fontWeight: 600, letterSpacing: '0.08em' },\n },\n transitions: {\n duration: {\n shortest: duration.fast,\n shorter: duration.fast,\n short: duration.standard,\n standard: duration.standard,\n complex: duration.emphasis,\n enteringScreen: duration.emphasis,\n leavingScreen: duration.exit,\n },\n easing: {\n easeInOut: easing.standard,\n easeOut: easing.emphasized,\n easeIn: easing.exit,\n sharp: easing.standard,\n },\n },\n components: {\n MuiCssBaseline: {\n styleOverrides: {\n 'code, kbd, pre, samp': { fontFamily: fontMono },\n '@media (prefers-reduced-motion: reduce)': {\n '*, ::before, ::after': {\n animationDuration: '1ms !important',\n transitionDuration: '1ms !important',\n },\n },\n },\n },\n MuiButtonBase: { defaultProps: { disableRipple: true } },\n MuiButton: {\n defaultProps: { disableElevation: true, size: compact ? 'small' : 'medium' },\n styleOverrides: {\n root: {\n borderRadius: radius.md,\n '&:focus-visible': {\n boxShadow: focusRing,\n outline: `2px solid ${p.ring}`,\n outlineOffset: 2,\n },\n },\n outlined: { borderColor: p['border-strong'] },\n },\n },\n MuiIconButton: {\n defaultProps: { size: compact ? 'small' : 'medium' },\n styleOverrides: {\n root: {\n borderRadius: radius.md,\n '&:focus-visible': { outline: `2px solid ${p.ring}`, outlineOffset: 2 },\n },\n },\n },\n MuiPaper: {\n styleOverrides: {\n root: { backgroundImage: 'none' },\n outlined: { borderColor: p.border },\n rounded: { borderRadius: radius.lg },\n },\n },\n MuiCard: {\n defaultProps: { variant: 'outlined' },\n styleOverrides: {\n root: { borderRadius: radius.lg, backgroundColor: p.card, borderColor: p.border },\n },\n },\n MuiDialog: {\n styleOverrides: {\n paper: { borderRadius: radius.xl, border: `1px solid ${p.border}`, boxShadow: shadow.md },\n },\n },\n MuiMenu: {\n styleOverrides: {\n paper: {\n borderRadius: radius.lg,\n border: `1px solid ${p['border-strong']}`,\n boxShadow: shadow.md,\n },\n list: { paddingTop: 4, paddingBottom: 4 },\n },\n },\n MuiPopover: {\n styleOverrides: { paper: { borderRadius: radius.lg, border: `1px solid ${p.border}` } },\n },\n MuiChip: {\n defaultProps: { size: 'small' },\n styleOverrides: { root: { borderRadius: radius.full, fontWeight: 500 } },\n },\n MuiTabs: {\n styleOverrides: { indicator: { backgroundColor: p.brand, height: 2 } },\n },\n MuiTab: {\n styleOverrides: {\n root: {\n textTransform: 'none',\n fontWeight: 500,\n minHeight: compact ? 36 : 44,\n '&.Mui-selected': { color: p.foreground },\n },\n },\n },\n MuiOutlinedInput: {\n styleOverrides: {\n root: {\n borderRadius: radius.md,\n backgroundColor: p.surface,\n '& .MuiOutlinedInput-notchedOutline': { borderColor: p.input },\n '&:hover .MuiOutlinedInput-notchedOutline': { borderColor: p['border-strong'] },\n // Same focus as the Tailwind fields: a 2px ring-coloured edge inside\n // the radius, no outer halo that a scroll container could clip.\n '&.Mui-focused .MuiOutlinedInput-notchedOutline': {\n borderColor: p.ring,\n borderWidth: 2,\n },\n '&.Mui-error .MuiOutlinedInput-notchedOutline': { borderColor: p.destructive },\n },\n },\n },\n // Menu, Select and Autocomplete rows: inset 4px in a 12px surface, 8px\n // radius, a quiet secondary fill for the active row (as MenuItem and\n // SelectItem in the Tailwind kit).\n MuiMenuItem: {\n styleOverrides: {\n root: {\n margin: '0 4px',\n borderRadius: radius.sm,\n '&.Mui-focusVisible, &:hover': { backgroundColor: p.secondary },\n '&.Mui-selected': { backgroundColor: 'transparent', fontWeight: 600 },\n '&.Mui-selected.Mui-focusVisible, &.Mui-selected:hover': {\n backgroundColor: p.secondary,\n },\n },\n },\n },\n MuiAutocomplete: {\n styleOverrides: {\n paper: { borderRadius: radius.lg, border: `1px solid ${p['border-strong']}` },\n listbox: {\n padding: 4,\n '& .MuiAutocomplete-option': {\n borderRadius: radius.sm,\n '&.Mui-focused, &.Mui-focusVisible': { backgroundColor: p.secondary },\n '&[aria-selected=\"true\"]': { backgroundColor: 'transparent', fontWeight: 600 },\n '&[aria-selected=\"true\"].Mui-focused': { backgroundColor: p.secondary },\n },\n },\n },\n },\n MuiTextField: { defaultProps: { size: compact ? 'small' : 'medium' } },\n MuiAlert: { styleOverrides: { root: { borderRadius: radius.md } } },\n MuiTooltip: {\n styleOverrides: {\n tooltip: {\n backgroundColor: p.code,\n color: p['code-foreground'],\n fontSize: 12,\n borderRadius: radius.sm,\n },\n },\n },\n MuiSwitch: {\n styleOverrides: {\n switchBase: {\n '&.Mui-checked + .MuiSwitch-track': { backgroundColor: p.brand, opacity: 1 },\n },\n track: { backgroundColor: p['border-strong'], opacity: 1 },\n },\n },\n MuiList: { defaultProps: { dense: compact } },\n MuiTable: { defaultProps: { size: compact ? 'small' : 'medium' } },\n MuiToolbar: { defaultProps: { variant: compact ? 'dense' : 'regular' } },\n MuiDivider: { styleOverrides: { root: { borderColor: p.border } } },\n },\n };\n}\n\n/**\n * `createBurtsonTheme('dark')` or `createBurtsonTheme({ mode, accent, density })`,\n * then any MUI overrides, merged in order.\n */\nexport function createBurtsonTheme(\n modeOrConfig: BurtsonMode | BurtsonThemeConfig = 'dark',\n ...overrides: ThemeOptions[]\n): Theme {\n return createTheme(burtsonThemeOptions(modeOrConfig), ...overrides);\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport { mix } from '@burtson-labs/ui/tokens';\n\nimport type { BanditTokens as Palette } from './tokenTypes';\n\n/**\n * Bandit product semantics, derived from the Burtson UI tokens. Components\n * name what a thing IS (the composer, an assistant message, a recording\n * state), never which colour it happened to borrow (\"chat.fileIcon\" for a\n * send button). Tenants and skins change the tokens; these follow.\n */\nexport interface BanditSemantics {\n /** Surface levels, lowest to highest. */\n surface: {\n base: string;\n raised: string;\n subtle: string;\n interactive: string;\n interactiveHover: string;\n overlay: string;\n terminal: string;\n terminalForeground: string;\n };\n composer: {\n surface: string;\n border: string;\n borderFocus: string;\n foreground: string;\n placeholder: string;\n };\n /** Small round controls: send, attach, mic, menu. */\n control: {\n surface: string;\n surfaceHover: string;\n foreground: string;\n foregroundMuted: string;\n /** The one control that should stand out (send). */\n primarySurface: string;\n primaryForeground: string;\n };\n attachment: { surface: string; border: string; foreground: string; icon: string };\n conversation: {\n user: { surface: string; foreground: string; border: string };\n assistant: { surface: string; foreground: string; border: string };\n border: string;\n divider: string;\n meta: string;\n code: { surface: string; foreground: string };\n };\n agent: { active: string; idle: string; surface: string };\n engine: { accent: string; surface: string };\n tool: { surface: string; border: string; foreground: string };\n knowledge: { accent: string; surface: string };\n workspace: { surface: string; border: string };\n /** States. Recording is its own state, not an error. */\n status: {\n recording: string;\n transcribing: string;\n thinking: string;\n streaming: string;\n syncing: string;\n temporary: string;\n degraded: string;\n disconnected: string;\n available: string;\n premium: string;\n locked: string;\n info: string;\n success: string;\n warning: string;\n error: string;\n };\n}\n\nexport function deriveSemantics(p: Palette, mode: 'light' | 'dark'): BanditSemantics {\n const dark = mode === 'dark';\n const raised = p['surface-raised'];\n return {\n surface: {\n base: p.background,\n raised,\n subtle: p['surface-muted'],\n interactive: p.muted,\n interactiveHover: mix(p.muted, p.foreground, dark ? 0.08 : 0.05),\n overlay: p.popover,\n terminal: p.code,\n terminalForeground: p['code-foreground'],\n },\n composer: {\n surface: dark ? raised : p.surface,\n border: p.border,\n borderFocus: p.ring,\n foreground: p.foreground,\n placeholder: p['muted-foreground'],\n },\n control: {\n surface: p.muted,\n surfaceHover: mix(p.muted, p.foreground, dark ? 0.1 : 0.06),\n foreground: p.foreground,\n foregroundMuted: p['muted-foreground'],\n primarySurface: p.primary,\n primaryForeground: p['primary-foreground'],\n },\n attachment: {\n surface: p['surface-muted'],\n border: p.border,\n foreground: p.foreground,\n icon: p['muted-foreground'],\n },\n conversation: {\n user: { surface: p.muted, foreground: p.foreground, border: p.border },\n assistant: { surface: 'transparent', foreground: p.foreground, border: 'transparent' },\n border: p.border,\n divider: p.border,\n meta: p['muted-foreground'],\n code: { surface: p.code, foreground: p['code-foreground'] },\n },\n agent: { active: p.brand, idle: p['muted-foreground'], surface: p['brand-soft'] },\n engine: { accent: p.brand, surface: p['brand-soft'] },\n tool: { surface: p['surface-muted'], border: p.border, foreground: p.foreground },\n knowledge: { accent: p.info, surface: mix(p.background, p.info, dark ? 0.12 : 0.07) },\n workspace: { surface: p.surface, border: p.border },\n status: {\n recording: p.recording,\n transcribing: p.info,\n thinking: p.brand,\n streaming: p.brand,\n syncing: p.info,\n temporary: p.warning,\n degraded: p.warning,\n disconnected: p['muted-foreground'],\n available: p.success,\n premium: p.brand,\n locked: p['muted-foreground'],\n info: p.info,\n success: p.success,\n warning: p.warning,\n error: p.destructive,\n },\n };\n}\n\n/**\n * The legacy `palette.chat` shape, derived from the semantics.\n *\n * @deprecated Bandit itself no longer reads `palette.chat`; it stays as an\n * alias for embedders of the published packages that do. Read\n * `palette.bandit` instead. Remove in the next major.\n */\nexport function legacyChatPalette(s: BanditSemantics, p: Palette) {\n return {\n shell: s.surface.base,\n input: s.composer.surface,\n badge: s.control.surface,\n badgeHover: s.control.surfaceHover,\n file: s.attachment.surface,\n fileIcon: s.control.surfaceHover,\n fileText: s.attachment.foreground,\n caption: s.conversation.meta,\n suggestion: {\n background: s.surface.subtle,\n text: p.foreground,\n border: p.border,\n hoverBackground: s.surface.interactive,\n hoverBorder: p['border-strong'],\n },\n appBar: {\n background: s.surface.base,\n border: p.border,\n icon: p.foreground,\n iconHover: s.surface.interactive,\n menuBackground: s.surface.overlay,\n menuText: p.foreground,\n },\n response: {\n userBackground: s.conversation.user.surface,\n userText: p.foreground,\n userBorder: s.conversation.user.border,\n userBubble: s.conversation.user.surface,\n userAvatarBackground: 'transparent',\n modelLabel: s.conversation.meta,\n border: s.conversation.border,\n aiBackground: s.surface.subtle,\n aiText: s.conversation.assistant.foreground,\n aiBorder: p.border,\n aiBubble: s.surface.subtle,\n memoryText: s.status.success,\n divider: s.conversation.divider,\n containerBackground: s.surface.base,\n codeBackground: s.conversation.code.surface,\n codeText: s.conversation.code.foreground,\n },\n };\n}\n\nexport type LegacyChatPalette = ReturnType<typeof legacyChatPalette>;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\n/**\n * Bandit skins. A skin is a parameter set, not a separate theme: every skin\n * inherits the same spacing, type, radii, density, focus, motion, component\n * shapes and semantic state colours from Burtson UI, and varies only its\n * accent and a light tint of the neutral surfaces.\n *\n * The accent is the brand signal (primary action, selection, focus, links);\n * `createBanditTheme` derives its fills and text tones with contrast kept,\n * so a skin cannot make a button or a link unreadable.\n */\nexport interface BanditSkin {\n id: string;\n label: string;\n /** Accent per mode. One colour is fine; the mode's tones are derived from it. */\n accent: { light: string; dark: string };\n /** A hue mixed lightly into backgrounds, surfaces and borders; omit for neutral. */\n tint?: string;\n /** How much tint, per mode (0–0.2 is the useful range). */\n tintStrength?: { light: number; dark: number };\n}\n\nconst soft = { light: 0.05, dark: 0.1 };\n\n/** Burtson purple: the Bandit default. Purple is a signal, not wallpaper. */\nexport const BANDIT_ACCENT = '#a60ee5';\n\nexport const skins = {\n bandit: { id: 'bandit', label: 'Bandit', accent: { light: BANDIT_ACCENT, dark: '#c65ef1' } },\n neutral: { id: 'neutral', label: 'Neutral', accent: { light: '#2563eb', dark: '#4d90fe' } },\n corporate: {\n id: 'corporate',\n label: 'Corporate',\n accent: { light: '#1d4ed8', dark: '#3b82f6' },\n tint: '#1e3a5f',\n tintStrength: soft,\n },\n cyber: { id: 'cyber', label: 'Cyber', accent: { light: '#c026d3', dark: '#e879f9' } },\n dawn: {\n id: 'dawn',\n label: 'Dawn',\n accent: { light: '#c2410c', dark: '#f4a261' },\n tint: '#7c4a2d',\n tintStrength: soft,\n },\n forest: {\n id: 'forest',\n label: 'Forest',\n accent: { light: '#2e7d32', dark: '#4caf50' },\n tint: '#1f5130',\n tintStrength: { light: 0.06, dark: 0.14 },\n },\n mist: {\n id: 'mist',\n label: 'Mist',\n accent: { light: '#4f5bd5', dark: '#8c9eff' },\n tint: '#3b4a7a',\n tintStrength: soft,\n },\n neon: { id: 'neon', label: 'Neon', accent: { light: '#db2777', dark: '#ff4fa3' } },\n ocean: {\n id: 'ocean',\n label: 'Ocean',\n accent: { light: '#0e7490', dark: '#22c3dc' },\n tint: '#0b3b5c',\n tintStrength: { light: 0.06, dark: 0.16 },\n },\n sage: {\n id: 'sage',\n label: 'Sage',\n accent: { light: '#3f8a4f', dark: '#66bb6a' },\n tint: '#2f4a38',\n tintStrength: soft,\n },\n stone: {\n id: 'stone',\n label: 'Stone',\n accent: { light: '#57534e', dark: '#d6d3d1' },\n tint: '#57534e',\n tintStrength: { light: 0.06, dark: 0.06 },\n },\n sunset: {\n id: 'sunset',\n label: 'Sunset',\n accent: { light: '#c2410c', dark: '#ff8a3d' },\n tint: '#6b3417',\n tintStrength: { light: 0.05, dark: 0.14 },\n },\n volcanic: {\n id: 'volcanic',\n label: 'Volcanic',\n accent: { light: '#c62828', dark: '#ef5350' },\n tint: '#4a1512',\n tintStrength: { light: 0.03, dark: 0.08 },\n },\n} satisfies Record<string, BanditSkin>;\n\nexport type BanditSkinId = keyof typeof skins;\n\n/**\n * Legacy registry keys (\"ocean-dark\") map to a skin and mode. The historical\n * key for the cyber skin is \"cyber\"; \"cyberPunk\" is kept as an alias.\n */\nexport function parseThemeKey(key: string): { skin: BanditSkinId; mode: 'light' | 'dark' } {\n const m = /^([a-z]+?)(?:Punk)?-(dark|light)$/i.exec(key);\n const skin = (m?.[1]?.toLowerCase() ?? 'bandit') as BanditSkinId;\n return { skin: skin in skins ? skin : 'bandit', mode: m?.[2] === 'light' ? 'light' : 'dark' };\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport { ThemeProvider, type Theme } from '@mui/material/styles';\nimport * as React from 'react';\n\nimport { createBanditTheme, type BanditThemeConfig } from './createBanditTheme';\n\nexport interface BanditThemeProviderProps {\n /** A theme from createBanditTheme, or the config to build one. */\n theme?: Theme;\n config?: BanditThemeConfig;\n /**\n * Where Burtson UI components read their colours from.\n * `document` (the host app): variables and the dark/light class go on <html>.\n * `element` (an embedded engine): they go on a wrapper, so the host page is untouched.\n */\n scope?: 'document' | 'element';\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\n/**\n * One provider for both component systems: MUI gets the Bandit theme, and\n * Burtson UI components get the same tokens as CSS variables. Without it an\n * MUI button and a Burtson button on the same screen could disagree about\n * the accent, the surfaces or the mode.\n */\nexport function BanditThemeProvider({\n theme,\n config,\n scope = 'document',\n className,\n style,\n children,\n}: BanditThemeProviderProps) {\n const resolved = React.useMemo(() => theme ?? createBanditTheme(config), [theme, config]);\n const { cssVars, mode } = resolved.bandit;\n\n React.useLayoutEffect(() => {\n if (scope !== 'document' || typeof document === 'undefined') return;\n const root = document.documentElement;\n const previous = new Map<string, string>();\n for (const [k, v] of Object.entries(cssVars)) {\n previous.set(k, root.style.getPropertyValue(k));\n root.style.setProperty(k, v);\n }\n const hadDark = root.classList.contains('dark');\n const hadLight = root.classList.contains('light');\n const previousScheme = root.style.colorScheme;\n root.classList.toggle('dark', mode === 'dark');\n root.classList.toggle('light', mode === 'light');\n root.style.colorScheme = mode;\n return () => {\n for (const [k, v] of previous) {\n if (v) root.style.setProperty(k, v);\n else root.style.removeProperty(k);\n }\n // A nested document-scope provider (Management over the site) hands the\n // mode back too, not only the variables.\n root.classList.toggle('dark', hadDark);\n root.classList.toggle('light', hadLight);\n root.style.colorScheme = previousScheme;\n };\n }, [scope, cssVars, mode]);\n\n if (scope === 'element') {\n return (\n <ThemeProvider theme={resolved}>\n <div\n className={[mode === 'dark' ? 'dark' : 'light', className].filter(Boolean).join(' ')}\n data-bandit-theme={resolved.bandit.skin}\n style={{ ...(cssVars as React.CSSProperties), colorScheme: mode, ...style }}\n >\n {children}\n </div>\n </ThemeProvider>\n );\n }\n return <ThemeProvider theme={resolved}>{children}</ThemeProvider>;\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport type { Theme } from '@mui/material/styles';\n\nimport { createBanditTheme, type BanditDensity, type BanditMode, type BanditTenantBranding } from './createBanditTheme';\nimport { type BanditSkinId, skins } from './skins';\n\n/**\n * Tenant branding as a theme key.\n *\n * Every place that stores a Bandit theme stores one string (\"ocean-dark\").\n * A tenant accent rides in the same string, \"tenant-0f766e-dark\", so the\n * stores, exports and the engine's theme lookups need no second field, and\n * every lookup builds it through createBanditTheme({ tenant }), which corrects\n * the accent for contrast. Older readers that don't know the form fall back to\n * the Bandit theme instead of breaking.\n */\nconst TENANT_KEY = /^tenant-([0-9a-f]{6})-(dark|light)$/i;\nconst SKIN_KEY = /^([a-z]+?)(?:Punk)?-(dark|light)$/i;\nconst HEX = /^#[0-9a-f]{6}$/i;\n\n/** A six-digit hex colour (#RRGGBB): the only accent form a tenant can set. */\nexport const isTenantAccent = (value: string): boolean => HEX.test(value.trim());\n\nexport interface BrandingThemeChoice {\n mode: BanditMode;\n /** The skin (surface tint and default accent). A tenant accent uses the Bandit skin. */\n skin: BanditSkinId;\n /** A tenant's own accent (#rrggbb), when they chose one instead of a skin. */\n accent?: string;\n}\n\n/** Reads any stored theme key: a skin (\"ocean-light\"), a tenant accent, or junk (Bandit dark). */\nexport function parseBrandingTheme(key: string | null | undefined): BrandingThemeChoice {\n const value = (key ?? '').trim();\n const tenant = TENANT_KEY.exec(value);\n if (tenant) {\n return { skin: 'bandit', mode: tenant[2]!.toLowerCase() === 'light' ? 'light' : 'dark', accent: `#${tenant[1]!.toLowerCase()}` };\n }\n const m = SKIN_KEY.exec(value);\n const skin = (m?.[1]?.toLowerCase() ?? 'bandit') as BanditSkinId;\n return { skin: skin in skins ? skin : 'bandit', mode: m?.[2]?.toLowerCase() === 'light' ? 'light' : 'dark' };\n}\n\n/** The key to store for a choice. A valid accent wins over the skin. */\nexport function brandingThemeKey(choice: BrandingThemeChoice): string {\n if (choice.accent && isTenantAccent(choice.accent)) {\n return `tenant-${choice.accent.trim().slice(1).toLowerCase()}-${choice.mode}`;\n }\n return `${choice.skin in skins ? choice.skin : 'bandit'}-${choice.mode}`;\n}\n\n/** True for keys this module writes for a tenant accent. */\nexport const isTenantThemeKey = (key: string): boolean => TENANT_KEY.test(key);\n\n/**\n * The theme for a stored key, through createBanditTheme only. Name and logo\n * travel on `theme.bandit.tenant` for hosts that show them.\n */\nexport function createBrandingTheme(\n key: string | null | undefined,\n options: { density?: BanditDensity; name?: string; logoUrl?: string } = {},\n): Theme {\n const { skin, mode, accent } = parseBrandingTheme(key);\n const tenant: BanditTenantBranding | undefined = accent\n ? { accent, name: options.name || undefined, logoUrl: options.logoUrl || undefined }\n : undefined;\n return createBanditTheme({ skin, mode, density: options.density, tenant });\n}\n\n/** \"Ocean · Light\", or \"Custom <hex> · Dark\" for a tenant accent. */\nexport function describeBrandingTheme(key: string | null | undefined): string {\n const { skin, mode, accent } = parseBrandingTheme(key);\n const modeLabel = mode === 'light' ? 'Light' : 'Dark';\n return accent ? `Custom ${accent} · ${modeLabel}` : `${skins[skin].label} · ${modeLabel}`;\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport type { Theme } from '@mui/material/styles';\n\nimport { createBanditTheme, type StatusScale } from './createBanditTheme';\nimport { type BanditSkinId, skins } from './skins';\nimport { createBrandingTheme, isTenantThemeKey } from './tenant';\n\n/**\n * The registry the engine and Management have always used (\"ocean-dark\" →\n * Theme), now generated from the skins so every entry is the same system.\n * Keys, names and shapes are unchanged for existing consumers.\n */\nconst REGISTRY_SKINS: BanditSkinId[] = [\n 'bandit',\n 'corporate',\n 'neutral',\n 'cyber',\n 'dawn',\n 'mist',\n 'sage',\n 'stone',\n 'ocean',\n 'neon',\n 'forest',\n 'sunset',\n 'volcanic',\n];\n\ntype ThemeRegistry = Record<string, Theme>;\n\nconst skinThemes: ThemeRegistry = {};\nfor (const id of REGISTRY_SKINS) {\n for (const mode of ['dark', 'light'] as const) {\n skinThemes[`${id}-${mode}`] = createBanditTheme({ skin: id, mode });\n }\n}\n\n/**\n * The registry also answers tenant keys (\"tenant-0f766e-dark\"), built on first\n * use through createBanditTheme({ tenant }) and cached. They are not listed:\n * Object.keys(themeMap) is still the 26 skin themes, so pickers are unchanged,\n * and every existing `themeMap[key]` lookup (the chat, the chat modal) shows a\n * tenant's saved accent without code of its own.\n */\nconst tenantThemes = new Map<string, Theme>();\nconst themeMap: ThemeRegistry = new Proxy(skinThemes, {\n get(target, prop, receiver) {\n if (typeof prop === 'string' && !(prop in target) && isTenantThemeKey(prop)) {\n const key = prop.toLowerCase();\n let theme = tenantThemes.get(key);\n if (!theme) {\n theme = createBrandingTheme(key);\n tenantThemes.set(key, theme);\n }\n return theme;\n }\n return Reflect.get(target, prop, receiver);\n },\n});\n\nexport default themeMap;\nexport { themeMap };\n\nexport const predefinedThemes: Record<string, Theme & { name: string }> = Object.fromEntries(\n Object.entries(skinThemes).map(([name, theme]) => [name, { name, ...theme }]),\n);\n\n/** Skin ids in registry order, for pickers. */\nexport const themeSkinIds = REGISTRY_SKINS;\nexport const themeSkinLabel = (id: BanditSkinId) => skins[id].label;\n\n// Named exports kept for existing imports (`import { oceanDarkTheme } …`).\nexport const banditDarkTheme = skinThemes['bandit-dark']!;\nexport const banditLightTheme = skinThemes['bandit-light']!;\nexport const corporateDarkTheme = skinThemes['corporate-dark']!;\nexport const corporateLightTheme = skinThemes['corporate-light']!;\nexport const neutralDarkTheme = skinThemes['neutral-dark']!;\nexport const neutralLightTheme = skinThemes['neutral-light']!;\nexport const cyberPunkDarkTheme = skinThemes['cyber-dark']!;\nexport const cyberPunkLightTheme = skinThemes['cyber-light']!;\nexport const dawnDarkTheme = skinThemes['dawn-dark']!;\nexport const dawnLightTheme = skinThemes['dawn-light']!;\nexport const mistDarkTheme = skinThemes['mist-dark']!;\nexport const mistLightTheme = skinThemes['mist-light']!;\nexport const sageDarkTheme = skinThemes['sage-dark']!;\nexport const sageLightTheme = skinThemes['sage-light']!;\nexport const stoneDarkTheme = skinThemes['stone-dark']!;\nexport const stoneLightTheme = skinThemes['stone-light']!;\nexport const oceanDarkTheme = skinThemes['ocean-dark']!;\nexport const oceanLightTheme = skinThemes['ocean-light']!;\nexport const neonDarkTheme = skinThemes['neon-dark']!;\nexport const neonLightTheme = skinThemes['neon-light']!;\nexport const forestDarkTheme = skinThemes['forest-dark']!;\nexport const forestLightTheme = skinThemes['forest-light']!;\nexport const sunsetDarkTheme = skinThemes['sunset-dark']!;\nexport const sunsetLightTheme = skinThemes['sunset-light']!;\nexport const volcanicDarkTheme = skinThemes['volcanic-dark']!;\nexport const volcanicLightTheme = skinThemes['volcanic-light']!;\n\n/** The status scale of a theme (every Bandit theme carries one). */\nexport const statusColors = (theme: Theme): StatusScale => theme.palette.status;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n*/\n\nimport Avatar from '@mui/material/Avatar';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Paper from '@mui/material/Paper';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport { useTheme } from '@mui/material/styles';\nimport * as React from 'react';\n\nimport { createBanditTheme, type BanditDensity, type BanditMode } from './createBanditTheme';\nimport { BanditThemeProvider } from './provider';\nimport type { BanditSkinId } from './skins';\n\nexport interface TenantPreviewProps {\n /** The tenant's accent (#rrggbb). Omit to preview a skin's own accent. */\n accent?: string;\n skin?: BanditSkinId;\n name: string;\n tagline?: string;\n logoUrl?: string;\n /** Which modes to show. Default both, the page's own mode first. */\n modes?: BanditMode[];\n density?: BanditDensity;\n /** Heading above the panes; null hides it. */\n title?: React.ReactNode;\n /**\n * What sits under the header in each pane. Default: a primary action and a\n * link, the two places the accent shows most.\n */\n renderBody?: (mode: BanditMode) => React.ReactNode;\n}\n\n/**\n * The tenant's branding rendered through createBanditTheme in light and dark,\n * so the owner sees the contrast-corrected result their team will get. One\n * implementation for every host: create-workspace, the account branding page\n * and the engine's Branding section. MUI only, so the engine can ship it\n * without Burtson UI CSS; each pane is its own element-scoped theme.\n */\nexport function TenantPreview({\n accent,\n skin,\n name,\n tagline,\n logoUrl,\n modes,\n density = 'compact',\n title = 'Preview',\n renderBody,\n}: TenantPreviewProps) {\n const pageMode = useTheme().palette.mode as BanditMode;\n const shown = modes ?? (pageMode === 'light' ? ['light', 'dark'] : ['dark', 'light']);\n return (\n <Stack spacing={1.5} role=\"group\" aria-label=\"Branding preview\">\n {title !== null && (\n <Typography component=\"h3\" variant=\"subtitle2\" sx={{ fontWeight: 600 }}>\n {title}\n </Typography>\n )}\n <Box\n sx={{\n display: 'grid',\n gap: 1.5,\n gridTemplateColumns: shown.length > 1 ? { xs: '1fr', md: 'repeat(2, minmax(0, 1fr))' } : '1fr',\n }}\n >\n {shown.map((mode) => (\n <PreviewPane\n key={mode}\n mode={mode}\n accent={accent}\n skin={skin}\n name={name}\n tagline={tagline}\n logoUrl={logoUrl}\n density={density}\n renderBody={renderBody}\n />\n ))}\n </Box>\n </Stack>\n );\n}\n\nfunction PreviewPane({\n mode,\n accent,\n skin,\n name,\n tagline,\n logoUrl,\n density,\n renderBody,\n}: Omit<TenantPreviewProps, 'modes' | 'title'> & { mode: BanditMode }) {\n const theme = React.useMemo(\n () =>\n createBanditTheme({\n mode,\n skin,\n density,\n tenant: accent ? { accent, name, logoUrl: logoUrl || undefined } : undefined,\n }),\n [mode, skin, density, accent, name, logoUrl],\n );\n // createBanditTheme may move the fill (primary) and the text tone (brand)\n // to keep 4.5:1; say so when either moved away from what the owner picked.\n const { primary, brand } = theme.bandit.tokens;\n const adjusted = Boolean(accent) && [primary, brand].some((c) => c.toLowerCase() !== accent!.toLowerCase());\n const label = name.trim() || 'Your workspace';\n return (\n <BanditThemeProvider theme={theme} scope=\"element\">\n <Paper\n variant=\"outlined\"\n sx={{ p: 2, bgcolor: 'background.default', color: 'text.primary', minWidth: 0, height: '100%' }}\n >\n <Stack direction=\"row\" spacing={1.25} alignItems=\"center\" sx={{ minWidth: 0 }}>\n {logoUrl ? (\n <Box component=\"img\" src={logoUrl} alt=\"\" sx={{ width: 28, height: 28, objectFit: 'contain', flexShrink: 0 }} />\n ) : (\n <Avatar\n aria-hidden\n sx={{ width: 28, height: 28, fontSize: 13, fontWeight: 600, bgcolor: 'primary.main', color: 'primary.contrastText' }}\n >\n {label.charAt(0).toUpperCase()}\n </Avatar>\n )}\n <Typography sx={{ fontWeight: 600, minWidth: 0, flex: 1, overflowWrap: 'anywhere' }}>{label}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ textTransform: 'capitalize', flexShrink: 0 }}>\n {mode}\n </Typography>\n </Stack>\n {tagline ? (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 0.5 }}>\n {tagline}\n </Typography>\n ) : null}\n {renderBody ? (\n <Box sx={{ mt: 2 }}>{renderBody(mode)}</Box>\n ) : (\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\" sx={{ mt: 2 }}>\n <Button variant=\"contained\" size=\"small\" tabIndex={-1}>\n New chat\n </Button>\n <Typography\n variant=\"body2\"\n sx={(t) => ({ color: t.bandit.tokens.brand, textDecoration: 'underline', textUnderlineOffset: 3 })}\n >\n Shared knowledge\n </Typography>\n </Stack>\n )}\n {adjusted && (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 1.5 }}>\n Adjusted in {mode} mode to keep text readable.\n </Typography>\n )}\n </Paper>\n </BanditThemeProvider>\n );\n}\n"],"mappings":"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","names":["storeConfigs","db","e","json","import_rxjs","models","import_rxjs","import_rxjs","import_rxjs","import_zustand","TOKEN_KEY","import_rxjs","axios","e","rawToken","import_operators","import_operators","import_operators","import_operators","import_rxjs","normalizeImageUrl","models","import_rxjs","import_rxjs","import_rxjs","import_zustand","import_zustand","isRecord","import_zustand","useModelStore","storeConfigs","import_zustand","storeConfigs","import_react","import_material","React","import_react","import_material","import_jsx_runtime","theme","import_react","import_material","import_jsx_runtime","import_react","import_react","import_material","import_react","uuidv4","storeConfigs","import_uuid","import_rxjs","str","import_rxjs","import_rxjs","import_rxjs","import_rxjs","import_zustand","files","MemoryUtils","duration","import_react","DB_NAME","STORE_NAME","storeConfigs","import_react","import_react","import_jsx_runtime","import_zustand","import_uuid","import_zustand","import_uuid","import_zustand","DB_NAME","STORE_NAME","storeConfigs","DB_NAME","STORE_NAME","DB_VERSION","storeConfigs","DB_NAME","STORE_NAME","DB_VERSION","storeConfigs","uuidv4","import_zustand","import_uuid","DB_NAME","STORE_NAME","DB_VERSION","storeConfigs","uuidv4","isRecord","uuidv4","useAIProviderStore","results","DB_NAME","STORE_NAME","useKnowledgeStore","storeConfigs","uuidv4","mammoth","import_jsx_runtime","useKnowledgeStore","import_react","import_material","pdfjsLib","javascript","typescript","json","bash","shell","yaml","python","css","xml","markdown","sql","java","csharp","cpp","go","rust","kotlin","swift","scala","ruby","php","powershell","import_react","import_material","import_jsx_runtime","React","import_jsx_runtime","getFileTypeInfo","doc","error","import_styles","import_rehype_sanitize","import_material","import_react","import_zustand","import_rxjs","import_rxjs","import_zustand","import_react","import_material","import_react","import_react","import_material","import_styles","soft","import_react","import_jsx_runtime","React","ComposerControl","import_jsx_runtime","CheckIcon","ContentCopyIcon","CanvasIcon","PlayArrowIcon","CampaignOutlined","CampaignRounded","PauseIcon","StopIcon","ThumbUpIcon","ThumbDownIcon","import_jsx_runtime","markdown","React","useKnowledgeStore","timeout","ReactMarkdown","remarkGfm","rehypeRaw","rehypeSanitize","import_react","import_material","import_react","import_styles","import_material","import_jsx_runtime","shell","React","import_rxjs","import_jsx_runtime","theme","React","import_material","import_jsx_runtime","import_react","import_material","import_react","import_material","import_styles","import_jsx_runtime","BugReportIcon","LightbulbIcon","TrendingUpIcon","HelpIcon","MessageIcon","CloseIcon","theme","AttachFileIcon","PhotoCameraIcon","DeleteIcon","MailIcon","import_jsx_runtime","FeedbackIcon","import_react","import_material","import_react","import_react","import_react","import_material","import_jsx_runtime","import_styles","dark","import_styles","React","import_jsx_runtime","import_styles","React","import_jsx_runtime","import_rxjs","import_jsx_runtime","banditHead","notificationService","toTitleCase","str"]}