Parcourir la source

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)
tags/v0.20.0
balibabu il y a 3 mois
Parent
révision
2a79f4fc7f
Aucun compte lié à l'adresse e-mail de l'auteur

+ 3
- 9
web/src/components/originui/select-with-search.tsx Voir le fichier

> >
{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">
{selectLabel}
</span>
<span className="leading-none truncate">{selectLabel}</span>
</span> </span>
) : ( ) : (
<span className="text-muted-foreground">Select value</span> <span className="text-muted-foreground">Select value</span>
disabled={option.disabled} disabled={option.disabled}
onSelect={handleSelect} onSelect={handleSelect}
> >
<span className="text-lg leading-none">
{option.label}
</span>
<span className="leading-none">{option.label}</span>


{value === option.value && ( {value === option.value && (
<CheckIcon size={16} className="ml-auto" /> <CheckIcon size={16} className="ml-auto" />
disabled={group.disabled} disabled={group.disabled}
onSelect={handleSelect} onSelect={handleSelect}
> >
<span className="text-lg leading-none">
{group.label}
</span>
<span className="leading-none">{group.label}</span>


{value === group.value && ( {value === group.value && (
<CheckIcon size={16} className="ml-auto" /> <CheckIcon size={16} className="ml-auto" />

+ 2
- 0
web/src/locales/en.ts Voir le fichier

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: {

+ 5
- 3
web/src/pages/agent/canvas/node/agent-node.tsx Voir le fichier

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';
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);
{(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="truncate flex-1">
{isGotoMethod ? 'Exception branch' : 'Output default value'}
<span className="text-text-sub-title">On Failure</span>
<span className="truncate flex-1 text-right">
{t(`flow.${exceptionMethod}`)}
</span> </span>
</div> </div>
)} )}

+ 11
- 4
web/src/pages/agent/constant.tsx Voir le fichier

...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 user’s 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_comment: '',
exception_method: '',
exception_goto: [], exception_goto: [],
exception_default_value: '', exception_default_value: '',
tools: [], tools: [],
export enum AgentExceptionMethod { export enum AgentExceptionMethod {
Comment = 'comment', Comment = 'comment',
Goto = 'goto', Goto = 'goto',
Null = 'null',
} }

+ 26
- 32
web/src/pages/agent/form/agent-form/index.tsx Voir le fichier

} 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,
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';
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(),
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_comment: z.string().optional(),
exception_method: 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,


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]);
<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
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`}
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Exception comment</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
{exceptionMethod === AgentExceptionMethod.Comment && (
<FormField
control={form.control}
name={`exception_default_value`}
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>Exception default value</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
)}
</FormContainer> </FormContainer>
</Collapse> </Collapse>
<Output list={outputList}></Output> <Output list={outputList}></Output>

+ 1
- 5
web/src/pages/agent/form/agent-form/use-values.ts Voir le fichier

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();
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]);



+ 1
- 5
web/src/pages/agent/form/agent-form/use-watch-change.ts Voir le fichier

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>) {
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);

Chargement…
Annuler
Enregistrer