'use client' import { useState } from 'react' import { Navigation } from '@/components/navigation' import { Alert, AlertDescription } from '@/components/ui/alert' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Separator } from '@/components/ui/separator' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' import { Textarea } from '@/components/ui/textarea' // Import SWR hooks and utilities import { getErrorMessage, useDebounce, useModels, useUpdateModel } from '@/lib/api-client' import type { CapabilityType, Model } from '@/lib/catalog-types' // Type-safe capabilities list const CAPABILITIES: readonly CapabilityType[] = [ 'FUNCTION_CALL', 'REASONING', 'IMAGE_RECOGNITION', 'IMAGE_GENERATION', 'AUDIO_RECOGNITION', 'AUDIO_GENERATION', 'EMBEDDING', 'RERANK', 'AUDIO_TRANSCRIPT', 'VIDEO_RECOGNITION', 'VIDEO_GENERATION', 'STRUCTURED_OUTPUT', 'FILE_INPUT', 'WEB_SEARCH', 'CODE_EXECUTION', 'FILE_SEARCH', 'COMPUTER_USE' ] as const // Simple Pagination Component function SimplePagination({ currentPage, totalPages, onPageChange }: { currentPage: number totalPages: number onPageChange: (page: number) => void }) { const pages = Array.from({ length: Math.min(5, totalPages) }, (_, i) => { if (totalPages <= 5) return i + 1 if (currentPage <= 3) return i + 1 if (currentPage >= totalPages - 2) return totalPages - 4 + i return currentPage - 2 + i }) return (
{pages.map((page) => ( ))}
) } export default function CatalogReview() { // Form state const [search, setSearch] = useState('') const [selectedCapabilities, setSelectedCapabilities] = useState([]) const [selectedProviders, setSelectedProviders] = useState([]) const [currentPage, setCurrentPage] = useState(1) const [editingModel, setEditingModel] = useState(null) const [jsonContent, setJsonContent] = useState('') // Debounce search to avoid excessive API calls const debouncedSearch = useDebounce(search, 300) // SWR hook for fetching models const { data: modelsData, error, isLoading } = useModels({ page: currentPage, limit: 20, search: debouncedSearch, capabilities: selectedCapabilities.length > 0 ? selectedCapabilities : undefined, providers: selectedProviders.length > 0 ? selectedProviders : undefined }) // SWR mutation for updating models const { trigger: updateModel, isMutating: isUpdating } = useUpdateModel() // Extract data from SWR response const models = modelsData?.data || [] const pagination = modelsData?.pagination || { page: 1, limit: 20, total: 0, totalPages: 0, hasNext: false, hasPrev: false } const handleEdit = (model: Model) => { setEditingModel(model) setJsonContent(JSON.stringify(model, null, 2)) } const handleSave = async () => { if (!editingModel) return try { // Validate JSON before sending const updatedModel = JSON.parse(jsonContent) as unknown // Basic validation - the API will do thorough validation if (!updatedModel || typeof updatedModel !== 'object') { throw new Error('Invalid JSON format') } // Use SWR mutation for optimistic update await updateModel({ id: editingModel.id, data: updatedModel as Partial }) // Close dialog and reset form setEditingModel(null) setJsonContent('') } catch (error) { console.error('Error saving model:', error) // Error will be handled by SWR and displayed in UI } } // Type-safe function to extract unique providers const getUniqueProviders = (): string[] => { return [ ...new Set(models.map((model) => model.owned_by).filter((provider): provider is string => Boolean(provider))) ] } return (

Catalog Review

Review and validate model configurations after migration

Filters Filter models to review specific configurations
setSearch(e.target.value)} className="max-w-sm" />
{CAPABILITIES.map((capability) => ( { setSelectedCapabilities((prev) => prev.includes(capability) ? prev.filter((c) => c !== capability) : [...prev, capability] ) }}> {capability.replace('_', ' ')} ))}
{getUniqueProviders().map((provider) => ( { setSelectedProviders((prev) => prev.includes(provider) ? prev.filter((p) => p !== provider) : [...prev, provider] ) }}> {provider} ))}
{/* Error Display */} {error && ( {getErrorMessage(error)} )} Models ({pagination.total}) Review migrated model configurations {isLoading ? (
Loading models...
) : ( <> ID Name Provider Capabilities Context Window Modalities Actions {models.map((model) => ( {model.id} {model.name || model.id} {model.owned_by}
{model.capabilities.slice(0, 3).map((cap) => ( {cap.replace('_', ' ')} ))} {model.capabilities.length > 3 && ( +{model.capabilities.length - 3} )}
{model.context_window.toLocaleString()}
In: {model.input_modalities?.join(', ')}
Out: {model.output_modalities?.join(', ')}
Edit Model Configuration Modify the JSON configuration for {model.name || model.id}