mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(editor): Memory getting rendered in chat on workflow load (#14346)
This commit is contained in:
@@ -315,12 +315,15 @@ describe('CanvasChat', () => {
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockReturnValue({
|
||||
getChatMessages: vi.fn().mockReturnValue(mockMessages),
|
||||
sendMessage: vi.fn(),
|
||||
extractResponseMessage: vi.fn(),
|
||||
previousMessageIndex: ref(0),
|
||||
isLoading: computed(() => false),
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockImplementation(({ messages }) => {
|
||||
messages.value.push(...mockMessages);
|
||||
|
||||
return {
|
||||
sendMessage: vi.fn(),
|
||||
extractResponseMessage: vi.fn(),
|
||||
previousMessageIndex: ref(0),
|
||||
isLoading: computed(() => false),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -381,7 +384,6 @@ describe('CanvasChat', () => {
|
||||
describe('file handling', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockReturnValue({
|
||||
getChatMessages: vi.fn().mockReturnValue([]),
|
||||
sendMessage: vi.fn(),
|
||||
extractResponseMessage: vi.fn(),
|
||||
previousMessageIndex: ref(0),
|
||||
@@ -478,12 +480,15 @@ describe('CanvasChat', () => {
|
||||
createdAt: new Date().toISOString(),
|
||||
},
|
||||
];
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockReturnValue({
|
||||
getChatMessages: vi.fn().mockReturnValue(mockMessages),
|
||||
sendMessage: sendMessageSpy,
|
||||
extractResponseMessage: vi.fn(),
|
||||
previousMessageIndex: ref(0),
|
||||
isLoading: computed(() => false),
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockImplementation(({ messages }) => {
|
||||
messages.value.push(...mockMessages);
|
||||
|
||||
return {
|
||||
sendMessage: sendMessageSpy,
|
||||
extractResponseMessage: vi.fn(),
|
||||
previousMessageIndex: ref(0),
|
||||
isLoading: computed(() => false),
|
||||
};
|
||||
});
|
||||
workflowsStore.messages = mockMessages;
|
||||
});
|
||||
@@ -584,22 +589,4 @@ describe('CanvasChat', () => {
|
||||
expect(input).toHaveValue('Line 1\nLine 2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('chat synchronization', () => {
|
||||
it('should load initial chat history when first opening panel', async () => {
|
||||
const getChatMessagesSpy = vi.fn().mockReturnValue(['Previous message']);
|
||||
vi.spyOn(useChatMessaging, 'useChatMessaging').mockReturnValue({
|
||||
...vi.fn()(),
|
||||
getChatMessages: getChatMessagesSpy,
|
||||
});
|
||||
|
||||
workflowsStore.chatPanelState = LOGS_PANEL_STATE.CLOSED;
|
||||
const { rerender } = renderComponent();
|
||||
|
||||
workflowsStore.chatPanelState = LOGS_PANEL_STATE.ATTACHED;
|
||||
await rerender({});
|
||||
|
||||
expect(getChatMessagesSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ComputedRef, Ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { ChatMessage, ChatMessageText } from '@n8n/chat/types';
|
||||
import { NodeConnectionTypes, CHAT_TRIGGER_NODE_TYPE } from 'n8n-workflow';
|
||||
import type { ChatMessage } from '@n8n/chat/types';
|
||||
import { CHAT_TRIGGER_NODE_TYPE } from 'n8n-workflow';
|
||||
import type {
|
||||
ITaskData,
|
||||
INodeExecutionData,
|
||||
@@ -10,16 +10,14 @@ import type {
|
||||
IDataObject,
|
||||
IBinaryData,
|
||||
BinaryFileType,
|
||||
Workflow,
|
||||
IRunExecutionData,
|
||||
} from 'n8n-workflow';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
import { usePinnedData } from '@/composables/usePinnedData';
|
||||
import { get, isEmpty, last } from 'lodash-es';
|
||||
import { get, isEmpty } from 'lodash-es';
|
||||
import { MANUAL_CHAT_TRIGGER_NODE_TYPE, MODAL_CONFIRM } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { MemoryOutput } from '../types/chat';
|
||||
import type { IExecutionPushResponse, INodeUi } from '@/Interface';
|
||||
|
||||
export type RunWorkflowChatPayload = {
|
||||
@@ -30,12 +28,9 @@ export type RunWorkflowChatPayload = {
|
||||
};
|
||||
export interface ChatMessagingDependencies {
|
||||
chatTrigger: Ref<INodeUi | null>;
|
||||
connectedNode: Ref<INodeUi | null>;
|
||||
messages: Ref<ChatMessage[]>;
|
||||
sessionId: Ref<string>;
|
||||
workflow: ComputedRef<Workflow>;
|
||||
executionResultData: ComputedRef<IRunExecutionData['resultData'] | undefined>;
|
||||
getWorkflowResultDataByNodeName: (nodeName: string) => ITaskData[] | null;
|
||||
onRunChatWorkflow: (
|
||||
payload: RunWorkflowChatPayload,
|
||||
) => Promise<IExecutionPushResponse | undefined>;
|
||||
@@ -43,12 +38,9 @@ export interface ChatMessagingDependencies {
|
||||
|
||||
export function useChatMessaging({
|
||||
chatTrigger,
|
||||
connectedNode,
|
||||
messages,
|
||||
sessionId,
|
||||
workflow,
|
||||
executionResultData,
|
||||
getWorkflowResultDataByNodeName,
|
||||
onRunChatWorkflow,
|
||||
}: ChatMessagingDependencies) {
|
||||
const locale = useI18n();
|
||||
@@ -247,42 +239,10 @@ export function useChatMessaging({
|
||||
await startWorkflowWithMessage(newMessage.text, files);
|
||||
}
|
||||
|
||||
function getChatMessages(): ChatMessageText[] {
|
||||
if (!connectedNode.value) return [];
|
||||
|
||||
const connectedMemoryInputs =
|
||||
workflow.value.connectionsByDestinationNode?.[connectedNode.value.name]?.[
|
||||
NodeConnectionTypes.AiMemory
|
||||
];
|
||||
if (!connectedMemoryInputs) return [];
|
||||
|
||||
const memoryConnection = (connectedMemoryInputs ?? []).find((i) => (i ?? []).length > 0)?.[0];
|
||||
|
||||
if (!memoryConnection) return [];
|
||||
|
||||
const nodeResultData = getWorkflowResultDataByNodeName(memoryConnection.node);
|
||||
|
||||
const memoryOutputData = (nodeResultData ?? [])
|
||||
.map(
|
||||
(data) => get(data, ['data', NodeConnectionTypes.AiMemory, 0, 0, 'json']) as MemoryOutput,
|
||||
)
|
||||
.find((data) => data && data.action === 'saveContext');
|
||||
|
||||
return (memoryOutputData?.chatHistory ?? []).map((message, index) => {
|
||||
return {
|
||||
createdAt: new Date().toISOString(),
|
||||
text: message.kwargs.content,
|
||||
id: `preload__${index}`,
|
||||
sender: last(message.id) === 'HumanMessage' ? 'user' : 'bot',
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
previousMessageIndex,
|
||||
isLoading: computed(() => isLoading.value),
|
||||
sendMessage,
|
||||
extractResponseMessage,
|
||||
getChatMessages,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -60,14 +60,11 @@ export function useChatState(isDisabled: Ref<boolean>, onWindowResize: () => voi
|
||||
getNodeType: nodeTypesStore.getNodeType,
|
||||
});
|
||||
|
||||
const { sendMessage, getChatMessages, isLoading } = useChatMessaging({
|
||||
const { sendMessage, isLoading } = useChatMessaging({
|
||||
chatTrigger: chatTriggerNode,
|
||||
connectedNode,
|
||||
messages,
|
||||
sessionId: currentSessionId,
|
||||
workflow,
|
||||
executionResultData: computed(() => workflowsStore.getWorkflowExecution?.data?.resultData),
|
||||
getWorkflowResultDataByNodeName: workflowsStore.getWorkflowResultDataByNodeName,
|
||||
onRunChatWorkflow,
|
||||
});
|
||||
|
||||
@@ -134,10 +131,6 @@ export function useChatState(isDisabled: Ref<boolean>, onWindowResize: () => voi
|
||||
setChatTriggerNode();
|
||||
setConnectedNode();
|
||||
|
||||
if (messages.value.length === 0) {
|
||||
messages.value = getChatMessages();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
onWindowResize();
|
||||
chatEventBus.emit('focusInput');
|
||||
|
||||
Reference in New Issue
Block a user