From 526ba3388f2a646e05612d9447922e5978e57ad3 Mon Sep 17 00:00:00 2001 From: balibabu Date: Fri, 7 Nov 2025 16:35:32 +0800 Subject: [PATCH] Feat: The output is derived based on the configuration of the variable aggregation operator. #10427 (#11109) ### What problem does this PR solve? Feat: The output is derived based on the configuration of the variable aggregation operator. #10427 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/pages/agent/constant/index.tsx | 2 +- .../prompt-editor/variable-picker-plugin.tsx | 20 +++++-- .../agent/form/components/query-variable.tsx | 8 ++- .../components/select-with-secondary-menu.tsx | 6 +- .../structured-output-secondary-menu.tsx | 7 ++- .../dynamic-group-variable.tsx | 19 ++++++- .../form/variable-aggregator-form/index.tsx | 46 ++++++---------- .../variable-aggregator-form/name-input.tsx | 55 +++++++++++++++++++ .../form/variable-aggregator-form/schema.ts | 15 +++++ .../use-handle-name-change.ts | 37 +++++++++++++ .../use-watch-change.ts | 31 +++++++++++ 11 files changed, 207 insertions(+), 39 deletions(-) create mode 100644 web/src/pages/agent/form/variable-aggregator-form/name-input.tsx create mode 100644 web/src/pages/agent/form/variable-aggregator-form/schema.ts create mode 100644 web/src/pages/agent/form/variable-aggregator-form/use-handle-name-change.ts create mode 100644 web/src/pages/agent/form/variable-aggregator-form/use-watch-change.ts diff --git a/web/src/pages/agent/constant/index.tsx b/web/src/pages/agent/constant/index.tsx index 2e85f46c2..1f43093f6 100644 --- a/web/src/pages/agent/constant/index.tsx +++ b/web/src/pages/agent/constant/index.tsx @@ -598,7 +598,7 @@ export const initialDataOperationsValues = { export const initialVariableAssignerValues = {}; -export const initialVariableAggregatorValues = {}; +export const initialVariableAggregatorValues = { outputs: {}, groups: [] }; export const CategorizeAnchorPointPositions = [ { top: 1, right: 34 }, diff --git a/web/src/pages/agent/form/components/prompt-editor/variable-picker-plugin.tsx b/web/src/pages/agent/form/components/prompt-editor/variable-picker-plugin.tsx index 3f1d080b1..d80d0c2df 100644 --- a/web/src/pages/agent/form/components/prompt-editor/variable-picker-plugin.tsx +++ b/web/src/pages/agent/form/components/prompt-editor/variable-picker-plugin.tsx @@ -36,6 +36,7 @@ import { useShowSecondaryMenu, } from '@/pages/agent/hooks/use-build-structured-output'; import { useFilterQueryVariableOptionsByTypes } from '@/pages/agent/hooks/use-get-begin-query'; +import { get } from 'lodash'; import { PromptIdentity } from '../../agent-form/use-build-prompt-options'; import { StructuredOutputSecondaryMenu } from '../structured-output-secondary-menu'; import { ProgrammaticTag } from './constant'; @@ -45,18 +46,21 @@ class VariableInnerOption extends MenuOption { value: string; parentLabel: string | JSX.Element; icon?: ReactNode; + type?: string; constructor( label: string, value: string, parentLabel: string | JSX.Element, icon?: ReactNode, + type?: string, ) { super(value); this.label = label; this.value = value; this.parentLabel = parentLabel; this.icon = icon; + this.type = type; } } @@ -126,9 +130,10 @@ function VariablePickerMenuItem({
  • selectOptionAndCleanUp(x)} - className="hover:bg-bg-card p-1 text-text-primary rounded-sm" + className="hover:bg-bg-card p-1 text-text-primary rounded-sm flex justify-between items-center" > - {x.label} + {x.label} + {get(x, 'type')}
  • ); })} @@ -146,6 +151,7 @@ export type VariablePickerMenuOptionType = { label: string; value: string; icon: ReactNode; + type?: string; }>; }; @@ -214,7 +220,13 @@ export default function VariablePickerMenuPlugin({ x.label, x.title, x.options.map((y) => { - return new VariableInnerOption(y.label, y.value, x.label, y.icon); + return new VariableInnerOption( + y.label, + y.value, + x.label, + y.icon, + y.type, + ); }), ), ); @@ -378,7 +390,7 @@ export default function VariablePickerMenuPlugin({ const nextOptions = buildNextOptions(); return anchorElementRef.current && nextOptions.length ? ReactDOM.createPortal( -
    +
      {nextOptions.map((option, i: number) => ( void; }; export function QueryVariable({ @@ -26,6 +27,7 @@ export function QueryVariable({ label, hideLabel = false, className, + onChange, }: QueryVariableProps) { const { t } = useTranslation(); const form = useFormContext(); @@ -46,7 +48,11 @@ export function QueryVariable({ { + field.onChange(val); + onChange?.(val); + }} // allowClear types={types} > diff --git a/web/src/pages/agent/form/components/select-with-secondary-menu.tsx b/web/src/pages/agent/form/components/select-with-secondary-menu.tsx index 24c7a6f45..5f28efc4b 100644 --- a/web/src/pages/agent/form/components/select-with-secondary-menu.tsx +++ b/web/src/pages/agent/form/components/select-with-secondary-menu.tsx @@ -209,8 +209,12 @@ export function GroupedSelectWithSecondaryMenu({ onChange?.(option.value); setOpen(false); }} + className="flex items-center justify-between" > - {option.label} + {option.label} + + {get(option, 'type')} + ); })} diff --git a/web/src/pages/agent/form/components/structured-output-secondary-menu.tsx b/web/src/pages/agent/form/components/structured-output-secondary-menu.tsx index fd56a75c9..f2ecd9191 100644 --- a/web/src/pages/agent/form/components/structured-output-secondary-menu.tsx +++ b/web/src/pages/agent/form/components/structured-output-secondary-menu.tsx @@ -112,9 +112,12 @@ export function StructuredOutputSecondaryMenu({
    • - {data.label} +
      + {data.label} object +
      +
    • + {(field) => ( + + )} + + {/* Use a hidden form to store data types; otherwise, data loss may occur. */} + -