diff --git a/web/src/pages/data-flow/canvas/index.tsx b/web/src/pages/data-flow/canvas/index.tsx index d48bfd68a..fd3b88c50 100644 --- a/web/src/pages/data-flow/canvas/index.tsx +++ b/web/src/pages/data-flow/canvas/index.tsx @@ -44,6 +44,7 @@ import { CategorizeNode } from './node/categorize-node'; import ChunkerNode from './node/chunker-node'; import { InnerNextStepDropdown } from './node/dropdown/next-step-dropdown'; import { GenerateNode } from './node/generate-node'; +import { HierarchicalMergerNode } from './node/hierarchical-merger-node'; import { InvokeNode } from './node/invoke-node'; import { IterationNode, IterationStartNode } from './node/iteration-node'; import { KeywordNode } from './node/keyword-node'; @@ -84,6 +85,7 @@ export const nodeTypes: NodeTypes = { chunkerNode: ChunkerNode, tokenizerNode: TokenizerNode, splitterNode: SplitterNode, + hierarchicalMergerNode: HierarchicalMergerNode, }; const edgeTypes = { diff --git a/web/src/pages/data-flow/constant.tsx b/web/src/pages/data-flow/constant.tsx index 96569cde1..402ff364f 100644 --- a/web/src/pages/data-flow/constant.tsx +++ b/web/src/pages/data-flow/constant.tsx @@ -378,7 +378,7 @@ export const initialStringTransformValues = { export const initialParserValues = { outputs: {}, parser: [] }; -export const initialSplitterValues = {}; +export const initialSplitterValues = { outputs: {}, chunk_token_size: 512 }; export const initialHierarchicalMergerValues = {}; @@ -466,7 +466,7 @@ export const NodeMap = { [Operator.Chunker]: 'chunkerNode', [Operator.Tokenizer]: 'tokenizerNode', [Operator.Splitter]: 'splitterNode', - [Operator.HierarchicalMerger]: 'hierarchicalMergerrNode', + [Operator.HierarchicalMerger]: 'hierarchicalMergerNode', }; export enum BeginQueryType { diff --git a/web/src/pages/data-flow/form-sheet/form-config-map.tsx b/web/src/pages/data-flow/form-sheet/form-config-map.tsx index f00d93009..20caee379 100644 --- a/web/src/pages/data-flow/form-sheet/form-config-map.tsx +++ b/web/src/pages/data-flow/form-sheet/form-config-map.tsx @@ -7,6 +7,7 @@ import CodeForm from '../form/code-form'; import CrawlerForm from '../form/crawler-form'; import EmailForm from '../form/email-form'; import ExeSQLForm from '../form/exesql-form'; +import HierarchicalMergerForm from '../form/hierarchical-merger-form'; import InvokeForm from '../form/invoke-form'; import IterationForm from '../form/iteration-form'; import IterationStartForm from '../form/iteration-start-from'; @@ -16,6 +17,7 @@ import ParserForm from '../form/parser-form'; import RelevantForm from '../form/relevant-form'; import RetrievalForm from '../form/retrieval-form/next'; import RewriteQuestionForm from '../form/rewrite-question-form'; +import SplitterForm from '../form/splitter-form'; import StringTransformForm from '../form/string-transform-form'; import SwitchForm from '../form/switch-form'; import TokenizerForm from '../form/tokenizer-form'; @@ -94,4 +96,10 @@ export const FormConfigMap = { [Operator.Tokenizer]: { component: TokenizerForm, }, + [Operator.Splitter]: { + component: SplitterForm, + }, + [Operator.HierarchicalMerger]: { + component: HierarchicalMergerForm, + }, }; diff --git a/web/src/pages/data-flow/form/hierarchical-merger-form/index.tsx b/web/src/pages/data-flow/form/hierarchical-merger-form/index.tsx new file mode 100644 index 000000000..f002c4cca --- /dev/null +++ b/web/src/pages/data-flow/form/hierarchical-merger-form/index.tsx @@ -0,0 +1,140 @@ +import { FormContainer } from '@/components/form-container'; +import NumberInput from '@/components/originui/number-input'; +import { SelectWithSearch } from '@/components/originui/select-with-search'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { useTranslate } from '@/hooks/common-hooks'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { memo } from 'react'; +import { useForm, useFormContext } from 'react-hook-form'; +import { z } from 'zod'; +import { initialChunkerValues } from '../../constant'; +import { useFormValues } from '../../hooks/use-form-values'; +import { useWatchFormChange } from '../../hooks/use-watch-form-change'; +import { INextOperatorForm } from '../../interface'; +import { GoogleCountryOptions, GoogleLanguageOptions } from '../../options'; +import { buildOutputList } from '../../utils/build-output-list'; +import { ApiKeyField } from '../components/api-key-field'; +import { FormWrapper } from '../components/form-wrapper'; +import { Output } from '../components/output'; +import { QueryVariable } from '../components/query-variable'; + +const outputList = buildOutputList(initialChunkerValues.outputs); + +export const GoogleFormPartialSchema = { + api_key: z.string(), + country: z.string(), + language: z.string(), +}; + +export const FormSchema = z.object({ + ...GoogleFormPartialSchema, + q: z.string(), + start: z.number(), + num: z.number(), +}); + +export function GoogleFormWidgets() { + const form = useFormContext(); + const { t } = useTranslate('flow'); + + return ( + <> + ( + + {t('country')} + + + + + + )} + /> + ( + + {t('language')} + + + + + + )} + /> + + ); +} + +const HierarchicalMergerForm = ({ node }: INextOperatorForm) => { + const { t } = useTranslate('flow'); + const defaultValues = useFormValues(initialChunkerValues, node); + + const form = useForm>({ + defaultValues, + resolver: zodResolver(FormSchema), + }); + + useWatchFormChange(node?.id, form); + + return ( +
+ + + + + + + ( + + {t('flowStart')} + + + + + + )} + /> + ( + + {t('flowNum')} + + + + + + )} + /> + + + +
+ +
+
+ ); +}; + +export default memo(HierarchicalMergerForm); diff --git a/web/src/pages/data-flow/form/splitter-form/index.tsx b/web/src/pages/data-flow/form/splitter-form/index.tsx new file mode 100644 index 000000000..83be6c559 --- /dev/null +++ b/web/src/pages/data-flow/form/splitter-form/index.tsx @@ -0,0 +1,95 @@ +import { FormContainer } from '@/components/form-container'; +import { RAGFlowFormItem } from '@/components/ragflow-form'; +import { SliderInputFormField } from '@/components/slider-input-form-field'; +import { BlockButton, Button } from '@/components/ui/button'; +import { Form } from '@/components/ui/form'; +import { Input } from '@/components/ui/input'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { X } from 'lucide-react'; +import { memo } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { initialChunkerValues, initialSplitterValues } from '../../constant'; +import { useFormValues } from '../../hooks/use-form-values'; +import { useWatchFormChange } from '../../hooks/use-watch-form-change'; +import { INextOperatorForm } from '../../interface'; +import { buildOutputList } from '../../utils/build-output-list'; +import { FormWrapper } from '../components/form-wrapper'; +import { Output } from '../components/output'; + +const outputList = buildOutputList(initialSplitterValues.outputs); + +export const FormSchema = z.object({ + chunk_token_size: z.number(), + delimiters: z.array( + z.object({ + value: z.string().optional(), + }), + ), + overlapped_percent: z.number(), // 0.0 - 0.3 +}); + +const SplitterForm = ({ node }: INextOperatorForm) => { + const defaultValues = useFormValues(initialChunkerValues, node); + + const form = useForm>({ + defaultValues, + resolver: zodResolver(FormSchema), + }); + const name = 'delimiters'; + + const { fields, append, remove } = useFieldArray({ + name: name, + control: form.control, + }); + + useWatchFormChange(node?.id, form); + + return ( +
+ + + + + delimiters + {fields.map((field, index) => ( +
+
+ + + +
+ +
+ ))} + append({ value: '' })}>Add +
+
+
+ +
+
+ ); +}; + +export default memo(SplitterForm);