diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts index cbd2cef75adaa..5508f957f8ff5 100644 --- a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts @@ -54,6 +54,6 @@ export class VectorStoreInMemory extends createVectorStoreNode({ const workflowId = context.getWorkflow().id; const vectorStoreInstance = MemoryVectorStoreManager.getInstance(embeddings); - void vectorStoreInstance.addDocuments(`${workflowId}__${memoryKey}`, documents, clearStore); + await vectorStoreInstance.addDocuments(`${workflowId}__${memoryKey}`, documents, clearStore); }, }) {} diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.test.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.test.ts new file mode 100644 index 0000000000000..6229868f320ad --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.test.ts @@ -0,0 +1,44 @@ +import type { OpenAIEmbeddings } from '@langchain/openai'; + +import { MemoryVectorStoreManager } from './MemoryVectorStoreManager'; +import { mock } from 'jest-mock-extended'; + +describe('MemoryVectorStoreManager', () => { + it('should create an instance of MemoryVectorStoreManager', () => { + const embeddings = mock(); + + const instance = MemoryVectorStoreManager.getInstance(embeddings); + expect(instance).toBeInstanceOf(MemoryVectorStoreManager); + }); + + it('should return existing instance', () => { + const embeddings = mock(); + + const instance1 = MemoryVectorStoreManager.getInstance(embeddings); + const instance2 = MemoryVectorStoreManager.getInstance(embeddings); + expect(instance1).toBe(instance2); + }); + + it('should update embeddings in existing instance', () => { + const embeddings1 = mock(); + const embeddings2 = mock(); + + const instance = MemoryVectorStoreManager.getInstance(embeddings1); + MemoryVectorStoreManager.getInstance(embeddings2); + + expect((instance as any).embeddings).toBe(embeddings2); + }); + + it('should update embeddings in existing vector store instances', async () => { + const embeddings1 = mock(); + const embeddings2 = mock(); + + const instance1 = MemoryVectorStoreManager.getInstance(embeddings1); + await instance1.getVectorStore('test'); + + const instance2 = MemoryVectorStoreManager.getInstance(embeddings2); + const vectorStoreInstance2 = await instance2.getVectorStore('test'); + + expect((vectorStoreInstance2 as any).embeddings).toBe(embeddings2); + }); +}); diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.ts index 1076fb93bafbb..5c507a5196f17 100644 --- a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.ts +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/MemoryVectorStoreManager.ts @@ -14,7 +14,16 @@ export class MemoryVectorStoreManager { public static getInstance(embeddings: Embeddings): MemoryVectorStoreManager { if (!MemoryVectorStoreManager.instance) { MemoryVectorStoreManager.instance = new MemoryVectorStoreManager(embeddings); + } else { + // We need to update the embeddings in the existing instance. + // This is important as embeddings instance is wrapped in a logWrapper, + // which relies on supplyDataFunctions context which changes on each workflow run + MemoryVectorStoreManager.instance.embeddings = embeddings; + MemoryVectorStoreManager.instance.vectorStoreBuffer.forEach((vectorStoreInstance) => { + vectorStoreInstance.embeddings = embeddings; + }); } + return MemoryVectorStoreManager.instance; }