import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { providersApi, type ApplyModePayload, type SelfHostedConfigPayload, } from "@/lib/api/providers"; export const providerKeys = { all: ["providers"] as const, catalog: () => [...providerKeys.all, "catalog"] as const, ollamaKey: () => [...providerKeys.all, "ollama-key"] as const, grokKey: () => [...providerKeys.all, "grok-key"] as const, mode: () => [...providerKeys.all, "mode"] as const, selfHostedConfig: () => [...providerKeys.all, "self-hosted-config"] as const, selfHostedModels: () => [...providerKeys.all, "self-hosted-models"] as const, selfHostedTest: () => [...providerKeys.all, "self-hosted-test"] as const, }; export function useCatalog() { return useQuery({ queryKey: providerKeys.catalog(), queryFn: () => providersApi.catalog(), staleTime: 5 * 60_000, // 5 minutes — static list }); } export function useOllamaKey() { return useQuery({ queryKey: providerKeys.ollamaKey(), queryFn: () => providersApi.getOllamaKey(), staleTime: 60_000, }); } export function useSetOllamaKey() { const qc = useQueryClient(); return useMutation({ mutationFn: (apiKey: string) => providersApi.setOllamaKey(apiKey), onSuccess: () => { qc.invalidateQueries({ queryKey: providerKeys.ollamaKey() }); // Applying a mode also reads this so refresh it too. qc.invalidateQueries({ queryKey: providerKeys.mode() }); }, }); } export function useGrokKey() { return useQuery({ queryKey: providerKeys.grokKey(), queryFn: () => providersApi.getGrokKey(), staleTime: 60_000, }); } export function useSetGrokKey() { const qc = useQueryClient(); return useMutation({ mutationFn: (apiKey: string) => providersApi.setGrokKey(apiKey), onSuccess: () => { qc.invalidateQueries({ queryKey: providerKeys.grokKey() }); qc.invalidateQueries({ queryKey: providerKeys.mode() }); }, }); } export function useRoutingMode() { return useQuery({ queryKey: providerKeys.mode(), queryFn: () => providersApi.getMode(), staleTime: 30_000, }); } export function useApplyMode() { const qc = useQueryClient(); return useMutation({ mutationFn: (payload: ApplyModePayload) => providersApi.applyMode(payload), onSuccess: () => { qc.invalidateQueries({ queryKey: providerKeys.mode() }); }, }); } // --------------------------------------------------------------------------- // Self-hosted LLM hooks // --------------------------------------------------------------------------- /** Query: fetch saved self-hosted config (base_url + has_token flag). */ export function useSelfHostedConfig() { return useQuery({ queryKey: providerKeys.selfHostedConfig(), queryFn: () => providersApi.getSelfHostedConfig(), staleTime: 30_000, }); } /** Mutation: save self-hosted base URL + optional auth token. */ export function useSetSelfHostedConfig() { const qc = useQueryClient(); return useMutation({ mutationFn: (payload: SelfHostedConfigPayload) => providersApi.saveSelfHostedConfig(payload), onSuccess: () => { qc.invalidateQueries({ queryKey: providerKeys.selfHostedConfig() }); }, }); } /** Mutation: test the self-hosted connection and return status + model count. */ export function useTestSelfHosted() { const qc = useQueryClient(); return useMutation({ mutationFn: () => providersApi.testSelfHosted(), onSuccess: () => { // After a successful test, also refresh the model list. qc.invalidateQueries({ queryKey: providerKeys.selfHostedModels() }); }, }); } /** Query: list models discovered from the self-hosted endpoint. */ export function useSelfHostedModels() { return useQuery({ queryKey: providerKeys.selfHostedModels(), queryFn: () => providersApi.getSelfHostedModels(), staleTime: 2 * 60_000, // 2 minutes }); } /** Mutation: invalidate the cached model list so it is re-fetched from GET /self-hosted/models. */ export function useRefreshSelfHostedModels() { const qc = useQueryClient(); return useMutation({ mutationFn: async () => { await qc.invalidateQueries({ queryKey: providerKeys.selfHostedModels() }); }, }); }