diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 7d2d7783e..b65148b4a 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -843,7 +843,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 relevant: '是否相关', rewriteQuestion: '问题优化', begin: '开始', - message: '静态消息', + message: '回复消息', blank: '空', createFromNothing: '从无到有', addItem: '新增', @@ -1245,7 +1245,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 modeTip: '模式定义了工作流的启动方式。', beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。', query: '查询变量', - agent: 'Agent', + agent: '智能体', agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。', maxRecords: '最大记录数', createAgent: 'Create Agent', diff --git a/web/src/pages/agent/hooks.tsx b/web/src/pages/agent/hooks.tsx index 40cf6e1cb..ed27e7a37 100644 --- a/web/src/pages/agent/hooks.tsx +++ b/web/src/pages/agent/hooks.tsx @@ -1,6 +1,7 @@ import { Connection, Edge, + getOutgoers, Node, Position, ReactFlowInstance, @@ -15,9 +16,6 @@ import { get, lowerFirst, omit } from 'lodash'; import { UseFormReturn } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { - NodeMap, - Operator, - RestrictedUpstreamMap, initialAgentValues, initialAkShareValues, initialArXivValues, @@ -57,6 +55,9 @@ import { initialWenCaiValues, initialWikipediaValues, initialYahooFinanceValues, + NodeMap, + Operator, + RestrictedUpstreamMap, } from './constant'; import useGraphStore, { RFState } from './store'; import { @@ -333,9 +334,8 @@ export const useHandleFormValuesChange = ( }; export const useValidateConnection = () => { - const { getOperatorTypeFromId, getParentIdById } = useGraphStore( - (state) => state, - ); + const { getOperatorTypeFromId, getParentIdById, edges, nodes } = + useGraphStore((state) => state); const isSameNodeChild = useCallback( (connection: Connection | Edge) => { @@ -349,6 +349,27 @@ export const useValidateConnection = () => { [getParentIdById], ); + const hasCanvasCycle = useCallback( + (connection: Connection | Edge) => { + const target = nodes.find((node) => node.id === connection.target); + const hasCycle = (node: RAGFlowNodeType, visited = new Set()) => { + if (visited.has(node.id)) return false; + + visited.add(node.id); + + for (const outgoer of getOutgoers(node, nodes, edges)) { + if (outgoer.id === connection.source) return true; + if (hasCycle(outgoer, visited)) return true; + } + }; + + if (target?.id === connection.source) return false; + + return target ? !hasCycle(target) : false; + }, + [edges, nodes], + ); + // restricted lines cannot be connected successfully. const isValidConnection = useCallback( (connection: Connection | Edge) => { @@ -365,10 +386,11 @@ export const useValidateConnection = () => { RestrictedUpstreamMap[ getOperatorTypeFromId(connection.source) as Operator ]?.every((x) => x !== getOperatorTypeFromId(connection.target)) && - isSameNodeChild(connection); + isSameNodeChild(connection) && + hasCanvasCycle(connection); return ret; }, - [getOperatorTypeFromId, isSameNodeChild], + [getOperatorTypeFromId, hasCanvasCycle, isSameNodeChild], ); return isValidConnection;