From 13299197b8e176a9f98e701062a2d6bc62def738 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 21 Nov 2025 16:21:27 +0800 Subject: [PATCH] Feat: Enable logical operators in metadata. #11387 #11376 (#11442) ### What problem does this PR solve? Feat: Enable logical operators in metadata. #11387 #11376 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/components/metadata-filter/index.tsx | 1 + .../metadata-filter-conditions.tsx | 162 ++++++++++-------- web/src/constants/agent.tsx | 5 + .../hooks/logic-hooks/use-build-options.ts | 12 ++ web/src/pages/agent/constant/index.tsx | 5 +- .../pages/agent/form/switch-form/index.tsx | 14 +- 6 files changed, 119 insertions(+), 80 deletions(-) create mode 100644 web/src/hooks/logic-hooks/use-build-options.ts diff --git a/web/src/components/metadata-filter/index.tsx b/web/src/components/metadata-filter/index.tsx index 8dbdce42f..48388e4c2 100644 --- a/web/src/components/metadata-filter/index.tsx +++ b/web/src/components/metadata-filter/index.tsx @@ -14,6 +14,7 @@ type MetadataFilterProps = { export const MetadataFilterSchema = { meta_data_filter: z .object({ + logic: z.string().optional(), method: z.string().optional(), manual: z .array( diff --git a/web/src/components/metadata-filter/metadata-filter-conditions.tsx b/web/src/components/metadata-filter/metadata-filter-conditions.tsx index 80cb6409b..aee103a1f 100644 --- a/web/src/components/metadata-filter/metadata-filter-conditions.tsx +++ b/web/src/components/metadata-filter/metadata-filter-conditions.tsx @@ -15,14 +15,17 @@ import { } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Separator } from '@/components/ui/separator'; -import { SwitchOperatorOptions } from '@/constants/agent'; +import { SwitchLogicOperator, SwitchOperatorOptions } from '@/constants/agent'; import { useBuildSwitchOperatorOptions } from '@/hooks/logic-hooks/use-build-operator-options'; +import { useBuildSwitchLogicOperatorOptions } from '@/hooks/logic-hooks/use-build-options'; import { useFetchKnowledgeMetadata } from '@/hooks/use-knowledge-request'; import { PromptEditor } from '@/pages/agent/form/components/prompt-editor'; import { Plus, X } from 'lucide-react'; import { useCallback } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import { RAGFlowFormItem } from '../ragflow-form'; +import { RAGFlowSelect } from '../ui/select'; export function MetadataFilterConditions({ kbIds, @@ -36,10 +39,13 @@ export function MetadataFilterConditions({ const { t } = useTranslation(); const form = useFormContext(); const name = prefix + 'meta_data_filter.manual'; + const logic = prefix + 'meta_data_filter.logic'; const metadata = useFetchKnowledgeMetadata(kbIds); const switchOperatorOptions = useBuildSwitchOperatorOptions(); + const switchLogicOperatorOptions = useBuildSwitchLogicOperatorOptions(); + const { fields, remove, append } = useFieldArray({ name, control: form.control, @@ -47,13 +53,14 @@ export function MetadataFilterConditions({ const add = useCallback( (key: string) => () => { + form.setValue(logic, SwitchLogicOperator.And); append({ key, value: '', op: SwitchOperatorOptions[0].value, }); }, - [append], + [append, form, logic], ); return ( @@ -77,73 +84,92 @@ export function MetadataFilterConditions({ -
- {fields.map((field, index) => { - const typeField = `${name}.${index}.key`; - return ( -
- ( - - - - - - - )} - /> - - ( - - - - - - - )} - /> - - ( - - - {canReference ? ( - - ) : ( - +
+ {fields.length > 1 && ( +
+ + + +
+
+ )} +
+ {fields.map((field, index) => { + const typeField = `${name}.${index}.key`; + return ( +
+
+
+ ( + + + + + + )} - - - - )} - /> - -
- ); - })} -
+ /> + + ( + + + + + + + )} + /> +
+ ( + + + {canReference ? ( + + ) : ( + + )} + + + + )} + /> +
+ + + ); + })} +
+ ); } diff --git a/web/src/constants/agent.tsx b/web/src/constants/agent.tsx index 0ba1d927c..5877b91b1 100644 --- a/web/src/constants/agent.tsx +++ b/web/src/constants/agent.tsx @@ -179,3 +179,8 @@ export enum JsonSchemaDataType { Array = 'array', Object = 'object', } + +export enum SwitchLogicOperator { + And = 'and', + Or = 'or', +} diff --git a/web/src/hooks/logic-hooks/use-build-options.ts b/web/src/hooks/logic-hooks/use-build-options.ts new file mode 100644 index 000000000..62370e9bd --- /dev/null +++ b/web/src/hooks/logic-hooks/use-build-options.ts @@ -0,0 +1,12 @@ +import { SwitchLogicOperator } from '@/constants/agent'; +import { buildOptions } from '@/utils/form'; +import { useTranslation } from 'react-i18next'; + +export function useBuildSwitchLogicOperatorOptions() { + const { t } = useTranslation(); + return buildOptions( + SwitchLogicOperator, + t, + 'flow.switchLogicOperatorOptions', + ); +} diff --git a/web/src/pages/agent/constant/index.tsx b/web/src/pages/agent/constant/index.tsx index c357e8cb7..4a442271b 100644 --- a/web/src/pages/agent/constant/index.tsx +++ b/web/src/pages/agent/constant/index.tsx @@ -10,6 +10,7 @@ import { JsonSchemaDataType, Operator, ProgrammingLanguage, + SwitchLogicOperator, SwitchOperatorOptions, initialLlmBaseValues, } from '@/constants/agent'; @@ -51,8 +52,6 @@ import { export const BeginId = 'begin'; -export const SwitchLogicOperatorOptions = ['and', 'or']; - export const CommonOperatorList = Object.values(Operator).filter( (x) => x !== Operator.Note, ); @@ -308,7 +307,7 @@ export const initialExeSqlValues = { export const initialSwitchValues = { conditions: [ { - logical_operator: SwitchLogicOperatorOptions[0], + logical_operator: SwitchLogicOperator.And, items: [ { operator: SwitchOperatorOptions[0].value, diff --git a/web/src/pages/agent/form/switch-form/index.tsx b/web/src/pages/agent/form/switch-form/index.tsx index f9ccee919..53f4995af 100644 --- a/web/src/pages/agent/form/switch-form/index.tsx +++ b/web/src/pages/agent/form/switch-form/index.tsx @@ -11,16 +11,17 @@ import { import { RAGFlowSelect } from '@/components/ui/select'; import { Separator } from '@/components/ui/separator'; import { Textarea } from '@/components/ui/textarea'; +import { SwitchLogicOperator } from '@/constants/agent'; import { useBuildSwitchOperatorOptions } from '@/hooks/logic-hooks/use-build-operator-options'; +import { useBuildSwitchLogicOperatorOptions } from '@/hooks/logic-hooks/use-build-options'; import { cn } from '@/lib/utils'; import { zodResolver } from '@hookform/resolvers/zod'; import { t } from 'i18next'; import { X } from 'lucide-react'; -import { memo, useCallback, useMemo } from 'react'; +import { memo, useCallback } from 'react'; import { useFieldArray, useForm, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; -import { SwitchLogicOperatorOptions } from '../../constant'; import { IOperatorForm } from '../../interface'; import { FormWrapper } from '../components/form-wrapper'; import { QueryVariable } from '../components/query-variable'; @@ -185,12 +186,7 @@ function SwitchForm({ node }: IOperatorForm) { control: form.control, }); - const switchLogicOperatorOptions = useMemo(() => { - return SwitchLogicOperatorOptions.map((x) => ({ - value: x, - label: t(`flow.switchLogicOperatorOptions.${x}`), - })); - }, [t]); + const switchLogicOperatorOptions = useBuildSwitchLogicOperatorOptions(); useWatchFormChange(node?.id, form); @@ -253,7 +249,7 @@ function SwitchForm({ node }: IOperatorForm) { append({ - logical_operator: SwitchLogicOperatorOptions[0], + logical_operator: SwitchLogicOperator.And, [ItemKey]: [ { operator: switchOperatorOptions[0].value,