@ -1,10 +1,12 @@
'use client'
import React from 'react'
import { memo , useMemo } from 'react'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine ,
} from '@remixicon/react'
import WeightedScore from './weighted-score'
import TopKItem from '@/app/components/base/param-item/top-k-item'
import ScoreThresholdItem from '@/app/components/base/param-item/score-threshold-item'
import RadioCard from '@/app/components/base/radio-card/simple'
@ -16,13 +18,20 @@ import {
import type {
DatasetConfigs ,
} from '@/models/debug'
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 type { ModelConfig } from '@/app/components/workflow/types'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type {
DataSet ,
WeightedScoreEnum ,
} from '@/models/datasets'
import { RerankingModeEnum } from '@/models/datasets'
import cn from '@/utils/classnames'
import { useSelectedDatasetsMode } from '@/app/components/workflow/nodes/knowledge-retrieval/hooks'
import Switch from '@/app/components/base/switch'
type Props = {
datasetConfigs : DatasetConfigs
@ -31,6 +40,7 @@ type Props = {
singleRetrievalModelConfig? : ModelConfig
onSingleRetrievalModelChange ? : ( config : ModelConfig ) = > void
onSingleRetrievalModelParamsChange ? : ( config : ModelConfig ) = > void
selectedDatasets? : DataSet [ ]
}
const ConfigContent : FC < Props > = ( {
@ -40,8 +50,10 @@ const ConfigContent: FC<Props> = ({
singleRetrievalModelConfig : singleRetrievalConfig = { } as ModelConfig ,
onSingleRetrievalModelChange = ( ) = > { } ,
onSingleRetrievalModelParamsChange = ( ) = > { } ,
selectedDatasets = [ ] ,
} ) = > {
const { t } = useTranslation ( )
const selectedDatasetsMode = useSelectedDatasetsMode ( selectedDatasets )
const type = datasetConfigs . retrieval_model
const setType = ( value : RETRIEVE_TYPE ) = > {
onChange ( {
@ -54,7 +66,7 @@ const ConfigContent: FC<Props> = ({
defaultModel : rerankDefaultModel ,
} = useModelListAndDefaultModelAndCurrentProviderAndModel ( ModelTypeEnum . rerank )
const rerankModel = ( ( ) = > {
if ( datasetConfigs . reranking_model ) {
if ( datasetConfigs . reranking_model ? . reranking_provider_name ) {
return {
provider_name : datasetConfigs.reranking_model.reranking_provider_name ,
model_name : datasetConfigs.reranking_model.reranking_model_name ,
@ -93,14 +105,73 @@ const ConfigContent: FC<Props> = ({
} )
}
const handleWeightedScoreChange = ( value : { type : WeightedScoreEnum ; value : number [ ] } ) = > {
const configs = {
. . . datasetConfigs ,
weights : {
. . . datasetConfigs . weights ! ,
weight_type : value.type ,
vector_setting : {
. . . datasetConfigs . weights ! . vector_setting ! ,
vector_weight : value.value [ 0 ] ,
} ,
keyword_setting : {
keyword_weight : value.value [ 1 ] ,
} ,
} ,
}
onChange ( configs )
}
const handleRerankModeChange = ( mode : RerankingModeEnum ) = > {
onChange ( {
. . . datasetConfigs ,
reranking_mode : mode ,
} )
}
const model = singleRetrievalConfig
const rerankingModeOptions = [
{
value : RerankingModeEnum.WeightedScore ,
label : t ( 'dataset.weightedScore.title' ) ,
tips : t ( 'dataset.weightedScore.description' ) ,
} ,
{
value : RerankingModeEnum.RerankingModel ,
label : t ( 'common.modelProvider.rerankModel.key' ) ,
tips : t ( 'common.modelProvider.rerankModel.tip' ) ,
} ,
]
const showWeightedScore = selectedDatasetsMode . allHighQuality
&& ! selectedDatasetsMode . inconsistentEmbeddingModel
const showWeightedScorePanel = showWeightedScore && datasetConfigs . reranking_mode === RerankingModeEnum . WeightedScore && datasetConfigs . weights
const selectedRerankMode = datasetConfigs . reranking_mode || RerankingModeEnum . RerankingModel
const showRerankModel = useMemo ( ( ) = > {
if ( datasetConfigs . reranking_enable === false && selectedDatasetsMode . allEconomic )
return false
return true
} , [ datasetConfigs . reranking_enable , selectedDatasetsMode . allEconomic ] )
return (
< div >
< div className = 'system-xl-semibold text-text-primary' > { t ( 'dataset.retrievalSettings' ) } < / div >
< div className = 'mt-2 space-y-3' >
< RadioCard
icon = { < NTo1Retrieval className = 'shrink-0 mr-3 w-9 h-9 rounded-lg' / > }
title = { t ( 'appDebug.datasetConfig.retrieveOneWay.title' ) }
title = { (
< div className = 'flex items-center' >
{ t ( 'appDebug.datasetConfig.retrieveOneWay.title' ) }
< TooltipPlus popupContent = { < div className = 'w-[320px]' > { t ( 'dataset.nTo1RetrievalLegacy' ) } < / div > } >
< div className = 'ml-1 flex items-center px-[5px] h-[18px] rounded-[5px] border border-text-accent-secondary system-2xs-medium-uppercase text-text-accent-secondary' > legacy < / div >
< / TooltipPlus >
< / div >
) }
description = { t ( 'appDebug.datasetConfig.retrieveOneWay.description' ) }
isChosen = { type === RETRIEVE_TYPE . oneWay }
onChosen = { ( ) = > { setType ( RETRIEVE_TYPE . oneWay ) } }
@ -115,43 +186,152 @@ const ConfigContent: FC<Props> = ({
< / div >
{ type === RETRIEVE_TYPE . multiWay && (
< >
< div className = 'mt-6' >
< div className = 'leading-[32px] text-[13px] font-medium text-gray-900' > { t ( 'common.modelProvider.rerankModel.key' ) } < / div >
< div >
< ModelSelector
defaultModel = { rerankModel && { provider : rerankModel?.provider_name , model : rerankModel?.model_name } }
onSelect = { ( v ) = > {
onChange ( {
. . . datasetConfigs ,
reranking_model : {
reranking_provider_name : v.provider ,
reranking_model_name : v.model ,
} ,
} )
} }
modelList = { rerankModelList }
/ >
< / div >
< / div >
< div className = 'mt-4 space-y-4' >
< TopKItem
value = { datasetConfigs . top_k }
onChange = { handleParamChange }
enable = { true }
/ >
< ScoreThresholdItem
value = { datasetConfigs . score_threshold as number }
onChange = { handleParamChange }
enable = { datasetConfigs . score_threshold_enabled }
hasSwitch = { true }
onSwitchChange = { handleSwitch }
/ >
< div className = 'mb-2 mt-4 h-[1px] bg-divider-subtle' > < / div >
< div
className = 'flex items-center mb-2 h-6 system-md-semibold text-text-secondary'
>
{ t ( 'dataset.rerankSettings' ) }
< / div >
{
selectedDatasetsMode . inconsistentEmbeddingModel
&& (
< div className = 'mt-4 system-xs-regular text-text-warning' >
{ t ( 'dataset.inconsistentEmbeddingModelTip' ) }
< / div >
)
}
{
selectedDatasetsMode . mixtureHighQualityAndEconomic
&& (
< div className = 'mt-4 system-xs-regular text-text-warning' >
{ t ( 'dataset.mixtureHighQualityAndEconomicTip' ) }
< / div >
)
}
{
showWeightedScore && (
< div className = 'flex items-center justify-between' >
{
rerankingModeOptions . map ( option = > (
< div
key = { option . value }
className = { cn (
'flex items-center justify-center w-[calc((100%-8px)/2)] h-8 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg cursor-pointer system-sm-medium text-text-secondary' ,
selectedRerankMode === option . value && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary' ,
) }
onClick = { ( ) = > handleRerankModeChange ( option . value ) }
>
< div className = 'truncate' > { option . label } < / div >
< TooltipPlus
popupContent = { < div className = 'w-[200px]' > { option . tips } < / div > }
hideArrow
>
< RiQuestionLine className = 'ml-0.5 w-3.5 h-4.5 text-text-quaternary' / >
< / TooltipPlus >
< / div >
) )
}
< / div >
)
}
{
! showWeightedScorePanel && (
< div className = 'mt-2' >
< div className = 'flex items-center' >
{
selectedDatasetsMode . allEconomic && (
< Switch
size = 'md'
defaultValue = { showRerankModel }
onChange = { ( v ) = > {
onChange ( {
. . . datasetConfigs ,
reranking_enable : v ,
} )
} }
/ >
)
}
< div className = 'ml-2 leading-[32px] text-[13px] font-medium text-gray-900' > { t ( 'common.modelProvider.rerankModel.key' ) } < / div >
< TooltipPlus popupContent = { < div className = "w-[200px]" > { t ( 'common.modelProvider.rerankModel.tip' ) } < / div > } >
< RiQuestionLine className = 'ml-0.5 w-[14px] h-[14px] text-gray-400' / >
< / TooltipPlus >
< / div >
< div >
< ModelSelector
defaultModel = { rerankModel && { provider : rerankModel?.provider_name , model : rerankModel?.model_name } }
onSelect = { ( v ) = > {
onChange ( {
. . . datasetConfigs ,
reranking_model : {
reranking_provider_name : v.provider ,
reranking_model_name : v.model ,
} ,
} )
} }
modelList = { rerankModelList }
/ >
< / div >
< / div >
)
}
{
showWeightedScorePanel
&& (
< div className = 'mt-2 space-y-4' >
< WeightedScore
value = { {
type : datasetConfigs . weights ! . weight_type ,
value : [
datasetConfigs . weights ! . vector_setting . vector_weight ,
datasetConfigs . weights ! . keyword_setting . keyword_weight ,
] ,
} }
onChange = { handleWeightedScoreChange }
/ >
< TopKItem
value = { datasetConfigs . top_k }
onChange = { handleParamChange }
enable = { true }
/ >
< ScoreThresholdItem
value = { datasetConfigs . score_threshold as number }
onChange = { handleParamChange }
enable = { datasetConfigs . score_threshold_enabled }
hasSwitch = { true }
onSwitchChange = { handleSwitch }
/ >
< / div >
)
}
{
! showWeightedScorePanel
&& (
< div className = 'mt-4 space-y-4' >
< TopKItem
value = { datasetConfigs . top_k }
onChange = { handleParamChange }
enable = { true }
/ >
{
showRerankModel && (
< ScoreThresholdItem
value = { datasetConfigs . score_threshold as number }
onChange = { handleParamChange }
enable = { datasetConfigs . score_threshold_enabled }
hasSwitch = { true }
onSwitchChange = { handleSwitch }
/ >
)
}
< / div >
)
}
< / >
) }
{ isInWorkflow && type === RETRIEVE_TYPE . oneWay && (
< div className = 'mt-6' >
< div className = 'mt- 4 '>
< div className = 'flex items-center space-x-0.5' >
< div className = 'leading-[32px] text-[13px] font-medium text-gray-900' > { t ( 'common.modelProvider.systemReasoningModel.key' ) } < / div >
< TooltipPlus
@ -180,4 +360,4 @@ const ConfigContent: FC<Props> = ({
< / d i v >
)
}
export default React. memo( ConfigContent )
export default memo( ConfigContent )