### 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)tags/v0.19.1
| @@ -153,7 +153,7 @@ export const SelectWithSearch = forwardRef< | |||
| <span className="text-lg leading-none"> | |||
| {option.label} | |||
| </span> | |||
| {option.value} | |||
| {value === option.value && ( | |||
| <CheckIcon size={16} className="ml-auto" /> | |||
| )} | |||
| @@ -11,6 +11,7 @@ export interface DSL { | |||
| graph?: IGraph; | |||
| messages: Message[]; | |||
| reference: IReference[]; | |||
| globals: Record<string, any>; | |||
| } | |||
| export interface IOperator { | |||
| @@ -57,7 +57,7 @@ export function ButtonEdge({ | |||
| if (previousGraphPath.length > 0 && previousLatestElement) { | |||
| graphPath = [previousLatestElement, ...graphPath]; | |||
| } | |||
| return graphPath; | |||
| return Array.isArray(graphPath) ? graphPath : []; | |||
| }, [flowDetail.dsl?.path]); | |||
| const highlightStyle = useMemo(() => { | |||
| @@ -2,7 +2,9 @@ import { useTheme } from '@/components/theme-provider'; | |||
| import { IAgentNode } from '@/interfaces/database/flow'; | |||
| import { Handle, NodeProps, Position } from '@xyflow/react'; | |||
| 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 styles from './index.less'; | |||
| import NodeHeader from './node-header'; | |||
| @@ -14,6 +16,15 @@ function InnerAgentNode({ | |||
| selected, | |||
| }: NodeProps<IAgentNode>) { | |||
| 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 ( | |||
| <section | |||
| className={classNames( | |||
| @@ -24,22 +35,26 @@ function InnerAgentNode({ | |||
| }, | |||
| )} | |||
| > | |||
| <Handle | |||
| id="c" | |||
| type="source" | |||
| position={Position.Left} | |||
| isConnectable={isConnectable} | |||
| className={styles.handle} | |||
| style={LeftHandleStyle} | |||
| ></Handle> | |||
| <Handle | |||
| type="source" | |||
| position={Position.Right} | |||
| isConnectable={isConnectable} | |||
| className={styles.handle} | |||
| id="b" | |||
| style={RightHandleStyle} | |||
| ></Handle> | |||
| {isNotParentAgent && ( | |||
| <> | |||
| <Handle | |||
| id="c" | |||
| type="source" | |||
| position={Position.Left} | |||
| isConnectable={isConnectable} | |||
| className={styles.handle} | |||
| style={LeftHandleStyle} | |||
| ></Handle> | |||
| <Handle | |||
| type="source" | |||
| position={Position.Right} | |||
| isConnectable={isConnectable} | |||
| className={styles.handle} | |||
| id="b" | |||
| style={RightHandleStyle} | |||
| ></Handle> | |||
| </> | |||
| )} | |||
| <Handle | |||
| type="target" | |||
| position={Position.Top} | |||
| @@ -442,7 +442,7 @@ const initialQueryBaseValues = { | |||
| export const initialRetrievalValues = { | |||
| query: '', | |||
| top_n: 0.2, | |||
| top_n: 8, | |||
| top_k: 1024, | |||
| kb_ids: [], | |||
| rerank_id: '', | |||
| @@ -6,12 +6,31 @@ import { | |||
| FormLabel, | |||
| FormMessage, | |||
| } from '@/components/ui/form'; | |||
| import { useFetchAgent } from '@/hooks/use-agent-request'; | |||
| import { useContext, useMemo } from 'react'; | |||
| import { useFormContext } from 'react-hook-form'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import { AgentFormContext } from '../../context'; | |||
| import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; | |||
| export function QueryVariable() { | |||
| const { t } = useTranslation(); | |||
| 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 ( | |||
| <FormField | |||
| @@ -21,7 +40,10 @@ export function QueryVariable() { | |||
| <FormItem> | |||
| <FormLabel tooltip={t('chat.modelTip')}>{t('flow.query')}</FormLabel> | |||
| <FormControl> | |||
| <SelectWithSearch {...field}></SelectWithSearch> | |||
| <SelectWithSearch | |||
| options={nextOptions} | |||
| {...field} | |||
| ></SelectWithSearch> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| @@ -128,9 +128,10 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) { | |||
| const addNode = useGraphStore((state) => state.addNode); | |||
| const getNode = useGraphStore((state) => state.getNode); | |||
| const addEdge = useGraphStore((state) => state.addEdge); | |||
| const nodes = useGraphStore((state) => state.nodes); | |||
| const edges = useGraphStore((state) => state.edges); | |||
| const getNodeName = useGetNodeName(); | |||
| const initializeOperatorParams = useInitializeOperatorParams(); | |||
| const nodes = useGraphStore((state) => state.nodes); | |||
| // const [reactFlowInstance, setReactFlowInstance] = | |||
| // useState<ReactFlowInstance<any, any>>(); | |||
| @@ -182,8 +183,19 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) { | |||
| } else if (type === Operator.Agent) { | |||
| const agentNode = getNode(id); | |||
| 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 = { | |||
| x: agentNode.position.x + 82, | |||
| x: xAxises.length > 0 ? maxX + 262 : agentNode.position.x + 82, | |||
| y: agentNode.position.y + 140, | |||
| }; | |||
| } | |||