mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(Chat Memory Manager Node): Fix simplifyMessages to not overwrite consecutive messages of same type (#16168)
This commit is contained in:
committed by
GitHub
parent
cdab4c1bc6
commit
5015290dbe
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */
|
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */
|
||||||
import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';
|
import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';
|
||||||
import { AIMessage, SystemMessage, HumanMessage, type BaseMessage } from '@langchain/core/messages';
|
import type { MessageContent, BaseMessage } from '@langchain/core/messages';
|
||||||
|
import { AIMessage, SystemMessage, HumanMessage } from '@langchain/core/messages';
|
||||||
import { NodeConnectionTypes } from 'n8n-workflow';
|
import { NodeConnectionTypes } from 'n8n-workflow';
|
||||||
import type {
|
import type {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
@@ -17,24 +18,31 @@ interface MessageRecord {
|
|||||||
hideFromUI: boolean;
|
hideFromUI: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function simplifyMessages(messages: BaseMessage[]) {
|
export function simplifyMessages(messages: BaseMessage[]): Array<Record<string, MessageContent>> {
|
||||||
const chunkedMessages = [];
|
if (messages.length === 0) return [];
|
||||||
for (let i = 0; i < messages.length; i += 2) {
|
|
||||||
chunkedMessages.push([messages[i], messages[i + 1]]);
|
const result: Array<Record<string, MessageContent>> = [];
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
while (index < messages.length) {
|
||||||
|
const currentGroup: Record<string, MessageContent> = {};
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformedMessages = chunkedMessages.map((exchange) => {
|
return result;
|
||||||
const simplified = {
|
|
||||||
[exchange[0]._getType()]: exchange[0].content,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (exchange[1]) {
|
|
||||||
simplified[exchange[1]._getType()] = exchange[1].content;
|
|
||||||
}
|
|
||||||
|
|
||||||
return simplified;
|
|
||||||
});
|
|
||||||
return transformedMessages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepareOutputSetup = (ctx: IExecuteFunctions, version: number, memory: BaseChatMemory) => {
|
const prepareOutputSetup = (ctx: IExecuteFunctions, version: number, memory: BaseChatMemory) => {
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import { AIMessage, HumanMessage, SystemMessage } from '@langchain/core/messages';
|
||||||
|
|
||||||
|
import { simplifyMessages } from '../MemoryManager.node';
|
||||||
|
|
||||||
|
describe('simplifyMessages', () => {
|
||||||
|
it('should handle single message', () => {
|
||||||
|
const messages = [new HumanMessage('Hello')];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([{ human: 'Hello' }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should group different message types together', () => {
|
||||||
|
const messages = [
|
||||||
|
new HumanMessage('Hello, how are you?'),
|
||||||
|
new AIMessage("I'm doing well, thank you for asking! How about you?"),
|
||||||
|
];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{
|
||||||
|
human: 'Hello, how are you?',
|
||||||
|
ai: "I'm doing well, thank you for asking! How about you?",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should separate consecutive messages of same type into different groups', () => {
|
||||||
|
const messages = [
|
||||||
|
new HumanMessage('First human message'),
|
||||||
|
new HumanMessage('Second human message'),
|
||||||
|
new AIMessage('AI response'),
|
||||||
|
];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ human: 'First human message' },
|
||||||
|
{ human: 'Second human message', ai: 'AI response' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle three consecutive messages of same type', () => {
|
||||||
|
const messages = [new HumanMessage('1'), new HumanMessage('2'), new HumanMessage('3')];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([{ human: '1' }, { human: '2' }, { human: '3' }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle mixed message types with grouping', () => {
|
||||||
|
const messages = [
|
||||||
|
new SystemMessage('System message'),
|
||||||
|
new HumanMessage('Hello'),
|
||||||
|
new AIMessage('Hi there'),
|
||||||
|
new HumanMessage('Another human message'),
|
||||||
|
new AIMessage('Another AI message'),
|
||||||
|
];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{
|
||||||
|
system: 'System message',
|
||||||
|
human: 'Hello',
|
||||||
|
ai: 'Hi there',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
human: 'Another human message',
|
||||||
|
ai: 'Another AI message',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle system messages correctly', () => {
|
||||||
|
const messages = [
|
||||||
|
new SystemMessage('System instruction'),
|
||||||
|
new HumanMessage('User question'),
|
||||||
|
new AIMessage('AI response'),
|
||||||
|
];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{
|
||||||
|
system: 'System instruction',
|
||||||
|
human: 'User question',
|
||||||
|
ai: 'AI response',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle alternating same types correctly', () => {
|
||||||
|
const messages = [
|
||||||
|
new HumanMessage('Human 1'),
|
||||||
|
new AIMessage('AI 1'),
|
||||||
|
new HumanMessage('Human 2'),
|
||||||
|
new AIMessage('AI 2'),
|
||||||
|
];
|
||||||
|
const result = simplifyMessages(messages);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{
|
||||||
|
human: 'Human 1',
|
||||||
|
ai: 'AI 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
human: 'Human 2',
|
||||||
|
ai: 'AI 2',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user