feat(MongoDB Chat Memory Node): New MongoDB Chat Memory Node (#14049)

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <netroy@users.noreply.github.com>
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
Co-authored-by: Jonathan Bennetts <jonathan.bennetts@gmail.com>
Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
Pash10g
2025-04-04 12:12:18 +03:00
committed by GitHub
parent 5382531970
commit 0bac6ffac6
4 changed files with 170 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
import { MongoDBChatMessageHistory } from '@langchain/mongodb';
import { BufferWindowMemory } from 'langchain/memory';
import { MongoClient } from 'mongodb';
import type {
ISupplyDataFunctions,
INodeType,
INodeTypeDescription,
SupplyData,
} from 'n8n-workflow';
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import { getSessionId } from '@utils/helpers';
import { logWrapper } from '@utils/logWrapper';
import { getConnectionHintNoticeField } from '@utils/sharedFields';
import {
sessionIdOption,
sessionKeyProperty,
expressionSessionKeyProperty,
contextWindowLengthProperty,
} from '../descriptions';
export class MemoryMongoDbChat implements INodeType {
description: INodeTypeDescription = {
displayName: 'MongoDB Chat Memory',
name: 'memoryMongoDbChat',
icon: 'file:mongodb.svg',
group: ['transform'],
version: [1],
description: 'Stores the chat history in MongoDB collection.',
defaults: {
name: 'MongoDB Chat Memory',
},
credentials: [
{
name: 'mongoDb',
required: true,
},
],
codex: {
categories: ['AI'],
subcategories: {
AI: ['Memory'],
},
resources: {
primaryDocumentation: [
{
url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.memorymongochat/',
},
],
},
},
inputs: [],
outputs: [NodeConnectionTypes.AiMemory],
outputNames: ['Memory'],
properties: [
getConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),
sessionIdOption,
expressionSessionKeyProperty(1),
sessionKeyProperty,
{
displayName: 'Collection Name',
name: 'collectionName',
type: 'string',
default: 'n8n_chat_histories',
description:
'The collection name to store the chat history in. If collection does not exist, it will be created.',
},
{
displayName: 'Database Name',
name: 'databaseName',
type: 'string',
default: '',
description:
'The database name to store the chat history in. If not provided, the database from credentials will be used.',
},
contextWindowLengthProperty,
],
};
async supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {
const credentials = await this.getCredentials<{
configurationType: string;
connectionString: string;
database: string;
host: string;
user: string;
port: number;
password: string;
tls: boolean;
}>('mongoDb');
const collectionName = this.getNodeParameter(
'collectionName',
itemIndex,
'n8n_chat_histories',
) as string;
const databaseName = this.getNodeParameter('databaseName', itemIndex, '') as string;
const sessionId = getSessionId(this, itemIndex);
let connectionString: string;
let dbName: string;
if (credentials.configurationType === 'connectionString') {
connectionString = credentials.connectionString;
dbName = databaseName || credentials.database;
} else {
// Build connection string from individual fields
const host = credentials.host;
const port = credentials.port;
const user = credentials.user ? encodeURIComponent(credentials.user) : '';
const password = credentials.password ? encodeURIComponent(credentials.password) : '';
const authString = user && password ? `${user}:${password}@` : '';
const tls = credentials.tls;
connectionString = `mongodb://${authString}${host}:${port}/?appname=n8n`;
if (tls) {
connectionString += '&ssl=true';
}
dbName = databaseName || credentials.database;
}
if (!dbName) {
throw new NodeOperationError(
this.getNode(),
'Database name must be provided either in credentials or in node parameters',
);
}
try {
const client = new MongoClient(connectionString);
await client.connect();
const db = client.db(dbName);
const collection = db.collection(collectionName);
const mongoDBChatHistory = new MongoDBChatMessageHistory({
collection,
sessionId,
});
const memory = new BufferWindowMemory({
memoryKey: 'chat_history',
chatHistory: mongoDBChatHistory,
returnMessages: true,
inputKey: 'input',
outputKey: 'output',
k: this.getNodeParameter('contextWindowLength', itemIndex, 5) as number,
});
async function closeFunction() {
await client.close();
}
return {
closeFunction,
response: logWrapper(memory, this),
};
} catch (error) {
throw new NodeOperationError(this.getNode(), `MongoDB connection error: ${error.message}`);
}
}
}

View File

@@ -0,0 +1,3 @@
<svg width="120" height="258" viewBox="0 0 120 258" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M83.0089 28.7559C72.1328 15.9086 62.7673 2.86053 60.8539 0.150554C60.6525 -0.0501848 60.3503 -0.0501848 60.1489 0.150554C58.2355 2.86053 48.8699 15.9086 37.9938 28.7559C-55.3594 147.292 52.6968 227.287 52.6968 227.287L53.6031 227.889C54.4087 240.235 56.4228 258 56.4228 258H60.451H64.4792C64.4792 258 66.4934 240.335 67.299 227.889L68.2052 227.187C68.306 227.187 176.362 147.292 83.0089 28.7559ZM60.451 225.48C60.451 225.48 55.6172 221.365 54.3081 219.257V219.057L60.1489 89.9813C60.1489 89.5798 60.7532 89.5798 60.7532 89.9813L66.594 219.057V219.257C65.2848 221.365 60.451 225.48 60.451 225.48Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 728 B

View File

@@ -0,0 +1,3 @@
<svg width="120" height="258" viewBox="0 0 120 258" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M83.0089 28.7559C72.1328 15.9086 62.7673 2.86053 60.8539 0.150554C60.6525 -0.0501848 60.3503 -0.0501848 60.1489 0.150554C58.2355 2.86053 48.8699 15.9086 37.9938 28.7559C-55.3594 147.292 52.6968 227.287 52.6968 227.287L53.6031 227.889C54.4087 240.235 56.4228 258 56.4228 258H60.451H64.4792C64.4792 258 66.4934 240.335 67.299 227.889L68.2052 227.187C68.306 227.187 176.362 147.292 83.0089 28.7559ZM60.451 225.48C60.451 225.48 55.6172 221.365 54.3081 219.257V219.057L60.1489 89.9813C60.1489 89.5798 60.7532 89.5798 60.7532 89.9813L66.594 219.057V219.257C65.2848 221.365 60.451 225.48 60.451 225.48Z" fill="#00684A"/>
</svg>

After

Width:  |  Height:  |  Size: 730 B

View File

@@ -85,6 +85,7 @@
"dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js",
"dist/nodes/memory/MemoryMotorhead/MemoryMotorhead.node.js",
"dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js",
"dist/nodes/memory/MemoryMongoDbChat/MemoryMongoDbChat.node.js",
"dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js",
"dist/nodes/memory/MemoryManager/MemoryManager.node.js",
"dist/nodes/memory/MemoryChatRetriever/MemoryChatRetriever.node.js",