"use client"; import { useState, useEffect } from "react"; import { RagQuery, RagParams } from "@/components/rag-query"; import type { Triple } from "@/types/graph"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { DatabaseConnection } from "@/components/database-connection"; import { NvidiaIcon } from "@/components/nvidia-icon"; import { ArrowLeft, BarChart2, Search as SearchIcon } from "lucide-react"; export default function RagPage() { const router = useRouter(); const [results, setResults] = useState(null); const [isLoading, setIsLoading] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const [vectorEnabled, setVectorEnabled] = useState(false); const [metrics, setMetrics] = useState<{ avgQueryTime: number; avgRelevance: number; precision: number; recall: number; } | null>(null); const [currentParams, setCurrentParams] = useState({ kNeighbors: 4096, fanout: 400, numHops: 2, topK: 5, useVectorSearch: false, usePureRag: false, queryMode: 'traditional' }); // Initialize backend when the page loads useEffect(() => { // Initialize the backend services const initializeBackend = async () => { try { // Check graph database connection (ArangoDB by default) const graphResponse = await fetch('/api/graph-db', { method: 'GET', headers: { 'Content-Type': 'application/json', }, }); if (!graphResponse.ok) { const errorData = await graphResponse.json(); console.warn('Graph database connection warning:', errorData.error); } // Check if vector search is available const vectorResponse = await fetch('/api/pinecone-diag/stats'); if (vectorResponse.ok) { const data = await vectorResponse.json(); setVectorEnabled(data.totalVectorCount > 0); } // Fetch basic metrics const metricsResponse = await fetch('/api/metrics'); if (metricsResponse.ok) { const data = await metricsResponse.json(); setMetrics({ avgQueryTime: data.avgQueryTime, avgRelevance: data.avgRelevance, precision: data.precision, recall: data.recall }); } } catch (error) { console.warn('Error initializing backends:', error); } }; initializeBackend(); }, []); const handleQuerySubmit = async (query: string, params: RagParams) => { setIsLoading(true); setErrorMessage(null); setCurrentParams(params); // Store current params for UI rendering const startTime = Date.now(); let queryMode: 'pure-rag' | 'vector-search' | 'traditional' = 'traditional'; let resultCount = 0; let relevanceScore = 0; try { // If using pure RAG (Pinecone + LangChain) without graph search if (params.usePureRag) { queryMode = 'pure-rag'; try { console.log('Using pure RAG with just Pinecone and LangChain for query:', query); const ragResponse = await fetch('/api/rag-query', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, topK: params.topK }) }); if (ragResponse.ok) { const data = await ragResponse.json(); // Handle the answer - we might need to display differently than triples if (data.answer) { // Special UI handling for text answer rather than triples setResults([{ subject: 'Answer', predicate: '', object: data.answer, usedFallback: data.usedFallback }]); resultCount = 1; relevanceScore = data.relevanceScore || 0; // Log the query with performance metrics logQuery(query, queryMode, { executionTimeMs: Date.now() - startTime, relevanceScore, resultCount }); console.log('Pure RAG query completed successfully'); setIsLoading(false); return; } } else { // If the RAG query fails, log but continue to try other methods const errorData = await ragResponse.json(); throw new Error(errorData.error || 'Failed to execute pure RAG query'); } } catch (ragError) { console.warn('Pure RAG query error (falling back to other methods):', ragError); // Continue to other query methods as fallback } } // If we have vector embeddings, use enhanced query with metadata if (vectorEnabled && params.useVectorSearch) { queryMode = 'vector-search'; try { console.log('Using enhanced RAG with LangChain for query:', query); const enhancedResponse = await fetch('/api/enhanced-query', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, kNeighbors: params.kNeighbors, fanout: params.fanout, numHops: params.numHops, topK: params.topK }) }); if (enhancedResponse.ok) { const data = await enhancedResponse.json(); // Update the results setResults(data.relevantTriples || []); resultCount = data.count || 0; relevanceScore = data.relevanceScore || 0; // Log the query with performance metrics logQuery(query, queryMode, { executionTimeMs: Date.now() - startTime, relevanceScore, resultCount, precision: data.precision || 0, recall: data.recall || 0, }); // Log to console instead of showing alert let message = `Enhanced query completed. Found ${resultCount} relevant triples`; if (data.metadata?.entityMatches) { message += ` from ${data.metadata.entityMatches} matched entities`; } console.log(message); setIsLoading(false); return; } } catch (enhancedError) { console.warn('Enhanced query error (falling back to traditional query):', enhancedError); // Continue to traditional query as fallback } } // Call the traditional backend API as fallback or if explicitly selected queryMode = 'traditional'; const response = await fetch(`/api/query`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query, kNeighbors: params.kNeighbors, fanout: params.fanout, numHops: params.numHops, topK: params.topK, queryMode: queryMode, // Explicitly pass the query mode useTraditional: true // Force use of the direct pattern matching approach }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to query the RAG backend'); } const data = await response.json(); // Update the results setResults(data.relevantTriples || []); resultCount = data.count || 0; relevanceScore = data.relevanceScore || 0; // Log the query with performance metrics logQuery(query, queryMode, { executionTimeMs: Date.now() - startTime, relevanceScore, resultCount, precision: data.precision || 0, recall: data.recall || 0, }); // Log to console instead of showing alert let message = `Query completed. Found ${resultCount} relevant triples`; if (vectorEnabled && params.useVectorSearch) { message += ` (using standard vector search)`; } console.log(message); } catch (error) { console.error("RAG query error:", error); setErrorMessage(error instanceof Error ? error.message : "An unknown error occurred"); setResults([]); // Log failed query logQuery(query, queryMode, { executionTimeMs: Date.now() - startTime, resultCount: 0, error: error instanceof Error ? error.message : "Unknown error" }); } finally { setIsLoading(false); } }; // Helper function to log queries const logQuery = async ( query: string, queryMode: 'pure-rag' | 'vector-search' | 'traditional', metrics: { executionTimeMs: number; relevanceScore?: number; precision?: number; recall?: number; resultCount: number; error?: string; } ) => { try { await fetch('/api/query-log', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, queryMode, metrics }) }); console.log('Query logged successfully'); } catch (error) { // Non-blocking error, just log it console.warn('Failed to log query:', error); } }; const clearResults = () => { setResults(null); setErrorMessage(null); }; return (
{/* Main Content */}
{/* Header Section */}
Back to Documents
{/* Two Column Layout */}
{/* Left Column - Database Connections */}
{/* Performance Metrics Card */} {metrics && (

Performance Metrics

View All
Avg. Query Time: {metrics.avgQueryTime > 0 ? `${metrics.avgQueryTime.toFixed(2)}ms` : "No data"}
Relevance Score: {metrics.avgRelevance > 0 ? `${(metrics.avgRelevance * 100).toFixed(1)}%` : "No data"}
Precision: {metrics.precision > 0 ? `${(metrics.precision * 100).toFixed(1)}%` : "No data"}
Recall: {metrics.recall > 0 ? `${(metrics.recall * 100).toFixed(1)}%` : "No data"}
)}
{/* Right Column - RAG Query Interface */}
{/* Results Section */} {results && results.length > 0 && (

Results ({results.length})

{results.map((triple, index) => (
{currentParams.usePureRag ? ( // Pure RAG display format (no subject/predicate/object columns)
{triple.usedFallback && (
Using general knowledge (no documents found)
)}

{triple.object}

) : ( // Standard triple display for other modes

Subject

{triple.subject}

Predicate

{triple.predicate}

Object

{triple.object}

)} {triple.confidence && !currentParams.usePureRag && (
Confidence: {(triple.confidence * 100).toFixed(1)}%
)}
))}
)} {results && results.length === 0 && !isLoading && (

No results found for your query

Try adjusting your query or parameters

)}
); }