From 3b3062abe83f622601ddf048d1348197e8a3418a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=9A=E5=AD=90?= <40852301+uiYzzi@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:11:02 +0800 Subject: [PATCH] feat(models): add extra_body config field in model add/edit UI (#1969) * Add extraBody field to model configuration forms This adds a new field allowing users to specify additional JSON fields to inject into the request body when configuring models. * Handle ExtraBody clearing when frontend sends empty object The backend now interprets an empty object sent from the frontend as a signal to clear the ExtraBody field, while nil/undefined preserves the existing value. Frontend changed to send {} instead of undefined when the field is empty. --- web/backend/api/models.go | 5 ++++ .../src/components/models/add-model-sheet.tsx | 20 +++++++++++++++- .../components/models/edit-model-sheet.tsx | 23 ++++++++++++++++++- web/frontend/src/i18n/locales/en.json | 4 +++- web/frontend/src/i18n/locales/zh.json | 4 +++- 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/web/backend/api/models.go b/web/backend/api/models.go index ce7719906..38a55948b 100644 --- a/web/backend/api/models.go +++ b/web/backend/api/models.go @@ -204,8 +204,13 @@ func (h *Handler) handleUpdateModel(w http.ResponseWriter, r *http.Request) { } else { mc.ModelConfig.SetAPIKey(mc.APIKey) } + // Preserve existing ExtraBody when omitted (nil), but clear it when + // the frontend sends an empty object {} to indicate the field should + // be removed. if mc.ExtraBody == nil { mc.ExtraBody = cfg.ModelList[idx].ExtraBody + } else if len(mc.ExtraBody) == 0 { + mc.ExtraBody = nil } cfg.ModelList[idx] = &mc.ModelConfig diff --git a/web/frontend/src/components/models/add-model-sheet.tsx b/web/frontend/src/components/models/add-model-sheet.tsx index c760bc672..c0c48994f 100644 --- a/web/frontend/src/components/models/add-model-sheet.tsx +++ b/web/frontend/src/components/models/add-model-sheet.tsx @@ -12,6 +12,7 @@ import { } 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, @@ -34,6 +35,7 @@ interface AddForm { maxTokensField: string requestTimeout: string thinkingLevel: string + extraBody: string } const EMPTY_ADD_FORM: AddForm = { @@ -49,6 +51,7 @@ const EMPTY_ADD_FORM: AddForm = { maxTokensField: "", requestTimeout: "", thinkingLevel: "", + extraBody: "", } interface AddModelSheetProps { @@ -100,7 +103,7 @@ export function AddModelSheet({ } const setField = - (key: keyof AddForm) => (e: React.ChangeEvent) => { + (key: keyof AddForm) => (e: React.ChangeEvent) => { setForm((f) => ({ ...f, [key]: e.target.value })) if (fieldErrors[key]) { setFieldErrors((prev) => ({ ...prev, [key]: undefined })) @@ -129,6 +132,9 @@ export function AddModelSheet({ ? Number(form.requestTimeout) : undefined, thinking_level: form.thinkingLevel.trim() || undefined, + extra_body: form.extraBody.trim() + ? JSON.parse(form.extraBody.trim()) + : undefined, }) if (setAsDefault) { await setDefaultModel(modelName) @@ -305,6 +311,18 @@ export function AddModelSheet({ placeholder="max_completion_tokens" /> + + +