mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: add switching thinking/non-thinking modes to models
This commit is contained in:
parent
a7c90925ef
commit
9b93b81f84
@ -785,6 +785,11 @@ async def process_chat_payload(request, form_data, user, metadata, model):
|
|||||||
),
|
),
|
||||||
form_data["messages"],
|
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)
|
tool_ids = form_data.pop("tool_ids", None)
|
||||||
files = form_data.pop("files", None)
|
files = form_data.pop("files", None)
|
||||||
|
@ -121,8 +121,8 @@
|
|||||||
let selectedToolIds = [];
|
let selectedToolIds = [];
|
||||||
let imageGenerationEnabled = false;
|
let imageGenerationEnabled = false;
|
||||||
let webSearchEnabled = false;
|
let webSearchEnabled = false;
|
||||||
let thinkingEnabled = false;
|
|
||||||
let codeInterpreterEnabled = false;
|
let codeInterpreterEnabled = false;
|
||||||
|
let thinkingEnabled = false;
|
||||||
|
|
||||||
let chat = null;
|
let chat = null;
|
||||||
let tags = [];
|
let tags = [];
|
||||||
@ -148,6 +148,7 @@
|
|||||||
files = [];
|
files = [];
|
||||||
selectedToolIds = [];
|
selectedToolIds = [];
|
||||||
webSearchEnabled = false;
|
webSearchEnabled = false;
|
||||||
|
webSearchEnabled = false;
|
||||||
imageGenerationEnabled = false;
|
imageGenerationEnabled = false;
|
||||||
|
|
||||||
if (localStorage.getItem(`chat-input${chatIdProp ? `-${chatIdProp}` : ''}`)) {
|
if (localStorage.getItem(`chat-input${chatIdProp ? `-${chatIdProp}` : ''}`)) {
|
||||||
@ -161,6 +162,7 @@
|
|||||||
files = input.files;
|
files = input.files;
|
||||||
selectedToolIds = input.selectedToolIds;
|
selectedToolIds = input.selectedToolIds;
|
||||||
webSearchEnabled = input.webSearchEnabled;
|
webSearchEnabled = input.webSearchEnabled;
|
||||||
|
thinkingEnabled = input.thinkingEnabled;
|
||||||
imageGenerationEnabled = input.imageGenerationEnabled;
|
imageGenerationEnabled = input.imageGenerationEnabled;
|
||||||
codeInterpreterEnabled = input.codeInterpreterEnabled;
|
codeInterpreterEnabled = input.codeInterpreterEnabled;
|
||||||
}
|
}
|
||||||
@ -426,6 +428,7 @@
|
|||||||
files = [];
|
files = [];
|
||||||
selectedToolIds = [];
|
selectedToolIds = [];
|
||||||
webSearchEnabled = false;
|
webSearchEnabled = false;
|
||||||
|
thinkingEnabled = false;
|
||||||
imageGenerationEnabled = false;
|
imageGenerationEnabled = false;
|
||||||
codeInterpreterEnabled = false;
|
codeInterpreterEnabled = false;
|
||||||
|
|
||||||
@ -441,6 +444,7 @@
|
|||||||
webSearchEnabled = input.webSearchEnabled;
|
webSearchEnabled = input.webSearchEnabled;
|
||||||
imageGenerationEnabled = input.imageGenerationEnabled;
|
imageGenerationEnabled = input.imageGenerationEnabled;
|
||||||
codeInterpreterEnabled = input.codeInterpreterEnabled;
|
codeInterpreterEnabled = input.codeInterpreterEnabled;
|
||||||
|
thinkingEnabled = input.thinkingEnabled;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
@ -749,6 +753,10 @@
|
|||||||
webSearchEnabled = true;
|
webSearchEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($page.url.searchParams.get('thinking') === 'true') {
|
||||||
|
thinkingEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($page.url.searchParams.get('image-generation') === 'true') {
|
if ($page.url.searchParams.get('image-generation') === 'true') {
|
||||||
imageGenerationEnabled = true;
|
imageGenerationEnabled = true;
|
||||||
}
|
}
|
||||||
@ -1636,7 +1644,8 @@
|
|||||||
$config?.features?.enable_web_search &&
|
$config?.features?.enable_web_search &&
|
||||||
($user?.role === 'admin' || $user?.permissions?.features?.web_search)
|
($user?.role === 'admin' || $user?.permissions?.features?.web_search)
|
||||||
? webSearchEnabled || ($settings?.webSearch ?? false) === 'always'
|
? webSearchEnabled || ($settings?.webSearch ?? false) === 'always'
|
||||||
: false
|
: false,
|
||||||
|
thinking: thinkingEnabled
|
||||||
},
|
},
|
||||||
variables: {
|
variables: {
|
||||||
...getPromptVariables(
|
...getPromptVariables(
|
||||||
@ -2062,6 +2071,7 @@
|
|||||||
bind:imageGenerationEnabled
|
bind:imageGenerationEnabled
|
||||||
bind:codeInterpreterEnabled
|
bind:codeInterpreterEnabled
|
||||||
bind:webSearchEnabled
|
bind:webSearchEnabled
|
||||||
|
bind:thinkingEnabled
|
||||||
bind:atSelectedModel
|
bind:atSelectedModel
|
||||||
toolServers={$toolServers}
|
toolServers={$toolServers}
|
||||||
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
||||||
@ -2118,6 +2128,7 @@
|
|||||||
bind:imageGenerationEnabled
|
bind:imageGenerationEnabled
|
||||||
bind:codeInterpreterEnabled
|
bind:codeInterpreterEnabled
|
||||||
bind:webSearchEnabled
|
bind:webSearchEnabled
|
||||||
|
bind:thinkingEnabled
|
||||||
bind:atSelectedModel
|
bind:atSelectedModel
|
||||||
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
transparentBackground={$settings?.backgroundImageUrl ?? false}
|
||||||
toolServers={$toolServers}
|
toolServers={$toolServers}
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
import XMark from '../icons/XMark.svelte';
|
import XMark from '../icons/XMark.svelte';
|
||||||
import Headphone from '../icons/Headphone.svelte';
|
import Headphone from '../icons/Headphone.svelte';
|
||||||
import GlobeAlt from '../icons/GlobeAlt.svelte';
|
import GlobeAlt from '../icons/GlobeAlt.svelte';
|
||||||
|
import Thinking from "../icons/Thinking.svelte";
|
||||||
import PhotoSolid from '../icons/PhotoSolid.svelte';
|
import PhotoSolid from '../icons/PhotoSolid.svelte';
|
||||||
import Photo from '../icons/Photo.svelte';
|
import Photo from '../icons/Photo.svelte';
|
||||||
import CommandLine from '../icons/CommandLine.svelte';
|
import CommandLine from '../icons/CommandLine.svelte';
|
||||||
@ -83,6 +84,7 @@
|
|||||||
export let imageGenerationEnabled = false;
|
export let imageGenerationEnabled = false;
|
||||||
export let webSearchEnabled = false;
|
export let webSearchEnabled = false;
|
||||||
export let codeInterpreterEnabled = false;
|
export let codeInterpreterEnabled = false;
|
||||||
|
export let thinkingEnabled = false;
|
||||||
|
|
||||||
$: onChange({
|
$: onChange({
|
||||||
prompt,
|
prompt,
|
||||||
@ -90,7 +92,8 @@
|
|||||||
selectedToolIds,
|
selectedToolIds,
|
||||||
imageGenerationEnabled,
|
imageGenerationEnabled,
|
||||||
webSearchEnabled,
|
webSearchEnabled,
|
||||||
codeInterpreterEnabled
|
codeInterpreterEnabled,
|
||||||
|
thinkingEnabled
|
||||||
});
|
});
|
||||||
|
|
||||||
let showTools = false;
|
let showTools = false;
|
||||||
@ -117,6 +120,10 @@
|
|||||||
(model) => $models.find((m) => m.id === model)?.info?.meta?.capabilities?.vision ?? true
|
(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 scrollToBottom = () => {
|
||||||
const element = document.getElementById('messages-container');
|
const element = document.getElementById('messages-container');
|
||||||
element.scrollTo({
|
element.scrollTo({
|
||||||
@ -773,6 +780,7 @@
|
|||||||
selectedToolIds = [];
|
selectedToolIds = [];
|
||||||
webSearchEnabled = false;
|
webSearchEnabled = false;
|
||||||
imageGenerationEnabled = false;
|
imageGenerationEnabled = false;
|
||||||
|
thinkingEnabled = false;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:paste={async (e) => {
|
on:paste={async (e) => {
|
||||||
@ -980,6 +988,7 @@
|
|||||||
selectedToolIds = [];
|
selectedToolIds = [];
|
||||||
webSearchEnabled = false;
|
webSearchEnabled = false;
|
||||||
imageGenerationEnabled = false;
|
imageGenerationEnabled = false;
|
||||||
|
thinkingEnabled = false;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
rows="1"
|
rows="1"
|
||||||
@ -1127,6 +1136,24 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $_user}
|
{#if $_user}
|
||||||
|
{#if selectedModels.length > 0 && selectedModels.some((model) => switchThinkingCapableModels.includes(model))}
|
||||||
|
<Tooltip content={$i18n.t('Thinking')} placement="top">
|
||||||
|
<button
|
||||||
|
on:click|preventDefault={() => (thinkingEnabled = !thinkingEnabled)}
|
||||||
|
type="button"
|
||||||
|
class="px-1.5 @xl:px-2.5 py-1.5 flex gap-1.5 items-center text-sm rounded-full font-medium transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden border {thinkingEnabled
|
||||||
|
? 'bg-blue-100 dark:bg-blue-500/20 border-blue-400/20 text-blue-500 dark:text-blue-400'
|
||||||
|
: 'bg-transparent border-transparent text-gray-600 dark:text-gray-300 border-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800'}"
|
||||||
|
>
|
||||||
|
<Thinking className="size-5" strokeWidth="1.75" />
|
||||||
|
<span
|
||||||
|
class="hidden @xl:block whitespace-nowrap overflow-hidden text-ellipsis translate-y-[0.5px]"
|
||||||
|
>{$i18n.t('Thinking')}</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if $config?.features?.enable_web_search && ($_user.role === 'admin' || $_user?.permissions?.features?.web_search)}
|
{#if $config?.features?.enable_web_search && ($_user.role === 'admin' || $_user?.permissions?.features?.web_search)}
|
||||||
<Tooltip content={$i18n.t('Search the internet')} placement="top">
|
<Tooltip content={$i18n.t('Search the internet')} placement="top">
|
||||||
<button
|
<button
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
export let imageGenerationEnabled = false;
|
export let imageGenerationEnabled = false;
|
||||||
export let codeInterpreterEnabled = false;
|
export let codeInterpreterEnabled = false;
|
||||||
export let webSearchEnabled = false;
|
export let webSearchEnabled = false;
|
||||||
|
export let thinkingEnabled = false;
|
||||||
|
|
||||||
export let toolServers = [];
|
export let toolServers = [];
|
||||||
|
|
||||||
@ -195,6 +196,7 @@
|
|||||||
bind:imageGenerationEnabled
|
bind:imageGenerationEnabled
|
||||||
bind:codeInterpreterEnabled
|
bind:codeInterpreterEnabled
|
||||||
bind:webSearchEnabled
|
bind:webSearchEnabled
|
||||||
|
bind:thinkingEnabled
|
||||||
bind:atSelectedModel
|
bind:atSelectedModel
|
||||||
{toolServers}
|
{toolServers}
|
||||||
{transparentBackground}
|
{transparentBackground}
|
||||||
|
19
src/lib/components/icons/Thinking.svelte
Normal file
19
src/lib/components/icons/Thinking.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let className = 'w-4 h-4';
|
||||||
|
export let strokeWidth = '1.5';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width={strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M12 18v-5.25m0 0a6.01 6.01 0 0 0 1.5-.189m-1.5.189a6.01 6.01 0 0 1-1.5-.189m3.75 7.478a12.06 12.06 0 0 1-4.5 0m3.75 2.383a14.406 14.406 0 0 1-3 0M14.25 18v-.192c0-.983.658-1.823 1.508-2.316a7.5 7.5 0 1 0-7.517 0c.85.493 1.509 1.333 1.509 2.316V18"
|
||||||
|
/>
|
||||||
|
</svg>
|
@ -11,13 +11,15 @@
|
|||||||
usage: $i18n.t(
|
usage: $i18n.t(
|
||||||
'Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.'
|
'Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.'
|
||||||
),
|
),
|
||||||
citations: $i18n.t('Displays citations in the response')
|
citations: $i18n.t('Displays citations in the response'),
|
||||||
|
switch_thinking: $i18n.t('Sends `enable_thinking: true` in the request. \nSupported toggle providers will return thinking content')
|
||||||
};
|
};
|
||||||
|
|
||||||
export let capabilities: {
|
export let capabilities: {
|
||||||
vision?: boolean;
|
vision?: boolean;
|
||||||
usage?: boolean;
|
usage?: boolean;
|
||||||
citations?: boolean;
|
citations?: boolean;
|
||||||
|
switch_thinking?: boolean;
|
||||||
} = {};
|
} = {};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -78,7 +78,8 @@
|
|||||||
let capabilities = {
|
let capabilities = {
|
||||||
vision: true,
|
vision: true,
|
||||||
usage: undefined,
|
usage: undefined,
|
||||||
citations: true
|
citations: true,
|
||||||
|
switch_thinking: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let knowledge = [];
|
let knowledge = [];
|
||||||
|
@ -1031,6 +1031,7 @@
|
|||||||
"Send a Message": "输入消息",
|
"Send a Message": "输入消息",
|
||||||
"Send message": "发送消息",
|
"Send message": "发送消息",
|
||||||
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "在请求中发送 `stream_options: { include_usage: true }`。设置后,支持的供应商会在响应中返回 Token 使用信息。",
|
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "在请求中发送 `stream_options: { include_usage: true }`。设置后,支持的供应商会在响应中返回 Token 使用信息。",
|
||||||
|
"Sends `enable_thinking: true` in the request. \nSupported toggle providers will return thinking content": "在请求中发送 `enable_thinking: true`。设置后,支持的供应商会返回深度思考的能力",
|
||||||
"September": "九月",
|
"September": "九月",
|
||||||
"SerpApi API Key": "SerpApi API 密钥",
|
"SerpApi API Key": "SerpApi API 密钥",
|
||||||
"SerpApi Engine": "SerpApi 引擎",
|
"SerpApi Engine": "SerpApi 引擎",
|
||||||
@ -1134,6 +1135,7 @@
|
|||||||
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分值应介于 0.0(0%)和 1.0(100%)之间。",
|
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分值应介于 0.0(0%)和 1.0(100%)之间。",
|
||||||
"The temperature of the model. Increasing the temperature will make the model answer more creatively.": "模型的温度。增加温度将使模型的回答更有创意。",
|
"The temperature of the model. Increasing the temperature will make the model answer more creatively.": "模型的温度。增加温度将使模型的回答更有创意。",
|
||||||
"Theme": "主题",
|
"Theme": "主题",
|
||||||
|
"Thinking...": "深度思考",
|
||||||
"Thinking...": "正在思考...",
|
"Thinking...": "正在思考...",
|
||||||
"This action cannot be undone. Do you wish to continue?": "此操作无法撤销。是否确认继续?",
|
"This action cannot be undone. Do you wish to continue?": "此操作无法撤销。是否确认继续?",
|
||||||
"This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "此频道创建于{{createdAt}},这里是{{channelName}}频道的开始",
|
"This channel was created on {{createdAt}}. This is the very beginning of the {{channelName}} channel.": "此频道创建于{{createdAt}},这里是{{channelName}}频道的开始",
|
||||||
|
Loading…
Reference in New Issue
Block a user