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 */
|
||||
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 type {
|
||||
IDataObject,
|
||||
@@ -17,24 +18,31 @@ interface MessageRecord {
|
||||
hideFromUI: boolean;
|
||||
}
|
||||
|
||||
function simplifyMessages(messages: BaseMessage[]) {
|
||||
const chunkedMessages = [];
|
||||
for (let i = 0; i < messages.length; i += 2) {
|
||||
chunkedMessages.push([messages[i], messages[i + 1]]);
|
||||
export function simplifyMessages(messages: BaseMessage[]): Array<Record<string, MessageContent>> {
|
||||
if (messages.length === 0) return [];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const transformedMessages = chunkedMessages.map((exchange) => {
|
||||
const simplified = {
|
||||
[exchange[0]._getType()]: exchange[0].content,
|
||||
};
|
||||
currentGroup[messageType] = message.content;
|
||||
index++;
|
||||
} while (index < messages.length);
|
||||
|
||||
if (exchange[1]) {
|
||||
simplified[exchange[1]._getType()] = exchange[1].content;
|
||||
result.push(currentGroup);
|
||||
}
|
||||
|
||||
return simplified;
|
||||
});
|
||||
return transformedMessages;
|
||||
return result;
|
||||
}
|
||||
|
||||
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