@@ -161,6 +161,7 @@ export interface ExecutionGroup {
161161 */
162162interface IterationGroup {
163163 iterationType : string
164+ iterationContainerId : string
164165 iterationCurrent : number
165166 iterationTotal ?: number
166167 blocks : ConsoleEntry [ ]
@@ -169,7 +170,7 @@ interface IterationGroup {
169170
170171/**
171172 * Builds a tree structure from flat entries.
172- * Groups iteration entries by (iterationType, iterationCurrent), showing all blocks
173+ * Groups iteration entries by (iterationType, iterationContainerId, iterationCurrent), showing all blocks
173174 * that executed within each iteration.
174175 * Sorts by start time to ensure chronological order.
175176 */
@@ -186,16 +187,18 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
186187 }
187188 }
188189
189- // Group iteration entries by (iterationType, iterationCurrent)
190+ // Group iteration entries by (iterationType, iterationContainerId, iterationCurrent)
190191 const iterationGroupsMap = new Map < string , IterationGroup > ( )
191192 for ( const entry of iterationEntries ) {
192- const key = `${ entry . iterationType } -${ entry . iterationCurrent } `
193+ const iterationContainerId = entry . iterationContainerId || 'unknown'
194+ const key = `${ entry . iterationType } -${ iterationContainerId } -${ entry . iterationCurrent } `
193195 let group = iterationGroupsMap . get ( key )
194196 const entryStartMs = new Date ( entry . startedAt || entry . timestamp ) . getTime ( )
195197
196198 if ( ! group ) {
197199 group = {
198200 iterationType : entry . iterationType ! ,
201+ iterationContainerId,
199202 iterationCurrent : entry . iterationCurrent ! ,
200203 iterationTotal : entry . iterationTotal ,
201204 blocks : [ ] ,
@@ -220,26 +223,34 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
220223 group . blocks . sort ( ( a , b ) => a . executionOrder - b . executionOrder )
221224 }
222225
223- // Group iterations by iterationType to create subflow parents
224- const subflowGroups = new Map < string , IterationGroup [ ] > ( )
226+ // Group iterations by (iterationType, iterationContainerId) to create subflow parents
227+ const subflowGroups = new Map <
228+ string ,
229+ { iterationType : string ; iterationContainerId : string ; groups : IterationGroup [ ] }
230+ > ( )
225231 for ( const group of iterationGroupsMap . values ( ) ) {
226- const type = group . iterationType
227- let groups = subflowGroups . get ( type )
228- if ( ! groups ) {
229- groups = [ ]
230- subflowGroups . set ( type , groups )
232+ const key = `${ group . iterationType } -${ group . iterationContainerId } `
233+ let subflowGroup = subflowGroups . get ( key )
234+ if ( ! subflowGroup ) {
235+ subflowGroup = {
236+ iterationType : group . iterationType ,
237+ iterationContainerId : group . iterationContainerId ,
238+ groups : [ ] ,
239+ }
240+ subflowGroups . set ( key , subflowGroup )
231241 }
232- groups . push ( group )
242+ subflowGroup . groups . push ( group )
233243 }
234244
235245 // Sort iterations within each subflow by iteration number
236- for ( const groups of subflowGroups . values ( ) ) {
237- groups . sort ( ( a , b ) => a . iterationCurrent - b . iterationCurrent )
246+ for ( const subflowGroup of subflowGroups . values ( ) ) {
247+ subflowGroup . groups . sort ( ( a , b ) => a . iterationCurrent - b . iterationCurrent )
238248 }
239249
240250 // Build subflow nodes with iteration children
241251 const subflowNodes : EntryNode [ ] = [ ]
242- for ( const [ iterationType , iterationGroups ] of subflowGroups . entries ( ) ) {
252+ for ( const subflowGroup of subflowGroups . values ( ) ) {
253+ const { iterationType, iterationContainerId, groups : iterationGroups } = subflowGroup
243254 // Calculate subflow timing from all its iterations
244255 const firstIteration = iterationGroups [ 0 ]
245256 const allBlocks = iterationGroups . flatMap ( ( g ) => g . blocks )
@@ -255,10 +266,10 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
255266 // Use the minimum executionOrder from all child blocks for proper ordering
256267 const subflowExecutionOrder = Math . min ( ...allBlocks . map ( ( b ) => b . executionOrder ) )
257268 const syntheticSubflow : ConsoleEntry = {
258- id : `subflow-${ iterationType } -${ firstIteration . blocks [ 0 ] ?. executionId || 'unknown' } ` ,
269+ id : `subflow-${ iterationType } -${ iterationContainerId } - ${ firstIteration . blocks [ 0 ] ?. executionId || 'unknown' } ` ,
259270 timestamp : new Date ( subflowStartMs ) . toISOString ( ) ,
260271 workflowId : firstIteration . blocks [ 0 ] ?. workflowId || '' ,
261- blockId : `${ iterationType } -container` ,
272+ blockId : `${ iterationType } -container- ${ iterationContainerId } ` ,
262273 blockName : iterationType . charAt ( 0 ) . toUpperCase ( ) + iterationType . slice ( 1 ) ,
263274 blockType : iterationType ,
264275 executionId : firstIteration . blocks [ 0 ] ?. executionId ,
@@ -284,10 +295,10 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
284295 // Use the minimum executionOrder from blocks in this iteration
285296 const iterExecutionOrder = Math . min ( ...iterBlocks . map ( ( b ) => b . executionOrder ) )
286297 const syntheticIteration : ConsoleEntry = {
287- id : `iteration-${ iterationType } -${ iterGroup . iterationCurrent } -${ iterBlocks [ 0 ] ?. executionId || 'unknown' } ` ,
298+ id : `iteration-${ iterationType } -${ iterGroup . iterationContainerId } - ${ iterGroup . iterationCurrent } -${ iterBlocks [ 0 ] ?. executionId || 'unknown' } ` ,
288299 timestamp : new Date ( iterStartMs ) . toISOString ( ) ,
289300 workflowId : iterBlocks [ 0 ] ?. workflowId || '' ,
290- blockId : `iteration-${ iterGroup . iterationCurrent } ` ,
301+ blockId : `iteration-${ iterGroup . iterationContainerId } - ${ iterGroup . iterationCurrent } ` ,
291302 blockName : `Iteration ${ iterGroup . iterationCurrent } ${ iterGroup . iterationTotal !== undefined ? ` / ${ iterGroup . iterationTotal } ` : '' } ` ,
292303 blockType : iterationType ,
293304 executionId : iterBlocks [ 0 ] ?. executionId ,
@@ -299,6 +310,7 @@ function buildEntryTree(entries: ConsoleEntry[]): EntryNode[] {
299310 iterationCurrent : iterGroup . iterationCurrent ,
300311 iterationTotal : iterGroup . iterationTotal ,
301312 iterationType : iterationType as 'loop' | 'parallel' ,
313+ iterationContainerId : iterGroup . iterationContainerId ,
302314 }
303315
304316 // Block nodes within this iteration
0 commit comments