fix(ai-builder): Hide and reap intermediate AI-created workflows (backport to release-candidate/2.18.x)#29344
Conversation
|
Please cherry-pick the changes locally and resolve any conflicts. git fetch origin backport-29066-to-release-candidate/2.18.x
git worktree add --checkout .worktree/backport-29066-to-release-candidate/2.18.x backport-29066-to-release-candidate/2.18.x
cd .worktree/backport-29066-to-release-candidate/2.18.x
git reset --hard HEAD^
git cherry-pick -x 632ae67de3fa33487e1ad513043cf740cb32bb1a
git push --force-with-lease |
Performance ComparisonComparing current → latest master → 14-day baseline Memory consumption baseline with starter plan resources
Idle baseline with Instance AI module loaded
docker-stats
How to read this table
|
There was a problem hiding this comment.
5 issues found across 30 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/components/AgentActivityTree.vue">
<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/AgentActivityTree.vue:94">
P0: Unresolved merge conflict markers were committed in the Vue template, which will break compilation.</violation>
</file>
<file name="packages/frontend/@n8n/i18n/src/locales/en.json">
<violation number="1" location="packages/frontend/@n8n/i18n/src/locales/en.json:5151">
P0: Remove unresolved merge-conflict markers from the locale JSON file; they make `en.json` invalid JSON.</violation>
</file>
<file name="packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts">
<violation number="1" location="packages/@n8n/instance-ai/src/storage/__tests__/planned-task-storage.test.ts:6">
P2: Move this mock state inside the factory or rename it to a `mock*` variable so Jest can hoist the mock without hitting the out-of-scope variable restriction.</violation>
</file>
<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.store.ts">
<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/instanceAi.store.ts:521">
P2: Clearing `archivedWorkflowIds` on thread reset drops archived artifact state when returning to a previously viewed thread, because hydration does not repopulate archived IDs.</violation>
</file>
<file name="packages/@n8n/db/src/repositories/workflow.repository.ts">
<violation number="1" location="packages/@n8n/db/src/repositories/workflow.repository.ts:886">
P2: The AI-temporary filter is applied unconditionally, so archived list queries (`isArchived: true`) also hide AI-created archived workflows. This prevents those workflows from being visible/recoverable in archive views.</violation>
</file>
Architecture diagram
sequenceDiagram
participant UI as Client (Frontend Store/UI)
participant AIS as InstanceAiService
participant Adapter as InstanceAiAdapterService
participant TWR as NEW: AiBuilderTemporaryWorkflowRepository
participant DB as Database (Workflow Table)
Note over UI, DB: AI Workflow Creation & Marking
UI->>AIS: Start AI Run (chat/replan)
AIS->>Adapter: Create intermediate workflow (stepping-stone)
Adapter->>DB: Insert workflow record
Adapter->>TWR: NEW: mark(workflowId, threadId)
TWR->>DB: Insert into ai_builder_temporary_workflow
Note over UI, DB: List Filtering (Concurrent Request)
UI->>DB: GET /workflows (User list)
DB->>DB: CHANGED: Filter WHERE NOT EXISTS in temporary_marker_table
DB-->>UI: Workflow list (intermediate AI workflows hidden)
Note over UI, DB: Main Workflow Promotion
AIS->>AIS: Identify successful main workflow
AIS->>Adapter: NEW: clearAiTemporary(workflowId)
Adapter->>TWR: NEW: unmark(workflowId)
TWR->>DB: DELETE FROM ai_builder_temporary_workflow
Note over UI, DB: Run Finish & Reaping (Success or Error)
AIS->>AIS: handleRunFinish()
AIS->>TWR: NEW: findByThread(threadId)
TWR-->>AIS: List of remaining marked workflowIds
loop For each marked ID (Stepping-stones)
AIS->>Adapter: NEW: archiveIfAiTemporary(workflowId)
Adapter->>DB: CHANGED: Soft-delete (archive) workflow
Adapter->>TWR: NEW: unmark(workflowId)
end
Note over UI, DB: UI Synchronization
AIS-->>UI: CHANGED: Event: "run-finish" (includes archivedWorkflowIds[])
UI->>UI: NEW: Update ResourceRegistry (archived: true)
UI->>UI: CHANGED: Render archived ArtifactCards dimmed/strikethrough
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| <<<<<<< HEAD | ||
| ======= | ||
| :archived="store.producedArtifacts.get(artifact.resourceId)?.archived" | ||
| :class="$style.artifactCard" | ||
| >>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066)) |
There was a problem hiding this comment.
P0: Unresolved merge conflict markers were committed in the Vue template, which will break compilation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/frontend/editor-ui/src/features/ai/instanceAi/components/AgentActivityTree.vue, line 94:
<comment>Unresolved merge conflict markers were committed in the Vue template, which will break compilation.</comment>
<file context>
@@ -91,6 +91,11 @@ function resolveArtifactName(artifact: ArtifactInfo): string {
:name="resolveArtifactName(artifact)"
:resource-id="artifact.resourceId"
:project-id="artifact.projectId"
+<<<<<<< HEAD
+=======
+ :archived="store.producedArtifacts.get(artifact.resourceId)?.archived"
</file context>
| <<<<<<< HEAD | |
| ======= | |
| :archived="store.producedArtifacts.get(artifact.resourceId)?.archived" | |
| :class="$style.artifactCard" | |
| >>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066)) | |
| :archived="store.producedArtifacts.get(artifact.resourceId)?.archived" | |
| :class="$style.artifactCard" |
| <<<<<<< HEAD | ||
| ======= | ||
| "instanceAi.artifactsPanel.archived": "Archived", | ||
| "instanceAi.previewTabBar.collapse": "Collapse panel", | ||
| "instanceAi.previewTabBar.openInEditor": "Open in editor", | ||
| "instanceAi.previewTabBar.copyLink": "Copy link", | ||
| >>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066)) |
There was a problem hiding this comment.
P0: Remove unresolved merge-conflict markers from the locale JSON file; they make en.json invalid JSON.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/frontend/@n8n/i18n/src/locales/en.json, line 5151:
<comment>Remove unresolved merge-conflict markers from the locale JSON file; they make `en.json` invalid JSON.</comment>
<file context>
@@ -5148,6 +5148,13 @@
"instanceAi.artifactsPanel.noArtifacts": "No artifacts yet",
"instanceAi.artifactsPanel.tasks": "Tasks",
"instanceAi.artifactsPanel.openWorkflow": "Open",
+<<<<<<< HEAD
+=======
+ "instanceAi.artifactsPanel.archived": "Archived",
</file context>
| <<<<<<< HEAD | |
| ======= | |
| "instanceAi.artifactsPanel.archived": "Archived", | |
| "instanceAi.previewTabBar.collapse": "Collapse panel", | |
| "instanceAi.previewTabBar.openInEditor": "Open in editor", | |
| "instanceAi.previewTabBar.copyLink": "Copy link", | |
| >>>>>>> 632ae67de3 (fix(ai-builder): Hide and reap intermediate AI-created workflows (#29066)) | |
| "instanceAi.artifactsPanel.archived": "Archived", | |
| "instanceAi.previewTabBar.collapse": "Collapse panel", | |
| "instanceAi.previewTabBar.openInEditor": "Open in editor", | |
| "instanceAi.previewTabBar.copyLink": "Copy link", |
- workflow.repository.ts: skip the AI-temporary filter when listing archived workflows so reaped AI-created workflows remain visible in the archive view. - instanceAi.store.ts: scope archivedWorkflowIds per thread so the archived state survives thread switches instead of being cleared on every reset. - planned-task-storage.test.ts: rename metadataByThread to mockMetadataByThread so jest can hoist the mock factory without hitting the out-of-scope variable restriction.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Instance AI Workflow Eval Results8/8 built | 12/27 passed (44%)
Failure detailsmissing-fields
partial-action-failure [builder_issue]
invalid-email [builder_issue]
multi-team-creator [builder_issue]
The scenario data states Alice api-error [builder_issue]
channel-not-found [builder_issue]
insufficient-permissions [builder_issue]
happy-path [builder_issue]
no-bugs [builder_issue]
high-priority [builder_issue]
medium-priority [builder_issue]
low-priority [builder_issue]
happy-path [builder_issue]
happy-path [builder_issue]
no-alerts [builder_issue]
|
Bundle ReportChanges will increase total bundle size by 44.01kB (0.1%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: editor-ui-esmAssets Changed:
Files in
Files in
|
|
Got released with |
Description
Backport of #29066 to
release-candidate/2.18.x.Checklist for the author (@aalises) to go through.
After this PR has been merged, it will be picked up in the next patch release for release track.
Original description
Summary
The AI builder leaves intermediate workflows behind in two scenarios (INS-24):
Both surface in the user's workflows list as half-built clutter the user didn't ask for.
How it works
meta.aiTemporary: trueis stamped on every workflow the AI builder creates (submit-workflow+build-workflow, only on create — never on update so user-authored workflows are untouched). No DB migration:metais already a nullable JSON column.mainWorkflowAttempt.workflowIdat the end of every successful build — the deliverable is now indistinguishable from a user workflow.archiveIfAiTemporaryon each id. Atomic check-and-archive: anything still stamped (chunks, scratch, obsoleted-by-replan) gets soft-deleted; the main survives because its stamp was cleared.Artifacts panel UX
The artifacts panel keeps stepping-stones visible in the conversation history after the run ends — but they've been archived, so clicking them would lead to a dead preview. To close that loop:
run-finishevents carryarchivedWorkflowIds: string[]— the ids the reap just soft-deleted.archived: true.ArtifactCardused by the activity tree and timeline, render archived entries dimmed with a strikethrough name and an "Archived" pill.Why this shape
build-workflow-with-agentcalls — every code path that could leak a stepping-stone reduces to a single SQL predicate.Crash leaks (process dies mid-run before run-finish fires) are accepted as known: invisible to the user (list filter) and rare. Easy to add a one-off admin sweep later if it ever materializes.
Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/INS-24
Review / Merge checklist