@@ -331,6 +331,63 @@ describe('DAGExecutor run-from-block snapshot metadata', () => {
331331 } )
332332} )
333333
334+ describe ( 'DAGExecutor resume DAG construction' , ( ) => {
335+ it ( 'includes non-starter resume targets when a workflow has a disconnected starter' , async ( ) => {
336+ const workflow : SerializedWorkflow = {
337+ version : '1' ,
338+ blocks : [
339+ createBlock ( 'start-t2-v2' , BlockType . STARTER ) ,
340+ createBlock ( 'webhook-start' , 'generic_webhook' ) ,
341+ createBlock ( 'hitl' , BlockType . HUMAN_IN_THE_LOOP ) ,
342+ createBlock ( 'generate-report' , BlockType . FUNCTION ) ,
343+ ] ,
344+ connections : [
345+ { source : 'webhook-start' , target : 'hitl' , sourceHandle : 'source' } ,
346+ { source : 'hitl' , target : 'generate-report' , sourceHandle : 'source' } ,
347+ ] ,
348+ loops : { } ,
349+ parallels : { } ,
350+ }
351+ let capturedDag : ReturnType < DAGBuilder [ 'build' ] > | undefined
352+ const executor = new DAGExecutor ( {
353+ workflow,
354+ contextExtensions : {
355+ resumeFromSnapshot : true ,
356+ remainingEdges : [ { source : 'hitl' , target : 'generate-report' , sourceHandle : 'source' } ] ,
357+ dagIncomingEdges : { 'start-t2-v2' : [ ] } ,
358+ snapshotState : {
359+ blockStates : { } ,
360+ executedBlocks : [ 'webhook-start' , 'hitl' ] ,
361+ blockLogs : [ ] ,
362+ decisions : { router : { } , condition : { } } ,
363+ completedLoops : [ ] ,
364+ activeExecutionPath : [ ] ,
365+ } ,
366+ } ,
367+ } ) as unknown as DAGExecutor & {
368+ buildExecutionPipeline : (
369+ context : ExecutionContext ,
370+ dag : ReturnType < DAGBuilder [ 'build' ] >
371+ ) => { run : ( ) => Promise < ExecutionResult > }
372+ }
373+ executor . buildExecutionPipeline = vi . fn ( ( _context , dag ) => {
374+ capturedDag = dag
375+ return {
376+ run : async ( ) : Promise < ExecutionResult > => ( {
377+ success : true ,
378+ output : { ok : true } ,
379+ metadata : { } ,
380+ } ) ,
381+ }
382+ } )
383+
384+ await executor . execute ( 'wf' )
385+
386+ expect ( capturedDag ?. nodes . has ( 'generate-report' ) ) . toBe ( true )
387+ expect ( capturedDag ?. nodes . get ( 'generate-report' ) ?. incomingEdges . has ( 'hitl' ) ) . toBe ( true )
388+ } )
389+ } )
390+
334391describe ( 'DAGExecutor createExecutionContext useDraftState' , ( ) => {
335392 function buildMetadataUseDraftState ( opts : {
336393 metadataUseDraftState ?: boolean
0 commit comments