diff --git a/src/renderer/src/components/ModelTags.tsx b/src/renderer/src/components/ModelTags.tsx index e798b9be..c4a25ab4 100644 --- a/src/renderer/src/components/ModelTags.tsx +++ b/src/renderer/src/components/ModelTags.tsx @@ -1,4 +1,4 @@ -import { isEmbeddingModel, isVisionModel, isWebSearchModel } from '@renderer/config/models' +import { isEmbeddingModel, isReasoningModel, isVisionModel, isWebSearchModel } from '@renderer/config/models' import { Model } from '@renderer/types' import { isFreeModel } from '@renderer/utils' import { Tag } from 'antd' @@ -29,6 +29,11 @@ const ModelTags: FC = ({ model, showFree = true }) => { {t('models.embedding')} )} + {isReasoningModel(model) && ( + + {t('models.reasoning')} + + )} ) } diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 7d9f54b8..663c106a 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -156,6 +156,8 @@ export const VISION_REGEX = new RegExp( ) export const TEXT_TO_IMAGE_REGEX = /flux|diffusion|stabilityai|sd-|dall|cogview|janus/i +export const REASONING_REGEX = /^(o\d+(?:-[\w-]+)?|.*\breasoner\b.*|.*-[rR]\d+.*)$/i + export const EMBEDDING_REGEX = /(?:^text-|embed|rerank|davinci|babbage|bge-|e5-|LLM2Vec|retrieval|uae-|gte-|jina)/i export const NOT_SUPPORTED_REGEX = /(?:^tts|rerank|whisper|speech)/i @@ -1127,6 +1129,14 @@ export function isVisionModel(model: Model): boolean { return VISION_REGEX.test(model.id) || model.type?.includes('vision') || false } +export function isReasoningModel(model: Model): boolean { + if (!model) { + return false + } + + return REASONING_REGEX.test(model.id) || model.type?.includes('reasoning') || false +} + export function isSupportedModel(model: OpenAI.Models.Model): boolean { if (!model) { return false diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 7e75aa03..cad2d5fb 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -40,6 +40,11 @@ "save.success": "Saved successfully", "save.title": "Save to agent", "search": "Search assistants...", + "settings.reasoning_effort": "Reasoning effort", + "settings.reasoning_effort.tip": "Only supports reasoning models", + "settings.reasoning_effort.low": "low", + "settings.reasoning_effort.medium": "medium", + "settings.reasoning_effort.high": "high", "settings.auto_reset_model": "Auto Reset Model", "settings.auto_reset_model.tip": "Automatically reset the model when a new topic is created.", "settings.default_model": "Default Model", @@ -640,12 +645,14 @@ "select": "Select Model Types", "text": "Text", "vision": "Vision", - "embedding": "Embedding" + "embedding": "Embedding", + "reasoning": "Reasoning" }, "all": "All", "vision": "Vision", "websearch": "WebSearch", "free": "Free", + "reasoning": "Reasoning", "embedding": "Embedding", "embedding_model": "Embedding Model", "embedding_model_tooltip": "Add in Settings->Model Provider->Manage", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 96af4735..ee0fcaba 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -625,12 +625,14 @@ "select": "モデルタイプを選択", "text": "テキスト", "vision": "画像", - "embedding": "埋め込み" + "embedding": "埋め込み", + "reasoning": "推論" }, "all": "すべて", "vision": "画像モデル", "websearch": "ウェブ検索モデル", "free": "無料モデル", + "reasoning": "推論モデル", "embedding": "埋め込みモデル", "embedding_model": "埋め込みモデル", "embedding_model_tooltip": "設定->モデルサービス->管理で追加", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 08a3e945..9bd79e56 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -637,12 +637,14 @@ "select": "Выберите тип модели", "text": "Текст", "vision": "Изображение", - "embedding": "Встраиваемые" + "embedding": "Встраиваемые", + "reasoning": "Рассуждение" }, "all": "Все", "vision": "Визуальные модели", "websearch": "Веб-поисковые модели", "free": "Бесплатные модели", + "reasoning": "Модели рассуждения", "embedding": "Встраиваемые модели", "embedding_model": "Встраиваемые модели", "embedding_model_tooltip": "Добавьте в настройки->модель сервиса->управление", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index e6d89306..b3e74af9 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -40,6 +40,11 @@ "save.success": "保存成功", "save.title": "保存到智能体", "search": "搜索助手", + "settings.reasoning_effort": "思维链长度", + "settings.reasoning_effort.tip": "该设置仅支持推理模型", + "settings.reasoning_effort.low": "短", + "settings.reasoning_effort.medium": "中", + "settings.reasoning_effort.high": "长", "settings.auto_reset_model": "自动重置模型", "settings.auto_reset_model.tip": "创建新话题时自动重置模型", "settings.default_model": "默认模型", @@ -627,12 +632,14 @@ "select": "选择模型类型", "text": "文本", "vision": "图像", - "embedding": "嵌入" + "embedding": "嵌入", + "reasoning": "推理" }, "all": "全部", "vision": "视觉模型", "websearch": "联网模型", "free": "免费模型", + "reasoning": "推理模型", "embedding": "嵌入模型", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 73ce63f9..c0e5e9f4 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -40,6 +40,11 @@ "save.success": "儲存成功", "save.title": "儲存到智能體", "search": "搜尋助手...", + "settings.reasoning_effort": "思維鏈長度", + "settings.reasoning_effort.tip": "該設置僅支持推理模型", + "settings.reasoning_effort.low": "短", + "settings.reasoning_effort.medium": "中", + "settings.reasoning_effort.high": "長", "settings.auto_reset_model": "自動重置模型", "settings.auto_reset_model.tip": "每次新的話題時自動重置模型", "settings.default_model": "預設模型", @@ -626,12 +631,14 @@ "select": "選擇模型類型", "text": "文字", "vision": "圖像", - "embedding": "嵌入" + "embedding": "嵌入", + "reasoning": "推理" }, "all": "全部", "vision": "視覺模型", "websearch": "網路搜索模型", "free": "免費模型", + "reasoning": "推理模型", "embedding": "嵌入模型", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", diff --git a/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx b/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx index d3fe3f89..998c7eaa 100644 --- a/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx +++ b/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx @@ -5,7 +5,7 @@ import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup' import { DEFAULT_CONTEXTCOUNT, DEFAULT_TEMPERATURE } from '@renderer/config/constant' import { SettingRow } from '@renderer/pages/settings' import { Assistant, AssistantSettingCustomParameters, AssistantSettings } from '@renderer/types' -import { Button, Col, Divider, Input, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd' +import { Button, Col, Divider, Input, InputNumber, Radio, Row, Select, Slider, Switch, Tooltip } from 'antd' import { isNull } from 'lodash' import { FC, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -23,6 +23,7 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA const [enableMaxTokens, setEnableMaxTokens] = useState(assistant?.settings?.enableMaxTokens ?? false) const [maxTokens, setMaxTokens] = useState(assistant?.settings?.maxTokens ?? 0) const [autoResetModel, setAutoResetModel] = useState(assistant?.settings?.autoResetModel ?? false) + const [reasoningEffort, setReasoningEffort] = useState(assistant?.settings?.reasoning_effort ?? 'medium') const [streamOutput, setStreamOutput] = useState(assistant?.settings?.streamOutput ?? true) const [defaultModel, setDefaultModel] = useState(assistant?.defaultModel) const [topP, setTopP] = useState(assistant?.settings?.topP ?? 1) @@ -43,6 +44,10 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA } } + const onReasoningEffortChange = (value) => { + updateAssistantSettings({ reasoning_effort: value }) + } + const onContextCountChange = (value) => { if (!isNaN(value as number)) { updateAssistantSettings({ contextCount: value }) @@ -384,6 +389,26 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA /> + + + { + setReasoningEffort(e.target.value) + onReasoningEffortChange(e.target.value) + }}> + {t('assistants.settings.reasoning_effort.low')} + {t('assistants.settings.reasoning_effort.medium')} + {t('assistants.settings.reasoning_effort.high')} + + +