UNPKG

n8n-nodes-zep-memory-v3

Version:

n8n community node for Zep v3 Memory - replaces discontinued official node

273 lines (272 loc) 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ZepMemory = void 0; const n8n_workflow_1 = require("n8n-workflow"); const zep_cloud_1 = require("@langchain/community/memory/zep_cloud"); const zep_1 = require("@langchain/community/memory/zep"); class WhiteSpaceTrimmedZepCloudMemory extends zep_cloud_1.ZepCloudMemory { async loadMemoryVariables(values) { const memoryVariables = await super.loadMemoryVariables(values); memoryVariables.chat_history = memoryVariables.chat_history.filter((m) => m.content.toString().trim()); return memoryVariables; } } // MANTIDO: BaseChatMemoryWrapper para compatibilidade máxima class BaseChatMemoryWrapper { constructor(memory) { this.memory = memory; } async loadMemoryVariables(values) { var _a; const startTime = Date.now(); const response = await this.memory.loadMemoryVariables(values); const duration = Date.now() - startTime; // Logging seguro para visibilidade nos logs do Docker/console console.log(`[Zep Memory v3] loadMemoryVariables completed in ${duration}ms`, { hasHistory: !!(response === null || response === void 0 ? void 0 : response.chat_history), messageCount: ((_a = response === null || response === void 0 ? void 0 : response.chat_history) === null || _a === void 0 ? void 0 : _a.length) || 0, }); return response; } async saveContext(inputValues, outputValues) { const startTime = Date.now(); const response = await this.memory.saveContext(inputValues, outputValues); const duration = Date.now() - startTime; // Logging seguro para visibilidade nos logs do Docker/console console.log(`[Zep Memory v3] saveContext completed in ${duration}ms`, { input: (inputValues === null || inputValues === void 0 ? void 0 : inputValues.input) || 'N/A', output: (outputValues === null || outputValues === void 0 ? void 0 : outputValues.output) || 'N/A', }); return response; } async clear() { console.log('[Zep Memory v3] Clearing memory'); const response = await this.memory.clear(); console.log('[Zep Memory v3] Memory cleared successfully'); return response; } get memoryKey() { return this.memory.memoryKey; } get returnMessages() { return this.memory.returnMessages; } get inputKey() { return this.memory.inputKey; } get outputKey() { return this.memory.outputKey; } } class ZepMemory { constructor() { this.description = { displayName: 'Zep Memory v3', name: 'zepMemoryV3', icon: 'file:zep.png', group: ['transform'], version: [1, 2, 3, 4], description: 'Use Zep Memory v3 for AI agent conversations', defaults: { name: 'Zep Memory v3', }, codex: { categories: ['AI'], subcategories: { AI: ['Memory'], Memory: ['Other memories'], }, resources: { primaryDocumentation: [ { url: 'https://docs.getzep.com', }, ], }, }, inputs: [], outputs: ['ai_memory'], outputNames: ['Memory'], credentials: [ { name: 'zepApi', required: true, }, ], properties: [ { displayName: 'Connect to AI Agent', name: 'connectionHint', type: 'notice', default: '', description: 'Connect this node to an AI Agent node to provide memory functionality', }, { displayName: 'Works with Zep Cloud v3 and enhanced context retrieval', name: 'supportedVersions', type: 'notice', default: '', }, // Thread ID para versão 1 { displayName: 'Thread ID', name: 'threadId', type: 'string', required: true, default: '', displayOptions: { show: { '@version': [1], }, }, }, // Thread ID para versão 1.1 { displayName: 'Thread ID', name: 'threadId', type: 'string', default: '={{ $json.threadId }}', description: 'The thread ID to use to store the memory', displayOptions: { show: { '@version': [2], }, }, }, // Thread ID Type para versões 1.2+ { displayName: 'Thread ID', name: 'threadIdType', type: 'options', options: [ { name: 'Connected Chat Trigger Node', value: 'fromInput', description: 'Looks for an input field called "threadId" from a connected Chat Trigger', }, { name: 'Define below', value: 'customKey', description: 'Use an expression to reference data in previous nodes or enter static text', }, ], default: 'fromInput', displayOptions: { show: { '@version': [{ _cnd: { gte: 3 } }], }, }, }, // Thread Key From Previous Node (versão 1.3+) { displayName: 'Thread Key From Previous Node', name: 'threadKey', type: 'string', default: '={{ $json.threadId }}', displayOptions: { show: { threadIdType: ['fromInput'], '@version': [{ _cnd: { gte: 4 } }], }, }, }, // Custom Thread Key { displayName: 'Key', name: 'threadKey', type: 'string', default: '', description: 'The key to use to store thread ID in the memory', displayOptions: { show: { threadIdType: ['customKey'], }, }, }, ], }; } async supplyData(itemIndex) { var _a, _b; // Helper de logging seguro - funciona mesmo se this.logger não estiver disponível const log = (level, message, meta) => { try { if (this.logger && typeof this.logger[level] === 'function') { this.logger[level](message, meta); } } catch (error) { // Fallback silencioso para console (aparece nos logs do Docker) console.log(`[Zep Memory v3 ${level.toUpperCase()}] ${message}`, meta || ''); } }; log('info', '🚀 Zep Memory v3 - Starting initialization'); const credentials = await this.getCredentials('zepApi'); const nodeVersion = this.getNode().typeVersion; log('debug', `Node version: ${nodeVersion}`); let threadId; if (nodeVersion >= 3) { const threadIdType = this.getNodeParameter('threadIdType', itemIndex); if (threadIdType === 'fromInput') { const threadKey = this.getNodeParameter('threadKey', itemIndex, 'threadId'); const inputData = this.getInputData(itemIndex); threadId = String(((_b = (_a = inputData === null || inputData === void 0 ? void 0 : inputData[0]) === null || _a === void 0 ? void 0 : _a.json) === null || _b === void 0 ? void 0 : _b[threadKey]) || ''); log('debug', `Thread ID from input: ${threadId}`); } else { threadId = this.getNodeParameter('threadKey', itemIndex); log('debug', `Thread ID from custom key: ${threadId}`); } } else { threadId = this.getNodeParameter('threadId', itemIndex); log('debug', `Thread ID (legacy): ${threadId}`); } if (!threadId) { log('error', '❌ Thread ID is missing'); throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Thread ID is required. Please provide a valid thread ID.'); } log('info', `✓ Using thread ID: ${threadId}`); let baseMemory; if (credentials.cloud) { if (!credentials.apiKey) { log('error', '❌ API key is missing for Zep Cloud'); throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'API key is required for Zep Cloud'); } log('info', '☁️ Initializing Zep Cloud memory'); baseMemory = new WhiteSpaceTrimmedZepCloudMemory({ sessionId: threadId, apiKey: credentials.apiKey, memoryType: 'perpetual', memoryKey: 'chat_history', returnMessages: true, inputKey: 'input', outputKey: 'output', separateMessages: false, }); } else { if (!credentials.apiUrl) { log('error', '❌ API URL is missing for Zep Open Source'); throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'API URL is required for Zep Open Source'); } log('info', `🔧 Initializing Zep Open Source memory at ${credentials.apiUrl}`); baseMemory = new zep_1.ZepMemory({ sessionId: threadId, baseURL: credentials.apiUrl, apiKey: credentials.apiKey, memoryKey: 'chat_history', returnMessages: true, inputKey: 'input', outputKey: 'output', }); } // Wrapper para compatibilidade - SEM logWrapper customizado const wrappedMemory = new BaseChatMemoryWrapper(baseMemory); log('info', '✅ Zep Memory v3 initialized successfully'); return { response: wrappedMemory, }; } } exports.ZepMemory = ZepMemory;