mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
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:
@ -58,6 +58,7 @@ function InnerToolNode({
|
|||||||
const mcp = x as unknown as IAgentForm['mcp'][number];
|
const mcp = x as unknown as IAgentForm['mcp'][number];
|
||||||
return (
|
return (
|
||||||
<ToolCard
|
<ToolCard
|
||||||
|
key={mcp.mcp_id}
|
||||||
onClick={handleClick(mcp.mcp_id)}
|
onClick={handleClick(mcp.mcp_id)}
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
data-tool={x.mcp_id}
|
data-tool={x.mcp_id}
|
||||||
@ -70,6 +71,7 @@ function InnerToolNode({
|
|||||||
const tool = x as unknown as IAgentForm['tools'][number];
|
const tool = x as unknown as IAgentForm['tools'][number];
|
||||||
return (
|
return (
|
||||||
<ToolCard
|
<ToolCard
|
||||||
|
key={tool.component_name}
|
||||||
onClick={handleClick(tool.component_name)}
|
onClick={handleClick(tool.component_name)}
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
data-tool={tool.component_name}
|
data-tool={tool.component_name}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import {
|
import {
|
||||||
AgentExceptionMethod,
|
AgentExceptionMethod,
|
||||||
|
JsonSchemaDataType,
|
||||||
NodeHandleId,
|
NodeHandleId,
|
||||||
VariableType,
|
VariableType,
|
||||||
initialAgentValues,
|
initialAgentValues,
|
||||||
@ -157,6 +158,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
placeholder={t('flow.messagePlaceholder')}
|
placeholder={t('flow.messagePlaceholder')}
|
||||||
showToolbar={true}
|
showToolbar={true}
|
||||||
extraOptions={extraOptions}
|
extraOptions={extraOptions}
|
||||||
|
types={[JsonSchemaDataType.String]}
|
||||||
></PromptEditor>
|
></PromptEditor>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -174,6 +176,7 @@ function AgentForm({ node }: INextOperatorForm) {
|
|||||||
<PromptEditor
|
<PromptEditor
|
||||||
{...field}
|
{...field}
|
||||||
showToolbar={true}
|
showToolbar={true}
|
||||||
|
types={[JsonSchemaDataType.String]}
|
||||||
></PromptEditor>
|
></PromptEditor>
|
||||||
</section>
|
</section>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import {
|
|||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@/components/ui/tooltip';
|
} from '@/components/ui/tooltip';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { JsonSchemaDataType } from '@/pages/agent/constant';
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||||
import { Variable } from 'lucide-react';
|
import { Variable } from 'lucide-react';
|
||||||
import { ReactNode, useCallback, useState } from 'react';
|
import { ReactNode, useCallback, useState } from 'react';
|
||||||
@ -54,6 +55,7 @@ type IProps = {
|
|||||||
value?: string;
|
value?: string;
|
||||||
onChange?: (value?: string) => void;
|
onChange?: (value?: string) => void;
|
||||||
placeholder?: ReactNode;
|
placeholder?: ReactNode;
|
||||||
|
types?: JsonSchemaDataType[];
|
||||||
} & PromptContentProps &
|
} & PromptContentProps &
|
||||||
Pick<VariablePickerMenuPluginProps, 'extraOptions' | 'baseOptions'>;
|
Pick<VariablePickerMenuPluginProps, 'extraOptions' | 'baseOptions'>;
|
||||||
|
|
||||||
@ -127,6 +129,7 @@ export function PromptEditor({
|
|||||||
multiLine = true,
|
multiLine = true,
|
||||||
extraOptions,
|
extraOptions,
|
||||||
baseOptions,
|
baseOptions,
|
||||||
|
types,
|
||||||
}: IProps) {
|
}: IProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const initialConfig: InitialConfigType = {
|
const initialConfig: InitialConfigType = {
|
||||||
@ -179,6 +182,7 @@ export function PromptEditor({
|
|||||||
value={value}
|
value={value}
|
||||||
extraOptions={extraOptions}
|
extraOptions={extraOptions}
|
||||||
baseOptions={baseOptions}
|
baseOptions={baseOptions}
|
||||||
|
types={types}
|
||||||
></VariablePickerMenuPlugin>
|
></VariablePickerMenuPlugin>
|
||||||
<PasteHandlerPlugin />
|
<PasteHandlerPlugin />
|
||||||
<VariableOnChangePlugin
|
<VariableOnChangePlugin
|
||||||
|
|||||||
@ -30,11 +30,12 @@ import * as ReactDOM from 'react-dom';
|
|||||||
|
|
||||||
import { $createVariableNode } from './variable-node';
|
import { $createVariableNode } from './variable-node';
|
||||||
|
|
||||||
|
import { JsonSchemaDataType } from '@/pages/agent/constant';
|
||||||
import {
|
import {
|
||||||
useFindAgentStructuredOutputLabel,
|
useFindAgentStructuredOutputLabel,
|
||||||
useShowSecondaryMenu,
|
useShowSecondaryMenu,
|
||||||
} from '@/pages/agent/hooks/use-build-structured-output';
|
} 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 { PromptIdentity } from '../../agent-form/use-build-prompt-options';
|
||||||
import { StructuredOutputSecondaryMenu } from '../structured-output-secondary-menu';
|
import { StructuredOutputSecondaryMenu } from '../structured-output-secondary-menu';
|
||||||
import { ProgrammaticTag } from './constant';
|
import { ProgrammaticTag } from './constant';
|
||||||
@ -80,9 +81,11 @@ function VariablePickerMenuItem({
|
|||||||
index,
|
index,
|
||||||
option,
|
option,
|
||||||
selectOptionAndCleanUp,
|
selectOptionAndCleanUp,
|
||||||
|
types,
|
||||||
}: {
|
}: {
|
||||||
index: number;
|
index: number;
|
||||||
option: VariableOption;
|
option: VariableOption;
|
||||||
|
types?: JsonSchemaDataType[];
|
||||||
selectOptionAndCleanUp: (
|
selectOptionAndCleanUp: (
|
||||||
option: VariableOption | VariableInnerOption,
|
option: VariableOption | VariableInnerOption,
|
||||||
) => void;
|
) => void;
|
||||||
@ -108,6 +111,7 @@ function VariablePickerMenuItem({
|
|||||||
<StructuredOutputSecondaryMenu
|
<StructuredOutputSecondaryMenu
|
||||||
key={x.value}
|
key={x.value}
|
||||||
data={x}
|
data={x}
|
||||||
|
types={types}
|
||||||
click={(y) =>
|
click={(y) =>
|
||||||
selectOptionAndCleanUp({
|
selectOptionAndCleanUp({
|
||||||
...x,
|
...x,
|
||||||
@ -149,11 +153,13 @@ export type VariablePickerMenuPluginProps = {
|
|||||||
value?: string;
|
value?: string;
|
||||||
extraOptions?: VariablePickerMenuOptionType[];
|
extraOptions?: VariablePickerMenuOptionType[];
|
||||||
baseOptions?: VariablePickerMenuOptionType[];
|
baseOptions?: VariablePickerMenuOptionType[];
|
||||||
|
types?: JsonSchemaDataType[];
|
||||||
};
|
};
|
||||||
export default function VariablePickerMenuPlugin({
|
export default function VariablePickerMenuPlugin({
|
||||||
value,
|
value,
|
||||||
extraOptions,
|
extraOptions,
|
||||||
baseOptions,
|
baseOptions,
|
||||||
|
types,
|
||||||
}: VariablePickerMenuPluginProps): JSX.Element {
|
}: VariablePickerMenuPluginProps): JSX.Element {
|
||||||
const [editor] = useLexicalComposerContext();
|
const [editor] = useLexicalComposerContext();
|
||||||
|
|
||||||
@ -180,7 +186,7 @@ export default function VariablePickerMenuPlugin({
|
|||||||
|
|
||||||
const [queryString, setQueryString] = React.useState<string | null>('');
|
const [queryString, setQueryString] = React.useState<string | null>('');
|
||||||
|
|
||||||
let options = useBuildQueryVariableOptions();
|
let options = useFilterQueryVariableOptionsByTypes(types);
|
||||||
|
|
||||||
if (baseOptions) {
|
if (baseOptions) {
|
||||||
options = baseOptions as typeof options;
|
options = baseOptions as typeof options;
|
||||||
@ -379,6 +385,7 @@ export default function VariablePickerMenuPlugin({
|
|||||||
index={i}
|
index={i}
|
||||||
key={option.key}
|
key={option.key}
|
||||||
option={option}
|
option={option}
|
||||||
|
types={types}
|
||||||
selectOptionAndCleanUp={selectOptionAndCleanUp}
|
selectOptionAndCleanUp={selectOptionAndCleanUp}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -5,12 +5,11 @@ import {
|
|||||||
FormLabel,
|
FormLabel,
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { isEmpty, toLower } from 'lodash';
|
import { ReactNode } from 'react';
|
||||||
import { ReactNode, useMemo } from 'react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { JsonSchemaDataType } from '../../constant';
|
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';
|
import { GroupedSelectWithSecondaryMenu } from './select-with-secondary-menu';
|
||||||
|
|
||||||
type QueryVariableProps = {
|
type QueryVariableProps = {
|
||||||
@ -31,22 +30,7 @@ export function QueryVariable({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
|
|
||||||
const nextOptions = useBuildQueryVariableOptions();
|
const finalOptions = useFilterQueryVariableOptionsByTypes(types);
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField
|
<FormField
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { memo } from 'react';
|
|||||||
import { useFieldArray, useForm } from 'react-hook-form';
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { JsonSchemaDataType } from '../../constant';
|
||||||
import { INextOperatorForm } from '../../interface';
|
import { INextOperatorForm } from '../../interface';
|
||||||
import { FormWrapper } from '../components/form-wrapper';
|
import { FormWrapper } from '../components/form-wrapper';
|
||||||
import { PromptEditor } from '../components/prompt-editor';
|
import { PromptEditor } from '../components/prompt-editor';
|
||||||
@ -66,6 +67,7 @@ function MessageForm({ node }: INextOperatorForm) {
|
|||||||
<PromptEditor
|
<PromptEditor
|
||||||
{...field}
|
{...field}
|
||||||
placeholder={t('flow.messagePlaceholder')}
|
placeholder={t('flow.messagePlaceholder')}
|
||||||
|
types={[JsonSchemaDataType.String]}
|
||||||
></PromptEditor>
|
></PromptEditor>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@ -4,12 +4,14 @@ import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
|||||||
import { buildNodeOutputOptions } from '@/utils/canvas-util';
|
import { buildNodeOutputOptions } from '@/utils/canvas-util';
|
||||||
import { DefaultOptionType } from 'antd/es/select';
|
import { DefaultOptionType } from 'antd/es/select';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
import { isEmpty, toLower } from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
AgentDialogueMode,
|
AgentDialogueMode,
|
||||||
BeginId,
|
BeginId,
|
||||||
BeginQueryType,
|
BeginQueryType,
|
||||||
|
JsonSchemaDataType,
|
||||||
Operator,
|
Operator,
|
||||||
VariableType,
|
VariableType,
|
||||||
} from '../constant';
|
} from '../constant';
|
||||||
@ -171,6 +173,29 @@ export function useBuildQueryVariableOptions(n?: RAGFlowNodeType) {
|
|||||||
return nextOptions;
|
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) {
|
export function useBuildComponentIdOptions(nodeId?: string, parentId?: string) {
|
||||||
const nodes = useGraphStore((state) => state.nodes);
|
const nodes = useGraphStore((state) => state.nodes);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user