diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index fd5c0f016..c990b8b8d 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1710,12 +1710,12 @@ This delimiter is used to split the input text into several text pieces echo of tokenizerRequired: 'Please add the Indexer node first', tokenizerDescription: 'Transforms text into the required data structure (e.g., vector embeddings for Embedding Search) depending on the chosen search method.', - splitter: 'Token Splitter', + splitter: 'Token', splitterDescription: 'Split text into chunks by token length with optional delimiters and overlap.', hierarchicalMergerDescription: 'Split documents into sections by title hierarchy with regex rules for finer control.', - hierarchicalMerger: 'Title Splitter', + hierarchicalMerger: 'Title', extractor: 'Transformer', extractorDescription: 'Use an LLM to extract structured insights from document chunks—such as summaries, classifications, etc.', diff --git a/web/src/pages/data-flow/canvas/node/dropdown/next-step-dropdown.tsx b/web/src/pages/data-flow/canvas/node/dropdown/next-step-dropdown.tsx index 2450de579..2e8c8c30f 100644 --- a/web/src/pages/data-flow/canvas/node/dropdown/next-step-dropdown.tsx +++ b/web/src/pages/data-flow/canvas/node/dropdown/next-step-dropdown.tsx @@ -1,3 +1,9 @@ +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from '@/components/ui/accordion'; import { DropdownMenu, DropdownMenuContent, @@ -19,12 +25,13 @@ import { PropsWithChildren, createContext, memo, + useCallback, useContext, useEffect, useMemo, useRef, } from 'react'; -import { Operator, SingleOperators } from '../../../constant'; +import { Operator } from '../../../constant'; import { AgentInstanceContext, HandleContext } from '../../../context'; import OperatorIcon from '../../../operator-icon'; @@ -116,16 +123,22 @@ function OperatorItemList({ // Limit the number of operators of a certain type on the canvas to only one function useRestrictSingleOperatorOnCanvas() { - const list: Operator[] = []; const { findNodeByName } = useGraphStore((state) => state); - SingleOperators.forEach((operator) => { - if (!findNodeByName(operator)) { - list.push(operator); - } - }); + const restrictSingleOperatorOnCanvas = useCallback( + (singleOperators: Operator[]) => { + const list: Operator[] = []; + singleOperators.forEach((operator) => { + if (!findNodeByName(operator)) { + list.push(operator); + } + }); + return list; + }, + [findNodeByName], + ); - return list; + return restrictSingleOperatorOnCanvas; } function AccordionOperators({ @@ -137,25 +150,60 @@ function AccordionOperators({ mousePosition?: { x: number; y: number }; nodeId?: string; }) { - const singleOperators = useRestrictSingleOperatorOnCanvas(); + const restrictSingleOperatorOnCanvas = useRestrictSingleOperatorOnCanvas(); const { getOperatorTypeFromId } = useGraphStore((state) => state); const operators = useMemo(() => { - let list = [...singleOperators]; - if (getOperatorTypeFromId(nodeId) === Operator.Extractor) { - const Splitters = [Operator.HierarchicalMerger, Operator.Splitter]; - list = list.filter((x) => !Splitters.includes(x)); // The Context Generator node can only be followed by a Tokenizer and a Context Generator. - } + let list = [ + ...restrictSingleOperatorOnCanvas([Operator.Parser, Operator.Tokenizer]), + ]; list.push(Operator.Extractor); return list; - }, [getOperatorTypeFromId, nodeId, singleOperators]); + }, [restrictSingleOperatorOnCanvas]); + + const chunkerOperators = useMemo(() => { + return [ + ...restrictSingleOperatorOnCanvas([ + Operator.Splitter, + Operator.HierarchicalMerger, + ]), + ]; + }, [restrictSingleOperatorOnCanvas]); + + const showChunker = useMemo(() => { + return ( + getOperatorTypeFromId(nodeId) !== Operator.Extractor && + chunkerOperators.length > 0 + ); + }, [chunkerOperators.length, getOperatorTypeFromId, nodeId]); return ( - + <> + + {showChunker && ( + + + Chunker + + + + + + )} + ); }