feat: add assistant setting popup
This commit is contained in:
parent
33b83bf242
commit
32cdfbbfb0
@ -0,0 +1,187 @@
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { DEFAULT_CONEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { SettingRow, SettingRowTitle } from '@renderer/pages/settings'
|
||||
import { Assistant, AssistantSettings } from '@renderer/types'
|
||||
import { Button, Col, Row, Slider, Switch, Tooltip } from 'antd'
|
||||
import { FC, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
interface Props {
|
||||
assistant: Assistant
|
||||
}
|
||||
|
||||
const AssistantModelSettings: FC<Props> = (props) => {
|
||||
const { assistant, updateAssistantSettings, updateAssistant } = useAssistant(props.assistant.id)
|
||||
const [temperature, setTemperature] = useState(assistant?.settings?.temperature ?? DEFAULT_TEMPERATURE)
|
||||
const [contextCount, setConextCount] = useState(assistant?.settings?.contextCount ?? DEFAULT_CONEXTCOUNT)
|
||||
const [enableMaxTokens, setEnableMaxTokens] = useState(assistant?.settings?.enableMaxTokens ?? false)
|
||||
const [maxTokens, setMaxTokens] = useState(assistant?.settings?.maxTokens ?? 0)
|
||||
const [streamOutput, setStreamOutput] = useState(assistant?.settings?.streamOutput ?? true)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const onUpdateAssistantSettings = (settings: Partial<AssistantSettings>) => {
|
||||
updateAssistantSettings({
|
||||
temperature: settings.temperature ?? temperature,
|
||||
contextCount: settings.contextCount ?? contextCount,
|
||||
enableMaxTokens: settings.enableMaxTokens ?? enableMaxTokens,
|
||||
maxTokens: settings.maxTokens ?? maxTokens,
|
||||
streamOutput: settings.streamOutput ?? streamOutput
|
||||
})
|
||||
}
|
||||
|
||||
const onTemperatureChange = (value) => {
|
||||
if (!isNaN(value as number)) {
|
||||
onUpdateAssistantSettings({ temperature: value })
|
||||
}
|
||||
}
|
||||
|
||||
const onConextCountChange = (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)
|
||||
setConextCount(DEFAULT_CONEXTCOUNT)
|
||||
updateAssistant({
|
||||
...assistant,
|
||||
settings: {
|
||||
...assistant.settings,
|
||||
temperature: DEFAULT_TEMPERATURE,
|
||||
contextCount: DEFAULT_CONEXTCOUNT,
|
||||
enableMaxTokens: false,
|
||||
maxTokens: DEFAULT_MAX_TOKENS,
|
||||
streamOutput: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setTemperature(assistant?.settings?.temperature ?? DEFAULT_TEMPERATURE)
|
||||
setConextCount(assistant?.settings?.contextCount ?? DEFAULT_CONEXTCOUNT)
|
||||
setEnableMaxTokens(assistant?.settings?.enableMaxTokens ?? false)
|
||||
setMaxTokens(assistant?.settings?.maxTokens ?? DEFAULT_MAX_TOKENS)
|
||||
setStreamOutput(assistant?.settings?.streamOutput ?? true)
|
||||
}, [assistant])
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Row align="middle">
|
||||
<Label>{t('chat.settings.temperature')}</Label>
|
||||
<Tooltip title={t('chat.settings.temperature.tip')}>
|
||||
<QuestionIcon />
|
||||
</Tooltip>
|
||||
</Row>
|
||||
<Row align="middle" gutter={10}>
|
||||
<Col span={24}>
|
||||
<Slider
|
||||
min={0}
|
||||
max={2}
|
||||
onChange={setTemperature}
|
||||
onChangeComplete={onTemperatureChange}
|
||||
value={typeof temperature === 'number' ? temperature : 0}
|
||||
step={0.1}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row align="middle">
|
||||
<Label>{t('chat.settings.conext_count')}</Label>
|
||||
<Tooltip title={t('chat.settings.conext_count.tip')}>
|
||||
<QuestionIcon />
|
||||
</Tooltip>
|
||||
</Row>
|
||||
<Row align="middle" gutter={10}>
|
||||
<Col span={24}>
|
||||
<Slider
|
||||
min={0}
|
||||
max={20}
|
||||
onChange={setConextCount}
|
||||
onChangeComplete={onConextCountChange}
|
||||
value={typeof contextCount === 'number' ? contextCount : 0}
|
||||
step={1}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row align="middle" justify="space-between">
|
||||
<HStack alignItems="center">
|
||||
<Label>{t('chat.settings.max_tokens')}</Label>
|
||||
<Tooltip title={t('chat.settings.max_tokens.tip')}>
|
||||
<QuestionIcon />
|
||||
</Tooltip>
|
||||
</HStack>
|
||||
<Switch
|
||||
checked={enableMaxTokens}
|
||||
onChange={(enabled) => {
|
||||
setEnableMaxTokens(enabled)
|
||||
onUpdateAssistantSettings({ enableMaxTokens: enabled })
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
<Row align="middle" gutter={10}>
|
||||
<Col span={24}>
|
||||
<Slider
|
||||
disabled={!enableMaxTokens}
|
||||
min={0}
|
||||
max={32000}
|
||||
onChange={setMaxTokens}
|
||||
onChangeComplete={onMaxTokensChange}
|
||||
value={typeof maxTokens === 'number' ? maxTokens : 0}
|
||||
step={100}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<SettingRow>
|
||||
<SettingRowTitleSmall>{t('model.stream_output')}</SettingRowTitleSmall>
|
||||
<Switch
|
||||
checked={streamOutput}
|
||||
onChange={(checked) => {
|
||||
setStreamOutput(checked)
|
||||
onUpdateAssistantSettings({ streamOutput: checked })
|
||||
}}
|
||||
/>
|
||||
</SettingRow>
|
||||
<HStack
|
||||
justifyContent="flex-end"
|
||||
style={{ marginTop: 20, padding: '10px 0', borderTop: '0.5px solid var(--color-border)' }}>
|
||||
<Button onClick={onReset} style={{ width: 80 }} danger type="primary">
|
||||
{t('chat.settings.reset')}
|
||||
</Button>
|
||||
</HStack>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
padding-bottom: 10px;
|
||||
`
|
||||
|
||||
const Label = styled.p`
|
||||
margin: 0;
|
||||
margin-right: 5px;
|
||||
`
|
||||
|
||||
const QuestionIcon = styled(QuestionCircleOutlined)`
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
color: var(--color-text-3);
|
||||
`
|
||||
|
||||
const SettingRowTitleSmall = styled(SettingRowTitle)`
|
||||
font-size: 13px;
|
||||
`
|
||||
|
||||
export default AssistantModelSettings
|
||||
@ -0,0 +1,47 @@
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { syncAsistantToAgent } from '@renderer/services/assistant'
|
||||
import { Assistant } from '@renderer/types'
|
||||
import { Input } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { Box, VStack } from '../Layout'
|
||||
|
||||
const AssistantPromptSettings: React.FC<{ assistant: Assistant }> = (props) => {
|
||||
const { assistant, updateAssistant } = useAssistant(props.assistant.id)
|
||||
const [name, setName] = useState(assistant.name)
|
||||
const [prompt, setPrompt] = useState(assistant.prompt)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const onUpdate = () => {
|
||||
const _assistant = { ...assistant, name, prompt }
|
||||
updateAssistant(_assistant)
|
||||
syncAsistantToAgent(_assistant)
|
||||
}
|
||||
|
||||
return (
|
||||
<VStack flex={1}>
|
||||
<Box mb={8}>{t('common.name')}</Box>
|
||||
<Input
|
||||
placeholder={t('common.assistant') + t('common.name')}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
onBlur={onUpdate}
|
||||
/>
|
||||
<Box mt={8} mb={8}>
|
||||
{t('common.prompt')}
|
||||
</Box>
|
||||
<TextArea
|
||||
rows={10}
|
||||
placeholder={t('common.assistant') + t('common.prompt')}
|
||||
value={prompt}
|
||||
onChange={(e) => setPrompt(e.target.value)}
|
||||
onBlur={onUpdate}
|
||||
style={{ minHeight: 'calc(80vh - 150px)', maxHeight: 'calc(80vh - 150px)' }}
|
||||
/>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssistantPromptSettings
|
||||
154
src/renderer/src/components/AssistantSettings/index.tsx
Normal file
154
src/renderer/src/components/AssistantSettings/index.tsx
Normal file
@ -0,0 +1,154 @@
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { Assistant } from '@renderer/types'
|
||||
import { Menu, Modal } from 'antd'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import { HStack } from '../Layout'
|
||||
import { TopView } from '../TopView'
|
||||
import AssistantModelSettings from './AssistantModelSettings'
|
||||
import AssistantPromptSettings from './AssistantPromptSettings'
|
||||
|
||||
interface AssistantSettingPopupShowParams {
|
||||
assistant: Assistant
|
||||
}
|
||||
|
||||
interface Props extends AssistantSettingPopupShowParams {
|
||||
resolve: (assistant: Assistant) => void
|
||||
}
|
||||
|
||||
const AssistantSettingPopupContainer: React.FC<Props> = ({ assistant, resolve }) => {
|
||||
const [open, setOpen] = useState(true)
|
||||
const { t } = useTranslation()
|
||||
const [menu, setMenu] = useState('prompt')
|
||||
const { theme } = useTheme()
|
||||
|
||||
const onOk = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
resolve(assistant)
|
||||
}
|
||||
|
||||
const items = [
|
||||
{
|
||||
key: 'prompt',
|
||||
label: t('assistants.prompt_settings')
|
||||
},
|
||||
{
|
||||
key: 'model',
|
||||
label: t('assistants.model_settings')
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<StyledModal
|
||||
open={open}
|
||||
onOk={onOk}
|
||||
onCancel={handleCancel}
|
||||
afterClose={onClose}
|
||||
transitionName="ant-move-down"
|
||||
maskTransitionName="ant-fade"
|
||||
footer={null}
|
||||
title={assistant.name}
|
||||
styles={{
|
||||
content: {
|
||||
padding: 0,
|
||||
overflow: 'hidden',
|
||||
border: '1px solid var(--color-border)',
|
||||
background: 'var(--color-background)'
|
||||
},
|
||||
header: { padding: '10px 15px', borderBottom: '0.5px solid var(--color-border)', margin: 0 },
|
||||
mask: { background: theme === 'light' ? 'rgba(255,255,255, 0.8)' : 'rgba(0,0,0, 0.8)' }
|
||||
}}
|
||||
width="70vw"
|
||||
height="80vh"
|
||||
centered>
|
||||
<HStack>
|
||||
<LeftMenu>
|
||||
<Menu
|
||||
style={{ width: 220, padding: 5, background: 'transparent' }}
|
||||
defaultSelectedKeys={['prompt']}
|
||||
mode="vertical"
|
||||
items={items}
|
||||
onSelect={({ key }) => setMenu(key as string)}
|
||||
/>
|
||||
</LeftMenu>
|
||||
<Settings>
|
||||
{menu === 'prompt' && <AssistantPromptSettings assistant={assistant} />}
|
||||
{menu === 'model' && <AssistantModelSettings assistant={assistant} />}
|
||||
</Settings>
|
||||
</HStack>
|
||||
</StyledModal>
|
||||
)
|
||||
}
|
||||
|
||||
const LeftMenu = styled.div`
|
||||
background-color: var(--color-background);
|
||||
height: calc(80vh - 20px);
|
||||
border-right: 0.5px solid var(--color-border);
|
||||
`
|
||||
|
||||
const Settings = styled.div`
|
||||
flex: 1;
|
||||
padding: 10px 20px;
|
||||
height: calc(80vh - 20px);
|
||||
overflow-y: scroll;
|
||||
`
|
||||
|
||||
const StyledModal = styled(Modal)`
|
||||
.ant-modal-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
.ant-modal-close {
|
||||
top: 4px;
|
||||
}
|
||||
.ant-menu-item {
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
color: var(--color-text-2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.ant-menu-title-content {
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
.ant-menu-item-active {
|
||||
background-color: var(--color-background-soft) !important;
|
||||
transition: none;
|
||||
}
|
||||
.ant-menu-item-selected {
|
||||
background-color: var(--color-background-soft);
|
||||
.ant-menu-title-content {
|
||||
color: var(--color-text-1);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default class AssistantSettingPopup {
|
||||
static topviewId = 0
|
||||
static hide() {
|
||||
TopView.hide('AssistantSettingPopup')
|
||||
}
|
||||
static show(props: AssistantSettingPopupShowParams) {
|
||||
return new Promise<Assistant>((resolve) => {
|
||||
TopView.show(
|
||||
<AssistantSettingPopupContainer
|
||||
{...props}
|
||||
resolve={(v) => {
|
||||
resolve(v)
|
||||
this.hide()
|
||||
}}
|
||||
/>,
|
||||
'AssistantSettingPopup'
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
import { Assistant } from '@renderer/types'
|
||||
import { Input, Modal } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { Box } from '../Layout'
|
||||
import { TopView } from '../TopView'
|
||||
|
||||
interface AssistantSettingPopupShowParams {
|
||||
assistant: Assistant
|
||||
}
|
||||
|
||||
interface Props extends AssistantSettingPopupShowParams {
|
||||
resolve: (assistant: Assistant) => void
|
||||
}
|
||||
|
||||
const AssistantSettingPopupContainer: React.FC<Props> = ({ assistant, resolve }) => {
|
||||
const [name, setName] = useState(assistant.name)
|
||||
const [prompt, setPrompt] = useState(assistant.prompt)
|
||||
const [open, setOpen] = useState(true)
|
||||
const { t } = useTranslation()
|
||||
|
||||
const onOk = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
resolve({ ...assistant, name, prompt })
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={assistant.name}
|
||||
open={open}
|
||||
onOk={onOk}
|
||||
onCancel={handleCancel}
|
||||
afterClose={onClose}
|
||||
transitionName="ant-move-down"
|
||||
maskTransitionName="ant-fade"
|
||||
centered>
|
||||
<Box mb={8}>{t('common.name')}</Box>
|
||||
<Input
|
||||
placeholder={t('common.assistant') + t('common.name')}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
<Box mt={8} mb={8}>
|
||||
{t('common.prompt')}
|
||||
</Box>
|
||||
<TextArea
|
||||
rows={10}
|
||||
placeholder={t('common.assistant') + t('common.prompt')}
|
||||
value={prompt}
|
||||
onChange={(e) => setPrompt(e.target.value)}
|
||||
/>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default class AssistantSettingPopup {
|
||||
static topviewId = 0
|
||||
static hide() {
|
||||
TopView.hide('AssistantSettingPopup')
|
||||
}
|
||||
static show(props: AssistantSettingPopupShowParams) {
|
||||
return new Promise<Assistant>((resolve) => {
|
||||
TopView.show(
|
||||
<AssistantSettingPopupContainer
|
||||
{...props}
|
||||
resolve={(v) => {
|
||||
resolve(v)
|
||||
this.hide()
|
||||
}}
|
||||
/>,
|
||||
'AssistantSettingPopup'
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -20,11 +20,14 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||
trackBg: 'transparent',
|
||||
itemSelectedBg: isDarkTheme ? 'rgba(255, 255, 255, 0.05)' : 'rgba(0, 0, 0, 0.05)',
|
||||
boxShadowTertiary: undefined
|
||||
},
|
||||
Menu: {
|
||||
activeBarBorderWidth: 0,
|
||||
darkItemBg: 'transparent'
|
||||
}
|
||||
},
|
||||
token: {
|
||||
colorPrimary: '#00b96b',
|
||||
borderRadius: 6
|
||||
colorPrimary: '#00b96b'
|
||||
}
|
||||
}}>
|
||||
{children}
|
||||
|
||||
@ -110,7 +110,9 @@
|
||||
"assistants": {
|
||||
"title": "Assistants",
|
||||
"abbr": "Assistant",
|
||||
"search": "Search assistants..."
|
||||
"search": "Search assistants...",
|
||||
"prompt_settings": "Prompt Settings",
|
||||
"model_settings": "Model Settings"
|
||||
},
|
||||
"model": {
|
||||
"stream_output": "Stream Output"
|
||||
|
||||
@ -110,7 +110,9 @@
|
||||
"assistants": {
|
||||
"title": "助手",
|
||||
"abbr": "助手",
|
||||
"search": "搜索助手"
|
||||
"search": "搜索助手",
|
||||
"prompt_settings": "提示词设置",
|
||||
"model_settings": "模型设置"
|
||||
},
|
||||
"model": {
|
||||
"stream_output": "流式输出"
|
||||
|
||||
@ -110,7 +110,9 @@
|
||||
"assistants": {
|
||||
"title": "助手",
|
||||
"abbr": "助",
|
||||
"search": "搜尋助手..."
|
||||
"search": "搜尋助手...",
|
||||
"prompt_settings": "提示詞設定",
|
||||
"model_settings": "模型設定"
|
||||
},
|
||||
"model": {
|
||||
"stream_output": "串流輸出"
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { DeleteOutlined, EditOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
|
||||
import AssistantSettingPopup from '@renderer/components/AssistantSettings'
|
||||
import DragableList from '@renderer/components/DragableList'
|
||||
import CopyIcon from '@renderer/components/Icons/CopyIcon'
|
||||
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
|
||||
import { useAssistant, useAssistants } from '@renderer/hooks/useAssistant'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { getDefaultTopic, syncAsistantToAgent } from '@renderer/services/assistant'
|
||||
import { getDefaultTopic } from '@renderer/services/assistant'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import { setSearching } from '@renderer/store/runtime'
|
||||
@ -34,7 +34,7 @@ const Assistants: FC<Props> = ({
|
||||
const generating = useAppSelector((state) => state.runtime.generating)
|
||||
const [search, setSearch] = useState('')
|
||||
const [dragging, setDragging] = useState(false)
|
||||
const { updateAssistant, removeAllTopics } = useAssistant(activeAssistant.id)
|
||||
const { removeAllTopics } = useAssistant(activeAssistant.id)
|
||||
const { clickAssistantToShowTopic, topicPosition } = useSettings()
|
||||
const searchRef = useRef<InputRef>(null)
|
||||
const { t } = useTranslation()
|
||||
@ -49,15 +49,6 @@ const Assistants: FC<Props> = ({
|
||||
[assistants, onCreateDefaultAssistant, removeAssistant, setActiveAssistant]
|
||||
)
|
||||
|
||||
const onEditAssistant = useCallback(
|
||||
async (assistant: Assistant) => {
|
||||
const _assistant = await AssistantSettingPopup.show({ assistant })
|
||||
updateAssistant(_assistant)
|
||||
syncAsistantToAgent(_assistant)
|
||||
},
|
||||
[updateAssistant]
|
||||
)
|
||||
|
||||
const getMenuItems = useCallback(
|
||||
(assistant: Assistant) =>
|
||||
[
|
||||
@ -65,7 +56,7 @@ const Assistants: FC<Props> = ({
|
||||
label: t('common.edit'),
|
||||
key: 'edit',
|
||||
icon: <EditOutlined />,
|
||||
onClick: () => onEditAssistant(assistant)
|
||||
onClick: () => AssistantSettingPopup.show({ assistant })
|
||||
},
|
||||
{
|
||||
label: t('common.duplicate'),
|
||||
@ -100,7 +91,7 @@ const Assistants: FC<Props> = ({
|
||||
onClick: () => onDelete(assistant)
|
||||
}
|
||||
] as ItemType[],
|
||||
[addAssistant, onDelete, onEditAssistant, removeAllTopics, setActiveAssistant, t]
|
||||
[addAssistant, onDelete, removeAllTopics, setActiveAssistant, t]
|
||||
)
|
||||
|
||||
const onSwitchAssistant = useCallback(
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { syncAsistantToAgent } from '@renderer/services/assistant'
|
||||
import AssistantSettingPopup from '@renderer/components/AssistantSettings'
|
||||
import { Assistant } from '@renderer/types'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -12,22 +10,15 @@ interface Props {
|
||||
|
||||
const Prompt: FC<Props> = ({ assistant }) => {
|
||||
const { t } = useTranslation()
|
||||
const { updateAssistant } = useAssistant(assistant.id)
|
||||
|
||||
const prompt = assistant.prompt || t('chat.default.description')
|
||||
|
||||
const onEdit = async () => {
|
||||
const _assistant = await AssistantSettingPopup.show({ assistant })
|
||||
updateAssistant(_assistant)
|
||||
syncAsistantToAgent(_assistant)
|
||||
}
|
||||
|
||||
if (!prompt) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<Container onClick={onEdit}>
|
||||
<Container onClick={() => AssistantSettingPopup.show({ assistant })}>
|
||||
<Text>{prompt}</Text>
|
||||
</Container>
|
||||
)
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { FormOutlined } from '@ant-design/icons'
|
||||
import { Navbar, NavbarLeft, NavbarRight } from '@renderer/components/app/Navbar'
|
||||
import AssistantSettingPopup from '@renderer/components/AssistantSettings'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
|
||||
import { isMac, isWindows } from '@renderer/config/constant'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import db from '@renderer/databases'
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
||||
import { getDefaultTopic, syncAsistantToAgent } from '@renderer/services/assistant'
|
||||
import { getDefaultTopic } from '@renderer/services/assistant'
|
||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
||||
import { Assistant, Topic } from '@renderer/types'
|
||||
import { Switch } from 'antd'
|
||||
@ -25,19 +25,13 @@ interface Props {
|
||||
}
|
||||
|
||||
const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
||||
const { assistant, updateAssistant, addTopic } = useAssistant(activeAssistant.id)
|
||||
const { assistant, addTopic } = useAssistant(activeAssistant.id)
|
||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||
const { theme, toggleTheme } = useTheme()
|
||||
const { topicPosition } = useSettings()
|
||||
const { showTopics, toggleShowTopics } = useShowTopics()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const onEditAssistant = useCallback(async () => {
|
||||
const _assistant = await AssistantSettingPopup.show({ assistant })
|
||||
updateAssistant(_assistant)
|
||||
syncAsistantToAgent(_assistant)
|
||||
}, [assistant, updateAssistant])
|
||||
|
||||
const addNewTopic = useCallback(() => {
|
||||
const topic = getDefaultTopic()
|
||||
addTopic(topic)
|
||||
@ -68,7 +62,10 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
||||
<i className="iconfont icon-show-sidebar" />
|
||||
</NewButton>
|
||||
)}
|
||||
<TitleText style={{ marginRight: 10, cursor: 'pointer' }} className="nodrag" onClick={onEditAssistant}>
|
||||
<TitleText
|
||||
style={{ marginRight: 10, cursor: 'pointer' }}
|
||||
className="nodrag"
|
||||
onClick={() => AssistantSettingPopup.show({ assistant })}>
|
||||
{assistant.name}
|
||||
</TitleText>
|
||||
<SelectModelButton assistant={assistant} />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user