mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-19 14:41:24 +08:00
feat: add tool use mode setting to default assistant settings (#11943)
* feat: add tool use mode setting to default assistant settings - Add toolUseMode selector (prompt/function) to DefaultAssistantSettings - Add dividers between model parameter sections for better UI - Reduce slider margins for compact layout - Add migration (v185) to reset toolUseMode to 'function' for existing users 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: reset toolUseMode for all assistants during migration - Update migration logic to reset toolUseMode to 'function' for all assistants with a 'prompt' setting. - Ensure compatibility with function calling models by checking model type before resetting. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bfeef7ef91
commit
782f8496e0
@ -2,13 +2,14 @@ import { CloseCircleFilled, QuestionCircleOutlined } from '@ant-design/icons'
|
||||
import EmojiPicker from '@renderer/components/EmojiPicker'
|
||||
import { ResetIcon } from '@renderer/components/Icons'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import Selector from '@renderer/components/Selector'
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { DEFAULT_CONTEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useDefaultAssistant } from '@renderer/hooks/useAssistant'
|
||||
import type { AssistantSettings as AssistantSettingsType } from '@renderer/types'
|
||||
import { getLeadingEmoji, modalConfirm } from '@renderer/utils'
|
||||
import { Button, Col, Flex, Input, InputNumber, Modal, Popover, Row, Slider, Switch, Tooltip } from 'antd'
|
||||
import { Button, Col, Divider, Flex, Input, InputNumber, Modal, Popover, Row, Slider, Switch, Tooltip } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import type { Dispatch, FC, SetStateAction } from 'react'
|
||||
import { useState } from 'react'
|
||||
@ -26,6 +27,9 @@ const AssistantSettings: FC = () => {
|
||||
const [maxTokens, setMaxTokens] = useState(defaultAssistant?.settings?.maxTokens ?? 0)
|
||||
const [topP, setTopP] = useState(defaultAssistant.settings?.topP ?? 1)
|
||||
const [enableTopP, setEnableTopP] = useState(defaultAssistant.settings?.enableTopP ?? false)
|
||||
const [toolUseMode, setToolUseMode] = useState<AssistantSettingsType['toolUseMode']>(
|
||||
defaultAssistant.settings?.toolUseMode ?? 'function'
|
||||
)
|
||||
const [emoji, setEmoji] = useState(defaultAssistant.emoji || getLeadingEmoji(defaultAssistant.name) || '')
|
||||
const [name, setName] = useState(
|
||||
defaultAssistant.name.replace(getLeadingEmoji(defaultAssistant.name) || '', '').trim()
|
||||
@ -46,7 +50,8 @@ const AssistantSettings: FC = () => {
|
||||
maxTokens: settings.maxTokens ?? maxTokens,
|
||||
streamOutput: settings.streamOutput ?? true,
|
||||
topP: settings.topP ?? topP,
|
||||
enableTopP: settings.enableTopP ?? enableTopP
|
||||
enableTopP: settings.enableTopP ?? enableTopP,
|
||||
toolUseMode: settings.toolUseMode ?? toolUseMode
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -73,6 +78,7 @@ const AssistantSettings: FC = () => {
|
||||
setMaxTokens(0)
|
||||
setTopP(1)
|
||||
setEnableTopP(false)
|
||||
setToolUseMode('function')
|
||||
updateDefaultAssistant({
|
||||
...defaultAssistant,
|
||||
settings: {
|
||||
@ -84,7 +90,8 @@ const AssistantSettings: FC = () => {
|
||||
maxTokens: DEFAULT_MAX_TOKENS,
|
||||
streamOutput: true,
|
||||
topP: 1,
|
||||
enableTopP: false
|
||||
enableTopP: false,
|
||||
toolUseMode: 'function'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -107,10 +114,9 @@ const AssistantSettings: FC = () => {
|
||||
|
||||
return (
|
||||
<SettingContainer
|
||||
style={{ height: 'auto', background: 'transparent', padding: `0 0 12px 0`, gap: 12 }}
|
||||
style={{ height: 'auto', background: 'transparent', padding: `0 0 12px 0`, gap: 10 }}
|
||||
theme={theme}>
|
||||
<SettingSubtitle style={{ marginTop: 0 }}>{t('common.name')}</SettingSubtitle>
|
||||
<HStack gap={8} alignItems="center">
|
||||
<HStack gap={8} alignItems="center" mt={10}>
|
||||
<Popover content={<EmojiPicker onEmojiClick={handleEmojiSelect} />} arrow trigger="click">
|
||||
<EmojiButtonWrapper>
|
||||
<Button style={{ fontSize: 20, padding: '4px', minWidth: '30px', height: '30px' }}>{emoji}</Button>
|
||||
@ -161,6 +167,7 @@ const AssistantSettings: FC = () => {
|
||||
<Button type="text" onClick={onReset} icon={<ResetIcon size={16} />} />
|
||||
</Tooltip>
|
||||
</SettingSubtitle>
|
||||
<Divider style={{ margin: '2px 0' }} />
|
||||
<SettingRow>
|
||||
<HStack alignItems="center">
|
||||
<Label>{t('chat.settings.temperature.label')}</Label>
|
||||
@ -178,7 +185,7 @@ const AssistantSettings: FC = () => {
|
||||
/>
|
||||
</SettingRow>
|
||||
{enableTemperature && (
|
||||
<Row align="middle" gutter={12}>
|
||||
<Row align="middle" gutter={12} style={{ marginTop: -5, marginBottom: -10 }}>
|
||||
<Col span={20}>
|
||||
<Slider
|
||||
min={0}
|
||||
@ -202,6 +209,7 @@ const AssistantSettings: FC = () => {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Divider style={{ margin: '2px 0' }} />
|
||||
<SettingRow>
|
||||
<HStack alignItems="center">
|
||||
<Label>{t('chat.settings.top_p.label')}</Label>
|
||||
@ -219,7 +227,7 @@ const AssistantSettings: FC = () => {
|
||||
/>
|
||||
</SettingRow>
|
||||
{enableTopP && (
|
||||
<Row align="middle" gutter={12}>
|
||||
<Row align="middle" gutter={12} style={{ marginTop: -5, marginBottom: -10 }}>
|
||||
<Col span={20}>
|
||||
<Slider
|
||||
min={0}
|
||||
@ -236,13 +244,14 @@ const AssistantSettings: FC = () => {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Divider style={{ margin: '2px 0' }} />
|
||||
<Row align="middle">
|
||||
<Label>{t('chat.settings.context_count.label')}</Label>
|
||||
<Tooltip title={t('chat.settings.context_count.tip')}>
|
||||
<QuestionIcon />
|
||||
</Tooltip>
|
||||
</Row>
|
||||
<Row align="middle" gutter={20}>
|
||||
<Row align="middle" gutter={20} style={{ marginTop: -5, marginBottom: -10 }}>
|
||||
<Col span={19}>
|
||||
<Slider
|
||||
min={0}
|
||||
@ -265,6 +274,7 @@ const AssistantSettings: FC = () => {
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Divider style={{ margin: '2px 0' }} />
|
||||
<Flex justify="space-between" align="center">
|
||||
<HStack alignItems="center">
|
||||
<Label>{t('chat.settings.max_tokens.label')}</Label>
|
||||
@ -308,6 +318,22 @@ const AssistantSettings: FC = () => {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Divider style={{ margin: '2px 0' }} />
|
||||
<SettingRow>
|
||||
<Label>{t('assistants.settings.tool_use_mode.label')}</Label>
|
||||
<Selector
|
||||
value={toolUseMode}
|
||||
options={[
|
||||
{ label: t('assistants.settings.tool_use_mode.prompt'), value: 'prompt' },
|
||||
{ label: t('assistants.settings.tool_use_mode.function'), value: 'function' }
|
||||
]}
|
||||
onChange={(value) => {
|
||||
setToolUseMode(value)
|
||||
onUpdateAssistantSettings({ toolUseMode: value })
|
||||
}}
|
||||
size={14}
|
||||
/>
|
||||
</SettingRow>
|
||||
</SettingContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ const persistedReducer = persistReducer(
|
||||
{
|
||||
key: 'cherry-studio',
|
||||
storage,
|
||||
version: 184,
|
||||
version: 185,
|
||||
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs', 'toolPermissions'],
|
||||
migrate
|
||||
},
|
||||
|
||||
@ -3017,6 +3017,27 @@ const migrateConfig = {
|
||||
logger.error('migrate 184 error', error as Error)
|
||||
return state
|
||||
}
|
||||
},
|
||||
'185': (state: RootState) => {
|
||||
try {
|
||||
// Reset toolUseMode to function for default assistant
|
||||
if (state.assistants.defaultAssistant.settings?.toolUseMode) {
|
||||
state.assistants.defaultAssistant.settings.toolUseMode = 'function'
|
||||
}
|
||||
// Reset toolUseMode to function for assistants
|
||||
state.assistants.assistants.forEach((assistant) => {
|
||||
if (assistant.settings?.toolUseMode === 'prompt') {
|
||||
if (assistant.model && isFunctionCallingModel(assistant.model)) {
|
||||
assistant.settings.toolUseMode = 'function'
|
||||
}
|
||||
}
|
||||
})
|
||||
logger.info('migrate 185 success')
|
||||
return state
|
||||
} catch (error) {
|
||||
logger.error('migrate 185 error', error as Error)
|
||||
return state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user