mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 18:41:14 +00:00
feat(editor): Show logs panel in execution history page (#14477)
This commit is contained in:
122
packages/frontend/editor-ui/src/components/CanvasChat/utils.ts
Normal file
122
packages/frontend/editor-ui/src/components/CanvasChat/utils.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { CHAT_TRIGGER_NODE_TYPE, MANUAL_CHAT_TRIGGER_NODE_TYPE } from '@/constants';
|
||||
import { type IExecutionResponse, type INodeUi, type IWorkflowDb } from '@/Interface';
|
||||
import { type ChatMessage } from '@n8n/chat/types';
|
||||
import { get, isEmpty } from 'lodash-es';
|
||||
import { NodeConnectionTypes, type IDataObject, type IRunExecutionData } from 'n8n-workflow';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
export function isChatNode(node: INodeUi) {
|
||||
return [CHAT_TRIGGER_NODE_TYPE, MANUAL_CHAT_TRIGGER_NODE_TYPE].includes(node.type);
|
||||
}
|
||||
|
||||
export function getInputKey(node: INodeUi): string {
|
||||
if (node.type === MANUAL_CHAT_TRIGGER_NODE_TYPE && node.typeVersion < 1.1) {
|
||||
return 'input';
|
||||
}
|
||||
if (node.type === CHAT_TRIGGER_NODE_TYPE) {
|
||||
return 'chatInput';
|
||||
}
|
||||
|
||||
return 'chatInput';
|
||||
}
|
||||
|
||||
function extractChatInput(
|
||||
workflow: IWorkflowDb,
|
||||
resultData: IRunExecutionData['resultData'],
|
||||
): ChatMessage | undefined {
|
||||
const chatTrigger = workflow.nodes.find(isChatNode);
|
||||
|
||||
if (chatTrigger === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const inputKey = getInputKey(chatTrigger);
|
||||
const runData = (resultData.runData[chatTrigger.name] ?? [])[0];
|
||||
const message = runData?.data?.[NodeConnectionTypes.Main]?.[0]?.[0]?.json?.[inputKey];
|
||||
|
||||
if (runData === undefined || typeof message !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
text: message,
|
||||
sender: 'user',
|
||||
id: uuid(),
|
||||
};
|
||||
}
|
||||
|
||||
export function extractBotResponse(
|
||||
resultData: IRunExecutionData['resultData'],
|
||||
executionId: string,
|
||||
emptyText?: string,
|
||||
): ChatMessage | undefined {
|
||||
const lastNodeExecuted = resultData.lastNodeExecuted;
|
||||
|
||||
if (!lastNodeExecuted) return undefined;
|
||||
|
||||
const nodeResponseDataArray = get(resultData.runData, lastNodeExecuted) ?? [];
|
||||
|
||||
const nodeResponseData = nodeResponseDataArray[nodeResponseDataArray.length - 1];
|
||||
|
||||
let responseMessage: string;
|
||||
|
||||
if (get(nodeResponseData, 'error')) {
|
||||
responseMessage = '[ERROR: ' + get(nodeResponseData, 'error.message') + ']';
|
||||
} else {
|
||||
const responseData = get(nodeResponseData, 'data.main[0][0].json');
|
||||
const text = extractResponseText(responseData) ?? emptyText;
|
||||
|
||||
if (!text) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
responseMessage = text;
|
||||
}
|
||||
|
||||
return {
|
||||
text: responseMessage,
|
||||
sender: 'bot',
|
||||
id: executionId ?? uuid(),
|
||||
};
|
||||
}
|
||||
|
||||
/** Extracts response message from workflow output */
|
||||
function extractResponseText(responseData?: IDataObject): string | undefined {
|
||||
if (!responseData || isEmpty(responseData)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Paths where the response message might be located
|
||||
const paths = ['output', 'text', 'response.text'];
|
||||
const matchedPath = paths.find((path) => get(responseData, path));
|
||||
|
||||
if (!matchedPath) return JSON.stringify(responseData, null, 2);
|
||||
|
||||
const matchedOutput = get(responseData, matchedPath);
|
||||
if (typeof matchedOutput === 'object') {
|
||||
return '```json\n' + JSON.stringify(matchedOutput, null, 2) + '\n```';
|
||||
}
|
||||
|
||||
return matchedOutput?.toString() ?? '';
|
||||
}
|
||||
|
||||
export function restoreChatHistory(
|
||||
workflowExecutionData: IExecutionResponse | null,
|
||||
emptyText?: string,
|
||||
): ChatMessage[] {
|
||||
if (!workflowExecutionData?.data) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const userMessage = extractChatInput(
|
||||
workflowExecutionData.workflowData,
|
||||
workflowExecutionData.data.resultData,
|
||||
);
|
||||
const botMessage = extractBotResponse(
|
||||
workflowExecutionData.data.resultData,
|
||||
workflowExecutionData.id,
|
||||
emptyText,
|
||||
);
|
||||
|
||||
return [...(userMessage ? [userMessage] : []), ...(botMessage ? [botMessage] : [])];
|
||||
}
|
||||
Reference in New Issue
Block a user