@@ -83,7 +83,6 @@ export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinitio
8383 }
8484 }
8585
86- const orderedIds = topoSort ( nodeIds , graph . edges ) ;
8786 const incomingEdges = new Map < string , Set < string > > ( ) ;
8887 type GraphEdge = ( typeof graph . edges ) [ number ] ;
8988 const edgesByTarget = new Map < string , GraphEdge [ ] > ( ) ;
@@ -136,7 +135,7 @@ export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinitio
136135 } ;
137136 }
138137
139- const actions : WorkflowAction [ ] = orderedIds . map ( ( id ) => {
138+ const preliminaryActions : WorkflowAction [ ] = nodeIds . map ( ( id ) => {
140139 const node = executableNodes . find ( ( n : WorkflowNodeDto ) => n . id === id ) ! ;
141140 const config = ( node . data ?. config ?? { } ) as Record < string , unknown > ;
142141 const {
@@ -229,6 +228,61 @@ export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinitio
229228 } ;
230229 } ) ;
231230
231+ const actionsByRef = new Map ( preliminaryActions . map ( ( action ) => [ action . ref , action ] ) ) ;
232+ const loopExtraction = extractLoopBodies (
233+ executableNodes ,
234+ graph . edges ,
235+ nodesMetadata ,
236+ actionsByRef ,
237+ ) ;
238+ const mainNodeIdSet = new Set ( loopExtraction . mainNodeIds ) ;
239+ const mainGraphEdges = loopExtraction . mainEdges ;
240+
241+ const orderedIds = topoSortWithoutLoopBackCycles (
242+ loopExtraction . mainNodeIds ,
243+ mainGraphEdges ,
244+ loopExtraction . loopBodies ,
245+ ) ;
246+
247+ const mainIncomingEdges = new Map < string , Set < string > > ( ) ;
248+ for ( const nodeId of loopExtraction . mainNodeIds ) {
249+ mainIncomingEdges . set ( nodeId , new Set ( ) ) ;
250+ }
251+ for ( const edge of mainGraphEdges ) {
252+ if ( mainNodeIdSet . has ( edge . source ) && mainNodeIdSet . has ( edge . target ) ) {
253+ mainIncomingEdges . get ( edge . target ) ?. add ( edge . source ) ;
254+ }
255+ }
256+
257+ const actions : WorkflowAction [ ] = orderedIds . map ( ( id ) => {
258+ const action = actionsByRef . get ( id ) ;
259+ if ( ! action ) {
260+ throw new Error ( `Compiled action missing for node '${ id } '.` ) ;
261+ }
262+
263+ const inputMappings : WorkflowAction [ 'inputMappings' ] = { } ;
264+ for ( const edge of edgesByTarget . get ( id ) ?? [ ] ) {
265+ if ( ! mainNodeIdSet . has ( edge . source ) ) {
266+ continue ;
267+ }
268+ const targetHandle = edge . targetHandle ?? edge . sourceHandle ;
269+ const sourceHandle = edge . sourceHandle ?? '__self__' ;
270+ if ( ! targetHandle ) {
271+ continue ;
272+ }
273+ inputMappings [ targetHandle ] = {
274+ sourceRef : edge . source ,
275+ sourceHandle,
276+ } ;
277+ }
278+
279+ return {
280+ ...action ,
281+ dependsOn : Array . from ( mainIncomingEdges . get ( id ) ?? [ ] ) ,
282+ inputMappings,
283+ } ;
284+ } ) ;
285+
232286 const entrypointAction = actions . find (
233287 ( action ) => action . componentId === 'core.workflow.entrypoint' ,
234288 ) ;
@@ -242,7 +296,7 @@ export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinitio
242296 dependencyCounts [ action . ref ] = action . dependsOn . length ;
243297 }
244298
245- const edges : WorkflowEdge [ ] = graph . edges . map ( ( edge ) => ( {
299+ const edges : WorkflowEdge [ ] = mainGraphEdges . map ( ( edge ) => ( {
246300 id : edge . id ,
247301 sourceRef : edge . source ,
248302 targetRef : edge . target ,
@@ -269,10 +323,13 @@ export function compileWorkflowGraph(graph: WorkflowGraphDto): WorkflowDefinitio
269323 title : graph . name ,
270324 description : graph . description ,
271325 entrypoint : { ref : entryNode } ,
272- nodes : nodesMetadata ,
326+ nodes : Object . fromEntries (
327+ Object . entries ( nodesMetadata ) . filter ( ( [ nodeId ] ) => mainNodeIdSet . has ( nodeId ) ) ,
328+ ) ,
273329 edges,
274330 dependencyCounts,
275331 actions,
332+ loopBodies : loopExtraction . loopBodies ,
276333 config : { environment : 'default' , timeoutSeconds : 0 } ,
277334 } ;
278335
0 commit comments