'use client'; import React, { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { ManualModelSchema, type ManualModel } from '@/lib/api/schemas/models'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form'; import { Plus, Loader2 } from 'lucide-react'; import { toast } from 'sonner'; interface AddModelFormProps { onModelAdd: (model: ManualModel) => void; onCancel?: () => void; isOpen: boolean; } export function AddModelForm({ onModelAdd, onCancel, isOpen, }: AddModelFormProps) { const [isSubmitting, setIsSubmitting] = useState(false); const form = useForm({ resolver: zodResolver(ManualModelSchema) as any, // eslint-disable-line @typescript-eslint/no-explicit-any defaultValues: { name: '', full_name: '', input_cost: 0, output_cost: 0, provider: '', modelType: 'text' as const, description: '', contextLength: undefined, }, }); const onSubmit = async (data: ManualModel) => { setIsSubmitting(true); try { await onModelAdd(data); toast.success('Model added successfully!'); form.reset(); onCancel?.(); } catch (error) { toast.error('Failed to add model. Please try again.'); console.error('Error adding model:', error); } finally { setIsSubmitting(false); } }; const handleClose = () => { if (!isSubmitting) { form.reset(); onCancel?.(); } }; return ( Add New Model Manually add a new AI model to your collection
( Model Name * Display name for the model )} /> ( Provider * AI model provider or company )} />
( Input Cost (per 1M tokens) * { const value = parseFloat(e.target.value) || 0; const rounded = Math.round(value * 1000) / 1000; field.onChange(rounded); }} className='w-full' /> Cost in USD per 1,000,000 input tokens (max 3 decimals) )} /> ( Output Cost (per 1M tokens) * { const value = parseFloat(e.target.value) || 0; const rounded = Math.round(value * 1000) / 1000; field.onChange(rounded); }} className='w-full' /> Cost in USD per 1,000,000 output tokens (max 3 decimals) )} />
( Model Type Type of AI model functionality )} /> ( Context Length { const val = parseInt(e.target.value); field.onChange( isNaN(val) || val === 0 ? undefined : val ); }} className='w-full' /> Maximum context length in tokens (optional, leave empty for default) )} />
( Description