import { useState, useEffect, useRef } from 'react'; import { Upload, Cpu, HardDrive, Database, CheckCircle, AlertCircle, Loader2, Package, Trash2, Sparkles, Clock, Download } from 'lucide-react'; import { useSystemStore } from '../store'; import { motion, AnimatePresence } from 'framer-motion'; /** * ModelLoader page - load HuggingFace models with progress tracking */ export default function ModelLoader() { const systemInfo = useSystemStore((state) => state.systemInfo); const [modelName, setModelName] = useState(''); const [exampleModels, setExampleModels] = useState(null); const [loadResult, setLoadResult] = useState(null); const [isLoading, setIsLoading] = useState(false); const [progress, setProgress] = useState(null); const [cachedModels, setCachedModels] = useState([]); const [modelInfo, setModelInfo] = useState(null); const progressPollRef = useRef(null); // Fetch example models and cache info on mount useEffect(() => { // Optimistic load from cache const cachedExamples = localStorage.getItem('example_models'); if (cachedExamples) { try { setExampleModels(JSON.parse(cachedExamples)); } catch (e) { } } fetch('/api/models/examples') .then(res => res.json()) .then(data => { setExampleModels(data); localStorage.setItem('example_models', JSON.stringify(data)); }) .catch(() => { }); fetchCacheInfo(); fetchModelInfo(); }, []); const fetchCacheInfo = async () => { try { const res = await fetch('/api/models/cache'); const data = await res.json(); setCachedModels(data.models || []); } catch (e) { } }; const fetchModelInfo = async () => { try { const res = await fetch('/api/models/info'); const data = await res.json(); if (data.loaded) { setModelInfo(data); } } catch (e) { } }; const pollProgress = (name) => { if (progressPollRef.current) { clearInterval(progressPollRef.current); } progressPollRef.current = setInterval(async () => { try { const res = await fetch(`/api/models/progress/${encodeURIComponent(name)}`); const data = await res.json(); if (data.downloading) { setProgress(data); } } catch (e) { } }, 500); }; const stopPolling = () => { if (progressPollRef.current) { clearInterval(progressPollRef.current); progressPollRef.current = null; } }; const handleLoadModel = async () => { if (!modelName.trim() || isLoading) return; setIsLoading(true); setLoadResult(null); setProgress({ status: 'starting', percent: 0, message: 'Starting download...' }); // Start polling for progress pollProgress(modelName.trim()); try { const response = await fetch('/api/models/load', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model_name: modelName.trim(), dtype: 'auto', device: 'auto', trust_remote_code: true }) }); const data = await response.json(); setLoadResult(data); if (data.success) { setModelInfo(data.model_info); setProgress({ status: 'complete', percent: 100, message: 'Model loaded!' }); fetchCacheInfo(); } else { setProgress(null); } } catch (err) { setLoadResult({ success: false, error: err.message }); setProgress(null); } finally { setIsLoading(false); stopPolling(); } }; const handleQuickLoad = (modelId) => { setModelName(modelId); }; const handleUnload = async () => { try { await fetch('/api/models/unload', { method: 'POST' }); setModelInfo(null); setLoadResult(null); setProgress(null); } catch (e) { } }; const handleDeleteFromCache = async (name) => { try { await fetch(`/api/models/cache/${encodeURIComponent(name)}`, { method: 'DELETE' }); fetchCacheInfo(); } catch (e) { } }; const handleCleanup = async () => { try { const res = await fetch('/api/models/cache/cleanup', { method: 'POST' }); const data = await res.json(); fetchCacheInfo(); alert(`Cleaned up ${data.deleted_count} models`); } catch (e) { } }; return (
Download and analyze models directly from HuggingFace Hub
Enter the HuggingFace model identifier (organization/model-name)
{loadResult.model_info?.architecture} - {loadResult.model_info?.num_params_millions}M params
{loadResult.error}
{loadResult.suggestion &&{loadResult.suggestion}
}Click to select a model:
{exampleModels ? ( <> {exampleModels.sample_models?.length > 0 && (Loading...
)}Models auto-delete after 4 hours (except samples)
{cachedModels.length > 0 ? (No models cached
)}