Skip to content

Conversation

@Sg312
Copy link
Contributor

@Sg312 Sg312 commented Jan 27, 2026

Summary

Adds run from block and run until block functionality to the executor

Type of Change

  • New feature

Testing

Tested with @icecrasher321

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)

@vercel
Copy link

vercel bot commented Jan 27, 2026

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

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Jan 28, 2026 8:48pm

Request Review

@icecrasher321 icecrasher321 self-requested a review January 27, 2026 22:12
@icecrasher321 icecrasher321 self-assigned this Jan 27, 2026
Copy link
Collaborator

@icecrasher321 icecrasher321 left a comment

Choose a reason for hiding this comment

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

Tested all edge cases

@Sg312 Sg312 merged commit 655fe4f into staging Jan 28, 2026
11 checks passed
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 28, 2026

Greptile Overview

Greptile Summary

Implemented run-from-block and run-until-block execution features that allow users to execute workflows starting from a specific block or stopping after a target block. The implementation includes comprehensive validation, snapshot management, and UI integration.

Key Changes:

  • Added computeExecutionSets() to calculate dirty blocks (blocks needing re-execution) and upstream blocks (blocks with cached outputs) using BFS graph traversal
  • Created new API endpoint /api/workflows/[id]/execute-from-block with SSE streaming support
  • Extended DAGExecutor with executeFromBlock() method that filters snapshots, removes non-dirty incoming edges, and initializes execution from the target block
  • Added stopAfterBlockId support in ExecutionEngine to halt execution after a specific block completes
  • Implemented snapshot storage per workflow in execution store for caching block outputs between runs
  • Added UI menu items and handlers for "Run from block" and "Run until block" with validation checks

Implementation Approach:
The feature reuses cached outputs from previous executions by filtering the execution snapshot to include only reachable upstream blocks. Non-dirty incoming edges are removed so convergent blocks don't wait for cached dependencies. Loop and parallel containers are handled by resolving to their sentinel-start nodes.

Validation:

  • Blocks inside loops/parallels cannot be run-from targets (only container blocks themselves)
  • All upstream dependencies must have been executed in the source snapshot
  • Comprehensive test suite with 1500+ lines covering linear flows, branching, convergence, loops, parallels, and edge cases

Confidence Score: 4/5

  • Safe to merge with minor fixes - well-tested feature with isolated issues
  • Strong implementation with comprehensive testing, but has 3 issues: type mismatch in executor.ts:144, missing upstream logs in run-from-block mode, and incomplete snapshot merging that doesn't preserve loop/parallel state
  • executor/execution/executor.ts (type annotation and log preservation), use-workflow-execution.ts (snapshot merging completeness)

Important Files Changed

Filename Overview
apps/sim/executor/utils/run-from-block.ts New utility module for run-from-block validation and execution set computation with comprehensive test coverage
apps/sim/executor/execution/executor.ts Added executeFromBlock method with snapshot filtering logic and dirty set tracking
apps/sim/executor/execution/engine.ts Added run-from-block initialization and stopAfterBlockId handling in execution engine
apps/sim/app/api/workflows/[id]/execute-from-block/route.ts New API route for run-from-block execution with SSE streaming support
apps/sim/lib/workflows/executor/execution-core.ts Added runFromBlock parameter support and conditional executor invocation
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts Added handleRunFromBlock and handleRunUntilBlock with snapshot merging and validation logic

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as Block Menu
    participant Hook as useWorkflowExecution
    participant Stream as useExecutionStream
    participant API as execute-from-block API
    participant Core as execution-core
    participant Executor as DAGExecutor
    participant Engine as ExecutionEngine
    participant Store as ExecutionStore

    User->>UI: Right-click block, select "Run from block"
    UI->>Hook: handleRunFromBlock(blockId)
    Hook->>Store: getLastExecutionSnapshot(workflowId)
    Store-->>Hook: Return snapshot
    
    alt No snapshot or dependencies not satisfied
        Hook-->>User: Show error notification
    else Valid snapshot
        Hook->>Stream: executeFromBlock(workflowId, startBlockId, snapshot)
        Stream->>API: POST /api/workflows/{id}/execute-from-block
        API->>API: Validate auth & request body
        API->>Core: executeWorkflowCore(runFromBlock options)
        Core->>Executor: executeFromBlock(workflowId, startBlockId, snapshot)
        
        Executor->>Executor: validateRunFromBlock()
        Executor->>Executor: computeExecutionSets()
        Note over Executor: Compute dirty set (blocks to re-execute)<br/>and upstream set (cached blocks)
        
        Executor->>Executor: Filter snapshot to reachable upstream
        Executor->>Executor: Remove incoming edges from non-dirty sources
        Executor->>Engine: run()
        
        Engine->>Engine: initializeQueue(startBlockId)
        loop Until no work remaining
            Engine->>Engine: executeNodeAsync(nodeId)
            alt Block in dirty set
                Engine->>Engine: Re-execute block
            else Block not in dirty set
                Engine->>Engine: Use cached output
            end
            Engine->>API: Send SSE events (block:started, block:completed)
            API->>Stream: Stream SSE events
            Stream->>Hook: Trigger callbacks
            Hook->>Store: Update execution state
            Hook->>UI: Update active blocks visualization
        end
        
        Engine-->>Executor: Return ExecutionResult
        Executor-->>Core: Return result
        Core->>API: Send execution:completed event
        API->>Stream: Stream final result
        Stream->>Hook: onExecutionCompleted
        Hook->>Store: setLastExecutionSnapshot() (merge with existing)
        Hook->>UI: Update UI state
        UI-->>User: Show execution complete
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps 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 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile


// Filter snapshot to include all blocks reachable from dirty blocks
// This preserves sibling branch outputs that dirty blocks may reference
const filteredBlockStates: Record<string, any> = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

type mismatch - filteredBlockStates is Record<string, any> but should match the type expected by blockStates field

Suggested change
const filteredBlockStates: Record<string, any> = {}
const filteredBlockStates: Record<string, BlockState> = {}
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/executor/execution/executor.ts
Line: 144:144

Comment:
type mismatch - `filteredBlockStates` is `Record<string, any>` but should match the type expected by `blockStates` field

```suggestion
    const filteredBlockStates: Record<string, BlockState> = {}
```

How can I resolve this? If you propose a fix, please make it concise.

isDeployedContext: this.contextExtensions.isDeployedContext,
blockStates: state.getBlockStates(),
blockLogs: snapshotState?.blockLogs ?? [],
blockLogs: overrides?.runFromBlockContext ? [] : (snapshotState?.blockLogs ?? []),
Copy link
Contributor

Choose a reason for hiding this comment

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

when runFromBlockContext exists, blockLogs are reset to empty array, but this discards upstream execution logs that may be needed for debugging and tracing

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/executor/execution/executor.ts
Line: 268:268

Comment:
when `runFromBlockContext` exists, `blockLogs` are reset to empty array, but this discards upstream execution logs that may be needed for debugging and tracing

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +1656 to +1661
const mergedBlockStates: Record<string, BlockState> = {
...effectiveSnapshot.blockStates,
}
for (const [bId, state] of accumulatedBlockStates) {
mergedBlockStates[bId] = state
}
Copy link
Contributor

Choose a reason for hiding this comment

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

merging logic doesn't preserve loop/parallel execution state from the snapshot - only blockStates are merged but loopExecutions and parallelExecutions from effectiveSnapshot should also be included in updatedSnapshot

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts
Line: 1656:1661

Comment:
merging logic doesn't preserve loop/parallel execution state from the snapshot - only `blockStates` are merged but `loopExecutions` and `parallelExecutions` from `effectiveSnapshot` should also be included in `updatedSnapshot`

How can I resolve this? If you propose a fix, please make it concise.

@waleedlatif1 waleedlatif1 deleted the feat/run-from-block-2 branch January 29, 2026 00:27
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.

3 participants