File tree Expand file tree Collapse file tree 2 files changed +56
-2
lines changed
apps/sim/lib/copilot/tools/server/workflow/edit-workflow Expand file tree Collapse file tree 2 files changed +56
-2
lines changed Original file line number Diff line number Diff line change @@ -408,4 +408,42 @@ describe('handleEditOperation nestedNodes merge', () => {
408408 const helperBlock = Object . values ( state . blocks ) . find ( ( block : any ) => block . name === 'Helper' )
409409 expect ( helperBlock ) . toBeDefined ( )
410410 } )
411+
412+ it ( 'removes an unmatched nested container with all descendants and edges' , ( ) => {
413+ const workflow = makeNestedLoopWorkflow ( )
414+
415+ const { state } = applyOperationsToWorkflowState ( workflow , [
416+ {
417+ operation_type : 'edit' ,
418+ block_id : 'outer-loop' ,
419+ params : {
420+ nestedNodes : {
421+ replacement : {
422+ type : 'function' ,
423+ name : 'Replacement' ,
424+ inputs : { code : 'return 2' } ,
425+ } ,
426+ } ,
427+ } ,
428+ } ,
429+ ] )
430+
431+ expect ( state . blocks [ 'inner-loop' ] ) . toBeUndefined ( )
432+ expect ( state . blocks [ 'inner-agent' ] ) . toBeUndefined ( )
433+ expect (
434+ state . edges . some (
435+ ( edge : any ) =>
436+ edge . source === 'inner-loop' ||
437+ edge . target === 'inner-loop' ||
438+ edge . source === 'inner-agent' ||
439+ edge . target === 'inner-agent'
440+ )
441+ ) . toBe ( false )
442+
443+ const replacementBlock = Object . values ( state . blocks ) . find (
444+ ( block : any ) => block . name === 'Replacement'
445+ ) as any
446+ expect ( replacementBlock ) . toBeDefined ( )
447+ expect ( replacementBlock . data ?. parentId ) . toBe ( 'outer-loop' )
448+ } )
411449} )
Original file line number Diff line number Diff line change @@ -297,11 +297,27 @@ function mergeNestedNodesForParent(
297297 }
298298 } )
299299
300+ const collectBlockAndDescendants = (
301+ rootId : string ,
302+ collected = new Set < string > ( )
303+ ) : Set < string > => {
304+ collected . add ( rootId )
305+ Object . entries ( modifiedState . blocks ) . forEach ( ( [ childId , block ] : [ string , any ] ) => {
306+ if ( block . data ?. parentId === rootId && ! collected . has ( childId ) ) {
307+ collectBlockAndDescendants ( childId , collected )
308+ }
309+ } )
310+ return collected
311+ }
312+
300313 const removedIds = new Set < string > ( )
301314 for ( const [ existingId ] of existingChildren ) {
302315 if ( ! matchedExistingIds . has ( existingId ) ) {
303- delete modifiedState . blocks [ existingId ]
304- removedIds . add ( existingId )
316+ const subtreeIds = collectBlockAndDescendants ( existingId )
317+ subtreeIds . forEach ( ( id ) => {
318+ delete modifiedState . blocks [ id ]
319+ removedIds . add ( id )
320+ } )
305321 }
306322 }
307323
You can’t perform that action at this time.
0 commit comments