Feat: Remove the exception comment field from the agent form #3221 (#9153)

### What problem does this PR solve?
Feat: Remove the exception comment field from the agent form #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-08-01 15:19:33 +08:00
committed by GitHub
parent 4b98119c52
commit 2a79f4fc7f
7 changed files with 49 additions and 58 deletions

View File

@ -111,9 +111,7 @@ export const SelectWithSearch = forwardRef<
> >
{value ? ( {value ? (
<span className="flex min-w-0 options-center gap-2"> <span className="flex min-w-0 options-center gap-2">
<span className="text-lg leading-none truncate"> <span className="leading-none truncate">{selectLabel}</span>
{selectLabel}
</span>
</span> </span>
) : ( ) : (
<span className="text-muted-foreground">Select value</span> <span className="text-muted-foreground">Select value</span>
@ -159,9 +157,7 @@ export const SelectWithSearch = forwardRef<
disabled={option.disabled} disabled={option.disabled}
onSelect={handleSelect} onSelect={handleSelect}
> >
<span className="text-lg leading-none"> <span className="leading-none">{option.label}</span>
{option.label}
</span>
{value === option.value && ( {value === option.value && (
<CheckIcon size={16} className="ml-auto" /> <CheckIcon size={16} className="ml-auto" />
@ -179,9 +175,7 @@ export const SelectWithSearch = forwardRef<
disabled={group.disabled} disabled={group.disabled}
onSelect={handleSelect} onSelect={handleSelect}
> >
<span className="text-lg leading-none"> <span className="leading-none">{group.label}</span>
{group.label}
</span>
{value === group.value && ( {value === group.value && (
<CheckIcon size={16} className="ml-auto" /> <CheckIcon size={16} className="ml-auto" />

View File

@ -1317,6 +1317,8 @@ This delimiter is used to split the input text into several text pieces echo of
file: 'File upload', file: 'File upload',
integer: 'Number', integer: 'Number',
boolean: 'Boolean', boolean: 'Boolean',
goto: 'Fail Branch',
comment: 'Default Value',
}, },
llmTools: { llmTools: {
bad_calculator: { bad_calculator: {

View File

@ -3,6 +3,7 @@ import { IAgentNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react'; import { Handle, NodeProps, Position } from '@xyflow/react';
import { get } from 'lodash'; import { get } from 'lodash';
import { memo, useMemo } from 'react'; import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { AgentExceptionMethod, NodeHandleId } from '../../constant'; import { AgentExceptionMethod, NodeHandleId } from '../../constant';
import useGraphStore from '../../store'; import useGraphStore from '../../store';
import { isBottomSubAgent } from '../../utils'; import { isBottomSubAgent } from '../../utils';
@ -20,6 +21,7 @@ function InnerAgentNode({
selected, selected,
}: NodeProps<IAgentNode>) { }: NodeProps<IAgentNode>) {
const edges = useGraphStore((state) => state.edges); const edges = useGraphStore((state) => state.edges);
const { t } = useTranslation();
const isHeadAgent = useMemo(() => { const isHeadAgent = useMemo(() => {
return !isBottomSubAgent(edges, id); return !isBottomSubAgent(edges, id);
@ -87,9 +89,9 @@ function InnerAgentNode({
{(isGotoMethod || {(isGotoMethod ||
exceptionMethod === AgentExceptionMethod.Comment) && ( exceptionMethod === AgentExceptionMethod.Comment) && (
<div className="bg-background-card rounded-sm p-1 flex justify-between gap-2"> <div className="bg-background-card rounded-sm p-1 flex justify-between gap-2">
<span className="text-text-sub-title">Abnormal</span> <span className="text-text-sub-title">On Failure</span>
<span className="truncate flex-1"> <span className="truncate flex-1 text-right">
{isGotoMethod ? 'Exception branch' : 'Output default value'} {t(`flow.${exceptionMethod}`)}
</span> </span>
</div> </div>
)} )}

View File

@ -645,15 +645,23 @@ export const initialAgentValues = {
...initialLlmBaseValues, ...initialLlmBaseValues,
description: '', description: '',
user_prompt: '', user_prompt: '',
sys_prompt: ``, sys_prompt: `<role>
You are {{agent_name}}, an AI assistant specialized in {{domain_or_task}}.
</role>
<instructions>
1. Understand the users request.
2. Decompose it into logical subtasks.
3. Execute each subtask step by step, reasoning transparently.
4. Validate accuracy and consistency.
5. Summarize the final result clearly.
</instructions>`,
prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }], prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }],
message_history_window_size: 12, message_history_window_size: 12,
max_retries: 3, max_retries: 3,
delay_after_error: 1, delay_after_error: 1,
visual_files_var: '', visual_files_var: '',
max_rounds: 5, max_rounds: 5,
exception_method: null, exception_method: '',
exception_comment: '',
exception_goto: [], exception_goto: [],
exception_default_value: '', exception_default_value: '',
tools: [], tools: [],
@ -944,5 +952,4 @@ export enum VariableType {
export enum AgentExceptionMethod { export enum AgentExceptionMethod {
Comment = 'comment', Comment = 'comment',
Goto = 'goto', Goto = 'goto',
Null = 'null',
} }

View File

@ -6,6 +6,7 @@ import {
} from '@/components/large-model-form-field'; } from '@/components/large-model-form-field';
import { LlmSettingSchema } from '@/components/llm-setting-items/next'; import { LlmSettingSchema } from '@/components/llm-setting-items/next';
import { MessageHistoryWindowSizeFormField } from '@/components/message-history-window-size-item'; import { MessageHistoryWindowSizeFormField } from '@/components/message-history-window-size-item';
import { SelectWithSearch } from '@/components/originui/select-with-search';
import { import {
Form, Form,
FormControl, FormControl,
@ -14,10 +15,8 @@ import {
FormLabel, FormLabel,
} from '@/components/ui/form'; } from '@/components/ui/form';
import { Input, NumberInput } from '@/components/ui/input'; import { Input, NumberInput } from '@/components/ui/input';
import { RAGFlowSelect } from '@/components/ui/select';
import { LlmModelType } from '@/constants/knowledge'; import { LlmModelType } from '@/constants/knowledge';
import { useFindLlmByUuid } from '@/hooks/use-llm-request'; import { useFindLlmByUuid } from '@/hooks/use-llm-request';
import { buildOptions } from '@/utils/form';
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { memo, useEffect, useMemo } from 'react'; import { memo, useEffect, useMemo } from 'react';
import { useForm, useWatch } from 'react-hook-form'; import { useForm, useWatch } from 'react-hook-form';
@ -42,8 +41,6 @@ import { AgentTools, Agents } from './agent-tools';
import { useValues } from './use-values'; import { useValues } from './use-values';
import { useWatchFormChange } from './use-watch-change'; import { useWatchFormChange } from './use-watch-change';
const exceptionMethodOptions = buildOptions(AgentExceptionMethod);
const FormSchema = z.object({ const FormSchema = z.object({
sys_prompt: z.string(), sys_prompt: z.string(),
description: z.string().optional(), description: z.string().optional(),
@ -70,8 +67,7 @@ const FormSchema = z.object({
delay_after_error: z.coerce.number().optional(), delay_after_error: z.coerce.number().optional(),
visual_files_var: z.string().optional(), visual_files_var: z.string().optional(),
max_rounds: z.coerce.number().optional(), max_rounds: z.coerce.number().optional(),
exception_method: z.string().nullable(), exception_method: z.string().optional(),
exception_comment: z.string().optional(),
exception_goto: z.array(z.string()).optional(), exception_goto: z.array(z.string()).optional(),
exception_default_value: z.string().optional(), exception_default_value: z.string().optional(),
...LargeModelFilterFormSchema, ...LargeModelFilterFormSchema,
@ -87,6 +83,13 @@ function AgentForm({ node }: INextOperatorForm) {
const defaultValues = useValues(node); const defaultValues = useValues(node);
const ExceptionMethodOptions = Object.values(AgentExceptionMethod).map(
(x) => ({
label: t(`flow.${x}`),
value: x,
}),
);
const isSubAgent = useMemo(() => { const isSubAgent = useMemo(() => {
return isBottomSubAgent(edges, node?.id); return isBottomSubAgent(edges, node?.id);
}, [edges, node?.id]); }, [edges, node?.id]);
@ -224,38 +227,29 @@ function AgentForm({ node }: INextOperatorForm) {
<FormItem className="flex-1"> <FormItem className="flex-1">
<FormLabel>Exception method</FormLabel> <FormLabel>Exception method</FormLabel>
<FormControl> <FormControl>
<RAGFlowSelect <SelectWithSearch
{...field} {...field}
options={exceptionMethodOptions} options={ExceptionMethodOptions}
allowClear
/> />
</FormControl> </FormControl>
</FormItem> </FormItem>
)} )}
/> />
<FormField {exceptionMethod === AgentExceptionMethod.Comment && (
control={form.control} <FormField
name={`exception_default_value`} control={form.control}
render={({ field }) => ( name={`exception_default_value`}
<FormItem className="flex-1"> render={({ field }) => (
<FormLabel>Exception default value</FormLabel> <FormItem className="flex-1">
<FormControl> <FormLabel>Exception default value</FormLabel>
<Input {...field} /> <FormControl>
</FormControl> <Input {...field} />
</FormItem> </FormControl>
)} </FormItem>
/> )}
<FormField />
control={form.control} )}
name={`exception_comment`}
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Exception comment</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
</FormContainer> </FormContainer>
</Collapse> </Collapse>
<Output list={outputList}></Output> <Output list={outputList}></Output>

View File

@ -2,7 +2,7 @@ import { useFetchModelId } from '@/hooks/logic-hooks';
import { RAGFlowNodeType } from '@/interfaces/database/flow'; import { RAGFlowNodeType } from '@/interfaces/database/flow';
import { get, isEmpty } from 'lodash'; import { get, isEmpty } from 'lodash';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { AgentExceptionMethod, initialAgentValues } from '../../constant'; import { initialAgentValues } from '../../constant';
export function useValues(node?: RAGFlowNodeType) { export function useValues(node?: RAGFlowNodeType) {
const llmId = useFetchModelId(); const llmId = useFetchModelId();
@ -26,10 +26,6 @@ export function useValues(node?: RAGFlowNodeType) {
return { return {
...formData, ...formData,
prompts: get(formData, 'prompts.0.content', ''), prompts: get(formData, 'prompts.0.content', ''),
exception_method:
formData.exception_method === null
? AgentExceptionMethod.Null
: formData.exception_method,
}; };
}, [defaultValues, node?.data?.form]); }, [defaultValues, node?.data?.form]);

View File

@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { UseFormReturn, useWatch } from 'react-hook-form'; import { UseFormReturn, useWatch } from 'react-hook-form';
import { AgentExceptionMethod, PromptRole } from '../../constant'; import { PromptRole } from '../../constant';
import useGraphStore from '../../store'; import useGraphStore from '../../store';
export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) { export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) {
@ -14,10 +14,6 @@ export function useWatchFormChange(id?: string, form?: UseFormReturn<any>) {
let nextValues: any = { let nextValues: any = {
...values, ...values,
prompts: [{ role: PromptRole.User, content: values.prompts }], prompts: [{ role: PromptRole.User, content: values.prompts }],
exception_method:
values.exception_method === AgentExceptionMethod.Null
? null
: values.exception_method,
}; };
updateNodeForm(id, nextValues); updateNodeForm(id, nextValues);