diff --git a/surfsense_web/components/assistant-ui/connector-popup.tsx b/surfsense_web/components/assistant-ui/connector-popup.tsx index 7184d393f..e838dd02e 100644 --- a/surfsense_web/components/assistant-ui/connector-popup.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup.tsx @@ -1,12 +1,19 @@ "use client"; import { useAtomValue } from "jotai"; -import { Cable } from "lucide-react"; +import { AlertTriangle, Cable, Settings } from "lucide-react"; +import Link from "next/link"; import { useSearchParams } from "next/navigation"; import type { FC } from "react"; +import { + globalNewLLMConfigsAtom, + llmPreferencesAtom, +} from "@/atoms/new-llm-config/new-llm-config-query.atoms"; import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { currentUserAtom } from "@/atoms/user/user-query.atoms"; import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; import { Spinner } from "@/components/ui/spinner"; import { Tabs, TabsContent } from "@/components/ui/tabs"; @@ -34,6 +41,26 @@ export const ConnectorIndicator: FC = () => { const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom); const searchParams = useSearchParams(); const { data: currentUser } = useAtomValue(currentUserAtom); + const { data: preferences = {}, isFetching: preferencesLoading } = + useAtomValue(llmPreferencesAtom); + const { data: globalConfigs = [], isFetching: globalConfigsLoading } = + useAtomValue(globalNewLLMConfigsAtom); + + // Check if document summary LLM is properly configured + // - If ID is 0 (Auto mode), we need global configs to be available + // - If ID is positive (user config) or negative (specific global config), it's configured + // - If ID is null/undefined, it's not configured + const docSummaryLlmId = preferences.document_summary_llm_id; + const isAutoMode = docSummaryLlmId === 0; + const hasGlobalConfigs = globalConfigs.length > 0; + + const hasDocumentSummaryLLM = + docSummaryLlmId !== null && + docSummaryLlmId !== undefined && + // If it's Auto mode, we need global configs to actually be available + (!isAutoMode || hasGlobalConfigs); + + const llmConfigLoading = preferencesLoading || globalConfigsLoading; // Fetch document type counts using Electric SQL + PGlite for real-time updates const { documentTypeCounts, loading: documentTypesLoading } = useDocumentsElectric(searchSpaceId); @@ -329,6 +356,27 @@ export const ConnectorIndicator: FC = () => {
+ {/* LLM Configuration Warning */} + {!llmConfigLoading && !hasDocumentSummaryLLM && ( + + + LLM Configuration Required + +

+ {isAutoMode && !hasGlobalConfigs + ? "Auto mode is selected but no global LLM configurations are available. Please configure a custom LLM in Settings to process and summarize documents from your connected sources." + : "You need to configure a Document Summary LLM before adding connectors. This LLM is used to process and summarize documents from your connected sources."} +

+ +
+
+ )} + { allConnectors={connectors} documentTypeCounts={documentTypeCounts} indexingConnectorIds={indexingConnectorIds} - onConnectOAuth={handleConnectOAuth} - onConnectNonOAuth={handleConnectNonOAuth} - onCreateWebcrawler={handleCreateWebcrawler} - onCreateYouTubeCrawler={handleCreateYouTubeCrawler} + onConnectOAuth={hasDocumentSummaryLLM ? handleConnectOAuth : () => {}} + onConnectNonOAuth={hasDocumentSummaryLLM ? handleConnectNonOAuth : () => {}} + onCreateWebcrawler={hasDocumentSummaryLLM ? handleCreateWebcrawler : () => {}} + onCreateYouTubeCrawler={hasDocumentSummaryLLM ? handleCreateYouTubeCrawler : () => {}} onManage={handleStartEdit} onViewAccountsList={handleViewAccountsList} /> diff --git a/surfsense_web/components/assistant-ui/document-upload-popup.tsx b/surfsense_web/components/assistant-ui/document-upload-popup.tsx index abbd5cd1a..b8f2eb1cf 100644 --- a/surfsense_web/components/assistant-ui/document-upload-popup.tsx +++ b/surfsense_web/components/assistant-ui/document-upload-popup.tsx @@ -1,7 +1,8 @@ "use client"; import { useAtomValue } from "jotai"; -import { Upload } from "lucide-react"; +import { AlertTriangle, Settings, Upload } from "lucide-react"; +import Link from "next/link"; import { createContext, type FC, @@ -11,8 +12,14 @@ import { useRef, useState, } from "react"; +import { + globalNewLLMConfigsAtom, + llmPreferencesAtom, +} from "@/atoms/new-llm-config/new-llm-config-query.atoms"; import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms"; import { DocumentUploadTab } from "@/components/sources/DocumentUploadTab"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; // Context for opening the dialog from anywhere @@ -84,6 +91,10 @@ const DocumentUploadPopupContent: FC<{ onOpenChange: (open: boolean) => void; }> = ({ isOpen, onOpenChange }) => { const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom); + const { data: preferences = {}, isFetching: preferencesLoading } = + useAtomValue(llmPreferencesAtom); + const { data: globalConfigs = [], isFetching: globalConfigsLoading } = + useAtomValue(globalNewLLMConfigsAtom); if (!searchSpaceId) return null; @@ -91,6 +102,22 @@ const DocumentUploadPopupContent: FC<{ onOpenChange(false); }; + // Check if document summary LLM is properly configured + // - If ID is 0 (Auto mode), we need global configs to be available + // - If ID is positive (user config) or negative (specific global config), it's configured + // - If ID is null/undefined, it's not configured + const docSummaryLlmId = preferences.document_summary_llm_id; + const isAutoMode = docSummaryLlmId === 0; + const hasGlobalConfigs = globalConfigs.length > 0; + + const hasDocumentSummaryLLM = + docSummaryLlmId !== null && + docSummaryLlmId !== undefined && + // If it's Auto mode, we need global configs to actually be available + (!isAutoMode || hasGlobalConfigs); + + const isLoading = preferencesLoading || globalConfigsLoading; + return ( @@ -118,7 +145,27 @@ const DocumentUploadPopupContent: FC<{ {/* Content */}
- + {!isLoading && !hasDocumentSummaryLLM ? ( + + + LLM Configuration Required + +

+ {isAutoMode && !hasGlobalConfigs + ? "Auto mode is selected but no global LLM configurations are available. Please configure a custom LLM in Settings to process and summarize your uploaded documents." + : "You need to configure a Document Summary LLM before uploading files. This LLM is used to process and summarize your uploaded documents."} +

+ +
+
+ ) : ( + + )}