rag improvements

This commit is contained in:
2025-09-23 15:26:54 +02:00
parent 354b43494d
commit f8d127ff42
30 changed files with 817 additions and 2428 deletions

View File

@@ -7,7 +7,7 @@ export async function POST(request: NextRequest) {
// Make request to backend auth endpoint without requiring existing auth
const baseUrl = process.env.INTERNAL_API_URL || `http://enclava-backend:${process.env.BACKEND_INTERNAL_PORT || '8000'}`
const url = `${baseUrl}/api/auth/login`
const url = `${baseUrl}/api-internal/v1/auth/login`
const response = await fetch(url, {
method: 'POST',

View File

@@ -85,8 +85,31 @@ function RAGPageContent() {
const loadStats = async () => {
try {
const data = await apiClient.get('/api-internal/v1/rag/stats')
setStats(data.stats)
console.log('Stats API response:', data)
// Check if the response has the expected structure
if (data && data.stats && data.stats.collections) {
console.log('✓ Stats has collections property')
setStats(data.stats)
} else {
console.error('✗ Invalid stats structure:', data)
// Set default empty stats to prevent error
setStats({
collections: { total: 0, active: 0 },
documents: { total: 0, processing: 0, processed: 0 },
storage: { total_size_bytes: 0, total_size_mb: 0 },
vectors: { total: 0 }
})
}
} catch (error) {
console.error('Error loading stats:', error)
// Set default empty stats on error
setStats({
collections: { total: 0, active: 0 },
documents: { total: 0, processing: 0, processed: 0 },
storage: { total_size_bytes: 0, total_size_mb: 0 },
vectors: { total: 0 }
})
}
}

View File

@@ -9,7 +9,7 @@ import { Badge } from "@/components/ui/badge"
import { Separator } from "@/components/ui/separator"
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Search, FileText, Trash2, Eye, Download, Calendar, Hash, FileIcon, Filter } from "lucide-react"
import { Search, FileText, Trash2, Eye, Download, Calendar, Hash, FileIcon, Filter, RefreshCw } from "lucide-react"
import { useToast } from "@/hooks/use-toast"
import { apiClient } from "@/lib/api-client"
import { config } from "@/lib/config"
@@ -56,6 +56,7 @@ export function DocumentBrowser({ collections, selectedCollection, onCollectionS
const [filterStatus, setFilterStatus] = useState("all")
const [selectedDocument, setSelectedDocument] = useState<Document | null>(null)
const [deleting, setDeleting] = useState<string | null>(null)
const [reprocessing, setReprocessing] = useState<string | null>(null)
const { toast } = useToast()
useEffect(() => {
@@ -157,6 +158,43 @@ export function DocumentBrowser({ collections, selectedCollection, onCollectionS
}
}
const handleReprocessDocument = async (documentId: string) => {
setReprocessing(documentId)
try {
await apiClient.post(`/api-internal/v1/rag/documents/${documentId}/reprocess`)
// Update the document status to processing in the UI
setDocuments(prev => prev.map(doc =>
doc.id === documentId
? { ...doc, status: 'processing' as const, processed_at: new Date().toISOString() }
: doc
))
toast({
title: "Success",
description: "Document reprocessing started",
})
// Reload documents after a short delay to see status updates
setTimeout(() => {
loadDocuments()
}, 2000)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Failed to reprocess document"
toast({
title: "Error",
description: errorMessage.includes("Cannot reprocess document with status 'processed'")
? "Cannot reprocess documents that are already processed"
: errorMessage,
variant: "destructive",
})
} finally {
setReprocessing(null)
}
}
const formatFileSize = (bytes: number) => {
if (bytes === 0) return '0 Bytes'
const k = 1024
@@ -432,6 +470,21 @@ export function DocumentBrowser({ collections, selectedCollection, onCollectionS
<Download className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
className="h-8 w-8 p-0 hover:bg-blue-100"
onClick={() => handleReprocessDocument(document.id)}
disabled={reprocessing === document.id || document.status === 'processed'}
title={document.status === 'processed' ? "Document already processed" : "Reprocess document"}
>
{reprocessing === document.id ? (
<RefreshCw className="h-4 w-4 animate-spin" />
) : (
<RefreshCw className={`h-4 w-4 ${document.status === 'processed' ? 'text-gray-400' : ''}`} />
)}
</Button>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button

View File

@@ -67,12 +67,13 @@ const Navigation = () => {
// Core navigation items that are always visible
const coreNavItems = [
{ href: "/dashboard", label: "Dashboard" },
{
href: "/llm",
{
href: "/llm",
label: "LLM",
children: [
{ href: "/llm", label: "Models & Config" },
{ href: "/playground", label: "Playground" },
{ href: "/rag-demo", label: "RAG Demo" },
]
},
{