Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(editor): Add missing node parameter values to AI Assistant request #10788

Merged
merged 25 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c5d38ed
fix(editor): Add missing node parameter values
MiloradFilipovic Sep 11, 2024
7ce1d38
⚡ Sending resolved expression values to assistant
MiloradFilipovic Sep 11, 2024
c5a05a5
⚡ Not sending ndv inputs if node is not connected. Adding a function …
MiloradFilipovic Sep 11, 2024
a0bdf5b
⚡ Resolving all expressions and sending the values to assistant
MiloradFilipovic Sep 11, 2024
640e2ff
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 12, 2024
990ebbf
⚡ Moving util method to `workflowHelpers` fixing types
MiloradFilipovic Sep 12, 2024
e6c447b
⚡ Improving typing
MiloradFilipovic Sep 12, 2024
b2e0750
🔨 Renaming and refactoring
MiloradFilipovic Sep 12, 2024
7532510
✅ Adding tests
MiloradFilipovic Sep 12, 2024
90a3bb3
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 12, 2024
ab7c00f
🔥 Removing unused import
MiloradFilipovic Sep 12, 2024
60132e7
✔️ Adding missing router mock
MiloradFilipovic Sep 12, 2024
5333764
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 13, 2024
dad019c
👌 Converting `resolveNodeExpressions` to pure function, using `deepCo…
MiloradFilipovic Sep 13, 2024
7fa9b4f
👌 Refactoring for more readability, adding tests
MiloradFilipovic Sep 13, 2024
5ef46b2
👕 Removing unused import
MiloradFilipovic Sep 13, 2024
e47fdd0
👕 Breaking up long lines
MiloradFilipovic Sep 13, 2024
39a455e
✅ Adding more test cases, handling missed edge case
MiloradFilipovic Sep 13, 2024
1fa12b3
🔥 Removing leftover console.log
MiloradFilipovic Sep 13, 2024
60db641
⚡ Adding support for backticks, skipping empty values, updating test …
MiloradFilipovic Sep 17, 2024
29db847
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 17, 2024
8aa94fc
⚡ Updating expression resolving logic
MiloradFilipovic Sep 17, 2024
7173ef0
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 17, 2024
621e70a
Merge branch 'master' into ai-assistant-node-data-improvements
MiloradFilipovic Sep 17, 2024
acbc00f
⚡ Resolving assistant expressions using default values
MiloradFilipovic Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { useWorkflowsEEStore } from '@/stores/workflows.ee.store';
import { useTagsStore } from '@/stores/tags.store';
import { createTestWorkflow } from '@/__tests__/mocks';
import type { AssignmentCollectionValue } from 'n8n-workflow';

const getDuplicateTestWorkflow = (): IWorkflowDataUpdate => ({
name: 'Duplicate webhook test',
Expand Down Expand Up @@ -70,7 +71,7 @@ describe('useWorkflowHelpers', () => {
vi.clearAllMocks();
});

describe('resolveNodeExpressions', () => {
describe('getNodeParametersWithResolvedExpressions', () => {
it('should correctly detect and resolve expressions in a regular node ', () => {
const nodeParameters = {
curlImport: '',
Expand All @@ -85,8 +86,9 @@ describe('useWorkflowHelpers', () => {
infoMessage: '',
};
const workflowHelpers = useWorkflowHelpers({ router });
workflowHelpers.resolveNodeExpressions(nodeParameters);
expect(nodeParameters.url).toHaveProperty('resolvedExpressionValue');
const resolvedParameters =
workflowHelpers.getNodeParametersWithResolvedExpressions(nodeParameters);
expect(resolvedParameters.url).toHaveProperty('resolvedExpressionValue');
});

it('should correctly detect and resolve expressions in a node with assignments (set node) ', () => {
Expand All @@ -108,10 +110,12 @@ describe('useWorkflowHelpers', () => {
options: {},
};
const workflowHelpers = useWorkflowHelpers({ router });
workflowHelpers.resolveNodeExpressions(nodeParameters);
expect(nodeParameters.assignments.assignments[0].value).toHaveProperty(
'resolvedExpressionValue',
);
const resolvedParameters =
workflowHelpers.getNodeParametersWithResolvedExpressions(nodeParameters);
expect(resolvedParameters).toHaveProperty('assignments');
const assignments = resolvedParameters.assignments as AssignmentCollectionValue;
expect(assignments).toHaveProperty('assignments');
expect(assignments.assignments[0].value).toHaveProperty('resolvedExpressionValue');
});

it('should correctly detect and resolve expressions in a node with filter component', () => {
Expand Down Expand Up @@ -147,8 +151,12 @@ describe('useWorkflowHelpers', () => {
options: {},
};
const workflowHelpers = useWorkflowHelpers({ router });
workflowHelpers.resolveNodeExpressions(nodeParameters);
expect(nodeParameters.rules.values[0].conditions.conditions[0].leftValue).toHaveProperty(
const resolvedParameters = workflowHelpers.getNodeParametersWithResolvedExpressions(
nodeParameters,
) as typeof nodeParameters;
expect(resolvedParameters).toHaveProperty('rules');
expect(resolvedParameters.rules).toHaveProperty('values');
expect(resolvedParameters.rules.values[0].conditions.conditions[0].leftValue).toHaveProperty(
'resolvedExpressionValue',
);
});
Expand All @@ -172,9 +180,11 @@ describe('useWorkflowHelpers', () => {
options: {},
};
const workflowHelpers = useWorkflowHelpers({ router });
workflowHelpers.resolveNodeExpressions(nodeParameters);
expect(nodeParameters.documentId.value).toHaveProperty('resolvedExpressionValue');
expect(nodeParameters.sheetName.value).toHaveProperty('resolvedExpressionValue');
const resolvedParameters = workflowHelpers.getNodeParametersWithResolvedExpressions(
nodeParameters,
) as typeof nodeParameters;
expect(resolvedParameters.documentId.value).toHaveProperty('resolvedExpressionValue');
expect(resolvedParameters.sheetName.value).toHaveProperty('resolvedExpressionValue');
});
it('should correctly detect and resolve expressions in a node with resource mapper component', () => {
const nodeParameters = {
Expand Down Expand Up @@ -209,8 +219,10 @@ describe('useWorkflowHelpers', () => {
options: {},
};
const workflowHelpers = useWorkflowHelpers({ router });
workflowHelpers.resolveNodeExpressions(nodeParameters);
expect(nodeParameters.filtersUI.values[0].lookupValue).toHaveProperty(
const resolvedParameters = workflowHelpers.getNodeParametersWithResolvedExpressions(
nodeParameters,
) as typeof nodeParameters;
expect(resolvedParameters.filtersUI.values[0].lookupValue).toHaveProperty(
'resolvedExpressionValue',
);
});
Expand Down
28 changes: 19 additions & 9 deletions packages/editor-ui/src/composables/useWorkflowHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,30 +693,40 @@ export function useWorkflowHelpers(options: { router: ReturnType<typeof useRoute
return NodeHelpers.getNodeWebhookUrl(baseUrl, workflowId, node, path, isFullPath);
}

function resolveNodeExpressions(nodeParameters: INodeParameters): void {
function recurse(currentObj: { [key: string]: unknown }, currentPath: string) {
/**
* Returns a copy of provided node parameters with added resolvedExpressionValue
* @param nodeParameters
* @returns
*/
function getNodeParametersWithResolvedExpressions(
nodeParameters: INodeParameters,
): INodeParameters {
function recurse(currentObj: INodeParameters, currentPath: string): INodeParameters {
const newObj: INodeParameters = {};
for (const key in currentObj) {
const value = currentObj[key as keyof typeof currentObj];
const path = currentPath ? `${currentPath}.${key}` : key;
if (typeof value === 'object' && value !== null) {
recurse(value as { [key: string]: unknown }, path);
} else if (typeof value === 'string' && String(value).startsWith('={{')) {
newObj[key] = recurse(value as INodeParameters, path);
} else if (typeof value === 'string' && String(value).startsWith('=')) {
// Resolve the expression if it is one
let resolved;
try {
resolved = resolveExpression(value, nodeParameters);
} catch (error) {
resolved = `Error in expression: "${error.message}"`;
}
// Updating the original object with the resolved value
currentObj[key] = {
newObj[key] = {
value,
resolvedExpressionValue: resolved,
resolvedExpressionValue: String(resolved),
};
} else {
newObj[key] = value;
}
}
return newObj;
}
recurse(nodeParameters, '');
return recurse(nodeParameters, '');
}

function resolveExpression(
Expand Down Expand Up @@ -1185,6 +1195,6 @@ export function useWorkflowHelpers(options: { router: ReturnType<typeof useRoute
getWorkflowProjectRole,
promptSaveUnsavedWorkflowChanges,
initState,
resolveNodeExpressions,
getNodeParametersWithResolvedExpressions,
};
}
Loading
Loading