From 9b93b81f84b1280faa9046e74e45c879458b0a4e Mon Sep 17 00:00:00 2001
From: dongfangzan <787814104@qq.com>
Date: Thu, 15 May 2025 19:56:10 +0800
Subject: [PATCH] feat: add switching thinking/non-thinking modes to models
---
backend/open_webui/utils/middleware.py | 5 ++++
src/lib/components/chat/Chat.svelte | 15 ++++++++--
src/lib/components/chat/MessageInput.svelte | 29 ++++++++++++++++++-
src/lib/components/chat/Placeholder.svelte | 2 ++
src/lib/components/icons/Thinking.svelte | 19 ++++++++++++
.../workspace/Models/Capabilities.svelte | 4 ++-
.../workspace/Models/ModelEditor.svelte | 3 +-
src/lib/i18n/locales/zh-CN/translation.json | 2 ++
8 files changed, 74 insertions(+), 5 deletions(-)
create mode 100644 src/lib/components/icons/Thinking.svelte
diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py
index 442dfba76..58a5cdeae 100644
--- a/backend/open_webui/utils/middleware.py
+++ b/backend/open_webui/utils/middleware.py
@@ -785,6 +785,11 @@ async def process_chat_payload(request, form_data, user, metadata, model):
),
form_data["messages"],
)
+ if "thinking" in features:
+ form_data["enable_thinking"] = features["thinking"]
+ form_data["chat_template_kwargs"] = {
+ "enable_thinking": features["thinking"]
+ }
tool_ids = form_data.pop("tool_ids", None)
files = form_data.pop("files", None)
diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte
index 34abc20e8..776555227 100644
--- a/src/lib/components/chat/Chat.svelte
+++ b/src/lib/components/chat/Chat.svelte
@@ -121,8 +121,8 @@
let selectedToolIds = [];
let imageGenerationEnabled = false;
let webSearchEnabled = false;
- let thinkingEnabled = false;
let codeInterpreterEnabled = false;
+ let thinkingEnabled = false;
let chat = null;
let tags = [];
@@ -148,6 +148,7 @@
files = [];
selectedToolIds = [];
webSearchEnabled = false;
+ webSearchEnabled = false;
imageGenerationEnabled = false;
if (localStorage.getItem(`chat-input${chatIdProp ? `-${chatIdProp}` : ''}`)) {
@@ -161,6 +162,7 @@
files = input.files;
selectedToolIds = input.selectedToolIds;
webSearchEnabled = input.webSearchEnabled;
+ thinkingEnabled = input.thinkingEnabled;
imageGenerationEnabled = input.imageGenerationEnabled;
codeInterpreterEnabled = input.codeInterpreterEnabled;
}
@@ -426,6 +428,7 @@
files = [];
selectedToolIds = [];
webSearchEnabled = false;
+ thinkingEnabled = false;
imageGenerationEnabled = false;
codeInterpreterEnabled = false;
@@ -441,6 +444,7 @@
webSearchEnabled = input.webSearchEnabled;
imageGenerationEnabled = input.imageGenerationEnabled;
codeInterpreterEnabled = input.codeInterpreterEnabled;
+ thinkingEnabled = input.thinkingEnabled;
}
} catch (e) {}
}
@@ -749,6 +753,10 @@
webSearchEnabled = true;
}
+ if ($page.url.searchParams.get('thinking') === 'true') {
+ thinkingEnabled = true;
+ }
+
if ($page.url.searchParams.get('image-generation') === 'true') {
imageGenerationEnabled = true;
}
@@ -1636,7 +1644,8 @@
$config?.features?.enable_web_search &&
($user?.role === 'admin' || $user?.permissions?.features?.web_search)
? webSearchEnabled || ($settings?.webSearch ?? false) === 'always'
- : false
+ : false,
+ thinking: thinkingEnabled
},
variables: {
...getPromptVariables(
@@ -2062,6 +2071,7 @@
bind:imageGenerationEnabled
bind:codeInterpreterEnabled
bind:webSearchEnabled
+ bind:thinkingEnabled
bind:atSelectedModel
toolServers={$toolServers}
transparentBackground={$settings?.backgroundImageUrl ?? false}
@@ -2118,6 +2128,7 @@
bind:imageGenerationEnabled
bind:codeInterpreterEnabled
bind:webSearchEnabled
+ bind:thinkingEnabled
bind:atSelectedModel
transparentBackground={$settings?.backgroundImageUrl ?? false}
toolServers={$toolServers}
diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte
index 9e5593ea9..2b1fcd9b7 100644
--- a/src/lib/components/chat/MessageInput.svelte
+++ b/src/lib/components/chat/MessageInput.svelte
@@ -47,6 +47,7 @@
import XMark from '../icons/XMark.svelte';
import Headphone from '../icons/Headphone.svelte';
import GlobeAlt from '../icons/GlobeAlt.svelte';
+ import Thinking from "../icons/Thinking.svelte";
import PhotoSolid from '../icons/PhotoSolid.svelte';
import Photo from '../icons/Photo.svelte';
import CommandLine from '../icons/CommandLine.svelte';
@@ -83,6 +84,7 @@
export let imageGenerationEnabled = false;
export let webSearchEnabled = false;
export let codeInterpreterEnabled = false;
+ export let thinkingEnabled = false;
$: onChange({
prompt,
@@ -90,7 +92,8 @@
selectedToolIds,
imageGenerationEnabled,
webSearchEnabled,
- codeInterpreterEnabled
+ codeInterpreterEnabled,
+ thinkingEnabled
});
let showTools = false;
@@ -117,6 +120,10 @@
(model) => $models.find((m) => m.id === model)?.info?.meta?.capabilities?.vision ?? true
);
+ let switchThinkingCapableModels = [];
+ $: switchThinkingCapableModels = $models.filter((model) => model.info?.meta?.capabilities?.switch_thinking ?? false)
+ .map((model) => model.id)
+
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTo({
@@ -773,6 +780,7 @@
selectedToolIds = [];
webSearchEnabled = false;
imageGenerationEnabled = false;
+ thinkingEnabled = false;
}
}}
on:paste={async (e) => {
@@ -980,6 +988,7 @@
selectedToolIds = [];
webSearchEnabled = false;
imageGenerationEnabled = false;
+ thinkingEnabled = false;
}
}}
rows="1"
@@ -1127,6 +1136,24 @@
{/if}
{#if $_user}
+ {#if selectedModels.length > 0 && selectedModels.some((model) => switchThinkingCapableModels.includes(model))}
+
+
+
+ {/if}
+
{#if $config?.features?.enable_web_search && ($_user.role === 'admin' || $_user?.permissions?.features?.web_search)}