import { IconLoader2 } from "@tabler/icons-react" import { useEffect, useState } from "react" import { useTranslation } from "react-i18next" import { type ModelInfo, setDefaultModel, updateModel } from "@/api/models" import { maskedSecretPlaceholder } from "@/components/secret-placeholder" import { AdvancedSection, Field, KeyInput, SwitchCardField, } from "@/components/shared-form" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Textarea } from "@/components/ui/textarea" import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet" interface EditForm { apiKey: string apiBase: string proxy: string authMethod: string connectMode: string workspace: string rpm: string maxTokensField: string requestTimeout: string thinkingLevel: string extraBody: string } interface EditModelSheetProps { model: ModelInfo | null open: boolean onClose: () => void onSaved: () => void } export function EditModelSheet({ model, open, onClose, onSaved, }: EditModelSheetProps) { const { t } = useTranslation() const [form, setForm] = useState({ apiKey: "", apiBase: "", proxy: "", authMethod: "", connectMode: "", workspace: "", rpm: "", maxTokensField: "", requestTimeout: "", thinkingLevel: "", extraBody: "", }) const [saving, setSaving] = useState(false) const [setAsDefault, setSetAsDefault] = useState(false) const [error, setError] = useState("") useEffect(() => { if (model) { setForm({ apiKey: "", apiBase: model.api_base ?? "", proxy: model.proxy ?? "", authMethod: model.auth_method ?? "", connectMode: model.connect_mode ?? "", workspace: model.workspace ?? "", rpm: model.rpm ? String(model.rpm) : "", maxTokensField: model.max_tokens_field ?? "", requestTimeout: model.request_timeout ? String(model.request_timeout) : "", thinkingLevel: model.thinking_level ?? "", extraBody: model.extra_body ? JSON.stringify(model.extra_body, null, 2) : "", }) setSetAsDefault(model.is_default) setError("") } }, [model]) const setField = (key: keyof EditForm) => (e: React.ChangeEvent) => setForm((f) => ({ ...f, [key]: e.target.value })) const handleSave = async () => { if (!model) return setSaving(true) setError("") try { await updateModel(model.index, { model_name: model.model_name, model: model.model, api_base: form.apiBase || undefined, api_key: form.apiKey || undefined, proxy: form.proxy || undefined, auth_method: form.authMethod || undefined, connect_mode: form.connectMode || undefined, workspace: form.workspace || undefined, rpm: form.rpm ? Number(form.rpm) : undefined, max_tokens_field: form.maxTokensField || undefined, request_timeout: form.requestTimeout ? Number(form.requestTimeout) : undefined, thinking_level: form.thinkingLevel || undefined, extra_body: form.extraBody.trim() ? JSON.parse(form.extraBody.trim()) : {}, }) if (setAsDefault && !model.is_default) { await setDefaultModel(model.model_name) } onSaved() onClose() } catch (e) { setError(e instanceof Error ? e.message : t("models.edit.saveError")) } finally { setSaving(false) } } const isOAuth = model?.auth_method === "oauth" const apiKeyPlaceholder = model?.configured ? maskedSecretPlaceholder( model.api_key, t("models.field.apiKeyPlaceholderSet"), ) : t("models.field.apiKeyPlaceholder") return ( !v && onClose()}> {t("models.edit.title", { name: model?.model_name })} {model?.model}
{!isOAuth && ( setForm((f) => ({ ...f, apiKey: v }))} placeholder={apiKeyPlaceholder} /> )}