Revert "feat: remove model settings from settings tab"

This reverts commit a9aa5a8da001fe1715697001c083331a904aec0e.

# Conflicts:
#	src/renderer/src/pages/home/Tabs/Settings.tsx
This commit is contained in:
kangfenmao 2024-11-20 17:38:10 +08:00
parent c3414e9b6d
commit efa0f4cbdb
2 changed files with 365 additions and 178 deletions

View File

@ -1,6 +1,9 @@
import { CheckOutlined } from '@ant-design/icons' import { CheckOutlined, QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
import { DEFAULT_CONTEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
import { codeThemes } from '@renderer/context/SyntaxHighlighterProvider' import { codeThemes } from '@renderer/context/SyntaxHighlighterProvider'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
import { SettingDivider, SettingRow, SettingRowTitle, SettingSubtitle } from '@renderer/pages/settings' import { SettingDivider, SettingRow, SettingRowTitle, SettingSubtitle } from '@renderer/pages/settings'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
@ -19,14 +22,26 @@ import {
setShowMessageDivider, setShowMessageDivider,
setShowTopicTime setShowTopicTime
} from '@renderer/store/settings' } from '@renderer/store/settings'
import { Col, Row, Select, Slider, Switch } from 'antd' import { Assistant, AssistantSettings, ThemeMode } from '@renderer/types'
import { Col, Row, Select, Slider, Switch, Tooltip } from 'antd'
import { FC, useEffect, useState } from 'react' import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
const SettingsTab: FC = () => { interface Props {
assistant: Assistant
}
const SettingsTab: FC<Props> = (props) => {
const { assistant, updateAssistantSettings, updateAssistant } = useAssistant(props.assistant.id)
const { messageStyle, codeStyle, fontSize } = useSettings() const { messageStyle, codeStyle, fontSize } = useSettings()
const [temperature, setTemperature] = useState(assistant?.settings?.temperature ?? DEFAULT_TEMPERATURE)
const [contextCount, setContextCount] = useState(assistant?.settings?.contextCount ?? DEFAULT_CONTEXTCOUNT)
const [enableMaxTokens, setEnableMaxTokens] = useState(assistant?.settings?.enableMaxTokens ?? false)
const [maxTokens, setMaxTokens] = useState(assistant?.settings?.maxTokens ?? 0)
const [fontSizeValue, setFontSizeValue] = useState(fontSize) const [fontSizeValue, setFontSizeValue] = useState(fontSize)
const [streamOutput, setStreamOutput] = useState(assistant?.settings?.streamOutput ?? true)
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
@ -48,183 +63,336 @@ const SettingsTab: FC = () => {
setTopicPosition setTopicPosition
} = useSettings() } = useSettings()
const onUpdateAssistantSettings = (settings: Partial<AssistantSettings>) => {
updateAssistantSettings(settings)
}
const onTemperatureChange = (value) => {
if (!isNaN(value as number)) {
onUpdateAssistantSettings({ temperature: value })
}
}
const onContextCountChange = (value) => {
if (!isNaN(value as number)) {
onUpdateAssistantSettings({ contextCount: value })
}
}
const onMaxTokensChange = (value) => {
if (!isNaN(value as number)) {
onUpdateAssistantSettings({ maxTokens: value })
}
}
const onReset = () => {
setTemperature(DEFAULT_TEMPERATURE)
setContextCount(DEFAULT_CONTEXTCOUNT)
updateAssistant({
...assistant,
settings: {
...assistant.settings,
temperature: DEFAULT_TEMPERATURE,
contextCount: DEFAULT_CONTEXTCOUNT,
enableMaxTokens: false,
maxTokens: DEFAULT_MAX_TOKENS,
streamOutput: true,
hideMessages: false,
autoResetModel: false
}
})
}
useEffect(() => { useEffect(() => {
setFontSizeValue(fontSize) setTemperature(assistant?.settings?.temperature ?? DEFAULT_TEMPERATURE)
}, [fontSize]) setContextCount(assistant?.settings?.contextCount ?? DEFAULT_CONTEXTCOUNT)
setEnableMaxTokens(assistant?.settings?.enableMaxTokens ?? false)
setMaxTokens(assistant?.settings?.maxTokens ?? DEFAULT_MAX_TOKENS)
setStreamOutput(assistant?.settings?.streamOutput ?? true)
}, [assistant])
return ( return (
<Container> <Container>
<SettingSubtitle>{t('settings.messages.title')}</SettingSubtitle> <SettingGroup style={{ marginTop: 10 }}>
<SettingDivider /> <SettingSubtitle style={{ marginTop: 0 }}>
<SettingRow> {t('settings.messages.model.title')}{' '}
<SettingRowTitleSmall>{t('settings.messages.divider')}</SettingRowTitleSmall> <Tooltip title={t('chat.settings.reset')}>
<Switch <ReloadOutlined onClick={onReset} style={{ cursor: 'pointer', fontSize: 12, padding: '0 3px' }} />
size="small" </Tooltip>
checked={showMessageDivider} </SettingSubtitle>
onChange={(checked) => dispatch(setShowMessageDivider(checked))} <SettingDivider />
/> <Row align="middle">
</SettingRow> <Label>{t('chat.settings.temperature')}</Label>
<SettingDivider /> <Tooltip title={t('chat.settings.temperature.tip')}>
<SettingRow> <QuestionIcon />
<SettingRowTitleSmall>{t('settings.messages.use_serif_font')}</SettingRowTitleSmall> </Tooltip>
<Switch </Row>
size="small" <Row align="middle" gutter={10}>
checked={messageFont === 'serif'} <Col span={24}>
onChange={(checked) => dispatch(setMessageFont(checked ? 'serif' : 'system'))} <Slider
/> min={0}
</SettingRow> max={2}
<SettingDivider /> onChange={setTemperature}
<SettingRow> onChangeComplete={onTemperatureChange}
<SettingRowTitleSmall>{t('chat.settings.show_line_numbers')}</SettingRowTitleSmall> value={typeof temperature === 'number' ? temperature : 0}
<Switch step={0.1}
size="small" />
checked={codeShowLineNumbers} </Col>
onChange={(checked) => dispatch(setCodeShowLineNumbers(checked))} </Row>
/> <Row align="middle">
</SettingRow> <Label>{t('chat.settings.context_count')}</Label>
<SettingDivider /> <Tooltip title={t('chat.settings.context_count.tip')}>
<SettingRow> <QuestionIcon />
<SettingRowTitleSmall>{t('chat.settings.code_collapsible')}</SettingRowTitleSmall> </Tooltip>
<Switch size="small" checked={codeCollapsible} onChange={(checked) => dispatch(setCodeCollapsible(checked))} /> </Row>
</SettingRow> <Row align="middle" gutter={10}>
<SettingDivider /> <Col span={24}>
<SettingRow> <Slider
<SettingRowTitleSmall>{t('message.message.style')}</SettingRowTitleSmall> min={0}
<Select max={20}
value={messageStyle} onChange={setContextCount}
onChange={(value) => dispatch(setMessageStyle(value))} onChangeComplete={onContextCountChange}
style={{ width: 135 }} value={typeof contextCount === 'number' ? contextCount : 0}
size="small"> step={1}
<Select.Option value="plain">{t('message.message.style.plain')}</Select.Option> />
<Select.Option value="bubble">{t('message.message.style.bubble')}</Select.Option> </Col>
</Select> </Row>
</SettingRow> <SettingRow>
<SettingDivider /> <SettingRowTitleSmall>{t('model.stream_output')}</SettingRowTitleSmall>
<SettingRow> <Switch
<SettingRowTitleSmall>{t('message.message.code_style')}</SettingRowTitleSmall> size="small"
<Select checked={streamOutput}
value={codeStyle} onChange={(checked) => {
onChange={(value) => dispatch(setCodeStyle(value))} setStreamOutput(checked)
style={{ width: 135 }} onUpdateAssistantSettings({ streamOutput: checked })
size="small">
{codeThemes.map((theme) => (
<Select.Option key={theme} value={theme}>
{theme}
</Select.Option>
))}
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.math_engine')}</SettingRowTitleSmall>
<Select
value={mathEngine}
onChange={(value) => dispatch(setMathEngine(value))}
style={{ width: 135 }}
size="small">
<Select.Option value="KaTeX">KaTeX</Select.Option>
<Select.Option value="MathJax">MathJax</Select.Option>
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.font_size.title')}</SettingRowTitleSmall>
</SettingRow>
<Row align="middle" gutter={10}>
<Col span={24}>
<Slider
value={fontSizeValue}
onChange={(value) => setFontSizeValue(value)}
onChangeComplete={(value) => dispatch(setFontSize(value))}
min={12}
max={22}
step={1}
marks={{
12: <span style={{ fontSize: '12px' }}>A</span>,
14: <span style={{ fontSize: '14px' }}>{t('common.default')}</span>,
22: <span style={{ fontSize: '18px' }}>A</span>
}} }}
/> />
</Col> </SettingRow>
</Row> <SettingDivider />
<SettingSubtitle>{t('settings.messages.input.title')}</SettingSubtitle> <Row align="middle" justify="space-between">
<SettingDivider /> <HStack alignItems="center">
<SettingRow> <Label>{t('chat.settings.max_tokens')}</Label>
<SettingRowTitleSmall>{t('settings.messages.input.show_estimated_tokens')}</SettingRowTitleSmall> <Tooltip title={t('chat.settings.max_tokens.tip')}>
<Switch <QuestionIcon />
size="small" </Tooltip>
checked={showInputEstimatedTokens} </HStack>
onChange={(checked) => dispatch(setShowInputEstimatedTokens(checked))} <Switch
/> size="small"
</SettingRow> checked={enableMaxTokens}
<SettingDivider /> onChange={(enabled) => {
<SettingRow> setEnableMaxTokens(enabled)
<SettingRowTitleSmall>{t('settings.messages.input.paste_long_text_as_file')}</SettingRowTitleSmall> onUpdateAssistantSettings({ enableMaxTokens: enabled })
<Switch }}
size="small" />
checked={pasteLongTextAsFile} </Row>
onChange={(checked) => dispatch(setPasteLongTextAsFile(checked))} <Row align="middle" gutter={10}>
/> <Col span={24}>
</SettingRow> <Slider
<SettingDivider /> disabled={!enableMaxTokens}
<SettingRow> min={0}
<SettingRowTitleSmall>{t('settings.messages.markdown_rendering_input_message')}</SettingRowTitleSmall> max={32000}
<Switch onChange={setMaxTokens}
size="small" onChangeComplete={onMaxTokensChange}
checked={renderInputMessageAsMarkdown} value={typeof maxTokens === 'number' ? maxTokens : 0}
onChange={(checked) => dispatch(setRenderInputMessageAsMarkdown(checked))} step={100}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.input.send_shortcuts')}</SettingRowTitleSmall>
<Select
size="small"
value={sendMessageShortcut}
menuItemSelectedIcon={<CheckOutlined />}
options={[
{ value: 'Enter', label: 'Enter' },
{ value: 'Shift+Enter', label: `Shift + Enter` }
]}
onChange={(value) => setSendMessageShortcut(value)}
style={{ width: 135 }}
/>
</SettingRow>
<SettingDivider />
<SettingSubtitle>{t('settings.display.title')}</SettingSubtitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
<Select
defaultValue={topicPosition || 'right'}
style={{ width: 135 }}
onChange={setTopicPosition}
size="small"
options={[
{ value: 'left', label: t('settings.topic.position.left') },
{ value: 'right', label: t('settings.topic.position.right') }
]}
/>
</SettingRow>
<SettingDivider />
{topicPosition === 'left' && (
<>
<SettingRow>
<SettingRowTitle>{t('settings.advanced.auto_switch_to_topics')}</SettingRowTitle>
<Switch
size="small"
checked={clickAssistantToShowTopic}
onChange={(checked) => dispatch(setClickAssistantToShowTopic(checked))}
/> />
</SettingRow> </Col>
<SettingDivider /> </Row>
</> </SettingGroup>
)} <SettingGroup>
<SettingRow> <SettingSubtitle style={{ marginTop: 0 }}>{t('settings.messages.title')}</SettingSubtitle>
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle> <SettingDivider />
<Switch size="small" checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} /> <SettingRow>
</SettingRow> <SettingRowTitleSmall>{t('settings.messages.divider')}</SettingRowTitleSmall>
<SettingDivider /> <Switch
size="small"
checked={showMessageDivider}
onChange={(checked) => dispatch(setShowMessageDivider(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.use_serif_font')}</SettingRowTitleSmall>
<Switch
size="small"
checked={messageFont === 'serif'}
onChange={(checked) => dispatch(setMessageFont(checked ? 'serif' : 'system'))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('chat.settings.show_line_numbers')}</SettingRowTitleSmall>
<Switch
size="small"
checked={codeShowLineNumbers}
onChange={(checked) => dispatch(setCodeShowLineNumbers(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('chat.settings.code_collapsible')}</SettingRowTitleSmall>
<Switch
size="small"
checked={codeCollapsible}
onChange={(checked) => dispatch(setCodeCollapsible(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('message.message.code_style')}</SettingRowTitleSmall>
<Select
value={codeStyle}
onChange={(value) => dispatch(setCodeStyle(value))}
style={{ width: 135 }}
size="small">
{codeThemes.map((theme) => (
<Select.Option key={theme} value={theme}>
{theme}
</Select.Option>
))}
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('message.message.style')}</SettingRowTitleSmall>
<Select
value={messageStyle}
onChange={(value) => dispatch(setMessageStyle(value))}
style={{ width: 135 }}
size="small">
<Select.Option value="plain">{t('message.message.style.plain')}</Select.Option>
<Select.Option value="bubble">{t('message.message.style.bubble')}</Select.Option>
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('message.message.code_style')}</SettingRowTitleSmall>
<Select
value={codeStyle}
onChange={(value) => dispatch(setCodeStyle(value))}
style={{ width: 135 }}
size="small">
{codeThemes.map((theme) => (
<Select.Option key={theme} value={theme}>
{theme}
</Select.Option>
))}
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.math_engine')}</SettingRowTitleSmall>
<Select
value={mathEngine}
onChange={(value) => dispatch(setMathEngine(value))}
style={{ width: 135 }}
size="small">
<Select.Option value="KaTeX">KaTeX</Select.Option>
<Select.Option value="MathJax">MathJax</Select.Option>
</Select>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.font_size.title')}</SettingRowTitleSmall>
</SettingRow>
<Row align="middle" gutter={10}>
<Col span={24}>
<Slider
value={fontSizeValue}
onChange={(value) => setFontSizeValue(value)}
onChangeComplete={(value) => dispatch(setFontSize(value))}
min={12}
max={22}
step={1}
marks={{
12: <span style={{ fontSize: '12px' }}>A</span>,
14: <span style={{ fontSize: '14px' }}>{t('common.default')}</span>,
22: <span style={{ fontSize: '18px' }}>A</span>
}}
/>
</Col>
</Row>
</SettingGroup>
<SettingGroup>
<SettingSubtitle style={{ marginTop: 0 }}>{t('settings.messages.input.title')}</SettingSubtitle>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.input.show_estimated_tokens')}</SettingRowTitleSmall>
<Switch
size="small"
checked={showInputEstimatedTokens}
onChange={(checked) => dispatch(setShowInputEstimatedTokens(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.input.paste_long_text_as_file')}</SettingRowTitleSmall>
<Switch
size="small"
checked={pasteLongTextAsFile}
onChange={(checked) => dispatch(setPasteLongTextAsFile(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.markdown_rendering_input_message')}</SettingRowTitleSmall>
<Switch
size="small"
checked={renderInputMessageAsMarkdown}
onChange={(checked) => dispatch(setRenderInputMessageAsMarkdown(checked))}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.input.send_shortcuts')}</SettingRowTitleSmall>
<Select
size="small"
value={sendMessageShortcut}
menuItemSelectedIcon={<CheckOutlined />}
options={[
{ value: 'Enter', label: 'Enter' },
{ value: 'Shift+Enter', label: `Shift + Enter` }
]}
onChange={(value) => setSendMessageShortcut(value)}
style={{ width: 135 }}
/>
</SettingRow>
<SettingDivider />
<SettingSubtitle>{t('settings.display.title')}</SettingSubtitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.topic.position')}</SettingRowTitle>
<Select
defaultValue={topicPosition || 'right'}
style={{ width: 135 }}
onChange={setTopicPosition}
size="small"
options={[
{ value: 'left', label: t('settings.topic.position.left') },
{ value: 'right', label: t('settings.topic.position.right') }
]}
/>
</SettingRow>
<SettingDivider />
{topicPosition === 'left' && (
<>
<SettingRow>
<SettingRowTitle>{t('settings.advanced.auto_switch_to_topics')}</SettingRowTitle>
<Switch
size="small"
checked={clickAssistantToShowTopic}
onChange={(checked) => dispatch(setClickAssistantToShowTopic(checked))}
/>
</SettingRow>
<SettingDivider />
</>
)}
<SettingRow>
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle>
<Switch size="small" checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} />
</SettingRow>
<SettingDivider />
</SettingGroup>
</Container> </Container>
) )
} }
@ -233,14 +401,33 @@ const Container = styled(Scrollbar)`
display: flex; display: flex;
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
padding-bottom: 10px; padding: 0 10px;
padding: 10px 15px; padding-right: 5px;
margin-bottom: 10px; `
padding-top: 0;
const Label = styled.p`
margin: 0;
font-size: 12px;
margin-right: 5px;
`
const QuestionIcon = styled(QuestionCircleOutlined)`
font-size: 12px;
cursor: pointer;
color: var(--color-text-3);
` `
const SettingRowTitleSmall = styled(SettingRowTitle)` const SettingRowTitleSmall = styled(SettingRowTitle)`
font-size: 13px; font-size: 13px;
` `
export const SettingGroup = styled.div<{ theme?: ThemeMode }>`
padding: 10px;
width: 100%;
margin-top: 0;
border-radius: 8px;
margin-bottom: 10px;
background: var(--color-background-soft);
`
export default SettingsTab export default SettingsTab

View File

@ -137,7 +137,7 @@ const HomeTabs: FC<Props> = ({ activeAssistant, activeTopic, setActiveAssistant,
{tab === 'topic' && ( {tab === 'topic' && (
<Topics assistant={activeAssistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} /> <Topics assistant={activeAssistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} />
)} )}
{tab === 'settings' && <Settings />} {tab === 'settings' && <Settings assistant={activeAssistant} />}
</TabContent> </TabContent>
</Container> </Container>
) )