From 7bce35913d9a79748d810e22a7748babdf105e0e Mon Sep 17 00:00:00 2001 From: zxhlyh Date: Mon, 19 May 2025 18:08:27 +0800 Subject: [PATCH] i18n --- .../components/chunk-structure/constants.ts | 0 .../components/chunk-structure/hooks.tsx | 10 +-- .../components/embedding-model.tsx | 32 +++++----- .../components/index-method.tsx | 2 +- .../knowledge-base/components/option-card.tsx | 4 +- .../components/retrieval-setting/hooks.tsx | 38 ++++++------ .../components/retrieval-setting/index.tsx | 18 +++--- .../search-method-option.tsx | 62 +++++++++++++++++-- .../top-k-and-score-threshold.tsx | 56 ++++++++++------- .../workflow/nodes/knowledge-base/node.tsx | 6 +- 10 files changed, 149 insertions(+), 79 deletions(-) delete mode 100644 web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/constants.ts diff --git a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/constants.ts b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/constants.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/hooks.tsx b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/hooks.tsx index 3c5189b49f..cfb8210a86 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/hooks.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/chunk-structure/hooks.tsx @@ -1,3 +1,4 @@ +import { useTranslation } from 'react-i18next' import { GeneralChunk, ParentChildChunk, @@ -8,6 +9,7 @@ import { ChunkStructureEnum } from '../../types' import type { Option } from './type' export const useChunkStructure = () => { + const { t } = useTranslation() const GeneralOption: Option = { id: ChunkStructureEnum.general, icon: (isActive: boolean) => ( @@ -17,8 +19,8 @@ export const useChunkStructure = () => { isActive && 'text-util-colors-indigo-indigo-600', )} /> ), - title: 'General', - description: 'General text chunking mode, the chunks retrieved and recalled are the same.', + title: t('datasetCreation.stepTwo.general'), + description: t('datasetCreation.stepTwo.generalTip'), effectColor: 'blue', } const ParentChildOption: Option = { @@ -31,8 +33,8 @@ export const useChunkStructure = () => { )} /> ), - title: 'Parent-Child', - description: 'Parent-child text chunking mode, the chunks retrieved and recalled are different.', + title: t('datasetCreation.stepTwo.parentChild'), + description: t('datasetCreation.stepTwo.parentChildTip'), effectColor: 'blue-light', } const QuestionAnswerOption: Option = { diff --git a/web/app/components/workflow/nodes/knowledge-base/components/embedding-model.tsx b/web/app/components/workflow/nodes/knowledge-base/components/embedding-model.tsx index b90e2cdf16..77c4368128 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/embedding-model.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/embedding-model.tsx @@ -2,6 +2,7 @@ import { memo, useMemo, } from 'react' +import { useTranslation } from 'react-i18next' import { Field } from '@/app/components/workflow/nodes/_base/components/layout' import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' import { useModelListAndDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' @@ -23,30 +24,31 @@ const EmbeddingModel = ({ onEmbeddingModelChange, readonly = false, }: EmbeddingModelProps) => { + const { t } = useTranslation() const { modelList: embeddingModelList, } = useModelListAndDefaultModel(ModelTypeEnum.textEmbedding) -const embeddingModelConfig = useMemo(() => { - if (!embeddingModel || !embeddingModelProvider) - return undefined + const embeddingModelConfig = useMemo(() => { + if (!embeddingModel || !embeddingModelProvider) + return undefined - return { - providerName: embeddingModelProvider, - modelName: embeddingModel, + return { + providerName: embeddingModelProvider, + modelName: embeddingModel, + } + }, [embeddingModel, embeddingModelProvider]) + + const handleRerankingModelChange = (model: DefaultModel) => { + onEmbeddingModelChange?.({ + embeddingModelProvider: model.provider, + embeddingModel: model.model, + }) } -}, [embeddingModel, embeddingModelProvider]) - -const handleRerankingModelChange = (model: DefaultModel) => { - onEmbeddingModelChange?.({ - embeddingModelProvider: model.provider, - embeddingModel: model.model, - }) -} return (
diff --git a/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx b/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx index 59e3e5cee2..69f67300a3 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/option-card.tsx @@ -3,6 +3,7 @@ import { memo, useMemo, } from 'react' +import { useTranslation } from 'react-i18next' import cn from '@/utils/classnames' import Badge from '@/app/components/base/badge' import { @@ -53,6 +54,7 @@ const OptionCard = memo(({ onClick, readonly, }) => { + const { t } = useTranslation() const isActive = useMemo(() => { return id === selectedId }, [id, selectedId]) @@ -103,7 +105,7 @@ const OptionCard = memo(({ { isRecommended && ( - Recommend + {t('datasetCreation.stepTwo.recommend')} ) } diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/hooks.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/hooks.tsx index 53d16be61a..34d1269d8c 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/hooks.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/hooks.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { FullTextSearch, HybridSearch, @@ -15,57 +16,58 @@ import type { } from './type' export const useRetrievalSetting = (indexMethod: IndexMethodEnum) => { + const { t } = useTranslation() const VectorSearchOption: Option = useMemo(() => { return { id: RetrievalSearchMethodEnum.semantic, icon: VectorSearch as any, - title: 'Vector Search', - description: 'Generate query embeddings and search for the text chunk most similar to its vector representation.', + title: t('dataset.retrieval.semantic_search.title'), + description: t('dataset.retrieval.semantic_search.description'), effectColor: 'purple', } - }, []) + }, [t]) const FullTextSearchOption: Option = useMemo(() => { return { id: RetrievalSearchMethodEnum.fullText, icon: FullTextSearch as any, - title: 'Full-Text Search', - description: 'Execute full-text search and vector searches simultaneously, re-rank to select the best match for the user\'s query. Users can choose to set weights or configure to a Rerank model.', + title: t('dataset.retrieval.full_text_search.title'), + description: t('dataset.retrieval.full_text_search.description'), effectColor: 'purple', } - }, []) + }, [t]) const HybridSearchOption: Option = useMemo(() => { return { id: RetrievalSearchMethodEnum.hybrid, icon: HybridSearch as any, - title: 'Hybrid Search', - description: 'Execute full-text search and vector searches simultaneously, re-rank to select the best match for the user\'s query. Users can choose to set weights or configure to a Rerank model.', + title: t('dataset.retrieval.hybrid_search.title'), + description: t('dataset.retrieval.hybrid_search.description'), effectColor: 'purple', } - }, []) + }, [t]) const InvertedIndexOption: Option = useMemo(() => { return { id: RetrievalSearchMethodEnum.invertedIndex, icon: HybridSearch as any, - title: 'Inverted Index', - description: 'Use inverted index to search for the most relevant text chunks.', + title: t('dataset.retrieval.invertedIndex.title'), + description: t('dataset.retrieval.invertedIndex.description'), effectColor: 'purple', } - }, []) + }, [t]) const WeightedScoreModeOption: HybridSearchModeOption = useMemo(() => { return { id: HybridSearchModeEnum.WeightedScore, - title: 'Weighted Score', - description: 'By adjusting the weights assigned, this rerank strategy determines whether to prioritize semantic or keyword matching.', + title: t('dataset.weightedScore.title'), + description: t('dataset.weightedScore.description'), } - }, []) + }, [t]) const RerankModelModeOption: HybridSearchModeOption = useMemo(() => { return { id: HybridSearchModeEnum.RerankingModel, - title: 'Rerank Model', - description: 'Rerank model will reorder the candidate document list based on the semantic match with user query, improving the results of semantic ranking.', + title: t('common.modelProvider.rerankModel.key'), + description: t('common.modelProvider.rerankModel.tip'), } - }, []) + }, [t]) return useMemo(() => ({ options: indexMethod === IndexMethodEnum.ECONOMICAL ? [ diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/index.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/index.tsx index 8bc82509c1..70693b1eae 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/index.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/index.tsx @@ -1,6 +1,7 @@ import { memo, } from 'react' +import { useTranslation } from 'react-i18next' import { Field } from '@/app/components/workflow/nodes/_base/components/layout' import type { HybridSearchModeEnum, @@ -22,6 +23,8 @@ type RetrievalSettingProps = { onRetrievalSearchMethodChange: (value: RetrievalSearchMethodEnum) => void hybridSearchMode: HybridSearchModeEnum onHybridSearchModeChange: (value: HybridSearchModeEnum) => void + rerankingModelEnabled?: boolean + onRerankingModelEnabledChange?: (value: boolean) => void weightedScore?: WeightedScore onWeightedScoreChange: (value: { value: number[] }) => void } & RerankingModelSelectorProps & TopKAndScoreThresholdProps @@ -35,6 +38,8 @@ const RetrievalSetting = ({ onHybridSearchModeChange, weightedScore, onWeightedScoreChange, + rerankingModelEnabled, + onRerankingModelEnabledChange, rerankingModel, onRerankingModelChange, topK, @@ -44,6 +49,7 @@ const RetrievalSetting = ({ isScoreThresholdEnabled, onScoreThresholdEnabledChange, }: RetrievalSettingProps) => { + const { t } = useTranslation() const { options, hybridSearchModeOptions, @@ -52,16 +58,10 @@ const RetrievalSetting = ({ return ( - - Learn more - + {t('datasetSettings.form.retrievalSetting.learnMore')}   about retrieval method.
@@ -87,6 +87,8 @@ const RetrievalSetting = ({ onScoreThresholdChange={onScoreThresholdChange} isScoreThresholdEnabled={isScoreThresholdEnabled} onScoreThresholdEnabledChange={onScoreThresholdEnabledChange} + rerankingModelEnabled={rerankingModelEnabled} + onRerankingModelEnabledChange={onRerankingModelEnabledChange} rerankingModel={rerankingModel} onRerankingModelChange={onRerankingModelChange} readonly={readonly} diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx index 6991a63468..ae497cf828 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/search-method-option.tsx @@ -3,9 +3,12 @@ import { useCallback, useMemo, } from 'react' +import { useTranslation } from 'react-i18next' import cn from '@/utils/classnames' import WeightedScoreComponent from '@/app/components/app/configuration/dataset-config/params-config/weighted-score' import { DEFAULT_WEIGHTED_SCORE } from '@/models/datasets' +import Switch from '@/app/components/base/switch' +import Tooltip from '@/app/components/base/tooltip' import { HybridSearchModeEnum, RetrievalSearchMethodEnum, @@ -33,6 +36,8 @@ type SearchMethodOptionProps = { onHybridSearchModeChange: (value: HybridSearchModeEnum) => void weightedScore?: WeightedScore onWeightedScoreChange: (value: { value: number[] }) => void + rerankingModelEnabled?: boolean + onRerankingModelEnabledChange?: (value: boolean) => void } & RerankingModelSelectorProps & TopKAndScoreThresholdProps const SearchMethodOption = ({ readonly, @@ -44,6 +49,8 @@ const SearchMethodOption = ({ onHybridSearchModeChange, weightedScore, onWeightedScoreChange, + rerankingModelEnabled, + onRerankingModelEnabledChange, rerankingModel, onRerankingModelChange, topK, @@ -53,6 +60,7 @@ const SearchMethodOption = ({ isScoreThresholdEnabled, onScoreThresholdEnabledChange, }: SearchMethodOptionProps) => { + const { t } = useTranslation() const Icon = option.icon const isHybridSearch = option.id === RetrievalSearchMethodEnum.hybrid const isHybridSearchWeightedScoreMode = hybridSearchMode === HybridSearchModeEnum.WeightedScore @@ -82,6 +90,28 @@ const SearchMethodOption = ({ return isActive ? 'border-[1.5px] bg-components-option-card-option-selected-bg' : '' }, []) + const showRerankModelSelectorSwitch = useMemo(() => { + if (searchMethod === RetrievalSearchMethodEnum.semantic) + return true + + if (searchMethod === RetrievalSearchMethodEnum.fullText) + return true + + return false + }, [searchMethod]) + const showRerankModelSelector = useMemo(() => { + if (searchMethod === RetrievalSearchMethodEnum.semantic) + return true + + if (searchMethod === RetrievalSearchMethodEnum.fullText) + return true + + if (searchMethod === RetrievalSearchMethodEnum.hybrid && hybridSearchMode !== HybridSearchModeEnum.WeightedScore) + return true + + return false + }, [hybridSearchMode, searchMethod]) + return ( + showRerankModelSelector && ( +
+ { + showRerankModelSelectorSwitch && ( +
+ + {t('common.modelProvider.rerankModel.key')} + +
+ ) + } + +
) }
diff --git a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx index aac2439689..9d46037d84 100644 --- a/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/components/retrieval-setting/top-k-and-score-threshold.tsx @@ -1,4 +1,5 @@ import { memo } from 'react' +import { useTranslation } from 'react-i18next' import Tooltip from '@/app/components/base/tooltip' import Input from '@/app/components/base/input' import Switch from '@/app/components/base/switch' @@ -11,6 +12,7 @@ export type TopKAndScoreThresholdProps = { isScoreThresholdEnabled?: boolean onScoreThresholdEnabledChange?: (value: boolean) => void readonly?: boolean + hiddenScoreThreshold?: boolean } const TopKAndScoreThreshold = ({ topK, @@ -20,7 +22,9 @@ const TopKAndScoreThreshold = ({ isScoreThresholdEnabled, onScoreThresholdEnabledChange, readonly, + hiddenScoreThreshold, }: TopKAndScoreThresholdProps) => { + const { t } = useTranslation() const handleTopKChange = (e: React.ChangeEvent) => { const value = Number(e.target.value) if (Number.isNaN(value)) @@ -39,10 +43,10 @@ const TopKAndScoreThreshold = ({
- Top k + {t('appDebug.datasetConfig.top_k')}
-
-
- -
- Score Threshold + { + !hiddenScoreThreshold && ( +
+
+ +
+ {t('appDebug.datasetConfig.score_threshold')} +
+ +
+
- -
- -
+ ) + }
) } diff --git a/web/app/components/workflow/nodes/knowledge-base/node.tsx b/web/app/components/workflow/nodes/knowledge-base/node.tsx index 8390141f46..854f104c03 100644 --- a/web/app/components/workflow/nodes/knowledge-base/node.tsx +++ b/web/app/components/workflow/nodes/knowledge-base/node.tsx @@ -1,17 +1,19 @@ import type { FC } from 'react' import { memo } from 'react' +import { useTranslation } from 'react-i18next' import type { KnowledgeBaseNodeType } from './types' import type { NodeProps } from '@/app/components/workflow/types' const Node: FC> = ({ data }) => { + const { t } = useTranslation() return (
-
Index method
+
{t('datasetCreation.stepTwo.indexMode')}
{data.indexing_technique}
-
Retrieval Method
+
{t('datasetSettings.form.retrievalSetting.title')}
{data.retrieval_model.search_method}