import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; import { Brain, Sparkles, FileText, Search, Loader2, TrendingUp, Lightbulb, Target, CheckCircle, AlertCircle } from "lucide-react"; interface AIAssistantProps { onDocumentSelect?: (documentId: number) => void; } interface EnhancedSearchResult { results: any[]; enhancedQuery?: { enhancedQuery: string; intent: string; keywords: string[]; suggestions: string[]; }; searchInsights?: { totalResults: number; avgRelevanceScore: number; modalResultsCount: number; localResultsCount: number; }; } interface ResearchSynthesis { synthesis: string; keyFindings: string[]; gaps: string[]; recommendations: string[]; } export default function AIAssistant({ onDocumentSelect }: AIAssistantProps) { const [query, setQuery] = useState(""); const [selectedDocuments, setSelectedDocuments] = useState([]); const [analysisText, setAnalysisText] = useState(""); const queryClient = useQueryClient(); // Enhanced AI Search const aiSearchMutation = useMutation({ mutationFn: async (searchQuery: string): Promise => { const response = await fetch("/api/ai-search", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: searchQuery, maxResults: 10, useQueryEnhancement: true }), }); if (!response.ok) throw new Error("Enhanced search failed"); return response.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/search"] }); }, }); // Query Enhancement const queryEnhancementMutation = useMutation({ mutationFn: async (originalQuery: string) => { const response = await fetch("/api/enhance-query", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: originalQuery }), }); if (!response.ok) throw new Error("Query enhancement failed"); return response.json(); }, }); // Document Analysis const documentAnalysisMutation = useMutation({ mutationFn: async ({ content, analysisType }: { content: string; analysisType: string }) => { const response = await fetch("/api/analyze-document", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content, analysisType }), }); if (!response.ok) throw new Error("Document analysis failed"); return response.json(); }, }); // Research Synthesis const researchSynthesisMutation = useMutation({ mutationFn: async ({ query, documentIds }: { query: string; documentIds: number[] }): Promise => { const response = await fetch("/api/research-synthesis", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, documentIds }), }); if (!response.ok) throw new Error("Research synthesis failed"); return response.json(); }, }); // Generate Embeddings const embeddingsMutation = useMutation({ mutationFn: async (input: string) => { const response = await fetch("/api/embeddings", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ input }), }); if (!response.ok) throw new Error("Embedding generation failed"); return response.json(); }, }); const handleEnhancedSearch = () => { if (!query.trim()) return; aiSearchMutation.mutate(query); }; const handleQueryEnhancement = () => { if (!query.trim()) return; queryEnhancementMutation.mutate(query); }; const handleDocumentAnalysis = (analysisType: string) => { if (!analysisText.trim()) return; documentAnalysisMutation.mutate({ content: analysisText, analysisType }); }; const handleResearchSynthesis = () => { if (!query.trim() || selectedDocuments.length === 0) return; researchSynthesisMutation.mutate({ query, documentIds: selectedDocuments }); }; const handleGenerateEmbeddings = () => { if (!query.trim()) return; embeddingsMutation.mutate(query); }; return (
AI Research Assistant Powered by Nebius & Modal Smart Search Analysis Synthesis Embeddings {/* Enhanced Search Tab */}
setQuery(e.target.value)} onKeyDown={(e) => e.key === "Enter" && handleEnhancedSearch()} className="flex-1" />
{/* Query Enhancement Results */} {queryEnhancementMutation.data && (

Enhanced Query

{queryEnhancementMutation.data.enhancedQuery}

Intent: {queryEnhancementMutation.data.intent}
Keywords:
{queryEnhancementMutation.data.keywords.map((keyword: string, i: number) => ( {keyword} ))}
)} {/* Enhanced Search Results */} {aiSearchMutation.data && ( AI-Enhanced Results {aiSearchMutation.data.searchInsights && ( {aiSearchMutation.data.searchInsights.totalResults} results )} {aiSearchMutation.data.searchInsights && (
Avg Relevance: {(aiSearchMutation.data.searchInsights.avgRelevanceScore * 100).toFixed(1)}%
Modal Results: {aiSearchMutation.data.searchInsights.modalResultsCount}
Local Results: {aiSearchMutation.data.searchInsights.localResultsCount}
Total: {aiSearchMutation.data.searchInsights.totalResults}
)}
{aiSearchMutation.data.results.map((result: any, index: number) => (
{result.title}
{result.relevanceScore && ( {(result.relevanceScore * 100).toFixed(0)}% )} {result.aiExplanation && ( )}

{result.snippet}

{result.keyReasons && (
AI Analysis:
    {result.keyReasons.slice(0, 2).map((reason: string, i: number) => (
  • {reason}
  • ))}
)}
))}
)}
{/* Document Analysis Tab */}