Browse Source

feat: custom advanced params

Timothy Jaeryang Baek 1 month ago
parent
commit
9220afe7b3

+ 6 - 0
backend/open_webui/utils/middleware.py

@@ -658,6 +658,12 @@ async def chat_completion_files_handler(
 
 def apply_params_to_form_data(form_data, model):
     params = form_data.pop("params", {})
+    custom_params = params.pop("custom_params", {})
+
+    if custom_params:
+        # If custom_params are provided, merge them into params
+        params = deep_update(params, custom_params)
+
     if model.get("ollama"):
         form_data["options"] = params
 

+ 11 - 0
backend/open_webui/utils/payload.py

@@ -1,5 +1,6 @@
 from open_webui.utils.task import prompt_template, prompt_variables_template
 from open_webui.utils.misc import (
+    deep_update,
     add_or_update_system_message,
 )
 
@@ -59,6 +60,11 @@ def apply_model_params_to_body(
 
 # inplace function: form_data is modified
 def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict:
+    custom_params = params.pop("custom_params", {})
+    if custom_params:
+        # If there are custom parameters, we need to apply them first
+        params = deep_update(params, custom_params)
+
     mappings = {
         "temperature": float,
         "top_p": float,
@@ -76,6 +82,11 @@ def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict:
 
 
 def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict:
+    custom_params = params.pop("custom_params", {})
+    if custom_params:
+        # If there are custom parameters, we need to apply them first
+        params = deep_update(params, custom_params)
+
     # Convert OpenAI parameter names to Ollama parameter names if needed.
     name_differences = {
         "max_tokens": "num_predict",

+ 1 - 1
src/lib/components/chat/Controls/Controls.svelte

@@ -86,7 +86,7 @@
 			<Collapsible title={$i18n.t('Advanced Params')} open={true} buttonClassName="w-full">
 				<div class="text-sm mt-1.5" slot="content">
 					<div>
-						<AdvancedParams admin={$user?.role === 'admin'} bind:params />
+						<AdvancedParams admin={$user?.role === 'admin'} custom={true} bind:params />
 					</div>
 				</div>
 			</Collapsible>

+ 81 - 46
src/lib/components/chat/Settings/Advanced/AdvancedParams.svelte

@@ -1,15 +1,17 @@
 <script lang="ts">
 	import Switch from '$lib/components/common/Switch.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
-	import { getContext, createEventDispatcher } from 'svelte';
-
-	const dispatch = createEventDispatcher();
+	import Plus from '$lib/components/icons/Plus.svelte';
+	import { getContext } from 'svelte';
 
 	const i18n = getContext('i18n');
 
+	export let onChange: (params: any) => void = () => {};
+
 	export let admin = false;
+	export let custom = false;
 
-	export let params = {
+	const defaultParams = {
 		// Advanced
 		stream_response: null, // Set stream responses for this model individually
 		function_calling: null,
@@ -18,31 +20,30 @@
 		temperature: null,
 		reasoning_effort: null,
 		logit_bias: null,
+		max_tokens: null,
+		top_k: null,
+		top_p: null,
+		min_p: null,
 		frequency_penalty: null,
-		repeat_last_n: null,
+		presence_penalty: null,
 		mirostat: null,
 		mirostat_eta: null,
 		mirostat_tau: null,
-		top_k: null,
-		top_p: null,
-		min_p: null,
+		repeat_last_n: null,
 		tfs_z: null,
-		num_ctx: null,
-		num_batch: null,
-		num_keep: null,
-		max_tokens: null,
+		repeat_penalty: null,
 		use_mmap: null,
 		use_mlock: null,
+		num_keep: null,
+		num_ctx: null,
+		num_batch: null,
 		num_thread: null,
-		num_gpu: null,
-		template: null
+		num_gpu: null
 	};
 
-	let customFieldName = '';
-	let customFieldValue = '';
-
+	export let params = defaultParams;
 	$: if (params) {
-		dispatch('change', params);
+		onChange(params);
 	}
 </script>
 
@@ -145,7 +146,7 @@
 			<div class="flex mt-0.5 space-x-2">
 				<div class=" flex-1">
 					<input
-						class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-hidden"
+						class="text-sm w-full bg-transparent outline-hidden outline-none"
 						type="number"
 						placeholder={$i18n.t('Enter Seed')}
 						bind:value={params.seed}
@@ -190,7 +191,7 @@
 			<div class="flex mt-0.5 space-x-2">
 				<div class=" flex-1">
 					<input
-						class="w-full rounded-lg py-2 px-1 text-sm dark:text-gray-300 dark:bg-gray-850 outline-hidden"
+						class="text-sm w-full bg-transparent outline-hidden outline-none"
 						type="text"
 						placeholder={$i18n.t('Enter stop sequence')}
 						bind:value={params.stop}
@@ -288,7 +289,7 @@
 			<div class="flex mt-0.5 space-x-2">
 				<div class=" flex-1">
 					<input
-						class="w-full rounded-lg py-2 px-1 text-sm dark:text-gray-300 dark:bg-gray-850 outline-hidden"
+						class="text-sm w-full bg-transparent outline-hidden outline-none"
 						type="text"
 						placeholder={$i18n.t('Enter reasoning effort')}
 						bind:value={params.reasoning_effort}
@@ -331,7 +332,7 @@
 			<div class="flex mt-0.5 space-x-2">
 				<div class=" flex-1">
 					<input
-						class="w-full rounded-lg pl-2 py-2 px-1 text-sm dark:text-gray-300 dark:bg-gray-850 outline-hidden"
+						class="text-sm w-full bg-transparent outline-hidden outline-none"
 						type="text"
 						placeholder={$i18n.t(
 							'Enter comma-separated "token:bias_value" pairs (example: 5432:100, 413:-100)'
@@ -1367,37 +1368,71 @@
 			{/if}
 		</div>
 
-		<!-- <div class=" py-0.5 w-full justify-between">
-			<div class="flex w-full justify-between">
-				<div class=" self-center text-xs font-medium">{$i18n.t('Template')}</div>
+		{#if custom && admin}
+			<div class="flex flex-col justify-center">
+				{#each Object.keys(params?.custom_params ?? {}) as key}
+					<div class=" py-0.5 w-full justify-between mb-1">
+						<div class="flex w-full justify-between">
+							<div class=" self-center text-xs font-medium">
+								<input
+									type="text"
+									class=" text-xs w-full bg-transparent outline-none"
+									placeholder={$i18n.t('Custom Parameter Name')}
+									value={key}
+									on:change={(e) => {
+										const newKey = e.target.value.trim();
+										if (newKey && newKey !== key) {
+											params.custom_params[newKey] = params.custom_params[key];
+											delete params.custom_params[key];
+											params = {
+												...params,
+												custom_params: { ...params.custom_params }
+											};
+										}
+									}}
+								/>
+							</div>
+							<button
+								class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden"
+								type="button"
+								on:click={() => {
+									delete params.custom_params[key];
+									params = {
+										...params,
+										custom_params: { ...params.custom_params }
+									};
+								}}
+							>
+								{$i18n.t('Remove')}
+							</button>
+						</div>
+						<div class="flex mt-0.5 space-x-2">
+							<div class=" flex-1">
+								<input
+									bind:value={params.custom_params[key]}
+									type="text"
+									class="text-sm w-full bg-transparent outline-hidden outline-none"
+									placeholder={$i18n.t('Custom Parameter Value')}
+								/>
+							</div>
+						</div>
+					</div>
+				{/each}
 
 				<button
-					class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden"
+					class=" flex gap-2 items-center w-full text-center justify-center mb-5"
 					type="button"
 					on:click={() => {
-						params.template = (params?.template ?? null) === null ? '' : null;
+						params.custom_params = (params?.custom_params ?? {}) || {};
+						params.custom_params['custom_param_name'] = 'custom_param_value';
 					}}
 				>
-					{#if (params?.template ?? null) === null}
-						<span class="ml-2 self-center">{$i18n.t('Default')}</span>
-					{:else}
-						<span class="ml-2 self-center">{$i18n.t('Custom')}</span>
-					{/if}
+					<div>
+						<Plus />
+					</div>
+					<div>{$i18n.t('Add Custom Parameter')}</div>
 				</button>
 			</div>
-
-			{#if (params?.template ?? null) !== null}
-				<div class="flex mt-0.5 space-x-2">
-					<div class=" flex-1">
-						<textarea
-							class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-hidden rounded-lg -mb-1"
-							placeholder={$i18n.t('Write your model template content here')}
-							rows="4"
-							bind:value={params.template}
-						/>
-					</div>
-				</div>
-			{/if}
-		</div> -->
+		{/if}
 	{/if}
 </div>

+ 2 - 7
src/lib/components/workspace/Models/ModelEditor.svelte

@@ -119,6 +119,7 @@
 			toast.error('Model Name is required.');
 		}
 
+		info.params = { ...info.params, ...params };
 		info.access_control = accessControl;
 		info.meta.capabilities = capabilities;
 
@@ -588,13 +589,7 @@
 
 							{#if showAdvanced}
 								<div class="my-2">
-									<AdvancedParams
-										admin={true}
-										bind:params
-										on:change={(e) => {
-											info.params = { ...info.params, ...params };
-										}}
-									/>
+									<AdvancedParams admin={true} custom={true} bind:params />
 								</div>
 							{/if}
 						</div>