From c137d3ad17dcfb5d0bc1959e1d761df3103fd86f Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 27 Mar 2025 20:27:16 -0700 Subject: [PATCH] enh: allow json schema for format --- backend/open_webui/utils/payload.py | 4 + .../components/chat/Settings/General.svelte | 135 +++++++++++------- 2 files changed, 91 insertions(+), 48 deletions(-) diff --git a/backend/open_webui/utils/payload.py b/backend/open_webui/utils/payload.py index 452209491..5f8aafb78 100644 --- a/backend/open_webui/utils/payload.py +++ b/backend/open_webui/utils/payload.py @@ -116,6 +116,10 @@ def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: form_data["keep_alive"] = form_data["options"]["keep_alive"] del form_data["options"]["keep_alive"] + if "options" in form_data and "format" in form_data["options"]: + form_data["format"] = form_data["options"]["format"] + del form_data["options"]["format"] + return apply_model_params_to_body(params, form_data, mappings) diff --git a/src/lib/components/chat/Settings/General.svelte b/src/lib/components/chat/Settings/General.svelte index 666256c09..4e7e9cd36 100644 --- a/src/lib/components/chat/Settings/General.svelte +++ b/src/lib/components/chat/Settings/General.svelte @@ -9,6 +9,7 @@ const i18n = getContext('i18n'); import AdvancedParams from './Advanced/AdvancedParams.svelte'; + import Textarea from '$lib/components/common/Textarea.svelte'; export let saveSettings: Function; export let getModels: Function; @@ -40,7 +41,7 @@ }; // Advanced - let requestFormat = ''; + let requestFormat = null; let keepAlive: string | null = null; let params = { @@ -70,14 +71,74 @@ num_gpu: null }; + const validateJSON = (json) => { + try { + const obj = JSON.parse(json); + + if (obj && typeof obj === 'object') { + return true; + } + } catch (e) {} + return false; + }; + const toggleRequestFormat = async () => { - if (requestFormat === '') { + if (requestFormat === null) { requestFormat = 'json'; } else { - requestFormat = ''; + requestFormat = null; } - saveSettings({ requestFormat: requestFormat !== '' ? requestFormat : undefined }); + saveSettings({ requestFormat: requestFormat !== null ? requestFormat : undefined }); + }; + + const saveHandler = async () => { + if (requestFormat !== null && requestFormat !== 'json') { + if (validateJSON(requestFormat) === false) { + toast.error($i18n.t('Invalid JSON schema')); + return; + } else { + requestFormat = JSON.parse(requestFormat); + } + } + + saveSettings({ + system: system !== '' ? system : undefined, + params: { + stream_response: params.stream_response !== null ? params.stream_response : undefined, + function_calling: params.function_calling !== null ? params.function_calling : undefined, + seed: (params.seed !== null ? params.seed : undefined) ?? undefined, + stop: params.stop ? params.stop.split(',').filter((e) => e) : undefined, + temperature: params.temperature !== null ? params.temperature : undefined, + reasoning_effort: params.reasoning_effort !== null ? params.reasoning_effort : undefined, + logit_bias: params.logit_bias !== null ? params.logit_bias : undefined, + frequency_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined, + presence_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined, + repeat_penalty: params.frequency_penalty !== null ? params.frequency_penalty : undefined, + repeat_last_n: params.repeat_last_n !== null ? params.repeat_last_n : undefined, + mirostat: params.mirostat !== null ? params.mirostat : undefined, + mirostat_eta: params.mirostat_eta !== null ? params.mirostat_eta : undefined, + mirostat_tau: params.mirostat_tau !== null ? params.mirostat_tau : undefined, + top_k: params.top_k !== null ? params.top_k : undefined, + top_p: params.top_p !== null ? params.top_p : undefined, + min_p: params.min_p !== null ? params.min_p : undefined, + tfs_z: params.tfs_z !== null ? params.tfs_z : undefined, + num_ctx: params.num_ctx !== null ? params.num_ctx : undefined, + num_batch: params.num_batch !== null ? params.num_batch : undefined, + num_keep: params.num_keep !== null ? params.num_keep : undefined, + max_tokens: params.max_tokens !== null ? params.max_tokens : undefined, + use_mmap: params.use_mmap !== null ? params.use_mmap : undefined, + use_mlock: params.use_mlock !== null ? params.use_mlock : undefined, + num_thread: params.num_thread !== null ? params.num_thread : undefined, + num_gpu: params.num_gpu !== null ? params.num_gpu : undefined + }, + keepAlive: keepAlive ? (isNaN(keepAlive) ? keepAlive : parseInt(keepAlive)) : undefined, + requestFormat: requestFormat !== null ? requestFormat : undefined + }); + dispatch('save'); + + requestFormat = + typeof requestFormat === 'object' ? JSON.stringify(requestFormat, null, 2) : requestFormat; }; onMount(async () => { @@ -88,7 +149,12 @@ notificationEnabled = $settings.notificationEnabled ?? false; system = $settings.system ?? ''; - requestFormat = $settings.requestFormat ?? ''; + requestFormat = $settings.requestFormat ?? null; + if (requestFormat !== null && requestFormat !== 'json') { + requestFormat = + typeof requestFormat === 'object' ? JSON.stringify(requestFormat, null, 2) : requestFormat; + } + keepAlive = $settings.keepAlive ?? null; params = { ...params, ...$settings.params }; @@ -270,7 +336,7 @@
-
+
{$i18n.t('Keep Alive')}
@@ -302,8 +368,8 @@
-
-
{$i18n.t('Request Mode')}
+
+
{$i18n.t('Request Mode')}