@@ -777,6 +777,75 @@ class AIAgentPipelineTest {
777777 assertContentEquals(expectedEvents, actualEvents)
778778 }
779779
780+ @Test
781+ fun `test AgentExecutionInfo path with loop nodes invocation` () = runTest {
782+ val interceptedEvents = mutableListOf<String >()
783+ val interceptedRunIds = mutableListOf<String >()
784+
785+ val agentId = " test-agent-id"
786+ val agentInput = " test input"
787+
788+ val strategyName = " test-strategy"
789+ val nodeRootName = " node-root"
790+ val nodeRootOutput = " Root node output"
791+ val nodeExecuteName = " node-execute"
792+ val nodeExecuteOutput = " Execute output"
793+
794+ var isExecuted = false
795+
796+ val strategy = strategy(strategyName) {
797+ val nodeRoot by node<String , String >(nodeRootName) { it }
798+ val nodeExecute by node<String , String >(nodeExecuteName) {
799+ isExecuted = true
800+ it
801+ }
802+
803+ edge(nodeStart forwardTo nodeRoot)
804+ edge(nodeRoot forwardTo nodeExecute onCondition { ! isExecuted })
805+ edge(nodeRoot forwardTo nodeFinish onCondition { isExecuted } transformed { nodeRootOutput })
806+ edge(nodeExecute forwardTo nodeRoot transformed { nodeExecuteOutput })
807+ }
808+
809+ createAgent(
810+ strategy = strategy,
811+ promptExecutor = getMockExecutor { }
812+ ) {
813+ install(TestFeature ) {
814+ events = interceptedEvents
815+ runIds = interceptedRunIds
816+ }
817+ }.use { agent ->
818+ agent.run (agentInput)
819+ }
820+
821+ val actualEvents = interceptedEvents.filter { collectedEvent ->
822+ collectedEvent.startsWith(NodeExecutionStarting ::class .simpleName.toString()) ||
823+ collectedEvent.startsWith(NodeExecutionCompleted ::class .simpleName.toString()) ||
824+ collectedEvent.startsWith(NodeExecutionFailed ::class .simpleName.toString())
825+ }
826+
827+ val expectedEvents = listOf (
828+ " ${NodeExecutionStarting ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, START_NODE_PREFIX )} , name: $START_NODE_PREFIX , input: $agentInput )" ,
829+ " ${NodeExecutionCompleted ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, START_NODE_PREFIX )} , name: $START_NODE_PREFIX , input: $agentInput , output: $agentInput )" ,
830+ " ${NodeExecutionStarting ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeRootName)} , name: $nodeRootName , input: $agentInput )" ,
831+ " ${NodeExecutionCompleted ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeRootName)} , name: $nodeRootName , input: $agentInput , output: $agentInput )" ,
832+ " ${NodeExecutionStarting ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeExecuteName)} , name: $nodeExecuteName , input: $agentInput )" ,
833+ " ${NodeExecutionCompleted ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeExecuteName)} , name: $nodeExecuteName , input: $agentInput , output: $agentInput )" ,
834+ " ${NodeExecutionStarting ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeRootName)} , name: $nodeRootName , input: $nodeExecuteOutput )" ,
835+ " ${NodeExecutionCompleted ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, nodeRootName)} , name: $nodeRootName , input: $nodeExecuteOutput , output: $nodeExecuteOutput )" ,
836+ " ${NodeExecutionStarting ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, FINISH_NODE_PREFIX )} , name: $FINISH_NODE_PREFIX , input: $nodeRootOutput )" ,
837+ " ${NodeExecutionCompleted ::class .simpleName} (path: ${agentExecutionPath(agentId, strategyName, FINISH_NODE_PREFIX )} , name: $FINISH_NODE_PREFIX , input: $nodeRootOutput , output: $nodeRootOutput )" ,
838+ )
839+
840+ assertEquals(
841+ expectedEvents.size,
842+ actualEvents.size,
843+ " Miss intercepted node events. Expected ${expectedEvents.size} , but received: ${actualEvents.size} "
844+ )
845+
846+ assertContentEquals(expectedEvents, actualEvents)
847+ }
848+
780849 // endregion Execution Info
781850
782851 // region Private Methods
0 commit comments