mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-14 06:18:25 -08:00
fix(editor): Simplify workflow payload to AI Assistant (no-changelog) (#11975)
This commit is contained in:
parent
8d71307da0
commit
0ffc8591a0
|
@ -2,6 +2,7 @@
|
|||
import type { N8nLocale } from 'n8n-design-system/types';
|
||||
|
||||
export default {
|
||||
'generic.retry': 'Retry',
|
||||
'nds.auth.roles.owner': 'Owner',
|
||||
'nds.userInfo.you': '(you)',
|
||||
'nds.userSelect.selectUser': 'Select User',
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
import type { INode, IRunExecutionData, NodeConnectionType } from 'n8n-workflow';
|
||||
import { useAIAssistantHelpers } from './useAIAssistantHelpers';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
|
||||
const referencedNodesTestCases: Array<{ caseName: string; node: INode; expected: string[] }> = [
|
||||
{
|
||||
|
@ -76,6 +77,15 @@ const referencedNodesTestCases: Array<{ caseName: string; node: INode; expected:
|
|||
name: 'document',
|
||||
value: "={{ $('Edit Fields 2').item.json.document}}",
|
||||
type: 'string',
|
||||
typeVersion: 1,
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
id: 'b5942df6-0160-4ef7-965d-57583acdc8aa',
|
||||
name: 'Replace me with your logic',
|
||||
type: 'n8n-nodes-base.noOp',
|
||||
position: [520, 340],
|
||||
typeVersion: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -377,6 +387,121 @@ const referencedNodesTestCases: Array<{ caseName: string; node: INode; expected:
|
|||
},
|
||||
];
|
||||
|
||||
const testWorkflow: IWorkflowDb = {
|
||||
id: 'MokOcBHON6KkPq6Y',
|
||||
name: 'My Sub-Workflow 3',
|
||||
active: false,
|
||||
createdAt: -1,
|
||||
updatedAt: -1,
|
||||
connections: {
|
||||
'Execute Workflow Trigger': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Replace me with your logic',
|
||||
type: 'main' as NodeConnectionType,
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
nodes: [
|
||||
{
|
||||
parameters: {
|
||||
notice: '',
|
||||
events: 'worklfow_call',
|
||||
},
|
||||
id: 'c055762a-8fe7-4141-a639-df2372f30060',
|
||||
name: 'Execute Workflow Trigger',
|
||||
type: 'n8n-nodes-base.executeWorkflowTrigger',
|
||||
position: [260, 340],
|
||||
typeVersion: 0,
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
id: 'b5942df6-0160-4ef7-965d-57583acdc8aa',
|
||||
name: 'Replace me with your logic',
|
||||
type: 'n8n-nodes-base.noOp',
|
||||
position: [520, 340],
|
||||
typeVersion: 1,
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
executionOrder: 'v1',
|
||||
},
|
||||
tags: [],
|
||||
pinData: {},
|
||||
versionId: '9f3263e3-d23d-4cc8-bff0-0fdecfbd82bf',
|
||||
usedCredentials: [],
|
||||
scopes: [
|
||||
'workflow:create',
|
||||
'workflow:delete',
|
||||
'workflow:execute',
|
||||
'workflow:list',
|
||||
'workflow:move',
|
||||
'workflow:read',
|
||||
'workflow:share',
|
||||
'workflow:update',
|
||||
],
|
||||
sharedWithProjects: [],
|
||||
};
|
||||
|
||||
const testExecutionData: IRunExecutionData['resultData'] = {
|
||||
runData: {
|
||||
'When clicking ‘Test workflow’': [
|
||||
{
|
||||
hints: [],
|
||||
startTime: 1732882780588,
|
||||
executionTime: 4,
|
||||
source: [],
|
||||
executionStatus: 'success',
|
||||
data: {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
json: {},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
'Edit Fields': [
|
||||
{
|
||||
hints: [],
|
||||
startTime: 1732882780593,
|
||||
executionTime: 0,
|
||||
source: [
|
||||
{
|
||||
previousNode: 'When clicking ‘Test workflow’',
|
||||
},
|
||||
],
|
||||
executionStatus: 'success',
|
||||
data: {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
json: {
|
||||
something: 'here',
|
||||
},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
pinData: {},
|
||||
lastNodeExecuted: 'Edit Fields',
|
||||
};
|
||||
|
||||
describe.each(referencedNodesTestCases)('getReferencedNodes', (testCase) => {
|
||||
let aiAssistantHelpers: ReturnType<typeof useAIAssistantHelpers>;
|
||||
|
||||
|
@ -390,3 +515,37 @@ describe.each(referencedNodesTestCases)('getReferencedNodes', (testCase) => {
|
|||
expect(aiAssistantHelpers.getReferencedNodes(testCase.node)).toEqual(testCase.expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Simplify assistant payloads', () => {
|
||||
let aiAssistantHelpers: ReturnType<typeof useAIAssistantHelpers>;
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia());
|
||||
aiAssistantHelpers = useAIAssistantHelpers();
|
||||
});
|
||||
|
||||
it('simplifyWorkflowForAssistant: Should remove unnecessary properties from workflow object', () => {
|
||||
const simplifiedWorkflow = aiAssistantHelpers.simplifyWorkflowForAssistant(testWorkflow);
|
||||
const removedProperties = [
|
||||
'createdAt',
|
||||
'updatedAt',
|
||||
'settings',
|
||||
'versionId',
|
||||
'usedCredentials',
|
||||
'sharedWithProjects',
|
||||
'pinData',
|
||||
'scopes',
|
||||
'tags',
|
||||
];
|
||||
removedProperties.forEach((property) => {
|
||||
expect(simplifiedWorkflow).not.toHaveProperty(property);
|
||||
});
|
||||
});
|
||||
|
||||
it('simplifyResultData: Should remove data from nodes', () => {
|
||||
const simplifiedResultData = aiAssistantHelpers.simplifyResultData(testExecutionData);
|
||||
for (const nodeName of Object.keys(simplifiedResultData.runData)) {
|
||||
expect(simplifiedResultData.runData[nodeName][0]).not.toHaveProperty('data');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,6 +16,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
|||
import { useDataSchema } from './useDataSchema';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { useI18n } from './useI18n';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
|
||||
const CANVAS_VIEWS = [VIEWS.NEW_WORKFLOW, VIEWS.WORKFLOW, VIEWS.EXECUTION_DEBUG];
|
||||
const EXECUTION_VIEWS = [VIEWS.EXECUTION_PREVIEW];
|
||||
|
@ -225,13 +226,13 @@ export const useAIAssistantHelpers = () => {
|
|||
simplifiedResultData.error = data.error;
|
||||
}
|
||||
// Map runData, excluding the `data` field from ITaskData
|
||||
Object.keys(data.runData).forEach((key) => {
|
||||
for (const key of Object.keys(data.runData)) {
|
||||
const taskDataArray = data.runData[key];
|
||||
simplifiedResultData.runData[key] = taskDataArray.map((taskData) => {
|
||||
const { data: taskDataContent, ...taskDataWithoutData } = taskData;
|
||||
return taskDataWithoutData;
|
||||
});
|
||||
});
|
||||
}
|
||||
// Handle lastNodeExecuted if it exists
|
||||
if (data.lastNodeExecuted) {
|
||||
simplifiedResultData.lastNodeExecuted = data.lastNodeExecuted;
|
||||
|
@ -243,6 +244,13 @@ export const useAIAssistantHelpers = () => {
|
|||
return simplifiedResultData;
|
||||
}
|
||||
|
||||
const simplifyWorkflowForAssistant = (workflow: IWorkflowDb): Partial<IWorkflowDb> => ({
|
||||
name: workflow.name,
|
||||
active: workflow.active,
|
||||
connections: workflow.connections,
|
||||
nodes: workflow.nodes,
|
||||
});
|
||||
|
||||
return {
|
||||
processNodeForAssistant,
|
||||
getNodeInfoForAssistant,
|
||||
|
@ -252,5 +260,6 @@ export const useAIAssistantHelpers = () => {
|
|||
getCurrentViewDescription,
|
||||
getReferencedNodes,
|
||||
simplifyResultData,
|
||||
simplifyWorkflowForAssistant,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -399,7 +399,9 @@ export const useAssistantStore = defineStore(STORES.ASSISTANT, () => {
|
|||
authType: nodeInfo?.authType?.name,
|
||||
}
|
||||
: undefined,
|
||||
currentWorkflow: workflowDataStale.value ? workflowsStore.workflow : undefined,
|
||||
currentWorkflow: workflowDataStale.value
|
||||
? assistantHelpers.simplifyWorkflowForAssistant(workflowsStore.workflow)
|
||||
: undefined,
|
||||
executionData:
|
||||
workflowExecutionDataStale.value && executionResult
|
||||
? assistantHelpers.simplifyResultData(executionResult)
|
||||
|
|
|
@ -19,7 +19,7 @@ export namespace ChatRequest {
|
|||
|
||||
export interface WorkflowContext {
|
||||
executionSchema?: NodeExecutionSchema[];
|
||||
currentWorkflow?: IWorkflowDb;
|
||||
currentWorkflow?: Partial<IWorkflowDb>;
|
||||
executionData?: IRunExecutionData['resultData'];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue