@burtson-labs/bandit-engine 2.0.50 → 2.0.51

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 (35) hide show
  1. package/dist/{chat-CQWZOJH4.mjs → chat-W5IFNEUC.mjs} +5 -5
  2. package/dist/chat-provider.js +29 -14
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +3 -3
  5. package/dist/{chunk-VL3CMSDO.mjs → chunk-EWUUF4GE.mjs} +2 -2
  6. package/dist/{chunk-AXFX2HUK.mjs → chunk-HETIHZ42.mjs} +2 -2
  7. package/dist/{chunk-6WZUQHZT.mjs → chunk-IDH2YOW3.mjs} +30 -15
  8. package/dist/chunk-IDH2YOW3.mjs.map +1 -0
  9. package/dist/{chunk-ZTTGERUG.mjs → chunk-JBXNXSAH.mjs} +7 -7
  10. package/dist/{chunk-TVF45U7B.mjs → chunk-LXD3IV6Z.mjs} +3 -3
  11. package/dist/{chunk-KHKWYHXD.mjs → chunk-N7RMUOFB.mjs} +2 -2
  12. package/dist/{chunk-HKJTRBWC.mjs → chunk-QFSEZAG6.mjs} +3 -3
  13. package/dist/{chunk-Q2N7CCZI.mjs → chunk-STMXPFAQ.mjs} +45 -6
  14. package/dist/chunk-STMXPFAQ.mjs.map +1 -0
  15. package/dist/cli.js +1 -1
  16. package/dist/cli.js.map +1 -1
  17. package/dist/index.js +69 -15
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +8 -8
  20. package/dist/management/management.js +69 -15
  21. package/dist/management/management.js.map +1 -1
  22. package/dist/management/management.mjs +6 -6
  23. package/dist/modals/chat-modal/chat-modal.js +29 -14
  24. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  25. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  26. package/package.json +1 -1
  27. package/dist/chunk-6WZUQHZT.mjs.map +0 -1
  28. package/dist/chunk-Q2N7CCZI.mjs.map +0 -1
  29. /package/dist/{chat-CQWZOJH4.mjs.map → chat-W5IFNEUC.mjs.map} +0 -0
  30. /package/dist/{chunk-VL3CMSDO.mjs.map → chunk-EWUUF4GE.mjs.map} +0 -0
  31. /package/dist/{chunk-AXFX2HUK.mjs.map → chunk-HETIHZ42.mjs.map} +0 -0
  32. /package/dist/{chunk-ZTTGERUG.mjs.map → chunk-JBXNXSAH.mjs.map} +0 -0
  33. /package/dist/{chunk-TVF45U7B.mjs.map → chunk-LXD3IV6Z.mjs.map} +0 -0
  34. /package/dist/{chunk-KHKWYHXD.mjs.map → chunk-N7RMUOFB.mjs.map} +0 -0
  35. /package/dist/{chunk-HKJTRBWC.mjs.map → chunk-QFSEZAG6.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat/chat.tsx","../src/chat/custom-logo.tsx","../src/chat/chat.css","../src/chat/chat-scroll-to-bottom-button.tsx","../src/chat/bandit-chat-logo.tsx","../src/chat/chat-messages.tsx","../src/chat/chat-input.tsx","../src/services/stt/transcriber.tsx","../src/services/stt/sound-recorder.service.ts","../src/services/stt/create-audio-blob.ts","../src/services/stt/stt-client.ts","../src/store/voiceModeStore.ts","../src/chat/hooks/useAIProvider.tsx","../src/chat/hooks/useMemoryEnhancer.tsx","../src/chat/hooks/useMoodEngine.tsx","../src/services/mcp/mcpService.ts","../src/hooks/useAutoScroll.ts","../src/hooks/useNetworkStatus.ts","../src/chat/chat-app-bar.tsx","../src/chat/conversation-drawer.tsx","../src/chat/project-management-modal.tsx","../src/chat/move-conversation-modal.tsx","../src/chat/simple-conversation-item.tsx","../src/chat/project-header.tsx","../src/config/tooltips.ts","../src/chat/enhanced-mobile-conversations-modal.tsx","../src/chat/hooks/useConversationNameGenerator.tsx","../src/chat/query-suggestion-picker.tsx","../../../src/pages/under-review.tsx","../src/components/ConnectionStatus.tsx","../src/hooks/useVoiceMode.ts"],"sourcesContent":["/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-ADA1-C10301\nconst __banditFingerprint_chat_chattsx = 'BL-FP-CFC9B2-7718';\nconst __auditTrail_chat_chattsx = 'BL-AU-MGOIKVUY-9KCZ';\n// File: chat.tsx | Path: src/chat/chat.tsx | Hash: ada17718\n\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport CustomLogo from \"./custom-logo\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { Box, ThemeProvider, CssBaseline, CircularProgress, Typography } from \"@mui/material\";\nimport { createTheme } from \"@mui/material/styles\";\nimport { useAIQueryStore } from \"../store/aiQueryStore\";\nimport { useModelStore } from \"../store/modelStore\";\nimport { Navigate } from \"react-router-dom\";\nimport ChatScrollToBottomButton from \"./chat-scroll-to-bottom-button\";\nimport BanditChatLogo from \"./bandit-chat-logo\";\nimport ChatMessages from \"./chat-messages\";\nimport ChatInput from \"./chat-input\";\nimport { useAIProvider } from \"./hooks/useAIProvider\";\nimport { SCROLL_STATE_CHANGED_EVENT, useAutoScroll } from \"../hooks/useAutoScroll\";\nimport { useNetworkStatus } from \"../hooks/useNetworkStatus\";\nimport \"./chat.css\";\nimport { useVoiceStore } from \"../store/voiceStore\";\nimport { useAIProviderStore } from \"../store/aiProviderStore\";\nimport { useTTS } from \"../hooks/useTTS\";\nimport ChatAppBar from \"./chat-app-bar\";\nimport { useConversationStore } from \"../store/conversationStore\";\nimport { useConversationNameGenerator } from \"./hooks/useConversationNameGenerator\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport { QuerySuggestionPicker } from \"./query-suggestion-picker\";\nimport { authenticationService } from \"../services/auth/authenticationService\";\nimport themeMap from \"../theme/themeMap\";\nimport { banditDarkTheme } from \"../theme/banditTheme\";\nimport UnderReview from \"../../../../src/pages/under-review\";\nimport { usePreferencesStore } from \"../store/preferencesStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { stopTTS } from \"../services/tts/streaming-tts\";\nimport { FeedbackButton } from \"../components/feedback/FeedbackButton\";\nimport { useNotificationService } from \"../hooks/useNotificationService\";\nimport { ConnectionStatus } from \"../components/ConnectionStatus\";\nimport { useVoiceMode } from \"../hooks/useVoiceMode\";\nimport { useVoiceModeStore } from \"../store/voiceModeStore\";\nimport { sanitizeForTTS } from \"../services/tts/ttsSanitizer\";\nimport { StoredBanditConfigRecord, StoredBrandingConfig } from \"../types/config\";\nimport { useFeatureFlag } from \"../contexts/FeatureFlagContext\";\n\nconst ChatContent = () => {\n const packageSettings = usePackageSettingsStore((state) => state.settings);\n const featureFlag = useFeatureFlag();\n const { isOSSMode } = featureFlag;\n const ossMode = isOSSMode() || !packageSettings?.featureFlags?.subscriptionType;\n const playgroundBypassAccess =\n packageSettings?.playgroundBypassAuth ||\n (typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\"));\n const notificationService = useNotificationService();\n const [selectedTheme, setSelectedTheme] = useState<string | null>(null);\n const [themeLoading, setThemeLoading] = useState(true);\n \n // Check for super-admin role\n const token = authenticationService.getToken();\n const claims = token ? authenticationService.parseJwtClaims(token) : null;\n const baseTheme = themeMap[selectedTheme ?? \"bandit-dark\"] || banditDarkTheme;\n const banditTheme = useMemo(() => {\n return createTheme(baseTheme, {\n components: {\n MuiInputBase: {\n styleOverrides: {\n input: {\n outline: \"none\",\n boxShadow: \"none\",\n \"&:focus, &:focus-visible\": {\n outline: \"none\",\n boxShadow: \"none\",\n },\n },\n inputMultiline: {\n outline: \"none\",\n boxShadow: \"none\",\n \"&:focus, &:focus-visible\": {\n outline: \"none\",\n boxShadow: \"none\",\n },\n },\n },\n },\n },\n });\n }, [baseTheme]);\n\n const {\n inputValue,\n setInputValue,\n setResponse,\n history,\n addHistory,\n setComponentStatus,\n setPreviousQuestion,\n componentStatus,\n hydrated,\n } = useAIQueryStore();\n\n const { availableModels, selectedModel, setSelectedModel } = useModelStore();\n const { \n availableVoices, \n selectedVoice, \n setSelectedVoice,\n isServiceAvailable,\n loadVoicesFromAPI,\n initialized\n } = useVoiceStore();\n const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);\n const previousVoiceModeEnabledRef = useRef(isVoiceModeEnabled);\n const historyRef = useRef(history);\n\n useEffect(() => {\n historyRef.current = history;\n }, [history]);\n \n // TTS functionality\n const {\n speak: ttsSpeak,\n stop: ttsStop,\n isAvailable: isTTSAvailable,\n } = useTTS();\n \n // Initialize voice loading when component mounts\n useEffect(() => {\n // Force voice loading with a small delay to ensure package settings are ready\n const timer = setTimeout(() => {\n const isAuthenticated = authenticationService.isAuthenticated();\n \n if (!initialized || availableVoices.length === 0) {\n if (token && isAuthenticated) {\n debugLogger.debug('Chat: Voices not initialized or unavailable, attempting to load from API');\n loadVoicesFromAPI();\n } else {\n debugLogger.debug('Chat: No valid JWT token available - skipping voice loading');\n }\n }\n }, 500); // 500ms delay to ensure gateway URL is configured\n\n return () => clearTimeout(timer);\n }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);\n\n // Also try to load voices when package settings become available\n useEffect(() => {\n const isAuthenticated = authenticationService.isAuthenticated();\n \n if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {\n if (token && isAuthenticated) {\n debugLogger.debug('Chat: Gateway URL available and no voices loaded, attempting to load from API');\n loadVoicesFromAPI();\n } else {\n debugLogger.debug('Chat: Gateway URL available but no valid JWT token - skipping voice loading');\n }\n }\n }, [packageSettings?.gatewayApiUrl, availableVoices.length, initialized, loadVoicesFromAPI, token]);\n\n const provider = useAIProviderStore((state) => state.provider);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const [pastedImages, setPastedImages] = useState<string[]>([]);\n const inputContainerRef = useRef<HTMLDivElement | null>(null);\n const [inputHeight, setInputHeight] = useState(80);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [pendingMessage, setPendingMessage] = useState<{\n question: string;\n images?: string[];\n } | null>(null);\n\n const { conversations, currentId, _hasHydrated, hydrate } = useConversationStore();\n const [isMobile, setIsMobile] = useState(false);\n const [drawerOpen, setDrawerOpen] = useState(false);\n const { generateName } = useConversationNameGenerator();\n const { preferences } = usePreferencesStore();\n\n\n // Enhanced UX with auto-scroll and network awareness (after isMobile is defined)\n const { containerRef: chatContainerRef, targetRef: scrollTargetRef, scrollToBottom, getScrollState } = useAutoScroll({\n threshold: 16, // Smaller threshold so the button shows with light upward scrolls\n behavior: \"smooth\",\n isMobile: isMobile,\n });\n const chatContainerEl = chatContainerRef.current;\n const scrollTargetEl = scrollTargetRef.current;\n const { isSlowConnection, connectionQuality, trackRequestStart, trackRequestEnd } = useNetworkStatus();\n \n const [showScrollToBottom, setShowScrollToBottom] = useState(false);\n const [streamBuffer, setStreamBuffer] = useState(\"\");\n const [responseStarted, setResponseStarted] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const initialLogoState = history.length === 0;\n const [logoVisible, setLogoVisible] = useState(initialLogoState);\n const [logoShouldRender, setLogoShouldRender] = useState(initialLogoState);\n\n // Keep previous message slightly visible during the first moments of a new stream\n const streamingGraceUntilRef = useRef<number>(0);\n const GRACE_MS = 450; // duration of scroll grace\n const GRACE_OFFSET_DESKTOP = 28; // px reserved above bottom to keep previous answer visible\n const GRACE_OFFSET_MOBILE = 20;\n\n // Track whether we should follow the stream based on user's position at send time\n const followStreamRef = useRef<boolean>(true);\n const lastSpokenResponseRef = useRef<string | null>(null);\n const previousConversationIdRef = useRef<string | null>(null);\n const logoFadeTimeoutRef = useRef<number | null>(null);\n\n const [branding, setBranding] = useState<{ brandingText?: string, logoBase64?: string } | null>(null);\n const [brandingLoading, setBrandingLoading] = useState(true);\n const isBrandingLoadInProgressRef = useRef(false);\n const logoOnly = history.length === 0 && !brandingLoading;\n\n useEffect(() => {\n const isEmptyConversation = (history?.length ?? 0) === 0;\n const isSending = Boolean(pendingMessage);\n const shouldShowLogo = isEmptyConversation && !isSending;\n\n if (shouldShowLogo) {\n if (logoFadeTimeoutRef.current) {\n window.clearTimeout(logoFadeTimeoutRef.current);\n logoFadeTimeoutRef.current = null;\n }\n\n setLogoShouldRender((prev) => {\n if (prev) return prev;\n return true;\n });\n\n setLogoVisible((prev) => {\n if (prev) return prev;\n return true;\n });\n\n return;\n }\n\n setLogoVisible((prev) => {\n if (!prev) return prev;\n return false;\n });\n\n if (!logoFadeTimeoutRef.current) {\n logoFadeTimeoutRef.current = window.setTimeout(() => {\n setLogoShouldRender(false);\n logoFadeTimeoutRef.current = null;\n }, 500);\n }\n }, [history, pendingMessage]);\n\n useEffect(() => {\n if (!brandingLoading && !themeLoading) {\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n if (brandingLoading || themeLoading) {\n debugLogger.warn(\"Chat: branding/theme load timed out, falling back to defaults\");\n setBrandingLoading(false);\n setThemeLoading(false);\n if (!selectedTheme) {\n setSelectedTheme(\"bandit-dark\");\n }\n }\n }, 2500);\n\n return () => window.clearTimeout(timeoutId);\n }, [brandingLoading, themeLoading, selectedTheme]);\n\n useEffect(() => () => {\n if (logoFadeTimeoutRef.current) {\n window.clearTimeout(logoFadeTimeoutRef.current);\n logoFadeTimeoutRef.current = null;\n }\n }, []);\n\n // Ensure conversation store is hydrated on component mount\n useEffect(() => {\n // When a new stream starts, start a short grace window to avoid snapping to absolute bottom\n if (isStreaming && streamBuffer.trim() === \"\") {\n streamingGraceUntilRef.current = Date.now() + GRACE_MS;\n }\n }, [isStreaming, streamBuffer]);\n\n useEffect(() => {\n if (!isStreaming) return;\n const container = chatContainerRef.current;\n if (!container) return;\n const now = Date.now();\n if (now <= streamingGraceUntilRef.current && followStreamRef.current) {\n const offset = isMobile ? GRACE_OFFSET_MOBILE : GRACE_OFFSET_DESKTOP;\n const targetTop = Math.max(0, container.scrollHeight - container.clientHeight - offset);\n // Use smooth behavior to keep motion gentle\n container.scrollTo({ top: targetTop, behavior: \"smooth\" });\n }\n }, [streamBuffer, isStreaming, isMobile, chatContainerRef]);\n\n useEffect(() => {\n if (!_hasHydrated) {\n debugLogger.info(\"Chat component triggering conversation store hydration\");\n hydrate();\n }\n }, [_hasHydrated, hydrate]);\n\n useEffect(() => {\n const loadBrandingAndTheme = async () => {\n // Prevent concurrent loading\n if (isBrandingLoadInProgressRef.current) {\n debugLogger.warn(\"Branding loading already in progress, skipping\");\n return;\n }\n \n // Check if we're on management page and add delay to avoid conflicts\n const isManagementPage = window.location.pathname.includes('/management');\n if (isManagementPage) {\n debugLogger.info(\"Chat: Detected management page, adding delay before branding load\");\n await new Promise(resolve => setTimeout(resolve, 200));\n \n // Double-check if branding is still not being loaded\n if (isBrandingLoadInProgressRef.current) {\n debugLogger.info(\"Chat: Management branding load detected, skipping chat branding load\");\n return;\n }\n }\n \n isBrandingLoadInProgressRef.current = true;\n \n try {\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }] as const;\n const config = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n \n const brandingConfig = config?.branding;\n\n debugLogger.info(\"Branding load attempt\", {\n hasConfig: !!config,\n hasBrandingObject: !!brandingConfig,\n brandingContent: brandingConfig ? {\n hasText: !!brandingConfig.brandingText,\n hasLogo: !!brandingConfig.logoBase64,\n hasTheme: !!brandingConfig.theme,\n textValue: brandingConfig.brandingText,\n themeValue: brandingConfig.theme\n } : null\n });\n \n let loadedFromIndexedDB = false;\n let cdnBranding: StoredBrandingConfig | null = null;\n \n // NUCLEAR OPTION: If IndexedDB has ANY branding object at all, NEVER touch CDN\n const hasAnyBrandingObject = !!brandingConfig;\n \n // Enhanced protection: also check if any meaningful branding data exists\n const hasAnyBrandingData = brandingConfig && (\n brandingConfig.brandingText || \n brandingConfig.logoBase64 || \n brandingConfig.theme ||\n brandingConfig.hasTransparentLogo !== undefined ||\n brandingConfig.userSaved !== undefined\n );\n \n // Check if there's any evidence of user models (indicating user has used Management)\n const hasUserModels = await indexedDBService.getAll<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n storeConfigs\n );\n const hasCustomContent = hasUserModels.some(entry => \n entry.id !== \"main\" && \n entry.id !== \"deletedModels\" && \n entry.id !== \"preferences\" && \n entry.id !== \"mcpTools\" && \n entry.id !== \"knowledgeDocs\"\n );\n \n // ABSOLUTE NUCLEAR PROTECTION: If there's ANY trace of branding or user activity, skip CDN entirely\n const shouldSkipCDN = hasAnyBrandingObject || hasAnyBrandingData || hasCustomContent;\n \n if (shouldSkipCDN) {\n debugLogger.info(\"🚫 NUCLEAR PROTECTION ACTIVATED - COMPLETELY SKIPPING CDN\", {\n hasAnyBrandingObject,\n hasAnyBrandingData,\n hasCustomContent,\n brandingKeys: brandingConfig ? Object.keys(brandingConfig) : [],\n brandingValues: brandingConfig\n });\n \n // Use whatever is in IndexedDB, even if empty values\n if (brandingConfig) {\n setBranding({\n brandingText: brandingConfig.brandingText || \"\",\n logoBase64: brandingConfig.logoBase64 ?? undefined\n });\n \n if (brandingConfig.brandingText) {\n document.title = brandingConfig.brandingText;\n }\n \n setSelectedTheme(brandingConfig.theme || \"bandit-dark\");\n } else {\n setBranding(null);\n setSelectedTheme(\"bandit-dark\");\n }\n loadedFromIndexedDB = true;\n }\n \n if (!loadedFromIndexedDB) {\n // Enhanced protection: Double-check that we should really load from CDN\n if (shouldSkipCDN) {\n debugLogger.warn(\"🚫 CDN LOAD BLOCKED: Branding protection still active even with !loadedFromIndexedDB\");\n setBranding(null);\n setSelectedTheme(\"bandit-dark\");\n loadedFromIndexedDB = true; // Prevent further CDN attempts\n } else {\n // No meaningful branding in IndexedDB, try to load from CDN config\n debugLogger.info(\"No meaningful branding found in IndexedDB, checking CDN config\", {\n hasConfig: !!config,\n hasBrandingObject: !!brandingConfig,\n brandingKeys: brandingConfig ? Object.keys(brandingConfig) : []\n });\n const packageSettings = usePackageSettingsStore.getState().getSettings();\n \n if (packageSettings?.brandingConfigUrl) {\n try {\n const configResponse = await fetch(packageSettings.brandingConfigUrl);\n const configData: unknown = await configResponse.json();\n if (configData && typeof configData === \"object\" && \"branding\" in configData) {\n const maybeBranding = (configData as { branding?: unknown }).branding;\n if (maybeBranding && typeof maybeBranding === \"object\") {\n cdnBranding = maybeBranding as StoredBrandingConfig;\n }\n }\n } catch (err) {\n debugLogger.warn(\"Failed to load CDN branding config:\", { error: err });\n }\n }\n\n if (cdnBranding) {\n debugLogger.info(\"Loading branding and theme from CDN config\");\n \n // Set branding state\n setBranding({\n brandingText: cdnBranding.brandingText,\n logoBase64: cdnBranding.logoBase64 ?? undefined\n });\n \n // Set document title\n if (cdnBranding.brandingText) {\n document.title = cdnBranding.brandingText;\n }\n \n // Set theme\n setSelectedTheme(cdnBranding.theme || \"bandit-dark\");\n \n // NEVER save CDN branding to IndexedDB if ANY branding already exists\n // This prevents CDN from ever overwriting existing branding\n try {\n // Double-check that no branding exists before saving\n const existingConfig = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n const hasAnyExistingBranding = existingConfig?.branding && (\n existingConfig.branding.brandingText || \n existingConfig.branding.logoBase64 || \n existingConfig.branding.theme\n );\n \n if (!hasAnyExistingBranding) {\n debugLogger.info(\"Saving CDN branding to IndexedDB as absolutely no branding exists\");\n \n // Get current config to preserve any other data\n const currentConfig: StoredBanditConfigRecord = existingConfig ?? { id: \"main\" };\n \n await indexedDBService.put<StoredBanditConfigRecord>(\"banditConfig\", 1, \"config\", {\n ...currentConfig,\n id: \"main\",\n branding: {\n ...currentConfig.branding,\n ...cdnBranding,\n userSaved: false, // Mark as CDN-loaded, not user-saved\n },\n }, storeConfigs);\n \n debugLogger.info(\"CDN branding saved successfully\");\n } else {\n debugLogger.warn(\"SKIPPING CDN save - existing branding detected!\", {\n existingBranding: {\n hasText: !!existingConfig.branding?.brandingText,\n hasLogo: !!existingConfig.branding?.logoBase64,\n hasTheme: !!existingConfig.branding?.theme,\n userSaved: existingConfig.branding?.userSaved\n }\n });\n }\n } catch (putError) {\n debugLogger.warn(\"Failed to save CDN branding to IndexedDB:\", { error: putError });\n }\n } else {\n // Fall back to Bandit defaults\n debugLogger.info(\"Using Bandit default branding and theme\");\n setBranding(null);\n setSelectedTheme(\"bandit-dark\");\n }\n }\n }\n } catch (err) {\n debugLogger.error(\"Failed to load branding and theme from IndexedDB\", {\n error: err instanceof Error ? err.message : String(err),\n });\n // Fallback to default on error\n setBranding(null);\n setSelectedTheme(\"bandit-dark\");\n } finally {\n setThemeLoading(false);\n setBrandingLoading(false);\n isBrandingLoadInProgressRef.current = false;\n }\n };\n\n loadBrandingAndTheme();\n\n // Listen for custom theme change events\n const handleThemeChange = () => {\n debugLogger.info(\"Chat received bandit-theme-changed event - checking if reload needed\");\n \n // Don't reload if branding is already being loaded by another component\n if (isBrandingLoadInProgressRef.current) {\n debugLogger.info(\"Chat: Skipping branding reload - already in progress\");\n return;\n }\n \n // Add a small delay to avoid race conditions with Management component\n setTimeout(() => {\n if (!isBrandingLoadInProgressRef.current) {\n debugLogger.info(\"Chat: Reloading branding after theme change\");\n loadBrandingAndTheme();\n } else {\n debugLogger.info(\"Chat: Skipping delayed branding reload - still in progress\");\n }\n }, 100);\n };\n\n window.addEventListener('bandit-theme-changed', handleThemeChange);\n\n return () => {\n window.removeEventListener('bandit-theme-changed', handleThemeChange);\n };\n }, []);\n\n useEffect(() => {\n if (!chatContainerEl) return;\n const blurInputOnScroll = () => inputRef.current?.blur();\n chatContainerEl.addEventListener(\"scroll\", blurInputOnScroll);\n return () => chatContainerEl.removeEventListener(\"scroll\", blurInputOnScroll);\n }, [chatContainerEl]);\n\n useEffect(() => {\n const handleResize = () => setIsMobile(window.innerWidth <= 768);\n handleResize();\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n const setViewportHeight = () => {\n document.documentElement.style.setProperty(\n \"--vh\",\n `${window.innerHeight * 0.01}px`\n );\n };\n setViewportHeight();\n window.addEventListener(\"resize\", setViewportHeight);\n return () => window.removeEventListener(\"resize\", setViewportHeight);\n }, []);\n\n // Minimal visibility logic: show only when there is scrollable content and not at the bottom\n useEffect(() => {\n if (!chatContainerEl) return;\n\n let rafId: number | null = null;\n const update = () => {\n if (rafId) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n const s = getScrollState();\n setShowScrollToBottom(s.canScroll && !s.isNearBottom);\n });\n };\n\n update();\n // Listen to both native scroll and our custom state-changed event\n chatContainerEl.addEventListener('scroll', update, { passive: true });\n chatContainerEl.addEventListener(SCROLL_STATE_CHANGED_EVENT, update as EventListener);\n return () => {\n if (rafId) cancelAnimationFrame(rafId);\n chatContainerEl.removeEventListener('scroll', update as EventListener);\n chatContainerEl.removeEventListener(SCROLL_STATE_CHANGED_EVENT, update as EventListener);\n };\n }, [chatContainerEl, getScrollState]);\n\n // IntersectionObserver-based visibility: observe the bottom sentinel (robust to padding)\n useEffect(() => {\n if (!chatContainerEl) return;\n\n let observer: IntersectionObserver | null = null;\n let rafId: number | null = null;\n let cancelled = false;\n\n const setup = () => {\n if (cancelled) return;\n const target = scrollTargetRef.current ?? scrollTargetEl;\n if (!target) {\n // Try again on the next frame (child may not be mounted yet)\n rafId = requestAnimationFrame(setup);\n return;\n }\n\n // If the sentinel is on-screen, we're at/near the bottom; otherwise show the button\n observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries;\n const atBottom = entry?.isIntersecting ?? false;\n const s = getScrollState();\n setShowScrollToBottom(s.canScroll && !atBottom);\n },\n {\n root: chatContainerEl,\n threshold: 0.0,\n // Account for bottom padding (inputHeight) so \"near bottom\" counts as bottom\n rootMargin: `0px 0px ${Math.max(24, inputHeight + 48)}px 0px`,\n }\n );\n\n observer.observe(target);\n };\n\n rafId = requestAnimationFrame(setup);\n return () => {\n cancelled = true;\n if (rafId) cancelAnimationFrame(rafId);\n if (observer) observer.disconnect();\n };\n }, [chatContainerEl, scrollTargetEl, scrollTargetRef, getScrollState, inputHeight, history.length]);\n\n // Also update scroll button when content changes - but avoid during transitions\n useEffect(() => {\n // If we're transitioning between loading and content, delay the scroll state update\n const isTransitioning = isStreaming || (streamBuffer.trim() === \"\");\n const delay = isTransitioning ? 400 : 100; // Wait for transitions to complete\n \n const timer = setTimeout(() => {\n const scrollState = getScrollState();\n setShowScrollToBottom(scrollState.canScroll && !scrollState.isNearBottom);\n }, delay); // Small delay to let DOM update\n\n return () => clearTimeout(timer);\n }, [history, streamBuffer, getScrollState, isStreaming]);\n\n // Auto-scroll when new content is added - with smarter completion behavior\n useLayoutEffect(() => {\n const scrollState = getScrollState();\n const now = Date.now();\n\n if (isStreaming && scrollState.shouldAutoScroll && followStreamRef.current) {\n // During the initial grace window, avoid snapping to bottom so the previous answer stays visible\n if (now <= streamingGraceUntilRef.current) {\n return; // Grace effect handles offset scrolling\n }\n // After grace: follow the stream to bottom\n const scrollTimer = setTimeout(() => {\n scrollToBottom();\n }, 50);\n return () => clearTimeout(scrollTimer);\n } else if (!isStreaming && scrollState.shouldAutoScroll) {\n // When streaming completes: wait for transition to complete before scrolling\n const scrollTimer = setTimeout(() => {\n const container = chatContainerRef.current;\n if (container && history.length > 0) {\n const lastMessage = history[history.length - 1];\n const isLongResponse = lastMessage?.answer && lastMessage.answer.length > 500;\n // Decide whether to follow the stream for the next turn based on current position\n followStreamRef.current = getScrollState().isNearBottom;\n\n if (isMobile) {\n // Mobile: Always scroll to show input on completion (better UX for thumb typing)\n scrollToBottom();\n } else if (!isLongResponse) {\n // Desktop: Auto-scroll for short responses\n scrollToBottom();\n }\n // For long responses on desktop: let user decide (don't auto-scroll)\n }\n \n // Update button visibility after auto-scroll decision\n if (!isMobile) {\n setTimeout(() => {\n const s = getScrollState();\n setShowScrollToBottom(s.canScroll && !s.isNearBottom);\n }, 100);\n }\n }, 350); // Wait for transition to complete\n return () => clearTimeout(scrollTimer);\n }\n // else: do nothing\n }, [history, isStreaming, scrollToBottom, getScrollState, isMobile, chatContainerRef]);\n\n useEffect(() => {\n const observer = new ResizeObserver(() => {\n if (inputContainerRef.current)\n setInputHeight(inputContainerRef.current.offsetHeight);\n });\n if (inputContainerRef.current) {\n observer.observe(inputContainerRef.current);\n setInputHeight(inputContainerRef.current.offsetHeight);\n }\n return () => observer.disconnect();\n }, []);\n useEffect(() => {\n if (!hydrated || !_hasHydrated) return;\n\n if (currentId === null) {\n useAIQueryStore.setState({ history: [] });\n setInputValue(\"\");\n setResponse(\"\");\n setComponentStatus(\"Idle\");\n previousConversationIdRef.current = null;\n return;\n }\n\n const match = conversations.find((c) => c.id === currentId);\n if (!match) {\n return;\n }\n\n const conversationChanged = previousConversationIdRef.current !== match.id;\n\n useAIQueryStore.setState({ history: match.history });\n\n if (conversationChanged) {\n previousConversationIdRef.current = match.id;\n\n // Reset scroll button state when switching conversations\n setShowScrollToBottom(false);\n\n setInputValue(\"\");\n setResponse(\"\");\n setComponentStatus(\"Idle\");\n setLogoVisible(true); // Explicitly show the logo when a new conversation starts or is hydrated\n\n // Update inputHeight in case of hard reload\n if (inputContainerRef.current) {\n setInputHeight(inputContainerRef.current.offsetHeight);\n }\n\n // Ensure scroll after layout on conversation switch or hard reload\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n scrollToBottom();\n // Update scroll button state after conversation loads and scrolls\n setTimeout(() => {\n const scrollState = getScrollState();\n setShowScrollToBottom(scrollState.canScroll && !scrollState.isNearBottom);\n }, 150); // Allow time for scroll animation to complete\n });\n });\n return;\n }\n\n // For same conversation updates, keep the previous id reference but do not clear the input\n previousConversationIdRef.current = match.id;\n }, [\n hydrated,\n _hasHydrated,\n currentId,\n conversations,\n scrollToBottom,\n getScrollState,\n setInputValue,\n setResponse,\n setComponentStatus\n ]);\n\n // Debug conversation store state\n useEffect(() => {\n debugLogger.info(\"Chat component conversation state\", {\n hasHydrated: _hasHydrated,\n conversationCount: conversations.length,\n currentId,\n firstFewConversations: conversations.slice(0, 3).map(c => ({ id: c.id, name: c.name, historyLength: c.history.length })),\n storeState: \"main-chat\"\n });\n }, [_hasHydrated, conversations, currentId]);\n\n // Initial scroll button state check after component fully loads\n useEffect(() => {\n if (!_hasHydrated || !chatContainerEl) return;\n\n // Sync via rAF to catch layout after content renders\n let rafId: number | null = null;\n const sync = () => {\n rafId = requestAnimationFrame(() => {\n const scrollState = getScrollState();\n setShowScrollToBottom(scrollState.canScroll && !scrollState.isNearBottom);\n });\n };\n sync();\n return () => { if (rafId) cancelAnimationFrame(rafId); };\n }, [_hasHydrated, chatContainerEl, getScrollState, history.length]);\n\n const aiProvider = useAIProvider({\n overrideComponentStatus: setComponentStatus,\n setIsSubmitting,\n setIsStreaming,\n setResponseStarted,\n setResponse,\n setStreamBuffer,\n setPreviousQuestion,\n addHistory,\n setInputValue,\n setPastedImages,\n setPendingMessage,\n setLogoVisible,\n inputRef,\n isMobile,\n history,\n onError: (error) => {\n // Use the notification service to handle HTTP errors properly\n notificationService?.handleHttpError(error);\n },\n });\n\n const handleStop = useCallback(() => {\n try {\n aiProvider.cancel();\n } catch (error) {\n debugLogger.warn(\"AI provider cancel failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }, [aiProvider]);\n\n const handleVoiceInterrupt = useCallback(() => {\n try {\n ttsStop();\n } catch (error) {\n debugLogger.warn(\"Voice interrupt failed to stop TTS hook\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n try {\n stopTTS();\n } catch (error) {\n debugLogger.warn(\"Voice interrupt failed to stop streaming TTS\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n if (isStreaming) {\n handleStop();\n }\n }, [ttsStop, isStreaming, handleStop]);\n\n const handleSend = useCallback(\n (question: string, images: string[], displayQuestion?: string) => {\n const requestStartTime = trackRequestStart();\n \n // Immediate feedback - set pending message and loading state right away\n const questionForDisplay = displayQuestion || question;\n const pendingImages = images.length > 0 ? [...images] : undefined;\n setPendingMessage({ question: questionForDisplay, images: pendingImages });\n setIsStreaming(true); // Show skeleton immediately\n setResponseStarted(true); // Show loading feedback\n setStreamBuffer(\"\"); // Clear any previous buffer\n \n // Immediately add placeholder entry to history for smooth UX\n const { addToCurrent } = useConversationStore.getState();\n const placeholderImages = pendingImages ? [...pendingImages] : undefined;\n addToCurrent({\n question: questionForDisplay,\n answer: \"...\",\n images: placeholderImages,\n placeholder: true,\n rawQuestion: question,\n });\n \n const getCurrentModel = useModelStore.getState().getCurrentModel;\n const systemPrompt =\n getCurrentModel()?.systemPrompt ?? \"You are a helpful assistant.\";\n\n const { currentId, conversations, createConversation, renameConversation } =\n useConversationStore.getState();\n const existing = conversations.find((c) => c.id === currentId);\n\n if (!existing) {\n generateName(question).then((name) => {\n createConversation(name || question);\n\n setLogoVisible(true);\n\n setTimeout(() => {\n const newCurrentId = useConversationStore.getState().currentId;\n if (!newCurrentId) return;\n\n setResponse(\"\");\n \n // Add placeholder entry for new conversation too\n const { addToCurrent: addToNew } = useConversationStore.getState();\n const newPlaceholderImages = pendingImages ? [...pendingImages] : undefined;\n addToNew({\n question: questionForDisplay,\n answer: \"...\",\n images: newPlaceholderImages,\n placeholder: true,\n rawQuestion: question,\n });\n \n const providerImages = pendingImages ? [...pendingImages] : [];\n aiProvider(systemPrompt, question, providerImages);\n }, 0);\n });\n return;\n }\n\n // If the conversation is \"New Conversation\", rename it after first user message\n if (existing.name === \"New Conversation\") {\n generateName(question).then((newName) => {\n if (newName) {\n renameConversation(existing.id, newName);\n }\n });\n }\n \n // Decide whether to follow the stream for this message based on current position\n followStreamRef.current = getScrollState().isNearBottom;\n\n // Smart scrolling: on mobile, scroll to show AI response area; on desktop, scroll near-bottom (grace)\n if (isMobile) {\n // On mobile, scroll to position the AI response (skeleton) at the top of the viewport\n setTimeout(() => {\n const container = chatContainerRef.current;\n if (container) {\n // Wait for DOM to update with the new pending message\n setTimeout(() => {\n // Strategy: Find the AI response container and position it at the top of viewport\n // The skeleton appears in the last AIResponseTextField, so scroll to show that\n const containerHeight = container.clientHeight;\n const scrollHeight = container.scrollHeight;\n \n // Calculate position to show the AI response area where skeleton will appear\n // We want the AI response container to be at the top of the viewport\n // Leave a small buffer (about 50px) from the very top for breathing room\n const topBuffer = 50; \n const targetPosition = Math.max(0, scrollHeight - containerHeight + topBuffer);\n \n if (followStreamRef.current) {\n container.scrollTo({\n top: targetPosition,\n behavior: \"smooth\"\n });\n }\n }, 100); // Delay for DOM updates\n }\n }, 50);\n } else {\n // On desktop, avoid snapping to absolute bottom at stream start\n // Respect the grace offset so the previous answer remains visible briefly\n setTimeout(() => {\n const container = chatContainerRef.current;\n if (container) {\n const offset = isMobile ? 20 : 28; // mirror GRACE_OFFSETs\n const targetTop = Math.max(0, container.scrollHeight - container.clientHeight - offset);\n if (followStreamRef.current) {\n container.scrollTo({ top: targetTop, behavior: \"smooth\" });\n }\n } else {\n // Fallback\n if (followStreamRef.current) scrollToBottom();\n }\n \n // Update button state after scroll\n setTimeout(() => {\n const scrollState = getScrollState();\n setShowScrollToBottom(scrollState.canScroll && !scrollState.isNearBottom);\n }, 120);\n }, 50);\n }\n \n setResponse(\"\");\n\n const providerImages = pendingImages ? [...pendingImages] : [];\n aiProvider(systemPrompt, question, providerImages);\n },\n [\n aiProvider,\n chatContainerRef,\n generateName,\n getScrollState,\n isMobile,\n scrollToBottom,\n setIsStreaming,\n setLogoVisible,\n setPendingMessage,\n setResponse,\n setResponseStarted,\n setShowScrollToBottom,\n setStreamBuffer,\n trackRequestStart\n ]\n );\n\n const handleVoiceTranscription = useCallback(\n (text: string) => {\n const cleaned = text.trim();\n if (!cleaned) {\n return;\n }\n\n setInputValue(\"\");\n setPastedImages([]);\n handleSend(cleaned, [], cleaned);\n },\n [handleSend, setInputValue, setPastedImages]\n );\n\n useVoiceMode({\n onTranscription: handleVoiceTranscription,\n onInterrupt: handleVoiceInterrupt,\n onError: (message) => notificationService?.showError?.(message),\n });\n\n useEffect(() => {\n const previouslyEnabled = previousVoiceModeEnabledRef.current;\n previousVoiceModeEnabledRef.current = isVoiceModeEnabled;\n\n if (!previouslyEnabled && isVoiceModeEnabled) {\n const latest = historyRef.current[historyRef.current.length - 1];\n lastSpokenResponseRef.current = latest?.answer ?? null;\n }\n\n if (previouslyEnabled && !isVoiceModeEnabled) {\n lastSpokenResponseRef.current = null;\n try {\n ttsStop();\n } catch (error) {\n debugLogger.warn(\"Voice mode disable failed to stop TTS hook\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n try {\n stopTTS();\n } catch (error) {\n debugLogger.warn(\"Voice mode disable failed to stop streaming TTS\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }, [isVoiceModeEnabled, ttsStop]);\n\n useEffect(() => {\n if (!isVoiceModeEnabled || !isStreaming) {\n return;\n }\n\n try {\n ttsStop();\n } catch (error) {\n debugLogger.warn(\"Voice mode stream start failed to stop TTS hook\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n try {\n stopTTS();\n } catch (error) {\n debugLogger.warn(\"Voice mode stream start failed to stop streaming TTS\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n lastSpokenResponseRef.current = null;\n }, [isStreaming, isVoiceModeEnabled, ttsStop]);\n\n useEffect(() => {\n if (!isVoiceModeEnabled) {\n lastSpokenResponseRef.current = null;\n return;\n }\n\n if (isStreaming) {\n return;\n }\n\n if (!isTTSAvailable || history.length === 0) {\n return;\n }\n\n const latest = history[history.length - 1];\n if (!latest?.answer || latest.answer === \"...\" || !latest.answer.trim()) {\n return;\n }\n\n if (lastSpokenResponseRef.current === latest.answer) {\n return;\n }\n\n const sanitizedAnswer = sanitizeForTTS(latest.answer);\n if (!sanitizedAnswer) {\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n await ttsSpeak(sanitizedAnswer, { useStreaming: true, useRealtime: true });\n if (!cancelled) {\n lastSpokenResponseRef.current = latest.answer;\n }\n } catch (error) {\n if (!cancelled) {\n debugLogger.error(\"Voice mode auto playback failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [history, isStreaming, isVoiceModeEnabled, isTTSAvailable, ttsSpeak]);\n\n const handleModelChange = useCallback(\n (modelId: string) => {\n setSelectedModel(modelId);\n },\n [setSelectedModel]\n );\n\n const handleVoiceChange = useCallback(async (voiceId: string) => {\n // Stop any current TTS playback FIRST\n ttsStop();\n stopTTS(); // Extra insurance against voice mixing\n \n // Then set the new voice\n setSelectedVoice(voiceId);\n \n const voiceName = voiceId.split(\"-\")[1];\n const defaultModel = usePackageSettingsStore.getState().settings?.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 // Small delay to ensure TTS cleanup is complete and new voice is set\n await new Promise(resolve => setTimeout(resolve, 150));\n \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 }, [availableModels, selectedModel, isTTSAvailable, ttsStop, ttsSpeak, setSelectedVoice]);\n\n const handleScrollToBottomClick = () => {\n scrollToBottom();\n // Proactively re-check visibility on the next frame(s)\n const container = chatContainerRef.current;\n if (container) {\n let frames = 0;\n const pump = () => {\n frames += 1;\n const s = getScrollState();\n setShowScrollToBottom(s.canScroll && !s.isNearBottom);\n if (frames < 6) requestAnimationFrame(pump);\n };\n requestAnimationFrame(pump);\n }\n };\n\n\n\n\n if (!hydrated || brandingLoading || themeLoading) {\n return (\n <ThemeProvider theme={banditTheme}>\n <CssBaseline />\n <Box\n sx={(theme) => ({\n minHeight: \"100dvh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexDirection: \"column\",\n gap: 1.5,\n bgcolor: theme.palette.chat.shell,\n color: theme.palette.text.primary\n })}\n >\n <CircularProgress size={32} thickness={4} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n Preparing your workspace...\n </Typography>\n </Box>\n </ThemeProvider>\n );\n }\n\n const userHasAccess =\n playgroundBypassAccess ||\n ossMode ||\n claims?.roles?.includes(\"super-user\") ||\n claims?.roles?.includes(\"admin\");\n\n if (!userHasAccess) {\n return (\n <ThemeProvider theme={banditTheme}>\n <CssBaseline />\n <UnderReview />\n </ThemeProvider>\n );\n }\n\n return (\n <ThemeProvider theme={banditTheme}>\n <CssBaseline />\n <Box\n sx={(theme) => ({\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100dvh\",\n maxHeight: \"100dvh\",\n overflow: \"hidden\",\n bgcolor: theme.palette.chat.shell,\n color: theme.palette.text.primary,\n position: \"fixed\",\n top: 0,\n left: drawerOpen && !isMobile ? \"340px\" : 0,\n width: drawerOpen && !isMobile ? \"calc(100vw - 340px)\" : \"100vw\",\n zIndex: 0,\n transition: \"left 0.3s ease-in-out, width 0.3s ease-in-out\",\n })}\n >\n <ChatAppBar\n availableModels={availableModels}\n handleModelChange={handleModelChange}\n selectedVoice={selectedVoice}\n availableVoices={availableVoices}\n handleVoiceChange={handleVoiceChange}\n drawerOpen={drawerOpen}\n setDrawerOpen={setDrawerOpen}\n />\n <Box\n ref={chatContainerRef}\n sx={{\n flex: 1,\n overflowY: logoOnly ? \"hidden\" : \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n px: isMobile ? 1 : 2, // Reduce padding on mobile for better width utilization\n pb: logoOnly ? 0 : `${inputHeight + 24}px`,\n maxHeight: isMobile ? \"calc(var(--vh, 1vh) * 100)\" : \"100%\",\n WebkitOverflowScrolling: \"touch\",\n overscrollBehavior: \"contain\",\n position: \"relative\",\n scrollbarWidth: \"none\",\n msOverflowStyle: \"none\",\n \"&::-webkit-scrollbar\": { display: \"none\" },\n }}\n >\n <Box\n sx={{\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2,\n pt: 2,\n }}\n >\n {logoShouldRender && !brandingLoading && (\n branding?.logoBase64 ? (\n <CustomLogo visible={logoVisible} atTop />\n ) : (\n <BanditChatLogo visible={logoVisible} atTop />\n )\n )}\n <Box\n sx={{\n margin: \"0 auto\",\n width: \"100%\",\n maxWidth: isMobile ? \"100%\" : \"768px\",\n flexShrink: 0,\n px: isMobile ? 0 : 0,\n }}\n >\n <ChatMessages\n isStreaming={isStreaming}\n history={history}\n pendingMessage={pendingMessage}\n streamBuffer={streamBuffer}\n isMobile={isMobile}\n scrollTargetRef={scrollTargetRef}\n responseStarted={responseStarted}\n isNetworkSlow={isSlowConnection}\n showInstantFeedback={true}\n selectedModel={selectedModel}\n availableModels={availableModels}\n />\n </Box>\n </Box>\n </Box>\n\n {showScrollToBottom && (\n <ChatScrollToBottomButton\n inputHeight={inputHeight}\n drawerOpen={drawerOpen}\n isMobile={isMobile}\n onClick={handleScrollToBottomClick}\n />\n )}\n\n {history.length === 0 && componentStatus !== \"Loading\" && !isMobile && (\n <Box\n sx={(theme) => ({\n position: \"absolute\",\n bottom: `${inputHeight + 160}px`,\n textAlign: \"center\",\n width: \"100%\",\n color: theme.palette.mode === \"light\" ? \"#555\" : \"#ccc\",\n fontSize: \"0.95rem\",\n fontWeight: 500,\n fontStyle: \"italic\",\n opacity: 0.9,\n textShadow:\n theme.palette.mode === \"dark\"\n ? \"0 0 4px rgba(0,0,0,0.4)\"\n : \"0 0 2px rgba(255,255,255,0.4)\",\n transition: \"opacity 0.3s ease\",\n pointerEvents: \"none\",\n })}\n >\n </Box>\n )}\n <Box\n sx={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n margin: \"auto\",\n width: \"100vw\",\n maxWidth: \"768px\",\n }}\n >\n <Box sx={{ flex: \"1 1 auto\" }}></Box>\n {history.length === 0 && componentStatus !== \"Loading\" && !pendingMessage && preferences.chatSuggestionsEnabled && (\n <Box sx={{ marginBottom: \"20px\" }}>\n <QuerySuggestionPicker onSend={handleSend} inputHeight={inputHeight} />\n </Box>\n )}\n\n <ChatInput\n inputValue={inputValue}\n setInputValue={setInputValue}\n pastedImages={pastedImages}\n setPastedImages={setPastedImages}\n inputRef={inputRef}\n inputContainerRef={inputContainerRef}\n isMobile={isMobile}\n inputHeight={inputHeight}\n setInputHeight={setInputHeight}\n isSubmitting={isSubmitting}\n isStreaming={isStreaming}\n onSend={handleSend}\n onStop={handleStop}\n selectedModel={selectedModel}\n availableModels={availableModels}\n handleModelChange={handleModelChange}\n selectedVoice={selectedVoice}\n availableVoices={availableVoices}\n handleVoiceChange={handleVoiceChange}\n />\n </Box>\n\n {preferences.feedbackEnabled && !isMobile && (\n <FeedbackButton \n fullScreen={false}\n zIndex={1300}\n feedbackEmail={packageSettings?.feedbackEmail}\n absolute={true}\n position={{\n bottom: 20,\n right: 20,\n }}\n />\n )}\n\n {/* Connection status indicator */}\n <ConnectionStatus position=\"top\" showWhenGood={false} />\n\n </Box>\n </ThemeProvider>\n );\n};\n\nconst Chat = () => {\n const featureFlag = useFeatureFlag();\n const { isOSSMode } = featureFlag;\n const packageSettings = usePackageSettingsStore((state) => state.settings);\n\n if (!packageSettings) {\n return null;\n }\n\n const ossConfigured = !packageSettings.featureFlags?.subscriptionType;\n const allowUnauthenticated = isOSSMode() || ossConfigured;\n const playgroundBypassAuth = packageSettings.playgroundBypassAuth;\n const isPlaygroundRoute = typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const bypassAuth = playgroundBypassAuth || isPlaygroundRoute;\n debugLogger.info(\"Chat authentication gate\", {\n ossConfigured,\n isOSSMode: isOSSMode(),\n tier: featureFlag.getEvaluation()?.tier,\n hasToken: authenticationService.isAuthenticated(),\n playgroundBypassAuth,\n isPlaygroundRoute,\n bypassAuth,\n });\n\n if (!allowUnauthenticated && !bypassAuth && !authenticationService.isAuthenticated()) {\n debugLogger.debug(\"User is not authenticated, redirecting to login\");\n return <Navigate to=\"/login\" replace />;\n }\n\n return <ChatContent />;\n};\n\nexport default Chat;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-33AD-0DA2DC\nconst __banditFingerprint_chat_customlogotsx = 'BL-FP-2A41D9-C05C';\nconst __auditTrail_chat_customlogotsx = 'BL-AU-MGOIKVV0-YYER';\n// File: custom-logo.tsx | Path: src/chat/custom-logo.tsx | Hash: 33adc05c\n\nimport React, { useEffect } from \"react\";\nimport { Box, Avatar, useMediaQuery } from \"@mui/material\";\nimport { useTheme } from \"@mui/material/styles\";\nimport \"./chat.css\";\nimport brandingService from \"../services/branding/brandingService\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { detectTransparency } from \"../util\";\n\ninterface BanditLogoProps {\n visible: boolean;\n atTop?: boolean;\n}\n\nconst Logo: React.FC<BanditLogoProps> = ({ visible, atTop = false }) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down(\"sm\"));\n\n const [logoBase64, setLogoBase64] = React.useState<string | null>(null);\n const [hasTransparentLogo, setHasTransparentLogo] = React.useState<boolean>(true);\n const [loading, setLoading] = React.useState(true);\n\n useEffect(() => {\n const loadBranding = async () => {\n try {\n const brandingData = await brandingService.getBranding();\n if (brandingData) {\n setLogoBase64(brandingData.logoBase64 || null);\n // If transparency was not detected earlier, re-check to avoid forcing circle framing\n if (brandingData.logoBase64) {\n try {\n const detected = await detectTransparency(brandingData.logoBase64);\n const isPng = brandingData.logoBase64.startsWith(\"data:image/png\");\n // Prefer detection/PNG, even if stored flag was false\n const finalTransparent = detected || isPng || brandingData.hasTransparentLogo === true;\n setHasTransparentLogo(finalTransparent);\n } catch {\n const isPng = brandingData.logoBase64.startsWith(\"data:image/png\");\n const finalTransparent = brandingData.hasTransparentLogo === true || isPng;\n setHasTransparentLogo(finalTransparent);\n }\n } else {\n setHasTransparentLogo(brandingData.hasTransparentLogo ?? true);\n }\n }\n } catch (e) {\n debugLogger.error(\"Failed to load branding from service\", { error: e });\n } finally {\n setLoading(false);\n }\n };\n loadBranding();\n }, []);\n\n return (\n logoBase64 &&\n <>\n {loading ? null : hasTransparentLogo !== false ? (\n <Box\n component=\"img\"\n src={logoBase64}\n alt=\"Custom Logo\"\n className={`logo-container ${visible ? \"fade-in\" : \"fade-out\"} logo-animated`}\n sx={{\n width: isMobile ? \"80vw\" : \"60vw\",\n maxWidth: 600,\n aspectRatio: \"1 / 1\",\n margin: \"0 auto\",\n mt: atTop ? 2 : 6,\n display: \"block\"\n }}\n />\n ) : (\n <Avatar\n src={logoBase64}\n variant=\"circular\"\n className={`logo-container ${visible ? \"fade-in\" : \"fade-out\"} logo-animated`}\n sx={{\n width: isMobile ? \"50vw\" : \"400px\",\n height: isMobile ? \"50vw\" : \"400px\",\n maxWidth: 400,\n maxHeight: 400,\n aspectRatio: \"1 / 1\",\n bgcolor: theme.palette.background.paper,\n margin: \"0 auto\",\n mt: atTop ? 2 : 6,\n boxShadow: \"0px 8px 24px rgba(0,0,0,0.3)\",\n objectFit: \"cover\",\n }}\n />\n )}\n </>\n );\n};\n\nexport default Logo;\n","import styleInject from '#style-inject';styleInject(\".typing-only {\\n display: inline-flex;\\n gap: 0.4rem;\\n padding: 0;\\n background: transparent;\\n border-radius: 999px;\\n box-shadow: none;\\n}\\n.typing-only .dot {\\n width: 6px;\\n height: 6px;\\n background: #a78bfa;\\n border-radius: 50%;\\n animation: bounce 1.3s infinite ease-in-out;\\n}\\n.typing-only .dot:nth-child(2) {\\n animation-delay: 0.2s;\\n}\\n.typing-only .dot:nth-child(3) {\\n animation-delay: 0.4s;\\n}\\n@keyframes bounce {\\n 0%, 80%, 100% {\\n transform: translateY(0);\\n opacity: 0.3;\\n }\\n 40% {\\n transform: translateY(-6px);\\n opacity: 1;\\n }\\n}\\n@keyframes float {\\n 0% {\\n transform: translateY(0);\\n }\\n 50% {\\n transform: translateY(-8px);\\n }\\n 100% {\\n transform: translateY(0);\\n }\\n}\\n.logo-animated {\\n animation: pulseBandit 4s infinite ease-in-out;\\n transition: transform 0.3s ease-in-out;\\n}\\n@keyframes pulseBandit {\\n 0% {\\n transform: scale(1) rotate(0deg);\\n opacity: 0.85;\\n }\\n 50% {\\n transform: scale(1.05) rotate(1deg);\\n opacity: 1;\\n }\\n 100% {\\n transform: scale(1) rotate(0deg);\\n opacity: 0.85;\\n }\\n}\\n.logo-container {\\n transition: opacity 0.5s ease, transform 0.5s ease;\\n}\\n.fade-in {\\n opacity: 1;\\n transform: scale(1);\\n}\\n.fade-out {\\n opacity: 0;\\n transform: translateY(-16px) scale(0.95);\\n}\\n@keyframes fadeOut {\\n to {\\n opacity: 0;\\n transform: translateY(-5px);\\n visibility: hidden;\\n }\\n}\\n\")","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-22A7-982C6E\nconst __banditFingerprint_chat_chatscrolltobottombuttontsx = 'BL-FP-4E93B8-6C94';\nconst __auditTrail_chat_chatscrolltobottombuttontsx = 'BL-AU-MGOIKVUX-MLTK';\n// File: chat-scroll-to-bottom-button.tsx | Path: src/chat/chat-scroll-to-bottom-button.tsx | Hash: 22a76c94\n\nimport React from \"react\";\nimport { IconButton } from \"@mui/material\";\nimport ArrowDownwardIcon from \"@mui/icons-material/ArrowDownward\";\n\ninterface Props {\n inputHeight: number;\n onClick: () => void;\n drawerOpen?: boolean;\n isMobile?: boolean;\n}\n\nconst ChatScrollToBottomButton: React.FC<Props> = ({ \n inputHeight, \n onClick, \n drawerOpen = false, \n isMobile = false \n}) => {\n const verticalBuffer = isMobile ? 28 : 48;\n const bottomOffset = Math.max(inputHeight + verticalBuffer, verticalBuffer + 64);\n\n return (\n <IconButton\n onClick={onClick}\n sx={{\n position: \"fixed\",\n left: drawerOpen && !isMobile ? \"calc(50% + 170px)\" : \"50%\",\n transform: \"translateX(-50%)\",\n bottom: bottomOffset,\n bgcolor: (theme) => theme.palette.background.paper,\n color: (theme) => theme.palette.text.primary,\n border: \"1px solid\",\n borderColor: (theme) => theme.palette.divider,\n zIndex: (theme) => Math.max(theme.zIndex.modal + 1, 1400),\n boxShadow: 3,\n transition: \"bottom 0.25s ease, left 0.3s ease-in-out, transform 0.2s ease\",\n \"&:hover\": {\n bgcolor: (theme) => theme.palette.action.hover,\n },\n \"&:active\": {\n transform: \"translateX(-50%) translateY(1px)\"\n }\n }}\n >\n <ArrowDownwardIcon sx={{ color: \"inherit\" }} />\n </IconButton>\n );\n};\n\nexport default ChatScrollToBottomButton;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-C315-723983\nconst __banditFingerprint_chat_banditchatlogotsx = 'BL-FP-B03B6D-55C4';\nconst __auditTrail_chat_banditchatlogotsx = 'BL-AU-MGOIKVUW-H7IF';\n// File: bandit-chat-logo.tsx | Path: src/chat/bandit-chat-logo.tsx | Hash: c31555c4\n\nimport React, { useEffect, useState } from \"react\";\nimport { useTheme } from \"@mui/material/styles\";\nconst darkLogo = \"https://cdn.burtson.ai/logos/bandit-ai-logo-simple.png\";\nconst lightLogo = \"https://cdn.burtson.ai/logos/bandit-ai-logo-simple-alt.png\";\n\ninterface BanditChatLogoProps {\n atTop?: boolean;\n visible?: boolean;\n}\n\nconst BanditChatLogo: React.FC<BanditChatLogoProps> = ({ atTop = false, visible = false }) => {\n const theme = useTheme();\n const logoUrl = theme.palette.mode === \"light\" ? lightLogo : darkLogo;\n const [isVisible, setIsVisible] = useState(false);\n\n useEffect(() => {\n if (visible) {\n const timeout = setTimeout(() => setIsVisible(true), 50);\n return () => clearTimeout(timeout);\n }\n\n setIsVisible(false);\n }, [visible]);\n\n const backgroundStyle = { backgroundImage: `url(${logoUrl})` };\n const className = `bandit-logo ${isVisible ? \"bandit-logo-visible\" : \"bandit-logo-hidden\"}`;\n\n return (\n <div className=\"bandit-logo-container\" style={atTop ? { alignItems: 'flex-start' } : undefined}>\n <div\n className={className}\n style={{\n ...backgroundStyle,\n ...(atTop ? { height: '40vh', marginTop: '16px' } : {}),\n }}\n />\n </div>\n );\n};\nexport default BanditChatLogo;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-0913-A560CB\nconst __banditFingerprint_chat_chatmessagestsx = 'BL-FP-2C7887-6AEC';\nconst __auditTrail_chat_chatmessagestsx = 'BL-AU-MGOIKVUX-4EHG';\n// File: chat-messages.tsx | Path: src/chat/chat-messages.tsx | Hash: 09136aec\n\nimport React from \"react\";\nimport { Box } from \"@mui/material\";\nimport AIResponseTextField from \"../modals/chat-modal/ai-response-text-field\";\nimport StreamingMarkdown from \"../components/StreamingMarkdown\";\nimport { KnowledgeDoc } from \"../store/knowledgeStore\";\nimport { HistoryEntry } from \"../store/aiQueryStore\";\nimport { useConversationStore } from \"../store/conversationStore\";\nimport type { BanditPersonality } from \"../store/modelStore\";\n\ninterface ChatMessagesProps {\n history: HistoryEntry[];\n pendingMessage: {\n question: string;\n images?: string[];\n } | null;\n streamBuffer: string;\n isMobile: boolean;\n scrollTargetRef: React.RefObject<HTMLDivElement>;\n responseStarted: boolean;\n isStreaming: boolean;\n isNetworkSlow?: boolean;\n showInstantFeedback?: boolean;\n selectedModel?: string;\n availableModels?: BanditPersonality[];\n}\n\ntype SourceFileCandidate = KnowledgeDoc & { chunks?: string[] } & Record<string, unknown>;\n\nconst ChatMessages: React.FC<ChatMessagesProps> = ({\n pendingMessage,\n streamBuffer,\n isMobile,\n scrollTargetRef,\n responseStarted,\n isStreaming,\n isNetworkSlow = false,\n showInstantFeedback = true,\n selectedModel,\n availableModels,\n}) => {\n void availableModels;\n const { currentId, conversations } = useConversationStore();\n const history = conversations.find((c) => c.id === currentId)?.history ?? [];\n\n const lastIndex = history.length - 1;\n const hasActivePlaceholder = lastIndex >= 0 && history[lastIndex]?.answer === \"...\";\n\n if (!responseStarted && !pendingMessage && history.length === 0) return null;\n\n return (\n <Box sx={{ px: isMobile ? 0 : 0, pt: \"100px\", display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n {/* Instant feedback disabled - was interfering with loading indicator */}\n\n {history.map((entry, index) => {\n const isLast = index === lastIndex;\n const isPlaceholder = entry.answer === \"...\";\n\n const showLoader = isLast && isStreaming && streamBuffer.trim() === \"\";\n const content = isLast\n ? (isStreaming ? (streamBuffer || \"\") : (isPlaceholder ? \"\" : entry.answer))\n : entry.answer;\n\n const rawSources = entry.sourceFiles as SourceFileCandidate[] | undefined;\n const sourceSummaries = rawSources\n ? rawSources\n .filter((doc) => doc && typeof doc.name === \"string\" && doc.name.trim())\n .map((doc) => ({ id: doc.id || doc.name, name: doc.name.trim() }))\n : undefined;\n\n const responseNode = (\n <Box\n sx={{\n minHeight: isLast ? (isMobile ? \"80px\" : \"60px\") : undefined,\n position: \"relative\",\n overflow: \"hidden\",\n transition: \"min-height 0.25s cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {/* Loader stays mounted but only visible for the last item during pre-first-token */}\n <Box\n sx={{\n position: showLoader ? \"static\" : \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n opacity: showLoader ? 1 : 0,\n transform: showLoader ? \"translateY(0)\" : \"translateY(-6px)\",\n transition: \"all 220ms cubic-bezier(0.4, 0, 0.2, 1)\",\n pointerEvents: showLoader ? \"auto\" : \"none\",\n zIndex: showLoader ? 1 : 0,\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", minHeight: \"40px\", pl: 2 }}>\n <div className=\"typing-only\">\n <span className=\"dot\" />\n <span className=\"dot\" />\n <span className=\"dot\" />\n </div>\n </Box>\n </Box>\n\n {/* Streaming or final content, same component for all entries to avoid swaps */}\n <Box\n sx={{\n position: showLoader ? \"absolute\" : \"static\",\n top: 0,\n left: 0,\n right: 0,\n opacity: showLoader ? 0 : 1,\n transform: showLoader ? \"translateY(6px)\" : \"translateY(0)\",\n transition: \"all 220ms cubic-bezier(0.4, 0, 0.2, 1)\",\n pointerEvents: showLoader ? \"none\" : \"auto\",\n zIndex: 1,\n }}\n >\n <StreamingMarkdown\n content={content}\n isStreaming={isStreaming && isLast}\n sources={sourceSummaries}\n />\n </Box>\n </Box>\n );\n\n return (\n <Box key={index}>\n <AIResponseTextField\n question={entry.question}\n response={responseNode}\n responseText={isLast ? (isStreaming ? (streamBuffer || \"\") : (isPlaceholder ? \"\" : entry.answer)) : entry.answer}\n backgroundColor=\"#444\"\n images={entry.images}\n memoryUpdated={entry.memoryUpdated && !isPlaceholder}\n sourceFiles={rawSources}\n isMobile={isMobile}\n cancelled={entry.cancelled}\n />\n </Box>\n );\n })}\n\n <div style={{ height: \"1px\" }} ref={scrollTargetRef} />\n </Box>\n );\n};\n\nexport default ChatMessages;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-E95F-A26839\nconst __banditFingerprint_chat_chatinputtsx = 'BL-FP-E7A13E-4AF0';\nconst __auditTrail_chat_chatinputtsx = 'BL-AU-MGOIKVUX-SXD7';\n// File: chat-input.tsx | Path: src/chat/chat-input.tsx | Hash: e95f4af0\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { Box, TextField, IconButton, Tooltip, Avatar, Typography, CircularProgress, Collapse } from \"@mui/material\";\nimport CloseIcon from \"@mui/icons-material/Close\";\nimport ArrowUpwardIcon from \"@mui/icons-material/ArrowUpward\";\nimport PsychologyIcon from \"@mui/icons-material/Psychology\";\nimport FeedbackIcon from \"@mui/icons-material/Feedback\";\nimport HearingDisabledIcon from \"@mui/icons-material/HearingDisabled\";\nimport GraphicEqIcon from \"@mui/icons-material/GraphicEq\";\nimport ExpandMoreIcon from \"@mui/icons-material/ExpandMore\";\nimport { BanditPersonality } from \"../store/modelStore\";\nimport { usePreferencesStore } from \"../store/preferencesStore\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport Transcriber from \"../services/stt/transcriber\";\nimport MemoryModal from \"./memory-modal\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport brandingService from \"../services/branding/brandingService\";\nimport { FeedbackModal } from \"../components/feedback/FeedbackModal\";\nimport { useFeatures, useFeatureVisibility } from \"../hooks/useFeatures\";\nimport { useVoiceStore } from \"../store/voiceStore\";\nimport { useVoiceModeStore } from \"../store/voiceModeStore\";\nimport { shallow } from \"zustand/shallow\";\n\ninterface ChatInputProps {\n inputValue: string;\n setInputValue: (val: string) => void;\n pastedImages: string[];\n setPastedImages: React.Dispatch<React.SetStateAction<string[]>>;\n inputRef: React.RefObject<HTMLInputElement>;\n inputContainerRef: React.RefObject<HTMLDivElement>;\n isMobile: boolean;\n inputHeight: number;\n setInputHeight: (val: number) => void;\n isSubmitting: boolean;\n selectedVoice: string;\n availableVoices: string[];\n handleVoiceChange: (voiceId: string) => void;\n selectedModel: string;\n availableModels: BanditPersonality[];\n handleModelChange: (modelId: string) => void;\n onSend: (question: string, images: string[], displayQuestion: string) => void;\n onStop?: () => void;\n isStreaming?: boolean;\n}\n\nconst ChatInput: React.FC<ChatInputProps> = (props) => {\n const {\n inputValue,\n setInputValue,\n pastedImages,\n inputRef,\n isMobile,\n setPastedImages,\n inputContainerRef,\n isSubmitting,\n onSend,\n onStop,\n isStreaming,\n } = props;\n\n // Theme and color variables\n const theme = useTheme();\n const inputBackground = theme.palette.chat.input;\n const shellBackground = theme.palette.chat.shell;\n const badgeBackground = theme.palette.chat.badge;\n const hoverBadgeBackground = theme.palette.chat.badgeHover;\n const fileBg = theme.palette.chat.file;\n const fileIconBg = theme.palette.chat.fileIcon;\n const fileText = theme.palette.chat.fileText;\n const captionColor = theme.palette.chat.caption;\n\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n const isVoiceServiceAvailable = useVoiceStore((state) => state.isServiceAvailable);\n const {\n isVoiceModeEnabled,\n voiceStatus,\n voiceError,\n toggleVoiceMode,\n voiceLastTranscript,\n } = useVoiceModeStore(\n (state) => ({\n isVoiceModeEnabled: state.enabled,\n voiceStatus: state.status,\n voiceError: state.error,\n toggleVoiceMode: state.toggle,\n voiceLastTranscript: state.lastTranscript,\n }),\n shallow\n );\n const [memoryOpen, setMemoryOpen] = useState(false);\n const [fileInputs, setFileInputs] = useState<File[]>([]);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [brandingText, setBrandingText] = useState<string>(\"\");\n const [feedbackModalOpen, setFeedbackModalOpen] = useState(false);\n const [isKeyboardOpen, setKeyboardOpen] = useState(false);\n const [moreActionsOpen, setMoreActionsOpen] = useState(false);\n\n const compactMobile = isMobile;\n const primaryIconSize = isMobile ? 32 : 40;\n const sendIconSize = isMobile ? 36 : 44;\n const attachmentsGap = isMobile ? 0.6 : 1;\n const attachmentChipPaddingX = isMobile ? 1 : 1.5;\n const attachmentChipPaddingY = isMobile ? 0.55 : 0.75;\n const mobileShellPadding = `calc(var(--input-offset, 1.5rem) - 0.4rem)`;\n const streamingActive = Boolean(isStreaming);\n const sendButtonBackground = streamingActive\n ? alpha(theme.palette.error.main, theme.palette.mode === \"dark\" ? 0.75 : 0.65)\n : fileText;\n const sendButtonColor = streamingActive\n ? theme.palette.common.white\n : fileIconBg;\n const sendButtonHover = streamingActive\n ? alpha(theme.palette.error.main, theme.palette.mode === \"dark\" ? 0.9 : 0.82)\n : hoverBadgeBackground;\n const sendButtonShadow = streamingActive\n ? `0 0 0 3px ${alpha(theme.palette.error.main, 0.18)}`\n : \"none\";\n\n // Feature flag checks\n const { hasSTT, hasMemory, hasDocumentKnowledge } = useFeatures();\n const { showMemoryToggle, showDocumentUpload } = useFeatureVisibility();\n\n // Check if STT is available (URL is configured in package settings) AND enabled in preferences AND user has STT feature\n const isSTTAvailable = !!packageSettings?.gatewayApiUrl && preferences.sttEnabled && hasSTT();\n const isTTSAvailable = !!(\n packageSettings?.gatewayApiUrl &&\n preferences.ttsEnabled &&\n isVoiceServiceAvailable\n );\n const isVoiceModeEligible = isSTTAvailable && isTTSAvailable;\n \n // Check if memory modal should be shown\n const isMemoryEnabled = preferences.memoryEnabled && showMemoryToggle();\n\n // Check if document upload should be shown\n const isDocumentUploadEnabled = showDocumentUpload();\n\n // Check if feedback button should be shown\n const isFeedbackEnabled = preferences.feedbackEnabled;\n\n const gatewayUrlLower = packageSettings?.gatewayApiUrl?.toLowerCase?.() ?? \"\";\n const isPlaygroundMode =\n packageSettings?.playgroundMode === true ||\n gatewayUrlLower.startsWith(\"playground://\") ||\n (typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\"));\n\n useEffect(() => {\n const lockViewportHeight = () => {\n if (isMobile) {\n document.documentElement.style.setProperty(\"--vh\", `${window.innerHeight * 0.01}px`);\n document.documentElement.style.setProperty(\n \"--input-offset\",\n `max(env(safe-area-inset-bottom, 0px), 1.5rem)`\n );\n }\n };\n lockViewportHeight();\n window.addEventListener(\"resize\", lockViewportHeight);\n return () => window.removeEventListener(\"resize\", lockViewportHeight);\n }, [isMobile]);\n\n useEffect(() => {\n if (!isMobile) {\n setKeyboardOpen(false);\n return;\n }\n\n const viewport = window.visualViewport;\n let baseline = viewport?.height ?? window.innerHeight;\n const THRESHOLD = 120;\n\n const detectKeyboard = () => {\n const current = viewport?.height ?? window.innerHeight;\n if (current > baseline) {\n baseline = current;\n }\n setKeyboardOpen(baseline - current > THRESHOLD);\n };\n\n detectKeyboard();\n viewport?.addEventListener(\"resize\", detectKeyboard);\n window.addEventListener(\"resize\", detectKeyboard);\n\n return () => {\n viewport?.removeEventListener(\"resize\", detectKeyboard);\n window.removeEventListener(\"resize\", detectKeyboard);\n };\n }, [isMobile]);\n\n // Load branding text for disclaimer\n useEffect(() => {\n const loadBrandingText = async () => {\n try {\n const branding = await brandingService.getBranding();\n setBrandingText(branding?.brandingText || \"\");\n } catch (error) {\n debugLogger.error(\"Failed to load branding text\", { error });\n setBrandingText(\"\");\n }\n };\n loadBrandingText();\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 const result = event.target?.result;\n if (result) {\n setPastedImages((prev) => [...prev, result as string]);\n }\n };\n reader.readAsDataURL(file);\n }\n }\n }\n }\n };\n document.addEventListener(\"paste\", handlePaste);\n return () => document.removeEventListener(\"paste\", handlePaste);\n }, [setPastedImages]);\n\n const getFileIcon = (filename: string) => {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n switch (ext) {\n case \"js\":\n return \"JS\";\n case \"ts\":\n return \"TS\";\n case \"tsx\":\n return \"TX\";\n case \"py\":\n return \"🐍\";\n case \"json\":\n return \"{}\";\n case \"md\":\n return \"MD\";\n case \"pdf\":\n return \"📄\";\n case \"docx\":\n return \"📄\";\n case \"c\":\n return \"C\";\n case \"cpp\":\n return \"C++\";\n case \"cs\":\n return \"C#\";\n case \"java\":\n return \"J\";\n case \"txt\":\n return \"TXT\";\n default:\n return \"📁\";\n }\n };\n\n const removeImage = (index: number) => {\n setPastedImages((prev) => prev.filter((_, i) => i !== index));\n };\n\n const handleSubmit = async () => {\n if (inputValue.trim() === \"\" && pastedImages.length === 0 && fileInputs.length === 0)\n return;\n const tempImages = [...pastedImages];\n\n // Utility to escape prompt injection in user-uploaded content\n const escapePromptInjection = (text: string) => {\n return text\n .replace(/<\\s*\\/?script.*?>/gi, \"\")\n .replace(/```.*?```/gs, \"\")\n .replace(/(?<=\\n|^)\\/?(system|assistant|user):/gi, \"[removed-role]\");\n };\n\n const getFileText = async (file: File): Promise<string> => {\n const isCodeFile = (name: string) =>\n name.endsWith(\".js\") ||\n name.endsWith(\".ts\") ||\n name.endsWith(\".tsx\") ||\n name.endsWith(\".json\") ||\n name.endsWith(\".py\") ||\n name.endsWith(\".java\") ||\n name.endsWith(\".c\") ||\n name.endsWith(\".cpp\") ||\n name.endsWith(\".cs\");\n\n const sanitize = (text: string, name: string) =>\n isCodeFile(name) ? text.trim() : text.replace(/[^\\x20-\\x7E\\r\\n\\t]/g, \"\").trim();\n\n const name = file.name.toLowerCase();\n\n try {\n if (\n file.type.startsWith(\"text/\") ||\n name.endsWith(\".md\") ||\n name.endsWith(\".txt\") ||\n name.endsWith(\".js\") ||\n name.endsWith(\".ts\") ||\n name.endsWith(\".tsx\") ||\n name.endsWith(\".json\") ||\n name.endsWith(\".py\") ||\n name.endsWith(\".java\") ||\n name.endsWith(\".c\") ||\n name.endsWith(\".cpp\") ||\n name.endsWith(\".cs\")\n ) {\n const text = await file.text();\n // Sanitize prompt injection for non-code files\n if (\n name.endsWith(\".txt\") ||\n name.endsWith(\".md\") ||\n name.endsWith(\".docx\") ||\n name.endsWith(\".pdf\")\n ) {\n return `📄 ${file.name}\\n${sanitize(escapePromptInjection(text), file.name)}`;\n } else {\n return `📄 ${file.name}\\n${sanitize(text, file.name)}`;\n }\n }\n\n if (name.endsWith(\".docx\")) {\n const mammoth = await import(\"mammoth\");\n const arrayBuffer = await file.arrayBuffer();\n const { value } = await mammoth.extractRawText({ arrayBuffer });\n return `📄 ${file.name}\\n${sanitize(escapePromptInjection(value), file.name)}`;\n }\n\n if (name.endsWith(\".pdf\")) {\n const pdfjsLib = await import(\"pdfjs-dist/legacy/build/pdf\");\n pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.burtson.ai/scripts/pdf.worker.js';\n\n const buffer = await file.arrayBuffer();\n const loadingTask = pdfjsLib.getDocument({ data: buffer });\n\n try {\n const pdf = await loadingTask.promise;\n debugLogger.info(\"PDF loaded\", { numPages: pdf.numPages });\n\n const maxPages = Math.min(pdf.numPages, 10);\n const pages = await Promise.all(\n Array.from({ length: maxPages }, async (_, i) => {\n try {\n const page = await pdf.getPage(i + 1);\n const content = await page.getTextContent();\n return content.items\n .map((item: unknown) => {\n if (\n item &&\n typeof item === \"object\" &&\n \"str\" in item &&\n typeof (item as { str: unknown }).str === \"string\"\n ) {\n return (item as { str: string }).str;\n }\n return \"\";\n })\n .join(\" \");\n } catch (err) {\n debugLogger.error(`Failed to read page ${i + 1}`, { error: err });\n return \"\";\n }\n })\n );\n\n const joined = pages.join(\"\\n\\n\");\n debugLogger.info(\"Extracted PDF content\", { contentPreview: joined.slice(0, 500) });\n return `📄 ${file.name}\\n${sanitize(\n escapePromptInjection(joined),\n file.name\n )}`;\n } catch (error) {\n debugLogger.error(\"PDF load failed\", {\n error: error instanceof Error ? error.message : String(error),\n fileName: file.name,\n });\n return \"\";\n }\n }\n\n return \"\";\n } catch {\n return \"\";\n }\n };\n\n const fileTexts = await Promise.all(fileInputs.map(getFileText));\n // Logging all extracted file texts\n debugLogger.debug(\"All extracted file texts\", { fileTexts });\n const fileContent = fileTexts.filter(Boolean).join(\"\\n\\n\");\n\n const tempQuestionBase =\n inputValue.trim() ||\n (tempImages.length === 1\n ? \"[📷 You attached an image]\"\n : tempImages.length > 1\n ? `[📷 You attached ${tempImages.length} images]`\n : \"\");\n\n const fileDisplaySummary =\n fileInputs.length > 0\n ? `[📎 Attached ${fileInputs.length} file${fileInputs.length > 1 ? \"s\" : \"\"\n }: ${fileInputs.map((f) => f.name).join(\", \")}]`\n : \"\";\n\n //TODO:displayQuestion is what shows in chat history, excludes file content\n const displayQuestion = [\n tempQuestionBase ||\n (fileDisplaySummary ? \"[📤 You submitted content without text]\" : \"\"),\n fileDisplaySummary,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n // fullPrompt is what is sent to the LLM (inputValue + fileContent)\n const fullPrompt = [inputValue, fileContent].filter(Boolean).join(\"\\n\\n\");\n\n setInputValue(\"\");\n setPastedImages([]);\n setFileInputs([]);\n onSend(fullPrompt, tempImages, displayQuestion);\n inputRef.current?.blur();\n fileInputRef.current!.value = \"\"; // clear input field manually\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n const handleTranscriptionCompleted = (transcribed: string) => {\n const value = (inputValue + transcribed).trim();\n setInputValue(value);\n inputRef.current?.focus();\n };\n\n const memory = localStorage.getItem(\"bandit-memory\");\n\n const hasAttachmentAction = !isPlaygroundMode && fileInputs.length < 3 && isDocumentUploadEnabled;\n const hasMemoryAction = isMemoryEnabled;\n const hasFeedbackAction = isFeedbackEnabled && isMobile;\n const hasSttAction = isSTTAvailable && !isVoiceModeEnabled;\n const hasSecondaryActions = isMobile && (hasAttachmentAction || hasMemoryAction || hasFeedbackAction || hasSttAction);\n\n useEffect(() => {\n if (!isMobile || !hasSecondaryActions) {\n setMoreActionsOpen(false);\n }\n }, [isMobile, hasSecondaryActions]);\n\n const renderAttachmentButton = (key?: string) => {\n if (!hasAttachmentAction) return null;\n return (\n <Tooltip key={key ?? \"attach\"} title=\"Attach files or images\">\n <IconButton\n onClick={() => fileInputRef.current?.click()}\n sx={{\n bgcolor: badgeBackground,\n color: fileText,\n width: primaryIconSize,\n height: primaryIconSize,\n borderRadius: \"50%\",\n \"&:hover\": { bgcolor: hoverBadgeBackground },\n }}\n >\n +\n </IconButton>\n </Tooltip>\n );\n };\n\n const renderMemoryButton = (key?: string) => {\n if (!hasMemoryAction) return null;\n return (\n <Tooltip key={key ?? \"memory\"} title=\"Memory\">\n <IconButton\n onClick={() => setMemoryOpen(true)}\n sx={{\n bgcolor: badgeBackground,\n color: fileText,\n width: primaryIconSize,\n height: primaryIconSize,\n borderRadius: \"50%\",\n \"&:hover\": { bgcolor: hoverBadgeBackground },\n }}\n >\n <PsychologyIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n );\n };\n\n const renderFeedbackButton = (key?: string) => {\n if (!hasFeedbackAction) return null;\n return (\n <Tooltip key={key ?? \"feedback\"} title=\"Send Feedback\">\n <IconButton\n onClick={() => setFeedbackModalOpen(true)}\n sx={{\n bgcolor: badgeBackground,\n color: fileText,\n width: primaryIconSize,\n height: primaryIconSize,\n borderRadius: \"50%\",\n \"&:hover\": { bgcolor: hoverBadgeBackground },\n }}\n >\n <FeedbackIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n );\n };\n\n const renderSttButton = (key?: string) => {\n if (!hasSttAction) return null;\n return (\n <Box key={key ?? \"stt\"} sx={{ display: \"flex\", alignItems: \"center\" }}>\n <Transcriber onTranscriptionCompleted={handleTranscriptionCompleted} />\n </Box>\n );\n };\n\n return (\n <>\n <Box\n sx={{\n width: \"100%\",\n bgcolor: shellBackground,\n zIndex: isMobile ? 1300 : 1000,\n display: \"flex\",\n flexDirection: \"column\",\n flex: \"1 1 auto\",\n alignItems: \"center\",\n justifyContent: \"end\",\n marginTop: isMobile ? (compactMobile ? 0.5 : 1) : 2,\n px: isMobile ? (compactMobile ? 1.5 : 2) : 0,\n pb: isMobile ? mobileShellPadding : 3,\n pointerEvents: \"none\",\n \"& > *\": { pointerEvents: \"auto\" },\n }}\n ref={inputContainerRef}\n >\n <Box\n sx={{\n width: \"100%\",\n bgcolor: inputBackground,\n borderRadius: \"24px\",\n boxShadow: isMobile\n ? `0 0 0 1px ${theme.palette.mode === \"dark\" ? \"#444\" : \"#eee\"}`\n : \"0 4px 20px rgba(0, 0, 0, 0.4)\",\n px: isMobile ? (compactMobile ? 1 : 1.5) : 3,\n pt: isMobile ? (compactMobile ? 0.6 : 1) : 1,\n pb: isMobile ? (compactMobile ? 0.9 : 1.5) : 1.5,\n display: \"flex\",\n flexDirection: \"column\",\n gap: isMobile ? (compactMobile ? 0.75 : 1) : 1,\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: attachmentsGap,\n alignItems: \"center\",\n flexDirection: \"row\",\n }}\n >\n {fileInputs.map((file, idx) => (\n <Box\n key={idx}\n sx={{\n position: \"relative\",\n bgcolor: fileBg,\n px: attachmentChipPaddingX,\n py: attachmentChipPaddingY,\n borderRadius: 999,\n display: \"flex\",\n alignItems: \"center\",\n gap: isMobile ? (compactMobile ? 0.6 : 0.9) : 1,\n }}\n >\n <Avatar\n sx={{\n width: isMobile ? (compactMobile ? 16 : 18) : 18,\n height: isMobile ? (compactMobile ? 16 : 18) : 18,\n fontSize: \"0.7rem\",\n bgcolor: fileIconBg,\n color: fileText,\n }}\n variant=\"rounded\"\n >\n {getFileIcon(file.name)}\n </Avatar>\n <Typography variant=\"caption\" sx={{ color: fileText }}>\n {file.name}\n </Typography>\n <IconButton\n size=\"small\"\n onClick={() =>\n setFileInputs((prev) => prev.filter((_, i) => i !== idx))\n }\n sx={{ ml: 0.5, color: theme.palette.mode === \"dark\" ? \"#aaa\" : \"#444\" }}\n >\n <CloseIcon sx={{ fontSize: 14 }} />\n </IconButton>\n </Box>\n ))}\n {pastedImages.map((img, idx) => (\n <Box key={`img-${idx}`} sx={{ position: \"relative\" }}>\n <Avatar\n src={img}\n variant=\"rounded\"\n sx={{\n width: isMobile ? (compactMobile ? 30 : 32) : 32,\n height: isMobile ? (compactMobile ? 30 : 32) : 32,\n border: `1px solid ${fileIconBg}`,\n }}\n />\n <IconButton\n size=\"small\"\n onClick={() => removeImage(idx)}\n sx={{\n position: \"absolute\",\n top: -6,\n right: -6,\n bgcolor: fileText,\n p: 0.3,\n zIndex: 2,\n transition: \"background-color 0.2s ease\",\n \"&:hover\": {\n bgcolor: \"rgba(255, 5, 5, 0.85)\",\n },\n }}\n >\n <CloseIcon\n sx={{\n fontSize: 14,\n color: badgeBackground,\n }}\n />\n </IconButton>\n </Box>\n ))}\n <input\n type=\"file\"\n accept=\".txt,.docx,.pdf,.md,.json,.js,.ts,.tsx,.py,.java,.c,.cpp,.cs,image/*\"\n multiple\n hidden\n ref={fileInputRef}\n onChange={(e) => {\n const selected = Array.from(e.target.files || []);\n const nonImages = selected.filter(\n (file) => !file.type.startsWith(\"image/\")\n );\n const images = selected.filter((file) => file.type.startsWith(\"image/\"));\n\n if (nonImages.length + fileInputs.length > 3) {\n fileInputRef.current!.value = \"\"; // allow re-upload of same file\n return;\n }\n\n const safeNonImages = nonImages.filter((file) => file.size <= 1_000_000); // Optional: size cap\n setFileInputs((prev) => [...prev, ...safeNonImages]);\n\n images.forEach((image) => {\n const reader = new FileReader();\n reader.onload = (event) => {\n const result = event.target?.result;\n if (result) {\n setPastedImages((prev) => [...prev, result as string]);\n }\n };\n reader.readAsDataURL(image);\n });\n\n fileInputRef.current!.value = \"\"; // allow re-upload of same file\n }}\n />\n </Box>\n\n <Box\n sx={{\n display: \"flex\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n }}\n >\n <TextField\n fullWidth\n multiline\n maxRows={isMobile ? (compactMobile ? 6 : 12) : 6}\n placeholder={\"What's on your mind?\"}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={handleKeyPress}\n inputRef={inputRef}\n variant=\"standard\"\n InputProps={{\n disableUnderline: true,\n sx: {\n flex: \"1 1 auto\",\n maxHeight: isMobile ? (compactMobile ? \"120px\" : \"150px\") : \"none\",\n overflowY: \"auto\",\n color: fileText,\n \"& .MuiInputBase-inputMultiline\": {\n fontSize: isMobile ? (compactMobile ? \"0.95rem\" : \"1rem\") : \"1rem\",\n },\n },\n }}\n sx={{\n flex: 1,\n \"& .MuiInputBase-root\": {},\n }}\n />\n </Box>\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: isMobile ? 0.6 : 1,\n mt: isMobile ? 0.5 : 1,\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: isMobile ? 0.6 : 1,\n minHeight: primaryIconSize,\n }}\n >\n {isVoiceModeEligible && (\n <>\n <Tooltip\n title={\n !isVoiceModeEnabled\n ? \"Enable voice mode\"\n : voiceStatus === \"error\"\n ? voiceError || \"Voice mode error\"\n : voiceStatus === \"processing\"\n ? \"Transcribing your speech\"\n : voiceStatus === \"recording\"\n ? \"Recording - click to stop\"\n : voiceStatus === \"initializing\"\n ? \"Preparing microphone\"\n : \"Listening - click to turn off\"\n }\n >\n <IconButton\n onClick={toggleVoiceMode}\n sx={{\n width: primaryIconSize,\n height: primaryIconSize,\n borderRadius: \"50%\",\n bgcolor: isVoiceModeEnabled\n ? alpha(theme.palette.error.main, theme.palette.mode === \"dark\" ? 0.45 : 0.3)\n : badgeBackground,\n color: isVoiceModeEnabled\n ? theme.palette.common.white\n : fileText,\n boxShadow:\n isVoiceModeEnabled && voiceStatus === \"recording\"\n ? `0 0 0 2px ${alpha(theme.palette.error.main, 0.25)}`\n : \"none\",\n transform:\n isVoiceModeEnabled && voiceStatus === \"recording\" ? \"scale(1.05)\" : \"none\",\n transition: \"transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease\",\n \"&:hover\": {\n bgcolor: isVoiceModeEnabled\n ? alpha(theme.palette.error.main, theme.palette.mode === \"dark\" ? 0.55 : 0.38)\n : hoverBadgeBackground,\n },\n }}\n >\n {!isVoiceModeEnabled ? (\n <GraphicEqIcon fontSize=\"small\" sx={{ color: theme.palette.mode === \"dark\" ? fileText : theme.palette.text.secondary }} />\n ) : voiceStatus === \"processing\" || voiceStatus === \"initializing\" ? (\n <CircularProgress size={18} sx={{ color: fileText }} />\n ) : voiceStatus === \"error\" ? (\n <HearingDisabledIcon fontSize=\"small\" sx={{ color: theme.palette.error.light }} />\n ) : voiceStatus === \"recording\" ? (\n <GraphicEqIcon fontSize=\"small\" sx={{ color: theme.palette.error.light }} />\n ) : (\n <GraphicEqIcon fontSize=\"small\" sx={{ color: theme.palette.common.white }} />\n )}\n </IconButton>\n </Tooltip>\n {!isMobile && isVoiceModeEnabled && (\n <Typography\n variant=\"caption\"\n sx={{\n color:\n voiceStatus === \"error\"\n ? theme.palette.error.main\n : voiceStatus === \"processing\"\n ? theme.palette.warning.main\n : fileText,\n maxWidth: 240,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {voiceStatus === \"error\"\n ? voiceError || \"Voice mode unavailable\"\n : voiceStatus === \"initializing\"\n ? \"Starting voice mode...\"\n : voiceStatus === \"recording\"\n ? \"Recording...\"\n : voiceStatus === \"processing\"\n ? \"Transcribing...\"\n : voiceLastTranscript\n ? `Heard: \"${\n voiceLastTranscript.length > 60\n ? `${voiceLastTranscript.slice(0, 57)}...`\n : voiceLastTranscript\n }\"`\n : \"Listening...\"}\n </Typography>\n )}\n </>\n )}\n {!isMobile && renderAttachmentButton(\"attach-inline\")}\n {!isMobile && renderMemoryButton(\"memory-inline\")}\n {!isMobile && renderSttButton(\"stt-inline\")}\n {isMobile && hasSecondaryActions && (\n <IconButton\n onClick={() => setMoreActionsOpen((prev) => !prev)}\n sx={{\n bgcolor: badgeBackground,\n color: fileText,\n width: primaryIconSize,\n height: primaryIconSize,\n borderRadius: \"50%\",\n transition: \"background-color 0.2s ease\",\n \"&:hover\": { bgcolor: hoverBadgeBackground },\n }}\n >\n <ExpandMoreIcon\n fontSize=\"small\"\n sx={{\n transition: \"transform 0.2s ease\",\n transform: moreActionsOpen ? \"rotate(0deg)\" : \"rotate(180deg)\",\n }}\n />\n </IconButton>\n )}\n </Box>\n\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: isMobile ? 0.6 : 1 }}>\n <Tooltip title={isStreaming ? \"Stop response\" : \"Send message\"}>\n <span>\n <IconButton\n onClick={isStreaming ? (onStop || (() => {})) : handleSubmit}\n disabled={\n (isStreaming ? false : isSubmitting) ||\n (!isStreaming &&\n !inputValue.trim() &&\n pastedImages.length === 0 &&\n fileInputs.length === 0)\n }\n sx={{\n bgcolor: sendButtonBackground,\n color: sendButtonColor,\n borderRadius: \"50%\",\n width: sendIconSize,\n height: sendIconSize,\n boxShadow: sendButtonShadow,\n transition: \"background-color 0.2s ease, box-shadow 0.2s ease\",\n \"&:hover\": { bgcolor: sendButtonHover },\n \"&.Mui-disabled\": { opacity: 0.5 },\n }}\n >\n {isStreaming ? <CloseIcon fontSize=\"small\" /> : <ArrowUpwardIcon fontSize=\"small\" />}\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n </Box>\n {isMobile && hasSecondaryActions && (\n <Collapse in={moreActionsOpen} unmountOnExit>\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 0.7,\n mt: 0.6,\n flexWrap: \"wrap\",\n justifyContent: \"flex-end\",\n }}\n >\n {renderAttachmentButton(\"attach-tray\")}\n {renderMemoryButton(\"memory-tray\")}\n {renderSttButton(\"stt-tray\")}\n {renderFeedbackButton(\"feedback-tray\")}\n </Box>\n </Collapse>\n )}\n </Box>\n\n <Typography\n variant=\"caption\"\n sx={{\n mt: isMobile ? (compactMobile ? 0.25 : 0.75) : 1,\n color: captionColor,\n fontStyle: \"italic\",\n fontSize: \"0.75rem\",\n textAlign: \"center\",\n opacity: isKeyboardOpen ? 0 : 1,\n maxHeight: isKeyboardOpen ? 0 : \"2.4rem\",\n overflow: \"hidden\",\n transition: \"opacity 120ms ease, max-height 120ms ease, transform 120ms ease\",\n transform: `translateY(${isKeyboardOpen ? '6px' : '0'})`,\n pointerEvents: \"none\",\n }}\n >\n {brandingText || \"BanditAI\"} may be wrong - double-check important info.\n </Typography>\n </Box>\n\n {isMemoryEnabled && (\n <MemoryModal open={memoryOpen} onClose={() => setMemoryOpen(false)} />\n )}\n \n {isFeedbackEnabled && (\n <FeedbackModal \n open={feedbackModalOpen} \n onClose={() => setFeedbackModalOpen(false)}\n feedbackEmail={packageSettings?.feedbackEmail}\n />\n )}\n </>\n );\n};\n\nexport default ChatInput;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-F291-151AAD\nconst __banditFingerprint_stt_transcribertsx = 'BL-FP-CF71B4-71EF';\nconst __auditTrail_stt_transcribertsx = 'BL-AU-MGOIKVVZ-JTMQ';\n// File: transcriber.tsx | Path: src/services/stt/transcriber.tsx | Hash: f29171ef\n\nimport { useState, useRef } from \"react\";\nimport MicIcon from \"@mui/icons-material/Mic\";\nimport CheckIcon from \"@mui/icons-material/Check\";\nimport CloseIcon from \"@mui/icons-material/Close\";\nimport { SoundRecorderService } from \"./sound-recorder.service\";\nimport { STTClient } from \"./stt-client\";\nimport { CircularProgress, IconButton, useTheme } from \"@mui/material\";\nimport { from, Subscription, switchMap } from \"rxjs\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\ninterface TranscriberProps {\n onTranscriptionCompleted: (text: string) => void;\n}\n\ntype RecorderStatus = \"IDLE\" | \"RECORDING\" | \"LOADING\";\n\nconst initialButtonStyles = (badgeBackground: string, fileText: string, hoverBadgeBackground: string) => ({\n bgcolor: badgeBackground,\n color: fileText,\n width: 36,\n height: 36,\n borderRadius: \"50%\",\n \"&:hover\": { bgcolor: hoverBadgeBackground },\n});\n\nconst Transcriber: React.FC<TranscriberProps> = ({ onTranscriptionCompleted }) => {\n const theme = useTheme();\n const badgeBackground = theme.palette.chat.badge;\n const fileText = theme.palette.chat.fileText;\n const hoverBadgeBackground = theme.palette.chat.badgeHover;\n const [status, setStatus] = useState<RecorderStatus>(\"IDLE\");\n const recorderRef = useRef(new SoundRecorderService());\n const [iconButtonStyles] = useState(() => initialButtonStyles(badgeBackground, fileText, hoverBadgeBackground));\n const [recordingSub, setRecordingSub] = useState<Subscription>(() => new Subscription());\n const start = () => {\n recordingSub.unsubscribe();\n const recording = recorderRef.current.start();\n const text = recording.pipe(\n switchMap((blob: Blob) => {\n debugLogger.debug('Processing audio blob for transcription');\n return from(STTClient.transcribe(blob));\n })\n );\n const sub = text.subscribe({\n next: (value) => onTranscriptionCompleted(value),\n error: (error) => setStatus(\"IDLE\"),\n complete: () => setStatus(\"IDLE\"),\n });\n\n setRecordingSub(sub);\n };\n\n const stop = () => {\n recorderRef.current.stop();\n };\n const handleRecordClick = () => {\n setStatus(\"RECORDING\");\n start();\n };\n const handleCancelClick = () => {\n setStatus(\"IDLE\");\n };\n const handleSubmitClick = () => {\n setStatus(\"LOADING\");\n stop();\n };\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n transition: \"all 0.2s ease\",\n backgroundColor: status === \"RECORDING\" ? \"rgba(0,0,0,.3)\" : \"rgba(0,0,0,0)\",\n borderRadius: \"50px\",\n }}\n >\n {status === \"IDLE\" ? (\n <IconButton sx={{ ...iconButtonStyles }} onClick={handleRecordClick}>\n <MicIcon sx={{ color: \"#aaa\", cursor: \"pointer\" }} />\n </IconButton>\n ) : status === \"RECORDING\" ? (\n <>\n <IconButton\n onClick={handleCancelClick}\n sx={{ ...iconButtonStyles, marginRight: 1 }}\n >\n <CloseIcon></CloseIcon>\n </IconButton>\n <IconButton\n sx={{\n ...iconButtonStyles,\n filter: \"invert(110%)\",\n }}\n onClick={handleSubmitClick}\n >\n <CheckIcon></CheckIcon>\n </IconButton>\n </>\n ) : status === \"LOADING\" ? (\n <IconButton sx={{ ...iconButtonStyles }}>\n <CircularProgress size={20} />\n </IconButton>\n ) : null}\n </div>\n );\n};\n\nexport default Transcriber;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-17BC-5CBAB9\nconst __banditFingerprint_stt_soundrecorderservicets = 'BL-FP-A3A6BF-2B75';\nconst __auditTrail_stt_soundrecorderservicets = 'BL-AU-MGOIKVVZ-9DDJ';\n// File: sound-recorder.service.ts | Path: src/services/stt/sound-recorder.service.ts | Hash: 17bc2b75\n\nimport { first, from, fromEvent, map, Observable, shareReplay, switchMap } from \"rxjs\";\nimport { createAudioBlob } from \"./create-audio-blob\";\n\nexport class SoundRecorderService {\n private _mediaRecorder?: Observable<MediaRecorder>;\n\n\n start(): Observable<Blob> {\n\n const mediaStream = from(navigator.mediaDevices.getUserMedia({ audio: true }));\n\n this._mediaRecorder = mediaStream.pipe(map(stream => {\n const rec = new MediaRecorder(stream)\n rec.start();\n return rec;\n }), shareReplay(1));\n\n const dataAvailableEvent = this._mediaRecorder.pipe(\n switchMap(recorder => fromEvent<BlobEvent>(recorder, 'dataavailable'))\n );\n\n const blob = dataAvailableEvent.pipe(\n first(),\n map((event) => createAudioBlob(event.data)),\n shareReplay(1)\n );\n\n return blob;\n }\n\n\n stop() {\n if (!this._mediaRecorder) {\n return;\n }\n\n this._mediaRecorder.pipe(first()).subscribe(recorder => {\n recorder.stop();\n });\n }\n\n\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-36B0-9C1E70\nconst __banditFingerprint_stt_createaudioblobts = 'BL-FP-14329D-148B';\nconst __auditTrail_stt_createaudioblobts = 'BL-AU-MGOIKVVY-G0SR';\n// File: create-audio-blob.ts | Path: src/services/stt/create-audio-blob.ts | Hash: 36b0148b\n\nexport const createAudioBlob = (data: BlobPart | BlobPart[]): Blob => {\n const parts = Array.isArray(data) ? data : [data];\n return new Blob(parts, { type: 'audio/ogg' }); // Simplified MIME type without codec specification\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-C8A1-40B795\nconst __banditFingerprint_stt_sttclientts = 'BL-FP-B71992-8B55';\nconst __auditTrail_stt_sttclientts = 'BL-AU-MGOIKVVZ-KV58';\n// File: stt-client.ts | Path: src/services/stt/stt-client.ts | Hash: c8a18b55\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 Boolean(value) && typeof value === \"object\";\n\n/**\n * Abstract STT response parser to handle different API response formats\n */\nexport interface STTResponse {\n text: string;\n}\n\nexport class STTResponseParser {\n /**\n * Parse STT response to extract transcribed text\n * Supports multiple API response formats for maximum compatibility\n */\n static parseResponse(data: unknown): string {\n const root = isRecord(data) ? data : {};\n\n // Strategy 1: Nested JSON in transcription field (current C# API)\n const transcriptionValue = root[\"transcription\"];\n if (typeof transcriptionValue === \"string\") {\n try {\n const transcriptionData = JSON.parse(transcriptionValue) as Record<string, unknown>;\n const nestedText = transcriptionData?.text;\n if (typeof nestedText === \"string\") {\n return nestedText;\n }\n } catch (e) {\n debugLogger.warn('Failed to parse nested transcription JSON, trying direct access');\n }\n }\n\n // Strategy 2: Direct text field (common in Node.js/Python APIs)\n const directText = root[\"text\"];\n if (typeof directText === \"string\") {\n return directText;\n }\n\n // Strategy 3: Transcription as direct string (simple APIs)\n if (typeof transcriptionValue === \"string\" && !transcriptionValue.startsWith(\"{\")) {\n return transcriptionValue;\n }\n\n // Strategy 4: Result field (some ML APIs)\n const result = root[\"result\"];\n if (isRecord(result)) {\n const resultText = result[\"text\"];\n if (typeof resultText === \"string\") {\n return resultText;\n }\n }\n\n // Strategy 5: Response wrapper (enterprise APIs)\n const responseWrapper = root[\"response\"];\n if (isRecord(responseWrapper)) {\n const responseText = responseWrapper[\"transcription\"];\n if (typeof responseText === \"string\") {\n return responseText;\n }\n }\n\n // Strategy 6: Alternatives array (Google/AWS style)\n const alternatives = root[\"alternatives\"];\n if (Array.isArray(alternatives)) {\n const firstAlternative = alternatives[0];\n if (isRecord(firstAlternative) && typeof firstAlternative[\"transcript\"] === \"string\") {\n return firstAlternative[\"transcript\"] as string;\n }\n }\n\n debugLogger.error('Unable to parse STT response format:', data);\n throw new Error('Unsupported STT response format');\n }\n}\n\n/**\n * Universal STT client that works with any backend API\n */\nexport class STTClient {\n /**\n * Transcribe audio blob to text\n * @param blob Audio blob to transcribe\n * @returns Promise<string> Transcribed text\n */\n static async transcribe(blob: Blob): Promise<string> {\n const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl || \"\";\n \n if (!gatewayUrl) {\n throw new Error('Gateway API URL not configured');\n }\n \n let normalizedBlob: Blob = blob;\n\n if (blob.type.includes('webm') && blob.type.includes('codecs=')) {\n debugLogger.debug('STT Request: normalizing webm blob without codec suffix', {\n originalType: blob.type,\n });\n normalizedBlob = new Blob([blob], { type: 'audio/webm' });\n }\n\n const body = new FormData();\n const filename = normalizedBlob.type.includes('ogg') ? 'audio.ogg' : \n normalizedBlob.type.includes('wav') ? 'audio.wav' :\n normalizedBlob.type.includes('mp3') ? 'audio.mp3' : 'audio.webm';\n \n // Try common parameter names for maximum API compatibility\n body.append(\"audio\", normalizedBlob, filename); // Most common\n body.append(\"file\", normalizedBlob, filename); // Alternative\n body.append(\"audioFile\", normalizedBlob, filename); // Some APIs prefer this\n \n debugLogger.debug('STT Request:', {\n blobSize: normalizedBlob.size,\n blobType: normalizedBlob.type,\n filename: filename,\n url: `${gatewayUrl}/stt/transcribe`\n });\n \n const token = authenticationService.getToken();\n const response = await fetch(`${gatewayUrl}/stt/transcribe`, {\n method: \"POST\",\n headers: { \n Authorization: `Bearer ${token}`,\n // Let browser set Content-Type with boundary for FormData\n },\n body: body,\n });\n \n if (!response.ok) {\n const errorText = await response.text();\n debugLogger.error('STT API Error:', { status: response.status, error: errorText });\n throw new Error(`STT API Error: ${response.status} - ${errorText}`);\n }\n \n const data = await response.json();\n debugLogger.debug('STT Response:', data);\n \n return STTResponseParser.parseResponse(data);\n }\n}\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-06D6-4EC241\nconst __banditFingerprint_store_voiceModeStorets = 'BL-FP-590448-C812';\nconst __auditTrail_store_voiceModeStorets = 'BL-AU-MGOIKVW6-VU6Q';\n// File: voiceModeStore.ts | Path: src/store/voiceModeStore.ts | Hash: 06d6c812\n\nimport { create } from \"zustand\";\n\nexport type VoiceModeStatus =\n | \"idle\"\n | \"initializing\"\n | \"listening\"\n | \"recording\"\n | \"processing\"\n | \"error\";\n\ninterface VoiceModeState {\n enabled: boolean;\n status: VoiceModeStatus;\n lastTranscript: string | null;\n error: string | null;\n toggle: () => void;\n setEnabled: (enabled: boolean) => void;\n setStatus: (status: VoiceModeStatus) => void;\n setError: (error: string | null) => void;\n setLastTranscript: (transcript: string | null) => void;\n resetTransientState: () => void;\n}\n\nexport const useVoiceModeStore = create<VoiceModeState>((set) => ({\n enabled: false,\n status: \"idle\",\n lastTranscript: null,\n error: null,\n\n toggle: () =>\n set((state) => {\n const enabled = !state.enabled;\n return {\n enabled,\n status: enabled ? \"initializing\" : \"idle\",\n error: null,\n lastTranscript: enabled ? state.lastTranscript : null,\n };\n }),\n\n setEnabled: (enabled) =>\n set(() => ({\n enabled,\n status: enabled ? \"initializing\" : \"idle\",\n error: null,\n })),\n\n setStatus: (status) =>\n set((state) => ({\n status: state.error && status !== \"error\" ? state.status : status,\n })),\n\n setError: (error) =>\n set((state) => ({\n error,\n status: error ? \"error\" : state.enabled ? \"listening\" : \"idle\",\n })),\n\n setLastTranscript: (transcript) => set({ lastTranscript: transcript }),\n\n resetTransientState: () =>\n set((state) => ({\n status: state.enabled ? \"listening\" : \"idle\",\n error: null,\n })),\n}));\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-4003-44028A\nconst __banditFingerprint_hooks_useAIProvidertsx = 'BL-FP-53B7AF-EC0F';\nconst __auditTrail_hooks_useAIProvidertsx = 'BL-AU-MGOIKVV1-E28V';\n// File: useAIProvider.tsx | Path: src/chat/hooks/useAIProvider.tsx | Hash: 4003ec0f\n\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { useCallback, useRef } from \"react\";\nimport type { Subscription } from \"rxjs\";\nimport type { KnowledgeDoc } from \"../../store/knowledgeStore\";\nimport { useKnowledgeStore } from \"../../store/knowledgeStore\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { useConversationStore } from \"../../store/conversationStore\";\nimport { useMemoryEnhancer } from \"./useMemoryEnhancer\";\nimport { useVectorStore } from \"../../hooks/useVectorStore\";\nimport { embeddingService } from \"../../services/embedding/embeddingService\";\nimport { useMoodEngine, moodPromptMap } from \"./useMoodEngine\";\nimport { ComponentStatus, HistoryEntry } from \"../../store/aiQueryStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { determineRelevantDocuments, getCurrentDateTimeContext } from \"../../services/prompts\";\nimport { AIChatRequest, AIMessage } from \"../../services/ai-provider/types/common.types\";\nimport { usePreferencesStore } from \"../../store/preferencesStore\";\nimport { getEnabledMCPToolsForAI, isMCPAvailable, executeMCPTool } from \"../../services/mcp\";\nimport type { VectorMemory, VectorMemoryMetadata } from \"../../services/vectorDatabase/vectorDatabaseService\";\n\n// Model budget configuration - provider agnostic\nexport interface ModelBudget {\n maxTokens: number;\n memoryTokenBudget: number;\n historyMessages: number;\n moodInjection: boolean;\n}\n\nexport type ModelConfigIdentifier =\n | \"bandit-core:4b-it-qat\"\n | \"bandit-core:12b-it-qat\"\n | \"bandit-core:27b-it-qat\"\n | \"gemma3:4b-it-qat\"\n | \"gemma3:12b-it-qat\"\n | \"gemma3:27b-it-qat\"\n | \"gpt-3.5-turbo\"\n | \"gpt-4\"\n | \"gpt-4-turbo\"\n | string;\n\nconst lightBudget: ModelBudget = {\n maxTokens: 2048,\n memoryTokenBudget: 750,\n historyMessages: 2,\n moodInjection: true,\n};\n\nconst medBudget: ModelBudget = {\n maxTokens: 4096,\n memoryTokenBudget: 1250,\n historyMessages: 6,\n moodInjection: true,\n};\n\nconst heavyBudget: ModelBudget = {\n maxTokens: 8192,\n memoryTokenBudget: 2000,\n historyMessages: 10,\n moodInjection: true,\n};\n\nconst modelConfigs: { [key: ModelConfigIdentifier]: ModelBudget } = {\n // Ollama models\n \"bandit-core:4b-it-qat\": lightBudget,\n \"bandit-core:12b-it-qat\": medBudget,\n \"bandit-core:27b-it-qat\": medBudget,\n \"gemma3:4b-it-qat\": lightBudget,\n \"gemma3:12b-it-qat\": medBudget,\n \"gemma3:27b-it-qat\": medBudget,\n // OpenAI models\n \"gpt-3.5-turbo\": medBudget,\n \"gpt-4\": heavyBudget,\n \"gpt-4-turbo\": heavyBudget,\n};\n\ntype NormalizedVectorMemory = {\n id: string;\n content: string;\n title?: string;\n pinned: boolean;\n source: \"auto\" | \"user\";\n score: number;\n tags: string[];\n uploadedAt?: number;\n lastReferencedAt?: number;\n metadata?: VectorMemoryMetadata;\n personalConfidence?: number;\n engagement?: number;\n topic?: string;\n};\n\ntype RawVectorDocument = {\n id?: string;\n documentId?: string;\n fileId?: string;\n _id?: string;\n metadata?: {\n id?: string;\n _id?: string;\n fileId?: string;\n [key: string]: unknown;\n };\n key?: string;\n filename?: string;\n name?: string;\n content?: string;\n mimeType?: string;\n type?: string;\n uploadedAt?: string | number | Date;\n size?: number;\n uploadedBy?: string;\n userEmail?: string;\n bucket?: string;\n isUserContent?: boolean;\n isTeamContent?: boolean;\n contentSource?: string;\n originalFileName?: string;\n [key: string]: unknown;\n};\n\ntype KnowledgeSourceDoc = KnowledgeDoc & { _vectorResult?: RawVectorDocument; chunks?: string[] };\n\ntype MCPFunctionTool = ReturnType<typeof getEnabledMCPToolsForAI>[number];\n\ntype MCPToolParameters = Record<string, unknown>;\n\ntype ToolAwareChatRequest = AIChatRequest & { tools?: MCPFunctionTool[] };\n\ninterface SportsGameResult {\n status?: string;\n homeTeam?: string;\n homeScore?: number | string;\n awayTeam?: string;\n awayScore?: number | string;\n}\n\ninterface NewsArticleResult {\n title?: string;\n description?: string;\n summary?: string;\n source?: string;\n publishedAt?: string;\n published?: string;\n url?: string;\n link?: string;\n}\n\ninterface DocSearchResult {\n title?: string;\n url?: string;\n link?: string;\n summary?: string;\n description?: string;\n}\n\ninterface WeatherResult {\n location?: string;\n description?: string;\n temperature?: string | number;\n message?: string;\n details?: string;\n error?: string;\n}\n\ninterface ImageGenerationResult {\n imageUrl?: string;\n revisedPrompt?: string;\n}\n\ninterface MemorySection {\n title: string;\n lines: string[];\n}\n\ninterface PreparedMemoryContext {\n sections: MemorySection[];\n stats: {\n totalAvailable: number;\n selectedCount: number;\n pinnedSelected: number;\n personalSelected: number;\n otherSelected: number;\n tokensUsed: number;\n tokensRemaining: number;\n averageScore: number;\n averageConfidence: number;\n };\n}\n\nconst PERSONAL_TAG_HINTS = [\n \"personal\",\n \"profile\",\n \"bio\",\n \"favorite\",\n \"favourite\",\n \"likes\",\n \"dislikes\",\n \"hobby\",\n \"habit\",\n \"goal\",\n \"interest\",\n \"family\",\n \"relationship\",\n \"background\",\n \"origin\",\n \"birthday\",\n \"anniversary\",\n \"pet\",\n \"values\",\n \"preferences\",\n \"schedule\",\n \"team\",\n \"project\",\n];\n\nconst PERSONAL_TOPIC_HINTS = new Set([\n \"personal\",\n \"preferences\",\n \"preference\",\n \"relationship\",\n \"family\",\n \"friends\",\n \"hobby\",\n \"travel\",\n \"learning\",\n \"education\",\n \"goal\",\n \"goals\",\n \"health\",\n \"wellness\",\n \"project\",\n \"work\",\n \"career\",\n]);\n\nconst clamp = (value: number, min = 0, max = 1) => Math.min(max, Math.max(min, value));\n\nconst parseDateToEpoch = (value?: string | number): number | undefined => {\n if (!value && value !== 0) {\n return undefined;\n }\n\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value === \"string\") {\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? undefined : parsed;\n }\n\n return undefined;\n};\n\nconst normalizeVectorMemory = (memory: VectorMemory): NormalizedVectorMemory | null => {\n const content = memory?.content?.trim();\n if (!content) {\n return null;\n }\n\n const metadata = memory.metadata;\n\n const tagSet = new Set<string>();\n (memory.tags || []).forEach((tag) => {\n if (typeof tag === \"string\") {\n tagSet.add(tag.toLowerCase().trim());\n }\n });\n (metadata?.tags || []).forEach((tag) => {\n if (typeof tag === \"string\") {\n tagSet.add(tag.toLowerCase().trim());\n }\n });\n\n const personalConfidence = metadata?.personalConfidence;\n const engagement = metadata?.engagement;\n const topic = metadata?.topic?.toLowerCase().trim();\n\n return {\n id: memory.id,\n content,\n title: memory.title,\n pinned: Boolean(memory.pinned),\n source: memory.source === \"user\" ? \"user\" : \"auto\",\n score: typeof memory.score === \"number\" ? memory.score : personalConfidence ?? 0,\n tags: Array.from(tagSet),\n uploadedAt: parseDateToEpoch(memory.uploadedAt),\n lastReferencedAt: parseDateToEpoch(memory.lastReferencedAt),\n metadata,\n personalConfidence: typeof personalConfidence === \"number\" ? clamp(personalConfidence) : undefined,\n engagement: typeof engagement === \"number\" ? clamp(engagement) : undefined,\n topic: topic,\n };\n};\n\nconst isPersonalMemory = (memory: NormalizedVectorMemory): boolean => {\n if (memory.pinned || memory.source === \"user\") {\n return true;\n }\n\n if ((memory.personalConfidence ?? 0) >= 0.55) {\n return true;\n }\n\n if (memory.topic && PERSONAL_TOPIC_HINTS.has(memory.topic)) {\n return true;\n }\n\n const title = memory.title?.toLowerCase() || \"\";\n if (PERSONAL_TAG_HINTS.some((hint) => title.includes(hint))) {\n return true;\n }\n\n if (memory.tags.some((tag) => PERSONAL_TAG_HINTS.some((hint) => tag.includes(hint)))) {\n return true;\n }\n\n const metadataTags = (memory.metadata?.tags || []).map((tag) => tag.toLowerCase());\n if (metadataTags.some((tag) => PERSONAL_TAG_HINTS.some((hint) => tag.includes(hint)))) {\n return true;\n }\n\n const additionalValues = memory.metadata?.additionalProperties\n ? Object.values(memory.metadata.additionalProperties)\n : [];\n if (\n additionalValues.some(\n (value) =>\n typeof value === \"string\" &&\n PERSONAL_TAG_HINTS.some((hint) => value.toLowerCase().includes(hint))\n )\n ) {\n return true;\n }\n\n return false;\n};\n\nconst computeRecencyBoost = (memory: NormalizedVectorMemory): number => {\n const reference = memory.lastReferencedAt ?? memory.uploadedAt;\n if (!reference) {\n return 0;\n }\n\n const ageDays = (Date.now() - reference) / (1000 * 60 * 60 * 24);\n if (ageDays <= 1) return 0.2;\n if (ageDays <= 7) return 0.15;\n if (ageDays <= 30) return 0.1;\n if (ageDays <= 90) return 0.05;\n return 0;\n};\n\nconst computeBoostedScore = (memory: NormalizedVectorMemory): number => {\n const baseScore =\n typeof memory.score === \"number\" && memory.score > 0\n ? memory.score\n : memory.pinned\n ? 0.75\n : 0.2;\n const recencyBoost = computeRecencyBoost(memory);\n const personalBoost = memory.personalConfidence ? memory.personalConfidence * 0.25 : 0;\n const engagementBoost = memory.engagement ? memory.engagement * 0.15 : 0;\n const topicBoost = memory.topic && PERSONAL_TOPIC_HINTS.has(memory.topic) ? 0.08 : 0;\n const pinnedBoost = memory.pinned ? 0.25 : 0;\n return baseScore + recencyBoost + personalBoost + engagementBoost + topicBoost + pinnedBoost;\n};\n\nconst formatMemoryLine = (memory: NormalizedVectorMemory): string => {\n const topicDescriptor = !memory.pinned && memory.topic ? `[${memory.topic}] ` : \"\";\n return memory.title ? `${topicDescriptor}${memory.title}: ${memory.content}` : `${topicDescriptor}${memory.content}`;\n};\n\nconst prepareAdvancedMemoryContext = (\n memories: VectorMemory[],\n tokenBudget: number,\n estimateTokens: (text: string) => number\n): PreparedMemoryContext => {\n const normalized = memories\n .map((memory) => normalizeVectorMemory(memory))\n .filter((memory): memory is NormalizedVectorMemory => Boolean(memory));\n\n if (normalized.length === 0) {\n return {\n sections: [],\n stats: {\n totalAvailable: 0,\n selectedCount: 0,\n pinnedSelected: 0,\n personalSelected: 0,\n otherSelected: 0,\n tokensUsed: 0,\n tokensRemaining: tokenBudget,\n averageScore: 0,\n averageConfidence: 0,\n },\n };\n }\n\n const deduped = new Map<string, NormalizedVectorMemory>();\n for (const memory of normalized) {\n const key = memory.id || memory.content.toLowerCase();\n if (!deduped.has(key)) {\n deduped.set(key, memory);\n continue;\n }\n\n const existing = deduped.get(key)!;\n if (computeBoostedScore(memory) > computeBoostedScore(existing)) {\n deduped.set(key, memory);\n }\n }\n\n const memoriesToConsider = Array.from(deduped.values());\n const sortByPriority = (a: NormalizedVectorMemory, b: NormalizedVectorMemory) =>\n computeBoostedScore(b) - computeBoostedScore(a);\n\n const pinned = memoriesToConsider.filter((memory) => memory.pinned).sort(sortByPriority);\n const personal = memoriesToConsider\n .filter((memory) => !memory.pinned && isPersonalMemory(memory))\n .sort(sortByPriority);\n const other = memoriesToConsider\n .filter((memory) => !memory.pinned && !isPersonalMemory(memory))\n .sort(sortByPriority);\n\n const selected: NormalizedVectorMemory[] = [];\n let tokensUsed = 0;\n\n const tryAddMemory = (memory: NormalizedVectorMemory) => {\n if (selected.some((existing) => existing.id === memory.id)) {\n return;\n }\n\n const tokensNeeded = estimateTokens(memory.content);\n if (tokensNeeded <= 0 || tokensUsed + tokensNeeded > tokenBudget) {\n return;\n }\n\n selected.push(memory);\n tokensUsed += tokensNeeded;\n };\n\n pinned.forEach(tryAddMemory);\n personal.forEach(tryAddMemory);\n\n if (selected.length === 0 && personal.length > 0) {\n tryAddMemory(personal[0]);\n }\n\n other.forEach(tryAddMemory);\n\n if (selected.length === 0 && other.length > 0) {\n tryAddMemory(other[0]);\n }\n\n const pinnedSelected = selected.filter((memory) => memory.pinned);\n const personalSelected = selected.filter((memory) => !memory.pinned && isPersonalMemory(memory));\n const otherSelected = selected.filter((memory) => !memory.pinned && !isPersonalMemory(memory));\n\n const sections: MemorySection[] = [];\n if (pinnedSelected.length) {\n sections.push({ title: \"Pinned reminders\", lines: pinnedSelected.map(formatMemoryLine) });\n }\n if (personalSelected.length) {\n sections.push({ title: \"Personal details\", lines: personalSelected.map(formatMemoryLine) });\n }\n if (otherSelected.length) {\n sections.push({ title: \"Helpful context\", lines: otherSelected.map(formatMemoryLine) });\n }\n\n const averageScore = selected.length\n ? Number((selected.reduce((acc, memory) => acc + (memory.score || 0), 0) / selected.length).toFixed(3))\n : 0;\n\n const averageConfidence = selected.length\n ? Number(\n (\n selected.reduce((acc, memory) => acc + (memory.personalConfidence ?? 0), 0) /\n selected.length\n ).toFixed(3)\n )\n : 0;\n\n return {\n sections,\n stats: {\n totalAvailable: memoriesToConsider.length,\n selectedCount: selected.length,\n pinnedSelected: pinnedSelected.length,\n personalSelected: personalSelected.length,\n otherSelected: otherSelected.length,\n tokensUsed,\n tokensRemaining: Math.max(tokenBudget - tokensUsed, 0),\n averageScore,\n averageConfidence,\n },\n };\n};\n\nexport interface UseAIProviderProps {\n isMobile: boolean;\n setStreamBuffer: React.Dispatch<React.SetStateAction<string>>;\n setIsSubmitting: (val: boolean) => void;\n setResponseStarted: (val: boolean) => void;\n setIsStreaming: (val: boolean) => void;\n setResponse: (response: string) => void;\n setPastedImages: React.Dispatch<React.SetStateAction<string[]>>;\n setPendingMessage: React.Dispatch<\n React.SetStateAction<{ question: string; images?: string[] } | null>\n >;\n setLogoVisible: (val: boolean) => void;\n overrideComponentStatus: (status: ComponentStatus) => void;\n setPreviousQuestion: (val: string) => void;\n setInputValue: (value: string) => void;\n history: HistoryEntry[];\n addHistory: (entry: {\n question: string;\n answer: string;\n images?: string[];\n memoryUpdated?: boolean;\n }) => void;\n inputRef: React.RefObject<HTMLInputElement>;\n onError?: (error: unknown) => void;\n}\n\nexport type AIProviderExecutor = ((\n systemPrompt: string,\n question: string,\n images: string[]\n) => Promise<void>) & {\n cancel: () => void;\n};\n\nexport const useAIProvider = ({\n isMobile,\n setStreamBuffer,\n setIsSubmitting,\n setResponseStarted,\n setIsStreaming,\n setResponse,\n setPastedImages,\n setPendingMessage,\n setLogoVisible,\n overrideComponentStatus,\n setPreviousQuestion,\n setInputValue,\n history,\n addHistory,\n inputRef,\n onError,\n}: UseAIProviderProps): AIProviderExecutor => {\n // Stable references for stream and partial content\n const currentSubRef = useRef<Subscription | null>(null);\n const lastPartialRef = useRef<{ text: string; images: string[]; usedDocs: KnowledgeSourceDoc[]; question: string }>({\n text: \"\",\n images: [],\n usedDocs: [],\n question: \"\",\n });\n const flushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n // Pull current provider and settings from stores\n const { provider } = useAIProviderStore.getState();\n const { preferences } = usePreferencesStore.getState();\n const { docs } = useKnowledgeStore.getState();\n\n // Feature helpers\n const { analyzeMood, moodTokenBoost } = useMoodEngine();\n const { runMemoryScan } = useMemoryEnhancer();\n const { isVectorEnabled, searchMemories, searchDocuments, getUserMemories } = useVectorStore();\n\n const pinnedVectorCacheRef = useRef<{ fetchedAt: number; memories: VectorMemory[] }>({\n fetchedAt: 0,\n memories: [],\n });\n\n const getPinnedVectorMemories = useCallback(async (): Promise<VectorMemory[]> => {\n if (!isVectorEnabled) {\n return [];\n }\n\n const now = Date.now();\n const cache = pinnedVectorCacheRef.current;\n if (cache.memories.length && now - cache.fetchedAt < 60_000) {\n return cache.memories;\n }\n\n try {\n const userMemories = (await getUserMemories(0, 200)) as VectorMemory[];\n const pinned = userMemories.filter((memory) => memory.pinned);\n pinnedVectorCacheRef.current = { fetchedAt: now, memories: pinned };\n return pinned;\n } catch (error) {\n debugLogger.warn(\"Pinned memory refresh failed\", { error });\n return cache.memories;\n }\n }, [getUserMemories, isVectorEnabled]);\n\n const clearFlushTimer = () => {\n if (flushTimerRef.current) {\n clearTimeout(flushTimerRef.current);\n flushTimerRef.current = null;\n }\n };\n\n const runAIProvider = useCallback(\n async (systemPrompt: string, question: string, images: string[]) => {\n if (!provider) {\n debugLogger.error(\"No AI provider configured\");\n overrideComponentStatus(\"Error\");\n if (onError) onError(new Error(\"No AI provider configured\"));\n return;\n }\n // Get user preferences from the store\n const userPreferences = preferences;\n\n const isLowIntent = question.trim().toLowerCase().match(/^(hi|hello|hey|yo|what'?s up|how are you)\\??$/i);\n\n overrideComponentStatus(\"Loading\");\n setIsSubmitting(true);\n setResponseStarted(true);\n setIsStreaming(true);\n setResponse(\"\");\n setStreamBuffer(\"\");\n clearFlushTimer();\n const imageList = Array.isArray(images) ? [...images] : [];\n const conversationStoreState = useConversationStore.getState();\n const { addToCurrent, replaceLastAnswer, conversations, currentId } = conversationStoreState;\n const currentConv = conversations.find((c) => c.id === currentId);\n const lastEntry = currentConv?.history.at(-1);\n const lastWasPlaceholder =\n !!lastEntry &&\n lastEntry.answer === \"...\" &&\n (lastEntry.placeholder === true ||\n lastEntry.rawQuestion === question ||\n lastEntry.question === question);\n\n // Keep the pending message in sync with the visible placeholder card\n const pendingQuestion = lastWasPlaceholder ? lastEntry?.question ?? question : question;\n const pendingImagesRaw =\n lastWasPlaceholder && Array.isArray(lastEntry?.images) && lastEntry.images.length > 0\n ? lastEntry.images\n : imageList;\n const pendingImages =\n Array.isArray(pendingImagesRaw) && pendingImagesRaw.length > 0\n ? [...pendingImagesRaw]\n : undefined;\n setPendingMessage({\n question: pendingQuestion,\n images: pendingImages,\n });\n\n // Get current model and config\n const modelName = usePackageSettingsStore.getState().settings?.defaultModel || \"bandit-core:4b-it-qat\";\n const CONFIG = modelConfigs[modelName] ?? modelConfigs[\"bandit-core:4b-it-qat\"];\n\n const base64Images = imageList.map((img) => img.split(\",\")[1]);\n\n const latestEntries = history.slice(-CONFIG.historyMessages);\n const contextMessages: AIMessage[] = latestEntries.flatMap((entry) => [\n { role: \"user\", content: entry.question },\n { role: \"assistant\", content: entry.answer },\n ]);\n\n let tokenLimit = CONFIG.memoryTokenBudget;\n let moodText = \"\";\n\n // Only process mood if enabled in preferences and model supports it\n if (userPreferences.moodEnabled && CONFIG.moodInjection) {\n try {\n const currentMood = await analyzeMood(question);\n tokenLimit += moodTokenBoost; // moodTokenBoost is a number\n moodText = moodPromptMap[currentMood] || \"\";\n } catch (error) {\n debugLogger.warn(\"Failed to analyze mood:\", { error: error instanceof Error ? error.message : String(error) });\n }\n } else if (!userPreferences.moodEnabled) {\n debugLogger.info(\"Mood processing skipped - disabled in preferences\");\n }\n\n let memoryText = \"\";\n let usedDocs: KnowledgeSourceDoc[] = [];\n\n // Only process memory and knowledge documents if enabled in preferences\n if (!isLowIntent && (userPreferences.memoryEnabled || userPreferences.knowledgeDocsEnabled)) {\n try {\n let memoryContent = \"\";\n let docContent = \"\";\n\n // Process memory if enabled\n if (userPreferences.memoryEnabled) {\n if (isVectorEnabled) {\n debugLogger.info('Searching vector memories (advanced search enabled)', {\n memoryLimit: 18,\n scoreThreshold: 0.45,\n });\n\n try {\n const mergedResults = (await searchMemories(question, {\n memoryLimit: 18,\n scoreThreshold: 0.45,\n // Ask backend to append pinned memories so we don't overfetch separately\n filters: { includePinned: true },\n })) as VectorMemory[];\n\n const prepared = prepareAdvancedMemoryContext(\n mergedResults,\n tokenLimit,\n (text) => embeddingService.estimateTokens(text)\n );\n\n if (prepared.sections.length > 0) {\n const sectionText = prepared.sections\n .map((section) => `${section.title}\\n- ${section.lines.join(\"\\n- \")}`)\n .join(\"\\n\\n\");\n\n memoryContent = `Use the following long-term context when it helps personalize your response:\\n\\n${sectionText}\\n\\nReference these details only when they genuinely support the user's latest request.`;\n } else {\n memoryContent = \"\";\n }\n\n debugLogger.memoryDebug(\"Vector memory selection\", {\n tokenLimit,\n totalReturned: mergedResults.length,\n sections: prepared.sections.map((section) => ({\n title: section.title,\n itemCount: section.lines.length,\n })),\n stats: prepared.stats,\n });\n } catch (error) {\n debugLogger.error(\"Vector memory search failed\", { error });\n memoryContent = \"\";\n }\n } else {\n debugLogger.info('Searching local memories (advanced search disabled)');\n\n const memoryList = await embeddingService.selectRelevantMemories(question, tokenLimit);\n debugLogger.memoryDebug(\"Local memory selection\", {\n tokenLimit,\n memoryCount: memoryList.length,\n searchMode: 'local'\n });\n\n memoryContent =\n memoryList.length > 0\n ? `The user has shared the following background information:\\n\\n- ${memoryList.join(\n \"\\n- \"\n )}\\n\\nUse this information to personalize your responses whenever relevant.`\n : \"\";\n }\n } else {\n debugLogger.info(\"Memory processing skipped - disabled in preferences\");\n }\n\n // Process knowledge documents if enabled\n if (userPreferences.knowledgeDocsEnabled) {\n if (isVectorEnabled) {\n // VECTOR MODE: Use vector database exclusively for document search\n debugLogger.info('Searching vector knowledge documents (advanced search enabled)', { \n query: question.slice(0, 100), \n limit: 5, \n scoreThreshold: 0.50 \n });\n \n try {\n const vectorDocs = (await searchDocuments(question, { \n documentLimit: 5, \n scoreThreshold: 0.50 \n })) as RawVectorDocument[];\n \n debugLogger.info('Vector document search completed', { \n resultsCount: vectorDocs.length,\n docNames: vectorDocs.map((doc) => doc.filename || doc.name || 'Unknown')\n });\n\n // Convert vector search results to expected format\n const candidateDocs: KnowledgeSourceDoc[] = vectorDocs.map((result, index) => {\n const docId =\n result?.id ||\n result?.documentId ||\n result?.fileId ||\n result?._id ||\n result?.metadata?.id ||\n result?.metadata?._id ||\n result?.metadata?.fileId;\n const fallbackId = result?.key || result?.filename || result?.name;\n const resolvedId = docId || (fallbackId ? String(fallbackId) : `vector-doc-${index}`);\n\n if (!docId && !fallbackId) {\n debugLogger.warn(\"Vector document result missing identifier\", {\n availableKeys: result ? Object.keys(result) : [],\n sample: (result?.filename || result?.name || \"unknown\").toString(),\n });\n }\n\n return {\n id: resolvedId,\n name: result.filename || result.name || 'Unknown Document',\n content: result.content || 'No content available',\n mimeType: result.mimeType || result.type,\n addedDate: result.uploadedAt ? new Date(result.uploadedAt) : undefined,\n size: result.size,\n uploadedBy: result.uploadedBy,\n userEmail: result.userEmail,\n bucket: result.bucket,\n key: result.key || resolvedId,\n s3Url: resolvedId,\n isUserContent: result.isUserContent,\n isTeamContent: result.isTeamContent,\n contentSource: result.contentSource,\n originalFileName: result.originalFileName || result.filename || result.name,\n // Preserve original data for downstream checks (e.g. vector modal detection)\n _vectorResult: result\n };\n });\n\n // Debug log the actual content received from vector DB\n debugLogger.ragDebug(\"Vector DB content received\", {\n docsCount: candidateDocs.length,\n docs: candidateDocs.map(doc => ({\n name: doc.name,\n hasContent: !!doc.content,\n contentLength: doc.content?.length || 0,\n contentPreview: doc.content?.substring(0, 100) + \"...\" || \"NO CONTENT\"\n }))\n });\n\n let approvedIndexes: number[] = [];\n if (!isLowIntent && candidateDocs.length > 0) {\n debugLogger.ragDebug(\"Starting LLM vetting process for vector docs\", {\n candidateCount: candidateDocs.length,\n candidateNames: candidateDocs.map(d => d.name),\n question: question.substring(0, 150) + \"...\"\n });\n \n // Transform docs to expected format for relevance determination\n const docsForRelevance = candidateDocs.map(doc => ({\n name: doc.name,\n chunks: [doc.content] // Convert single content to chunks array\n }));\n approvedIndexes = await determineRelevantDocuments(question, docsForRelevance);\n \n debugLogger.ragDebug(\"LLM vetting completed for vector docs\", {\n approvedCount: approvedIndexes.length,\n approvedNames: approvedIndexes.map(i => candidateDocs[i]?.name).filter(Boolean),\n rejectedNames: candidateDocs.filter((_, i) => !approvedIndexes.includes(i)).map(d => d.name)\n });\n } else if (isLowIntent) {\n debugLogger.info(\"Skipping knowledge/doc scan for low-intent input\");\n } else {\n debugLogger.info(\"No candidate vector docs available for vetting\");\n }\n \n usedDocs = approvedIndexes\n .map((i) => candidateDocs[i])\n .filter((doc): doc is KnowledgeSourceDoc => Boolean(doc));\n\n debugLogger.ragDebug(\"Final vector document usage\", {\n usedDocsCount: usedDocs.length,\n docNames: usedDocs.map(d => d.name),\n searchMode: 'vector'\n });\n\n } catch (error) {\n debugLogger.error(\"Vector document search failed\", { error });\n // NO FALLBACK - fail cleanly in vector mode\n usedDocs = [];\n }\n } else {\n // LOCAL MODE: Use local IndexedDB documents exclusively \n debugLogger.info('Searching local knowledge documents (advanced search disabled)', { \n totalDocs: docs.length\n });\n\n const queryEmbedding = await embeddingService.generate(question);\n const validDocs = docs.filter(doc => doc.embedding && doc.embedding.length > 0);\n \n debugLogger.ragDebug(\"Local document search initialization\", {\n totalDocs: docs.length,\n validDocsCount: validDocs.length,\n question: question.substring(0, 100) + \"...\",\n docNames: docs.map(d => d.name),\n validDocNames: validDocs.map(d => d.name),\n searchMode: 'local'\n });\n\n if (docs.length === 0) {\n debugLogger.warn(\"No documents available in local knowledge store\");\n } else if (validDocs.length === 0) {\n debugLogger.warn(\"No documents have embeddings - they may need to be reprocessed\", {\n docsWithoutEmbeddings: docs.filter(d => !d.embedding || d.embedding.length === 0).map(d => d.name)\n });\n }\n\n const scoredDocs = validDocs\n .map((doc) => {\n const score = doc.embedding ? embeddingService.cosineSimilarity(queryEmbedding, doc.embedding) : 0;\n \n // Log detailed scoring info for each document\n debugLogger.ragDebug(\"Local document scoring details\", { \n docName: doc.name, \n hasEmbedding: !!doc.embedding,\n score: score.toFixed(4),\n hasContent: !!doc.content,\n contentLength: doc.content?.length || 0,\n strategy: 'low-threshold-llm-vetting'\n });\n \n return { doc, score };\n });\n\n const candidateDocs: KnowledgeSourceDoc[] = scoredDocs\n .filter(entry => entry.score >= 0.50) // Lower threshold, let LLM decide relevance\n .sort((a, b) => b.score - a.score)\n .slice(0, 5)\n .map(entry => entry.doc);\n\n if (candidateDocs.length === 0) {\n debugLogger.warn(\"No documents passed cosine threshold - skipping vetting\", {\n allScores: scoredDocs.map(d => ({ name: d.doc.name, score: d.score.toFixed(3) })),\n threshold: \"0.50\"\n });\n }\n\n let approvedIndexes: number[] = [];\n if (!isLowIntent && candidateDocs.length > 0) {\n debugLogger.ragDebug(\"Starting LLM vetting process for local docs\", {\n candidateCount: candidateDocs.length,\n candidateNames: candidateDocs.map(d => d.name),\n question: question.substring(0, 150) + \"...\"\n });\n \n // Transform docs to expected format for relevance determination\n const docsForRelevance = candidateDocs.map(doc => ({\n name: doc.name,\n chunks: [doc.content] // Convert single content to chunks array\n }));\n approvedIndexes = await determineRelevantDocuments(question, docsForRelevance);\n \n debugLogger.ragDebug(\"LLM vetting completed for local docs\", {\n approvedCount: approvedIndexes.length,\n approvedNames: approvedIndexes.map(i => candidateDocs[i]?.name).filter(Boolean),\n rejectedNames: candidateDocs.filter((_, i) => !approvedIndexes.includes(i)).map(d => d.name)\n });\n } else if (isLowIntent) {\n debugLogger.info(\"Skipping knowledge/doc scan for low-intent input\");\n } else {\n debugLogger.info(\"No candidate local docs available for vetting\");\n }\n \n usedDocs = approvedIndexes\n .map((i) => candidateDocs[i])\n .filter((doc): doc is KnowledgeSourceDoc => Boolean(doc));\n\n debugLogger.ragDebug(\"Final local document selection (trusting LLM vetting)\", {\n selectedDocsCount: usedDocs.length,\n finalSelectedDocs: usedDocs.map(d => d.name),\n searchMode: 'local'\n });\n }\n\n // Generate document content for the prompt\n docContent =\n usedDocs.length > 0\n ? `IMPORTANT CONTEXT - The user has uploaded the following documents that directly relate to their question. You MUST use this information to provide a comprehensive answer. Do NOT say you cannot help or that you need more information when relevant content is provided below.\\n\\n${usedDocs\n .map((doc) => {\n const content = doc.chunks ? doc.chunks.join(\"\\n\\n\") : doc.content || 'No content available';\n debugLogger.ragDebug(\"Document content usage\", {\n docName: doc.name,\n usingChunks: !!doc.chunks,\n contentLength: content.length,\n preview: content.substring(0, 100) + \"...\",\n searchMode: isVectorEnabled ? 'vector' : 'local',\n actualContent: content // Log full content for debugging\n });\n return `📄 **${doc.name}**\\n${content}`;\n })\n .join(\"\\n\\n\")}\\n\\nUSE THE ABOVE CONTENT to answer the user's question. Reference specific information from these documents.`\n : \"\";\n\n debugLogger.ragDebug(\"Final document usage\", {\n usedDocsCount: usedDocs.length,\n docNames: usedDocs.map(d => d.name),\n docContentLength: docContent.length,\n searchMode: isVectorEnabled ? 'vector' : 'local',\n docContent: docContent.substring(0, 500) + \"...\", // Log more content\n hasDocContent: docContent.length > 0,\n actualDocContents: usedDocs.map(d => ({\n name: d.name,\n contentLength: d.content?.length || 0,\n contentPreview: d.content?.substring(0, 200) || \"EMPTY\"\n }))\n });\n } else {\n debugLogger.info(\"Knowledge document processing skipped - disabled in preferences\");\n }\n\n // Combine memory and document content\n memoryText = `${memoryContent ? memoryContent : \"\"}${docContent ? \"\\n\\n\" + docContent : \"\"}`;\n\n } catch (error) {\n debugLogger.warn(\"Failed to process knowledge documents:\", { error: error instanceof Error ? error.message : String(error) });\n }\n } else if (!userPreferences.memoryEnabled && !userPreferences.knowledgeDocsEnabled) {\n debugLogger.info(\"Memory and knowledge document processing skipped - both disabled in preferences\");\n }\n\n // Build the complete system prompt with current date/time context\n const dateTimeContext = getCurrentDateTimeContext();\n let enhancedSystemPrompt = `${systemPrompt}${moodText}${memoryText}${dateTimeContext}`;\n\n // RAG-first guidance so the model confidently uses provided context\n const ragGuidance = `\\n\\n🎯 CONTEXT USAGE DIRECTIVE:\\n- The documents and background information above contain VERIFIED, RELEVANT content for this request\\n- Answer confidently using this provided context - do NOT apologize or claim insufficient information\\n- When documents are provided, they contain the information needed to answer the question\\n- Quote specific details from the documents and cite them as [Doc: NAME]\\n- Combine the provided context with your knowledge to give comprehensive answers\\n- Only use tools for live data (news, weather, sports scores) when specifically requested\\n- Trust and utilize the provided context without hesitation`;\n enhancedSystemPrompt += ragGuidance;\n\n // Add MCP tools information to system prompt if available\n const mcpToolsAvailable = isMCPAvailable();\n if (mcpToolsAvailable) {\n const enabledTools = getEnabledMCPToolsForAI();\n if (enabledTools.length > 0) {\n const toolList = enabledTools\n .map((tool) => {\n const parameterProps = tool.function?.parameters?.properties ?? {};\n const params = Object.keys(parameterProps);\n const paramSuffix = params.length ? ` (parameters: ${params.join(\", \")})` : \"\";\n return `- ${tool.function.name}: ${tool.function.description}${paramSuffix}`;\n })\n .join(\"\\n\");\n const protocol = `\\n\\nTOOL USAGE PROTOCOL (conservative approach)\\n- PRIORITIZE your built-in knowledge and the provided context ABOVE to answer questions first.\\n- Use your training data and general knowledge confidently for common topics, concepts, and questions.\\n- Only call tools for SPECIFIC, CURRENT information that requires real-time data:\\n * news() - ONLY when explicitly asked about recent/breaking news, current events, or \"what's happening now\"\\n * sports() - ONLY when asked about live scores, current games, recent sports results, or league standings\\n * search/documentation tools - ONLY when asked about very specific technical documentation or when you need to supplement your knowledge with current docs\\n- For general questions about concepts, definitions, explanations, or how-to topics, use your built-in knowledge WITHOUT calling tools.\\n- Examples of what NOT to use tools for: \"who are you?\", \"what is React?\", \"explain machine learning\", \"how does X work?\", general programming questions.\\n- When a tool is truly needed, call exactly ONE tool that best matches the request.\\n- Begin tool usage with a fenced code block: \\`\\`\\`tool_code\\nfunctionName({\"param\": \"value\"})\\n\\`\\`\\`\\n- If you cannot answer with your knowledge and context, and no suitable tool exists, ask a clarifying question.\\n\\nExamples of appropriate tool usage:\\n\\n\\`\\`\\`tool_code\\nnews({\"topic\": \"latest AI developments\", \"count\": 5})\\n\\`\\`\\`\\n\\n\\`\\`\\`tool_code\\nsports({\"league\": \"nfl\", \"type\": \"scores\"})\\n\\`\\`\\`\\n`;\n enhancedSystemPrompt += `\\n\\nYou have access to the following tools that can help you provide better responses. Use them when appropriate:\\n\\n${toolList}\\n${protocol}`;\n \n debugLogger.info(\"MCP tools added to system prompt\", { \n toolCount: enabledTools.length,\n toolNames: enabledTools.map(t => t.function.name)\n });\n }\n }\n\n // Prepare messages for AI provider\n const messages: AIMessage[] = [\n { role: \"system\", content: enhancedSystemPrompt },\n ...contextMessages,\n { role: \"user\", content: question }\n ];\n\n // Prepare request\n const request: ToolAwareChatRequest = {\n model: modelName,\n messages,\n stream: true,\n images: base64Images.length > 0 ? base64Images : undefined,\n options: { num_predict: tokenLimit + 250 }\n };\n\n // Add MCP tools to request if available\n if (mcpToolsAvailable) {\n const enabledTools = getEnabledMCPToolsForAI();\n if (enabledTools.length > 0) {\n request.tools = enabledTools;\n debugLogger.info(\"MCP tools added to AI request\", { toolCount: enabledTools.length });\n }\n }\n\n let fullMessage = \"\";\n let latestDisplayMessage = \"\";\n let sawToolBlock = false;\n\n const flushNow = () => {\n clearFlushTimer();\n if (!sawToolBlock) {\n lastPartialRef.current.text = latestDisplayMessage;\n setStreamBuffer(latestDisplayMessage);\n }\n };\n\n const scheduleFlush = (delay = 150) => {\n if (flushTimerRef.current || sawToolBlock) return;\n flushTimerRef.current = setTimeout(() => {\n flushTimerRef.current = null;\n lastPartialRef.current.text = latestDisplayMessage;\n setStreamBuffer(latestDisplayMessage);\n }, delay);\n };\n\n const stream = provider.chat(request);\n const initialPlaceholderQuestion = lastEntry?.question;\n\n // Initialize last-partial tracking for graceful cancel\n lastPartialRef.current = { text: \"\", images: [...imageList], usedDocs, question };\n\n // If a previous stream is still active, cancel it first\n if (currentSubRef.current) {\n try { currentSubRef.current.unsubscribe(); } catch {}\n currentSubRef.current = null;\n }\n\n const sub = stream.subscribe({\n next: (data) => {\n if (!data?.message?.content) return;\n fullMessage += data.message.content;\n // Throttled UI update, apply on all devices (no extra status injection)\n // Detect tool call block and suppress streaming if present\n if (/```(?:tool_code|TOOL_CODE)/.test(fullMessage)) {\n sawToolBlock = true;\n clearFlushTimer();\n }\n latestDisplayMessage = fullMessage;\n if (!sawToolBlock) {\n scheduleFlush();\n }\n },\n error: (err: Error) => {\n debugLogger.error(\"Stream error:\", err);\n overrideComponentStatus(\"Idle\");\n setIsSubmitting(false);\n setIsStreaming(false);\n\n // Finalize with the partial content on error/abort\n flushNow();\n let partial = lastPartialRef.current.text || latestDisplayMessage || fullMessage;\n if (partial && !partial.trim().endsWith(\"…\") && !partial.trim().endsWith(\"...\")) {\n partial = partial.trimEnd() + \" …\"; // append ellipsis to indicate truncation\n }\n if (partial) {\n const { replaceLastAnswer } = useConversationStore.getState();\n replaceLastAnswer(partial, lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);\n setResponse(partial);\n }\n setStreamBuffer(\"\");\n setPendingMessage(null);\n setLogoVisible(false);\n\n // Call the error handler if provided\n if (onError) {\n onError(err);\n }\n },\n complete: async () => {\n try {\n latestDisplayMessage = fullMessage;\n if (!sawToolBlock) {\n flushNow();\n }\n\n // Check for tool calls in the response and execute them\n const toolCallMatches = fullMessage.match(/```(?:tool_code|TOOL_CODE)\\s*\\n([^`]+)\\n```/gi);\n let enhancedMessage = fullMessage;\n\n if (toolCallMatches && toolCallMatches.length > 0 && mcpToolsAvailable) {\n debugLogger.info(\"Detected tool calls in AI response\", {\n toolCallCount: toolCallMatches.length,\n toolCalls: toolCallMatches,\n });\n\n for (const match of toolCallMatches) {\n const toolCallCode = match.replace(/```(?:tool_code|TOOL_CODE)\\s*\\n|\\n```/gi, \"\").trim();\n const functionCallMatch = toolCallCode.match(/^(\\w+)\\(\\s*(.*?)\\s*\\)$/);\n if (!functionCallMatch) continue;\n const [, functionName, params] = functionCallMatch;\n\n try {\n // Parse parameters if any\n let parsedParams: MCPToolParameters = {};\n const raw = params.trim();\n if (raw.length > 0) {\n if (raw.startsWith(\"{\")) {\n parsedParams = JSON.parse(raw);\n } else {\n try {\n parsedParams = JSON.parse(`{${raw}}`);\n } catch (innerErr) {\n debugLogger.warn(\"Failed to parse tool parameters, defaulting to empty object\", {\n raw,\n error: innerErr instanceof Error ? innerErr.message : String(innerErr),\n });\n parsedParams = {};\n }\n }\n }\n\n debugLogger.info(\"Executing MCP tool from AI response\", {\n functionName,\n parameters: parsedParams,\n });\n\n // Insert a neutral loading placeholder while executing\n const placeholderToken = `<<TOOL_LOADING_${functionName}_${Math.random()\n .toString(36)\n .slice(2)}>>`;\n // Replace the fenced block with an invisible placeholder token. Do not update UI yet.\n enhancedMessage = enhancedMessage.replace(match, placeholderToken);\n\n // Execute the tool\n const result = await executeMCPTool({\n toolName: functionName,\n parameters: parsedParams,\n });\n\n // Summarize result (no raw JSON, no tool names)\n let resultText = \"\";\n if (result.success) {\n if (functionName === \"sports\" && Array.isArray(result.data)) {\n const games = (result.data as SportsGameResult[]).filter(Boolean);\n const q = (question || \"\").toLowerCase();\n const normalize = (value: unknown) =>\n typeof value === \"string\" ? value.toLowerCase().replace(/[^a-z0-9 ]/g, \"\") : \"\";\n const tokens = (value: unknown) =>\n normalize(value)\n .split(\" \")\n .filter((w) => w.length > 3);\n const formatTeamScore = (team: unknown, score: unknown) => {\n const teamName = typeof team === \"string\" && team.trim().length > 0 ? team : \"Team\";\n const teamScore =\n typeof score === \"number\" || typeof score === \"string\" ? String(score) : \"—\";\n return `${teamName} ${teamScore}`;\n };\n const scoreLine = (game: SportsGameResult) => {\n const status = typeof game.status === \"string\" ? game.status : \"\";\n const final = status.toLowerCase().includes(\"final\");\n const score = `${formatTeamScore(game.homeTeam, game.homeScore)} — ${formatTeamScore(\n game.awayTeam,\n game.awayScore\n )}`;\n return final ? `Final: ${score}` : `${status || \"In progress\"} — ${score}`;\n };\n let best: SportsGameResult | null = null;\n let bestScore = -1;\n for (const game of games) {\n const homeTokens = tokens(game.homeTeam);\n const awayTokens = tokens(game.awayTeam);\n const hits = [...homeTokens, ...awayTokens].reduce(\n (acc, token) => acc + (q.includes(token) ? 1 : 0),\n 0\n );\n if (hits > bestScore) {\n bestScore = hits;\n best = game;\n }\n }\n if (best && bestScore > 0) {\n resultText = scoreLine(best);\n } else if (games.length > 0) {\n const topGames = games.slice(0, Math.min(5, games.length));\n resultText = `Here are some current scores:\\n- ${topGames.map(scoreLine).join(\"\\n- \")}`;\n } else {\n resultText = \"No games available right now.\";\n }\n } else if (\n functionName === \"image_generation\" ||\n functionName === \"image-generation\"\n ) {\n const imageData = (result.data ?? {}) as ImageGenerationResult;\n const { imageUrl, revisedPrompt } = imageData;\n resultText = imageUrl\n ? `Here you go!\\n\\n![Generated image](${imageUrl})\\n\\n${\n revisedPrompt ? `Prompt refinement: “${revisedPrompt}”\\n` : \"\"\n }Note: the image link may expire in ~2 hours.`\n : \"Image generated successfully.\";\n } else if (functionName === \"news\" && Array.isArray(result.data)) {\n const items = (result.data as NewsArticleResult[]).slice(0, 3);\n resultText = items.length\n ? `## Top News Results\\n\\n${items\n .map((item, index) => {\n const title = item.title ?? \"Untitled\";\n const source = item.source ?? \"Unknown\";\n const url = item.url ?? item.link;\n const description = item.description ?? item.summary;\n const publishedAt = item.publishedAt ?? item.published;\n\n let newsItem = `### ${index + 1}. ${title}\\n`;\n\n if (typeof description === \"string\" && description.length > 0) {\n const truncated =\n description.length > 150 ? `${description.slice(0, 150)}...` : description;\n newsItem += `${truncated}\\n\\n`;\n }\n\n newsItem += `**Source:** ${source}\\n`;\n\n if (publishedAt) {\n const date = new Date(publishedAt);\n if (!Number.isNaN(date.getTime())) {\n newsItem += `**Published:** ${date.toLocaleDateString()} at ${date.toLocaleTimeString(\n [],\n { hour: \"2-digit\", minute: \"2-digit\" }\n )}\\n`;\n }\n }\n\n if (typeof url === \"string\" && url.length > 0) {\n newsItem += `\\n**[📰 Read Full Article](${url})**\\n`;\n }\n\n return newsItem;\n })\n .join(\"\\n---\\n\\n\")}`\n : \"No news results found.\";\n } else if (functionName === \"docs\" && Array.isArray(result.data)) {\n const items = (result.data as DocSearchResult[]).slice(0, 3);\n resultText = items.length\n ? `Relevant docs:\\n- ${items\n .map((item) => {\n const title = item.title ?? \"Untitled doc\";\n const url = item.url ?? item.link;\n return url ? `${title} — ${url}` : title;\n })\n .join(\"\\n- \")}`\n : \"No documentation results found.\";\n } else if (functionName === \"weather\") {\n const weatherData = (result.data ?? {}) as Partial<WeatherResult>;\n const informative = [weatherData.message, weatherData.details, weatherData.error]\n .map((value) => (typeof value === \"string\" ? value.trim() : undefined))\n .filter((value): value is string => Boolean(value) && value.toLowerCase() !== \"n/a\");\n if (informative.length > 0) {\n const locationLabel =\n typeof weatherData.location === \"string\" && weatherData.location.length > 0\n ? ` for ${weatherData.location}`\n : \"\";\n resultText = `Weather service notice${locationLabel}: ${informative.join(\" — \")}`;\n } else {\n const parts = [weatherData.location, weatherData.description, weatherData.temperature]\n .map((value) =>\n typeof value === \"number\" || typeof value === \"string\"\n ? String(value).trim()\n : undefined\n )\n .filter((value): value is string => Boolean(value));\n resultText = parts.length ? parts.join(\" — \") : \"No weather data found.\";\n }\n } else if (typeof result.data === \"string\") {\n resultText = result.data;\n } else if (result.data) {\n resultText = JSON.stringify(result.data, null, 2).slice(0, 1000);\n } else {\n resultText = \"Here are the latest results.\";\n }\n } else {\n const data = (result.data ?? {}) as Partial<WeatherResult> & Record<string, unknown>;\n const informative = [data.message, data.details, data.error, result.error]\n .map((value) => (typeof value === \"string\" ? value.trim() : undefined))\n .filter((value): value is string => Boolean(value) && value.toLowerCase() !== \"n/a\");\n if (functionName === \"weather\" && informative.length) {\n const locationLabel =\n typeof data.location === \"string\" && data.location.length > 0 ? ` for ${data.location}` : \"\";\n resultText = `Weather service issue${locationLabel}: ${informative.join(\" — \")}`;\n } else if (informative.length) {\n resultText = informative.join(\" — \");\n } else {\n resultText = `I couldn't complete that request: ${result.error || \"Unknown error\"}.`;\n }\n }\n\n enhancedMessage = enhancedMessage.replace(placeholderToken, resultText);\n\n debugLogger.info(\"Tool execution completed\", {\n functionName,\n success: result.success,\n resultPreview:\n JSON.stringify(result).substring(0, 100) + \"...\",\n });\n } catch (error) {\n debugLogger.error(\"Failed to execute tool call\", {\n functionName,\n error:\n error instanceof Error ? error.message : String(error),\n });\n\n const friendly = error instanceof Error ? error.message : String(error);\n const errorText = `I ran into an issue completing that step: ${friendly}.`;\n if (enhancedMessage.includes(\"<<TOOL_LOADING_\")) {\n enhancedMessage = enhancedMessage.replace(\n /<<TOOL_LOADING_[^>]+>>/,\n errorText\n );\n } else {\n enhancedMessage = enhancedMessage.replace(match, errorText);\n }\n }\n }\n }\n\n // Wrap up and update UI/history\n overrideComponentStatus(\"Idle\");\n setIsSubmitting(false);\n setPreviousQuestion(question);\n\n if (!enhancedMessage.trim()) {\n enhancedMessage =\n \"Sorry, I got a bit tongue-tied there. Mind asking that again? 😅\";\n }\n\n clearFlushTimer();\n latestDisplayMessage = enhancedMessage;\n lastPartialRef.current.text = enhancedMessage;\n setResponse(enhancedMessage);\n setStreamBuffer(enhancedMessage);\n\n // Only run memory scan if memory is enabled in preferences\n let memoryUpdated = false;\n if (userPreferences.memoryEnabled) {\n memoryUpdated = await runMemoryScan(question, enhancedMessage);\n } else {\n debugLogger.info(\"Memory scan skipped - disabled in preferences\");\n }\n // Update history, then smoothly transition UI state\n const currentState = useConversationStore.getState();\n const conv = currentState.conversations.find((c) => c.id === currentState.currentId);\n const last = conv?.history.at(-1);\n const lastIsPlaceholder =\n !!last && last.answer === \"...\" && last.placeholder !== false;\n\n const preservedImagesSource =\n imageList.length > 0\n ? imageList\n : lastPartialRef.current.images.length > 0\n ? lastPartialRef.current.images\n : last?.images;\n const preservedImages =\n Array.isArray(preservedImagesSource) && preservedImagesSource.length > 0\n ? [...preservedImagesSource]\n : undefined;\n\n if (lastIsPlaceholder) {\n // Replace the temporary entry (if any)\n replaceLastAnswer(enhancedMessage, preservedImages, memoryUpdated, usedDocs);\n } else {\n // Fallback: record a fresh entry and preserve any display question if available\n const historyQuestion =\n (last && last.answer === \"...\" && last.question) ||\n initialPlaceholderQuestion ||\n question;\n addToCurrent({\n question: historyQuestion,\n answer: enhancedMessage,\n images: preservedImages,\n memoryUpdated,\n sourceFiles: usedDocs,\n rawQuestion: question,\n });\n }\n\n setInputValue(\"\");\n setPastedImages([]);\n // Keep buffer visible briefly so the last frame matches final markdown\n setTimeout(() => {\n clearFlushTimer();\n setPendingMessage(null);\n setStreamBuffer(\"\");\n setIsStreaming(false);\n setLogoVisible(false);\n inputRef.current?.focus();\n }, 320);\n } catch (e) {\n debugLogger.error(\"Completion handler failed\", {\n error: e instanceof Error ? e.message : String(e),\n });\n overrideComponentStatus(\"Idle\");\n setIsSubmitting(false);\n setIsStreaming(false);\n }\n },\n });\n currentSubRef.current = sub;\n },\n [\n provider,\n history,\n setResponse,\n overrideComponentStatus,\n setPreviousQuestion,\n setInputValue,\n setPastedImages,\n setPendingMessage,\n setStreamBuffer,\n setIsSubmitting,\n setResponseStarted,\n setLogoVisible,\n inputRef,\n moodTokenBoost,\n analyzeMood,\n runMemoryScan,\n docs,\n setIsStreaming,\n preferences,\n isVectorEnabled,\n searchMemories,\n searchDocuments,\n onError,\n ]\n );\n\n const cancel = () => {\n if (currentSubRef.current) {\n try { currentSubRef.current.unsubscribe(); } catch {}\n currentSubRef.current = null;\n // Finalize with the latest partial so user sees what was generated up to stop point\n let partial = lastPartialRef.current.text;\n if (partial && !partial.trim().endsWith(\"…\") && !partial.trim().endsWith(\"...\")) {\n partial = partial.trimEnd() + \" …\";\n }\n overrideComponentStatus(\"Idle\");\n setIsSubmitting(false);\n setIsStreaming(false);\n if (partial) {\n const { replaceLastAnswer } = useConversationStore.getState();\n replaceLastAnswer(partial, lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);\n setResponse(partial);\n }\n clearFlushTimer();\n setStreamBuffer(\"\");\n setPendingMessage(null);\n setLogoVisible(false);\n }\n };\n\n return Object.assign(runAIProvider, { cancel }) as AIProviderExecutor;\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-96A8-211AAB\nconst __banditFingerprint_hooks_useMemoryEnhancertsx = 'BL-FP-050810-A500';\nconst __auditTrail_hooks_useMemoryEnhancertsx = 'BL-AU-MGOIKVV2-Y7LR';\n// File: useMemoryEnhancer.tsx | Path: src/chat/hooks/useMemoryEnhancer.tsx | Hash: 96a8a500\n\n/**\n * 🧠 Bandit Interest-Focused Memory System (Phase 4)\n *\n * Mission:\n * - Capture meaningful user interests, excitement, and engagement signals\n * - Focus on information that enhances future user experiences\n * - Eliminate noise, creepy data collection, and irrelevant personal details\n * - Build memory that helps provide better, more personalized assistance\n *\n * New Approach - User Interest & Excitement Detection:\n * - Detects when users express passion, enthusiasm, or deep interest\n * - Captures user goals, aspirations, and active projects\n * - Records preferences that affect how AI should respond (format, tone, methods)\n * - Remembers tools, technologies, and workflows users prefer\n * - Tracks learning goals and skill development interests\n * - Ignores casual mentions and demographic trivia\n *\n * Key Improvements:\n * - Interest-based filtering instead of broad \"personal information\" scanning\n * - Enhanced LLM prompts focused on user engagement and excitement\n * - Stricter validation against generic or meaningless content\n * - Emphasis on actionable memory that improves future interactions\n *\n * Privacy-First Design:\n * - Only captures what users are genuinely excited to share\n * - Avoids invasive collection of routine personal details\n * - Focuses on enhancement, not surveillance\n * - User maintains full control (view, edit, pin, delete)\n *\n * Technical Enhancements:\n * - Improved semantic filtering for meaningful content detection\n * - Enhanced personal text recognition for engagement signals\n * - Stricter memory validation against generic statements\n * - Context-aware memory generation focused on user value\n *\n * - 100% local-first, fully user-controllable memory (view, edit, pin, delete).\n *\n * Technical Enhancements:\n * - Cosine similarity thresholds for echo rejection, divergence detection, and merging.\n * - Combined lightweight semantic filters with micro-LLM calls for max precision.\n * - Early foundations laid for memory token budgeting and relevance-based surfacing.\n * - Private semantic memory embeddings managed entirely client-side.\n *\n * Companionware Vision:\n * - Bandit's memory is no longer just reactive — it is **becoming an active companion**.\n * - Every captured memory moves Bandit closer to true contextual alignment with the user.\n * - Bandit is designed to serve as **Private AI Companionware**: evolving with you, not ahead of you.\n *\n * Future Phases:\n * - Phase 4: Auto-pinning highly important memories based on semantic scoring.\n * - Phase 5: Local RAG memory search — using your memories to enhance real-time chats.\n * - Phase 6: Visual memory timeline and relevance controls.\n *\n * Phase 3 Conclusion:\n * > Bandit is no longer just remembering facts.\n * > Bandit is **growing with you** — as a private, local, true AI Companion.\n */\n\nimport { lastValueFrom, map } from \"rxjs\";\nimport { useMemoryStore } from \"../../store/memoryStore\";\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport type { AIGenerateResponse } from \"../../services/ai-provider/types/common.types\";\nimport { useVectorStore } from \"../../hooks/useVectorStore\";\nimport { embeddingService } from \"../../services/embedding/embeddingService\";\nimport { detectUserInterestAndExcitement } from \"../../services/prompts\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { useConversationSyncStore } from \"../../store/conversationSyncStore\";\n\nconst MEMORY_LIMIT = 100;\nconst MIN_MEMORY_WORDS = 3;\nconst MERGE_THRESHOLD = 0.9;\nconst REJECT_ECHO_THRESHOLD = 0.98;\nconst REJECT_DUPLICATE_THRESHOLD = 0.985;\nconst DIVERGENCE_REJECTION_THRESHOLD = 0.65;\nconst CONTEXTUAL_DIVERGENCE_THRESHOLD = 0.75;\n\nconst normalizeText = (text: string) =>\n text\n .toLowerCase()\n .replace(/[^\\w\\s]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n\nconst isStructurallyDuplicate = (a: string, b: string) => {\n const tokensA = new Set(normalizeText(a).split(\" \"));\n const tokensB = new Set(normalizeText(b).split(\" \"));\n const shared = [...tokensA].filter((t) => tokensB.has(t));\n const ratio = shared.length / Math.min(tokensA.size, tokensB.size);\n return ratio > 0.8;\n};\n\nconst isAboutBandit = (text: string) => {\n const lc = text.toLowerCase();\n \n // Allow business/usage context even if it mentions Bandit AI\n const hasBusinessContext = lc.includes(\"business\") || lc.includes(\"help my\") || \n lc.includes(\"use for\") || lc.includes(\"using for\") || lc.includes(\"work with\") ||\n lc.includes(\"building with\") || lc.includes(\"vector db\") || lc.includes(\"setup\");\n \n if (hasBusinessContext) {\n return false; // Don't reject business context memories\n }\n \n // Only reject purely self-referential content about Bandit itself\n return (lc.includes(\"bandit ai\") && (lc.includes(\"you are\") || lc.includes(\"what are you\") || \n lc.includes(\"who are you\") || lc.includes(\"describe yourself\"))) || \n lc.includes(\"you are bandit\");\n};\n\nconst hasEngagementValue = (text: string) => {\n const lc = text.toLowerCase();\n \n // Strong signals for AI/building enthusiasm - always valuable\n const aiEnthusiasm = [\n \"enjoys building with ai\", \"loves building with\", \"building with ai\",\n \"so much fun\", \"really fun\", \"fun to\", \"exciting to\",\n \"passionate about building\", \"excited about\", \"love working with ai\",\n \"ai is fun\", \"found it fun\", \"having fun with\"\n ];\n \n if (aiEnthusiasm.some(signal => lc.includes(signal))) {\n return true; // Always accept AI building enthusiasm\n }\n \n // Look for signals that this memory could enhance future interactions\n const valuableSignals = [\n \"enjoys\", \"loves\", \"passionate about\", \"excited about\",\n \"interested in\", \"working on\", \"focusing on\", \"struggling with\",\n \"needs help with\", \"wants to learn\", \"trying to\", \"hoping to\",\n \"prefers\", \"works best with\", \"uses\", \"specializes in\",\n \"is passionate about\", \"is excited about\", \"is working on\",\n \"wants to learn\", \"goals include\", \"aspires to\", \"dreams of\",\n \"finds helpful\", \"effective approach\", \"preferred method\",\n \"learning\", \"developing\", \"building\", \"creating\", \"studying\",\n // Add business and enthusiasm signals\n \"pumped to use\", \"excited to use\", \"love how\", \"business\",\n \"help my business\", \"for my business\", \"using for work\",\n \"plans to use\", \"wants to use for\",\n // Add AI/building enthusiasm patterns\n \"love building\", \"building with\", \"so much fun\", \"really fun\",\n \"enjoy working\", \"love working\", \"passionate about building\",\n \"excited about\", \"fun to\", \"love using\", \"love how\",\n \"thanks for helping\", \"appreciate help\", \"helpful for\",\n \"setup\", \"vector db\", \"database setup\", \"ai setup\"\n ];\n \n return valuableSignals.some(signal => lc.includes(signal));\n};\n\nconst isMemoryTooShortOrGeneric = (text: string) => {\n const words = text.trim().split(/\\s+/);\n return words.length < MIN_MEMORY_WORDS;\n};\n\nconst isPersonalText = (text: string) => {\n const lc = text.toLowerCase();\n \n // Look for expressions of interest, excitement, or engagement\n const interestSignals = [\n \"i love\", \"i'm excited\", \"i'm passionate about\", \"i'm interested in\",\n \"i really enjoy\", \"i'm working on\", \"i'm learning\", \"i want to\",\n \"my goal\", \"i dream\", \"i hope to\", \"i plan to\", \"i aspire\",\n \"i'm trying to\", \"i need help with\", \"i prefer\", \"i use\",\n \"my favorite approach\", \"i find it helpful\", \"works best for me\",\n // Add business enthusiasm signals\n \"i'm so pumped\", \"pumped to use\", \"excited to use\", \"love how easy\",\n // Add AI/building enthusiasm patterns\n \"love building\", \"building with ai\", \"so much fun\", \"really fun\",\n \"thanks for helping\", \"appreciate the help\", \"helpful with\",\n \"with my\", \"for my\", \"help me with\"\n ];\n \n // Look for project/work engagement\n const engagementSignals = [\n \"i'm building\", \"i'm developing\", \"working on a project\",\n \"i'm studying\", \"i'm focusing on\", \"i specialize in\",\n // Add business context signals\n \"help my business\", \"for my business\", \"business needs\",\n // Add setup/technical enthusiasm\n \"vector db setup\", \"database setup\", \"ai setup\", \"setup process\"\n ];\n \n // Look for preference expressions that could improve responses\n const preferenceSignals = [\n \"i like when\", \"i prefer\", \"it helps when\", \"i find it easier\",\n \"i work better with\", \"i understand better when\"\n ];\n \n return [...interestSignals, ...engagementSignals, ...preferenceSignals]\n .some(signal => lc.includes(signal));\n};\n\nconst mergeMemory = (existing: string, incoming: string) => {\n const sanitizedIncoming = sanitizeMemoryText(incoming);\n const sanitizedExisting = sanitizeMemoryText(existing);\n if (\n sanitizedIncoming === \"NO_UPDATE\" ||\n sanitizedExisting.includes(sanitizedIncoming)\n ) {\n return existing;\n }\n return sanitizedExisting.endsWith(\".\")\n ? `${sanitizedExisting} ${sanitizedIncoming}`\n : `${sanitizedExisting}. ${sanitizedIncoming}`;\n};\n\nconst isVoiceShifted = (text: string) => {\n const lower = text.toLowerCase();\n return (\n lower.includes(\"for me\") || lower.includes(\"they are\") || lower.includes(\"he/she\")\n );\n};\n\nconst sanitizeMemory = (text: string) =>\n text\n .replace(/^_(.*?)_$/g, \"$1\")\n .replace(/_(.*?)_/g, \"$1\")\n .replace(/<\\/?endofturn>/gi, \"\") // Remove any remaining end of turn tokens\n .replace(/\\n+/g, \" \") // Convert newlines to spaces\n .replace(/\\s+/g, \" \") // Normalize whitespace\n .trim();\n\nconst sanitizeMemoryText = (text: string) =>\n text\n .replace(/[_*~`]+/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n\nconst shouldAcceptMemory = async (\n newMemory: string,\n userInput: string,\n shouldUseVectorForMemories: boolean = false,\n forceAccept: boolean = false\n): Promise<boolean> => {\n const { entries } = useMemoryStore.getState();\n\n debugLogger.memoryDebug(\"Memory acceptance validation start\", {\n newMemory: newMemory.slice(0, 150),\n userInput: userInput.slice(0, 100),\n entriesCount: entries.length,\n storageMode: shouldUseVectorForMemories ? 'vector' : 'indexeddb'\n });\n\n if (!newMemory.trim()) {\n debugLogger.memoryDebug(\"Memory rejected - empty or whitespace\", {});\n return false;\n }\n\n if (isAboutBandit(newMemory)) {\n debugLogger.memoryDebug(\"Memory rejected - about Bandit\", { \n memory: newMemory.slice(0, 100) \n });\n return false;\n }\n\n if (forceAccept) {\n debugLogger.memoryDebug(\"Memory force-accepted due to user request\", {\n memory: newMemory.slice(0, 150),\n });\n return true;\n }\n\n if (isMemoryTooShortOrGeneric(newMemory)) {\n debugLogger.memoryDebug(\"Memory rejected - too short or generic\", { \n memory: newMemory.slice(0, 100),\n wordCount: newMemory.trim().split(/\\s+/).length\n });\n return false;\n }\n\n if (!hasEngagementValue(newMemory)) {\n debugLogger.memoryDebug(\"Memory lacks engagement value but accepted\", {\n memory: newMemory.slice(0, 100),\n });\n }\n\n debugLogger.memoryDebug(\"Memory passed basic validation checks\", {\n memory: newMemory.slice(0, 100)\n });\n\n const newEmbedding = await embeddingService.generate(newMemory);\n const inputEmbedding = await embeddingService.generate(userInput);\n\n const echoSim = embeddingService.cosineSimilarity(newEmbedding, inputEmbedding);\n if (\n echoSim >= REJECT_ECHO_THRESHOLD &&\n normalizeText(newMemory) === normalizeText(userInput)\n ) {\n debugLogger.memoryDebug(\"Memory rejected - exact input duplication\", { \n echoSim, \n newMemory: newMemory.slice(0, 100) \n });\n return false;\n }\n\n const divergenceSim = embeddingService.cosineSimilarity(newEmbedding, inputEmbedding);\n // Accept memories that are related but not identical\n // Reject if too similar (echo) or completely unrelated\n if (divergenceSim >= REJECT_ECHO_THRESHOLD) {\n debugLogger.memoryDebug(\"Memory rejected - too similar to input (echo)\", {\n divergenceSim: divergenceSim.toFixed(2),\n threshold: REJECT_ECHO_THRESHOLD\n });\n return false;\n }\n \n // Allow memories that are somewhat related - don't require high similarity\n // This was previously rejecting good memories for being \"divergent\"\n if (divergenceSim < 0.3) {\n debugLogger.memoryDebug(\"Memory loosely related but accepted\", {\n divergenceSim: divergenceSim.toFixed(2),\n threshold: 0.3,\n });\n }\n\n // Only check for duplicates within the same storage system\n if (shouldUseVectorForMemories) {\n // For vector storage, we rely on the vector database's semantic deduplication\n // We don't check against local IndexedDB memories since they're in a different system\n debugLogger.memoryDebug(\"Skipping local duplicate check for vector storage\", {\n memory: newMemory.slice(0, 100)\n });\n } else {\n // For IndexedDB storage, check against existing local memories\n for (const entry of entries) {\n if (!entry.embedding) continue;\n const sim = embeddingService.cosineSimilarity(newEmbedding, entry.embedding);\n if (sim >= REJECT_DUPLICATE_THRESHOLD) {\n debugLogger.memoryDebug(\"Memory rejected - duplicate detected\", {\n similarity: sim.toFixed(2),\n existingContent: entry.content.slice(0, 100)\n });\n return false;\n }\n if (isStructurallyDuplicate(entry.content, newMemory)) {\n debugLogger.memoryDebug(\"Memory rejected - structurally duplicate\", { \n existingContent: entry.content.slice(0, 100) \n });\n return false;\n }\n }\n }\n\n return true;\n};\n\nconst isContextuallyDivergent = async (\n existing: string,\n incoming: string\n): Promise<boolean> => {\n const existingEmbedding = await embeddingService.generate(existing);\n const incomingEmbedding = await embeddingService.generate(incoming);\n const sim = embeddingService.cosineSimilarity(existingEmbedding, incomingEmbedding);\n return sim < CONTEXTUAL_DIVERGENCE_THRESHOLD;\n};\n\nexport const useMemoryEnhancer = () => {\n const { isVectorEnabled, addMemory: addVectorMemory } = useVectorStore();\n const isAdvancedVectorFeaturesEnabled = useConversationSyncStore(\n (state) => state.isAdvancedVectorFeaturesEnabled\n );\n \n const runMemoryScan = async (question: string, response: string) => {\n if (!question.trim() || !response.trim()) return false;\n if (response.length < 20) return false;\n\n const rememberPatterns = [\n /\\bplease\\s+remember\\b/i,\n /\\bcan\\s+you\\s+remember\\b/i,\n /\\bcould\\s+you\\s+remember\\b/i,\n /\\bremember\\s+(?:this|that|it|these|my|for\\s+me)\\b/i,\n /\\bsave\\s+(?:this|that|it|these)\\s+for\\s+later\\b/i,\n /\\bremember\\s+to\\s+call\\b/i,\n /\\badd\\s+(?:this|that|it|these)\\s+to\\s+memories?\\b/i,\n /\\bwill\\s+you\\s+remember\\s+(?:this|that|it|these|for\\s+me)?\\b/i,\n /\\bplease\\s+save\\s+(?:this|that|it|these)\\s+as\\s+(?:a\\s+)?memory\\b/i,\n /\\bremember\\s+this\\s+later\\b/i,\n /\\bdon't\\s+forget\\s+(?:this|that|it|these)\\b/i,\n /\\bkeep\\s+(?:this|that|it|these)\\s+in\\s+mind\\b/i,\n ];\n\n const userRequestedMemory =\n rememberPatterns.some((pattern) => pattern.test(question)) ||\n rememberPatterns.some((pattern) => pattern.test(response));\n\n const personalQuestion = isPersonalText(question);\n const personalResponse = isPersonalText(response);\n const engagementQuestion = hasEngagementValue(question);\n const engagementResponse = hasEngagementValue(response);\n const heuristicPersonalSignals =\n personalQuestion || personalResponse || engagementQuestion || engagementResponse;\n\n // Get the provider fresh each time the function is called\n const provider = useAIProviderStore.getState().provider;\n const settings = usePackageSettingsStore.getState().settings;\n const model = settings?.defaultModel || \"bandit-core\";\n\n if (!provider) {\n debugLogger.error(\"No AI provider available for memory scanning\");\n return false;\n }\n\n // Check if advanced memories are specifically enabled for memory storage\n const shouldUseVectorForMemories = isVectorEnabled && isAdvancedVectorFeaturesEnabled;\n\n debugLogger.memoryDebug(\"Memory storage mode check\", {\n isVectorEnabled,\n isAdvancedVectorFeaturesEnabled,\n shouldUseVectorForMemories,\n questionPreview: question.slice(0, 100)\n });\n\n debugLogger.memoryDebug(\"Memory enhancer start\", {\n questionLength: question.length,\n responseLength: response.length,\n questionPreview: question.slice(0, 150),\n responsePreview: response.slice(0, 150),\n });\n\n debugLogger.memoryDebug(\"Interest and engagement check\", {\n personalQuestion,\n personalResponse,\n engagementQuestion,\n engagementResponse,\n heuristicPersonalSignals,\n question: question.slice(0, 100),\n response: response.slice(0, 100),\n });\n\n let looksPersonal = false;\n let detectionSource: \"user_request\" | \"heuristics\" | \"llm\" = \"llm\";\n\n if (userRequestedMemory) {\n looksPersonal = true;\n detectionSource = \"user_request\";\n debugLogger.memoryDebug(\"Memory scan proceeding due to explicit user request\", {\n questionPreview: question.slice(0, 120),\n });\n } else if (heuristicPersonalSignals) {\n looksPersonal = true;\n detectionSource = \"heuristics\";\n debugLogger.memoryDebug(\"Memory scan proceeding due to heuristic signals\", {\n personalQuestion,\n personalResponse,\n engagementQuestion,\n engagementResponse,\n });\n } else {\n looksPersonal = await detectUserInterestAndExcitement(question, response);\n debugLogger.memoryDebug(\"Personal interest detection result\", {\n looksPersonal,\n questionPreview: question.slice(0, 100),\n });\n }\n\n if (!looksPersonal) {\n debugLogger.info(\"No user interest or excitement detected - skipping memory scan\", {\n questionPreview: question.slice(0, 100),\n detectionSource,\n userRequestedMemory,\n heuristicPersonalSignals,\n });\n return false;\n }\n\n const requestMemorySuggestion = async (\n promptText: string,\n attempt: \"primary\" | \"forced\"\n ): Promise<string | null> => {\n try {\n const result$ = provider.generate({\n model,\n prompt: promptText,\n stream: false,\n options: { temperature: 0.1, num_predict: 150 },\n });\n\n const suggestion = await lastValueFrom(\n result$.pipe(map((chunk: AIGenerateResponse) => chunk.response))\n );\n\n debugLogger.memoryDebug(`LLM memory suggestion received (${attempt})`, {\n suggestion: typeof suggestion === \"string\" ? suggestion.slice(0, 200) : suggestion,\n suggestionType: typeof suggestion,\n });\n\n if (!suggestion || typeof suggestion !== \"string\") {\n debugLogger.warn(`Invalid memory suggestion from LLM (${attempt})`, { suggestion });\n return null;\n }\n\n const cleaned = suggestion\n .replace(/```json|```/g, \"\")\n .replace(/<\\/?endofturn>/gi, \"\")\n .replace(/\\n+/g, \" \")\n .trim();\n const finalMemory = sanitizeMemory(\n cleaned.replace(/^(Bandit AI:|Note:|Suggestion:|Summary:|Memory:)\\s*/i, \"\").trim()\n );\n\n debugLogger.memoryDebug(`Memory cleaned and sanitized (${attempt})`, {\n originalSuggestion: suggestion.slice(0, 200),\n cleaned: cleaned.slice(0, 200),\n finalMemory: finalMemory.slice(0, 200),\n });\n\n return finalMemory;\n } catch (error) {\n debugLogger.error(`Memory suggestion generation failed (${attempt})`, { error });\n return null;\n }\n };\n\n const prompt = `Extract a short personal memory strictly based on what the user explicitly shared.\n- Summarize clearly and naturally using \"the user\" phrasing.\n- Do not invent, infer, or guess additional details.\n- Only state what the user explicitly said, reworded naturally.\n- Speak in the third person (\"the user\"), without addressing the user.\n- Do not add emojis, opinions, or assumptions.\n- Only include background, preferences, or activities.\n${userRequestedMemory ? \"- The user explicitly asked you to remember this; capture the detail they want saved.\\n\" : \"\"}- If no clear personal fact is found, respond exactly with \"NO_UPDATE\".\n\nUser: \"${question}\"\nAssistant: \"${response}\"\n\nRespond with:\n- A clean, short memory statement (strictly factual).\n- Or \"NO_UPDATE\".`.trim();\n\n try {\n let finalMemory = await requestMemorySuggestion(prompt, \"primary\");\n\n if (!finalMemory) {\n return false;\n }\n\n if (finalMemory === \"NO_UPDATE\" && userRequestedMemory) {\n debugLogger.memoryDebug(\"Retrying memory extraction due to explicit user request\", {\n questionPreview: question.slice(0, 120),\n });\n\n const forcedPrompt = `${prompt}\\n\\nThe user explicitly asked you to remember this. Respond with a short third-person memory sentence and do not reply with \"NO_UPDATE\".`;\n const forcedMemory = await requestMemorySuggestion(forcedPrompt, \"forced\");\n if (forcedMemory) {\n finalMemory = forcedMemory;\n }\n }\n\n if (\n finalMemory === \"NO_UPDATE\" ||\n finalMemory.length < 10 ||\n finalMemory.startsWith(\"{\") ||\n finalMemory.startsWith(\"[\")\n ) {\n debugLogger.info(\"Memory rejected - NO_UPDATE or invalid format\", {\n finalMemory,\n reason: finalMemory === \"NO_UPDATE\" ? \"NO_UPDATE\" : \n finalMemory.length < 10 ? \"too short\" : \"invalid format\"\n });\n return false;\n }\n\n const memoryAccepted = await shouldAcceptMemory(\n finalMemory,\n question,\n shouldUseVectorForMemories,\n userRequestedMemory\n );\n debugLogger.memoryDebug(\"Memory validation result\", {\n memoryAccepted,\n finalMemory: finalMemory.slice(0, 150),\n questionPreview: question.slice(0, 100),\n storageMode: shouldUseVectorForMemories ? 'vector' : 'indexeddb'\n });\n \n if (!memoryAccepted) {\n debugLogger.info(\"Memory rejected after validation checks\", {\n finalMemory: finalMemory.slice(0, 150),\n questionPreview: question.slice(0, 100)\n });\n return false;\n }\n\n // Use vector store if both vector is enabled AND advanced memories are specifically enabled\n if (shouldUseVectorForMemories) {\n // For vector store, we don't need to manage merging/duplicates manually\n // as the vector database will handle semantic search and relevance\n try {\n const result = await addVectorMemory(finalMemory, [], 'auto'); // Pass source as 'auto' for automatically detected memories\n if (result.success) {\n debugLogger.info(\"Memory successfully added to vector store\", {\n contentPreview: finalMemory.slice(0, 100),\n source: 'auto'\n });\n return true;\n } else {\n debugLogger.warn(\"Vector memory save failed, falling back to local store\", { \n error: result.error,\n contentPreview: finalMemory.slice(0, 100)\n });\n // Continue with local store logic as fallback\n }\n } catch (error) {\n debugLogger.error(\"Failed to add memory to vector store, falling back to local\", { error });\n // Continue with local store logic as fallback\n }\n }\n\n // Local store logic (original implementation)\n const { entries, addMemory } = useMemoryStore.getState();\n if (entries.length >= MEMORY_LIMIT) {\n debugLogger.warn(\"Memory limit reached - skipping save\", { \n currentCount: entries.length, \n limit: MEMORY_LIMIT \n });\n return false;\n }\n\n const newEmbedding = await embeddingService.generate(finalMemory);\n\n let merged = false;\n for (const entry of entries) {\n if (entry.embedding) {\n const sim = embeddingService.cosineSimilarity(entry.embedding, newEmbedding);\n if (\n isStructurallyDuplicate(entry.content, finalMemory) ||\n (sim >= MERGE_THRESHOLD &&\n !isVoiceShifted(finalMemory) &&\n !(await isContextuallyDivergent(entry.content, finalMemory)))\n ) {\n useMemoryStore.setState((state) => ({\n entries: state.entries.map((e) =>\n e.id === entry.id\n ? { ...e, content: mergeMemory(e.content, finalMemory) }\n : e\n ),\n }));\n merged = true;\n break;\n }\n }\n }\n\n if (!merged) {\n addMemory(finalMemory, [], \"auto\", newEmbedding);\n }\n\n return true;\n } catch (err) {\n debugLogger.error(\"Memory scan failed\", { error: err });\n return false;\n }\n };\n\n return { runMemoryScan };\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-BA71-78AB05\nconst __banditFingerprint_hooks_useMoodEnginetsx = 'BL-FP-E2C2A9-C9A6';\nconst __auditTrail_hooks_useMoodEnginetsx = 'BL-AU-MGOIKVV2-TYFB';\n// File: useMoodEngine.tsx | Path: src/chat/hooks/useMoodEngine.tsx | Hash: ba71c9a6\n\nimport { useState } from \"react\";\nimport { detectMessageMood } from \"../../services/prompts\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\n\nexport type UserMood = \"high\" | \"neutral\" | \"low\";\n\n/**\n * useMoodEngine\n *\n * Centralized hook for detecting and managing user mood.\n * - Uses Bandit's micro-LLM for emotional tone classification.\n * - Persists latest mood in memory for companion awareness.\n * - Can be used to drive UI styling, voice tone, or model behavior.\n */\nexport const useMoodEngine = () => {\n const [mood, setMood] = useState<UserMood>(\"neutral\");\n\n /**\n * Analyze user message and update mood.\n * Optionally logs response for debugging.\n */\n const analyzeMood = async (message: string): Promise<UserMood> => {\n try {\n const detected = await detectMessageMood(message);\n setMood(detected);\n debugLogger.debug(\"🧠 Mood Engine: updated mood to\", { mood: detected });\n return detected;\n } catch (err) {\n debugLogger.warn(\"⚠️ Mood Engine fallback to neutral due to error:\", { error: err });\n setMood(\"neutral\");\n return \"neutral\";\n }\n };\n\n // Reward-based token boost for excited users\n const moodTokenBoost = mood === \"high\" ? 250 : 0;\n\n return {\n mood,\n setMood,\n analyzeMood,\n moodTokenBoost,\n };\n};\n\nexport const moodPromptMap = {\n high: \"The user is highly energized and excited. Respond with enthusiasm, creativity, and momentum.\",\n neutral: \"Respond in your usual helpful, clear, and personable tone.\",\n low: \"The user may be feeling a bit off. Respond gently, with encouragement and calm support.\",\n };\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-1A78-E27B68\nconst __banditFingerprint_mcp_mcpServicets = 'BL-FP-11075C-9BD5';\nconst __auditTrail_mcp_mcpServicets = 'BL-AU-MGOIKVVV-87H3';\n// File: mcpService.ts | Path: src/services/mcp/mcpService.ts | Hash: 1a789bd5\n\nimport { useMCPToolsStore } from \"../../store/mcpToolsStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { authenticationService } from \"../auth/authenticationService\";\nimport { debugLogger } from \"../logging/debugLogger\";\n\nexport interface MCPToolCall {\n toolName: string;\n parameters?: Record<string, unknown>;\n}\n\nexport interface MCPToolResult {\n success: boolean;\n data?: unknown;\n error?: string;\n}\n\nconst isPlaygroundMode = (): boolean => {\n const settings = usePackageSettingsStore.getState().settings;\n if (!settings) {\n return false;\n }\n const gatewayUrl = settings.gatewayApiUrl?.toLowerCase() ?? \"\";\n return Boolean(settings.playgroundMode || gatewayUrl.startsWith(\"playground://\"));\n};\n\n/**\n * Execute an MCP tool by name with the given parameters\n */\nexport const executeMCPTool = async (toolCall: MCPToolCall): Promise<MCPToolResult> => {\n try {\n const { tools } = useMCPToolsStore.getState();\n const { settings } = usePackageSettingsStore.getState();\n\n if (isPlaygroundMode()) {\n debugLogger.info(\"Skipping MCP tool execution in playground mode\", { toolName: toolCall.toolName });\n return {\n success: false,\n error: \"MCP tools are disabled while playground mode is active.\"\n };\n }\n \n // Find the tool\n const tool = tools.find(t => t.function.name === toolCall.toolName && t.enabled);\n if (!tool) {\n return {\n success: false,\n error: `Tool '${toolCall.toolName}' not found or not enabled`\n };\n }\n \n // Ensure gateway is configured (tool execution goes through gateway)\n if (!settings?.gatewayApiUrl) {\n return {\n success: false,\n error: \"Gateway API not configured\"\n };\n }\n\n // Check if tool has an endpoint\n if (!tool.endpoint) {\n return {\n success: false,\n error: `Tool '${toolCall.toolName}' has no endpoint configured`\n };\n }\n \n // Build the API call\n const base = settings.gatewayApiUrl.replace(/\\/$/, \"\");\n let url = `${base}${tool.endpoint}`;\n const method = tool.method || 'GET';\n \n debugLogger.info(\"Executing MCP tool\", { \n toolName: toolCall.toolName, \n method, \n endpoint: tool.endpoint,\n parameters: toolCall.parameters \n });\n \n // Prepare request options\n const requestOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n };\n \n // Add authentication if available\n const token = authenticationService.getToken();\n if (token) {\n requestOptions.headers = {\n ...requestOptions.headers,\n 'Authorization': `Bearer ${token}`,\n };\n }\n \n // Attach parameters\n if (toolCall.parameters && Object.keys(toolCall.parameters).length > 0) {\n if (method === 'GET' || method === 'DELETE') {\n // Append as query string\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(toolCall.parameters)) {\n if (Array.isArray(value)) {\n value.forEach(v => params.append(key, String(v)));\n } else if (value !== undefined && value !== null) {\n params.append(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) {\n url += (url.includes('?') ? '&' : '?') + qs;\n }\n } else {\n // Add body for POST/PUT requests\n requestOptions.body = JSON.stringify(toolCall.parameters);\n }\n }\n \n // Make the API call\n const response = await fetch(url, requestOptions);\n const data = await response.json();\n \n if (!response.ok) {\n debugLogger.error(\"MCP tool execution failed\", { \n toolName: toolCall.toolName, \n status: response.status, \n statusText: response.statusText,\n data \n });\n \n return {\n success: false,\n error: `API call failed: ${response.status} ${response.statusText}`,\n data\n };\n }\n \n debugLogger.info(\"MCP tool executed successfully\", { \n toolName: toolCall.toolName, \n resultPreview: JSON.stringify(data).substring(0, 200) + \"...\"\n });\n \n return {\n success: true,\n data\n };\n \n } catch (error) {\n debugLogger.error(\"MCP tool execution error\", { \n toolName: toolCall.toolName, \n error: error instanceof Error ? error.message : String(error)\n });\n \n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error occurred\"\n };\n }\n};\n\n/**\n * Get all enabled MCP tools formatted for AI provider consumption\n */\nexport const getEnabledMCPToolsForAI = () => {\n const { getEnabledTools } = useMCPToolsStore.getState();\n const enabledTools = getEnabledTools();\n \n return enabledTools.map(tool => ({\n type: tool.type,\n function: tool.function\n }));\n};\n\n/**\n * Check if MCP tools are available and configured\n */\nexport const isMCPAvailable = (): boolean => {\n if (isPlaygroundMode()) {\n return false;\n }\n\n const { settings } = usePackageSettingsStore.getState();\n const { tools } = useMCPToolsStore.getState();\n \n return !!(settings?.gatewayApiUrl && tools.some(t => t.enabled));\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-CB36-E68584\nconst __banditFingerprint_hooks_useAutoScrollts = 'BL-FP-CB225C-6283';\nconst __auditTrail_hooks_useAutoScrollts = 'BL-AU-MGOIKVVE-3F6Z';\n// File: useAutoScroll.ts | Path: src/hooks/useAutoScroll.ts | Hash: cb366283\n\nimport { useRef, useEffect, useCallback } from \"react\";\n\n// A stable event name that components can listen to for scroll state updates\nexport const SCROLL_STATE_CHANGED_EVENT = 'scrollStateChanged';\n\ninterface UseAutoScrollOptions {\n threshold?: number; // Distance from bottom to consider \"near bottom\"\n behavior?: ScrollBehavior;\n enabled?: boolean;\n isMobile?: boolean; // Add mobile flag for smart scrolling\n}\n\nexport const useAutoScroll = (options: UseAutoScrollOptions = {}) => {\n const {\n threshold = 100,\n behavior = \"smooth\",\n enabled = true,\n isMobile = false,\n } = options;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const targetRef = useRef<HTMLDivElement>(null);\n const shouldAutoScrollRef = useRef(true);\n\n // Check if user is near bottom\n const isNearBottom = useCallback(() => {\n const container = containerRef.current;\n if (!container) return true;\n\n const { scrollTop, scrollHeight, clientHeight } = container;\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\n \n // Consider \"near bottom\" if within threshold pixels, with a minimum of 10px\n // to ensure reliable detection after scrollToBottom() completes\n const effectiveThreshold = Math.max(threshold, 10);\n return distanceFromBottom <= effectiveThreshold;\n }, [threshold]);\n\n // Scroll to bottom with mobile-aware behavior\n const scrollToBottom = useCallback((forceBehavior?: ScrollBehavior) => {\n if (!enabled) return;\n \n const container = containerRef.current;\n if (container) {\n // Use scrollTop directly to avoid scrollIntoView issues\n const scrollBehavior = forceBehavior || behavior;\n \n if (isMobile) {\n // On mobile, scroll to show content optimally (not necessarily the very bottom)\n const optimalScrollTop = Math.max(0, container.scrollHeight - container.clientHeight);\n if (scrollBehavior === \"smooth\") {\n container.scrollTo({\n top: optimalScrollTop,\n behavior: \"smooth\"\n });\n } else {\n container.scrollTop = optimalScrollTop;\n }\n } else {\n // Desktop behavior - scroll to absolute bottom\n if (scrollBehavior === \"smooth\") {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: \"smooth\"\n });\n } else {\n container.scrollTop = container.scrollHeight;\n }\n }\n }\n }, [enabled, behavior, isMobile]);\n\n // Force scroll to bottom (ignores auto-scroll state)\n const forceScrollToBottom = useCallback(() => {\n scrollToBottom(\"smooth\");\n \n // Ensure button state updates after forced scroll using rAF to catch the end of scroll\n const container = containerRef.current;\n if (container) {\n let rafId: number | null = null;\n let attempts = 0;\n\n const tick = () => {\n attempts += 1;\n // Dispatch on each frame so listeners can update progressively\n container.dispatchEvent(new CustomEvent(SCROLL_STATE_CHANGED_EVENT));\n\n // Stop once we're near bottom or after a reasonable number of frames\n if (isNearBottom() || attempts > 30) {\n if (rafId) cancelAnimationFrame(rafId);\n return;\n }\n rafId = requestAnimationFrame(tick);\n };\n\n rafId = requestAnimationFrame(tick);\n }\n }, [scrollToBottom, isNearBottom]);\n\n // Auto-scroll if conditions are met\n const autoScrollIfNeeded = useCallback(() => {\n if (enabled && shouldAutoScrollRef.current && isNearBottom()) {\n scrollToBottom();\n \n // Dispatch event(s) to update UI state after auto-scroll using rAF\n const container = containerRef.current;\n if (container) {\n let rafId: number | null = null;\n let frames = 0;\n const pump = () => {\n frames += 1;\n container.dispatchEvent(new CustomEvent(SCROLL_STATE_CHANGED_EVENT));\n if (frames < 20) {\n rafId = requestAnimationFrame(pump);\n } else if (rafId) {\n cancelAnimationFrame(rafId);\n }\n };\n rafId = requestAnimationFrame(pump);\n }\n }\n }, [enabled, isNearBottom, scrollToBottom]);\n\n // Handle scroll events to determine if user manually scrolled\n const containerElement = containerRef.current;\n\n useEffect(() => {\n if (!containerElement) return;\n\n const handleScroll = () => {\n const currentlyNearBottom = isNearBottom();\n\n // Update auto-scroll state based on current position\n shouldAutoScrollRef.current = currentlyNearBottom;\n\n // Always dispatch scroll state change event to ensure UI updates\n containerElement.dispatchEvent(new CustomEvent(SCROLL_STATE_CHANGED_EVENT));\n };\n\n containerElement.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => containerElement.removeEventListener(\"scroll\", handleScroll);\n }, [containerElement, isNearBottom]);\n\n // Auto-scroll on content changes\n useEffect(() => {\n autoScrollIfNeeded();\n });\n\n // Get scroll state info\n const getScrollState = useCallback(() => {\n const container = containerRef.current;\n if (!container) {\n return {\n isNearBottom: true,\n shouldAutoScroll: true,\n canScroll: false,\n scrollTop: 0,\n scrollHeight: 0,\n clientHeight: 0,\n };\n }\n\n const { scrollTop, scrollHeight, clientHeight } = container;\n const canScroll = scrollHeight > clientHeight;\n const nearBottom = isNearBottom();\n \n // Update the ref to reflect current state\n shouldAutoScrollRef.current = nearBottom;\n\n return {\n isNearBottom: nearBottom,\n shouldAutoScroll: nearBottom,\n canScroll,\n scrollTop,\n scrollHeight,\n clientHeight,\n };\n }, [isNearBottom]);\n\n return {\n containerRef,\n targetRef,\n scrollToBottom: forceScrollToBottom,\n autoScrollIfNeeded,\n getScrollState,\n isNearBottom,\n };\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-9120-F74DEA\nconst __banditFingerprint_hooks_useNetworkStatusts = 'BL-FP-517F02-D84F';\nconst __auditTrail_hooks_useNetworkStatusts = 'BL-AU-MGOIKVVE-S29A';\n// File: useNetworkStatus.ts | Path: src/hooks/useNetworkStatus.ts | Hash: 9120d84f\n\nimport { useState, useEffect, useCallback } from \"react\";\n\ntype NetworkEffectiveType = \"slow-2g\" | \"2g\" | \"3g\" | \"4g\";\n\ninterface NetworkInformation extends EventTarget {\n readonly effectiveType?: NetworkEffectiveType;\n readonly downlink?: number;\n readonly rtt?: number;\n readonly saveData?: boolean;\n onchange?: ((this: NetworkInformation, ev: Event) => unknown) | null;\n addEventListener(\n type: \"change\",\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n removeEventListener(\n type: \"change\",\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions\n ): void;\n}\n\ninterface NavigatorWithConnection extends Navigator {\n connection?: NetworkInformation;\n}\n\ninterface NetworkStatus {\n isOnline: boolean;\n isSlowConnection: boolean;\n connectionQuality: \"fast\" | \"slow\" | \"offline\";\n lastRequestTime: number;\n}\n\nexport const useNetworkStatus = () => {\n const [networkStatus, setNetworkStatus] = useState<NetworkStatus>({\n isOnline: navigator.onLine,\n isSlowConnection: false,\n connectionQuality: \"fast\",\n lastRequestTime: 0,\n });\n\n // Track request timing to detect slow connections\n const trackRequestStart = useCallback(() => {\n const startTime = Date.now();\n setNetworkStatus(prev => ({ ...prev, lastRequestTime: startTime }));\n return startTime;\n }, []);\n\n const trackRequestEnd = useCallback((startTime: number) => {\n const duration = Date.now() - startTime;\n const isSlowConnection = duration > 2000; // Consider >2s as slow\n \n setNetworkStatus(prev => ({\n ...prev,\n isSlowConnection,\n connectionQuality: !navigator.onLine \n ? \"offline\" \n : isSlowConnection \n ? \"slow\" \n : \"fast\",\n }));\n }, []);\n\n // Monitor online/offline status\n useEffect(() => {\n const handleOnline = () => {\n setNetworkStatus(prev => ({ \n ...prev, \n isOnline: true, \n connectionQuality: prev.isSlowConnection ? \"slow\" : \"fast\" \n }));\n };\n\n const handleOffline = () => {\n setNetworkStatus(prev => ({ \n ...prev, \n isOnline: false, \n connectionQuality: \"offline\" \n }));\n };\n\n window.addEventListener(\"online\", handleOnline);\n window.addEventListener(\"offline\", handleOffline);\n\n return () => {\n window.removeEventListener(\"online\", handleOnline);\n window.removeEventListener(\"offline\", handleOffline);\n };\n }, []);\n\n // Detect slow connection using Connection API if available\n useEffect(() => {\n const { connection } = navigator as NavigatorWithConnection;\n if (connection) {\n \n const updateConnectionInfo = () => {\n // Consider 2g/slow-2g as slow connections\n const slowConnections = ['slow-2g', '2g'];\n const isSlowConnection = slowConnections.includes(connection.effectiveType);\n \n setNetworkStatus(prev => ({\n ...prev,\n isSlowConnection,\n connectionQuality: !navigator.onLine \n ? \"offline\" \n : isSlowConnection \n ? \"slow\" \n : \"fast\",\n }));\n };\n\n updateConnectionInfo();\n\n const handleChange = () => updateConnectionInfo();\n\n if (typeof connection.addEventListener === \"function\") {\n connection.addEventListener(\"change\", handleChange);\n return () => connection.removeEventListener(\"change\", handleChange);\n }\n\n if (connection) {\n connection.onchange = handleChange;\n return () => {\n if (connection.onchange === handleChange) {\n connection.onchange = null;\n }\n };\n }\n }\n }, []);\n\n return {\n ...networkStatus,\n trackRequestStart,\n trackRequestEnd,\n };\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-0868-1B08DD\nconst __banditFingerprint_chat_chatappbartsx = 'BL-FP-17AC7A-1F59';\nconst __auditTrail_chat_chatappbartsx = 'BL-AU-MGOIKVUW-HL0K';\n// File: chat-app-bar.tsx | Path: src/chat/chat-app-bar.tsx | Hash: 08681f59\n\nimport { Avatar } from \"@mui/material\";\nimport { useModelStore } from \"../store/modelStore\";\nimport { BanditPersonality } from \"../store/modelStore\";\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};\nimport React, { useEffect, useRef, useState } from \"react\";\nimport {\n Box,\n IconButton,\n Menu,\n MenuItem,\n Tooltip,\n useMediaQuery,\n useTheme,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Typography,\n Button,\n} from \"@mui/material\";\nimport HomeIcon from \"@mui/icons-material/Home\";\nimport RecordVoiceOverIcon from \"@mui/icons-material/RecordVoiceOver\";\nimport AddIcon from \"@mui/icons-material/Add\";\nimport SettingsIcon from \"@mui/icons-material/Settings\";\nimport NotesIcon from \"@mui/icons-material/Notes\";\nimport NotesIconOutlined from \"@mui/icons-material/NotesOutlined\";\nimport CloudDoneIcon from \"@mui/icons-material/CloudDone\";\nimport CloudOffIcon from \"@mui/icons-material/CloudOff\";\nimport SyncIcon from \"@mui/icons-material/Sync\";\nimport ErrorOutlineIcon from \"@mui/icons-material/ErrorOutline\";\nimport { useNavigate, type NavigateFunction } from \"react-router-dom\";\nimport { toTitleCase } from \"../util\";\nimport ConversationDrawer from \"./conversation-drawer\";\nimport MobileConversationsModal from \"./enhanced-mobile-conversations-modal\";\nimport { useConversationStore } from \"../store/conversationStore\";\nimport indexedDBService from \"../services/indexedDB/indexedDBService\";\nimport { StoredBanditConfigRecord } from \"../types/config\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { usePreferencesStore } from \"../store/preferencesStore\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport { useFeatures, useFeatureVisibility } from \"../hooks/useFeatures\";\nimport { useConversationSyncStore } from \"../store/conversationSyncStore\";\nimport { shallow } from \"zustand/shallow\";\n\ninterface ChatAppBarProps {\n availableModels: BanditPersonality[];\n handleModelChange: (modelId: string) => void;\n selectedVoice: string;\n availableVoices: string[];\n handleVoiceChange: (voiceId: string) => void;\n drawerOpen: boolean;\n setDrawerOpen: (open: boolean) => void;\n}\n\nconst ChatAppBar: React.FC<ChatAppBarProps> = ({\n availableModels,\n handleModelChange,\n selectedVoice,\n availableVoices,\n handleVoiceChange,\n drawerOpen,\n setDrawerOpen,\n}) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down(\"sm\"));\n\n const hasLoggedRouterWarningRef = useRef(false);\n let navigate: NavigateFunction | null = null;\n try {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n navigate = useNavigate();\n } catch (error) {\n if (!hasLoggedRouterWarningRef.current) {\n debugLogger.warn(\"ChatAppBar: Navigation not available (missing Router context)\", { error });\n hasLoggedRouterWarningRef.current = true;\n }\n navigate = null;\n }\n\n const safeNavigate = (to: string) => {\n if (navigate) {\n navigate(to);\n } else if (typeof window !== \"undefined\") {\n window.location.href = to;\n }\n };\n\n const {\n background,\n border,\n icon,\n iconHover,\n menuBackground,\n menuText,\n } = theme.palette.chat.appBar;\n\n const [modelAnchorEl, setModelAnchorEl] = useState<null | HTMLElement>(null);\n const [voiceAnchorEl, setVoiceAnchorEl] = useState<null | HTMLElement>(null);\n const [modalOpen, setModalOpen] = useState(false);\n\n const [confirmModelChangeOpen, setConfirmModelChangeOpen] = useState(false);\n const [pendingModel, setPendingModel] = useState<string | null>(null);\n\n const { conversations, currentId, createNewConversation, _hasHydrated } =\n useConversationStore();\n const { preferences } = usePreferencesStore();\n const { settings: packageSettings } = usePackageSettingsStore();\n\n const isPlaygroundRoute =\n typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const isPlaygroundMode =\n Boolean(packageSettings?.playgroundMode) ||\n (packageSettings?.gatewayApiUrl ?? \"\").toLowerCase().startsWith(\"playground://\") ||\n (typeof window !== \"undefined\" && window.location.pathname.startsWith(\"/playground\"));\n const managementPath = isPlaygroundMode ? \"/playground/management\" : \"/management\";\n\n const {\n syncEnabled,\n syncStatus,\n lastSyncAt,\n pendingCount,\n warningConversations,\n oversizedConversations,\n triggerSync,\n setSyncEnabled,\n } = useConversationSyncStore((state) => ({\n syncEnabled: state.syncEnabled,\n syncStatus: state.status,\n lastSyncAt: state.lastSyncAt,\n pendingCount:\n state.pendingConversationUpserts.size +\n state.pendingConversationDeletes.size +\n state.pendingProjectUpserts.size +\n state.pendingProjectDeletes.size,\n warningConversations: state.warningConversations,\n oversizedConversations: state.oversizedConversations,\n triggerSync: state.runSync,\n setSyncEnabled: state.setSyncEnabled,\n }), shallow);\n\n useEffect(() => {\n if (isPlaygroundMode && syncEnabled) {\n void setSyncEnabled(false).catch((error) => {\n debugLogger.warn(\"ChatAppBar: Failed to disable sync in playground\", {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }\n }, [isPlaygroundMode, syncEnabled, setSyncEnabled]);\n\n const syncSpinSx = {\n animation: 'spin 1s linear infinite',\n '@keyframes spin': {\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' },\n },\n } as const;\n\n const syncIndicatorIcon = (() => {\n if (isPlaygroundMode || !syncEnabled) {\n return <CloudOffIcon fontSize=\"small\" color=\"disabled\" />;\n }\n switch (syncStatus) {\n case 'syncing':\n return <SyncIcon fontSize=\"small\" sx={syncSpinSx} color=\"primary\" />;\n case 'error':\n return <ErrorOutlineIcon fontSize=\"small\" color=\"error\" />;\n case 'idle':\n default:\n return <CloudDoneIcon fontSize=\"small\" color=\"success\" />;\n }\n })();\n\n const syncTooltip = (() => {\n if (isPlaygroundMode) {\n return \"Cloud sync is unavailable in playground mode.\";\n }\n if (!syncEnabled) {\n return \"Cloud sync is disabled. Enable it from Management > Preferences.\";\n }\n let base: string;\n if (oversizedConversations.length > 0) {\n base = 'Some conversations are too large for Bandit Cloud. Start a new conversation to keep syncing.';\n } else if (syncStatus === 'syncing') {\n base = 'Syncing changes to Bandit Cloud…';\n } else if (warningConversations.length > 0) {\n base = 'Conversations are nearing the Bandit Cloud limit. Consider starting a new one soon.';\n } else if (syncStatus === 'error') {\n base = 'Sync needs attention. Visit Management > Preferences for details.';\n } else {\n base = 'Conversations are in sync with Bandit Cloud.';\n }\n const pending = pendingCount > 0\n ? ` ${pendingCount} change${pendingCount === 1 ? '' : 's'} queued.`\n : '';\n const last = lastSyncAt\n ? ` Last sync ${new Date(lastSyncAt).toLocaleTimeString()}.`\n : '';\n return `${base}${pending}${last}`;\n })();\n\n const syncButtonDisabled = isPlaygroundMode || !syncEnabled;\n\n const handleSyncBadgeClick = () => {\n if (isPlaygroundMode || !syncEnabled || syncStatus === 'syncing') {\n return;\n }\n void triggerSync({ force: true });\n };\n\n // Feature flag checks\n const { hasTTS, hasSTT, isAdmin, getCurrentTier, hasLimitedAdminDashboard } = useFeatures();\n const { showVoiceControls, showLimitedAdminPanel } = useFeatureVisibility();\n\n // Check if TTS is available and enabled\n const isTTSAvailable = !!packageSettings?.gatewayApiUrl && preferences.ttsEnabled && hasTTS();\n\n const currentConversation = conversations.find((c) => c.id === currentId);\n const conversationCountDisplay = conversations.length > 99\n ? \"99+\"\n : conversations.length.toString();\n const isTrulyNewConversation =\n currentConversation?.name === \"New Conversation\" &&\n currentConversation.history.length === 0;\n\n const canShowNewConversationButton =\n _hasHydrated && currentConversation && !isTrulyNewConversation;\n\n // 🧼 Enhanced button styles with better UX\n const pillButtonStyles = {\n width: 36,\n height: 36,\n borderRadius: \"50%\",\n transition: \"all 0.2s cubic-bezier(0.4, 0, 0.2, 1)\",\n color: icon,\n bgcolor: background,\n position: \"relative\",\n \"&:hover\": { \n bgcolor: iconHover,\n transform: \"scale(1.05)\",\n boxShadow: theme.palette.mode === \"dark\" \n ? \"0 2px 8px rgba(255,255,255,0.1)\" \n : \"0 2px 8px rgba(0,0,0,0.1)\",\n },\n \"&:active\": {\n transform: \"scale(0.95)\",\n },\n \"&:focus-visible\": {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: \"2px\",\n },\n } as const;\n\n const selectedModel = useModelStore((s) => s.selectedModel);\n const currentModel = useModelStore((s) => s.availableModels.find((m) => m.name === selectedModel));\n const currentAvatar = currentModel?.avatarBase64 || modelAvatars[selectedModel] || banditHead;\n\n const pendingModelAvatar =\n useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 ||\n modelAvatars[pendingModel || \"\"] ||\n banditHead;\n\n const resolvedHomeUrl = preferences.homeUrl?.trim() || packageSettings?.homeUrl?.trim() || \"\";\n const homeTooltip = (() => {\n if (!resolvedHomeUrl) return \"Home\";\n try {\n return `Home (${new URL(resolvedHomeUrl).hostname})`;\n } catch {\n return \"Home\";\n }\n })();\n\n function goToHome() {\n // Check if user has configured a custom home URL\n if (resolvedHomeUrl) {\n window.location.href = resolvedHomeUrl;\n return;\n }\n\n // Default to React Router navigation within the current app\n if (typeof window !== 'undefined') {\n const navigatorWithStandalone = window.navigator as Navigator & { standalone?: boolean };\n const isStandalone =\n window.matchMedia?.('(display-mode: standalone)').matches ||\n navigatorWithStandalone.standalone === true;\n if (isStandalone) {\n try {\n sessionStorage.setItem('banditPwaStayOnHome', 'true');\n } catch (error) {\n debugLogger.warn('[chat-app-bar] Unable to persist home preference', {\n error: error instanceof Error ? error.message : String(error)\n });\n }\n safeNavigate('/?mode=home');\n return;\n }\n }\n\n safeNavigate('/');\n }\n\n return (\n <>\n <Box\n sx={{\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100%\",\n px: 2,\n py: 1,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n bgcolor: \"transparent\",\n zIndex: 1300,\n pointerEvents: \"none\",\n \"& > *\": {\n pointerEvents: \"auto\",\n },\n }}\n >\n {/* LEFT PILL */}\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n bgcolor: background,\n px: 1.25,\n py: 0.5,\n borderRadius: \"9999px\",\n border: `1px solid ${border}`,\n backdropFilter: \"blur(10px)\",\n boxShadow: theme.palette.mode === \"dark\" \n ? \"0 4px 16px rgba(0,0,0,0.3)\" \n : \"0 4px 16px rgba(0,0,0,0.1)\",\n transition: \"all 0.2s ease-in-out\",\n \"&:hover\": {\n transform: \"translateY(-1px)\",\n boxShadow: theme.palette.mode === \"dark\" \n ? \"0 6px 20px rgba(0,0,0,0.4)\" \n : \"0 6px 20px rgba(0,0,0,0.15)\",\n },\n }}\n >\n <Tooltip title={homeTooltip} arrow>\n <IconButton\n onClick={goToHome}\n sx={pillButtonStyles}\n aria-label=\"Go to home page\"\n >\n <HomeIcon />\n </IconButton>\n </Tooltip>\n \n {showLimitedAdminPanel() && (\n <Tooltip title=\"Management & Settings\" arrow>\n <IconButton \n onClick={() => safeNavigate(managementPath)} \n sx={{\n ...pillButtonStyles,\n ...(typeof window !== \"undefined\" && window.location.pathname === managementPath && {\n bgcolor: theme.palette.primary.main + \"20\",\n color: theme.palette.primary.main,\n }),\n }}\n aria-label=\"Open management settings\"\n >\n <SettingsIcon />\n </IconButton>\n </Tooltip>\n )}\n\n <Tooltip title={syncTooltip} arrow>\n <IconButton\n onClick={handleSyncBadgeClick}\n disabled={syncButtonDisabled}\n sx={{\n ...pillButtonStyles,\n color: syncButtonDisabled ? theme.palette.action.disabled : theme.palette.primary.main,\n bgcolor: syncButtonDisabled\n ? 'transparent'\n : syncStatus === 'error'\n ? theme.palette.error.main + '20'\n : theme.palette.primary.main + '12',\n '&:hover': syncButtonDisabled\n ? {}\n : {\n bgcolor: syncStatus === 'error'\n ? theme.palette.error.main + '30'\n : theme.palette.primary.main + '20',\n },\n }}\n aria-label=\"Conversation sync status\"\n >\n {syncIndicatorIcon}\n {pendingCount > 0 && !syncButtonDisabled && syncStatus !== 'syncing' && (\n <Box\n sx={{\n position: 'absolute',\n top: -2,\n right: -2,\n minWidth: 16,\n height: 16,\n px: 0.3,\n bgcolor: theme.palette.warning.main,\n color: theme.palette.getContrastText(theme.palette.warning.main),\n borderRadius: '999px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '0.6rem',\n fontWeight: 600,\n border: `2px solid ${background}`,\n }}\n >\n {pendingCount > 9 ? '9+' : pendingCount}\n </Box>\n )}\n </IconButton>\n </Tooltip>\n\n {!isMobile && (\n <Tooltip title={`${drawerOpen ? \"Close\" : \"Open\"} Conversations`} arrow>\n <IconButton\n onClick={() => setDrawerOpen(!drawerOpen)}\n sx={{\n ...pillButtonStyles,\n ...(drawerOpen && {\n bgcolor: theme.palette.primary.main + \"20\",\n color: theme.palette.primary.main,\n }),\n }}\n aria-label={`${drawerOpen ? \"Close\" : \"Open\"} conversations drawer`}\n aria-pressed={drawerOpen}\n >\n {drawerOpen ? (\n <NotesIcon />\n ) : (\n <NotesIconOutlined />\n )}\n {conversations.length > 0 && (\n <Box\n sx={{\n position: \"absolute\",\n top: -2,\n right: -2,\n minWidth: 16,\n height: 16,\n px: 0.3,\n bgcolor: theme.palette.primary.main,\n color: \"white\",\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"0.6rem\",\n fontWeight: \"bold\",\n border: `2px solid ${background}`,\n }}\n >\n {conversationCountDisplay}\n </Box>\n )}\n </IconButton>\n </Tooltip>\n )}\n\n {!isMobile && canShowNewConversationButton && (\n <Tooltip title=\"Start New Conversation\" arrow>\n <IconButton \n onClick={() => createNewConversation()} \n sx={{\n ...pillButtonStyles,\n bgcolor: theme.palette.success.main + \"20\",\n color: theme.palette.success.main,\n \"&:hover\": {\n bgcolor: theme.palette.success.main + \"30\",\n transform: \"scale(1.1)\",\n },\n }}\n aria-label=\"Create new conversation\"\n >\n <AddIcon />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n\n {/* RIGHT PILL */}\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n bgcolor: background,\n px: 1.25,\n py: 0.5,\n borderRadius: \"9999px\",\n border: `1px solid ${border}`,\n backdropFilter: \"blur(10px)\",\n boxShadow: theme.palette.mode === \"dark\" \n ? \"0 4px 16px rgba(0,0,0,0.3)\" \n : \"0 4px 16px rgba(0,0,0,0.1)\",\n transition: \"all 0.2s ease-in-out\",\n \"&:hover\": {\n transform: \"translateY(-1px)\",\n boxShadow: theme.palette.mode === \"dark\" \n ? \"0 6px 20px rgba(0,0,0,0.4)\" \n : \"0 6px 20px rgba(0,0,0,0.15)\",\n },\n }}\n >\n {isMobile && (\n <Tooltip title={`Conversations (${conversations.length})`} arrow>\n <IconButton \n onClick={() => setModalOpen(true)} \n sx={{\n ...pillButtonStyles,\n position: \"relative\",\n }}\n aria-label={`Open conversations modal with ${conversations.length} conversations`}\n >\n <NotesIcon fontSize=\"small\" />\n {conversations.length > 0 && (\n <Box\n sx={{\n position: \"absolute\",\n top: -2,\n right: -2,\n minWidth: 14,\n height: 14,\n px: 0.35,\n bgcolor: theme.palette.primary.main,\n color: \"white\",\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"0.55rem\",\n fontWeight: \"bold\",\n border: `1.5px solid ${background}`,\n }}\n >\n {conversationCountDisplay}\n </Box>\n )}\n </IconButton>\n </Tooltip>\n )}\n\n {isMobile && canShowNewConversationButton && (\n <Tooltip title=\"Start New Conversation\" arrow>\n <IconButton\n onClick={() => {\n createNewConversation();\n setModalOpen(false);\n }}\n sx={{\n ...pillButtonStyles,\n bgcolor: theme.palette.success.main + \"20\",\n color: theme.palette.success.main,\n \"&:hover\": {\n bgcolor: theme.palette.success.main + \"30\",\n transform: \"scale(1.1)\",\n },\n }}\n aria-label=\"Create new conversation\"\n >\n <AddIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n\n <Tooltip title={`Current AI: ${selectedModel.replace(\"Bandit-\", \"\")}`} arrow>\n <IconButton\n onClick={(e) => setModelAnchorEl(e.currentTarget)}\n sx={{\n ...pillButtonStyles,\n \"&:hover\": {\n ...pillButtonStyles[\"&:hover\"],\n \"& .MuiAvatar-root\": {\n transform: \"scale(1.1)\",\n filter: \"brightness(2) saturate(1.2)\",\n },\n },\n }}\n aria-label={`Change AI personality. Currently using ${selectedModel}`}\n >\n <Avatar\n src={currentAvatar}\n alt={selectedModel}\n sx={{\n width: \"36px\",\n height: \"36px\",\n filter: \"brightness(1.7)\",\n transition: \"all 0.2s ease-in-out\",\n border: `2px solid ${theme.palette.primary.main}20`,\n }}\n className=\"MuiAvatar-root\"\n />\n </IconButton>\n </Tooltip>\n <Menu\n anchorEl={modelAnchorEl}\n open={Boolean(modelAnchorEl)}\n onClose={() => setModelAnchorEl(null)}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n PaperProps={{\n sx: {\n bgcolor: menuBackground,\n color: menuText,\n fontSize: \"0.875rem\",\n zIndex: 20000,\n borderRadius: 2,\n border: `1px solid ${border}`,\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 minWidth: 200,\n \"& .MuiMenuItem-root\": {\n transition: \"all 0.15s ease-in-out\",\n borderRadius: \"6px\",\n margin: \"2px 4px\",\n \"&:hover\": {\n bgcolor: theme.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: theme.palette.primary.main + \"20\",\n color: theme.palette.primary.main,\n \"&:hover\": {\n bgcolor: theme.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 if (\n !currentConversation?.history.length ||\n currentConversation?.history.length === 0\n ) {\n handleModelChange(model.name);\n useModelStore.getState().setSelectedModel(model.name);\n (async () => {\n try {\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }] as const;\n const current: StoredBanditConfigRecord | undefined = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n const updated: StoredBanditConfigRecord = {\n ...(current ?? {}),\n id: \"main\",\n model: {\n ...(current?.model || {}),\n name: model.name,\n selectedModel: model.name,\n },\n };\n await indexedDBService.put(\"banditConfig\", 1, \"config\", updated, storeConfigs);\n } catch (err) {\n debugLogger.error(\"Failed to persist selectedModel to IndexedDB\", { error: err });\n }\n })();\n setModelAnchorEl(null);\n return;\n }\n\n setPendingModel(model.name);\n setConfirmModelChangeOpen(true);\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: theme.palette.text.secondary, display: \"block\" }}>\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: theme.palette.primary.main,\n }}\n />\n )}\n </MenuItem>\n ))}\n </Menu>\n\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 ...pillButtonStyles,\n bgcolor: theme.palette.info.main + \"20\",\n color: theme.palette.info.main,\n \"&:hover\": {\n ...pillButtonStyles[\"&:hover\"],\n bgcolor: theme.palette.info.main + \"30\",\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: 'right', vertical: 'top' }}\n anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}\n PaperProps={{\n sx: {\n bgcolor: menuBackground,\n color: menuText,\n fontSize: \"0.875rem\",\n zIndex: 20000,\n borderRadius: 2,\n border: `1px solid ${border}`,\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 minWidth: 180,\n \"& .MuiMenuItem-root\": {\n transition: \"all 0.15s ease-in-out\",\n borderRadius: \"6px\",\n margin: \"2px 4px\",\n minHeight: 40,\n \"&:hover\": {\n bgcolor: theme.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: theme.palette.info.main + \"20\",\n color: theme.palette.info.main,\n \"&:hover\": {\n bgcolor: theme.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: 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.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 </Box>\n </Box>\n\n <ConversationDrawer open={drawerOpen} onClose={() => setDrawerOpen(false)} />\n <MobileConversationsModal open={modalOpen} onClose={() => setModalOpen(false)} />\n <Dialog\n open={confirmModelChangeOpen}\n onClose={() => setConfirmModelChangeOpen(false)}\n >\n <DialogTitle>Change personality and start new conversation?</DialogTitle>\n <DialogContent>\n <Box display=\"flex\" alignItems=\"center\" gap={2} mt={1} justifyContent=\"center\">\n <Avatar\n src={pendingModelAvatar}\n alt={pendingModel || \"Personality Avatar\"}\n sx={{ width: 40, height: 40, filter: \"brightness(1.7)\" }}\n />\n <Typography variant=\"body2\">\n Your current conversation will be saved, and a new one will begin with <strong>{pendingModel}</strong>.\n </Typography>\n </Box>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setConfirmModelChangeOpen(false)}>Cancel</Button>\n <Button\n onClick={() => {\n if (pendingModel) {\n createNewConversation();\n handleModelChange(pendingModel);\n useModelStore.getState().setSelectedModel(pendingModel);\n (async () => {\n try {\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }] as const;\n const current: StoredBanditConfigRecord | undefined = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n const updated: StoredBanditConfigRecord = {\n ...(current ?? {}),\n id: \"main\",\n model: {\n ...(current?.model || {}),\n name: pendingModel,\n selectedModel: pendingModel,\n },\n };\n await indexedDBService.put(\"banditConfig\", 1, \"config\", updated, storeConfigs);\n } catch (err) {\n debugLogger.error(\"Failed to persist selectedModel to IndexedDB\", { error: err });\n }\n })();\n\n // Set the model on the new currentConversation\n const { conversations, currentId } = useConversationStore.getState();\n const conv = conversations.find((c) => c.id === currentId);\n if (conv) conv.model = pendingModel;\n }\n setConfirmModelChangeOpen(false);\n }}\n color=\"error\"\n >\n Change Personality\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n\nexport default ChatAppBar;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-2968-6B1DA0\nconst __banditFingerprint_chat_conversationdrawertsx = 'BL-FP-4ABDAD-3ADB';\nconst __auditTrail_chat_conversationdrawertsx = 'BL-AU-MGOIKVUZ-GN4Q';\n// File: conversation-drawer.tsx | Path: src/chat/conversation-drawer.tsx | Hash: 29683adb\n\nimport React, { useState, useMemo, useEffect, useRef, useCallback } from \"react\";\nimport {\n Drawer,\n Box,\n Typography,\n IconButton,\n Tooltip,\n TextField,\n InputAdornment,\n useMediaQuery,\n Collapse,\n Divider,\n Menu,\n MenuItem,\n ListItemIcon,\n ListItemText,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n Avatar,\n alpha,\n} from \"@mui/material\";\nimport {\n Close as CloseIcon,\n Clear as ClearIcon,\n Search as SearchIcon,\n Folder as FolderIcon,\n MoreVert as MoreVertIcon,\n DeleteSweep as DeleteSweepIcon,\n Inbox as InboxIcon,\n} from \"@mui/icons-material\";\nimport { Add as AddIcon } from \"@mui/icons-material\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { useConversationStore, type Conversation } from \"../store/conversationStore\";\nimport { useProjectStore } from \"../store/projectStore\";\nimport { HistoryEntry } from \"../store/aiQueryStore\";\nimport { useAuthenticationStore } from \"../store/authenticationStore\";\nimport brandingService from \"../services/branding/brandingService\";\nimport ProjectManagementModal from \"./project-management-modal\";\nimport MoveConversationModal from \"./move-conversation-modal\";\nimport SimpleConversationItem from \"./simple-conversation-item\";\nimport ProjectHeader from \"./project-header\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { tooltip } from \"../config/tooltips\";\n\ninterface Props {\n open: boolean;\n onClose: () => void;\n}\n\ntype ProjectConversation = Conversation & {\n _snippet?: string;\n};\n\ninterface ProjectGroup {\n id: string | null;\n name: string;\n color?: string;\n conversations: ProjectConversation[];\n collapsed: boolean;\n}\n\nconst BANDIT_AVATAR = \"https://cdn.burtson.ai/images/bandit-head.png\";\n\nconst coerceOptionalString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n};\n\nconst deriveInitials = (value: string): string => {\n if (!value) return \"B\";\n const sanitized = value.trim();\n if (!sanitized) return \"B\";\n\n const words = sanitized.split(/\\s+/).filter(Boolean);\n if (words.length >= 2) {\n const first = words[0]?.charAt(0) ?? \"\";\n const last = words[words.length - 1]?.charAt(0) ?? \"\";\n const initials = `${first}${last}`.trim();\n return initials ? initials.toUpperCase() : sanitized.slice(0, 2).toUpperCase();\n }\n\n const alphanumeric = sanitized.replace(/[^A-Za-z0-9]/g, \"\");\n if (alphanumeric.length >= 2) {\n return alphanumeric.slice(0, 2).toUpperCase();\n }\n if (alphanumeric.length === 1) {\n return alphanumeric.toUpperCase();\n }\n return sanitized.slice(0, 2).toUpperCase();\n};\n\nconst ConversationDrawer: React.FC<Props> = ({ open, onClose }) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down(\"sm\"));\n const { user } = useAuthenticationStore();\n const baseRadius = typeof theme.shape.borderRadius === \"number\"\n ? theme.shape.borderRadius\n : parseFloat(theme.shape.borderRadius) || 0;\n const drawerCornerRadius = baseRadius * 3;\n \n const {\n conversations,\n currentId,\n switchConversation,\n deleteConversation,\n renameConversation,\n createNewConversation,\n clearAllConversations,\n moveConversationToProject,\n getConversationsByProject,\n } = useConversationStore();\n\n const {\n projects,\n _hasHydrated: projectsHydrated,\n hydrate: hydrateProjects,\n createProject,\n deleteProject,\n } = useProjectStore();\n\n // State for UI\n const [projectManagementOpen, setProjectManagementOpen] = useState(false);\n const [collapsedProjects, setCollapsedProjects] = useState<Set<string>>(new Set());\n const didInitCollapseRef = useRef(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);\n const [clearConfirmOpen, setClearConfirmOpen] = useState(false);\n const [moveModalOpen, setMoveModalOpen] = useState(false);\n const [conversationToMove, setConversationToMove] = useState<Conversation | null>(null);\n const [renameProjectId, setRenameProjectId] = useState<string | null>(null);\n\n const getCustomClaim = useCallback((key: string): string | undefined => {\n if (!user) return undefined;\n const record = user as unknown as Record<string, unknown>;\n return coerceOptionalString(record[key]);\n }, [user]);\n\n const userDisplayName = useMemo(() => {\n if (!user) return undefined;\n\n const candidateFields = [\n coerceOptionalString(user.name),\n coerceOptionalString(user.preferred_username),\n user.given_name && user.family_name\n ? coerceOptionalString(`${user.given_name} ${user.family_name}`)\n : undefined,\n getCustomClaim(\"full_name\"),\n getCustomClaim(\"displayName\"),\n ];\n\n const resolvedName = candidateFields.find(Boolean);\n if (resolvedName) return resolvedName;\n\n const trimmedEmail = coerceOptionalString(user.email);\n if (trimmedEmail) return trimmedEmail;\n\n return user.sub;\n }, [user, getCustomClaim]);\n\n const userSecondaryText = useMemo(() => {\n if (!user) return undefined;\n\n const trimmedEmail = coerceOptionalString(user.email);\n if (trimmedEmail && trimmedEmail !== userDisplayName) {\n return trimmedEmail;\n }\n\n const subId = coerceOptionalString(user.sub);\n if (subId && subId !== userDisplayName) {\n return subId;\n }\n\n return undefined;\n }, [user, userDisplayName]);\n\n const [avatarImage, setAvatarImage] = useState<string>(BANDIT_AVATAR);\n\n useEffect(() => {\n const fetchBranding = async () => {\n try {\n const branding = await brandingService.getBranding();\n setAvatarImage(branding?.logoBase64 || BANDIT_AVATAR);\n } catch (error) {\n debugLogger.error(\"Failed to load branding avatar\", {\n error: error instanceof Error ? error.message : String(error),\n });\n setAvatarImage(BANDIT_AVATAR);\n }\n };\n\n fetchBranding();\n }, []);\n\n const avatarLabel = userDisplayName || user?.email || \"Bandit\";\n const avatarInitials = useMemo(() => deriveInitials(avatarLabel), [avatarLabel]);\n\n // Hydrate projects on mount\n useEffect(() => {\n if (!projectsHydrated) {\n hydrateProjects();\n }\n }, [projectsHydrated, hydrateProjects]);\n\n // Collapse all projects by default after projects hydrate (one-time)\n useEffect(() => {\n if (projectsHydrated && !didInitCollapseRef.current) {\n didInitCollapseRef.current = true;\n if (projects && projects.length > 0) {\n setCollapsedProjects(new Set(projects.map(p => p.id)));\n }\n }\n }, [projectsHydrated, projects]);\n\n // Build searchable results with a short snippet from questions/answers\n const buildSnippet = (text: string, query: string, idx: number) => {\n const start = Math.max(0, idx - 40);\n const end = Math.min(text.length, idx + query.length + 60);\n return text.slice(start, end).replace(/\\s+/g, \" \").trim();\n };\n\n // Organize conversations by projects\n const projectGroups = useMemo((): ProjectGroup[] => {\n const groups: ProjectGroup[] = projects.map((project) => ({\n id: project.id,\n name: project.name,\n color: project.color,\n conversations: conversations\n .filter((conversation) => conversation.projectId === project.id)\n .map<ProjectConversation>((conversation) => ({\n ...conversation,\n })),\n collapsed: collapsedProjects.has(project.id),\n }));\n\n const ungroupedConversations = conversations\n .filter((conversation) => !conversation.projectId)\n .map<ProjectConversation>((conversation) => ({\n ...conversation,\n }));\n\n if (ungroupedConversations.length > 0) {\n groups.push({\n id: null,\n name: \"Ungrouped\",\n conversations: ungroupedConversations,\n collapsed: false,\n });\n }\n\n return groups.filter((group) => group.conversations.length > 0 || group.id !== null);\n }, [projects, conversations, collapsedProjects]);\n\n // Filter conversations based on search query and attach snippet previews\n const filteredProjectGroups = useMemo((): ProjectGroup[] => {\n if (!searchQuery.trim()) return projectGroups;\n\n const query = searchQuery.toLowerCase();\n\n return projectGroups\n .map(group => {\n const conversationsWithSnippets = group.conversations\n .map<ProjectConversation | null>((conv) => {\n if (conv.name.toLowerCase().includes(query)) {\n return { ...conv, _snippet: undefined };\n }\n\n for (const entry of conv.history as HistoryEntry[]) {\n const body = `${entry.question || \"\"} ${entry.answer || \"\"}`;\n const hay = body.toLowerCase();\n const idx = hay.indexOf(query);\n if (idx !== -1) {\n return { ...conv, _snippet: buildSnippet(body, query, idx) };\n }\n }\n return null;\n })\n .filter((conv): conv is ProjectConversation => conv !== null);\n\n return {\n ...group,\n conversations: conversationsWithSnippets,\n };\n })\n .filter(group => group.conversations.length > 0);\n }, [projectGroups, searchQuery]);\n\n const handleToggleProject = (projectId: string | null) => {\n const key = projectId || \"ungrouped\";\n const newCollapsed = new Set(collapsedProjects);\n if (newCollapsed.has(key)) {\n newCollapsed.delete(key);\n } else {\n newCollapsed.add(key);\n }\n setCollapsedProjects(newCollapsed);\n };\n\n const handleDropConversation = (projectId: string | null, conversationId: string) => {\n moveConversationToProject(conversationId, projectId === null ? null : projectId);\n };\n\n const handleCreateConversation = () => {\n createNewConversation();\n if (isMobile) {\n onClose();\n }\n };\n\n const handleSearchClear = () => {\n setSearchQuery(\"\");\n };\n\n const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {\n setMenuAnchorEl(event.currentTarget);\n };\n\n const handleMenuClose = () => {\n setMenuAnchorEl(null);\n };\n\n const handleClearAllConfirm = async () => {\n try {\n await clearAllConversations();\n setClearConfirmOpen(false);\n handleMenuClose();\n } catch (error) {\n debugLogger.error(\"Failed to clear conversations:\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n const handleMoveConversation = (conversation: ProjectConversation) => {\n setConversationToMove(conversation);\n setMoveModalOpen(true);\n };\n\n const handleMoveModalClose = () => {\n setMoveModalOpen(false);\n setConversationToMove(null);\n };\n\n return (\n <>\n <Drawer\n anchor=\"left\"\n open={open}\n onClose={onClose}\n variant={isMobile ? \"temporary\" : \"persistent\"}\n sx={{\n width: isMobile ? \"auto\" : 340,\n flexShrink: 0,\n \"& .MuiDrawer-paper\": {\n width: isMobile ? `min(94vw, 360px)` : 340,\n maxWidth: 360,\n bgcolor: theme.palette.background.paper,\n borderRight: `1px solid ${isMobile ? alpha(theme.palette.divider, 0.4) : theme.palette.divider}`,\n display: \"flex\",\n flexDirection: \"column\",\n height: isMobile ? `calc(100dvh - ${theme.spacing(4)})` : \"100dvh\",\n top: isMobile ? theme.spacing(2) : 0,\n bottom: isMobile ? theme.spacing(2) : 0,\n left: 0,\n borderRadius: isMobile ? `0 ${drawerCornerRadius}px ${drawerCornerRadius}px 0` : 0,\n boxShadow: isMobile ? `0 18px 36px ${alpha(theme.palette.common.black, 0.28)}` : \"none\",\n overflow: \"hidden\",\n },\n }}\n ModalProps={{\n keepMounted: true, // Better performance on mobile\n ...(isMobile && {\n onBackdropClick: onClose, // Ensure backdrop click closes on mobile\n }),\n }}\n SlideProps={{\n ...(isMobile && {\n onExited: () => {}, // Ensure slide animation completes\n }),\n }}\n >\n {/* Header */}\n <Box\n sx={{\n p: 2,\n borderBottom: `1px solid ${theme.palette.divider}`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n gap: 1,\n }}\n >\n <Tooltip title={tooltip(\"manageProjects\")} arrow>\n <IconButton\n onClick={() => setProjectManagementOpen(true)}\n size=\"small\"\n aria-label={tooltip(\"manageProjects\")}\n sx={{\n color: theme.palette.text.secondary,\n \"&:hover\": {\n color: theme.palette.primary.main,\n bgcolor: alpha(theme.palette.primary.main, 0.1),\n },\n }}\n >\n <FolderIcon />\n </IconButton>\n </Tooltip>\n\n <Tooltip title={tooltip(\"conversationOptions\")} arrow>\n <IconButton\n onClick={handleMenuOpen}\n size=\"small\"\n aria-label={tooltip(\"conversationOptions\")}\n sx={{\n color: theme.palette.text.secondary,\n \"&:hover\": {\n color: theme.palette.text.primary,\n bgcolor: alpha(theme.palette.text.primary, 0.1),\n },\n }}\n >\n <MoreVertIcon />\n </IconButton>\n </Tooltip>\n \n {isMobile && (\n <Tooltip title={tooltip(\"closeConversationsPanel\")}>\n <IconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onClose();\n }}\n size=\"small\"\n aria-label={tooltip(\"closeConversationsPanel\")}\n sx={{ \n color: theme.palette.text.secondary,\n \"&:hover\": {\n color: theme.palette.error.main,\n bgcolor: alpha(theme.palette.error.main, 0.1),\n },\n }}\n >\n <CloseIcon />\n </IconButton>\n </Tooltip>\n )}\n </Box>\n\n {/* Search Bar */}\n <Box sx={{ p: 2, pb: 1 }}>\n <TextField\n fullWidth\n size=\"small\"\n placeholder=\"Search conversations and content...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n variant=\"outlined\"\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon fontSize=\"small\" sx={{ color: theme.palette.text.secondary }} />\n </InputAdornment>\n ),\n endAdornment: searchQuery && (\n <InputAdornment position=\"end\">\n <Tooltip title={tooltip(\"clearSearch\")}>\n <IconButton\n onClick={handleSearchClear}\n size=\"small\"\n edge=\"end\"\n aria-label={tooltip(\"clearSearch\")}\n sx={{ color: theme.palette.text.secondary }}\n >\n <ClearIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </InputAdornment>\n ),\n }}\n sx={{\n \"& .MuiOutlinedInput-root\": {\n bgcolor: alpha(theme.palette.background.default, 0.5),\n \"&:hover\": {\n bgcolor: alpha(theme.palette.background.default, 0.8),\n },\n \"&.Mui-focused\": {\n bgcolor: theme.palette.background.default,\n },\n },\n }}\n />\n </Box>\n\n {/* Content */}\n <Box sx={{ flex: 1, overflow: \"auto\", display: \"flex\", flexDirection: \"column\" }}>\n {/* Quick Add Project */}\n <Box\n onClick={async () => {\n const names = new Set(projects.map(p => p.name));\n const base = \"New Project\";\n let name = base;\n if (names.has(name)) {\n for (let i = 2; i < 1000; i++) {\n const candidate = `${base} ${i}`;\n if (!names.has(candidate)) { name = candidate; break; }\n }\n }\n try {\n const created = await createProject(name);\n setRenameProjectId(created.id);\n } catch (error) {\n debugLogger.error(\"Failed to create project\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }}\n sx={{\n px: 2,\n py: 1.25,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n cursor: \"pointer\",\n '&:hover': { bgcolor: alpha(theme.palette.text.primary, 0.04) },\n }}\n >\n <Box\n sx={{\n width: 28,\n height: 28,\n borderRadius: \"50%\",\n bgcolor: alpha(theme.palette.success.main, 0.15),\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <FolderIcon fontSize=\"small\" sx={{ color: theme.palette.success.main }} />\n </Box>\n <Typography\n variant=\"subtitle2\"\n sx={{ flex: 1, fontWeight: 600, fontSize: \"0.875rem\" }}\n >\n New Project\n </Typography>\n <Tooltip title={tooltip(\"addProject\")} arrow>\n <IconButton\n size=\"small\"\n aria-label={tooltip(\"addProject\")}\n sx={{ color: theme.palette.success.main }}\n >\n <AddIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n <Divider sx={{ opacity: 0.3 }} />\n\n {filteredProjectGroups.map((group, index) => (\n <Box key={group.id || \"ungrouped\"}>\n {/* Add visual separator before ungrouped section */}\n {group.id === null && filteredProjectGroups.length > 1 && (\n <Box\n sx={{\n py: 2,\n px: 2,\n display: \"flex\",\n alignItems: \"center\",\n gap: 2,\n }}\n >\n <Divider sx={{ flex: 1, opacity: 0.6 }} />\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <InboxIcon \n sx={{ \n color: theme.palette.text.disabled,\n fontSize: \"0.9rem\",\n opacity: 0.7,\n }} \n />\n <Typography \n variant=\"caption\" \n sx={{ \n color: theme.palette.text.disabled,\n fontSize: \"0.7rem\",\n fontWeight: 500,\n letterSpacing: \"0.5px\",\n textTransform: \"uppercase\",\n }}\n >\n Other Conversations\n </Typography>\n </Box>\n <Divider sx={{ flex: 1, opacity: 0.6 }} />\n </Box>\n )}\n\n {/* Only show project header for actual projects, not ungrouped */}\n {group.id !== null ? (\n <>\n <ProjectHeader\n projectId={group.id}\n projectName={group.name}\n projectColor={group.color}\n conversationCount={group.conversations.length}\n isCollapsed={group.collapsed}\n onToggleCollapse={() => handleToggleProject(group.id)}\n onDropConversation={(conversationId) => \n handleDropConversation(group.id, conversationId)\n }\n isRenaming={renameProjectId === group.id}\n onRenameComplete={() => setRenameProjectId(null)}\n onRenameCancelDelete={async () => {\n if (renameProjectId === group.id) {\n try {\n if (typeof group.id === 'string') {\n await deleteProject(group.id);\n }\n } catch (error) {\n debugLogger.error(\"Failed to delete project\", {\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n setRenameProjectId(null);\n }\n }\n }}\n />\n \n <Collapse in={!group.collapsed}>\n <Box sx={{ pb: 1 }}>\n {group.conversations.map((conversation) => (\n <SimpleConversationItem\n key={conversation.id}\n conversation={conversation}\n isSelected={conversation.id === currentId}\n onSelect={() => {\n switchConversation(conversation.id);\n if (isMobile) {\n // Force close on mobile after conversation switch\n setTimeout(() => onClose(), 100);\n }\n }}\n onDelete={() => deleteConversation(conversation.id)}\n onRename={(newName) => renameConversation(conversation.id, newName)}\n onMove={() => handleMoveConversation(conversation)}\n projectColor={group.color}\n snippet={searchQuery ? conversation._snippet : undefined}\n searchQuery={searchQuery.trim() || undefined}\n />\n ))}\n \n {group.conversations.length === 0 && !group.collapsed && group.id !== null && (\n <Box\n sx={{\n p: 3,\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <Typography variant=\"body2\">\n No conversations in this project yet\n </Typography>\n <Typography variant=\"caption\" sx={{ mt: 1, display: \"block\" }}>\n Drag conversations here or use the + button above\n </Typography>\n </Box>\n )}\n </Box>\n </Collapse>\n \n <Divider sx={{ opacity: 0.3 }} />\n </>\n ) : (\n // Special handling for ungrouped - no header, just conversations in scrollable area\n <Box \n sx={{ \n minHeight: 0, // Allow shrinking\n overflow: \"auto\",\n px: 1,\n py: 1,\n bgcolor: alpha(theme.palette.background.default, 0.3),\n borderRadius: \"8px 8px 0 0\",\n mx: 1,\n mb: 1,\n }}\n >\n {group.conversations.map((conversation) => (\n <SimpleConversationItem\n key={conversation.id}\n conversation={conversation}\n isSelected={conversation.id === currentId}\n onSelect={() => {\n switchConversation(conversation.id);\n if (isMobile) {\n // Force close on mobile after conversation switch\n setTimeout(() => onClose(), 100);\n }\n }}\n onDelete={() => deleteConversation(conversation.id)}\n onRename={(newName) => renameConversation(conversation.id, newName)}\n onMove={() => handleMoveConversation(conversation)}\n projectColor={group.color}\n snippet={searchQuery ? conversation._snippet : undefined}\n searchQuery={searchQuery.trim() || undefined}\n />\n ))}\n </Box>\n )}\n </Box>\n ))}\n \n {filteredProjectGroups.length === 0 && (\n <Box\n sx={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n p: 4,\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <Typography variant=\"h6\" sx={{ mb: 1 }}>\n {searchQuery ? \"No conversations found\" : \"No conversations yet\"}\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 3, maxWidth: 280 }}>\n {searchQuery \n ? `No conversations match \"${searchQuery}\"`\n : \"Start your first conversation to begin organizing your chats into projects\"\n }\n </Typography>\n </Box>\n )}\n </Box>\n\n {/* User badge */}\n <Box\n sx={{\n mt: \"auto\",\n px: 2,\n py: 1.75,\n borderTop: `1px solid ${alpha(theme.palette.divider, 0.6)}`,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n justifyContent: \"center\",\n bgcolor: alpha(theme.palette.background.default, isMobile ? 0.9 : 0.6),\n }}\n >\n <Avatar\n src={avatarImage}\n alt={avatarLabel}\n sx={{\n width: 36,\n height: 36,\n fontSize: \"0.95rem\",\n bgcolor: alpha(theme.palette.primary.main, 0.12),\n color: theme.palette.primary.main,\n }}\n >\n {avatarInitials}\n </Avatar>\n <Box\n sx={{\n minWidth: 0,\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: isMobile ? \"center\" : \"flex-start\",\n textAlign: isMobile ? \"center\" : \"left\",\n gap: 0.25,\n }}\n >\n <Typography\n variant=\"subtitle2\"\n noWrap\n sx={{ fontWeight: 600, color: theme.palette.text.primary }}\n >\n {user ? userDisplayName : \"Not signed in\"}\n </Typography>\n {!user && (\n <Typography\n variant=\"caption\"\n sx={{ color: theme.palette.text.secondary }}\n >\n Connect your account to sync chats\n </Typography>\n )}\n </Box>\n </Box>\n </Drawer>\n\n {/* Project Management Modal */}\n <ProjectManagementModal\n open={projectManagementOpen}\n onClose={() => setProjectManagementOpen(false)}\n />\n\n {/* Move Conversation Modal */}\n {conversationToMove && (\n <MoveConversationModal\n open={moveModalOpen}\n onClose={handleMoveModalClose}\n conversations={[conversationToMove]}\n currentProjectId={conversationToMove.projectId}\n />\n )}\n\n {/* Actions Menu */}\n <Menu\n anchorEl={menuAnchorEl}\n open={Boolean(menuAnchorEl)}\n onClose={handleMenuClose}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"right\",\n }}\n anchorOrigin={{\n vertical: \"bottom\",\n horizontal: \"right\",\n }}\n >\n <MenuItem \n onClick={() => {\n setClearConfirmOpen(true);\n handleMenuClose();\n }}\n sx={{ color: theme.palette.error.main }}\n >\n <ListItemIcon>\n <DeleteSweepIcon fontSize=\"small\" sx={{ color: theme.palette.error.main }} />\n </ListItemIcon>\n <ListItemText>Clear All Conversations</ListItemText>\n </MenuItem>\n </Menu>\n\n {/* Clear All Confirmation Dialog */}\n <Dialog\n open={clearConfirmOpen}\n onClose={() => setClearConfirmOpen(false)}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>Clear All Conversations?</DialogTitle>\n <DialogContent>\n <Typography>\n This will permanently delete all conversations and cannot be undone. \n Are you sure you want to continue?\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setClearConfirmOpen(false)}>\n Cancel\n </Button>\n <Button \n onClick={handleClearAllConfirm}\n color=\"error\"\n variant=\"contained\"\n >\n Clear All\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n\nexport default ConversationDrawer;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-4562-87A9A9\nconst __banditFingerprint_chat_projectmanagementmodaltsx = 'BL-FP-3B1138-F94C';\nconst __auditTrail_chat_projectmanagementmodaltsx = 'BL-AU-MGOIKVV5-QMKL';\n// File: project-management-modal.tsx | Path: src/chat/project-management-modal.tsx | Hash: 4562f94c\n\nimport React, { useState, useEffect, useRef } from \"react\";\nimport {\n Modal,\n Button,\n TextField,\n List,\n ListItem,\n IconButton,\n Box,\n Typography,\n Avatar,\n Chip,\n Menu,\n MenuItem,\n Alert,\n CircularProgress,\n SwipeableDrawer,\n useMediaQuery,\n} from \"@mui/material\";\nimport {\n Add as AddIcon,\n Edit as EditIcon,\n Delete as DeleteIcon,\n MoreVert as MoreVertIcon,\n Folder as FolderIcon,\n Close as CloseIcon,\n ArrowBack as ArrowBackIcon,\n} from \"@mui/icons-material\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport { useProjectStore, Project } from \"../store/projectStore\";\nimport { useConversationStore } from \"../store/conversationStore\";\n\ninterface ProjectManagementModalProps {\n open: boolean;\n onClose: () => void;\n}\n\ninterface ProjectFormData {\n name: string;\n description: string;\n color: string;\n}\n\nconst DEFAULT_COLORS = [\n \"#2196F3\", \"#4CAF50\", \"#FF9800\", \"#9C27B0\", \"#F44336\",\n \"#00BCD4\", \"#FFEB3B\", \"#795548\", \"#607D8B\", \"#E91E63\",\n];\n\nconst ProjectManagementModal: React.FC<ProjectManagementModalProps> = ({\n open,\n onClose,\n}) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n const {\n projects,\n _hasHydrated,\n createProject,\n deleteProject,\n renameProject,\n updateProjectColor,\n hydrate,\n } = useProjectStore();\n\n const { getConversationsByProject } = useConversationStore();\n\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [editingProject, setEditingProject] = useState<Project | null>(null);\n const [formData, setFormData] = useState<ProjectFormData>({\n name: \"\",\n description: \"\",\n color: DEFAULT_COLORS[0],\n });\n const [menuAnchor, setMenuAnchor] = useState<null | HTMLElement>(null);\n const [selectedProject, setSelectedProject] = useState<Project | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Container ref to anchor the menu within the sheet/drawer\n const modalContainerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (open && !_hasHydrated) {\n hydrate();\n }\n }, [open, _hasHydrated, hydrate]);\n\n useEffect(() => {\n if (!open) {\n setMenuAnchor(null);\n setSelectedProject(null);\n }\n }, [open]);\n\n const resetForm = () => {\n setFormData({\n name: \"\",\n description: \"\",\n color: DEFAULT_COLORS[0],\n });\n setEditingProject(null);\n setShowCreateForm(false);\n setError(null);\n };\n\n const handleClose = () => {\n resetForm();\n setMenuAnchor(null);\n setSelectedProject(null);\n onClose();\n };\n\n const handleCreateProject = async () => {\n if (!formData.name.trim()) {\n setError(\"Project name is required\");\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n await createProject(formData.name, formData.description, formData.color);\n resetForm();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to create project\");\n } finally {\n setLoading(false);\n }\n };\n\n const handleEditProject = async () => {\n if (!editingProject || !formData.name.trim()) {\n setError(\"Project name is required\");\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n await renameProject(editingProject.id, formData.name, formData.description);\n if (formData.color !== editingProject.color) {\n await updateProjectColor(editingProject.id, formData.color);\n }\n resetForm();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to update project\");\n } finally {\n setLoading(false);\n }\n };\n\n const handleDeleteProject = async (project: Project) => {\n const conversationCount = getConversationsByProject(project.id).length;\n\n if (conversationCount > 0) {\n setError(`Cannot delete project \"${project.name}\" - it contains ${conversationCount} conversation(s). Move conversations to another project first.`);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n setMenuAnchor(null);\n setSelectedProject(null);\n await deleteProject(project.id);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to delete project\");\n } finally {\n setLoading(false);\n }\n };\n\n const startEdit = (project: Project) => {\n setEditingProject(project);\n setFormData({\n name: project.name,\n description: project.description || \"\",\n color: project.color || DEFAULT_COLORS[0],\n });\n setShowCreateForm(true);\n setMenuAnchor(null);\n };\n\n const openMenu = (event: React.MouseEvent<HTMLButtonElement>, project: Project) => {\n event.stopPropagation();\n setMenuAnchor(event.currentTarget);\n setSelectedProject(project);\n };\n\n const closeMenu = () => {\n setMenuAnchor(null);\n setSelectedProject(null);\n };\n\n const chatPalette = theme.palette.chat ?? {};\n const overlayZIndex = (theme.zIndex?.modal ?? 1300) + 20;\n const surfaceColor = isMobile\n ? theme.palette.background.paper\n : chatPalette.shell ?? theme.palette.background.paper;\n const borderColor = chatPalette.appBar?.border ?? alpha(theme.palette.divider, 0.12);\n const subtleSurface = theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.white, 0.04)\n : alpha(theme.palette.common.black, 0.03);\n const hoverSurface = alpha(theme.palette.primary.main, theme.palette.mode === \"dark\" ? 0.22 : 0.08);\n\n const headerTitle = showCreateForm\n ? editingProject\n ? \"Edit Project\"\n : \"Create Project\"\n : \"Manage Projects\";\n\n const headerSubtitle = showCreateForm\n ? \"Name, describe, and color-code your project.\"\n : \"Organize conversations into cohesive projects.\";\n\n const content = (\n <Box\n ref={modalContainerRef}\n sx={{\n width: \"100%\",\n maxWidth: isMobile ? undefined : 560,\n maxHeight: isMobile ? \"min(720px, 82vh)\" : \"90vh\",\n height: isMobile ? \"100%\" : \"auto\",\n bgcolor: surfaceColor,\n borderRadius: isMobile ? \"22px 22px 0 0\" : 3,\n overflow: \"hidden\",\n boxShadow: isMobile ? \"none\" : `0 20px 60px ${alpha(theme.palette.common.black, 0.32)}`,\n border: isMobile ? \"none\" : `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\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 mt: 1.25,\n mb: 0.75,\n }}\n />\n )}\n\n <Box\n sx={{\n px: isMobile ? 1.5 : 2.75,\n pt: isMobile ? 1.25 : 2.5,\n pb: isMobile ? 1 : 2,\n borderBottom: `1px solid ${borderColor}`,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 1,\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 1,\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n minWidth: 0,\n flex: 1,\n }}\n >\n {showCreateForm && (\n <IconButton onClick={resetForm} size=\"small\" sx={{ mr: 0.5 }}>\n <ArrowBackIcon fontSize=\"small\" />\n </IconButton>\n )}\n <Typography\n variant=\"h6\"\n sx={{\n fontSize: isMobile ? \"1rem\" : \"1.125rem\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {headerTitle}\n </Typography>\n </Box>\n <IconButton onClick={handleClose} size=\"small\">\n <CloseIcon />\n </IconButton>\n </Box>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {headerSubtitle}\n </Typography>\n </Box>\n\n <Box\n sx={{\n flex: 1,\n overflowY: \"auto\",\n px: isMobile ? 1.5 : 2.75,\n py: isMobile ? 1.5 : 2,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 2.5,\n }}\n >\n {error && (\n <Alert severity=\"error\" onClose={() => setError(null)}>\n {error}\n </Alert>\n )}\n\n {showCreateForm ? (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n <TextField\n label=\"Project name\"\n value={formData.name}\n onChange={(e) => setFormData({ ...formData, name: e.target.value })}\n fullWidth\n required\n disabled={loading}\n autoFocus\n />\n\n <TextField\n label=\"Description (optional)\"\n value={formData.description}\n onChange={(e) => setFormData({ ...formData, description: e.target.value })}\n fullWidth\n multiline\n minRows={2}\n disabled={loading}\n />\n\n <Box>\n <Typography variant=\"subtitle2\" sx={{ mb: 1 }}>\n Color\n </Typography>\n <Box sx={{ display: \"flex\", flexWrap: \"wrap\", gap: 1 }}>\n {DEFAULT_COLORS.map((color) => (\n <Box\n key={color}\n sx={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n bgcolor: color,\n cursor: \"pointer\",\n border: formData.color === color\n ? `3px solid ${theme.palette.primary.main}`\n : \"2px solid transparent\",\n transition: \"transform 0.2s ease\",\n \"&:hover\": {\n transform: \"scale(1.08)\",\n },\n }}\n onClick={() => setFormData({ ...formData, color })}\n aria-label={`Select ${color} for project color`}\n />\n ))}\n </Box>\n </Box>\n </Box>\n ) : (\n <Box sx={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n <Button\n startIcon={<AddIcon />}\n onClick={() => setShowCreateForm(true)}\n variant=\"contained\"\n sx={{\n alignSelf: \"flex-start\",\n textTransform: \"none\",\n borderRadius: 2,\n px: 2.5,\n }}\n >\n Create project\n </Button>\n\n {projects.length === 0 ? (\n <Box\n sx={{\n textAlign: \"center\",\n py: 4,\n px: 2,\n color: theme.palette.text.secondary,\n borderRadius: 2,\n border: `1px dashed ${alpha(theme.palette.divider, 0.4)}`,\n backgroundColor: subtleSurface,\n }}\n >\n <FolderIcon sx={{ fontSize: 48, mb: 2, opacity: 0.5 }} />\n <Typography variant=\"body1\" sx={{ fontWeight: 600 }}>\n No projects yet\n </Typography>\n <Typography variant=\"body2\">\n Create your first project to organize conversations.\n </Typography>\n </Box>\n ) : (\n <List sx={{ display: \"flex\", flexDirection: \"column\", gap: 1.25, py: 0 }}>\n {projects.map((project) => {\n const conversationCount = getConversationsByProject(project.id).length;\n\n return (\n <ListItem key={project.id} disablePadding>\n <Box\n sx={{\n display: \"flex\",\n width: \"100%\",\n borderRadius: 2,\n alignItems: \"center\",\n gap: 1.5,\n px: 1.5,\n py: 1.25,\n backgroundColor: subtleSurface,\n transition: \"background-color 0.2s ease, transform 0.2s ease\",\n \"&:hover\": {\n backgroundColor: hoverSurface,\n transform: \"translateY(-1px)\",\n },\n }}\n >\n <Avatar\n sx={{\n bgcolor: project.color,\n width: 36,\n height: 36,\n fontSize: \"1rem\",\n }}\n >\n <FolderIcon fontSize=\"small\" />\n </Avatar>\n\n <Box sx={{ flex: 1, minWidth: 0 }}>\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1, flexWrap: \"wrap\" }}>\n <Typography\n variant=\"subtitle1\"\n sx={{ fontWeight: 600, overflow: \"hidden\", textOverflow: \"ellipsis\" }}\n >\n {project.name}\n </Typography>\n <Chip\n label={`${conversationCount}`}\n size=\"small\"\n sx={{\n height: 22,\n borderRadius: 999,\n fontWeight: 600,\n bgcolor: alpha(theme.palette.text.primary, 0.08),\n color: theme.palette.text.primary,\n }}\n />\n </Box>\n {project.description && (\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ mt: 0.5, display: \"-webkit-box\", WebkitLineClamp: 2, WebkitBoxOrient: \"vertical\", overflow: \"hidden\" }}\n >\n {project.description}\n </Typography>\n )}\n </Box>\n\n <IconButton\n onClick={(e) => {\n e.stopPropagation();\n openMenu(e, project);\n }}\n size=\"small\"\n sx={{\n alignSelf: \"flex-start\",\n mt: 0.25,\n zIndex: 1,\n }}\n >\n <MoreVertIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </ListItem>\n );\n })}\n </List>\n )}\n </Box>\n )}\n </Box>\n\n <Box\n sx={{\n px: isMobile ? 1.5 : 2.75,\n py: isMobile ? 1.25 : 2,\n borderTop: `1px solid ${borderColor}`,\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: 1,\n }}\n >\n {showCreateForm ? (\n <>\n <Button\n onClick={resetForm}\n disabled={loading}\n sx={{ textTransform: \"none\", borderRadius: 2 }}\n >\n Cancel\n </Button>\n <Button\n onClick={editingProject ? handleEditProject : handleCreateProject}\n variant=\"contained\"\n disabled={loading}\n startIcon={loading ? <CircularProgress size={16} /> : undefined}\n sx={{ textTransform: \"none\", borderRadius: 2 }}\n >\n {editingProject ? \"Update project\" : \"Create project\"}\n </Button>\n </>\n ) : (\n <Button onClick={handleClose} sx={{ textTransform: \"none\", borderRadius: 2 }}>\n Close\n </Button>\n )}\n </Box>\n\n {/* Menu rendered here so we can control z-index/positioning across modal + drawer modes */}\n <Menu\n anchorEl={menuAnchor}\n open={Boolean(menuAnchor)}\n onClose={closeMenu}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"right\" }}\n transformOrigin={{ vertical: \"top\", horizontal: \"right\" }}\n MenuListProps={{\n dense: true,\n disablePadding: false,\n }}\n disablePortal\n container={modalContainerRef.current ?? undefined}\n PaperProps={{\n sx: {\n zIndex: overlayZIndex + (isMobile ? 10 : 40),\n mt: 0.5,\n minWidth: 160,\n }\n }}\n >\n <MenuItem\n onClick={() => {\n if (!selectedProject) return;\n startEdit(selectedProject);\n }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <EditIcon fontSize=\"small\" />\n <Typography variant=\"body2\" color=\"inherit\">\n Edit\n </Typography>\n </Box>\n </MenuItem>\n <MenuItem\n onClick={() => {\n if (!selectedProject) return;\n handleDeleteProject(selectedProject);\n }}\n sx={{ color: theme.palette.error.main }}\n >\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <DeleteIcon fontSize=\"small\" />\n <Typography variant=\"body2\" color=\"inherit\">\n Delete\n </Typography>\n </Box>\n </MenuItem>\n </Menu>\n </Box>\n );\n\n return (\n <>\n {isMobile ? (\n <SwipeableDrawer\n anchor=\"bottom\"\n open={open}\n onClose={handleClose}\n onOpen={() => { }}\n disableSwipeToOpen\n ModalProps={{ keepMounted: true }}\n sx={{ zIndex: overlayZIndex }}\n PaperProps={{\n sx: {\n height: \"min(720px, 82vh)\",\n borderRadius: \"22px 22px 0 0\",\n overflow: \"hidden\",\n },\n }}\n >\n {content}\n </SwipeableDrawer>\n ) : (\n <Modal\n open={open}\n onClose={handleClose}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n p: 2,\n zIndex: overlayZIndex,\n }}\n >\n {content}\n </Modal>\n )}\n </>\n );\n};\n\nexport default ProjectManagementModal;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-EA1F-008865\nconst __banditFingerprint_chat_moveconversationmodaltsx = 'BL-FP-DB7872-D83A';\nconst __auditTrail_chat_moveconversationmodaltsx = 'BL-AU-MGOIKVV4-0HEP';\n// File: move-conversation-modal.tsx | Path: src/chat/move-conversation-modal.tsx | Hash: ea1fd83a\n\nimport React, { useState, useEffect } from \"react\";\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n List,\n ListItem,\n ListItemButton,\n ListItemText,\n ListItemIcon,\n Typography,\n Avatar,\n Radio,\n Box,\n Divider,\n} from \"@mui/material\";\nimport {\n Folder as FolderIcon,\n Inbox as InboxIcon,\n} from \"@mui/icons-material\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { useProjectStore } from \"../store/projectStore\";\nimport { useConversationStore, Conversation } from \"../store/conversationStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\ninterface MoveConversationModalProps {\n open: boolean;\n onClose: () => void;\n conversations: Conversation[];\n currentProjectId?: string | null;\n}\n\nconst MoveConversationModal: React.FC<MoveConversationModalProps> = ({\n open,\n onClose,\n conversations,\n currentProjectId = null,\n}) => {\n const theme = useTheme();\n const { projects, _hasHydrated, hydrate } = useProjectStore();\n const { moveConversationToProject } = useConversationStore();\n \n const [selectedProjectId, setSelectedProjectId] = useState<string | null>(\n currentProjectId\n );\n\n useEffect(() => {\n if (open && !_hasHydrated) {\n hydrate();\n }\n }, [open, _hasHydrated, hydrate]);\n\n useEffect(() => {\n setSelectedProjectId(currentProjectId);\n }, [currentProjectId, open]);\n\n const handleMove = async () => {\n try {\n await Promise.all(\n conversations.map((conv) =>\n moveConversationToProject(conv.id, selectedProjectId)\n )\n );\n onClose();\n } catch (error) {\n debugLogger.error(\"Failed to move conversations\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n const conversationCount = conversations.length;\n const isMultiple = conversationCount > 1;\n\n return (\n <Dialog\n open={open}\n onClose={onClose}\n maxWidth=\"sm\"\n fullWidth\n PaperProps={{\n sx: {\n bgcolor: theme.palette.background.paper,\n backgroundImage: \"none\",\n },\n }}\n >\n <DialogTitle>\n Move {isMultiple ? `${conversationCount} Conversations` : \"Conversation\"}\n </DialogTitle>\n\n <DialogContent sx={{ px: 3 }}>\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mb: 2 }}>\n {isMultiple\n ? `Select a project to move ${conversationCount} conversations to:`\n : `Select a project to move \"${conversations[0]?.name}\" to:`}\n </Typography>\n\n <List>\n {/* No Project (Ungrouped) Option */}\n <ListItem disablePadding>\n <ListItemButton\n onClick={() => setSelectedProjectId(null)}\n selected={selectedProjectId === null}\n >\n <ListItemIcon>\n <Radio\n checked={selectedProjectId === null}\n onChange={() => setSelectedProjectId(null)}\n size=\"small\"\n />\n </ListItemIcon>\n <ListItemIcon>\n <Avatar\n sx={{\n bgcolor: theme.palette.grey[400],\n width: 32,\n height: 32,\n }}\n >\n <InboxIcon />\n </Avatar>\n </ListItemIcon>\n <ListItemText\n primary=\"No Project\"\n secondary=\"Keep conversations ungrouped\"\n />\n </ListItemButton>\n </ListItem>\n\n <Divider sx={{ my: 1 }} />\n\n {/* Project Options */}\n {projects.map((project) => (\n <ListItem key={project.id} disablePadding>\n <ListItemButton\n onClick={() => setSelectedProjectId(project.id)}\n selected={selectedProjectId === project.id}\n >\n <ListItemIcon>\n <Radio\n checked={selectedProjectId === project.id}\n onChange={() => setSelectedProjectId(project.id)}\n size=\"small\"\n />\n </ListItemIcon>\n <ListItemIcon>\n <Avatar\n sx={{\n bgcolor: project.color,\n width: 32,\n height: 32,\n }}\n >\n <FolderIcon />\n </Avatar>\n </ListItemIcon>\n <ListItemText\n primary={project.name}\n secondary={project.description}\n />\n </ListItemButton>\n </ListItem>\n ))}\n\n {projects.length === 0 && (\n <Box sx={{ \n textAlign: \"center\", \n py: 2,\n color: theme.palette.text.secondary \n }}>\n <Typography variant=\"body2\">\n No projects available. Create a project first to organize conversations.\n </Typography>\n </Box>\n )}\n </List>\n </DialogContent>\n\n <DialogActions sx={{ px: 3, pb: 2 }}>\n <Button onClick={onClose}>\n Cancel\n </Button>\n <Button\n onClick={handleMove}\n variant=\"contained\"\n disabled={selectedProjectId === currentProjectId}\n >\n Move {isMultiple ? \"Conversations\" : \"Conversation\"}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport default MoveConversationModal;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-034C-6B5D35\nconst __banditFingerprint_chat_simpleconversationitemtsx = 'BL-FP-F0F022-71F5';\nconst __auditTrail_chat_simpleconversationitemtsx = 'BL-AU-MGOIKVV6-OIQT';\n// File: simple-conversation-item.tsx | Path: src/chat/simple-conversation-item.tsx | Hash: 034c71f5\n\nimport React, { useState, useRef, useEffect } from \"react\";\nimport {\n Box,\n Typography,\n IconButton,\n Menu,\n MenuItem,\n ListItemIcon,\n ListItemText,\n useMediaQuery,\n TextField,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n} from \"@mui/material\";\nimport {\n MoreVert as MoreVertIcon,\n Edit as EditIcon,\n Delete as DeleteIcon,\n DragIndicator as DragIcon,\n MoveToInbox as MoveIcon,\n} from \"@mui/icons-material\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport { Conversation } from \"../store/conversationStore\";\n\ninterface SimpleConversationItemProps {\n conversation: Conversation;\n isSelected: boolean;\n onSelect: () => void;\n onDelete: () => void;\n onRename?: (newName: string) => void;\n onMove?: () => void;\n projectColor?: string;\n // Optional short preview shown when searching\n snippet?: string;\n // Search query for highlighting\n searchQuery?: string;\n onTouchDragStart?: (conversation: Conversation, touch: React.Touch) => void;\n onTouchDragMove?: (touch: React.Touch) => void;\n onTouchDragEnd?: (touch?: React.Touch) => void;\n isTouchDragActive?: boolean;\n}\n\nconst SimpleConversationItem: React.FC<SimpleConversationItemProps> = ({\n conversation,\n isSelected,\n onSelect,\n onDelete,\n onRename,\n onMove,\n projectColor,\n snippet,\n searchQuery,\n onTouchDragStart,\n onTouchDragMove,\n onTouchDragEnd,\n isTouchDragActive,\n}) => {\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down(\"sm\"));\n \n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const [isEditing, setIsEditing] = useState(false);\n const [editName, setEditName] = useState(conversation.name);\n const [isDragging, setIsDragging] = useState(false);\n const [isTouchDragging, setIsTouchDragging] = useState(false);\n const [showRenameDialog, setShowRenameDialog] = useState(false);\n const longPressTimeoutRef = useRef<number | null>(null);\n const touchStartPointRef = useRef<{ x: number; y: number } | null>(null);\n const activeTouchIdRef = useRef<number | null>(null);\n const suppressClickRef = useRef(false);\n\n // Helper function to highlight search terms\n const highlightText = (text: string, query?: string) => {\n if (!query || !query.trim()) {\n return text;\n }\n\n const regex = new RegExp(`(${query.trim()})`, 'gi');\n const parts = text.split(regex);\n\n return parts.map((part, index) => \n regex.test(part) ? (\n <Box\n component=\"span\"\n key={index}\n sx={{\n bgcolor: alpha(theme.palette.warning.main, 0.3),\n color: theme.palette.text.primary,\n fontWeight: 600,\n borderRadius: 0.5,\n px: 0.25,\n }}\n >\n {part}\n </Box>\n ) : part\n );\n };\n\n const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {\n event.stopPropagation();\n event.preventDefault();\n setAnchorEl(event.currentTarget);\n };\n\n const handleMenuClose = () => {\n setAnchorEl(null);\n };\n\n const handleEdit = () => {\n setEditName(conversation.name);\n\n if (isMobile) {\n setShowRenameDialog(true);\n } else {\n setIsEditing(true);\n }\n\n handleMenuClose();\n };\n\n const handleMove = () => {\n if (onMove) {\n onMove();\n }\n handleMenuClose();\n };\n\n const handleDelete = () => {\n onDelete();\n handleMenuClose();\n };\n\n const commitRename = () => {\n const trimmed = editName.trim();\n if (!trimmed) {\n return;\n }\n\n if (trimmed !== conversation.name) {\n onRename?.(trimmed);\n }\n\n setEditName(trimmed);\n };\n\n const handleSaveEdit = () => {\n commitRename();\n setIsEditing(false);\n };\n\n const handleCancelEdit = () => {\n setIsEditing(false);\n setEditName(conversation.name);\n };\n\n const handleDragStart = (e: React.DragEvent) => {\n setIsDragging(true);\n e.dataTransfer.setData(\"text/plain\", conversation.id);\n e.dataTransfer.effectAllowed = \"move\";\n };\n\n const handleDragEnd = () => {\n setIsDragging(false);\n };\n\n const cancelLongPress = () => {\n if (longPressTimeoutRef.current !== null) {\n window.clearTimeout(longPressTimeoutRef.current);\n longPressTimeoutRef.current = null;\n }\n };\n\n const handleTouchStart = (e: React.TouchEvent<HTMLDivElement>) => {\n if (!isMobile || isEditing) return;\n if (e.touches.length === 0) return;\n const touch = e.touches[0];\n touchStartPointRef.current = { x: touch.clientX, y: touch.clientY };\n activeTouchIdRef.current = touch.identifier;\n suppressClickRef.current = false;\n cancelLongPress();\n const initialTouch = touch;\n longPressTimeoutRef.current = window.setTimeout(() => {\n if (activeTouchIdRef.current !== null) {\n setIsTouchDragging(true);\n onTouchDragStart?.(conversation, initialTouch);\n }\n }, 350);\n };\n\n const handleTouchMove = (e: React.TouchEvent<HTMLDivElement>) => {\n if (!isMobile) return;\n const targetTouch = activeTouchIdRef.current !== null\n ? Array.from(e.touches).find(t => t.identifier === activeTouchIdRef.current)\n : e.touches[0];\n\n if (!targetTouch) return;\n\n if (isTouchDragging) {\n if (e.cancelable) {\n e.preventDefault();\n }\n onTouchDragMove?.(targetTouch);\n return;\n }\n\n const startPoint = touchStartPointRef.current;\n if (startPoint) {\n const deltaX = Math.abs(targetTouch.clientX - startPoint.x);\n const deltaY = Math.abs(targetTouch.clientY - startPoint.y);\n if (deltaX > 8 || deltaY > 8) {\n cancelLongPress();\n }\n }\n };\n\n const finalizeTouchDrag = (touch?: React.Touch) => {\n if (isTouchDragging) {\n onTouchDragEnd?.(touch);\n suppressClickRef.current = true;\n }\n setIsTouchDragging(false);\n activeTouchIdRef.current = null;\n touchStartPointRef.current = null;\n cancelLongPress();\n };\n\n const handleTouchEnd = (e: React.TouchEvent<HTMLDivElement>) => {\n if (!isMobile) return;\n const touch = activeTouchIdRef.current !== null\n ? Array.from(e.changedTouches).find(t => t.identifier === activeTouchIdRef.current)\n : e.changedTouches[0];\n finalizeTouchDrag(touch);\n };\n\n const handleTouchCancel = () => {\n if (!isMobile) return;\n finalizeTouchDrag();\n };\n\n useEffect(() => {\n if (!isTouchDragActive && isTouchDragging) {\n setIsTouchDragging(false);\n }\n }, [isTouchDragActive, isTouchDragging]);\n\n return (\n <>\n <Box\n data-project-id={conversation.projectId ?? \"__ungrouped\"}\n draggable={!isMobile && !isEditing}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={handleTouchCancel}\n onClick={\n isEditing || isTouchDragging\n ? undefined\n : (event) => {\n if (suppressClickRef.current) {\n suppressClickRef.current = false;\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n onSelect();\n }\n }\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n px: 2,\n py: 1.5,\n mx: 1,\n borderRadius: 1,\n cursor: isEditing || isTouchDragging ? \"default\" : \"pointer\",\n bgcolor: isSelected \n ? alpha(projectColor || theme.palette.primary.main, 0.15)\n : \"transparent\",\n border: isSelected \n ? `1px solid ${alpha(projectColor || theme.palette.primary.main, 0.3)}`\n : \"1px solid transparent\",\n opacity: isDragging || isTouchDragActive ? 0.55 : 1,\n transition: \"all 0.2s ease\",\n transform: isTouchDragActive ? \"scale(0.98)\" : \"none\",\n boxShadow: isTouchDragActive\n ? `0 12px 24px ${alpha(theme.palette.common.black, 0.25)}`\n : undefined,\n touchAction: isTouchDragActive ? \"none\" : undefined,\n userSelect: isTouchDragging || isTouchDragActive ? \"none\" : undefined,\n WebkitUserSelect: isTouchDragging || isTouchDragActive ? \"none\" : undefined,\n \"&:hover\": !isEditing && !isTouchDragging ? {\n bgcolor: alpha(theme.palette.text.primary, 0.04),\n } : {},\n // Better touch handling on mobile\n ...(isMobile && {\n minHeight: 48, // Larger touch target\n userSelect: \"none\",\n WebkitUserSelect: \"none\",\n WebkitTouchCallout: \"none\",\n \"&:active\": {\n bgcolor: alpha(theme.palette.text.primary, 0.08),\n },\n }),\n }}\n >\n {/* Drag Handle */}\n {!isMobile && !isEditing && (\n <DragIcon \n sx={{ \n color: theme.palette.text.disabled,\n mr: 1,\n cursor: \"grab\",\n fontSize: \"1rem\",\n \"&:active\": {\n cursor: \"grabbing\",\n },\n }} \n />\n )}\n\n {/* Conversation Name */}\n <Box sx={{ flex: 1, minWidth: 0 }}>\n {isEditing ? (\n <TextField\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n onBlur={handleSaveEdit}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n handleSaveEdit();\n } else if (e.key === \"Escape\") {\n handleCancelEdit();\n }\n }}\n size=\"small\"\n variant=\"standard\"\n autoFocus\n fullWidth\n sx={{\n \"& .MuiInput-root\": {\n fontSize: \"0.875rem\",\n },\n }}\n />\n ) : (\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: isSelected ? 600 : 400,\n color: isSelected \n ? projectColor || theme.palette.primary.main\n : theme.palette.text.primary,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n fontSize: \"0.875rem\",\n }}\n >\n {highlightText(conversation.name, searchQuery)}\n </Typography>\n )}\n\n {/* Optional snippet preview when searching */}\n {!isEditing && snippet && (\n <Typography\n variant=\"caption\"\n sx={{\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n color: alpha(theme.palette.text.secondary, 0.9),\n mt: 0.25,\n lineHeight: 1.3,\n fontSize: \"0.72rem\",\n }}\n title={snippet}\n >\n {highlightText(snippet, searchQuery)}\n </Typography>\n )}\n </Box>\n\n {/* Menu Button */}\n {!isEditing && (\n <IconButton\n onClick={handleMenuOpen}\n size=\"small\"\n sx={{\n opacity: isMobile ? 1 : (isSelected ? 1 : 0), // Always visible on mobile\n color: theme.palette.text.secondary,\n ml: 1,\n minWidth: 32,\n minHeight: 32,\n transition: \"opacity 0.2s ease\",\n \".MuiBox-root:hover &\": {\n opacity: 1,\n },\n // Larger touch target on mobile\n ...(isMobile && {\n padding: 1,\n \"&:before\": {\n content: '\"\"',\n position: \"absolute\",\n top: -8,\n left: -8,\n right: -8,\n bottom: -8,\n },\n }),\n }}\n >\n <MoreVertIcon fontSize=\"small\" />\n </IconButton>\n )}\n\n {/* Context Menu */}\n <Menu\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={handleMenuClose}\n onClick={(e) => e.stopPropagation()} // Prevent menu clicks from bubbling\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"right\",\n }}\n anchorOrigin={{\n vertical: \"top\",\n horizontal: \"right\",\n }}\n PaperProps={{\n sx: {\n // Larger menu items on mobile for easier touch\n ...(isMobile && {\n \"& .MuiMenuItem-root\": {\n minHeight: 48,\n fontSize: \"1rem\",\n },\n }),\n },\n }}\n >\n {onRename && (\n <MenuItem onClick={handleEdit}>\n <ListItemIcon>\n <EditIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText>Rename</ListItemText>\n </MenuItem>\n )}\n {onMove && (\n <MenuItem onClick={handleMove}>\n <ListItemIcon>\n <MoveIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText>Move to Project</ListItemText>\n </MenuItem>\n )}\n <MenuItem onClick={handleDelete}>\n <ListItemIcon>\n <DeleteIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText>Delete</ListItemText>\n </MenuItem>\n </Menu>\n </Box>\n\n {/* Mobile rename dialog */}\n {isMobile && (\n <Dialog\n open={showRenameDialog}\n onClose={() => {\n setShowRenameDialog(false);\n setEditName(conversation.name);\n }}\n fullWidth\n PaperProps={{\n sx: {\n borderRadius: 3,\n pb: 1,\n },\n }}\n >\n <DialogTitle sx={{ pb: 1 }}>Rename Conversation</DialogTitle>\n <DialogContent>\n <TextField\n value={editName}\n onChange={(e) => setEditName(e.target.value)}\n autoFocus\n fullWidth\n placeholder=\"Enter a new name\"\n InputProps={{\n sx: { fontSize: \"1rem\" },\n }}\n />\n </DialogContent>\n <DialogActions sx={{ px: 3, pb: 2 }}>\n <Button\n onClick={() => {\n setShowRenameDialog(false);\n setEditName(conversation.name);\n }}\n >\n Cancel\n </Button>\n <Button\n onClick={() => {\n commitRename();\n setShowRenameDialog(false);\n }}\n variant=\"contained\"\n disabled={!editName.trim() || editName.trim() === conversation.name}\n >\n Save\n </Button>\n </DialogActions>\n </Dialog>\n )}\n </>\n );\n};\n\nexport default SimpleConversationItem;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-9FF1-8A9606\nconst __banditFingerprint_chat_projectheadertsx = 'BL-FP-8E1E75-E3D0';\nconst __auditTrail_chat_projectheadertsx = 'BL-AU-MGOIKVV4-JNZM';\n// File: project-header.tsx | Path: src/chat/project-header.tsx | Hash: 9ff1e3d0\n\nimport React, { useRef, useState } from \"react\";\nimport {\n Box,\n Typography,\n IconButton,\n Avatar,\n Chip,\n Tooltip,\n TextField,\n alpha,\n} from \"@mui/material\";\nimport {\n ExpandMore as ExpandMoreIcon,\n ExpandLess as ExpandLessIcon,\n Add as AddIcon,\n Folder as FolderIcon,\n FolderOpen as FolderOpenIcon,\n Inbox as InboxIcon,\n Close as CloseIcon,\n Check as CheckIcon,\n} from \"@mui/icons-material\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { useConversationStore } from \"../store/conversationStore\";\nimport { useProjectStore } from \"../store/projectStore\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\ninterface ProjectHeaderProps {\n projectId: string | null;\n projectName: string;\n projectColor?: string;\n conversationCount: number;\n isCollapsed: boolean;\n onToggleCollapse: () => void;\n onDropConversation?: (conversationId: string) => void;\n // Inline rename controls\n isRenaming?: boolean;\n onRenameComplete?: () => void;\n onRenameCancelDelete?: () => void;\n isTouchTarget?: boolean;\n}\n\nconst ProjectHeader: React.FC<ProjectHeaderProps> = ({\n projectId,\n projectName,\n projectColor,\n conversationCount,\n isCollapsed,\n onToggleCollapse,\n onDropConversation,\n isRenaming,\n onRenameComplete,\n onRenameCancelDelete,\n isTouchTarget,\n}) => {\n const theme = useTheme();\n const { createNewConversation } = useConversationStore();\n const { renameProject } = useProjectStore();\n const [isHovered, setIsHovered] = useState(false);\n const [isDragOver, setIsDragOver] = useState(false);\n const [renameDraft, setRenameDraft] = useState(projectName);\n // Track pre-blur intent to avoid committing when cancel/delete is clicked\n const renameActionRef = useRef<\"none\" | \"save\" | \"delete\">(\"none\");\n\n const isUngrouped = projectId === null;\n const Icon = isCollapsed ? FolderIcon : FolderOpenIcon;\n\n const handleAddConversation = (e: React.MouseEvent) => {\n e.stopPropagation();\n createNewConversation(projectId || undefined);\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n \n const conversationId = e.dataTransfer.getData(\"text/plain\");\n if (conversationId && onDropConversation) {\n onDropConversation(conversationId);\n }\n };\n\n const commitRename = async () => {\n if (!isRenaming || projectId === null) return;\n const next = renameDraft.trim();\n try {\n if (next && next !== projectName) {\n await renameProject(projectId, next);\n }\n } catch (error) {\n // swallow; keep original name on failure\n debugLogger.error(\"Failed to rename project\", {\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n onRenameComplete?.();\n renameActionRef.current = \"none\";\n }\n };\n\n const cancelRename = () => {\n setRenameDraft(projectName);\n onRenameComplete?.();\n };\n\n return (\n <Box\n data-project-id={projectId ?? \"__ungrouped\"}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={isUngrouped || isRenaming ? undefined : onToggleCollapse} // Disable toggle while renaming\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n px: 2,\n py: 1.5,\n cursor: isUngrouped ? \"default\" : \"pointer\", // No pointer cursor for ungrouped\n bgcolor: (isDragOver || isTouchTarget)\n ? alpha(projectColor || theme.palette.primary.main, 0.1)\n : undefined,\n border: (isDragOver || isTouchTarget)\n ? `2px dashed ${projectColor || theme.palette.primary.main}`\n : \"2px solid transparent\",\n borderRadius: (isDragOver || isTouchTarget) ? 1 : 0,\n transition: \"all 0.2s ease\",\n \"&:hover\": !isUngrouped ? { // Only show hover for projects, not ungrouped\n bgcolor: alpha(theme.palette.text.primary, 0.04),\n } : {},\n }}\n >\n {/* Project Icon */}\n <Avatar\n sx={{\n bgcolor: isUngrouped \n ? alpha(theme.palette.text.disabled, 0.1)\n : projectColor || theme.palette.grey[400],\n width: 28,\n height: 28,\n mr: 1.5,\n }}\n >\n {isUngrouped ? (\n <InboxIcon \n fontSize=\"small\" \n sx={{ \n color: theme.palette.text.disabled,\n opacity: 0.7,\n }} \n />\n ) : (\n <Icon fontSize=\"small\" />\n )}\n </Avatar>\n \n {/* Project Name */}\n {isRenaming && !isUngrouped ? (\n <TextField\n value={renameDraft}\n onChange={(e) => setRenameDraft(e.target.value)}\n onBlur={() => {\n // If cancel/delete was initiated, skip committing on blur\n if (renameActionRef.current === \"delete\") {\n renameActionRef.current = \"none\";\n return;\n }\n // If explicit save already triggered, do nothing\n if (renameActionRef.current === \"save\") {\n renameActionRef.current = \"none\";\n return;\n }\n commitRename();\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") { \n renameActionRef.current = \"save\"; \n commitRename();\n }\n if (e.key === \"Escape\") {\n renameActionRef.current = \"delete\";\n if (onRenameCancelDelete) {\n onRenameCancelDelete();\n } else {\n cancelRename();\n }\n }\n }}\n variant=\"standard\"\n autoFocus\n fullWidth\n inputProps={{\n style: {\n fontSize: \"0.875rem\",\n fontWeight: 600,\n },\n }}\n sx={{\n flex: 1,\n mr: 2,\n '& .MuiInputBase-input': {\n color: theme.palette.text.primary,\n },\n }}\n />\n ) : (\n <Typography\n variant=\"subtitle2\"\n sx={{\n flex: 1,\n fontWeight: 600,\n color: isUngrouped \n ? theme.palette.text.disabled\n : theme.palette.text.primary,\n fontSize: \"0.875rem\",\n opacity: isUngrouped ? 0.8 : 1,\n }}\n >\n {projectName}\n {isDragOver && (\n <Typography \n component=\"span\" \n variant=\"caption\" \n sx={{ \n ml: 1, \n color: projectColor || theme.palette.primary.main,\n fontWeight: 500,\n }}\n >\n Drop here\n </Typography>\n )}\n </Typography>\n )}\n \n {/* Conversation Count */}\n <Chip\n label={conversationCount}\n size=\"small\"\n sx={{\n bgcolor: isUngrouped\n ? alpha(theme.palette.text.disabled, 0.1)\n : alpha(projectColor || theme.palette.primary.main, 0.15),\n color: isUngrouped\n ? theme.palette.text.disabled\n : projectColor || theme.palette.primary.main,\n minWidth: 28,\n height: 22,\n mr: 1,\n opacity: isUngrouped ? 0.7 : 1,\n \"& .MuiChip-label\": {\n fontSize: \"0.7rem\",\n px: 0.5,\n fontWeight: 600,\n },\n }}\n />\n\n {/* Rename actions when inline editing */}\n {isRenaming && !isUngrouped && (\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 0.5, ml: 1 }}>\n <Tooltip title=\"Cancel and remove\">\n <IconButton\n size=\"small\"\n onMouseDown={(e) => {\n e.stopPropagation();\n // Mark delete intent before blur fires\n renameActionRef.current = \"delete\";\n onRenameCancelDelete ? onRenameCancelDelete() : cancelRename();\n }}\n sx={{ color: alpha(theme.palette.error.main, 0.9) }}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Save\">\n <IconButton\n size=\"small\"\n onMouseDown={(e) => {\n e.stopPropagation();\n renameActionRef.current = \"save\";\n commitRename();\n }}\n sx={{ color: theme.palette.success.main }}\n >\n <CheckIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n </Box>\n )}\n\n {/* Add Conversation Button (on hover) - Hidden for ungrouped to discourage usage */}\n {isHovered && !isDragOver && !isUngrouped && !isRenaming && (\n <Tooltip title={`Add conversation to ${projectName.toLowerCase()}`} arrow>\n <IconButton\n onClick={handleAddConversation}\n size=\"small\"\n sx={{\n color: projectColor || theme.palette.primary.main,\n bgcolor: alpha(projectColor || theme.palette.primary.main, 0.1),\n width: 24,\n height: 24,\n mr: 0.5,\n \"&:hover\": {\n bgcolor: alpha(projectColor || theme.palette.primary.main, 0.2),\n transform: \"scale(1.1)\",\n },\n transition: \"all 0.2s ease\",\n }}\n >\n <AddIcon fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n )}\n \n {/* Expand/Collapse Button - Hidden for ungrouped */}\n {!isUngrouped && !isRenaming && (\n <IconButton \n size=\"small\"\n sx={{\n color: theme.palette.text.secondary,\n transition: \"transform 0.2s ease\",\n }}\n >\n {isCollapsed ? (\n <ExpandMoreIcon fontSize=\"small\" />\n ) : (\n <ExpandLessIcon fontSize=\"small\" />\n )}\n </IconButton>\n )}\n </Box>\n );\n};\n\nexport default ProjectHeader;\n","export type TooltipKey =\n | \"openNavigation\"\n | \"closeNavigation\"\n | \"manageProjects\"\n | \"conversationOptions\"\n | \"closeConversationsPanel\"\n | \"clearSearch\"\n | \"addProject\";\n\nexport const TOOLTIP_COPY: Record<TooltipKey, string> = {\n openNavigation: \"Open navigation\",\n closeNavigation: \"Close navigation\",\n manageProjects: \"Manage projects\",\n conversationOptions: \"Open conversation options\",\n closeConversationsPanel: \"Close conversations panel\",\n clearSearch: \"Clear search\",\n addProject: \"Add new project\"\n};\n\nexport const tooltip = (key: TooltipKey) => TOOLTIP_COPY[key];\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-817D-B6A919\nconst __banditFingerprint_chat_enhancedmobileconversationsmodaltsx = 'BL-FP-E99537-679F';\nconst __auditTrail_chat_enhancedmobileconversationsmodaltsx = 'BL-AU-MGOIKVV1-DNC2';\n// File: enhanced-mobile-conversations-modal.tsx | Path: src/chat/enhanced-mobile-conversations-modal.tsx | Hash: 817d679f\n\nimport React, { useState, useMemo, useEffect, useRef, useCallback } from \"react\";\nimport {\n Box,\n IconButton,\n Modal,\n Typography,\n TextField,\n InputAdornment,\n Slide,\n Collapse,\n Divider,\n Menu,\n MenuItem,\n ListItemIcon,\n ListItemText,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n AppBar,\n Toolbar,\n Avatar,\n Chip,\n} from \"@mui/material\";\nimport {\n Close as CloseIcon,\n Clear as ClearIcon,\n Search as SearchIcon,\n Folder as FolderIcon,\n MoreVert as MoreVertIcon,\n DeleteSweep as DeleteSweepIcon,\n Inbox as InboxIcon,\n} from \"@mui/icons-material\";\nimport { Add as AddIcon } from \"@mui/icons-material\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport { useConversationStore, Conversation } from \"../store/conversationStore\";\nimport { useProjectStore } from \"../store/projectStore\";\nimport { HistoryEntry } from \"../store/aiQueryStore\";\nimport { useAuthenticationStore } from \"../store/authenticationStore\";\nimport brandingService from \"../services/branding/brandingService\";\nimport ProjectManagementModal from \"./project-management-modal\";\nimport MoveConversationModal from \"./move-conversation-modal\";\nimport SimpleConversationItem from \"./simple-conversation-item\";\nimport ProjectHeader from \"./project-header\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\n\ninterface MobileConversationsModalProps {\n open: boolean;\n onClose: () => void;\n}\n\ntype ProjectConversation = Conversation & {\n _snippet?: string;\n};\n\ninterface ProjectGroup {\n id: string | null;\n name: string;\n color?: string;\n conversations: ProjectConversation[];\n collapsed: boolean;\n}\n\nconst BANDIT_AVATAR = \"https://cdn.burtson.ai/images/bandit-head.png\";\n\nconst coerceOptionalString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n};\n\nconst deriveInitials = (value: string): string => {\n if (!value) return \"B\";\n const sanitized = value.trim();\n if (!sanitized) return \"B\";\n\n const words = sanitized.split(/\\s+/).filter(Boolean);\n if (words.length >= 2) {\n const first = words[0]?.charAt(0) ?? \"\";\n const last = words[words.length - 1]?.charAt(0) ?? \"\";\n const initials = `${first}${last}`.trim();\n return initials ? initials.toUpperCase() : sanitized.slice(0, 2).toUpperCase();\n }\n\n const alphanumeric = sanitized.replace(/[^A-Za-z0-9]/g, \"\");\n if (alphanumeric.length >= 2) {\n return alphanumeric.slice(0, 2).toUpperCase();\n }\n if (alphanumeric.length === 1) {\n return alphanumeric.toUpperCase();\n }\n return sanitized.slice(0, 2).toUpperCase();\n};\n\nconst EnhancedMobileConversationsModal: React.FC<MobileConversationsModalProps> = ({\n open,\n onClose,\n}) => {\n const theme = useTheme();\n const { user } = useAuthenticationStore();\n \n const {\n conversations,\n currentId,\n switchConversation,\n deleteConversation,\n renameConversation,\n createNewConversation,\n clearAllConversations,\n moveConversationToProject,\n getConversationsByProject,\n } = useConversationStore();\n\n const {\n projects,\n _hasHydrated: projectsHydrated,\n hydrate: hydrateProjects,\n createProject,\n deleteProject,\n } = useProjectStore();\n\n // State for UI\n const [projectManagementOpen, setProjectManagementOpen] = useState(false);\n const [collapsedProjects, setCollapsedProjects] = useState<Set<string>>(new Set());\n const didInitCollapseRef = useRef(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);\n const [clearConfirmOpen, setClearConfirmOpen] = useState(false);\n const [moveModalOpen, setMoveModalOpen] = useState(false);\n const [conversationToMove, setConversationToMove] = useState<Conversation | null>(null);\n const [renameProjectId, setRenameProjectId] = useState<string | null>(null);\n const [deletedConversationIds, setDeletedConversationIds] = useState<Set<string>>(new Set());\n const [touchDragState, setTouchDragState] = useState<{\n conversationId: string | null;\n originProjectId: string | null;\n hoverProjectId: string | null;\n }>({ conversationId: null, originProjectId: null, hoverProjectId: null });\n const [avatarImage, setAvatarImage] = useState<string>(BANDIT_AVATAR);\n\n const getCustomClaim = useCallback((key: string): string | undefined => {\n if (!user) return undefined;\n const record = user as unknown as Record<string, unknown>;\n return coerceOptionalString(record[key]);\n }, [user]);\n\n const userDisplayName = useMemo(() => {\n if (!user) return undefined;\n\n const candidateFields = [\n coerceOptionalString(user.name),\n coerceOptionalString(user.preferred_username),\n user.given_name && user.family_name\n ? coerceOptionalString(`${user.given_name} ${user.family_name}`)\n : undefined,\n getCustomClaim(\"full_name\"),\n getCustomClaim(\"displayName\"),\n ];\n\n const resolvedName = candidateFields.find(Boolean);\n if (resolvedName) return resolvedName;\n\n const trimmedEmail = coerceOptionalString(user.email);\n if (trimmedEmail) return trimmedEmail;\n\n return user.sub;\n }, [user, getCustomClaim]);\n\n const userSecondaryText = useMemo(() => {\n if (!user) return undefined;\n\n const trimmedEmail = coerceOptionalString(user.email);\n if (trimmedEmail && trimmedEmail !== userDisplayName) {\n return trimmedEmail;\n }\n\n const subId = coerceOptionalString(user.sub);\n if (subId && subId !== userDisplayName) {\n return subId;\n }\n\n return undefined;\n }, [user, userDisplayName]);\n\n useEffect(() => {\n const fetchBranding = async () => {\n try {\n const branding = await brandingService.getBranding();\n setAvatarImage(branding?.logoBase64 || BANDIT_AVATAR);\n } catch (error) {\n debugLogger.error(\"Failed to load branding avatar\", {\n error: error instanceof Error ? error.message : String(error),\n });\n setAvatarImage(BANDIT_AVATAR);\n }\n };\n\n if (open) {\n fetchBranding();\n }\n }, [open]);\n\n const avatarLabel = userDisplayName || user?.email || \"Bandit\";\n const avatarInitials = useMemo(() => deriveInitials(avatarLabel), [avatarLabel]);\n\n // Build snippet helper\n const buildSnippet = (text: string, query: string, idx: number) => {\n const start = Math.max(0, idx - 40);\n const end = Math.min(text.length, idx + query.length + 60);\n return text.slice(start, end).replace(/\\s+/g, \" \").trim();\n };\n\n // Hydrate projects on mount\n useEffect(() => {\n if (open && !projectsHydrated) {\n hydrateProjects();\n }\n }, [open, projectsHydrated, hydrateProjects]);\n\n // Collapse all projects by default after hydrate (one-time per mount)\n useEffect(() => {\n if (projectsHydrated && !didInitCollapseRef.current) {\n didInitCollapseRef.current = true;\n if (projects && projects.length > 0) {\n setCollapsedProjects(new Set(projects.map(p => p.id)));\n }\n }\n }, [projectsHydrated, projects]);\n\n // Organize conversations by projects (same as desktop)\n const projectGroups = useMemo((): ProjectGroup[] => {\n const visibleConversations = conversations.filter(\n (conversation) => !deletedConversationIds.has(conversation.id)\n );\n\n const groups: ProjectGroup[] = projects.map((project) => ({\n id: project.id,\n name: project.name,\n color: project.color,\n conversations: visibleConversations\n .filter((conversation) => conversation.projectId === project.id)\n .map<ProjectConversation>((conversation) => ({\n ...conversation,\n })),\n collapsed: collapsedProjects.has(project.id),\n }));\n\n const ungroupedConversations = visibleConversations\n .filter((conversation) => !conversation.projectId)\n .map<ProjectConversation>((conversation) => ({\n ...conversation,\n }));\n\n if (ungroupedConversations.length > 0) {\n groups.push({\n id: null,\n name: \"Ungrouped\",\n conversations: ungroupedConversations,\n collapsed: false,\n });\n }\n\n return groups.filter((group) => group.conversations.length > 0 || group.id !== null);\n }, [projects, conversations, collapsedProjects, deletedConversationIds]);\n\n const visibleConversationCount = useMemo(\n () => projectGroups.reduce((total, group) => total + group.conversations.length, 0),\n [projectGroups]\n );\n\n // Filter conversations based on search query and attach snippets\n const filteredProjectGroups = useMemo((): ProjectGroup[] => {\n if (!searchQuery.trim()) return projectGroups;\n\n const query = searchQuery.toLowerCase();\n\n return projectGroups\n .map(group => {\n const conversationsWithSnippets = group.conversations\n .map<ProjectConversation | null>((conv) => {\n if (conv.name.toLowerCase().includes(query)) {\n return { ...conv, _snippet: undefined };\n }\n\n for (const entry of conv.history as HistoryEntry[]) {\n const body = `${entry.question || \"\"} ${entry.answer || \"\"}`;\n const hay = body.toLowerCase();\n const idx = hay.indexOf(query);\n if (idx !== -1) {\n return { ...conv, _snippet: buildSnippet(body, query, idx) };\n }\n }\n return null;\n })\n .filter((conv): conv is ProjectConversation => conv !== null);\n\n return {\n ...group,\n conversations: conversationsWithSnippets,\n };\n })\n .filter(group => group.conversations.length > 0);\n }, [projectGroups, searchQuery]);\n\n const touchDragActive = Boolean(touchDragState.conversationId);\n\n const getProjectIdFromPoint = useCallback((clientX: number, clientY: number) => {\n if (typeof document === \"undefined\") return null;\n const element = document.elementFromPoint(clientX, clientY) as HTMLElement | null;\n if (!element) return null;\n const projectNode = element.closest('[data-project-id]') as HTMLElement | null;\n return projectNode?.getAttribute('data-project-id') ?? null;\n }, []);\n\n const handleTouchDragStart = useCallback((conversation: Conversation, touch: React.Touch) => {\n const initialHover = getProjectIdFromPoint(touch.clientX, touch.clientY);\n setTouchDragState({\n conversationId: conversation.id,\n originProjectId: conversation.projectId ?? null,\n hoverProjectId: initialHover ?? (conversation.projectId ?? null),\n });\n }, [getProjectIdFromPoint]);\n\n const handleTouchDragMove = useCallback((touch: React.Touch) => {\n setTouchDragState(prev => {\n if (!prev.conversationId) return prev;\n const hoverId = getProjectIdFromPoint(touch.clientX, touch.clientY);\n if (hoverId === prev.hoverProjectId) return prev;\n return { ...prev, hoverProjectId: hoverId };\n });\n }, [getProjectIdFromPoint]);\n\n const handleTouchDragEnd = useCallback((touch?: React.Touch) => {\n setTouchDragState(prev => {\n if (!prev.conversationId) {\n return { conversationId: null, originProjectId: null, hoverProjectId: null };\n }\n\n let hoverId = prev.hoverProjectId;\n if (touch) {\n const resolved = getProjectIdFromPoint(touch.clientX, touch.clientY);\n if (resolved !== null) hoverId = resolved;\n }\n\n if (hoverId) {\n const targetProjectId = hoverId === \"__ungrouped\" ? null : hoverId;\n if (targetProjectId !== prev.originProjectId) {\n const conversationId = prev.conversationId;\n setTimeout(() => {\n try {\n moveConversationToProject(conversationId, targetProjectId);\n } catch (error) {\n debugLogger.error(\"Failed to move conversation via touch drag\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }, 0);\n }\n }\n\n return { conversationId: null, originProjectId: null, hoverProjectId: null };\n });\n }, [getProjectIdFromPoint, moveConversationToProject]);\n\n const activeDragConversation = useMemo(() => {\n if (!touchDragState.conversationId) return null;\n return conversations.find(conv => conv.id === touchDragState.conversationId) || null;\n }, [touchDragState.conversationId, conversations]);\n\n const activeHoverLabel = useMemo(() => {\n if (!touchDragState.hoverProjectId) return \"\";\n if (touchDragState.hoverProjectId === \"__ungrouped\") return \"Ungrouped\";\n const project = projects.find(p => p.id === touchDragState.hoverProjectId);\n return project?.name || \"\";\n }, [touchDragState.hoverProjectId, projects]);\n\n const handleToggleProject = (projectId: string | null) => {\n const key = projectId || \"ungrouped\";\n const newCollapsed = new Set(collapsedProjects);\n if (newCollapsed.has(key)) {\n newCollapsed.delete(key);\n } else {\n newCollapsed.add(key);\n }\n setCollapsedProjects(newCollapsed);\n };\n\n const handleDropConversation = (projectId: string | null, conversationId: string) => {\n moveConversationToProject(conversationId, projectId === null ? null : projectId);\n };\n\n const handleSearchClear = () => {\n setSearchQuery(\"\");\n };\n\n const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {\n setMenuAnchorEl(event.currentTarget);\n };\n\n const handleMenuClose = () => {\n setMenuAnchorEl(null);\n };\n\n const handleClearAllConfirm = async () => {\n try {\n setDeletedConversationIds(new Set(conversations.map((conv) => conv.id)));\n await clearAllConversations();\n setClearConfirmOpen(false);\n handleMenuClose();\n onClose(); // Close modal after clearing\n } catch (error) {\n debugLogger.error(\"Failed to clear conversations\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n const handleMoveConversation = (conversation: ProjectConversation) => {\n setConversationToMove(conversation);\n setMoveModalOpen(true);\n };\n\n const handleMoveModalClose = () => {\n setMoveModalOpen(false);\n setConversationToMove(null);\n };\n\n useEffect(() => {\n setDeletedConversationIds((prev) => {\n let changed = false;\n const active = new Set(conversations.map((conv) => conv.id));\n const next = new Set<string>();\n prev.forEach((id) => {\n if (active.has(id)) {\n next.add(id);\n } else {\n changed = true;\n }\n });\n return changed ? next : prev;\n });\n }, [conversations]);\n\n return (\n <>\n <Modal\n open={open}\n onClose={onClose}\n sx={{\n display: \"flex\",\n alignItems: \"flex-end\",\n }}\n >\n <Slide direction=\"up\" in={open}>\n <Box\n sx={{\n width: \"100%\",\n height: \"86vh\",\n maxHeight: 720,\n bgcolor: theme.palette.background.paper,\n borderRadius: \"20px 20px 0 0\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n >\n {/* Header */}\n <AppBar \n position=\"static\" \n elevation={0}\n sx={{\n bgcolor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n borderBottom: `1px solid ${theme.palette.divider}`,\n }}\n >\n <Toolbar>\n <Typography variant=\"h6\" sx={{ flex: 1, fontWeight: 600 }}>\n Conversations\n </Typography>\n {visibleConversationCount > 0 && (\n <Chip\n label={visibleConversationCount}\n size=\"small\"\n sx={{\n mr: 1,\n bgcolor:\n theme.palette.mode === \"dark\"\n ? \"rgba(148, 163, 184, 0.16)\"\n : \"rgba(15, 23, 42, 0.08)\",\n color: theme.palette.text.secondary,\n fontWeight: 600,\n }}\n />\n )}\n \n <IconButton\n onClick={() => setProjectManagementOpen(true)}\n sx={{ color: theme.palette.text.secondary }}\n >\n <FolderIcon />\n </IconButton>\n\n <IconButton\n onClick={handleMenuOpen}\n sx={{ color: theme.palette.text.secondary }}\n >\n <MoreVertIcon />\n </IconButton>\n \n <IconButton\n onClick={onClose}\n sx={{ color: theme.palette.text.secondary }}\n >\n <CloseIcon />\n </IconButton>\n </Toolbar>\n </AppBar>\n\n {/* Search Bar */}\n <Box sx={{ p: 2, pb: 1 }}>\n <TextField\n fullWidth\n size=\"small\"\n placeholder=\"Search conversations and content...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n variant=\"outlined\"\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon fontSize=\"small\" sx={{ color: theme.palette.text.secondary }} />\n </InputAdornment>\n ),\n endAdornment: searchQuery && (\n <InputAdornment position=\"end\">\n <IconButton\n onClick={handleSearchClear}\n size=\"small\"\n edge=\"end\"\n sx={{ color: theme.palette.text.secondary }}\n >\n <ClearIcon fontSize=\"small\" />\n </IconButton>\n </InputAdornment>\n ),\n }}\n />\n </Box>\n\n {/* Content */}\n <Box\n sx={{\n flex: 1,\n overflow: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n position: \"relative\",\n pb: 2,\n }}\n >\n {touchDragActive && activeDragConversation && (\n <Box\n sx={{\n position: \"absolute\",\n top: theme.spacing(5),\n left: \"50%\",\n transform: \"translate(-50%, -100%)\",\n zIndex: theme.zIndex.modal + 10,\n pointerEvents: \"none\",\n bgcolor: theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.black, 0.82)\n : alpha(theme.palette.common.white, 0.95),\n color: theme.palette.mode === \"dark\"\n ? theme.palette.common.white\n : theme.palette.text.primary,\n border: `1px solid ${theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.white, 0.25)\n : alpha(theme.palette.common.black, 0.2)}`,\n borderRadius: 999,\n px: 2,\n py: 0.75,\n boxShadow: `0 16px 32px ${alpha(theme.palette.common.black, 0.3)}`,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1,\n backdropFilter: \"blur(12px)\",\n whiteSpace: \"nowrap\",\n maxWidth: \"min(90vw, 520px)\",\n overflow: \"hidden\",\n }}\n >\n <Typography\n variant=\"caption\"\n sx={{\n fontWeight: 600,\n display: \"flex\",\n alignItems: \"center\",\n gap: 0.75,\n whiteSpace: \"nowrap\",\n }}\n >\n Move\n <Box\n component=\"span\"\n sx={{\n fontWeight: 700,\n maxWidth: \"45vw\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n “{activeDragConversation.name}”\n </Box>\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"inherit\"\n sx={{\n fontWeight: 500,\n whiteSpace: \"nowrap\",\n }}\n >\n {activeHoverLabel ? (\n <>\n to{\" \"}\n <Box\n component=\"span\"\n sx={{\n fontWeight: 700,\n whiteSpace: \"nowrap\",\n }}\n >\n {activeHoverLabel}\n </Box>\n </>\n ) : (\n \"Drag over a project to drop\"\n )}\n </Typography>\n </Box>\n )}\n {/* Quick Add Project */}\n <Box\n onClick={async () => {\n const names = new Set(projects.map(p => p.name));\n const base = \"New Project\";\n let name = base;\n if (names.has(name)) {\n for (let i = 2; i < 1000; i++) {\n const candidate = `${base} ${i}`;\n if (!names.has(candidate)) { name = candidate; break; }\n }\n }\n try {\n const created = await createProject(name);\n setRenameProjectId(created.id);\n } catch (error) {\n debugLogger.error(\"Failed to create project\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }}\n sx={{\n px: 2,\n py: 1.25,\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n cursor: \"pointer\",\n '&:hover': { bgcolor: alpha(theme.palette.text.primary, 0.04) },\n }}\n >\n <Box\n sx={{\n width: 28,\n height: 28,\n borderRadius: \"50%\",\n bgcolor: alpha(theme.palette.success.main, 0.15),\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <FolderIcon fontSize=\"small\" sx={{ color: theme.palette.success.main }} />\n </Box>\n <Typography\n variant=\"subtitle2\"\n sx={{ flex: 1, fontWeight: 600, fontSize: \"0.875rem\" }}\n >\n New Project\n </Typography>\n <IconButton size=\"small\" sx={{ color: theme.palette.success.main }}>\n <AddIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n <Divider sx={{ opacity: 0.3 }} />\n\n {filteredProjectGroups.map((group, index) => (\n <Box key={group.id || \"ungrouped\"}>\n {/* Add visual separator before ungrouped section */}\n {group.id === null && filteredProjectGroups.length > 1 && (\n <Box\n sx={{\n py: 2,\n px: 2,\n display: \"flex\",\n alignItems: \"center\",\n gap: 2,\n }}\n >\n <Divider sx={{ flex: 1, opacity: 0.6 }} />\n <Box sx={{ display: \"flex\", alignItems: \"center\", gap: 1 }}>\n <InboxIcon \n sx={{ \n color: theme.palette.text.disabled,\n fontSize: \"0.9rem\",\n opacity: 0.7,\n }} \n />\n <Typography \n variant=\"caption\" \n sx={{ \n color: theme.palette.text.disabled,\n fontSize: \"0.7rem\",\n fontWeight: 500,\n letterSpacing: \"0.5px\",\n textTransform: \"uppercase\",\n }}\n >\n Other Conversations\n </Typography>\n </Box>\n <Divider sx={{ flex: 1, opacity: 0.6 }} />\n </Box>\n )}\n\n {/* Only show project header for actual projects, not ungrouped */}\n {group.id !== null ? (\n <>\n <ProjectHeader\n projectId={group.id}\n projectName={group.name}\n projectColor={group.color}\n conversationCount={group.conversations.length}\n isCollapsed={group.collapsed}\n onToggleCollapse={() => handleToggleProject(group.id)}\n onDropConversation={(conversationId) => \n handleDropConversation(group.id, conversationId)\n }\n isRenaming={renameProjectId === group.id}\n onRenameComplete={() => setRenameProjectId(null)}\n onRenameCancelDelete={async () => {\n if (renameProjectId === group.id) {\n try {\n if (typeof group.id === 'string') {\n await deleteProject(group.id);\n }\n } catch (error) {\n debugLogger.error(\"Failed to delete project\", {\n error: error instanceof Error ? error.message : String(error),\n });\n } finally {\n setRenameProjectId(null);\n }\n }\n }}\n isTouchTarget={touchDragActive && touchDragState.hoverProjectId === group.id}\n />\n \n <Collapse in={!group.collapsed}>\n <Box\n data-project-id={group.id ?? \"__ungrouped\"}\n sx={{\n pb: 1,\n border: touchDragActive && touchDragState.hoverProjectId === group.id\n ? `2px dashed ${theme.palette.primary.main}`\n : \"1px solid transparent\",\n borderRadius: touchDragActive && touchDragState.hoverProjectId === group.id ? 2 : 0,\n transition: \"border 0.2s ease, background-color 0.2s ease\",\n backgroundColor: touchDragActive && touchDragState.hoverProjectId === group.id\n ? alpha(theme.palette.primary.main, 0.08)\n : \"transparent\",\n }}\n >\n {group.conversations.map((conversation) => (\n <SimpleConversationItem\n key={conversation.id}\n conversation={conversation}\n isSelected={conversation.id === currentId}\n onSelect={() => {\n switchConversation(conversation.id);\n onClose();\n }}\n onDelete={() => {\n setDeletedConversationIds((prev) => {\n if (prev.has(conversation.id)) return prev;\n const next = new Set(prev);\n next.add(conversation.id);\n return next;\n });\n deleteConversation(conversation.id);\n }}\n onRename={(newName) => renameConversation(conversation.id, newName)}\n onMove={() => handleMoveConversation(conversation)}\n projectColor={group.color}\n snippet={searchQuery ? conversation._snippet : undefined}\n searchQuery={searchQuery.trim() || undefined}\n onTouchDragStart={handleTouchDragStart}\n onTouchDragMove={handleTouchDragMove}\n onTouchDragEnd={handleTouchDragEnd}\n isTouchDragActive={touchDragState.conversationId === conversation.id}\n />\n ))}\n </Box>\n </Collapse>\n </>\n ) : (\n // Special handling for ungrouped - no header, just conversations in scrollable area\n <Box \n sx={{ \n minHeight: 0,\n overflow: \"auto\",\n px: 1,\n py: 1,\n bgcolor: alpha(theme.palette.background.default, 0.3),\n borderRadius: \"8px 8px 0 0\",\n mx: 1,\n mb: 1,\n border: touchDragActive && touchDragState.hoverProjectId === \"__ungrouped\"\n ? `2px dashed ${theme.palette.primary.main}`\n : \"1px solid transparent\",\n transition: \"border 0.2s ease, background-color 0.2s ease\",\n backgroundColor: touchDragActive && touchDragState.hoverProjectId === \"__ungrouped\"\n ? alpha(theme.palette.primary.main, 0.08)\n : alpha(theme.palette.background.default, 0.3),\n }}\n data-project-id=\"__ungrouped\"\n >\n {group.conversations.map((conversation) => (\n <SimpleConversationItem\n key={conversation.id}\n conversation={conversation}\n isSelected={conversation.id === currentId}\n onSelect={() => {\n switchConversation(conversation.id);\n onClose();\n }}\n onDelete={() => {\n setDeletedConversationIds((prev) => {\n if (prev.has(conversation.id)) return prev;\n const next = new Set(prev);\n next.add(conversation.id);\n return next;\n });\n deleteConversation(conversation.id);\n }}\n onRename={(newName) => renameConversation(conversation.id, newName)}\n onMove={() => handleMoveConversation(conversation)}\n projectColor={group.color}\n snippet={searchQuery ? conversation._snippet : undefined}\n searchQuery={searchQuery.trim() || undefined}\n onTouchDragStart={handleTouchDragStart}\n onTouchDragMove={handleTouchDragMove}\n onTouchDragEnd={handleTouchDragEnd}\n isTouchDragActive={touchDragState.conversationId === conversation.id}\n />\n ))}\n </Box>\n )}\n </Box>\n ))}\n \n {filteredProjectGroups.length === 0 && (\n <Box\n sx={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n p: 4,\n textAlign: \"center\",\n color: theme.palette.text.secondary,\n }}\n >\n <Typography variant=\"h6\" sx={{ mb: 1 }}>\n {searchQuery ? \"No conversations found\" : \"No conversations yet\"}\n </Typography>\n <Typography variant=\"body2\" sx={{ mb: 3, maxWidth: 280 }}>\n {searchQuery \n ? `No conversations match \"${searchQuery}\"`\n : \"Start your first conversation to begin organizing your chats into projects\"\n }\n </Typography>\n </Box>\n )}\n </Box>\n\n <Box\n sx={{\n mt: \"auto\",\n px: 2,\n py: 1.75,\n borderTop: `1px solid ${alpha(theme.palette.divider, 0.6)}`,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 1.25,\n bgcolor: alpha(theme.palette.background.default, 0.88),\n flexWrap: \"wrap\",\n }}\n >\n <Avatar\n src={avatarImage}\n alt={avatarLabel}\n sx={{\n width: 40,\n height: 40,\n fontSize: \"1rem\",\n bgcolor: alpha(theme.palette.primary.main, 0.12),\n color: theme.palette.primary.main,\n }}\n >\n {avatarInitials}\n </Avatar>\n <Box sx={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 0.5, minWidth: 0 }}>\n <Typography\n variant=\"subtitle2\"\n noWrap\n sx={{ fontWeight: 600, color: theme.palette.text.primary }}\n >\n {user ? userDisplayName : \"Not signed in\"}\n </Typography>\n {!user && (\n <Typography\n variant=\"caption\"\n sx={{ color: theme.palette.text.secondary }}\n noWrap\n >\n Connect your account to sync chats\n </Typography>\n )}\n </Box>\n </Box>\n </Box>\n </Slide>\n </Modal>\n\n {/* Project Management Modal */}\n <ProjectManagementModal\n open={projectManagementOpen}\n onClose={() => setProjectManagementOpen(false)}\n />\n\n {/* Move Conversation Modal */}\n {conversationToMove && (\n <MoveConversationModal\n open={moveModalOpen}\n onClose={handleMoveModalClose}\n conversations={[conversationToMove]}\n currentProjectId={conversationToMove.projectId}\n />\n )}\n\n {/* Actions Menu */}\n <Menu\n anchorEl={menuAnchorEl}\n open={Boolean(menuAnchorEl)}\n onClose={handleMenuClose}\n transformOrigin={{\n vertical: \"top\",\n horizontal: \"right\",\n }}\n anchorOrigin={{\n vertical: \"bottom\",\n horizontal: \"right\",\n }}\n >\n <MenuItem \n onClick={() => {\n setClearConfirmOpen(true);\n handleMenuClose();\n }}\n disabled={visibleConversationCount === 0}\n sx={{ color: theme.palette.error.main }}\n >\n <ListItemIcon>\n <DeleteSweepIcon fontSize=\"small\" sx={{ color: theme.palette.error.main }} />\n </ListItemIcon>\n <ListItemText>Clear All Conversations</ListItemText>\n </MenuItem>\n </Menu>\n\n {/* Clear All Confirmation Dialog */}\n <Dialog\n open={clearConfirmOpen}\n onClose={() => setClearConfirmOpen(false)}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>Clear All Conversations?</DialogTitle>\n <DialogContent>\n <Typography>\n {visibleConversationCount === 0\n ? \"No conversations available to clear.\"\n : `This will permanently delete ${visibleConversationCount} conversation${visibleConversationCount === 1 ? '' : 's'} and cannot be undone.`}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setClearConfirmOpen(false)}>\n Cancel\n </Button>\n <Button \n onClick={handleClearAllConfirm}\n color=\"error\"\n variant=\"contained\"\n >\n Clear All\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n};\n\nexport default EnhancedMobileConversationsModal;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-75D8-51D2DC\nconst __banditFingerprint_hooks_useConversationNameGeneratortsx = 'BL-FP-10F724-D630';\nconst __auditTrail_hooks_useConversationNameGeneratortsx = 'BL-AU-MGOIKVV2-5247';\n// File: useConversationNameGenerator.tsx | Path: src/chat/hooks/useConversationNameGenerator.tsx | Hash: 75d8d630\n\nimport { useAIProviderStore } from \"../../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../../store/packageSettingsStore\";\nimport { debugLogger } from \"../../services/logging/debugLogger\";\nimport { lastValueFrom } from \"rxjs\";\nimport { map } from \"rxjs/operators\";\nimport { sanitizeConversationName } from \"../../store/conversationStore\";\n\nexport const useConversationNameGenerator = () => {\n const generateName = async (userMessage: string): Promise<string | null> => {\n // Get the provider fresh each time the function is called\n const provider = useAIProviderStore.getState().provider;\n const settings = usePackageSettingsStore.getState().settings;\n const defaultModel = settings?.defaultModel || \"bandit-core\";\n \n debugLogger.info(\"ConversationNameGenerator: Starting generation\", { \n hasProvider: !!provider, \n providerType: provider?.getProviderType?.(),\n defaultModel,\n settingsModel: settings?.defaultModel\n });\n\n if (!provider) {\n debugLogger.error(\"No AI provider available for conversation name generation\");\n return null;\n }\n\n // Use the same model selection as conversation starters\n const modelToUse = defaultModel;\n \n debugLogger.info(\"ConversationNameGenerator: Using model\", { modelToUse, fromSettings: settings?.defaultModel });\n\n const prompt = `\nSummarize this user message as a short and descriptive conversation name (max 6 words, title case):\n\"${userMessage}\"\n\nRespond with just the title and nothing else.\n `.trim();\n\n try {\n const result$ = provider.generate({\n model: modelToUse,\n prompt,\n stream: false,\n options: {\n temperature: 0.5,\n num_predict: 20,\n },\n });\n\n const title = await lastValueFrom(\n result$.pipe(map((d) => d.response?.trim().replace(/[\"']/g, \"\")))\n );\n\n if (title && title.length > 0) {\n const sanitizedTitle = sanitizeConversationName(title, 60);\n debugLogger.info(\"Generated conversation name:\", { title: sanitizedTitle, userMessage: userMessage.slice(0, 50) });\n return sanitizedTitle;\n }\n } catch (err) {\n debugLogger.error(\"Conversation name generation failed:\", { error: err, userMessage: userMessage.slice(0, 50), modelUsed: modelToUse });\n }\n\n return null;\n };\n\n return { generateName };\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-5238-C1AF86\nconst __banditFingerprint_chat_querysuggestionpickertsx = 'BL-FP-4174A5-AFBE';\nconst __auditTrail_chat_querysuggestionpickertsx = 'BL-AU-MGOIKVV5-AD62';\n// File: query-suggestion-picker.tsx | Path: src/chat/query-suggestion-picker.tsx | Hash: 5238afbe\n\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { Box, useMediaQuery, Theme } from \"@mui/material\";\nimport { useTheme, alpha } from \"@mui/material/styles\";\nimport ReactMarkdown from \"react-markdown\";\nimport type { Components } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport rehypeRaw from \"rehype-raw\";\nimport { generateConversationStarters } from \"../services/prompts\";\nimport {\n getRandomTopicOfInterest,\n QuestionPromptArgs,\n} from \"../prompts/getStableQuestionPrompt\";\nimport { useModelStore } from \"../store/modelStore\";\n\ninterface QuerySuggestionPickerProps {\n onSend: (prompt: string, images: string[]) => void;\n inputHeight: number;\n}\n\nconst markdownComponents: Components = {\n p: ({ node, ...props }) => <span {...props} />,\n mark: ({ node, children, ...props }) => (\n <mark {...props}>{children}</mark>\n ),\n code: ({ node, children, ...props }) => {\n const { inline, ...rest } = props as (typeof props) & { inline?: boolean };\n return inline ? <code {...rest}>{children}</code> : <code {...rest}>{children}</code>;\n },\n};\n\nexport const QuerySuggestionPicker: React.FC<QuerySuggestionPickerProps> = ({\n onSend,\n inputHeight,\n}) => {\n const hasGenerated = useRef(false);\n const [hasSentPrompt, setHasSentPrompt] = useState(false);\n const [examplePrompts, setExamplePrompts] = useState<string[]>([]);\n const [visiblePrompts, setVisiblePrompts] = useState<string[]>([]);\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down(\"sm\"));\n const { background, text, border, hoverBackground, hoverBorder } =\n theme.palette.chat.suggestion;\n \n const { getCurrentModel, isLoading } = useModelStore();\n\n useEffect(() => {\n if (hasGenerated.current || isLoading) return;\n hasGenerated.current = true;\n\n const currentModel = getCurrentModel();\n const args: QuestionPromptArgs = {\n // keep responses quick and snappy, server may be handling concurrent requests adjust as needed\n limit: 9,\n // pick a random topic of interest from the list, consider using the users preference topics dynamically, otherwise get a random one\n topicOfInterest: getRandomTopicOfInterest(),\n // Pass the current model's system prompt to tailor suggestions\n modelSystemPrompt: currentModel?.systemPrompt,\n };\n generateConversationStarters(args)\n .then((prompts) => {\n // Only set prompts if we have meaningful conversation starters\n if (prompts.length > 0) {\n setExamplePrompts(prompts);\n setVisiblePrompts(prompts.slice(0, 3));\n } else {\n // No meaningful conversation starters generated - don't show component\n setExamplePrompts([]);\n setVisiblePrompts([]);\n hasGenerated.current = false;\n }\n })\n .catch((error) => {\n // Error handling is already done in the generateConversationStarters function\n // Just ensure we don't render any prompts if generation fails\n setExamplePrompts([]);\n setVisiblePrompts([]);\n hasGenerated.current = false;\n });\n }, [getCurrentModel, isLoading]);\n\n useEffect(() => {\n if (!isLoading) {\n hasGenerated.current = false;\n }\n }, [isLoading]);\n\n useEffect(() => {\n if (hasSentPrompt || examplePrompts.length === 0) return; // Don't shuffle if no prompts\n const interval = setInterval(() => {\n setExamplePrompts((prev) => {\n if (prev.length < 3) return prev; // Need at least 3 prompts to shuffle meaningfully\n const shuffled = [...prev].sort(() => 0.5 - Math.random());\n setVisiblePrompts((current) => [shuffled[0], current[1], current[2]]);\n setTimeout(() => {\n setVisiblePrompts((current) => [shuffled[0], shuffled[1], current[2]]);\n }, 400);\n setTimeout(() => {\n setVisiblePrompts(shuffled.slice(0, 3));\n }, 800);\n return shuffled;\n });\n }, 12000);\n return () => clearInterval(interval);\n }, [hasSentPrompt, examplePrompts.length]);\n\n const displayPrompts = isMobile\n ? visiblePrompts.slice(0, Math.min(visiblePrompts.length, 6))\n : visiblePrompts;\n\n return (\n displayPrompts.length > 0 && (\n <>\n <Box\n ref={scrollRef}\n sx={{\n zIndex: 1200,\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"row\",\n gap: isMobile ? 0.8 : 1,\n px: isMobile ? 1.5 : 2,\n overflowX: isMobile ? \"auto\" : \"visible\",\n scrollSnapType: isMobile ? \"x mandatory\" : \"none\",\n WebkitOverflowScrolling: \"touch\",\n pb: isMobile ? 0.4 : 0,\n \"&::-webkit-scrollbar\": { display: \"none\" },\n }}\n >\n {displayPrompts.map((prompt, i) => (\n <Box\n key={`${i}-${prompt}`}\n sx={{\n px: isMobile ? 1.4 : 2,\n py: isMobile ? 1.2 : 2,\n flex: isMobile ? \"0 0 85%\" : 1,\n minWidth: isMobile ? \"85%\" : \"auto\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: isMobile ? 0.9 : 1,\n backgroundColor: background,\n borderRadius: 2,\n fontSize: isMobile ? \"0.875rem\" : \"0.9rem\",\n color: text,\n userSelect: \"none\",\n cursor: \"pointer\",\n border: `1px solid ${border || alpha(text, 0.12)}`,\n boxShadow: theme.palette.mode === \"dark\"\n ? \"0 4px 18px rgba(0,0,0,0.25)\"\n : \"0 6px 20px rgba(15,23,42,0.12)\",\n scrollSnapAlign: isMobile ? \"start\" : \"none\",\n transition: \"transform 0.25s ease, box-shadow 0.25s ease, background-color 0.25s ease\",\n \"&:hover\": {\n backgroundColor: hoverBackground,\n borderColor: hoverBorder,\n transform: \"translateY(-2px)\",\n boxShadow: theme.palette.mode === \"dark\"\n ? \"0 6px 22px rgba(0,0,0,0.28)\"\n : \"0 8px 24px rgba(15,23,42,0.14)\",\n },\n \"&:active\": {\n transform: \"translateY(0) scale(0.98)\",\n },\n }}\n onClick={() => {\n onSend(prompt, []);\n setHasSentPrompt(true);\n }}\n >\n <Box\n sx={{\n flex: 1,\n lineHeight: 1.4,\n fontWeight: isMobile ? 500 : 400,\n textAlign: isMobile ? \"left\" : \"center\",\n ...(isMobile && { hyphens: \"auto\", wordBreak: \"break-word\" }),\n '& code': {\n borderRadius: 4,\n fontSize: \"0.92em\",\n fontFamily:\n \"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace\",\n backgroundColor:\n theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.white, 0.06)\n : alpha(theme.palette.text.primary, 0.06),\n border: `1px solid ${alpha(theme.palette.text.primary, 0.15)}`,\n padding: \"0.15em 0.35em\",\n },\n '& mark': {\n display: \"inline-block\",\n backgroundColor:\n theme.palette.mode === \"dark\"\n ? alpha(theme.palette.common.white, 0.06)\n : alpha(theme.palette.text.primary, 0.12),\n color: theme.palette.mode === \"dark\"\n ? theme.palette.common.white\n : theme.palette.text.primary,\n borderRadius: 4,\n padding: \"0.1em 0.25em\",\n },\n }}\n >\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={markdownComponents}\n >\n {prompt}\n </ReactMarkdown>\n </Box>\n </Box>\n ))}\n </Box>\n </>\n )\n );\n};\n","import { Box, Typography, useTheme } from \"@mui/material\";\nimport { useNavigate } from \"react-router-dom\";\n\nexport const UnderReview = () => {\n const theme = useTheme();\n const navigate = useNavigate();\n\n const handleSneakyLogout = () => {\n localStorage.removeItem('authToken');\n navigate('/login');\n };\n\n return (\n <Box\n sx={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n bgcolor: theme.palette.background.default,\n color: theme.palette.text.primary,\n textAlign: \"center\",\n px: 2,\n position: \"relative\",\n }}\n >\n {/* Sneaky logout button - small dot in top right corner */}\n <Box\n onClick={handleSneakyLogout}\n sx={{\n position: \"absolute\",\n top: 16,\n right: 16,\n width: 16,\n height: 16,\n borderRadius: \"50%\",\n bgcolor: theme.palette.background.paper,\n opacity: 0.6,\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n border: `1px solid ${theme.palette.divider}`,\n \"&:hover\": {\n opacity: 1,\n transform: \"scale(1.3)\",\n bgcolor: theme.palette.error.main,\n border: `1px solid ${theme.palette.error.main}`,\n },\n }}\n title=\"Reset session\"\n />\n \n <Typography variant=\"h4\" sx={{ mb: 2, fontWeight: 700, color: theme.palette.error.main }}>\n Under Review\n </Typography>\n <Typography variant=\"body1\" sx={{ mb: 2, color: theme.palette.text.secondary }}>\n Your request to use our services is currently being reviewed.<br />\n For more info, please contact {\" \"}\n <a href=\"mailto:team@banditai.ai\" style={{ color: theme.palette.primary.main, fontWeight: 600 }}>\n team@banditai.ai\n </a>\n </Typography>\n </Box>\n );\n};\n\nexport default UnderReview;\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-6ED3-47FEC9\nconst __banditFingerprint_components_ConnectionStatustsx = 'BL-FP-C8A6D8-1324';\nconst __auditTrail_components_ConnectionStatustsx = 'BL-AU-MGOIKVV8-XF32';\n// File: ConnectionStatus.tsx | Path: src/components/ConnectionStatus.tsx | Hash: 6ed31324\n\nimport React from \"react\";\nimport { Box, Chip, useTheme } from \"@mui/material\";\nimport WifiIcon from \"@mui/icons-material/Wifi\";\nimport WifiOffIcon from \"@mui/icons-material/WifiOff\";\nimport SignalWifi2BarIcon from \"@mui/icons-material/SignalWifi2Bar\";\nimport { useNetworkStatus } from \"../hooks/useNetworkStatus\";\n\ninterface ConnectionStatusProps {\n showWhenGood?: boolean;\n position?: \"top\" | \"bottom\";\n}\n\nexport const ConnectionStatus: React.FC<ConnectionStatusProps> = ({\n showWhenGood = false,\n position = \"top\",\n}) => {\n const theme = useTheme();\n const { isOnline, connectionQuality, isSlowConnection } = useNetworkStatus();\n\n // Don't show if connection is good and showWhenGood is false\n if (connectionQuality === \"fast\" && !showWhenGood) {\n return null;\n }\n\n const getStatusConfig = () => {\n switch (connectionQuality) {\n case \"offline\":\n return {\n icon: <WifiOffIcon sx={{ fontSize: 16 }} />,\n label: \"Offline\",\n color: \"error\" as const,\n severity: \"high\" as const,\n };\n case \"slow\":\n return {\n icon: <SignalWifi2BarIcon sx={{ fontSize: 16 }} />,\n label: \"Slow connection\",\n color: \"warning\" as const,\n severity: \"medium\" as const,\n };\n case \"fast\":\n return {\n icon: <WifiIcon sx={{ fontSize: 16 }} />,\n label: \"Connected\",\n color: \"success\" as const,\n severity: \"low\" as const,\n };\n default:\n return {\n icon: <WifiIcon sx={{ fontSize: 16 }} />,\n label: \"Unknown\",\n color: \"default\" as const,\n severity: \"low\" as const,\n };\n }\n };\n\n const config = getStatusConfig();\n\n return (\n <Box\n sx={{\n position: \"fixed\",\n [position]: 10,\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 1400,\n animation: config.severity === \"high\" ? \"pulse 2s ease-in-out infinite\" : \"none\",\n \"@keyframes pulse\": {\n \"0%\": { opacity: 1 },\n \"50%\": { opacity: 0.7 },\n \"100%\": { opacity: 1 },\n },\n }}\n >\n <Chip\n icon={config.icon}\n label={config.label}\n color={config.color}\n size=\"small\"\n sx={{\n bgcolor: theme.palette.mode === \"dark\" \n ? config.color === \"default\" \n ? \"rgba(156, 163, 175, 0.2)\"\n : `rgba(${config.color === \"error\" ? \"244, 67, 54\" : config.color === \"warning\" ? \"255, 152, 0\" : \"76, 175, 80\"}, 0.2)`\n : config.color === \"default\"\n ? \"rgba(156, 163, 175, 0.1)\"\n : `rgba(${config.color === \"error\" ? \"244, 67, 54\" : config.color === \"warning\" ? \"255, 152, 0\" : \"76, 175, 80\"}, 0.1)`,\n color: `${config.color}.main`,\n border: config.color === \"default\" \n ? \"1px solid rgba(156, 163, 175, 0.4)\"\n : `1px solid rgba(${config.color === \"error\" ? \"244, 67, 54\" : config.color === \"warning\" ? \"255, 152, 0\" : \"76, 175, 80\"}, 0.4)`,\n backdropFilter: \"blur(10px)\",\n fontWeight: 500,\n \"& .MuiChip-icon\": {\n color: `${config.color}.main`,\n },\n }}\n />\n </Box>\n );\n};\n","/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-667C-1D0BDF\nconst __banditFingerprint_hooks_useVoiceModets = 'BL-FP-AFC188-7088';\nconst __auditTrail_hooks_useVoiceModets = 'BL-AU-MGOIKVVG-VHRQ';\n// File: useVoiceMode.ts | Path: src/hooks/useVoiceMode.ts | Hash: 667c7088\n\nimport { useEffect, useRef } from \"react\";\nimport { STTClient } from \"../services/stt/stt-client\";\nimport { debugLogger } from \"../services/logging/debugLogger\";\nimport { useVoiceModeStore } from \"../store/voiceModeStore\";\n\nexport interface UseVoiceModeConfig {\n onTranscription: (text: string) => void;\n onInterrupt?: () => void;\n /**\n * Optional guard to temporarily block recording (for example while another request is pending).\n * Returning true prevents a new recording session from starting.\n */\n shouldHoldRecording?: () => boolean;\n /**\n * Invoked when a transcription attempt fails. Used for surfacing friendly messaging.\n */\n onError?: (message: string) => void;\n amplitudeThreshold?: number;\n minSpeechMs?: number;\n minSilenceMs?: number;\n}\n\ninterface AudioSession {\n stream: MediaStream;\n audioContext: AudioContext;\n analyser: AnalyserNode;\n dataArray: Uint8Array;\n}\n\nconst RMS_BASELINE = 128;\nconst RMS_NORMALIZER = 128;\n\nconst computeRms = (data: Uint8Array): number => {\n let sumSquares = 0;\n for (let i = 0; i < data.length; i += 1) {\n const sample = (data[i] - RMS_BASELINE) / RMS_NORMALIZER;\n sumSquares += sample * sample;\n }\n return Math.sqrt(sumSquares / data.length);\n};\n\n/**\n * Continuous voice mode controller that toggles microphone capture, performs lightweight\n * voice-activity detection, forwards audio to STT, and coordinates interruptions with TTS/streaming.\n */\nexport const useVoiceMode = (config: UseVoiceModeConfig) => {\n const enabled = useVoiceModeStore((state) => state.enabled);\n const setStatus = useVoiceModeStore((state) => state.setStatus);\n const setError = useVoiceModeStore((state) => state.setError);\n const resetTransientState = useVoiceModeStore((state) => state.resetTransientState);\n const setLastTranscript = useVoiceModeStore((state) => state.setLastTranscript);\n\n const configRef = useRef(config);\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n useEffect(() => {\n if (!enabled) {\n return () => undefined;\n }\n\n let cancelled = false;\n let rafId: number | null = null;\n let recorder: MediaRecorder | null = null;\n let audioSession: AudioSession | null = null;\n let chunks: BlobPart[] = [];\n let speechStartAt = 0;\n let silenceStartAt = 0;\n const isRecordingRef = { current: false };\n const isProcessingRef = { current: false };\n\n const amplitudeThreshold = configRef.current.amplitudeThreshold ?? 0.025;\n const minSpeechMs = configRef.current.minSpeechMs ?? 180;\n const minSilenceMs = configRef.current.minSilenceMs ?? 720;\n\n const clearAudioSession = async () => {\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (recorder && recorder.state !== \"inactive\") {\n try {\n recorder.stop();\n } catch (err) {\n debugLogger.warn(\"Voice mode recorder stop failed\", { error: err });\n }\n }\n recorder = null;\n chunks = [];\n if (audioSession) {\n const { stream, audioContext } = audioSession;\n stream.getTracks().forEach((track) => track.stop());\n try {\n await audioContext.close();\n } catch (err) {\n debugLogger.warn(\"Voice mode audio context close failed\", { error: err });\n }\n }\n audioSession = null;\n speechStartAt = 0;\n silenceStartAt = 0;\n isRecordingRef.current = false;\n isProcessingRef.current = false;\n };\n\n const processTranscript = async (blob: Blob) => {\n isProcessingRef.current = true;\n setStatus(\"processing\");\n\n try {\n const transcript = await STTClient.transcribe(blob);\n const trimmed = transcript.trim();\n setLastTranscript(trimmed || null);\n if (trimmed) {\n try {\n configRef.current.onTranscription(trimmed);\n } catch (handlerError) {\n debugLogger.error(\"Voice mode transcription handler failed\", { error: handlerError });\n }\n }\n if (!cancelled) {\n resetTransientState();\n }\n } catch (error) {\n debugLogger.error(\"Voice mode transcription failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n const message = \"Unable to transcribe speech. Please try again.\";\n setError(message);\n configRef.current.onError?.(message);\n } finally {\n isProcessingRef.current = false;\n }\n };\n\n const handleRecorderStop = () => {\n recorder?.removeEventListener(\"stop\", handleRecorderStop);\n const blobType = recorder?.mimeType || \"audio/webm\";\n const blob = new Blob(chunks, { type: blobType });\n chunks = [];\n\n if (blob.size < 1024) {\n // Treat ultra-short clips as noise.\n resetTransientState();\n return;\n }\n\n processTranscript(blob).catch((error) => {\n debugLogger.error(\"Voice mode transcript processing crashed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n };\n\n const stopRecording = () => {\n if (!recorder || recorder.state === \"inactive\") {\n return;\n }\n isRecordingRef.current = false;\n isProcessingRef.current = true;\n setStatus(\"processing\");\n recorder.addEventListener(\"stop\", handleRecorderStop, { once: true });\n try {\n recorder.stop();\n } catch (error) {\n debugLogger.error(\"Voice mode recorder stop threw\", { error });\n recorder.removeEventListener(\"stop\", handleRecorderStop);\n resetTransientState();\n isProcessingRef.current = false;\n }\n };\n\n const startRecording = (stream: MediaStream) => {\n chunks = [];\n try {\n recorder = new MediaRecorder(stream);\n recorder.addEventListener(\"dataavailable\", (event) => {\n if (event.data && event.data.size > 0) {\n chunks.push(event.data);\n }\n });\n } catch (error) {\n debugLogger.error(\"Voice mode recorder init failed\", { error });\n setError(\"Microphone recorder unavailable\");\n useVoiceModeStore.getState().setEnabled(false);\n return;\n }\n\n try {\n configRef.current.onInterrupt?.();\n } catch (handlerError) {\n debugLogger.warn(\"Voice mode interrupt handler threw\", { error: handlerError });\n }\n\n setError(null);\n setStatus(\"recording\");\n isRecordingRef.current = true;\n\n try {\n recorder.start();\n } catch (error) {\n debugLogger.error(\"Voice mode recorder start failed\", { error });\n setError(\"Failed to start recording\");\n isRecordingRef.current = false;\n useVoiceModeStore.getState().setEnabled(false);\n }\n };\n\n const monitorAudio = () => {\n if (cancelled || !audioSession) {\n return;\n }\n\n const { analyser, dataArray, stream } = audioSession;\n analyser.getByteTimeDomainData(dataArray);\n const rms = computeRms(dataArray);\n const now = performance.now();\n\n if (!isRecordingRef.current && !isProcessingRef.current) {\n const holdRecording = configRef.current.shouldHoldRecording?.();\n if (!holdRecording) {\n if (rms > amplitudeThreshold) {\n if (!speechStartAt) {\n speechStartAt = now;\n } else if (now - speechStartAt >= minSpeechMs) {\n startRecording(stream);\n speechStartAt = 0;\n silenceStartAt = 0;\n }\n } else {\n speechStartAt = 0;\n }\n }\n } else if (isRecordingRef.current) {\n if (rms > amplitudeThreshold * 0.6) {\n silenceStartAt = 0;\n } else {\n if (!silenceStartAt) {\n silenceStartAt = now;\n } else if (now - silenceStartAt >= minSilenceMs) {\n stopRecording();\n speechStartAt = 0;\n silenceStartAt = 0;\n }\n }\n }\n\n rafId = requestAnimationFrame(monitorAudio);\n };\n\n const initAudioSession = async () => {\n setError(null);\n setStatus(\"initializing\");\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n if (cancelled) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n\n const win = window as Window & { webkitAudioContext?: typeof AudioContext };\n const AudioContextCtor = win.AudioContext || win.webkitAudioContext;\n if (!AudioContextCtor) {\n throw new Error(\"AudioContext is not supported in this browser\");\n }\n\n const audioContext = new AudioContextCtor();\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 2048;\n source.connect(analyser);\n const dataArray = new Uint8Array(analyser.frequencyBinCount);\n\n audioSession = {\n stream,\n audioContext,\n analyser,\n dataArray,\n };\n\n resetTransientState();\n monitorAudio();\n } catch (error) {\n debugLogger.error(\"Voice mode failed to initialize microphone\", {\n error: error instanceof Error ? error.message : String(error),\n });\n const message =\n error instanceof DOMException && error.name === \"NotAllowedError\"\n ? \"Microphone permission denied\"\n : \"Microphone unavailable\";\n setError(message);\n configRef.current.onError?.(message);\n useVoiceModeStore.getState().setEnabled(false);\n }\n };\n\n initAudioSession();\n\n return () => {\n cancelled = true;\n clearAudioSession().catch((error) => {\n debugLogger.warn(\"Voice mode cleanup failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n resetTransientState();\n };\n }, [enabled, setStatus, setError, resetTransientState, setLastTranscript]);\n};\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useRef","useState","Box","CircularProgress","Typography","jsx","jsx","useEffect","useTheme","jsx","useTheme","useEffect","jsx","Box","jsx","Box","jsx","useEffect","useRef","useState","Box","IconButton","Avatar","CircularProgress","CloseIcon","useState","IconButton","useTheme","from","switchMap","Fragment","jsx","jsxs","useTheme","useState","switchMap","from","jsx","IconButton","jsxs","Fragment","useTheme","Fragment","jsx","jsxs","useTheme","useState","useRef","isPlaygroundMode","useEffect","name","jsx","IconButton","Box","jsxs","Fragment","Avatar","CloseIcon","CircularProgress","useRef","map","map","useState","useState","useRef","replaceLastAnswer","useRef","useEffect","useCallback","useRef","useCallback","useEffect","useState","useEffect","useCallback","useState","useCallback","useEffect","Avatar","useEffect","useRef","useState","Box","IconButton","Menu","MenuItem","Tooltip","useMediaQuery","useTheme","Dialog","DialogTitle","DialogContent","DialogActions","Typography","Button","AddIcon","useState","useEffect","useRef","useCallback","Box","Typography","IconButton","Tooltip","TextField","useMediaQuery","Collapse","Divider","Menu","MenuItem","ListItemIcon","ListItemText","Dialog","DialogTitle","DialogContent","DialogActions","Button","Avatar","alpha","CloseIcon","FolderIcon","MoreVertIcon","InboxIcon","AddIcon","useTheme","useState","useEffect","useRef","TextField","IconButton","Box","Typography","Avatar","CircularProgress","useMediaQuery","CloseIcon","useTheme","alpha","Fragment","jsx","jsxs","useTheme","useMediaQuery","useState","useRef","useEffect","alpha","jsxs","Box","jsx","IconButton","Typography","CloseIcon","TextField","Avatar","Fragment","CircularProgress","useState","useEffect","Button","List","ListItem","Typography","Avatar","Box","FolderIcon","useTheme","jsx","jsxs","useTheme","useState","useEffect","jsxs","jsx","Typography","List","ListItem","Avatar","FolderIcon","Box","Button","useState","useRef","useEffect","Box","Typography","IconButton","Menu","MenuItem","ListItemIcon","ListItemText","useMediaQuery","TextField","Dialog","DialogTitle","DialogContent","DialogActions","Button","MoreVertIcon","EditIcon","DeleteIcon","useTheme","alpha","Fragment","jsx","jsxs","useTheme","useMediaQuery","useState","useRef","jsx","Box","alpha","useEffect","jsxs","Fragment","TextField","Typography","IconButton","MoreVertIcon","Menu","MenuItem","ListItemIcon","EditIcon","ListItemText","DeleteIcon","Dialog","DialogTitle","DialogContent","DialogActions","Button","useRef","useState","Box","Typography","IconButton","Avatar","Chip","Tooltip","TextField","alpha","ExpandMoreIcon","AddIcon","FolderIcon","InboxIcon","CloseIcon","CheckIcon","useTheme","jsx","jsxs","useTheme","useState","useRef","FolderIcon","jsxs","Box","alpha","jsx","Avatar","InboxIcon","TextField","Typography","Chip","Tooltip","IconButton","CloseIcon","CheckIcon","AddIcon","ExpandMoreIcon","Fragment","jsx","jsxs","first","useTheme","useMediaQuery","useState","useRef","useCallback","useEffect","jsxs","Fragment","alpha","Box","jsx","Tooltip","IconButton","FolderIcon","MoreVertIcon","CloseIcon","TextField","Typography","AddIcon","Divider","InboxIcon","Collapse","Avatar","Menu","MenuItem","ListItemIcon","ListItemText","Dialog","DialogTitle","DialogContent","DialogActions","Button","useState","useMemo","useEffect","useRef","useCallback","Box","IconButton","Modal","Typography","TextField","InputAdornment","Collapse","Divider","Menu","MenuItem","ListItemIcon","ListItemText","Dialog","DialogTitle","DialogContent","DialogActions","Button","Avatar","Chip","CloseIcon","ClearIcon","SearchIcon","FolderIcon","MoreVertIcon","DeleteSweepIcon","InboxIcon","AddIcon","useTheme","alpha","Fragment","jsx","jsxs","BANDIT_AVATAR","coerceOptionalString","deriveInitials","first","useTheme","useState","useRef","useCallback","useMemo","useEffect","jsxs","Fragment","jsx","Modal","Box","Typography","Chip","IconButton","FolderIcon","MoreVertIcon","CloseIcon","TextField","InputAdornment","SearchIcon","ClearIcon","alpha","AddIcon","Divider","InboxIcon","Collapse","Avatar","Menu","MenuItem","ListItemIcon","DeleteSweepIcon","ListItemText","Dialog","DialogTitle","DialogContent","DialogActions","Button","shallow","Fragment","jsx","jsxs","useTheme","useMediaQuery","useRef","useState","isPlaygroundMode","shallow","useEffect","jsx","jsxs","Fragment","Box","Tooltip","IconButton","AddIcon","Avatar","Menu","MenuItem","Typography","Dialog","DialogTitle","DialogContent","DialogActions","Button","conversations","currentId","lastValueFrom","map","lastValueFrom","map","useEffect","useRef","useState","Box","useMediaQuery","useTheme","alpha","Fragment","jsx","jsx","useRef","useState","useTheme","useMediaQuery","theme","useEffect","Fragment","Box","alpha","Box","Typography","useTheme","useNavigate","jsx","jsxs","Box","Chip","useTheme","jsx","useTheme","jsx","Box","Chip","useEffect","useRef","useRef","useEffect","jsx","jsxs","useState","useMemo","useRef","useEffect","packageSettings","useCallback","currentId","conversations","providerImages","jsxs","jsx","Box","CircularProgress","Typography"]}