Skip to content

improvement(execution): multiple response blocks#3918

Open
icecrasher321 wants to merge 2 commits intostagingfrom
feat/multi-resp-blocks
Open

improvement(execution): multiple response blocks#3918
icecrasher321 wants to merge 2 commits intostagingfrom
feat/multi-resp-blocks

Conversation

@icecrasher321
Copy link
Copy Markdown
Collaborator

Summary

  • Remove singleInstance limitation
  • Add to docs note on non-deterministic behaviour if response block in parallel with side-effect
  • First response block wins policy like code

Type of Change

  • Other: UX Improvement

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 3, 2026

PR Summary

Medium Risk
Changes core execution-engine completion/error behavior so a Response block short-circuits workflow execution and suppresses later errors/outputs, which could affect API responses and side effects in parallel branches.

Overview
Response blocks now behave as workflow exit points with “first response wins”. The executor locks the first Response block’s output as the final API response, stops further scheduling/edge propagation, and prevents later isFinalOutput nodes (or parallel errors) from overwriting/throwing once a response is locked.

Multiple Response blocks are now supported. The Response block config drops the singleInstance restriction, adds best-practice guidance about parallel branch non-determinism, and docs/FAQ are updated to reflect multi-branch responses plus a warning to avoid placing Response in parallel with side-effecting work. Comprehensive engine tests are added to cover branching/parallel, overwrite-prevention, and error-after-response cases.

Reviewed by Cursor Bugbot for commit 33aa581. Configure here.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 3, 2026 10:42pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 3, 2026

Greptile Summary

This PR removes the single-instance constraint on the Response block and implements a "first response wins" policy for workflows that place Response blocks on multiple branches (e.g., after a Router or Condition). The execution engine gains a responseOutputLocked flag so the first Response block to complete claims finalOutput and signals stoppedEarlyFlag, causing all subsequent completions to be fast-pathed out with no state updates or edge propagation.

Key changes:

  • engine.ts: Added responseOutputLocked flag; Response block detection now uses node.block.metadata?.id === BlockType.RESPONSE; errors in parallel branches are suppressed when a Response block has already locked the output; nodes completing after the lock are no-op'd.
  • response.ts: Removed singleInstance constraint; updated bestPractices to describe the new multi-response semantics and non-determinism caveat for parallel branches.
  • engine.test.ts: New describe('Multiple Response blocks') suite covering router-driven routing, parallel-branch early exit, standard finalOutput fallback, duplicate-response no-overwrite, non-response terminal no-overwrite, and error-in-parallel-branch scenarios.
  • Docs: Updated to reflect exit-point semantics and added a warning callout about non-deterministic behavior when a Response block is on a parallel branch alongside side-effectful blocks.

Confidence Score: 5/5

Safe to merge — implementation is correct, well-tested, and documentation is updated to reflect the new semantics.

All identified findings are P2 or informational. The core logic (responseOutputLocked flag, first-wins policy, error suppression for locked state, fast-path no-op for late completions) is correct and covered by thorough tests. No regressions to existing paths are introduced.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/executor/execution/engine.ts Core execution engine updated with responseOutputLocked flag, first-response-wins locking, error suppression for locked output, and early-return fast-path for post-lock completions. Logic is correct and the changes are minimal and well-scoped.
apps/sim/executor/execution/engine.test.ts New test suite for multiple Response blocks covers all key scenarios: router-branch routing, parallel early-exit with downstream skip verification, lock non-overwrite (response vs response, response vs terminal), and error suppression when response is locked.
apps/sim/blocks/blocks/response.ts Removed singleInstance constraint and updated bestPractices text to reflect exit-point semantics and the non-determinism caveat for parallel branches.
apps/docs/content/docs/en/blocks/response.mdx Documentation accurately updated: single-instance FAQ answer replaced with multi-branch guidance, and a warning callout added for non-deterministic parallel-branch behavior.
apps/docs/content/docs/en/execution/basics.mdx Minor prose update — no functional concerns.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[run: processQueue loop] --> B{stoppedEarlyFlag or errorFlag?}
    B -- Yes --> C[waitForAllExecutions]
    B -- No --> D[dequeue & executeNodeAsync]
    D --> E[nodeOrchestrator.executeNode]
    E --> F[withQueueLock: handleNodeCompletion]
    F --> G{stoppedEarlyFlag && responseOutputLocked?}
    G -- Yes --> H[early return — no-op]
    G -- No --> I{isPauseMetadata?}
    I -- Yes --> J[register pause, return]
    I -- No --> K[nodeOrchestrator.handleNodeCompletion]
    K --> L{isResponseBlock?}
    L -- Yes --> M{responseOutputLocked?}
    M -- No --> N[lock finalOutput, set responseOutputLocked=true]
    N --> O[set stoppedEarlyFlag=true, return]
    M -- Yes --> O
    L -- No --> P{isFinalOutput && !responseOutputLocked?}
    P -- Yes --> Q[set finalOutput]
    P -- No --> R[processOutgoingEdges, addMultipleToQueue]
    Q --> R
    C --> S{errorFlag && !responseOutputLocked?}
    S -- Yes --> T[throw error]
    S -- No --> U[return success result with locked finalOutput]
Loading

Reviews (2): Last reviewed commit: "address comments" | Re-trigger Greptile

@icecrasher321
Copy link
Copy Markdown
Collaborator Author

bugbot run

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 33aa581. Configure here.

@waleedlatif1 waleedlatif1 deleted the branch staging April 3, 2026 23:01
@waleedlatif1 waleedlatif1 reopened this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants