Feat: The agent operator and message operator can only select string variables as prompt words. #10427 (#11054)

### What problem does this PR solve?

Feat: The agent operator and message operator can only select string
variables as prompt words. #10427
### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-11-06 13:58:20 +08:00
committed by GitHub
parent f581a1c4e5
commit d469ae6d50
7 changed files with 48 additions and 21 deletions

View File

@ -58,6 +58,7 @@ function InnerToolNode({
const mcp = x as unknown as IAgentForm['mcp'][number];
return (
<ToolCard
key={mcp.mcp_id}
onClick={handleClick(mcp.mcp_id)}
className="cursor-pointer"
data-tool={x.mcp_id}
@ -70,6 +71,7 @@ function InnerToolNode({
const tool = x as unknown as IAgentForm['tools'][number];
return (
<ToolCard
key={tool.component_name}
onClick={handleClick(tool.component_name)}
className="cursor-pointer"
data-tool={tool.component_name}

View File

@ -26,6 +26,7 @@ import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import {
AgentExceptionMethod,
JsonSchemaDataType,
NodeHandleId,
VariableType,
initialAgentValues,
@ -157,6 +158,7 @@ function AgentForm({ node }: INextOperatorForm) {
placeholder={t('flow.messagePlaceholder')}
showToolbar={true}
extraOptions={extraOptions}
types={[JsonSchemaDataType.String]}
></PromptEditor>
</FormControl>
</FormItem>
@ -174,6 +176,7 @@ function AgentForm({ node }: INextOperatorForm) {
<PromptEditor
{...field}
showToolbar={true}
types={[JsonSchemaDataType.String]}
></PromptEditor>
</section>
</FormControl>

View File

@ -21,6 +21,7 @@ import {
TooltipTrigger,
} from '@/components/ui/tooltip';
import { cn } from '@/lib/utils';
import { JsonSchemaDataType } from '@/pages/agent/constant';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { Variable } from 'lucide-react';
import { ReactNode, useCallback, useState } from 'react';
@ -54,6 +55,7 @@ type IProps = {
value?: string;
onChange?: (value?: string) => void;
placeholder?: ReactNode;
types?: JsonSchemaDataType[];
} & PromptContentProps &
Pick<VariablePickerMenuPluginProps, 'extraOptions' | 'baseOptions'>;
@ -127,6 +129,7 @@ export function PromptEditor({
multiLine = true,
extraOptions,
baseOptions,
types,
}: IProps) {
const { t } = useTranslation();
const initialConfig: InitialConfigType = {
@ -179,6 +182,7 @@ export function PromptEditor({
value={value}
extraOptions={extraOptions}
baseOptions={baseOptions}
types={types}
></VariablePickerMenuPlugin>
<PasteHandlerPlugin />
<VariableOnChangePlugin

View File

@ -30,11 +30,12 @@ import * as ReactDOM from 'react-dom';
import { $createVariableNode } from './variable-node';
import { JsonSchemaDataType } from '@/pages/agent/constant';
import {
useFindAgentStructuredOutputLabel,
useShowSecondaryMenu,
} from '@/pages/agent/hooks/use-build-structured-output';
import { useBuildQueryVariableOptions } from '@/pages/agent/hooks/use-get-begin-query';
import { useFilterQueryVariableOptionsByTypes } from '@/pages/agent/hooks/use-get-begin-query';
import { PromptIdentity } from '../../agent-form/use-build-prompt-options';
import { StructuredOutputSecondaryMenu } from '../structured-output-secondary-menu';
import { ProgrammaticTag } from './constant';
@ -80,9 +81,11 @@ function VariablePickerMenuItem({
index,
option,
selectOptionAndCleanUp,
types,
}: {
index: number;
option: VariableOption;
types?: JsonSchemaDataType[];
selectOptionAndCleanUp: (
option: VariableOption | VariableInnerOption,
) => void;
@ -108,6 +111,7 @@ function VariablePickerMenuItem({
<StructuredOutputSecondaryMenu
key={x.value}
data={x}
types={types}
click={(y) =>
selectOptionAndCleanUp({
...x,
@ -149,11 +153,13 @@ export type VariablePickerMenuPluginProps = {
value?: string;
extraOptions?: VariablePickerMenuOptionType[];
baseOptions?: VariablePickerMenuOptionType[];
types?: JsonSchemaDataType[];
};
export default function VariablePickerMenuPlugin({
value,
extraOptions,
baseOptions,
types,
}: VariablePickerMenuPluginProps): JSX.Element {
const [editor] = useLexicalComposerContext();
@ -180,7 +186,7 @@ export default function VariablePickerMenuPlugin({
const [queryString, setQueryString] = React.useState<string | null>('');
let options = useBuildQueryVariableOptions();
let options = useFilterQueryVariableOptionsByTypes(types);
if (baseOptions) {
options = baseOptions as typeof options;
@ -379,6 +385,7 @@ export default function VariablePickerMenuPlugin({
index={i}
key={option.key}
option={option}
types={types}
selectOptionAndCleanUp={selectOptionAndCleanUp}
/>
))}

View File

@ -5,12 +5,11 @@ import {
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { isEmpty, toLower } from 'lodash';
import { ReactNode, useMemo } from 'react';
import { ReactNode } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { JsonSchemaDataType } from '../../constant';
import { useBuildQueryVariableOptions } from '../../hooks/use-get-begin-query';
import { useFilterQueryVariableOptionsByTypes } from '../../hooks/use-get-begin-query';
import { GroupedSelectWithSecondaryMenu } from './select-with-secondary-menu';
type QueryVariableProps = {
@ -31,22 +30,7 @@ export function QueryVariable({
const { t } = useTranslation();
const form = useFormContext();
const nextOptions = useBuildQueryVariableOptions();
const finalOptions = useMemo(() => {
return !isEmpty(types)
? nextOptions.map((x) => {
return {
...x,
options: x.options.filter(
(y) =>
types?.some((x) => toLower(y.type).includes(x)) ||
y.type === undefined, // agent structured output
),
};
})
: nextOptions;
}, [nextOptions, types]);
const finalOptions = useFilterQueryVariableOptionsByTypes(types);
return (
<FormField

View File

@ -14,6 +14,7 @@ import { memo } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import { JsonSchemaDataType } from '../../constant';
import { INextOperatorForm } from '../../interface';
import { FormWrapper } from '../components/form-wrapper';
import { PromptEditor } from '../components/prompt-editor';
@ -66,6 +67,7 @@ function MessageForm({ node }: INextOperatorForm) {
<PromptEditor
{...field}
placeholder={t('flow.messagePlaceholder')}
types={[JsonSchemaDataType.String]}
></PromptEditor>
</FormControl>
</FormItem>

View File

@ -4,12 +4,14 @@ import { RAGFlowNodeType } from '@/interfaces/database/flow';
import { buildNodeOutputOptions } from '@/utils/canvas-util';
import { DefaultOptionType } from 'antd/es/select';
import { t } from 'i18next';
import { isEmpty, toLower } from 'lodash';
import get from 'lodash/get';
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import {
AgentDialogueMode,
BeginId,
BeginQueryType,
JsonSchemaDataType,
Operator,
VariableType,
} from '../constant';
@ -171,6 +173,29 @@ export function useBuildQueryVariableOptions(n?: RAGFlowNodeType) {
return nextOptions;
}
export function useFilterQueryVariableOptionsByTypes(
types?: JsonSchemaDataType[],
) {
const nextOptions = useBuildQueryVariableOptions();
const filteredOptions = useMemo(() => {
return !isEmpty(types)
? nextOptions.map((x) => {
return {
...x,
options: x.options.filter(
(y) =>
types?.some((x) => toLower(y.type).includes(x)) ||
y.type === undefined, // agent structured output
),
};
})
: nextOptions;
}, [nextOptions, types]);
return filteredOptions;
}
export function useBuildComponentIdOptions(nodeId?: string, parentId?: string) {
const nodes = useGraphStore((state) => state.nodes);