diff --git a/packages/editor-ui/src/composables/useCanvasOperations.ts b/packages/editor-ui/src/composables/useCanvasOperations.ts index 8836cff72f7..240d3e23482 100644 --- a/packages/editor-ui/src/composables/useCanvasOperations.ts +++ b/packages/editor-ui/src/composables/useCanvasOperations.ts @@ -490,7 +490,6 @@ export function useCanvasOperations({ router }: { router: ReturnType { nodeHelpers.updateNodeInputIssues(sourceNode); nodeHelpers.updateNodeInputIssues(targetNode); - adjustNewNodes(sourceNode, targetNode, { parentIsNew, childIsNew }); }); if (!keepPristine) { diff --git a/packages/editor-ui/src/constants.ts b/packages/editor-ui/src/constants.ts index 0d70e156c22..dd35b7467c6 100644 --- a/packages/editor-ui/src/constants.ts +++ b/packages/editor-ui/src/constants.ts @@ -144,6 +144,12 @@ export const OPEN_AI_NODE_MESSAGE_ASSISTANT_TYPE = export const OPEN_AI_ASSISTANT_NODE_TYPE = '@n8n/n8n-nodes-langchain.openAiAssistant'; export const BASIC_CHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.chainLlm'; export const QA_CHAIN_NODE_TYPE = '@n8n/n8n-nodes-langchain.chainRetrievalQa'; +export const MEMORY_BUFFER_WINDOW_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryBufferWindow'; +export const MEMORY_MOTORHEAD_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryMotorhead'; +export const MEMORY_POSTGRES_CHAT_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryPostgresChat'; +export const MEMORY_REDIS_CHAT_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryRedisChat'; +export const MEMORY_XATA_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryXata'; +export const MEMORY_ZEP_NODE_TYPE = '@n8n/n8n-nodes-langchain.memoryZep'; export const MICROSOFT_TEAMS_NODE_TYPE = 'n8n-nodes-base.microsoftTeams'; export const N8N_NODE_TYPE = 'n8n-nodes-base.n8n'; export const NO_OP_NODE_TYPE = 'n8n-nodes-base.noOp'; @@ -234,6 +240,23 @@ export const LIST_LIKE_NODE_OPERATIONS = ['getAll', 'getMany', 'read', 'search'] export const PRODUCTION_ONLY_TRIGGER_NODE_TYPES = [CHAT_TRIGGER_NODE_TYPE]; +export const AI_ROOT_NODE_TYPES = [ + QA_CHAIN_NODE_TYPE, + AGENT_NODE_TYPE, + BASIC_CHAIN_NODE_TYPE, + OPEN_AI_ASSISTANT_NODE_TYPE, + OPEN_AI_NODE_MESSAGE_ASSISTANT_TYPE, +]; + +export const AI_MEMORY_NODE_TYPES = [ + MEMORY_BUFFER_WINDOW_NODE_TYPE, + MEMORY_MOTORHEAD_NODE_TYPE, + MEMORY_POSTGRES_CHAT_NODE_TYPE, + MEMORY_REDIS_CHAT_NODE_TYPE, + MEMORY_XATA_NODE_TYPE, + MEMORY_ZEP_NODE_TYPE, +]; + // Node creator export const NODE_CREATOR_OPEN_SOURCES: Record< Uppercase, diff --git a/packages/editor-ui/src/utils/connectionNodeUtils.ts b/packages/editor-ui/src/utils/connectionNodeUtils.ts index b7cd91a71e3..86d583f26f5 100644 --- a/packages/editor-ui/src/utils/connectionNodeUtils.ts +++ b/packages/editor-ui/src/utils/connectionNodeUtils.ts @@ -1,32 +1,8 @@ import { type INode } from 'n8n-workflow'; -import { - AGENT_NODE_TYPE, - BASIC_CHAIN_NODE_TYPE, - CHAT_TRIGGER_NODE_TYPE, - OPEN_AI_ASSISTANT_NODE_TYPE, - OPEN_AI_NODE_MESSAGE_ASSISTANT_TYPE, - QA_CHAIN_NODE_TYPE, -} from '@/constants'; +import { AI_MEMORY_NODE_TYPES, AI_ROOT_NODE_TYPES, CHAT_TRIGGER_NODE_TYPE } from '@/constants'; import { useWorkflowsStore } from '@/stores/workflows.store'; import type { AddedNode } from '@/Interface'; -const AI_NODES = [ - QA_CHAIN_NODE_TYPE, - AGENT_NODE_TYPE, - BASIC_CHAIN_NODE_TYPE, - OPEN_AI_ASSISTANT_NODE_TYPE, - OPEN_AI_NODE_MESSAGE_ASSISTANT_TYPE, -]; - -const MEMORY_NODE_NAMES = [ - '@n8n/n8n-nodes-langchain.memoryBufferWindow', - '@n8n/n8n-nodes-langchain.memoryMotorhead', - '@n8n/n8n-nodes-langchain.memoryPostgresChat', - '@n8n/n8n-nodes-langchain.memoryRedisChat', - '@n8n/n8n-nodes-langchain.memoryXata', - '@n8n/n8n-nodes-langchain.memoryZep', -]; - const PROMPT_PROVIDER_NODE_NAMES = [CHAT_TRIGGER_NODE_TYPE]; export function adjustNewNodes( @@ -39,22 +15,20 @@ export function adjustNewNodes( } function adjustNewChild(parent: AddedNode, child: AddedNode) { - if (AI_NODES.includes(child.type)) { - if (PROMPT_PROVIDER_NODE_NAMES.includes(parent.type)) { - Object.assign>(child, { - parameters: { ...child.parameters, promptType: 'auto', text: '={{ $json.chatInput }}' }, - }); - } + if (AI_ROOT_NODE_TYPES.includes(child.type) && PROMPT_PROVIDER_NODE_NAMES.includes(parent.type)) { + Object.assign>(child, { + parameters: { ...child.parameters, promptType: 'auto', text: '={{ $json.chatInput }}' }, + }); } } function adjustNewParent(parent: AddedNode, child: AddedNode) { - if (MEMORY_NODE_NAMES.includes(parent.type) && child.name) { + if (AI_MEMORY_NODE_TYPES.includes(parent.type) && child.name) { const { getCurrentWorkflow } = useWorkflowsStore(); const workflow = getCurrentWorkflow(); - // If a memory node is added to an Agent, the memory node is actually the parent since it provides input - // So we need to look for the Agent's parents to determine if there is a sessionId provider + // If a memory node is added to an Agent, the memory node is actually a parent since it provides input + // So we need to look for the Agent's (other) parents to determine if there is a sessionId provider const ps = workflow.getParentNodesByDepth(child.name, 1); if ( !ps.some((x) => PROMPT_PROVIDER_NODE_NAMES.includes(workflow.getNode(x.name)?.type ?? ''))