Instance AI workflow setup nodes groupping#29764
Instance AI workflow setup nodes groupping#29764scdekov wants to merge 5 commits intofeature/instance-ai-workflow-setup-rewritefrom
Conversation
b8b07b6 to
b3b3727
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
3 issues found across 102 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupGroupCard.vue">
<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/workflowSetup/components/WorkflowSetupGroupCard.vue:73">
P2: Use an interactive control (e.g. `button`) for the section toggle instead of a clickable `div` so it is keyboard-accessible and has correct semantics.</violation>
</file>
<file name="packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts">
<violation number="1" location="packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts:876">
P2: Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.</violation>
</file>
<file name="packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts">
<violation number="1" location="packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts:885">
P2: Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.</violation>
</file>
Architecture diagram
sequenceDiagram
participant AI as Instance AI Agent
participant Backend as Backend API
participant Tool as Workflows Tool
participant Service as Setup Workflow Service
participant Frontend as Wizard UI
participant Sections as useWorkflowSetupSections
participant Steps as useWorkflowSetupSteps
participant Wizard as WorkflowSetupWizard
participant GroupCard as WorkflowSetupGroupCard
participant SectionCard as WorkflowSetupSectionBody
Note over AI,Service: NEW: Grouping and Parent/Sub-node support
AI->>Tool: setup(workflowId)
Tool->>Service: analyzeWorkflow(workflowId)
Service->>Service: NEW: filter(isActionableSetupRequest)
alt No actionable requests
Tool-->>AI: { success: true, reason: "No nodes require setup." }
end
Service->>Service: NEW: buildSubnodeToRootParentMap()
Note over Service: Walks workflow graph via ALL_NON_MAIN connections
Service->>Service: Stamp parentNode on sub-node setup requests
Service-->>Tool: setupRequests[] with parentNode metadata
Tool-->>AI: suspend with actionable setupRequests
Note over AI,Tool: NEW: Non-actionable requests filtered out before suspend
AI-->>Frontend: Open setup wizard with setupRequests
Frontend->>Sections: useWorkflowSetupSections(setupRequests)
Sections->>Sections: NEW: Group cred-only requests by credentialType
Sections->>Sections: NEW: Group HTTP requests by same URL (split expressions)
Sections->>Sections: NEW: Keep params-bearing requests independent
Sections-->>Frontend: sections[]
Frontend->>Steps: useWorkflowSetupSteps({ sections, setupRequests })
Steps->>Steps: NEW: Fold sections sharing a parentNode into a { group } step
alt Section has parentNode metadata
Steps->>Steps: Add to group.subnodeSections
else Section is itself a parent (has sub-node children)
Steps->>Steps: Add as group.parentSection
else No parent
Steps->>Steps: Emit as { kind: 'section' }
end
Steps-->>Frontend: steps[]
Frontend->>Wizard: Render steps
Note over Wizard: NEW: Steps can be 'section' or 'group'
alt Step is kind: 'group'
Wizard->>GroupCard: render(group)
GroupCard->>GroupCard: NEW: Show parent header (always visible)
alt Group has parentSection
GroupCard->>SectionCard: Render parent inline (no collapse)
end
loop For each sub-node section
GroupCard->>GroupCard: NEW: Collapsible sub-node sections
GroupCard->>SectionCard: Render with expand/collapse
Note over GroupCard: Auto-expand first incomplete sub-node
Note over GroupCard: Auto-collapse completed cred-only sections
end
else Step is kind: 'section'
Wizard->>SectionCard: render(section)
end
Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Fix all with cubic.
| const subnodeToRootParent = buildSubnodeToRootParentMap( | ||
| workflowJson.nodes, | ||
| workflowJson.connections as unknown as IConnections, | ||
| setupRequests.map((req) => req.node.name), |
There was a problem hiding this comment.
P2: Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/instance-ai/src/tools/workflows/setup-workflow.service.ts, line 876:
<comment>Parent ownership ranking is based on filtered setup requests, so root parents without cards lose execution-order priority and sub-nodes can be grouped under the wrong parent.</comment>
<file context>
@@ -785,5 +866,23 @@ export async function analyzeWorkflow(
+ const subnodeToRootParent = buildSubnodeToRootParentMap(
+ workflowJson.nodes,
+ workflowJson.connections as unknown as IConnections,
+ setupRequests.map((req) => req.node.name),
+ );
+ if (subnodeToRootParent.size > 0) {
</file context>
There was a problem hiding this comment.
Since we're not executing nodes in the instance-ai setup flow, it's fine (or even better) to show the subnode as part of the parent which is actionable since that will result in fewer cards and it still make sense to the user.
There was a problem hiding this comment.
Thanks for the feedback! I've saved this as a new learning to improve future reviews.
| const firstCrdentialInList = await n8n.api.credentials.createCredential({ | ||
| name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME, | ||
| type: 'slackApi', | ||
| data: { | ||
| accessToken: 'xoxb-initial-token-for-testing', | ||
| accessToken: 'xoxb-target-token-for-testing', | ||
| }, | ||
| }); | ||
| const targetCredential = await n8n.api.credentials.createCredential({ | ||
| name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME, | ||
| const secondCrdentialInList = await n8n.api.credentials.createCredential({ | ||
| name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME, | ||
| type: 'slackApi', | ||
| data: { | ||
| accessToken: 'xoxb-target-token-for-testing', | ||
| accessToken: 'xoxb-initial-token-for-testing', | ||
| }, | ||
| }); | ||
|
|
There was a problem hiding this comment.
P2: Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/testing/playwright/tests/e2e/instance-ai/instance-ai-workflow-setup.spec.ts, line 885:
<comment>Create the alphabetically first credential first here, or update the expectation to match the actual dropdown order.</comment>
<file context>
@@ -576,26 +881,24 @@ test.describe(
- const initialCredential = await n8n.api.credentials.createCredential({
- name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME,
+ // creds are sorted by name, in the dropdown
+ const firstCrdentialInList = await n8n.api.credentials.createCredential({
+ name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME,
type: 'slackApi',
</file context>
| const firstCrdentialInList = await n8n.api.credentials.createCredential({ | |
| name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME, | |
| type: 'slackApi', | |
| data: { | |
| accessToken: 'xoxb-initial-token-for-testing', | |
| accessToken: 'xoxb-target-token-for-testing', | |
| }, | |
| }); | |
| const targetCredential = await n8n.api.credentials.createCredential({ | |
| name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME, | |
| const secondCrdentialInList = await n8n.api.credentials.createCredential({ | |
| name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME, | |
| type: 'slackApi', | |
| data: { | |
| accessToken: 'xoxb-target-token-for-testing', | |
| accessToken: 'xoxb-initial-token-for-testing', | |
| }, | |
| }); | |
| // creds are sorted by name, in the dropdown | |
| const firstCrdentialInList = await n8n.api.credentials.createCredential({ | |
| name: SELECT_EXISTING_INITIAL_CREDENTIAL_NAME, | |
| type: 'slackApi', | |
| data: { | |
| accessToken: 'xoxb-initial-token-for-testing', | |
| }, | |
| }); | |
| const secondCrdentialInList = await n8n.api.credentials.createCredential({ | |
| name: SELECT_EXISTING_TARGET_CREDENTIAL_NAME, | |
| type: 'slackApi', | |
| data: { | |
| accessToken: 'xoxb-target-token-for-testing', | |
| }, | |
| }); |
Instance AI Workflow Eval Results14/14 built | 3 run(s) | pass@3: 74% | pass^3: 43% | iterations: 57% / 60% / 51%
Failure detailsCreate a workflow that handles contact form submissions via a webhook. / partial-action-failure — 0/3 passed
Create a workflow that handles contact form submissions via a webhook. / invalid-email — 0/3 passed
Get all the Linear issues created in the last 2 weeks. Filter them for / happy-path — 1/3 passed
Get all the Linear issues created in the last 2 weeks. Filter them for / multi-team-creator — 2/3 passed
Get all the Linear issues created in the last 2 weeks. Filter them for / no-cross-team-issues — 1/3 passed
Get all the Linear issues created in the last 2 weeks. Filter them for / unknown-creator — 2/3 passed
Get all the Linear issues created in the last 2 weeks. Filter them for / api-error — 1/3 passed
Every day, get the posts made in the past day on 3 different Slack cha / happy-path — 2/3 passed
Every day, get the posts made in the past day on 3 different Slack cha / empty-channel — 1/3 passed
Every day, get the posts made in the past day on 3 different Slack cha / high-volume — 1/3 passed
Every day, get the posts made in the past day on 3 different Slack cha / channel-not-found — 0/3 passed
Every day, get the posts made in the past day on 3 different Slack cha / insufficient-permissions — 0/3 passed
Every day, fetch all open GitHub issues from repository 'acme-corp/bac / happy-path — 2/3 passed
Every day, fetch all open GitHub issues from repository 'acme-corp/bac / no-bugs — 2/3 passed
Every two weeks I want to check the amount of n8n usage and bug report / happy-path — 0/3 passed
Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp / happy-path — 0/3 passed
Fetch the latest posts from the JSONPlaceholder API (GET https://jsonp / all-filtered — 0/3 passed
Build a Telegram chatbot workflow for a family assistant. It should re / distinct-telegram-chat — 0/3 passed
Every day at 8am, check the weather in Berlin using the OpenMeteo API / rain-not-expected — 2/3 passed
Every hour, check the current weather for London, New York, and Tokyo / happy-path — 0/3 passed
Every hour, check the current weather for London, New York, and Tokyo / no-alerts — 1/3 passed
I want you to build a workflow that will read n8n workflow databases a / happy-path — 2/3 passed
|
…toggling and improved accessibility
Summary
Grouping of instance ai setup requests based on:
Review notes:
parentNodeto theworkflowSetupNodeSchemaso that FE doesn't have to fetch the whole workflow in order to group based on parent/sub nodesWorkflowSetupCardandWorkflowSetupGroupCard, both using a newWorkflowSetupSectionBodycomponentWorkflowSetupWizardFooterfromWorkflowSetupWizardas it's now reused for the group and non group card componentsRelated Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/ADO-5119/add-cards-grouping
Review / Merge checklist
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)