Spaces:
Paused
Paused
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg'; | |
import { IModalManagerChildrenProps } from '@/components/modal-manager'; | |
import { | |
ModelVariableType, | |
settledModelVariableMap, | |
} from '@/constants/knowledge'; | |
import { useTranslate } from '@/hooks/common-hooks'; | |
import { useFetchModelId } from '@/hooks/logic-hooks'; | |
import { IDialog } from '@/interfaces/database/chat'; | |
import { getBase64FromUploadFileList } from '@/utils/file-util'; | |
import { removeUselessFieldsFromValues } from '@/utils/form'; | |
import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd'; | |
import { SegmentedValue } from 'antd/es/segmented'; | |
import camelCase from 'lodash/camelCase'; | |
import { useEffect, useRef, useState } from 'react'; | |
import { IPromptConfigParameters } from '../interface'; | |
import AssistantSetting from './assistant-setting'; | |
import ModelSetting from './model-setting'; | |
import PromptEngine from './prompt-engine'; | |
import styles from './index.less'; | |
const layout = { | |
labelCol: { span: 9 }, | |
wrapperCol: { span: 15 }, | |
}; | |
const validateMessages = { | |
required: '${label} is required!', | |
types: { | |
email: '${label} is not a valid email!', | |
number: '${label} is not a valid number!', | |
}, | |
number: { | |
range: '${label} must be between ${min} and ${max}', | |
}, | |
}; | |
enum ConfigurationSegmented { | |
AssistantSetting = 'Assistant Setting', | |
PromptEngine = 'Prompt Engine', | |
ModelSetting = 'Model Setting', | |
} | |
const segmentedMap = { | |
[ConfigurationSegmented.AssistantSetting]: AssistantSetting, | |
[ConfigurationSegmented.ModelSetting]: ModelSetting, | |
[ConfigurationSegmented.PromptEngine]: PromptEngine, | |
}; | |
interface IProps extends IModalManagerChildrenProps { | |
initialDialog: IDialog; | |
loading: boolean; | |
onOk: (dialog: IDialog) => void; | |
clearDialog: () => void; | |
} | |
const ChatConfigurationModal = ({ | |
visible, | |
hideModal, | |
initialDialog, | |
loading, | |
onOk, | |
clearDialog, | |
}: IProps) => { | |
const [form] = Form.useForm(); | |
const [value, setValue] = useState<ConfigurationSegmented>( | |
ConfigurationSegmented.AssistantSetting, | |
); | |
const promptEngineRef = useRef<Array<IPromptConfigParameters>>([]); | |
const modelId = useFetchModelId(); | |
const { t } = useTranslate('chat'); | |
const handleOk = async () => { | |
const values = await form.validateFields(); | |
const nextValues: any = removeUselessFieldsFromValues( | |
values, | |
'llm_setting.', | |
); | |
const emptyResponse = nextValues.prompt_config?.empty_response ?? ''; | |
const icon = await getBase64FromUploadFileList(values.icon); | |
const finalValues = { | |
dialog_id: initialDialog.id, | |
...nextValues, | |
vector_similarity_weight: 1 - nextValues.vector_similarity_weight, | |
prompt_config: { | |
...nextValues.prompt_config, | |
parameters: promptEngineRef.current, | |
empty_response: emptyResponse, | |
}, | |
icon, | |
}; | |
onOk(finalValues); | |
}; | |
const handleSegmentedChange = (val: SegmentedValue) => { | |
setValue(val as ConfigurationSegmented); | |
}; | |
const handleModalAfterClose = () => { | |
clearDialog(); | |
form.resetFields(); | |
}; | |
const title = ( | |
<Flex gap={16}> | |
<ChatConfigurationAtom></ChatConfigurationAtom> | |
<div> | |
<b>{t('chatConfiguration')}</b> | |
<div className={styles.chatConfigurationDescription}> | |
{t('chatConfigurationDescription')} | |
</div> | |
</div> | |
</Flex> | |
); | |
useEffect(() => { | |
if (visible) { | |
const icon = initialDialog.icon; | |
let fileList: UploadFile[] = []; | |
if (icon) { | |
fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }]; | |
} | |
form.setFieldsValue({ | |
...initialDialog, | |
llm_setting: | |
initialDialog.llm_setting ?? | |
settledModelVariableMap[ModelVariableType.Precise], | |
icon: fileList, | |
llm_id: initialDialog.llm_id ?? modelId, | |
vector_similarity_weight: | |
1 - (initialDialog.vector_similarity_weight ?? 0.3), | |
}); | |
} | |
}, [initialDialog, form, visible, modelId]); | |
return ( | |
<Modal | |
title={title} | |
width={688} | |
open={visible} | |
onOk={handleOk} | |
onCancel={hideModal} | |
confirmLoading={loading} | |
destroyOnClose | |
afterClose={handleModalAfterClose} | |
> | |
<Segmented | |
size={'large'} | |
value={value} | |
onChange={handleSegmentedChange} | |
options={Object.values(ConfigurationSegmented).map((x) => ({ | |
label: t(camelCase(x)), | |
value: x, | |
}))} | |
block | |
/> | |
<Divider></Divider> | |
<Form | |
{...layout} | |
name="nest-messages" | |
form={form} | |
style={{ maxWidth: 600 }} | |
validateMessages={validateMessages} | |
colon={false} | |
> | |
{Object.entries(segmentedMap).map(([key, Element]) => ( | |
<Element | |
key={key} | |
show={key === value} | |
form={form} | |
{...(key === ConfigurationSegmented.ModelSetting | |
? { initialLlmSetting: initialDialog.llm_setting, visible } | |
: {})} | |
{...(key === ConfigurationSegmented.PromptEngine | |
? { ref: promptEngineRef } | |
: {})} | |
></Element> | |
))} | |
</Form> | |
</Modal> | |
); | |
}; | |
export default ChatConfigurationModal; | |