Feat: Add loop operator form

This commit is contained in:
bill 2025-11-24 13:19:02 +08:00
parent 6b4b9ef21f
commit 419c86155c
5 changed files with 67 additions and 7 deletions

View file

@ -624,7 +624,12 @@ export const initialVariableAssignerValues = {};
export const initialVariableAggregatorValues = { outputs: {}, groups: [] }; 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 = [ export const CategorizeAnchorPointPositions = [
{ top: 1, right: 34 }, { top: 1, right: 34 },

View file

@ -22,6 +22,7 @@ import IterationStartForm from '../form/iteration-start-from';
import Jin10Form from '../form/jin10-form'; import Jin10Form from '../form/jin10-form';
import KeywordExtractForm from '../form/keyword-extract-form'; import KeywordExtractForm from '../form/keyword-extract-form';
import ListOperationsForm from '../form/list-operations-form'; import ListOperationsForm from '../form/list-operations-form';
import LoopForm from '../form/loop-form';
import MessageForm from '../form/message-form'; import MessageForm from '../form/message-form';
import ParserForm from '../form/parser-form'; import ParserForm from '../form/parser-form';
import PubMedForm from '../form/pubmed-form'; import PubMedForm from '../form/pubmed-form';
@ -191,8 +192,10 @@ export const FormConfigMap = {
[Operator.VariableAssigner]: { [Operator.VariableAssigner]: {
component: VariableAssignerForm, component: VariableAssignerForm,
}, },
[Operator.VariableAggregator]: { [Operator.VariableAggregator]: {
component: VariableAggregatorForm, component: VariableAggregatorForm,
}, },
[Operator.Loop]: {
component: LoopForm,
},
}; };

View file

@ -9,7 +9,6 @@ import { FormWrapper } from '../components/form-wrapper';
import { Output } from '../components/output'; import { Output } from '../components/output';
import { QueryVariable } from '../components/query-variable'; import { QueryVariable } from '../components/query-variable';
import { DynamicOutput } from './dynamic-output'; import { DynamicOutput } from './dynamic-output';
import { DynamicVariables } from './dynamic-variables';
import { OutputArray } from './interface'; import { OutputArray } from './interface';
import { useValues } from './use-values'; import { useValues } from './use-values';
import { useWatchFormChange } from './use-watch-form-change'; import { useWatchFormChange } from './use-watch-form-change';
@ -53,7 +52,6 @@ function IterationForm({ node }: INextOperatorForm) {
name="items_ref" name="items_ref"
types={ArrayFields as any[]} types={ArrayFields as any[]}
></QueryVariable> ></QueryVariable>
<DynamicVariables name="variables" label="Variables"></DynamicVariables>
<DynamicOutput node={node}></DynamicOutput> <DynamicOutput node={node}></DynamicOutput>
<Output list={outputList}></Output> <Output list={outputList}></Output>
</FormWrapper> </FormWrapper>

View file

@ -67,7 +67,7 @@ function RadioButton({ value, onChange }: RadioButtonProps) {
const VariableTypeOptions = buildConversationVariableSelectOptions(); const VariableTypeOptions = buildConversationVariableSelectOptions();
const modeField = 'mode'; const modeField = 'input_mode';
const ConstantValueMap = { const ConstantValueMap = {
[TypesWithArray.Boolean]: 'yes', [TypesWithArray.Boolean]: 'yes',
@ -85,8 +85,8 @@ export function DynamicVariables({
label, label,
tooltip, tooltip,
keyField = 'variable', keyField = 'variable',
valueField = 'parameter', valueField = 'value',
operatorField = 'operator', operatorField = 'type',
}: SelectKeysProps) { }: SelectKeysProps) {
const form = useFormContext(); const form = useFormContext();
const isDarkTheme = useIsDarkTheme(); const isDarkTheme = useIsDarkTheme();

View file

@ -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 (
<Form {...form}>
<FormWrapper>
<DynamicVariables
name="loop_variables"
label="Variables"
></DynamicVariables>
</FormWrapper>
</Form>
);
}
export default memo(LoopForm);