@@ -2405,3 +2405,38 @@ async def stream_async(self, prompt=None, **kwargs):
24052405 assert result .completed_nodes == 2
24062406 assert "custom_node" in result .results
24072407 assert "regular_node" in result .results
2408+
2409+
2410+ def test_find_newly_ready_nodes_only_evaluates_outbound_edges ():
2411+ """Verify _find_newly_ready_nodes only checks destinations of outbound edges from completed batch.
2412+
2413+ Previously, it iterated over ALL nodes, which could cause nodes to fire
2414+ before their actual dependencies completed.
2415+
2416+ See: https://github.com/strands-agents/sdk-python/issues/685
2417+ """
2418+ # Build a graph: A -> B -> C, D -> E (independent chain)
2419+ node_a = GraphNode (node_id = "A" , executor = create_mock_agent ("A" ))
2420+ node_b = GraphNode (node_id = "B" , executor = create_mock_agent ("B" ))
2421+ node_c = GraphNode (node_id = "C" , executor = create_mock_agent ("C" ))
2422+ node_d = GraphNode (node_id = "D" , executor = create_mock_agent ("D" ))
2423+ node_e = GraphNode (node_id = "E" , executor = create_mock_agent ("E" ))
2424+
2425+ graph = Graph .__new__ (Graph )
2426+ graph .nodes = {"A" : node_a , "B" : node_b , "C" : node_c , "D" : node_d , "E" : node_e }
2427+ graph .edges = [
2428+ GraphEdge (from_node = node_a , to_node = node_b ),
2429+ GraphEdge (from_node = node_b , to_node = node_c ),
2430+ GraphEdge (from_node = node_d , to_node = node_e ),
2431+ ]
2432+ graph .state = GraphState ()
2433+
2434+ # When A completes, only B should be ready (not E)
2435+ ready = graph ._find_newly_ready_nodes ([node_a ])
2436+ ready_ids = {n .node_id for n in ready }
2437+ assert ready_ids == {"B" }, f"Expected only B, got { ready_ids } "
2438+
2439+ # When D completes, only E should be ready (not B or C)
2440+ ready = graph ._find_newly_ready_nodes ([node_d ])
2441+ ready_ids = {n .node_id for n in ready }
2442+ assert ready_ids == {"E" }, f"Expected only E, got { ready_ids } "
0 commit comments