UNPKG

@n8n/n8n-nodes-langchain

Version:

![Banner image](https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png)

349 lines 14.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryManager = void 0; exports.simplifyMessages = simplifyMessages; const messages_1 = require("@langchain/core/messages"); const n8n_workflow_1 = require("n8n-workflow"); function simplifyMessages(messages) { if (messages.length === 0) return []; const result = []; let index = 0; while (index < messages.length) { const currentGroup = {}; do { const message = messages[index]; const messageType = message.getType(); if (messageType in currentGroup) { break; } currentGroup[messageType] = message.content; index++; } while (index < messages.length); result.push(currentGroup); } return result; } const prepareOutputSetup = (ctx, version, memory) => { if (version === 1) { return async (i) => { const messages = await memory.chatHistory.getMessages(); const serializedMessages = messages?.map((message) => message.toJSON()) ?? []; const executionData = ctx.helpers.constructExecutionMetaData(ctx.helpers.returnJsonArray(serializedMessages), { itemData: { item: i } }); return executionData; }; } return async (i) => { return [ { json: { success: true }, pairedItem: { item: i }, }, ]; }; }; class MemoryManager { constructor() { this.description = { displayName: 'Chat Memory Manager', name: 'memoryManager', icon: 'node:chat-memory-manager', iconColor: 'black', group: ['transform'], version: [1, 1.1], description: 'Manage chat messages memory and use it in the workflow', defaults: { name: 'Chat Memory Manager', }, codex: { categories: ['AI'], subcategories: { AI: ['Miscellaneous', 'Root Nodes'], }, resources: { primaryDocumentation: [ { url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.memorymanager/', }, ], }, }, inputs: [ { displayName: '', type: n8n_workflow_1.NodeConnectionTypes.Main, }, { displayName: 'Memory', type: n8n_workflow_1.NodeConnectionTypes.AiMemory, required: true, maxConnections: 1, }, ], outputs: [ { displayName: '', type: n8n_workflow_1.NodeConnectionTypes.Main, }, ], properties: [ { displayName: 'Operation Mode', name: 'mode', type: 'options', noDataExpression: true, default: 'load', options: [ { name: 'Get Many Messages', description: 'Retrieve chat messages from connected memory', value: 'load', }, { name: 'Insert Messages', description: 'Insert chat messages into connected memory', value: 'insert', }, { name: 'Delete Messages', description: 'Delete chat messages from connected memory', value: 'delete', }, ], }, { displayName: 'Insert Mode', name: 'insertMode', type: 'options', description: 'Choose how new messages are inserted into the memory', noDataExpression: true, default: 'insert', options: [ { name: 'Insert Messages', value: 'insert', description: 'Add messages alongside existing ones', }, { name: 'Override All Messages', value: 'override', description: 'Replace the current memory with new messages', }, ], displayOptions: { show: { mode: ['insert'], }, }, }, { displayName: 'Delete Mode', name: 'deleteMode', type: 'options', description: 'How messages are deleted from memory', noDataExpression: true, default: 'lastN', options: [ { name: 'Last N', value: 'lastN', description: 'Delete the last N messages', }, { name: 'All Messages', value: 'all', description: 'Clear all messages from memory', }, ], displayOptions: { show: { mode: ['delete'], }, }, }, { displayName: 'Chat Messages', name: 'messages', description: 'Chat messages to insert into memory', type: 'fixedCollection', typeOptions: { multipleValues: true, }, default: {}, placeholder: 'Add message', options: [ { name: 'messageValues', displayName: 'Message', values: [ { displayName: 'Type Name or ID', name: 'type', type: 'options', options: [ { name: 'AI', value: 'ai', }, { name: 'System', value: 'system', }, { name: 'User', value: 'user', }, ], default: 'system', }, { displayName: 'Message', name: 'message', type: 'string', required: true, default: '', }, { displayName: 'Hide Message in Chat', name: 'hideFromUI', type: 'boolean', required: true, default: false, description: 'Whether to hide the message from the chat UI', }, ], }, ], displayOptions: { show: { mode: ['insert'], }, }, }, { displayName: 'Messages Count', name: 'lastMessagesCount', type: 'number', description: 'The amount of last messages to delete', default: 2, displayOptions: { show: { mode: ['delete'], deleteMode: ['lastN'], }, }, }, { displayName: 'Simplify Output', name: 'simplifyOutput', type: 'boolean', description: 'Whether to simplify the output to only include the sender and the text', default: true, displayOptions: { show: { mode: ['load'], }, }, }, { displayName: 'Options', name: 'options', placeholder: 'Add Option', type: 'collection', default: {}, options: [ { displayName: 'Group Messages', name: 'groupMessages', type: 'boolean', default: true, description: 'Whether to group messages into a single item or return each message as a separate item', }, ], displayOptions: { show: { mode: ['load'], }, }, }, ], }; } async execute() { const nodeVersion = this.getNode().typeVersion; const items = this.getInputData(); const mode = this.getNodeParameter('mode', 0, 'load'); const returnData = []; for (let i = 0; i < items.length; i++) { const memory = (await this.getInputConnectionData(n8n_workflow_1.NodeConnectionTypes.AiMemory, i)); const prepareOutput = prepareOutputSetup(this, nodeVersion, memory); const messages = await memory.chatHistory.getMessages(); if (mode === 'delete') { const deleteMode = this.getNodeParameter('deleteMode', i); if (deleteMode === 'lastN') { const lastMessagesCount = this.getNodeParameter('lastMessagesCount', i); if (messages.length >= lastMessagesCount) { const newMessages = messages.slice(0, messages.length - lastMessagesCount); await memory.chatHistory.clear(); for (const message of newMessages) { await memory.chatHistory.addMessage(message); } } } else { await memory.chatHistory.clear(); } returnData.push(...(await prepareOutput(i))); } if (mode === 'insert') { const insertMode = this.getNodeParameter('insertMode', i); const messagesToInsert = this.getNodeParameter('messages.messageValues', i, []); const templateMapper = { ai: messages_1.AIMessage, system: messages_1.SystemMessage, user: messages_1.HumanMessage, }; if (insertMode === 'override') { await memory.chatHistory.clear(); } for (const message of messagesToInsert) { const MessageClass = new templateMapper[message.type](message.message); if (message.hideFromUI) { MessageClass.additional_kwargs.hideFromUI = true; } await memory.chatHistory.addMessage(MessageClass); } returnData.push(...(await prepareOutput(i))); } if (mode === 'load') { const simplifyOutput = this.getNodeParameter('simplifyOutput', i, false); const options = this.getNodeParameter('options', i); if (simplifyOutput && messages.length && nodeVersion === 1) { const groupMessages = options.groupMessages; const output = simplifyMessages(messages); return [ this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(groupMessages ? [{ messages: output, messagesCount: output.length }] : output), { itemData: { item: i } }), ]; } let groupMessages = true; if (options.groupMessages === false) { groupMessages = false; } if (options.groupMessages === undefined && nodeVersion === 1) { groupMessages = false; } let output = (simplifyOutput ? simplifyMessages(messages) : messages?.map((message) => message.toJSON())) ?? []; if (groupMessages) { output = [{ messages: output, messagesCount: output.length }]; } const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(output), { itemData: { item: i } }); returnData.push(...executionData); } } return [returnData]; } } exports.MemoryManager = MemoryManager; //# sourceMappingURL=MemoryManager.node.js.map