diff --git a/src/strands/multiagent/graph.py b/src/strands/multiagent/graph.py index 966d2a0b3..58c63d8fa 100644 --- a/src/strands/multiagent/graph.py +++ b/src/strands/multiagent/graph.py @@ -188,7 +188,7 @@ def reset_executor_state(self) -> None: if hasattr(self.executor, "messages"): self.executor.messages = copy.deepcopy(self._initial_messages) - if hasattr(self.executor, "state"): + if hasattr(self.executor, "state") and hasattr(self.executor.state, "get"): self.executor.state = AgentState(self._initial_state.get()) # Reset execution status diff --git a/tests/strands/multiagent/test_graph.py b/tests/strands/multiagent/test_graph.py index 8158bf4b1..f1f79b3b3 100644 --- a/tests/strands/multiagent/test_graph.py +++ b/tests/strands/multiagent/test_graph.py @@ -2405,3 +2405,37 @@ async def stream_async(self, prompt=None, **kwargs): assert result.completed_nodes == 2 assert "custom_node" in result.results assert "regular_node" in result.results + + +@pytest.mark.asyncio +async def test_reset_executor_state_preserves_graph_state_for_nested_graph(): + """Verify reset_executor_state does not corrupt MultiAgentBase state. + + When a GraphNode wraps a MultiAgentBase executor (e.g. a nested Graph), + reset_executor_state() must not overwrite GraphState with AgentState. + Regression test for #1775. + """ + inner_agent = create_mock_agent("inner", "inner response") + inner_builder = GraphBuilder() + inner_builder.add_node(inner_agent, "inner_node") + inner_builder.set_entry_point("inner_node") + inner_graph = inner_builder.build() + + # inner_graph.state is a GraphState, not AgentState + assert isinstance(inner_graph.state, GraphState) + + node = GraphNode(node_id="nested", executor=inner_graph) + + # Simulate a completed execution + node.execution_status = Status.COMPLETED + node.result = NodeResult(result=MagicMock(), status=Status.COMPLETED) + + # Reset should NOT corrupt the nested graph's state + node.reset_executor_state() + + # After reset, the executor's state must still be GraphState + assert isinstance(inner_graph.state, GraphState), ( + "reset_executor_state overwrote GraphState with AgentState" + ) + assert node.execution_status == Status.PENDING + assert node.result is None