mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
Fix: The Context Generator(Transformer) node can only be followed by a Tokenizer(Indexer) and a Context Generator(Transformer). #9869 (#10515)
### What problem does this PR solve? Fix: The Context Generator node can only be followed by a Tokenizer and a Context Generator. #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -98,7 +98,7 @@ export function FileUploadDialog({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open onOpenChange={hideModal}>
|
<Dialog open onOpenChange={hideModal}>
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
<DialogContent>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{t('fileManager.uploadFile')}</DialogTitle>
|
<DialogTitle>{t('fileManager.uploadFile')}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|||||||
@ -1703,8 +1703,8 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
parser: 'Parser',
|
parser: 'Parser',
|
||||||
parserDescription:
|
parserDescription:
|
||||||
'Extracts raw text and structure from files for downstream processing.',
|
'Extracts raw text and structure from files for downstream processing.',
|
||||||
tokenizer: 'Tokenizer',
|
tokenizer: 'Indexer',
|
||||||
tokenizerRequired: 'Please add the Tokenizer node first',
|
tokenizerRequired: 'Please add the Indexer node first',
|
||||||
tokenizerDescription:
|
tokenizerDescription:
|
||||||
'Transforms text into the required data structure (e.g., vector embeddings for Embedding Search) depending on the chosen search method.',
|
'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 Splitter',
|
||||||
@ -1713,7 +1713,7 @@ This delimiter is used to split the input text into several text pieces echo of
|
|||||||
hierarchicalMergerDescription:
|
hierarchicalMergerDescription:
|
||||||
'Split documents into sections by title hierarchy with regex rules for finer control.',
|
'Split documents into sections by title hierarchy with regex rules for finer control.',
|
||||||
hierarchicalMerger: 'Title Splitter',
|
hierarchicalMerger: 'Title Splitter',
|
||||||
extractor: 'Context Generator',
|
extractor: 'Transformer',
|
||||||
extractorDescription:
|
extractorDescription:
|
||||||
'Use an LLM to extract structured insights from document chunks—such as summaries, classifications, etc.',
|
'Use an LLM to extract structured insights from document chunks—such as summaries, classifications, etc.',
|
||||||
outputFormat: 'Output format',
|
outputFormat: 'Output format',
|
||||||
|
|||||||
@ -292,6 +292,7 @@ function DataFlowCanvas({ drawerVisible, hideDrawer, showLogSheet }: IProps) {
|
|||||||
clearActiveDropdown();
|
clearActiveDropdown();
|
||||||
}}
|
}}
|
||||||
position={dropdownPosition}
|
position={dropdownPosition}
|
||||||
|
nodeId={connectionStartRef.current?.nodeId || ''}
|
||||||
>
|
>
|
||||||
<span></span>
|
<span></span>
|
||||||
</NextStepDropdown>
|
</NextStepDropdown>
|
||||||
|
|||||||
@ -131,16 +131,24 @@ function useRestrictSingleOperatorOnCanvas() {
|
|||||||
function AccordionOperators({
|
function AccordionOperators({
|
||||||
isCustomDropdown = false,
|
isCustomDropdown = false,
|
||||||
mousePosition,
|
mousePosition,
|
||||||
|
nodeId,
|
||||||
}: {
|
}: {
|
||||||
isCustomDropdown?: boolean;
|
isCustomDropdown?: boolean;
|
||||||
mousePosition?: { x: number; y: number };
|
mousePosition?: { x: number; y: number };
|
||||||
|
nodeId?: string;
|
||||||
}) {
|
}) {
|
||||||
const singleOperators = useRestrictSingleOperatorOnCanvas();
|
const singleOperators = useRestrictSingleOperatorOnCanvas();
|
||||||
|
const { getOperatorTypeFromId } = useGraphStore((state) => state);
|
||||||
|
|
||||||
const operators = useMemo(() => {
|
const operators = useMemo(() => {
|
||||||
const list = [...singleOperators];
|
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.
|
||||||
|
}
|
||||||
list.push(Operator.Extractor);
|
list.push(Operator.Extractor);
|
||||||
return list;
|
return list;
|
||||||
}, [singleOperators]);
|
}, [getOperatorTypeFromId, nodeId, singleOperators]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OperatorItemList
|
<OperatorItemList
|
||||||
@ -151,16 +159,19 @@ function AccordionOperators({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NextStepDropdownProps = PropsWithChildren &
|
||||||
|
IModalProps<any> & {
|
||||||
|
position?: { x: number; y: number };
|
||||||
|
onNodeCreated?: (newNodeId: string) => void;
|
||||||
|
nodeId?: string;
|
||||||
|
};
|
||||||
export function InnerNextStepDropdown({
|
export function InnerNextStepDropdown({
|
||||||
children,
|
children,
|
||||||
hideModal,
|
hideModal,
|
||||||
position,
|
position,
|
||||||
onNodeCreated,
|
onNodeCreated,
|
||||||
}: PropsWithChildren &
|
nodeId,
|
||||||
IModalProps<any> & {
|
}: NextStepDropdownProps) {
|
||||||
position?: { x: number; y: number };
|
|
||||||
onNodeCreated?: (newNodeId: string) => void;
|
|
||||||
}) {
|
|
||||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -200,6 +211,7 @@ export function InnerNextStepDropdown({
|
|||||||
<AccordionOperators
|
<AccordionOperators
|
||||||
isCustomDropdown={true}
|
isCustomDropdown={true}
|
||||||
mousePosition={position}
|
mousePosition={position}
|
||||||
|
nodeId={nodeId}
|
||||||
></AccordionOperators>
|
></AccordionOperators>
|
||||||
</OnNodeCreatedContext.Provider>
|
</OnNodeCreatedContext.Provider>
|
||||||
</HideModalContext.Provider>
|
</HideModalContext.Provider>
|
||||||
@ -224,7 +236,7 @@ export function InnerNextStepDropdown({
|
|||||||
>
|
>
|
||||||
<DropdownMenuLabel>{t('flow.nextStep')}</DropdownMenuLabel>
|
<DropdownMenuLabel>{t('flow.nextStep')}</DropdownMenuLabel>
|
||||||
<HideModalContext.Provider value={hideModal}>
|
<HideModalContext.Provider value={hideModal}>
|
||||||
<AccordionOperators></AccordionOperators>
|
<AccordionOperators nodeId={nodeId}></AccordionOperators>
|
||||||
</HideModalContext.Provider>
|
</HideModalContext.Provider>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|||||||
@ -61,6 +61,7 @@ export function CommonHandle({
|
|||||||
hideModal();
|
hideModal();
|
||||||
clearActiveDropdown();
|
clearActiveDropdown();
|
||||||
}}
|
}}
|
||||||
|
nodeId={nodeId}
|
||||||
>
|
>
|
||||||
<span></span>
|
<span></span>
|
||||||
</NextStepDropdown>
|
</NextStepDropdown>
|
||||||
|
|||||||
@ -299,7 +299,9 @@ export const initialHierarchicalMergerValues = {
|
|||||||
export const initialExtractorValues = {
|
export const initialExtractorValues = {
|
||||||
...initialLlmBaseValues,
|
...initialLlmBaseValues,
|
||||||
field_name: ContextGeneratorFieldName.Summary,
|
field_name: ContextGeneratorFieldName.Summary,
|
||||||
outputs: {},
|
outputs: {
|
||||||
|
chunks: { type: 'Array<Object>', value: [] },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CategorizeAnchorPointPositions = [
|
export const CategorizeAnchorPointPositions = [
|
||||||
|
|||||||
@ -19,7 +19,9 @@ import { useBuildNodeOutputOptions } from '../../hooks/use-build-options';
|
|||||||
import { useFormValues } from '../../hooks/use-form-values';
|
import { useFormValues } from '../../hooks/use-form-values';
|
||||||
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
|
||||||
import { INextOperatorForm } from '../../interface';
|
import { INextOperatorForm } from '../../interface';
|
||||||
|
import { buildOutputList } from '../../utils/build-output-list';
|
||||||
import { FormWrapper } from '../components/form-wrapper';
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
|
import { Output } from '../components/output';
|
||||||
import { useSwitchPrompt } from './use-switch-prompt';
|
import { useSwitchPrompt } from './use-switch-prompt';
|
||||||
|
|
||||||
export const FormSchema = z.object({
|
export const FormSchema = z.object({
|
||||||
@ -31,6 +33,8 @@ export const FormSchema = z.object({
|
|||||||
|
|
||||||
export type ExtractorFormSchemaType = z.infer<typeof FormSchema>;
|
export type ExtractorFormSchemaType = z.infer<typeof FormSchema>;
|
||||||
|
|
||||||
|
const outputList = buildOutputList(initialExtractorValues.outputs);
|
||||||
|
|
||||||
const ExtractorForm = ({ node }: INextOperatorForm) => {
|
const ExtractorForm = ({ node }: INextOperatorForm) => {
|
||||||
const defaultValues = useFormValues(initialExtractorValues, node);
|
const defaultValues = useFormValues(initialExtractorValues, node);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -85,6 +89,7 @@ const ExtractorForm = ({ node }: INextOperatorForm) => {
|
|||||||
baseOptions={promptOptions}
|
baseOptions={promptOptions}
|
||||||
></PromptEditor>
|
></PromptEditor>
|
||||||
</RAGFlowFormItem>
|
</RAGFlowFormItem>
|
||||||
|
<Output list={outputList}></Output>
|
||||||
</FormWrapper>
|
</FormWrapper>
|
||||||
{visible && (
|
{visible && (
|
||||||
<ConfirmDeleteDialog
|
<ConfirmDeleteDialog
|
||||||
|
|||||||
Reference in New Issue
Block a user