import type { FC } from 'react' import type { KnowledgeBaseNodeType } from './types' import type { NodePanelProps, Var } from '@/app/components/workflow/types' import { useQuery } from '@tanstack/react-query' import { memo, useCallback, useMemo, } from 'react' import { useTranslation } from 'react-i18next' import SummaryIndexSetting from '@/app/components/datasets/settings/summary-index-setting' import { checkShowMultiModalTip } from '@/app/components/datasets/settings/utils' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks' import { useNodesReadOnly } from '@/app/components/workflow/hooks' import { BoxGroup, BoxGroupField, Group, } from '@/app/components/workflow/nodes/_base/components/layout' import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' import { IS_CE_EDITION } from '@/config' import { consoleQuery } from '@/service/client' import Split from '../_base/components/split' import ChunkStructure from './components/chunk-structure' import EmbeddingModel from './components/embedding-model' import IndexMethod from './components/index-method' import RetrievalSetting from './components/retrieval-setting' import { useConfig } from './hooks/use-config' import { useEmbeddingModelStatus } from './hooks/use-embedding-model-status' import { ChunkStructureEnum, IndexMethodEnum, } from './types' import { getKnowledgeBaseValidationIssue, KnowledgeBaseValidationIssueCode, } from './utils' const Panel: FC> = ({ id, data, }) => { const { t } = useTranslation() const { nodesReadOnly } = useNodesReadOnly() const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding) const { data: rerankModelList } = useModelList(ModelTypeEnum.rerank) const chunkStructure = data.chunk_structure const indexChunkVariableSelector = data.index_chunk_variable_selector const indexingTechnique = data.indexing_technique const embeddingModel = data.embedding_model const retrievalModel = data.retrieval_model const retrievalSearchMethod = retrievalModel?.search_method const retrievalRerankingEnable = retrievalModel?.reranking_enable const embeddingModelProvider = data.embedding_model_provider const { data: embeddingProviderModelList } = useQuery( consoleQuery.modelProviders.models.queryOptions({ input: { params: { provider: embeddingModelProvider || '' } }, enabled: indexingTechnique === IndexMethodEnum.QUALIFIED && !!embeddingModelProvider, refetchOnWindowFocus: false, select: response => response.data, }), ) const { handleChunkStructureChange, handleIndexMethodChange, handleKeywordNumberChange, handleEmbeddingModelChange, handleRetrievalSearchMethodChange, handleHybridSearchModeChange, handleRerankingModelEnabledChange, handleWeighedScoreChange, handleRerankingModelChange, handleTopKChange, handleScoreThresholdChange, handleScoreThresholdEnabledChange, handleInputVariableChange, handleSummaryIndexSettingChange, } = useConfig(id) const filterVar = useCallback((variable: Var) => { if (!data.chunk_structure) return false switch (data.chunk_structure) { case ChunkStructureEnum.general: return variable.schemaType === 'general_structure' || variable.schemaType === 'multimodal_general_structure' case ChunkStructureEnum.parent_child: return variable.schemaType === 'parent_child_structure' || variable.schemaType === 'multimodal_parent_child_structure' case ChunkStructureEnum.question_answer: return variable.schemaType === 'qa_structure' default: return false } }, [data.chunk_structure]) const chunkTypePlaceHolder = useMemo(() => { if (!data.chunk_structure) return '' let placeholder = '' switch (data.chunk_structure) { case ChunkStructureEnum.general: placeholder = '(multimodal_)general_structure' break case ChunkStructureEnum.parent_child: placeholder = '(multimodal_)parent_child_structure' break case ChunkStructureEnum.question_answer: placeholder = 'qa_structure' break default: return '' } return placeholder.charAt(0).toUpperCase() + placeholder.slice(1) }, [data.chunk_structure]) const showMultiModalTip = useMemo(() => { return checkShowMultiModalTip({ embeddingModel: { provider: data.embedding_model_provider ?? '', model: data.embedding_model ?? '', }, rerankingEnable: !!data.retrieval_model?.reranking_enable, rerankModel: { rerankingProviderName: data.retrieval_model?.reranking_model?.reranking_provider_name ?? '', rerankingModelName: data.retrieval_model?.reranking_model?.reranking_model_name ?? '', }, indexMethod: data.indexing_technique, embeddingModelList, rerankModelList, }) }, [data.embedding_model_provider, data.embedding_model, data.retrieval_model?.reranking_enable, data.retrieval_model?.reranking_model, data.indexing_technique, embeddingModelList, rerankModelList]) const validationPayload = useMemo(() => { return { chunk_structure: chunkStructure, index_chunk_variable_selector: indexChunkVariableSelector, indexing_technique: indexingTechnique, embedding_model: embeddingModel, embedding_model_provider: embeddingModelProvider, retrieval_model: { search_method: retrievalSearchMethod, reranking_enable: retrievalRerankingEnable, reranking_model: retrievalModel?.reranking_model, }, _embeddingModelList: embeddingModelList, _embeddingProviderModelList: embeddingProviderModelList, _rerankModelList: rerankModelList, } }, [ chunkStructure, indexChunkVariableSelector, indexingTechnique, embeddingModel, embeddingModelProvider, retrievalSearchMethod, retrievalRerankingEnable, retrievalModel?.reranking_model, embeddingModelList, embeddingProviderModelList, rerankModelList, ]) const validationIssue = useMemo(() => { return getKnowledgeBaseValidationIssue(validationPayload) }, [validationPayload]) const { status: embeddingModelStatus } = useEmbeddingModelStatus({ embeddingModel, embeddingModelProvider, embeddingModelList, }) const chunkStructureWarning = validationIssue?.code === KnowledgeBaseValidationIssueCode.chunkStructureRequired const chunksInputWarning = validationIssue?.code === KnowledgeBaseValidationIssueCode.chunksVariableRequired const embeddingModelWarning = indexingTechnique === IndexMethodEnum.QUALIFIED && embeddingModelStatus !== 'active' return (
{ !!data.chunk_structure && ( <>
{ data.indexing_technique === IndexMethodEnum.QUALIFIED && ( ) }
{ data.indexing_technique === IndexMethodEnum.QUALIFIED && [ChunkStructureEnum.general, ChunkStructureEnum.parent_child].includes(data.chunk_structure) && IS_CE_EDITION && ( <>
) }
) }
) } export default memo(Panel)