diff --git a/web/src/components/floating-chat-widget.tsx b/web/src/components/floating-chat-widget.tsx index f95920a6ed..c1cedb8a4c 100644 --- a/web/src/components/floating-chat-widget.tsx +++ b/web/src/components/floating-chat-widget.tsx @@ -438,7 +438,7 @@ const FloatingChatWidget = () => { // Wait for state to update, then send setTimeout(() => { - handlePressEnter({ enableThinking: false, enableInternet: false }); + handlePressEnter({ enableThinking: '0', enableInternet: false }); // Clear our local input after sending setInputValue(''); }, 50); diff --git a/web/src/components/message-input/next.tsx b/web/src/components/message-input/next.tsx index dee8c72c26..edc623dc94 100644 --- a/web/src/components/message-input/next.tsx +++ b/web/src/components/message-input/next.tsx @@ -14,24 +14,16 @@ import { } from '@/components/file-upload'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; -import { cn } from '@/lib/utils'; -import { t } from 'i18next'; -import { - Atom, - CircleStop, - Globe, - Paperclip, - Send, - Upload, - X, -} from 'lucide-react'; +import { CircleStop, Globe, Paperclip, Send, Upload, X } from 'lucide-react'; import * as React from 'react'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; +import { SelectWithSearch } from '../originui/select-with-search'; import { AudioButton } from '../ui/audio-button'; export type NextMessageInputOnPressEnterParameter = { - enableThinking: boolean; + enableThinking: string; enableInternet: boolean; }; @@ -75,16 +67,27 @@ export function NextMessageInput({ showReasoning = false, showInternet = false, }: NextMessageInputProps) { + const { t } = useTranslation(); const [files, setFiles] = React.useState([]); const [audioInputValue, setAudioInputValue] = React.useState( null, ); - const [enableThinking, setEnableThinking] = useState(false); + const [enableThinking, setEnableThinking] = useState('0'); const [enableInternet, setEnableInternet] = useState(false); - const handleThinkingToggle = useCallback(() => { - setEnableThinking((prev) => !prev); + const thinkingOptions = useMemo( + () => [ + { label: t('chat.thinkingLevelUltra'), value: '3' }, + { label: t('chat.thinkingLevelHigh'), value: '2' }, + { label: t('chat.thinkingLevelMedium'), value: '1' }, + { label: t('chat.thinkingLevelLow'), value: '0' }, + ], + [t], + ); + + const handleThinkingChange = useCallback((value: string) => { + setEnableThinking(value); }, []); const handleInternetToggle = useCallback(() => { @@ -245,19 +248,13 @@ export function NextMessageInput({ )} {showReasoning && ( - + )} {showInternet && ( diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 19e9ee0705..f14e8077d7 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1118,6 +1118,10 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s thinkingDefault: 'System default', thinkingEnabled: 'Enabled', thinkingDisabled: 'Disabled', + thinkingLevelLow: 'Low', + thinkingLevelMedium: 'Medium', + thinkingLevelHigh: 'High', + thinkingLevelUltra: 'Ultra', thinkingTip: 'Only controls thinking mode for official Qwen, Kimi, and GLM model providers. System default disables Qwen thinking to avoid long-running tasks.', quote: 'Show quote', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index e284a42c80..5d3212b90b 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1017,6 +1017,10 @@ NER:使用 spaCy NER 和基于规则的关键词提取来抽取实体和关系 thinkingDefault: '系统默认', thinkingEnabled: '开启', thinkingDisabled: '关闭', + thinkingLevelLow: '轻度', + thinkingLevelMedium: '中', + thinkingLevelHigh: '高', + thinkingLevelUltra: '极高', thinkingTip: '仅控制官方模型提供商中的 Qwen、Kimi 和 GLM 模型思考模式。系统默认会关闭 Qwen 思考,以避免任务长时间运行。', quote: '显示引文', diff --git a/web/src/pages/next-chats/hooks/use-send-chat-message.ts b/web/src/pages/next-chats/hooks/use-send-chat-message.ts index 138964ffbc..f72e9e0ada 100644 --- a/web/src/pages/next-chats/hooks/use-send-chat-message.ts +++ b/web/src/pages/next-chats/hooks/use-send-chat-message.ts @@ -109,7 +109,7 @@ export const useSendMessage = (controller: AbortController) => { message, ], pass_all_history_messages: true, - reasoning: enableThinking, + reasoning: Number(enableThinking), internet: enableInternet, }, controller, diff --git a/web/src/pages/next-chats/hooks/use-send-shared-message.ts b/web/src/pages/next-chats/hooks/use-send-shared-message.ts index 57017896cd..ecebbff277 100644 --- a/web/src/pages/next-chats/hooks/use-send-shared-message.ts +++ b/web/src/pages/next-chats/hooks/use-send-shared-message.ts @@ -67,7 +67,7 @@ export const useSendSharedMessage = () => { async ( message: Message, id?: string, - enableThinking?: boolean, + enableThinking?: string, enableInternet?: boolean, ) => { const res = await send(completionUrl, { @@ -75,7 +75,7 @@ export const useSendSharedMessage = () => { quote: true, question: message.content, session_id: get(derivedMessages, '0.session_id'), - reasoning: enableThinking, + reasoning: Number(enableThinking), internet: enableInternet, ...(chatInfo?.llm_id ? { model_name: chatInfo.llm_id } : {}), }); @@ -100,7 +100,7 @@ export const useSendSharedMessage = () => { const handleSendMessage = useCallback( async ( message: Message, - enableThinking?: boolean, + enableThinking?: string, enableInternet?: boolean, ) => { sendMessage(message, undefined, enableThinking, enableInternet); diff --git a/web/src/pages/next-chats/hooks/use-send-single-message.ts b/web/src/pages/next-chats/hooks/use-send-single-message.ts index e82777f206..abc3442401 100644 --- a/web/src/pages/next-chats/hooks/use-send-single-message.ts +++ b/web/src/pages/next-chats/hooks/use-send-single-message.ts @@ -78,7 +78,7 @@ export function useSendSingleMessage({ : (derivedMessages ?? [])), message, ], - reasoning: enableThinking, + reasoning: Number(enableThinking), internet: enableInternet, ...params, pass_all_history_messages: true,