"use client"; import { useAtomValue } from "jotai"; import { AlertCircle, Bot, Clock, Edit3, FileText, Loader2, MessageSquareQuote, Plus, RefreshCw, Sparkles, Trash2, Wand2, } from "lucide-react"; import { AnimatePresence, motion } from "motion/react"; import { useCallback, useState } from "react"; import { toast } from "sonner"; import { createNewLLMConfigMutationAtom, deleteNewLLMConfigMutationAtom, updateNewLLMConfigMutationAtom, } from "@/atoms/new-llm-config/new-llm-config-mutation.atoms"; import { globalNewLLMConfigsAtom, newLLMConfigsAtom, } from "@/atoms/new-llm-config/new-llm-config-query.atoms"; import { LLMConfigForm, type LLMConfigFormData } from "@/components/shared/llm-config-form"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { LLM_PROVIDERS } from "@/contracts/enums/llm-providers"; import type { NewLLMConfig } from "@/contracts/types/new-llm-config.types"; import { cn } from "@/lib/utils"; interface ModelConfigManagerProps { searchSpaceId: number; } const container = { hidden: { opacity: 0 }, show: { opacity: 1, transition: { staggerChildren: 0.05, }, }, }; const item = { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 }, }; export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) { // Mutations const { mutateAsync: createConfig, isPending: isCreating, error: createError, } = useAtomValue(createNewLLMConfigMutationAtom); const { mutateAsync: updateConfig, isPending: isUpdating, error: updateError, } = useAtomValue(updateNewLLMConfigMutationAtom); const { mutateAsync: deleteConfig, isPending: isDeleting, error: deleteError, } = useAtomValue(deleteNewLLMConfigMutationAtom); // Queries const { data: configs, isFetching: isLoading, error: fetchError, refetch: refreshConfigs, } = useAtomValue(newLLMConfigsAtom); const { data: globalConfigs = [] } = useAtomValue(globalNewLLMConfigsAtom); // Local state const [isDialogOpen, setIsDialogOpen] = useState(false); const [editingConfig, setEditingConfig] = useState(null); const [configToDelete, setConfigToDelete] = useState(null); const isSubmitting = isCreating || isUpdating; const errors = [createError, updateError, deleteError, fetchError].filter(Boolean) as Error[]; const handleFormSubmit = useCallback( async (formData: LLMConfigFormData) => { try { if (editingConfig) { await updateConfig({ id: editingConfig.id, data: { ...formData, search_space_id: undefined, // Can't change search_space_id }, }); } else { await createConfig(formData); } setIsDialogOpen(false); setEditingConfig(null); } catch { // Error handled by mutation } }, [editingConfig, createConfig, updateConfig] ); const handleDelete = async () => { if (!configToDelete) return; try { await deleteConfig({ id: configToDelete.id }); setConfigToDelete(null); } catch { // Error handled by mutation } }; const openEditDialog = (config: NewLLMConfig) => { setEditingConfig(config); setIsDialogOpen(true); }; const openNewDialog = () => { setEditingConfig(null); setIsDialogOpen(true); }; const closeDialog = () => { setIsDialogOpen(false); setEditingConfig(null); }; const getProviderInfo = (providerValue: string) => LLM_PROVIDERS.find((p) => p.value === providerValue); return (
{/* Header */}
{/* Error Alerts */} {errors.length > 0 && errors.map((err, i) => ( {err?.message ?? "Something went wrong"} ))} {/* Global Configs Info */} {globalConfigs.length > 0 && ( {globalConfigs.length} global configuration(s){" "} available from your administrator. These are pre-configured and ready to use.{" "} Global configs: {globalConfigs.map((g) => g.name).join(", ")} )} {/* Loading State */} {isLoading && (
Loading configurations...
)} {/* Configurations List */} {!isLoading && (

Your Configurations

{configs?.length === 0 ? (

No Configurations Yet

Create your first AI configuration to customize how your agent responds

) : ( {configs?.map((config) => { const providerInfo = getProviderInfo(config.provider); return (
{/* Left accent bar */}
{/* Main content */}
{/* Title row */}

{config.name}

{config.provider} {config.citations_enabled && ( Citations Citations are enabled for this configuration )} {!config.use_default_system_instructions && config.system_instructions && ( Custom Using custom system instructions )}
{/* Model name */} {config.model_name} {/* Description if any */} {config.description && (

{config.description}

)} {/* Footer row */}
{new Date(config.created_at).toLocaleDateString()}
{/* Actions */}
Edit Delete
); })} )}
)} {/* Add/Edit Configuration Dialog */} !open && closeDialog()}> {editingConfig ? ( ) : ( )} {editingConfig ? "Edit Configuration" : "Create New Configuration"} {editingConfig ? "Update your AI model and prompt configuration" : "Set up a new AI model with custom prompts and citation settings"} {/* Delete Confirmation Dialog */} !open && setConfigToDelete(null)} > Delete Configuration Are you sure you want to delete{" "} {configToDelete?.name}? This action cannot be undone. Cancel {isDeleting ? ( <> Deleting... ) : ( <> Delete )}
); }