dify-run
/
web
/app
/components
/base
/features
/new-feature-panel
/annotation-reply
/config-param-modal.tsx
'use client' | |
import type { FC } from 'react' | |
import React, { useState } from 'react' | |
import { useTranslation } from 'react-i18next' | |
import ScoreSlider from './score-slider' | |
import { Item } from './config-param' | |
import Modal from '@/app/components/base/modal' | |
import Button from '@/app/components/base/button' | |
import Toast from '@/app/components/base/toast' | |
import type { AnnotationReplyConfig } from '@/models/debug' | |
import { ANNOTATION_DEFAULT } from '@/config' | |
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' | |
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' | |
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' | |
type Props = { | |
appId: string | |
isShow: boolean | |
onHide: () => void | |
onSave: (embeddingModel: { | |
embedding_provider_name: string | |
embedding_model_name: string | |
}, score: number) => void | |
isInit?: boolean | |
annotationConfig: AnnotationReplyConfig | |
} | |
const ConfigParamModal: FC<Props> = ({ | |
isShow, | |
onHide: doHide, | |
onSave, | |
isInit, | |
annotationConfig: oldAnnotationConfig, | |
}) => { | |
const { t } = useTranslation() | |
const { | |
modelList: embeddingsModelList, | |
defaultModel: embeddingsDefaultModel, | |
currentModel: isEmbeddingsDefaultModelValid, | |
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textEmbedding) | |
const [annotationConfig, setAnnotationConfig] = useState(oldAnnotationConfig) | |
const [isLoading, setLoading] = useState(false) | |
const [embeddingModel, setEmbeddingModel] = useState(oldAnnotationConfig.embedding_model | |
? { | |
providerName: oldAnnotationConfig.embedding_model.embedding_provider_name, | |
modelName: oldAnnotationConfig.embedding_model.embedding_model_name, | |
} | |
: (embeddingsDefaultModel | |
? { | |
providerName: embeddingsDefaultModel.provider.provider, | |
modelName: embeddingsDefaultModel.model, | |
} | |
: undefined)) | |
const onHide = () => { | |
if (!isLoading) | |
doHide() | |
} | |
const handleSave = async () => { | |
if (!embeddingModel || !embeddingModel.modelName || (embeddingModel.modelName === embeddingsDefaultModel?.model && !isEmbeddingsDefaultModelValid)) { | |
Toast.notify({ | |
message: t('common.modelProvider.embeddingModel.required'), | |
type: 'error', | |
}) | |
return | |
} | |
setLoading(true) | |
await onSave({ | |
embedding_provider_name: embeddingModel.providerName, | |
embedding_model_name: embeddingModel.modelName, | |
}, annotationConfig.score_threshold) | |
setLoading(false) | |
} | |
return ( | |
<Modal | |
isShow={isShow} | |
onClose={onHide} | |
className='!p-8 !pb-6 !mt-14 !max-w-none !w-[640px]' | |
> | |
<div className='mb-2 text-xl font-semibold text-[#1D2939]'> | |
{t(`appAnnotation.initSetup.${isInit ? 'title' : 'configTitle'}`)} | |
</div> | |
<div className='mt-6 space-y-3'> | |
<Item | |
title={t('appDebug.feature.annotation.scoreThreshold.title')} | |
tooltip={t('appDebug.feature.annotation.scoreThreshold.description')} | |
> | |
<ScoreSlider | |
className='mt-1' | |
value={(annotationConfig.score_threshold || ANNOTATION_DEFAULT.score_threshold) * 100} | |
onChange={(val) => { | |
setAnnotationConfig({ | |
...annotationConfig, | |
score_threshold: val / 100, | |
}) | |
}} | |
/> | |
</Item> | |
<Item | |
title={t('common.modelProvider.embeddingModel.key')} | |
tooltip={t('appAnnotation.embeddingModelSwitchTip')} | |
> | |
<div className='pt-1'> | |
<ModelSelector | |
defaultModel={embeddingModel && { | |
provider: embeddingModel.providerName, | |
model: embeddingModel.modelName, | |
}} | |
modelList={embeddingsModelList} | |
onSelect={(val) => { | |
setEmbeddingModel({ | |
providerName: val.provider, | |
modelName: val.model, | |
}) | |
}} | |
/> | |
</div> | |
</Item> | |
</div> | |
<div className='mt-6 flex gap-2 justify-end'> | |
<Button onClick={onHide}>{t('common.operation.cancel')}</Button> | |
<Button | |
variant='primary' | |
onClick={handleSave} | |
loading={isLoading} | |
> | |
<div></div> | |
<div>{t(`appAnnotation.initSetup.${isInit ? 'confirmBtn' : 'configConfirmBtn'}`)}</div> | |
</Button > | |
</div > | |
</Modal > | |
) | |
} | |
export default React.memo(ConfigParamModal) | |