@@ -221,230 +221,6 @@ describe('AgentflowContext - deleteNode', () => {
221221 expect ( result . current . state . edges ) . toHaveLength ( 1 )
222222 expect ( result . current . state . edges [ 0 ] . id ) . toBe ( 'edge-3-4' )
223223 } )
224-
225- it ( 'should clean up connected input values when node is deleted' , ( ) => {
226- const initialFlow : FlowData = {
227- nodes : [
228- makeFlowNode ( 'agent_0' , {
229- data : {
230- id : 'agent_0' ,
231- name : 'agent' ,
232- label : 'Agent' ,
233- outputAnchors : [ { id : 'agent_0-output-0' , name : 'output' , label : 'Output' , type : 'Agent' } ]
234- }
235- } ) ,
236- makeFlowNode ( 'tool_0' , {
237- data : {
238- id : 'tool_0' ,
239- name : 'tool' ,
240- label : 'Tool' ,
241- inputs : [ { id : 'tool_0-input-agent-Agent' , name : 'agent' , label : 'Agent' , type : 'Agent' } ] ,
242- inputAnchors : [ { id : 'tool_0-input-agent-Agent' , name : 'agent' , label : 'Agent' , type : 'Agent' } ] ,
243- inputValues : {
244- agent : '{{agent_0.data.instance}}' ,
245- apiKey : 'sk-1234'
246- } ,
247- outputAnchors : [ ]
248- }
249- } )
250- ] ,
251- edges : [
252- makeEdge ( 'agent_0' , 'tool_0' , {
253- id : 'edge-agent-tool' ,
254- sourceHandle : 'agent_0-output-0' ,
255- targetHandle : 'tool_0-input-agent-Agent'
256- } )
257- ]
258- }
259-
260- const { result } = renderHook ( ( ) => useAgentflowContext ( ) , {
261- wrapper : createWrapper ( initialFlow )
262- } )
263-
264- // Delete agent_0
265- act ( ( ) => {
266- result . current . deleteNode ( 'agent_0' )
267- } )
268-
269- // tool_0 should still exist
270- expect ( result . current . state . nodes ) . toHaveLength ( 1 )
271- const tool = result . current . state . nodes . find ( ( n ) => n . id === 'tool_0' )
272- expect ( tool ) . toBeDefined ( )
273-
274- // The agent input should be cleared, but apiKey should be preserved
275- expect ( tool ?. data . inputValues ?. agent ) . toBe ( '' )
276- expect ( tool ?. data . inputValues ?. apiKey ) . toBe ( 'sk-1234' )
277-
278- // Edge should be removed
279- expect ( result . current . state . edges ) . toHaveLength ( 0 )
280- } )
281-
282- it ( 'should clean up list input values when node is deleted' , ( ) => {
283- const initialFlow : FlowData = {
284- nodes : [
285- makeFlowNode ( 'tool_0' , {
286- data : {
287- id : 'tool_0' ,
288- name : 'tool' ,
289- label : 'Tool 1' ,
290- outputAnchors : [ { id : 'tool_0-output-0' , name : 'output' , label : 'Output' , type : 'Tool' } ]
291- }
292- } ) ,
293- makeFlowNode ( 'tool_1' , {
294- data : {
295- id : 'tool_1' ,
296- name : 'tool' ,
297- label : 'Tool 2' ,
298- outputAnchors : [ { id : 'tool_1-output-0' , name : 'output' , label : 'Output' , type : 'Tool' } ]
299- }
300- } ) ,
301- makeFlowNode ( 'agent_0' , {
302- data : {
303- id : 'agent_0' ,
304- name : 'agent' ,
305- label : 'Agent' ,
306- inputs : [ { id : 'agent_0-input-tools-Tool' , name : 'tools' , label : 'Tools' , type : 'Tool' } ] ,
307- inputAnchors : [ { id : 'agent_0-input-tools-Tool' , name : 'tools' , label : 'Tools' , type : 'Tool' , list : true } as any ] ,
308- inputValues : {
309- tools : [ '{{tool_0.data.instance}}' , '{{tool_1.data.instance}}' ]
310- } ,
311- outputAnchors : [ ]
312- }
313- } )
314- ] ,
315- edges : [
316- makeEdge ( 'tool_0' , 'agent_0' , {
317- id : 'edge-tool0-agent' ,
318- sourceHandle : 'tool_0-output-0' ,
319- targetHandle : 'agent_0-input-tools-Tool'
320- } ) ,
321- makeEdge ( 'tool_1' , 'agent_0' , {
322- id : 'edge-tool1-agent' ,
323- sourceHandle : 'tool_1-output-0' ,
324- targetHandle : 'agent_0-input-tools-Tool'
325- } )
326- ]
327- }
328-
329- const { result } = renderHook ( ( ) => useAgentflowContext ( ) , {
330- wrapper : createWrapper ( initialFlow )
331- } )
332-
333- // Delete tool_0
334- act ( ( ) => {
335- result . current . deleteNode ( 'tool_0' )
336- } )
337-
338- // agent_0 should still exist with tool_1 reference
339- expect ( result . current . state . nodes ) . toHaveLength ( 2 )
340- const agent = result . current . state . nodes . find ( ( n ) => n . id === 'agent_0' )
341- expect ( agent ) . toBeDefined ( )
342-
343- // The tools list should only contain tool_1
344- expect ( agent ?. data . inputValues ?. tools ) . toEqual ( [ '{{tool_1.data.instance}}' ] )
345-
346- // Only one edge should remain
347- expect ( result . current . state . edges ) . toHaveLength ( 1 )
348- expect ( result . current . state . edges [ 0 ] . id ) . toBe ( 'edge-tool1-agent' )
349- } )
350-
351- it ( 'should delete parent node and all descendant nodes' , ( ) => {
352- const initialFlow : FlowData = {
353- nodes : [
354- makeFlowNode ( 'parent' , {
355- data : { id : 'parent' , name : 'stickyNote' , label : 'Parent' , outputAnchors : [ ] }
356- } ) ,
357- makeFlowNode ( 'child-1' , {
358- parentNode : 'parent' ,
359- data : { id : 'child-1' , name : 'agent' , label : 'Child 1' , outputAnchors : [ ] }
360- } ) ,
361- makeFlowNode ( 'child-2' , {
362- parentNode : 'parent' ,
363- data : { id : 'child-2' , name : 'tool' , label : 'Child 2' , outputAnchors : [ ] }
364- } ) ,
365- makeFlowNode ( 'grandchild' , {
366- parentNode : 'child-1' ,
367- data : { id : 'grandchild' , name : 'agent' , label : 'Grandchild' , outputAnchors : [ ] }
368- } ) ,
369- makeFlowNode ( 'unrelated' , {
370- data : { id : 'unrelated' , name : 'agent' , label : 'Unrelated' , outputAnchors : [ ] }
371- } )
372- ] ,
373- edges : [ ]
374- }
375-
376- const { result } = renderHook ( ( ) => useAgentflowContext ( ) , {
377- wrapper : createWrapper ( initialFlow )
378- } )
379-
380- // Delete parent node
381- act ( ( ) => {
382- result . current . deleteNode ( 'parent' )
383- } )
384-
385- // Should only have the unrelated node left
386- expect ( result . current . state . nodes ) . toHaveLength ( 1 )
387- expect ( result . current . state . nodes [ 0 ] . id ) . toBe ( 'unrelated' )
388- } )
389-
390- it ( 'should clean up inputs for all descendant nodes before deletion' , ( ) => {
391- const initialFlow : FlowData = {
392- nodes : [
393- makeFlowNode ( 'parent' , {
394- data : { id : 'parent' , name : 'stickyNote' , label : 'Parent' , outputAnchors : [ ] }
395- } ) ,
396- makeFlowNode ( 'child' , {
397- parentNode : 'parent' ,
398- data : {
399- id : 'child' ,
400- name : 'agent' ,
401- label : 'Child' ,
402- outputAnchors : [ { id : 'child-output-0' , name : 'output' , label : 'Output' , type : 'Agent' } ]
403- }
404- } ) ,
405- makeFlowNode ( 'target' , {
406- data : {
407- id : 'target' ,
408- name : 'tool' ,
409- label : 'Target' ,
410- inputs : [ { id : 'target-input-agent-Agent' , name : 'agent' , label : 'Agent' , type : 'Agent' } ] ,
411- inputAnchors : [ { id : 'target-input-agent-Agent' , name : 'agent' , label : 'Agent' , type : 'Agent' } ] ,
412- inputValues : {
413- agent : '{{child.data.instance}}'
414- } ,
415- outputAnchors : [ ]
416- }
417- } )
418- ] ,
419- edges : [
420- makeEdge ( 'child' , 'target' , {
421- id : 'edge-child-target' ,
422- sourceHandle : 'child-output-0' ,
423- targetHandle : 'target-input-agent-Agent'
424- } )
425- ]
426- }
427-
428- const { result } = renderHook ( ( ) => useAgentflowContext ( ) , {
429- wrapper : createWrapper ( initialFlow )
430- } )
431-
432- // Delete parent (which should also delete child)
433- act ( ( ) => {
434- result . current . deleteNode ( 'parent' )
435- } )
436-
437- // Should only have target node left
438- expect ( result . current . state . nodes ) . toHaveLength ( 1 )
439- const target = result . current . state . nodes [ 0 ]
440- expect ( target . id ) . toBe ( 'target' )
441-
442- // The agent input should be cleared
443- expect ( target . data . inputValues ?. agent ) . toBe ( '' )
444-
445- // Edge should be removed
446- expect ( result . current . state . edges ) . toHaveLength ( 0 )
447- } )
448224} )
449225
450226describe ( 'AgentflowContext - duplicateNode' , ( ) => {
0 commit comments