Skip to content

feat(editor): Add response grouping and thinking UI for instance AI (no-changelog)#28236

Merged
r00gm merged 25 commits intomasterfrom
thinking-ui
Apr 13, 2026
Merged

feat(editor): Add response grouping and thinking UI for instance AI (no-changelog)#28236
r00gm merged 25 commits intomasterfrom
thinking-ui

Conversation

@r00gm
Copy link
Copy Markdown
Contributor

@r00gm r00gm commented Apr 9, 2026

Summary

  • Add response grouping to instance AI timeline, collapsing tool calls and intermediate text into expandable sections per response
  • Track responseId through stream chunks and agent-spawned tool calls for accurate grouping
  • Extract trailing text from response groups so conclusions remain visible
  • Add AnimatedCollapsibleContent component with slide animations for all collapsible sections
  • Make PlanReviewPanel header a collapsible trigger so the body collapses after approval
  • Fix InstanceAiMarkdown event listener leak (clean up handlers on update/unmount)
  • Reduce initial event listener count by ~37% through listener cleanup
  • Visual refinements from instance-ai-visual-tweaks-3

Related Linear tickets, Github issues, and Community forum posts

Builds on #28155

Review / Merge checklist

  • I have seen this code, I have run this code, and I take responsibility for this code.
  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.

Test plan

  • Verify response groups collapse/expand correctly in instance AI chat
  • Verify streaming responses group in real-time
  • Verify answered questions count displays correctly
  • Verify trailing text after tool calls remains visible outside groups
  • Verify collapsible animations (slide down/up) work on all sections
  • Verify PlanReviewPanel collapses after approval
  • Browser performance profiled — listeners reduced from ~7,900 to ~4,900

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Bundle Report

Changes will decrease total bundle size by 45.61MB (-100.0%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
editor-ui-esm (removed) -45.61MB (-100.0%) ⬇️

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Performance Comparison

Comparing currentlatest master14-day baseline

Idle baseline with Instance AI module loaded

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
instance-ai-heap-used-baseline 186.06 MB 186.02 MB 186.31 MB (σ 0.25) +0.0% -0.1%
instance-ai-rss-baseline 342.67 MB 380.71 MB 369.52 MB (σ 24.20) -10.0% -7.3% ⚠️

docker-stats

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
docker-image-size-n8n 1269.76 MB 1269.76 MB 1269.76 MB (σ 0.00) +0.0% +0.0%
docker-image-size-runners 393.00 MB 418.00 MB 391.43 MB (σ 11.93) -6.0% +0.4%

Memory consumption baseline with starter plan resources

Metric Current Latest Master Baseline (avg) vs Master vs Baseline Status
memory-heap-used-baseline 113.91 MB 114.20 MB 113.67 MB (σ 1.06) -0.2% +0.2%
memory-rss-baseline 345.33 MB 352.66 MB 283.64 MB (σ 42.70) -2.1% +21.8% ⚠️
How to read this table
  • Current: This PR's value (or latest master if PR perf tests haven't run)
  • Latest Master: Most recent nightly master measurement
  • Baseline: Rolling 14-day average from master
  • vs Master: PR impact (current vs latest master)
  • vs Baseline: Drift from baseline (current vs rolling avg)
  • Status: ✅ within 1σ | ⚠️ 1-2σ | 🔴 >2σ regression

@n8n-assistant n8n-assistant Bot added the n8n team Authored by the n8n team label Apr 9, 2026
Tuukkaa and others added 22 commits April 13, 2026 09:12
…ents

Remove header icon, task count, status badges, kind icons/badges,
accordion behavior, and divider lines. Use N8nText, N8nInput components
instead of raw HTML elements. Shorten approve button label to "Approve".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… mode contrast

Restyle AnsweredQuestions to match user message alignment and appearance
(right-aligned grey bubble). Use neutral design token for ConfirmationPreview
background in dark mode for better contrast.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…section

Extract communication style rules (conciseness, no emojis, always end with
text) into a dedicated section, keeping Safety focused on actual safety
concerns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ArtifactCard: replace hoverable prop with standard box-shadow hover
- CredentialSetup & WorkflowSetup: remove green success border on
  completed/confirm cards, keep regular border

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…st spacing

Use consistent medium-size buttons across all instance AI confirmation
components, add background to gateway resource decision panel, and
reduce thread item height to 32px with proper padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use design system N8nHeading for artifacts/tasks panel titles, increase
pagination button sizes, use ghost variant for credential nav buttons,
and lighten question list hover states.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove accidentally committed debug mock messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tance AI

Add ResponseGroup component and useTimelineGrouping composable for better
organization of agent activity. Update agent-run-reducer schema, stream
mapping, and timeline components to support grouped responses. Fix invalid
CSS variable --text-color--subtler in AgentActivityTree and ArtifactCard.
…ponseId patch, keep intermediate text in groups

- Extract HIDDEN_TOOLS to shared agentTimeline.utils
- Preserve responseId when patching streaming timeline entries
- Keep text inside groups when it shares the same API response as tool calls
- Only render text inline when it comes from a standalone response
…count, prevent premature collapse

- Remove isCompleted gate — grouping applies as soon as responseId data exists
- Last response group stays flat while agent is still active (prevents collapsing during streaming)
- Groups with loading tool calls or active children don't collapse
- Track and display answered questions count in group summaries
… inherit for agent-spawned

- Capture responseId from step-start before the trace hooks branch (was skipped when hooks active)
- Inherit responseId from parent timeline for agent-spawned events (emitted from tool code, not stream)
- Remove temporary debug logging
- Lazy-mount CollapsibleContent in ResponseGroup and AgentSection
  (v-if="isOpen" + force-mount) so reka-ui RAF loops and keyboard
  handlers are not registered for collapsed items
- Fix InstanceAiMarkdown listener leak: clean up click handlers on
  onUpdated and onBeforeUnmount instead of accumulating them
- Mutate workflowExecutions Map in-place with triggerRef instead of
  cloning on every SSE event in useExecutionPushEvents
- Narrow useEventRelay watch to only track active workflow status and
  log length instead of the entire Map reference
Keep the readable original watch shape while adding a prevLogLength
guard to skip redundant relay calls when the event log hasn't grown.
- Create AnimatedCollapsibleContent wrapper component with slideDown/
  slideUp keyframes using reka-ui's --reka-collapsible-content-height
- Replace raw CollapsibleContent in all 8 instance AI components
- Make PlanReviewPanel header a collapsible trigger so the body
  collapses after approval
- Add i18n key for changesRequested
…nal patterns

Revert the triggerRef/in-place mutation optimization in
useExecutionPushEvents and the prevLogLength guard in useEventRelay.
The in-place mutation + triggerRef approach doesn't propagate correctly
through Vue's watch equality check, causing test failures. The perf
wins are maintained by the other fixes (InstanceAiMarkdown listener
cleanup, AnimatedCollapsibleContent).
r00gm added 2 commits April 13, 2026 09:29
… counter

Bring back in-place Map mutation in useExecutionPushEvents (avoids
cloning the entire Map on every SSE event). Use a monotonic version
counter ref instead of triggerRef so Vue's watch equality check
properly detects changes. Update useEventRelay to watch the version
counter, and update tests to bump version alongside mutations.
Replace version counter approach with shallowRef + triggerRef. This is
the standard Vue pattern for in-place mutations on non-primitive refs:
shallowRef skips deep reactivity wrapping so triggerRef properly
notifies watchers. Avoids cloning the entire Map on every SSE event.
…tions

Remove shallowRef/triggerRef/version-counter optimizations from
useExecutionPushEvents and useEventRelay. Profiling showed these
changes had no measurable impact on listener count or heap usage —
the listener reduction attributed to them was actually caused by
the relay watch silently breaking (never firing). Restore original
patterns from master for correctness and simplicity.
@Cadiac Cadiac marked this pull request as ready for review April 13, 2026 08:40
Copy link
Copy Markdown
Contributor

@Cadiac Cadiac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 nice, pretty clean looking changes

@Cadiac Cadiac changed the title feat(editor): Add response grouping and thinking UI for instance AI feat(editor): Add response grouping and thinking UI for instance AI (no-changelog) Apr 13, 2026
@r00gm r00gm added this pull request to the merge queue Apr 13, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 issues found across 37 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/InstanceAiMarkdown.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiMarkdown.vue:216">
P1: The new update cycle removes link click handlers but does not reattach them for already-enhanced links, which can break resource preview clicks after updates.</violation>
</file>

<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiConfirmationPanel.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiConfirmationPanel.vue:504">
P3: This change introduces a legacy background token (`--color--background--light-3`) in modified styles. Use the semantic token (`--color-background-xlight`) for new/updated code to align with design-system migration rules.</violation>
</file>

<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiThreadList.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiThreadList.vue:225">
P3: This token substitution changes thread list spacing (`--spacing--4xs` → `--spacing--2xs`). Please confirm this is an intentional visual adjustment and not an accidental regression.</violation>

<violation number="2" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiThreadList.vue:245">
P2: Replace the hard-coded `32px` height with a design-system token (for example `var(--height--md)`) to keep sizing consistent and themeable.

(Based on your team's feedback about using design-system tokens for visual values when a matching token exists.) [FEEDBACK_USED]</violation>
</file>

<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiQuestions.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/InstanceAiQuestions.vue:619">
P3: This changes the hover background token from neutral-200 to neutral-100. Per the design-system style rules, token substitutions should be confirmed as intentional to avoid accidental visual regressions.</violation>
</file>

<file name="packages/frontend/editor-ui/src/features/ai/instanceAi/components/PlanReviewPanel.vue">

<violation number="1" location="packages/frontend/editor-ui/src/features/ai/instanceAi/components/PlanReviewPanel.vue:45">
P2: `isExpanded` is not kept in sync with `readOnly`, so the panel can stay open after approval/resolution instead of collapsing with the new read-only state.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant LLM as Anthropic / LLM
    participant Exec as ResumableStreamExecutor (Backend)
    participant Reducer as Agent Run Reducer
    participant Store as InstanceAiStore (Frontend)
    participant Grouping as useTimelineGrouping (Composable)
    participant Tree as AgentActivityTree (UI)
    participant Group as ResponseGroup (UI)
    participant MD as InstanceAiMarkdown (UI)

    Note over LLM, MD: Runtime Streaming & Grouping Flow

    LLM->>Exec: SSE Chunk (step-start)
    Exec->>Exec: NEW: Extract responseId (messageId)
    
    LLM->>Exec: SSE Chunk (text-delta / tool-call)
    Exec->>Reducer: NEW: Emit event with responseId
    
    Reducer->>Reducer: CHANGED: Append to timeline<br/>(Merge text if responseId matches last)
    Reducer-->>Store: Update Agent State
    
    Store->>Grouping: Trigger reactivity (agentNode change)
    Note over Grouping: Logic: Groups entries by responseId.<br/>Extracts trailing text as "conclusions".
    Grouping-->>Tree: Return TimelineSegments[]
    
    alt If Agent is Active (Streaming)
        Tree->>Tree: Render AgentTimeline (Flat view)
    else If Agent is Complete
        Tree->>Group: NEW: Render ResponseGroup (Collapsible)
        Group->>Group: NEW: Calculate summary<br/>(tool/message/question counts)
        Group->>MD: Render trailing text (conclusion)
    end

    Note over MD: Performance & Resource Management
    
    MD->>MD: CHANGED: enhanceResourceLinks()
    MD->>MD: NEW: Track link click handlers in WeakMap
    
    opt On Component Update / Unmount
        MD->>MD: NEW: cleanupLinkHandlers() (Prevents memory leaks)
    end

    Note over Tree,Group: Animation Control
    Group->>Group: NEW: AnimatedCollapsibleContent<br/>(Slide down/up animations)
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

onMounted(enhanceResourceLinks);
onUpdated(enhanceResourceLinks);
onUpdated(() => {
cleanupLinkHandlers();
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The new update cycle removes link click handlers but does not reattach them for already-enhanced links, which can break resource preview clicks after updates.

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/InstanceAiMarkdown.vue, line 216:

<comment>The new update cycle removes link click handlers but does not reattach them for already-enhanced links, which can break resource preview clicks after updates.</comment>

<file context>
@@ -193,8 +198,25 @@ function enhanceResourceLinks(): void {
 onMounted(enhanceResourceLinks);
-onUpdated(enhanceResourceLinks);
+onUpdated(() => {
+	cleanupLinkHandlers();
+	enhanceResourceLinks();
+});
</file context>
Fix with Cubic

.threadItem {
display: flex;
align-items: center;
height: 32px;
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Replace the hard-coded 32px height with a design-system token (for example var(--height--md)) to keep sizing consistent and themeable.

(Based on your team's feedback about using design-system tokens for visual values when a matching token exists.)

View Feedback: 1 2

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/InstanceAiThreadList.vue, line 245:

<comment>Replace the hard-coded `32px` height with a design-system token (for example `var(--height--md)`) to keep sizing consistent and themeable.

(Based on your team's feedback about using design-system tokens for visual values when a matching token exists.) </comment>

<file context>
@@ -242,6 +242,7 @@ function handleThreadAction(action: string, threadId: string) {
 .threadItem {
 	display: flex;
 	align-items: center;
+	height: 32px;
 	border-radius: var(--radius);
 	transition: background-color 0.1s ease;
</file context>
Suggested change
height: 32px;
height: var(--height--md);
Fix with Cubic

expandedIds.value.delete(id);
} else {
expandedIds.value.add(id);
const isExpanded = ref(!props.readOnly);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: isExpanded is not kept in sync with readOnly, so the panel can stay open after approval/resolution instead of collapsing with the new read-only state.

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/PlanReviewPanel.vue, line 45:

<comment>`isExpanded` is not kept in sync with `readOnly`, so the panel can stay open after approval/resolution instead of collapsing with the new read-only state.</comment>

<file context>
@@ -35,38 +37,23 @@ const emit = defineEmits<{
-		expandedIds.value.delete(id);
-	} else {
-		expandedIds.value.add(id);
+const isExpanded = ref(!props.readOnly);
+
+function getDescription(task: PlannedTaskArg): string {
</file context>
Fix with Cubic

.root {
border: var(--border);
border-radius: var(--radius--lg);
background-color: var(--color--background--light-3);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This change introduces a legacy background token (--color--background--light-3) in modified styles. Use the semantic token (--color-background-xlight) for new/updated code to align with design-system migration rules.

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/InstanceAiConfirmationPanel.vue, line 504:

<comment>This change introduces a legacy background token (`--color--background--light-3`) in modified styles. Use the semantic token (`--color-background-xlight`) for new/updated code to align with design-system migration rules.</comment>

<file context>
@@ -501,6 +501,7 @@ function isAllGenericApproval(items: PendingConfirmationItem[]): boolean {
 .root {
 	border: var(--border);
 	border-radius: var(--radius--lg);
+	background-color: var(--color--background--light-3);
 }
 
</file context>
Suggested change
background-color: var(--color--background--light-3);
background-color: var(--color-background-xlight);
Fix with Cubic

flex: 1;
overflow-y: auto;
padding: var(--spacing--4xs);
padding: var(--spacing--2xs);
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This token substitution changes thread list spacing (--spacing--4xs--spacing--2xs). Please confirm this is an intentional visual adjustment and not an accidental regression.

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/InstanceAiThreadList.vue, line 225:

<comment>This token substitution changes thread list spacing (`--spacing--4xs` → `--spacing--2xs`). Please confirm this is an intentional visual adjustment and not an accidental regression.</comment>

<file context>
@@ -222,7 +222,7 @@ function handleThreadAction(action: string, threadId: string) {
 	flex: 1;
 	overflow-y: auto;
-	padding: var(--spacing--4xs);
+	padding: var(--spacing--2xs);
 }
 
</file context>
Fix with Cubic

&:hover,
&.highlighted {
background-color: light-dark(var(--color--neutral-200), var(--color--neutral-800));
background-color: light-dark(var(--color--neutral-100), var(--color--neutral-800));
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This changes the hover background token from neutral-200 to neutral-100. Per the design-system style rules, token substitutions should be confirmed as intentional to avoid accidental visual regressions.

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/InstanceAiQuestions.vue, line 619:

<comment>This changes the hover background token from neutral-200 to neutral-100. Per the design-system style rules, token substitutions should be confirmed as intentional to avoid accidental visual regressions.</comment>

<file context>
@@ -619,7 +616,7 @@ function onOptionMouseEnter(idx: number) {
 	&:hover,
 	&.highlighted {
-		background-color: light-dark(var(--color--neutral-200), var(--color--neutral-800));
+		background-color: light-dark(var(--color--neutral-100), var(--color--neutral-800));
 	}
 
</file context>
Fix with Cubic

Merged via the queue into master with commit 316d5bd Apr 13, 2026
69 checks passed
@r00gm r00gm deleted the thinking-ui branch April 13, 2026 09:01
@n8n-assistant
Copy link
Copy Markdown
Contributor

n8n-assistant Bot commented Apr 14, 2026

Got released with n8n@

Aijeyomah pushed a commit to Aijeyomah/n8n that referenced this pull request Apr 15, 2026
…no-changelog) (n8n-io#28236)

Co-authored-by: Tuukka Kantola <tuukka@n8n.io>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

n8n team Authored by the n8n team Released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants