From 0d5589bfda95a5f649722a12741d7195a5440d89 Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 20 Nov 2025 15:35:28 +0800 Subject: [PATCH] Feat: Outputs data is directly synchronized to the canvas without going through the form. #10427 (#11406) ### What problem does this PR solve? Feat: Outputs data is directly synchronized to the canvas without going through the form. #10427 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/pages/agent/form/agent-form/index.tsx | 27 +++++++++-------- .../use-show-structured-output-dialog.ts | 30 +++++++++++++++---- .../pages/agent/form/agent-form/use-values.ts | 4 ++- .../agent/form/agent-form/use-watch-change.ts | 11 +------ 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/web/src/pages/agent/form/agent-form/index.tsx b/web/src/pages/agent/form/agent-form/index.tsx index 2b23010cd..38c49b666 100644 --- a/web/src/pages/agent/form/agent-form/index.tsx +++ b/web/src/pages/agent/form/agent-form/index.tsx @@ -22,7 +22,8 @@ import { Switch } from '@/components/ui/switch'; import { LlmModelType } from '@/constants/knowledge'; import { useFindLlmByUuid } from '@/hooks/use-llm-request'; import { zodResolver } from '@hookform/resolvers/zod'; -import { memo, useCallback, useEffect, useMemo } from 'react'; +import { get } from 'lodash'; +import { memo, useEffect, useMemo } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; @@ -45,7 +46,10 @@ import { AgentTools, Agents } from './agent-tools'; import { StructuredOutputDialog } from './structured-output-dialog'; import { StructuredOutputPanel } from './structured-output-panel'; import { useBuildPromptExtraPromptOptions } from './use-build-prompt-options'; -import { useShowStructuredOutputDialog } from './use-show-structured-output-dialog'; +import { + useHandleShowStructuredOutput, + useShowStructuredOutputDialog, +} from './use-show-structured-output-dialog'; import { useValues } from './use-values'; import { useWatchFormChange } from './use-watch-change'; @@ -121,22 +125,19 @@ function AgentForm({ node }: INextOperatorForm) { }); const { - initialStructuredOutput, showStructuredOutputDialog, structuredOutputDialogVisible, hideStructuredOutputDialog, handleStructuredOutputDialogOk, } = useShowStructuredOutputDialog(node?.id); - const updateNodeForm = useGraphStore((state) => state.updateNodeForm); + const structuredOutput = get( + node, + `data.form.outputs.${AgentStructuredOutputField}`, + ); - const handleShowStructuredOutput = useCallback( - (val: boolean) => { - if (node?.id && val) { - updateNodeForm(node?.id, {}, ['outputs', AgentStructuredOutputField]); - } - }, - [node?.id, updateNodeForm], + const { handleShowStructuredOutput } = useHandleShowStructuredOutput( + node?.id, ); useEffect(() => { @@ -327,7 +328,7 @@ function AgentForm({ node }: INextOperatorForm) { )} @@ -337,7 +338,7 @@ function AgentForm({ node }: INextOperatorForm) { )} diff --git a/web/src/pages/agent/form/agent-form/use-show-structured-output-dialog.ts b/web/src/pages/agent/form/agent-form/use-show-structured-output-dialog.ts index 19e38cefe..d66fcfb45 100644 --- a/web/src/pages/agent/form/agent-form/use-show-structured-output-dialog.ts +++ b/web/src/pages/agent/form/agent-form/use-show-structured-output-dialog.ts @@ -1,6 +1,8 @@ import { JSONSchema } from '@/components/jsonjoy-builder'; +import { AgentStructuredOutputField } from '@/constants/agent'; import { useSetModalState } from '@/hooks/common-hooks'; import { useCallback } from 'react'; +import { initialAgentValues } from '../../constant'; import useGraphStore from '../../store'; export function useShowStructuredOutputDialog(nodeId?: string) { @@ -9,15 +11,13 @@ export function useShowStructuredOutputDialog(nodeId?: string) { showModal: showStructuredOutputDialog, hideModal: hideStructuredOutputDialog, } = useSetModalState(); - const { updateNodeForm, getNode } = useGraphStore((state) => state); - - const initialStructuredOutput = getNode(nodeId)?.data.form.outputs.structured; + const { updateNodeForm } = useGraphStore((state) => state); const handleStructuredOutputDialogOk = useCallback( (values: JSONSchema) => { // Sync data to canvas if (nodeId) { - updateNodeForm(nodeId, values, ['outputs', 'structured']); + updateNodeForm(nodeId, values, ['outputs', AgentStructuredOutputField]); } hideStructuredOutputDialog(); }, @@ -25,10 +25,30 @@ export function useShowStructuredOutputDialog(nodeId?: string) { ); return { - initialStructuredOutput, structuredOutputDialogVisible, showStructuredOutputDialog, hideStructuredOutputDialog, handleStructuredOutputDialogOk, }; } + +export function useHandleShowStructuredOutput(nodeId?: string) { + const updateNodeForm = useGraphStore((state) => state.updateNodeForm); + + const handleShowStructuredOutput = useCallback( + (val: boolean) => { + if (nodeId) { + if (val) { + updateNodeForm(nodeId, {}, ['outputs', AgentStructuredOutputField]); + } else { + updateNodeForm(nodeId, initialAgentValues.outputs, ['outputs']); + } + } + }, + [nodeId, updateNodeForm], + ); + + return { + handleShowStructuredOutput, + }; +} diff --git a/web/src/pages/agent/form/agent-form/use-values.ts b/web/src/pages/agent/form/agent-form/use-values.ts index f8747e4b4..fb7f94861 100644 --- a/web/src/pages/agent/form/agent-form/use-values.ts +++ b/web/src/pages/agent/form/agent-form/use-values.ts @@ -6,8 +6,10 @@ import { initialAgentValues } from '../../constant'; // You need to exclude the mcp and tools fields that are not in the form, // otherwise the form data update will reset the tools or mcp data to an array +// Exclude data that is not in the form to avoid writing this data to the canvas when using useWatch. +// Outputs, tools, and MCP data are directly synchronized to the canvas without going through the form. function omitToolsAndMcp(values: Record) { - return omit(values, ['mcp', 'tools']); + return omit(values, ['mcp', 'tools', 'outputs']); } export function useValues(node?: RAGFlowNodeType) { diff --git a/web/src/pages/agent/form/agent-form/use-watch-change.ts b/web/src/pages/agent/form/agent-form/use-watch-change.ts index 7c53a8d40..98b0ecf31 100644 --- a/web/src/pages/agent/form/agent-form/use-watch-change.ts +++ b/web/src/pages/agent/form/agent-form/use-watch-change.ts @@ -1,7 +1,6 @@ -import { omit } from 'lodash'; import { useEffect } from 'react'; import { UseFormReturn, useWatch } from 'react-hook-form'; -import { AgentStructuredOutputField, PromptRole } from '../../constant'; +import { PromptRole } from '../../constant'; import useGraphStore from '../../store'; export function useWatchFormChange(id?: string, form?: UseFormReturn) { @@ -17,14 +16,6 @@ export function useWatchFormChange(id?: string, form?: UseFormReturn) { prompts: [{ role: PromptRole.User, content: values.prompts }], }; - if (!values.showStructuredOutput) { - nextValues = { - ...nextValues, - outputs: omit(values.outputs, [AgentStructuredOutputField]), - }; - } else { - nextValues = omit(nextValues, 'outputs'); - } updateNodeForm(id, nextValues); } }, [form?.formState.isDirty, id, updateNodeForm, values]);