()
| 126 | } |
| 127 | |
| 128 | export function ModelManagement() { |
| 129 | const { t } = useTranslation(); |
| 130 | const { toast } = useToast(); |
| 131 | const queryClient = useQueryClient(); |
| 132 | const platform = usePlatform(); |
| 133 | const customModelsDir = useServerStore((state) => state.customModelsDir); |
| 134 | const setCustomModelsDir = useServerStore((state) => state.setCustomModelsDir); |
| 135 | const [migrating, setMigrating] = useState(false); |
| 136 | const [migrationProgress, setMigrationProgress] = useState<{ |
| 137 | current: number; |
| 138 | total: number; |
| 139 | progress: number; |
| 140 | filename?: string; |
| 141 | status: string; |
| 142 | } | null>(null); |
| 143 | const [pendingMigrateDir, setPendingMigrateDir] = useState<string | null>(null); |
| 144 | const [downloadingModel, setDownloadingModel] = useState<string | null>(null); |
| 145 | const [downloadingDisplayName, setDownloadingDisplayName] = useState<string | null>(null); |
| 146 | const [consoleOpen, setConsoleOpen] = useState(false); |
| 147 | const [dismissedErrors, setDismissedErrors] = useState<Set<string>>(new Set()); |
| 148 | const [localErrors, setLocalErrors] = useState<Map<string, string>>(new Map()); |
| 149 | |
| 150 | // Modal state |
| 151 | const [selectedModel, setSelectedModel] = useState<ModelStatus | null>(null); |
| 152 | const [detailOpen, setDetailOpen] = useState(false); |
| 153 | |
| 154 | const { data: modelStatus, isLoading } = useQuery({ |
| 155 | queryKey: ['modelStatus'], |
| 156 | queryFn: async () => { |
| 157 | const result = await apiClient.getModelStatus(); |
| 158 | return result; |
| 159 | }, |
| 160 | refetchInterval: 5000, |
| 161 | }); |
| 162 | |
| 163 | const { data: cacheDir } = useQuery({ |
| 164 | queryKey: ['modelsCacheDir'], |
| 165 | queryFn: () => apiClient.getModelsCacheDir(), |
| 166 | staleTime: 1000 * 60 * 5, |
| 167 | }); |
| 168 | |
| 169 | const { data: activeTasks } = useQuery({ |
| 170 | queryKey: ['activeTasks'], |
| 171 | queryFn: () => apiClient.getActiveTasks(), |
| 172 | refetchInterval: (query) => { |
| 173 | const data = query.state.data; |
| 174 | const hasActive = data?.downloads.some((d) => d.status === 'downloading'); |
| 175 | return hasActive ? 1000 : 5000; |
| 176 | }, |
| 177 | }); |
| 178 | |
| 179 | // HuggingFace model card query - only fetches when modal is open and model has a repo ID |
| 180 | const { data: hfModelInfo, isLoading: hfLoading } = useQuery({ |
| 181 | queryKey: ['hfModelInfo', selectedModel?.hf_repo_id], |
| 182 | queryFn: () => fetchHuggingFaceModelInfo(selectedModel!.hf_repo_id!), |
| 183 | enabled: detailOpen && !!selectedModel?.hf_repo_id, |
| 184 | staleTime: 1000 * 60 * 30, // Cache for 30 minutes |
| 185 | retry: 1, |
nothing calls this directly
no test coverage detected