Skip to content

Commit

Permalink
feat: add asistant model temperature maxTokens contextCount
Browse files Browse the repository at this point in the history
  • Loading branch information
kangfenmao committed Jul 21, 2024
1 parent 75c3763 commit 4169a2e
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 32 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-unused-imports": "^4.0.0",
"gpt-tokens": "^1.3.6",
"i18next": "^23.11.5",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/assets/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
--topic-list-width: 250px;
--settings-width: var(--assistants-width);
--status-bar-height: 40px;
--input-bar-height: 120px;
--input-bar-height: 125px;
}

*,
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/src/components/app/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,13 @@ const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 0;
padding: 8px 0;
min-width: var(--sidebar-width);
min-height: 100%;
-webkit-app-region: drag !important;
background-color: #1f1f1f;
border-right: 0.5px solid var(--color-border);
margin-top: var(--navbar-height);
padding-bottom: calc(var(--navbar-height) + 6px);
padding-top: var(--navbar-height);
`

const AvatarImg = styled.img`
Expand All @@ -60,6 +59,7 @@ const AvatarImg = styled.img`
height: 28px;
background-color: var(--color-background-soft);
margin: 5px 0;
margin-top: 12px;
`
const MainMenus = styled.div`
display: flex;
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/src/config/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const DEFAULT_TEMPERATURE = 0.7
export const DEFAULT_MAXTOKENS = 800
export const DEFAULT_CONEXTCOUNT = 5
8 changes: 7 additions & 1 deletion src/renderer/src/hooks/useProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ import {
} from '@renderer/store/llm'
import { Assistant, Model, Provider } from '@renderer/types'
import { useDefaultModel } from './useAssistant'
import { createSelector } from '@reduxjs/toolkit'

const selectEnabledProviders = createSelector(
(state) => state.llm.providers,
(providers) => providers.filter((p) => p.enabled)
)

export function useProviders() {
const providers = useAppSelector((state) => state.llm.providers.filter((p) => p.enabled))
const providers = useAppSelector(selectEnabledProviders)
const dispatch = useAppDispatch()

return {
Expand Down
30 changes: 28 additions & 2 deletions src/renderer/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,18 @@ const resources = {
'input.clear.content': 'Are you sure to clear all messages?',
'input.placeholder': 'Type your message here...',
'input.send': 'Send',
'input.pause': 'Pause'
'input.pause': 'Pause',
'input.settings': 'Settings',
'settings.temperature': 'Temperature',
'settings.temperature.tip':
'Lower values make the model more creative and unpredictable, while higher values make it more deterministic and precise.',
'settings.max_tokens': 'Max Tokens',
'settings.max_tokens.tip': 'The maximum number of tokens to generate in the completion.',
'settings.conext_count': 'Context',
'settings.conext_count.tip': 'The number of previous messages to keep in the context.',
'settings.reset': 'Reset',
'settings.set_as_default': 'Apply to default assistant',
'settings.max': 'Max'
},
apps: {
title: 'Agents'
Expand Down Expand Up @@ -112,6 +123,7 @@ const resources = {
'models.add.group_name.placeholder': 'Optional e.g. ChatGPT',
'models.empty': 'No models found',
'assistant.title': 'Default Assistant',
'assistant.model_params': 'Model Parameters',
'about.description': 'A powerful AI assistant for producer',
'about.updateNotAvailable': 'You are using the latest version',
'about.checkingUpdate': 'Checking for updates...',
Expand Down Expand Up @@ -186,7 +198,20 @@ const resources = {
'input.clear.content': '确定要清除所有消息吗?',
'input.placeholder': '在这里输入消息...',
'input.send': '发送',
'input.pause': '暂停'
'input.pause': '暂停',
'input.settings': '设置',
'settings.temperature': '模型温度',
'settings.temperature.tip':
'模型生成文本的随机程度。值越大,回复内容越赋有多样性、创造性、随机性;设为 0 根据事实回答。日常聊天建议设置为 0.7',
'settings.max_tokens': '最大回复',
'settings.max_tokens.tip':
'最大回复内容多少,数值越大,生成的文本越长。普通聊天建议 500-800;短文生成建议 800-2000;代码生成建议 2000-3600;长文生成建议切换模型到 4000 左右',
'settings.conext_count': '上下文数',
'settings.conext_count.tip':
'要保留在上下文中的消息数量,数值越大,上下文越长,消耗的 token 越多。普通聊天建议 5-10,代码生成建议 5-10',
'settings.reset': '重置',
'settings.set_as_default': '应用到默认助手',
'settings.max': '不限'
},
apps: {
title: '智能体'
Expand Down Expand Up @@ -234,6 +259,7 @@ const resources = {
'models.add.group_name.placeholder': '例如 ChatGPT',
'models.empty': '没有模型',
'assistant.title': '默认助手',
'assistant.model_params': '模型参数',
'about.description': '一个为创造者而生的 AI 助手',
'about.updateNotAvailable': '你的软件已是最新版本',
'about.checkingUpdate': '正在检查更新...',
Expand Down
219 changes: 219 additions & 0 deletions src/renderer/src/pages/home/components/AssistantSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import { QuestionCircleOutlined } from '@ant-design/icons'
import { DEFAULT_CONEXTCOUNT, DEFAULT_MAXTOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
import { useAssistants } from '@renderer/hooks/useAssistant'
import { Assistant } from '@renderer/types'
import { Button, Col, InputNumber, Popover, Row, Slider, Tooltip } from 'antd'
import { FC, PropsWithChildren, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

interface Props {
assistant: Assistant
}

const PopoverContent: FC<Props> = ({ assistant }) => {
const { updateAssistant } = useAssistants()
const [temperature, setTemperature] = useState(assistant.settings?.temperature ?? DEFAULT_TEMPERATURE)
const [maxTokens, setMaxTokens] = useState(assistant.settings?.maxTokens ?? DEFAULT_MAXTOKENS)
const [contextCount, setConextCount] = useState(assistant.settings?.contextCount ?? DEFAULT_CONEXTCOUNT)
const { t } = useTranslation()

const onUpdateAssistantSettings = ({
_temperature,
_maxTokens,
_contextCount
}: {
_temperature?: number
_maxTokens?: number
_contextCount?: number
}) => {
updateAssistant({
...assistant,
settings: {
...assistant.settings,
temperature: _temperature ?? temperature,
maxTokens: _maxTokens ?? maxTokens,
contextCount: _contextCount ?? contextCount
}
})
}

const onTemperatureChange = (value) => {
if (!isNaN(value as number)) {
setTemperature(value)
onUpdateAssistantSettings({ _temperature: value })
}
}

const onMaxTokensChange = (value) => {
if (!isNaN(value as number)) {
setMaxTokens(value)
onUpdateAssistantSettings({ _maxTokens: value })
}
}

const onConextCountChange = (value) => {
if (!isNaN(value as number)) {
setConextCount(value)
onUpdateAssistantSettings({ _contextCount: value })
}
}

const onReset = () => {
setTemperature(DEFAULT_TEMPERATURE)
setMaxTokens(DEFAULT_MAXTOKENS)
setConextCount(DEFAULT_CONEXTCOUNT)
updateAssistant({
...assistant,
settings: {
...assistant.settings,
temperature: DEFAULT_TEMPERATURE,
maxTokens: DEFAULT_MAXTOKENS,
contextCount: DEFAULT_CONEXTCOUNT
}
})
}

return (
<Container>
<Row align="middle" style={{ marginBottom: 10 }} gutter={20}>
<Col span={5}>
<Row align="middle">
<Label>{t('assistant.settings.temperature')}</Label>
<Tooltip title={t('assistant.settings.temperature.tip')}>
<QuestionIcon />
</Tooltip>
</Row>
</Col>
<Col span={14}>
<Slider
min={0}
max={1.2}
onChange={onTemperatureChange}
value={typeof temperature === 'number' ? temperature : 0}
marks={{ 0: '0', 0.7: '0.7', 1: '1', 1.2: '1.2' }}
step={0.1}
/>
</Col>
<Col span={4}>
<InputNumber
min={0}
max={1.2}
style={{ width: 70, marginLeft: 5, textAlign: 'center' }}
step={0.1}
value={temperature}
onChange={onTemperatureChange}
controls={false}
/>
</Col>
</Row>
<Row align="middle" style={{ marginBottom: 10 }} gutter={20}>
<Col span={5}>
<Row align="middle">
<Label>{t('assistant.settings.conext_count')}</Label>
<Tooltip title={t('assistant.settings.conext_count.tip')}>
<QuestionIcon />
</Tooltip>
</Row>
</Col>
<Col span={14}>
<Slider
min={0}
max={20}
marks={{ 0: '0', 5: '5', 10: '10', 15: '15', 20: t('assistant.settings.max') }}
onChange={onConextCountChange}
value={typeof contextCount === 'number' ? contextCount : 0}
step={1}
/>
</Col>
<Col span={4}>
<InputNumber
min={0}
max={20}
style={{ width: 70, marginLeft: 5, textAlign: 'center' }}
step={1}
value={contextCount}
onChange={onConextCountChange}
controls={false}
/>
</Col>
</Row>
<Row align="middle" gutter={20}>
<Col span={5}>
<Row align="middle">
<Label>{t('assistant.settings.max_tokens')}</Label>
<Tooltip title={t('assistant.settings.max_tokens.tip')}>
<QuestionIcon />
</Tooltip>
</Row>
</Col>
<Col span={14}>
<Slider
min={0}
max={5000}
onChange={onMaxTokensChange}
value={typeof maxTokens === 'number' ? maxTokens : 0}
marks={{ 0: '0', 800: '800', 2000: '2000', 3600: '3600', 5000: t('assistant.settings.max') }}
step={64}
/>
</Col>
<Col span={4}>
<InputNumber
min={0}
max={5000}
style={{ width: 70, marginLeft: 5, textAlign: 'center' }}
step={64}
value={maxTokens}
onChange={onMaxTokensChange}
controls={false}
/>
</Col>
</Row>
<Row justify="center" style={{ marginTop: 10 }}>
<Button onClick={onReset} style={{ marginRight: 10 }}>
{t('assistant.settings.reset')}
</Button>
</Row>
</Container>
)
}

const AssistantSettings: FC<Props & PropsWithChildren> = ({ children, assistant }) => {
const [open, setOpen] = useState(false)
const { t } = useTranslation()

return (
<Popover content={<PopoverContent assistant={assistant} />} trigger="click" onOpenChange={setOpen}>
{open ? (
children
) : (
<Tooltip placement="top" title={t('assistant.input.settings')} arrow>
{children}
</Tooltip>
)}
</Popover>
)
}

const Container = styled.div`
display: flex;
flex-direction: column;
margin-bottom: 8px;
width: 500px;
padding: 5px;
`

const Label = styled.p`
margin: 0;
font-size: 14px;
font-weight: bold;
margin-right: 5px;
`

const QuestionIcon = styled(QuestionCircleOutlined)`
font-size: 14px;
cursor: pointer;
color: var(--color-text-3);
`

export default AssistantSettings
9 changes: 5 additions & 4 deletions src/renderer/src/pages/home/components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Assistant } from '@renderer/types'
import { FC } from 'react'
import { Assistant, Message } from '@renderer/types'
import { FC, useRef } from 'react'
import styled from 'styled-components'
import Inputbar from './Inputbar'
import Messages from './Messages'
Expand All @@ -15,6 +15,7 @@ interface Props {
const Chat: FC<Props> = (props) => {
const { assistant } = useAssistant(props.assistant.id)
const { activeTopic, setActiveTopic } = useActiveTopic(assistant)
const messagesRef = useRef<Message[]>([])

if (!assistant) {
return null
Expand All @@ -23,8 +24,8 @@ const Chat: FC<Props> = (props) => {
return (
<Container id="chat">
<Flex vertical flex={1} justify="space-between">
<Messages assistant={assistant} topic={activeTopic} />
<Inputbar assistant={assistant} setActiveTopic={setActiveTopic} />
<Messages assistant={assistant} topic={activeTopic} messagesRef={messagesRef} />
<Inputbar assistant={assistant} setActiveTopic={setActiveTopic} messagesRef={messagesRef} />
</Flex>
<Topics assistant={assistant} activeTopic={activeTopic} setActiveTopic={setActiveTopic} />
</Container>
Expand Down
Loading

0 comments on commit 4169a2e

Please sign in to comment.