diff --git a/web/src/pages/agent/constant/index.tsx b/web/src/pages/agent/constant/index.tsx index 581dd27de..3c8a5c8b8 100644 --- a/web/src/pages/agent/constant/index.tsx +++ b/web/src/pages/agent/constant/index.tsx @@ -624,7 +624,12 @@ export const initialVariableAssignerValues = {}; export const initialVariableAggregatorValues = { outputs: {}, groups: [] }; -export const initialLoopValues = { outputs: {} }; +export const initialLoopValues = { + loop_variables: [], + loop_termination_condition: [], + maximum_loop_count: 10, + outputs: {}, +}; export const CategorizeAnchorPointPositions = [ { top: 1, right: 34 }, diff --git a/web/src/pages/agent/form-sheet/form-config-map.tsx b/web/src/pages/agent/form-sheet/form-config-map.tsx index 37ab4cf2f..1b3576ffd 100644 --- a/web/src/pages/agent/form-sheet/form-config-map.tsx +++ b/web/src/pages/agent/form-sheet/form-config-map.tsx @@ -22,6 +22,7 @@ import IterationStartForm from '../form/iteration-start-from'; import Jin10Form from '../form/jin10-form'; import KeywordExtractForm from '../form/keyword-extract-form'; import ListOperationsForm from '../form/list-operations-form'; +import LoopForm from '../form/loop-form'; import MessageForm from '../form/message-form'; import ParserForm from '../form/parser-form'; import PubMedForm from '../form/pubmed-form'; @@ -191,8 +192,10 @@ export const FormConfigMap = { [Operator.VariableAssigner]: { component: VariableAssignerForm, }, - [Operator.VariableAggregator]: { component: VariableAggregatorForm, }, + [Operator.Loop]: { + component: LoopForm, + }, }; diff --git a/web/src/pages/agent/form/iteration-form/index.tsx b/web/src/pages/agent/form/iteration-form/index.tsx index c528fa720..61e16277d 100644 --- a/web/src/pages/agent/form/iteration-form/index.tsx +++ b/web/src/pages/agent/form/iteration-form/index.tsx @@ -9,7 +9,6 @@ import { FormWrapper } from '../components/form-wrapper'; import { Output } from '../components/output'; import { QueryVariable } from '../components/query-variable'; import { DynamicOutput } from './dynamic-output'; -import { DynamicVariables } from './dynamic-variables'; import { OutputArray } from './interface'; import { useValues } from './use-values'; import { useWatchFormChange } from './use-watch-form-change'; @@ -53,7 +52,6 @@ function IterationForm({ node }: INextOperatorForm) { name="items_ref" types={ArrayFields as any[]} > - diff --git a/web/src/pages/agent/form/iteration-form/dynamic-variables.tsx b/web/src/pages/agent/form/loop-form/dynamic-variables.tsx similarity index 98% rename from web/src/pages/agent/form/iteration-form/dynamic-variables.tsx rename to web/src/pages/agent/form/loop-form/dynamic-variables.tsx index 62840d5a7..9a9b86d90 100644 --- a/web/src/pages/agent/form/iteration-form/dynamic-variables.tsx +++ b/web/src/pages/agent/form/loop-form/dynamic-variables.tsx @@ -67,7 +67,7 @@ function RadioButton({ value, onChange }: RadioButtonProps) { const VariableTypeOptions = buildConversationVariableSelectOptions(); -const modeField = 'mode'; +const modeField = 'input_mode'; const ConstantValueMap = { [TypesWithArray.Boolean]: 'yes', @@ -85,8 +85,8 @@ export function DynamicVariables({ label, tooltip, keyField = 'variable', - valueField = 'parameter', - operatorField = 'operator', + valueField = 'value', + operatorField = 'type', }: SelectKeysProps) { const form = useFormContext(); const isDarkTheme = useIsDarkTheme(); diff --git a/web/src/pages/agent/form/loop-form/index.tsx b/web/src/pages/agent/form/loop-form/index.tsx new file mode 100644 index 000000000..ff4acfc25 --- /dev/null +++ b/web/src/pages/agent/form/loop-form/index.tsx @@ -0,0 +1,54 @@ +import { Form } from '@/components/ui/form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { memo } from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { initialLoopValues } from '../../constant'; +import { useFormValues } from '../../hooks/use-form-values'; +import { useWatchFormChange } from '../../hooks/use-watch-form-change'; +import { INextOperatorForm } from '../../interface'; +import { FormWrapper } from '../components/form-wrapper'; +import { DynamicVariables } from './dynamic-variables'; + +const FormSchema = z.object({ + loop_variables: z.array( + z.object({ + variable: z.string().optional(), + type: z.string().optional(), + value: z.string().or(z.number()).or(z.boolean()).optional(), + input_mode: z.string(), + }), + ), + loop_termination_condition: z.array( + z.object({ + variable: z.string().optional(), + operator: z.string().optional(), + value: z.string().or(z.number()).or(z.boolean()).optional(), + input_mode: z.string(), + }), + ), +}); + +function LoopForm({ node }: INextOperatorForm) { + const defaultValues = useFormValues(initialLoopValues, node); + + const form = useForm({ + defaultValues: defaultValues, + resolver: zodResolver(FormSchema), + }); + + useWatchFormChange(node?.id, form, true); + + return ( +
+ + + +
+ ); +} + +export default memo(LoopForm);