diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 7aa0d49c8..e5c3dca08 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -586,7 +586,15 @@ "embedding": "Embedding", "embedding_model": "Embedding Model", "embedding_model_tooltip": "Add in Settings->Model Provider->Manage", - "dimensions": "Dimensions {{dimensions}}" + "dimensions": "Dimensions {{dimensions}}", + "custom_parameters": "Custom Parameters", + "add_parameter": "Add Parameter", + "parameter_name": "Parameter Name", + "parameter_type": { + "string": "Text", + "number": "Number", + "boolean": "Boolean" + } }, "prompts": { "summarize": "You are an assistant who is good at conversation. You need to summarize the user's conversation into a title of 10 characters or less, ensuring it matches the user's primary language without using punctuation or other special symbols." diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 796ffe74a..82f27549f 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -568,7 +568,16 @@ "free": "無料モデル", "embedding": "埋め込みモデル", "embedding_model": "埋め込みモデル", - "embedding_model_tooltip": "設定->モデルサービス->管理で追加" + "embedding_model_tooltip": "設定->モデルサービス->管理で追加", + "dimensions": "{{dimensions}} 次元", + "custom_parameters": "カスタムパラメータ", + "add_parameter": "パラメータを追加", + "parameter_name": "パラメータ名", + "parameter_type": { + "string": "テキスト", + "number": "数値", + "boolean": "真偽値" + } }, "prompts": { "summarize": "あなたは会話を得意とするアシスタントです。ユーザーの会話を10文字以内のタイトルに要約し、ユーザーの主言語と一致していることを確認してください。句読点や特殊記号は使用しないでください。" diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index ab405be79..636039733 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -586,7 +586,15 @@ "embedding": "Встраиваемые модели", "embedding_model": "Встраиваемые модели", "embedding_model_tooltip": "Добавьте в настройки->модель сервиса->управление", - "dimensions": "{{dimensions}} мер" + "dimensions": "{{dimensions}} мер", + "custom_parameters": "Пользовательские параметры", + "add_parameter": "Добавить параметр", + "parameter_name": "Имя параметра", + "parameter_type": { + "string": "Текст", + "number": "Число", + "boolean": "Логическое" + } }, "prompts": { "summarize": "Вы - эксперт в общении, который суммирует разговоры пользователя в 10-символьном заголовке, совпадающем с языком пользователя, без использования знаков препинания и других специальных символов" diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 67f19a7eb..8e2e8a807 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -575,7 +575,15 @@ "embedding": "嵌入模型", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", - "dimensions": "{{dimensions}} 维" + "dimensions": "{{dimensions}} 维", + "custom_parameters": "自定义参数", + "add_parameter": "添加参数", + "parameter_name": "参数名称", + "parameter_type": { + "string": "文本", + "number": "数字", + "boolean": "布尔值" + } }, "prompts": { "summarize": "你是一名擅长会话的助理,你需要将用户的会话总结为 10 个字以内的标题,标题语言与用户的首要语言一致,不要使用标点符号和其他特殊符号" diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index de74933da..b67dd122b 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -574,7 +574,15 @@ "embedding": "嵌入模型", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", - "dimensions": "{{dimensions}} 維" + "dimensions": "{{dimensions}} 維", + "custom_parameters": "自定義參數", + "add_parameter": "添加參數", + "parameter_name": "參數名稱", + "parameter_type": { + "string": "文字", + "number": "數字", + "boolean": "布林值" + } }, "prompts": { "summarize": "你是一名擅長會話的助理,你需要將用戶的會話總結為 10 個字以內的標題,標題語言與用戶的首要語言一致,不要使用標點符號和其他特殊符號" diff --git a/src/renderer/src/pages/home/Tabs/SettingsTab.tsx b/src/renderer/src/pages/home/Tabs/SettingsTab.tsx index 1654a0930..9f8f59fa1 100644 --- a/src/renderer/src/pages/home/Tabs/SettingsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/SettingsTab.tsx @@ -1,4 +1,4 @@ -import { CheckOutlined, QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons' +import { CheckOutlined, DeleteOutlined, PlusOutlined, QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons' import { HStack } from '@renderer/components/Layout' import Scrollbar from '@renderer/components/Scrollbar' import { @@ -29,7 +29,7 @@ import { setShowMessageDivider } from '@renderer/store/settings' import { Assistant, AssistantSettings, ThemeMode } from '@renderer/types' -import { Col, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd' +import { Button, Col, Input, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd' import { FC, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -102,7 +102,8 @@ const SettingsTab: FC = (props) => { maxTokens: DEFAULT_MAX_TOKENS, streamOutput: true, hideMessages: false, - autoResetModel: false + autoResetModel: false, + customParameters: [] } }) } @@ -202,6 +203,106 @@ const SettingsTab: FC = (props) => { /> + {assistant?.settings?.customParameters?.map((param, index) => ( + + + + { + const newParams = [...(assistant?.settings?.customParameters || [])] + newParams[index] = { ...param, name: e.target.value } + onUpdateAssistantSettings({ customParameters: newParams }) + }} + /> + + + + + + + + {param.type === 'boolean' ? ( + { + const newParams = [...(assistant?.settings?.customParameters || [])] + newParams[index] = { ...param, value: checked } + onUpdateAssistantSettings({ customParameters: newParams }) + }} + /> + ) : param.type === 'number' ? ( + { + const newParams = [...(assistant?.settings?.customParameters || [])] + newParams[index] = { ...param, value: value || 0 } + onUpdateAssistantSettings({ customParameters: newParams }) + }} + step={0.01} + /> + ) : ( + { + const newParams = [...(assistant?.settings?.customParameters || [])] + newParams[index] = { ...param, value: e.target.value } + onUpdateAssistantSettings({ customParameters: newParams }) + }} + /> + )} + + + {t('settings.messages.title')} @@ -418,4 +519,15 @@ export const SettingGroup = styled.div<{ theme?: ThemeMode }>` background: var(--color-group-background); ` +const ParameterCard = styled.div` + margin-bottom: 8px; + padding: 8px; + border: 1px solid var(--color-border); + border-radius: 6px; + background: var(--color-background); + &:last-child { + margin-bottom: 12px; + } +` + export default SettingsTab diff --git a/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx b/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx index 645564ca8..ee8c7bccc 100644 --- a/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx +++ b/src/renderer/src/pages/settings/AssistantSettings/AssistantModelSettings.tsx @@ -1,11 +1,11 @@ -import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons' +import { DeleteOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import { HStack } from '@renderer/components/Layout' import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup' import { DEFAULT_CONTEXTCOUNT, DEFAULT_TEMPERATURE } from '@renderer/config/constant' import { SettingRow } from '@renderer/pages/settings' import { Assistant, AssistantSettings } from '@renderer/types' -import { Button, Col, Divider, InputNumber, Row, Slider, Switch, Tooltip } from 'antd' +import { Button, Col, Divider, Input, InputNumber, Row, Select, Slider, Switch, Tooltip } from 'antd' import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -25,6 +25,13 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA const [streamOutput, setStreamOutput] = useState(assistant?.settings?.streamOutput ?? true) const [defaultModel, setDefaultModel] = useState(assistant?.defaultModel) const [topP, setTopP] = useState(assistant?.settings?.topP ?? 1) + const [customParameters, setCustomParameters] = useState< + Array<{ + name: string + value: string | number | boolean + type: 'string' | 'number' | 'boolean' + }> + >(assistant?.settings?.customParameters ?? []) const { t } = useTranslation() const onTemperatureChange = (value) => { @@ -51,6 +58,77 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA } } + const onAddCustomParameter = () => { + const newParam = { name: '', value: '', type: 'string' as const } + const newParams = [...customParameters, newParam] + setCustomParameters(newParams) + updateAssistantSettings({ customParameters: newParams }) + } + + const onUpdateCustomParameter = ( + index: number, + field: 'name' | 'value' | 'type', + value: string | number | boolean + ) => { + const newParams = [...customParameters] + if (field === 'type') { + let defaultValue: any = '' + switch (value) { + case 'number': + defaultValue = 0 + break + case 'boolean': + defaultValue = false + break + default: + defaultValue = '' + } + newParams[index] = { + ...newParams[index], + type: value as any, + value: defaultValue + } + } else { + newParams[index] = { ...newParams[index], [field]: value } + } + setCustomParameters(newParams) + updateAssistantSettings({ customParameters: newParams }) + } + + const renderParameterValueInput = (param: (typeof customParameters)[0], index: number) => { + switch (param.type) { + case 'number': + return ( + onUpdateCustomParameter(index, 'value', value || 0)} + step={0.01} + /> + ) + case 'boolean': + return ( + onUpdateCustomParameter(index, 'value', checked)} + /> + ) + default: + return ( + onUpdateCustomParameter(index, 'value', e.target.value)} + /> + ) + } + } + + const onDeleteCustomParameter = (index: number) => { + const newParams = customParameters.filter((_, i) => i !== index) + setCustomParameters(newParams) + updateAssistantSettings({ customParameters: newParams }) + } + const onReset = () => { setTemperature(DEFAULT_TEMPERATURE) setContextCount(DEFAULT_CONTEXTCOUNT) @@ -58,13 +136,15 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA setMaxTokens(0) setStreamOutput(true) setTopP(1) + setCustomParameters([]) updateAssistantSettings({ temperature: DEFAULT_TEMPERATURE, contextCount: DEFAULT_CONTEXTCOUNT, enableMaxTokens: false, maxTokens: 0, streamOutput: true, - topP: 1 + topP: 1, + customParameters: [] }) } @@ -249,6 +329,38 @@ const AssistantModelSettings: FC = ({ assistant, updateAssistant, updateA }} /> + + + + + + {customParameters.map((param, index) => ( + + + onUpdateCustomParameter(index, 'name', e.target.value)} + /> + + + + + {renderParameterValueInput(param, index)} + +