Spaces:
Paused
Paused
| import { useState, useCallback } from 'react' | |
| import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' | |
| import { modelsApi } from '@/lib/api/models' | |
| import { useToast } from '@/lib/hooks/use-toast' | |
| import { useTranslation } from '@/lib/hooks/use-translation' | |
| import { getApiErrorKey } from '@/lib/utils/error-handler' | |
| import { CreateModelRequest, ModelDefaults, ModelTestResult } from '@/lib/types/models' | |
| export const MODEL_QUERY_KEYS = { | |
| models: ['models'] as const, | |
| model: (id: string) => ['models', id] as const, | |
| defaults: ['models', 'defaults'] as const, | |
| providers: ['models', 'providers'] as const, | |
| } | |
| export function useModels() { | |
| return useQuery({ | |
| queryKey: MODEL_QUERY_KEYS.models, | |
| queryFn: () => modelsApi.list(), | |
| }) | |
| } | |
| export function useModel(id: string) { | |
| return useQuery({ | |
| queryKey: MODEL_QUERY_KEYS.model(id), | |
| queryFn: () => modelsApi.get(id), | |
| enabled: !!id, | |
| }) | |
| } | |
| export function useCreateModel() { | |
| const queryClient = useQueryClient() | |
| const { toast } = useToast() | |
| const { t } = useTranslation() | |
| return useMutation({ | |
| mutationFn: (data: CreateModelRequest) => modelsApi.create(data), | |
| onSuccess: () => { | |
| queryClient.invalidateQueries({ queryKey: MODEL_QUERY_KEYS.models }) | |
| toast({ | |
| title: t('common.success'), | |
| description: t('models.saveSuccess'), | |
| }) | |
| }, | |
| onError: (error: unknown) => { | |
| toast({ | |
| title: t('common.error'), | |
| description: getApiErrorKey(error, t('common.error')), | |
| variant: 'destructive', | |
| }) | |
| }, | |
| }) | |
| } | |
| export function useDeleteModel() { | |
| const queryClient = useQueryClient() | |
| const { toast } = useToast() | |
| const { t } = useTranslation() | |
| return useMutation({ | |
| mutationFn: (id: string) => modelsApi.delete(id), | |
| onSuccess: () => { | |
| queryClient.invalidateQueries({ queryKey: MODEL_QUERY_KEYS.models }) | |
| queryClient.invalidateQueries({ queryKey: MODEL_QUERY_KEYS.defaults }) | |
| queryClient.invalidateQueries({ queryKey: ['credentials'] }) | |
| toast({ | |
| title: t('common.success'), | |
| description: t('models.deleteSuccess'), | |
| }) | |
| }, | |
| onError: (error: unknown) => { | |
| toast({ | |
| title: t('common.error'), | |
| description: getApiErrorKey(error, t('common.error')), | |
| variant: 'destructive', | |
| }) | |
| }, | |
| }) | |
| } | |
| export function useModelDefaults() { | |
| return useQuery({ | |
| queryKey: MODEL_QUERY_KEYS.defaults, | |
| queryFn: () => modelsApi.getDefaults(), | |
| }) | |
| } | |
| export function useUpdateModelDefaults() { | |
| const queryClient = useQueryClient() | |
| const { toast } = useToast() | |
| const { t } = useTranslation() | |
| return useMutation({ | |
| mutationFn: (data: Partial<ModelDefaults>) => modelsApi.updateDefaults(data), | |
| onSuccess: () => { | |
| queryClient.invalidateQueries({ queryKey: MODEL_QUERY_KEYS.defaults }) | |
| toast({ | |
| title: t('common.success'), | |
| description: t('models.saveSuccess'), | |
| }) | |
| }, | |
| onError: (error: unknown) => { | |
| toast({ | |
| title: t('common.error'), | |
| description: getApiErrorKey(error, t('common.error')), | |
| variant: 'destructive', | |
| }) | |
| }, | |
| }) | |
| } | |
| export function useProviders() { | |
| return useQuery({ | |
| queryKey: MODEL_QUERY_KEYS.providers, | |
| queryFn: () => modelsApi.getProviders(), | |
| }) | |
| } | |
| export function useAutoAssignDefaults() { | |
| const queryClient = useQueryClient() | |
| const { toast } = useToast() | |
| const { t } = useTranslation() | |
| return useMutation({ | |
| mutationFn: () => modelsApi.autoAssign(), | |
| onSuccess: (result) => { | |
| queryClient.invalidateQueries({ queryKey: MODEL_QUERY_KEYS.defaults }) | |
| const assignedCount = Object.keys(result.assigned).length | |
| const missingCount = result.missing.length | |
| if (assignedCount > 0) { | |
| toast({ | |
| title: t('common.success'), | |
| description: t('models.autoAssignSuccess').replace('{count}', assignedCount.toString()), | |
| }) | |
| } else if (missingCount > 0) { | |
| toast({ | |
| title: t('common.warning'), | |
| description: t('models.autoAssignNoModels'), | |
| variant: 'destructive', | |
| }) | |
| } else { | |
| toast({ | |
| title: t('common.success'), | |
| description: t('models.autoAssignAlreadySet'), | |
| }) | |
| } | |
| }, | |
| onError: (error: unknown) => { | |
| toast({ | |
| title: t('common.error'), | |
| description: getApiErrorKey(error, t('common.error')), | |
| variant: 'destructive', | |
| }) | |
| }, | |
| }) | |
| } | |
| export function useTestModel() { | |
| const [testResult, setTestResult] = useState<ModelTestResult | null>(null) | |
| const [testedModelName, setTestedModelName] = useState('') | |
| const [testingModelId, setTestingModelId] = useState<string | null>(null) | |
| const mutation = useMutation({ | |
| mutationFn: (modelId: string) => modelsApi.testModel(modelId), | |
| onSuccess: (result) => { | |
| setTestResult(result) | |
| setTestingModelId(null) | |
| }, | |
| onError: (error: unknown) => { | |
| const msg = error instanceof Error ? error.message : String(error) | |
| setTestResult({ success: false, message: msg }) | |
| setTestingModelId(null) | |
| }, | |
| }) | |
| const testModel = useCallback((modelId: string, modelName: string) => { | |
| setTestedModelName(modelName) | |
| setTestingModelId(modelId) | |
| setTestResult(null) | |
| mutation.mutate(modelId) | |
| }, [mutation]) | |
| const clearResult = useCallback(() => { | |
| setTestResult(null) | |
| setTestedModelName('') | |
| setTestingModelId(null) | |
| }, []) | |
| return { | |
| testModel, | |
| isPending: mutation.isPending, | |
| testingModelId, | |
| testResult, | |
| testedModelName, | |
| clearResult, | |
| } | |
| } | |