Feat: Constructing query parameter options for the Retrieval operator #3221 (#8152)

### What problem does this PR solve?

Feat: Constructing query parameter options for the Retrieval operator
#3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-06-10 10:49:41 +08:00 committed by GitHub
parent 9c6c6c51e0
commit 08f2223a6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 73 additions and 23 deletions

View File

@ -153,7 +153,7 @@ export const SelectWithSearch = forwardRef<
<span className="text-lg leading-none"> <span className="text-lg leading-none">
{option.label} {option.label}
</span> </span>
{option.value}
{value === option.value && ( {value === option.value && (
<CheckIcon size={16} className="ml-auto" /> <CheckIcon size={16} className="ml-auto" />
)} )}

View File

@ -11,6 +11,7 @@ export interface DSL {
graph?: IGraph; graph?: IGraph;
messages: Message[]; messages: Message[];
reference: IReference[]; reference: IReference[];
globals: Record<string, any>;
} }
export interface IOperator { export interface IOperator {

View File

@ -57,7 +57,7 @@ export function ButtonEdge({
if (previousGraphPath.length > 0 && previousLatestElement) { if (previousGraphPath.length > 0 && previousLatestElement) {
graphPath = [previousLatestElement, ...graphPath]; graphPath = [previousLatestElement, ...graphPath];
} }
return graphPath; return Array.isArray(graphPath) ? graphPath : [];
}, [flowDetail.dsl?.path]); }, [flowDetail.dsl?.path]);
const highlightStyle = useMemo(() => { const highlightStyle = useMemo(() => {

View File

@ -2,7 +2,9 @@ import { useTheme } from '@/components/theme-provider';
import { IAgentNode } from '@/interfaces/database/flow'; import { IAgentNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react'; import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames'; import classNames from 'classnames';
import { memo } from 'react'; import { memo, useMemo } from 'react';
import { Operator } from '../../constant';
import useGraphStore from '../../store';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less'; import styles from './index.less';
import NodeHeader from './node-header'; import NodeHeader from './node-header';
@ -14,6 +16,15 @@ function InnerAgentNode({
selected, selected,
}: NodeProps<IAgentNode>) { }: NodeProps<IAgentNode>) {
const { theme } = useTheme(); const { theme } = useTheme();
const getNode = useGraphStore((state) => state.getNode);
const edges = useGraphStore((state) => state.edges);
const isNotParentAgent = useMemo(() => {
const edge = edges.find((x) => x.target === id);
const label = getNode(edge?.source)?.data.label;
return label !== Operator.Agent;
}, [edges, getNode, id]);
return ( return (
<section <section
className={classNames( className={classNames(
@ -24,6 +35,8 @@ function InnerAgentNode({
}, },
)} )}
> >
{isNotParentAgent && (
<>
<Handle <Handle
id="c" id="c"
type="source" type="source"
@ -40,6 +53,8 @@ function InnerAgentNode({
id="b" id="b"
style={RightHandleStyle} style={RightHandleStyle}
></Handle> ></Handle>
</>
)}
<Handle <Handle
type="target" type="target"
position={Position.Top} position={Position.Top}

View File

@ -442,7 +442,7 @@ const initialQueryBaseValues = {
export const initialRetrievalValues = { export const initialRetrievalValues = {
query: '', query: '',
top_n: 0.2, top_n: 8,
top_k: 1024, top_k: 1024,
kb_ids: [], kb_ids: [],
rerank_id: '', rerank_id: '',

View File

@ -6,12 +6,31 @@ import {
FormLabel, FormLabel,
FormMessage, FormMessage,
} from '@/components/ui/form'; } from '@/components/ui/form';
import { useFetchAgent } from '@/hooks/use-agent-request';
import { useContext, 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 { AgentFormContext } from '../../context';
import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query';
export function QueryVariable() { export function QueryVariable() {
const { t } = useTranslation(); const { t } = useTranslation();
const form = useFormContext(); const form = useFormContext();
const { data } = useFetchAgent();
const node = useContext(AgentFormContext);
const options = useBuildComponentIdSelectOptions(node?.id, node?.parentId);
const nextOptions = useMemo(() => {
const globalOptions = Object.keys(data?.dsl?.globals ?? {}).map((x) => ({
label: x,
value: x,
}));
return [
{ ...options[0], options: [...options[0]?.options, ...globalOptions] },
...options.slice(1),
];
}, [data.dsl.globals, options]);
return ( return (
<FormField <FormField
@ -21,7 +40,10 @@ export function QueryVariable() {
<FormItem> <FormItem>
<FormLabel tooltip={t('chat.modelTip')}>{t('flow.query')}</FormLabel> <FormLabel tooltip={t('chat.modelTip')}>{t('flow.query')}</FormLabel>
<FormControl> <FormControl>
<SelectWithSearch {...field}></SelectWithSearch> <SelectWithSearch
options={nextOptions}
{...field}
></SelectWithSearch>
</FormControl> </FormControl>
<FormMessage /> <FormMessage />
</FormItem> </FormItem>

View File

@ -128,9 +128,10 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) {
const addNode = useGraphStore((state) => state.addNode); const addNode = useGraphStore((state) => state.addNode);
const getNode = useGraphStore((state) => state.getNode); const getNode = useGraphStore((state) => state.getNode);
const addEdge = useGraphStore((state) => state.addEdge); const addEdge = useGraphStore((state) => state.addEdge);
const nodes = useGraphStore((state) => state.nodes);
const edges = useGraphStore((state) => state.edges);
const getNodeName = useGetNodeName(); const getNodeName = useGetNodeName();
const initializeOperatorParams = useInitializeOperatorParams(); const initializeOperatorParams = useInitializeOperatorParams();
const nodes = useGraphStore((state) => state.nodes);
// const [reactFlowInstance, setReactFlowInstance] = // const [reactFlowInstance, setReactFlowInstance] =
// useState<ReactFlowInstance<any, any>>(); // useState<ReactFlowInstance<any, any>>();
@ -182,8 +183,19 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) {
} else if (type === Operator.Agent) { } else if (type === Operator.Agent) {
const agentNode = getNode(id); const agentNode = getNode(id);
if (agentNode) { if (agentNode) {
// Calculate the coordinates of child nodes to prevent newly added child nodes from covering other child nodes
const allChildAgentNodeIds = edges
.filter((x) => x.source === id && x.sourceHandle === 'e')
.map((x) => x.target);
const xAxises = nodes
.filter((x) => allChildAgentNodeIds.some((y) => y === x.id))
.map((x) => x.position.x);
const maxX = Math.max(...xAxises);
newNode.position = { newNode.position = {
x: agentNode.position.x + 82, x: xAxises.length > 0 ? maxX + 262 : agentNode.position.x + 82,
y: agentNode.position.y + 140, y: agentNode.position.y + 140,
}; };
} }