@ -373,6 +373,9 @@ interface WorkflowStore {
// Switch dimming state
dimmedNodeIds : Set < string > ;
// Skip propagation state (optional empty inputs)
skippedNodeIds : Set < string > ;
// Switch dimming actions
recomputeDimmedNodes : ( ) = > void ;
@ -507,6 +510,9 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
// Switch dimming initial state
dimmedNodeIds : new Set < string > ( ) ,
// Skip propagation initial state
skippedNodeIds : new Set < string > ( ) ,
setEdgeStyle : ( style : EdgeStyle ) = > {
set ( { edgeStyle : style } ) ;
} ,
@ -999,7 +1005,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
const abortController = new AbortController ( ) ;
const isResuming = startFromNodeId === get ( ) . pausedAtNodeId ;
const skippedNodeIds = new Set < string > ( ) ;
set ( { isRunning : true , pausedAtNodeId : null , currentNodeIds : [ ] , _abortController : abortController } ) ;
set ( { isRunning : true , pausedAtNodeId : null , currentNodeIds : [ ] , skippedNodeIds : new Set ( ) , _abortController : abortController } ) ;
// Start logging session
await logger . startSession ( ) ;
@ -1081,6 +1087,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
( node . type === "prompt" && ! ( nodeData . prompt as string ) ? . trim ( ) ) ;
if ( isEmpty ) {
skippedNodeIds . add ( node . id ) ;
set ( { skippedNodeIds : new Set ( skippedNodeIds ) } ) ;
logger . info ( 'node.execution' , 'Node skipped (optional input empty)' , {
nodeId : node.id ,
nodeType : node.type ,
@ -1094,6 +1101,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
const hasSkippedSource = incomingEdgesForSkip . some ( ( e ) = > skippedNodeIds . has ( e . source ) ) ;
if ( hasSkippedSource ) {
skippedNodeIds . add ( node . id ) ;
set ( { skippedNodeIds : new Set ( skippedNodeIds ) } ) ;
if ( nodeData . status !== undefined ) {
get ( ) . updateNodeData ( node . id , { status : "skipped" } as Partial < WorkflowNodeData > ) ;
}
@ -1255,7 +1263,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
}
}
set ( { isRunning : false , currentNodeIds : [ ] , _abortController : null } ) ;
set ( { isRunning : false , currentNodeIds : [ ] , skippedNodeIds : new Set ( ) , _abortController : null } ) ;
saveLogSession ( ) ;
await logger . endSession ( ) ;
@ -1278,7 +1286,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
get ( ) . updateNodeData ( skippedId , { status : "idle" } as Partial < WorkflowNodeData > ) ;
}
}
set ( { isRunning : false , currentNodeIds : [ ] , _abortController : null } ) ;
set ( { isRunning : false , currentNodeIds : [ ] , skippedNodeIds : new Set ( ) , _abortController : null } ) ;
saveLogSession ( ) ;
await logger . endSession ( ) ;
@ -1291,7 +1299,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
if ( controller ) {
controller . abort ( "user-cancelled" ) ;
}
set ( { isRunning : false , currentNodeIds : [ ] , _abortController : null } ) ;
set ( { isRunning : false , currentNodeIds : [ ] , skippedNodeIds : new Set ( ) , _abortController : null } ) ;
} ,
setMaxConcurrentCalls : ( value : number ) = > {
@ -1826,6 +1834,8 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
viewedCommentNodeIds : new Set < string > ( ) ,
// Reset dimmed nodes
dimmedNodeIds : new Set < string > ( ) ,
// Reset skipped nodes
skippedNodeIds : new Set < string > ( ) ,
} ) ;
get ( ) . clearSnapshot ( ) ;
} ,