Feat: Handling abnormal anchor points of agent operators #3221 (#9121)

### What problem does this PR solve?
Feat: Handling abnormal anchor points of agent operators #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-07-30 19:14:33 +08:00
committed by GitHub
parent db6d4307f2
commit 07e37560fc
10 changed files with 125 additions and 277 deletions

View File

@ -19,19 +19,22 @@ import { LlmModelType } from '@/constants/knowledge';
import { useFindLlmByUuid } from '@/hooks/use-llm-request';
import { buildOptions } from '@/utils/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { memo, useMemo } from 'react';
import { memo, useEffect, useMemo } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import {
AgentExceptionMethod,
NodeHandleId,
VariableType,
initialAgentValues,
} from '../../constant';
import { INextOperatorForm } from '../../interface';
import useGraphStore from '../../store';
import { isBottomSubAgent } from '../../utils';
import { buildOutputList } from '../../utils/build-output-list';
import { DescriptionField } from '../components/description-field';
import { FormWrapper } from '../components/form-wrapper';
import { Output } from '../components/output';
import { PromptEditor } from '../components/prompt-editor';
import { QueryVariable } from '../components/query-variable';
@ -69,13 +72,18 @@ const FormSchema = z.object({
max_rounds: z.coerce.number().optional(),
exception_method: z.string().nullable(),
exception_comment: z.string().optional(),
exception_goto: z.string().optional(),
exception_goto: z.array(z.string()).optional(),
exception_default_value: z.string().optional(),
...LargeModelFilterFormSchema,
});
const outputList = buildOutputList(initialAgentValues.outputs);
function AgentForm({ node }: INextOperatorForm) {
const { t } = useTranslation();
const { edges } = useGraphStore((state) => state);
const { edges, deleteEdgesBySourceAndSourceHandle } = useGraphStore(
(state) => state,
);
const defaultValues = useValues(node);
@ -83,12 +91,6 @@ function AgentForm({ node }: INextOperatorForm) {
return isBottomSubAgent(edges, node?.id);
}, [edges, node?.id]);
const outputList = useMemo(() => {
return [
{ title: 'content', type: initialAgentValues.outputs.content.type },
];
}, []);
const form = useForm<z.infer<typeof FormSchema>>({
defaultValues: defaultValues,
resolver: zodResolver(FormSchema),
@ -98,16 +100,27 @@ function AgentForm({ node }: INextOperatorForm) {
const findLlmByUuid = useFindLlmByUuid();
const exceptionMethod = useWatch({
control: form.control,
name: 'exception_method',
});
useEffect(() => {
if (exceptionMethod !== AgentExceptionMethod.Goto) {
if (node?.id) {
deleteEdgesBySourceAndSourceHandle(
node?.id,
NodeHandleId.AgentException,
);
}
}
}, [deleteEdgesBySourceAndSourceHandle, exceptionMethod, node?.id]);
useWatchFormChange(node?.id, form);
return (
<Form {...form}>
<form
className="space-y-6 p-4"
onSubmit={(e) => {
e.preventDefault();
}}
>
<FormWrapper>
<FormContainer>
{isSubAgent && <DescriptionField></DescriptionField>}
<LargeModelFormField></LargeModelFormField>
@ -219,6 +232,18 @@ function AgentForm({ node }: INextOperatorForm) {
</FormItem>
)}
/>
<FormField
control={form.control}
name={`exception_default_value`}
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Exception default value</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name={`exception_comment`}
@ -231,15 +256,10 @@ function AgentForm({ node }: INextOperatorForm) {
</FormItem>
)}
/>
<QueryVariable
name="exception_goto"
label="Exception goto"
type={VariableType.File}
></QueryVariable>
</FormContainer>
</Collapse>
<Output list={outputList}></Output>
</form>
</FormWrapper>
</Form>
);
}

View File

@ -177,7 +177,7 @@ const DynamicCategorize = ({ nodeId }: IProps) => {
const FormSchema = useCreateCategorizeFormSchema();
const deleteCategorizeCaseEdges = useGraphStore(
(state) => state.deleteCategorizeCaseEdges,
(state) => state.deleteEdgesBySourceAndSourceHandle,
);
const form = useFormContext<z.infer<typeof FormSchema>>();
const { t } = useTranslate('flow');

View File

@ -7,7 +7,6 @@ import {
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { RAGFlowSelect } from '@/components/ui/select';
import { buildOptions } from '@/utils/form';
import { zodResolver } from '@hookform/resolvers/zod';
@ -26,6 +25,7 @@ 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 { PromptEditor } from '../components/prompt-editor';
import { TavilyFormSchema } from '../tavily-form';
const outputList = buildOutputList(initialTavilyExtractValues.outputs);
@ -64,7 +64,11 @@ function TavilyExtractForm({ node }: INextOperatorForm) {
<FormItem>
<FormLabel>URL</FormLabel>
<FormControl>
<Input {...field} />
<PromptEditor
{...field}
multiLine={false}
showToolbar={false}
></PromptEditor>
</FormControl>
<FormMessage />
</FormItem>

View File

@ -12,7 +12,7 @@ import { RAGFlowSelect } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { buildOptions } from '@/utils/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { memo, useMemo } from 'react';
import { memo } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import {
@ -21,9 +21,10 @@ import {
initialTavilyValues,
} from '../../constant';
import { INextOperatorForm } from '../../interface';
import { buildOutputList } from '../../utils/build-output-list';
import { ApiKeyField } from '../components/api-key-field';
import { FormWrapper } from '../components/form-wrapper';
import { Output, OutputType } from '../components/output';
import { Output } from '../components/output';
import { QueryVariable } from '../components/query-variable';
import { DynamicDomain } from './dynamic-domain';
import { useValues } from './use-values';
@ -33,6 +34,8 @@ export const TavilyFormSchema = {
api_key: z.string(),
};
const outputList = buildOutputList(initialTavilyValues.outputs);
function TavilyForm({ node }: INextOperatorForm) {
const values = useValues(node);
@ -56,16 +59,6 @@ function TavilyForm({ node }: INextOperatorForm) {
resolver: zodResolver(FormSchema),
});
const outputList = useMemo(() => {
return Object.entries(initialTavilyValues.outputs).reduce<OutputType[]>(
(pre, [key, val]) => {
pre.push({ title: key, type: val.type });
return pre;
},
[],
);
}, []);
useWatchFormChange(node?.id, form);
return (