diff --git a/src/strands/multiagent/base.py b/src/strands/multiagent/base.py index dc3258f68..9c99be54a 100644 --- a/src/strands/multiagent/base.py +++ b/src/strands/multiagent/base.py @@ -161,6 +161,23 @@ def from_dict(cls, data: dict[str, Any]) -> "MultiAgentResult": ) return multiagent_result + def __str__(self) -> str: + """Get the combined output from all agent results as a string. + + This method extracts and concatenates text content from all node results, + providing a convenient way to access the multi-agent output via str(). + + Returns: + The combined text output from all agent results. + """ + parts = [] + for node_result in self.results.values(): + for agent_result in node_result.get_agent_results(): + text = str(agent_result) + if text: + parts.append(text) + return "\n".join(parts) + def to_dict(self) -> dict[str, Any]: """Convert MultiAgentResult to JSON-serializable dict.""" return { diff --git a/tests/strands/multiagent/test_base.py b/tests/strands/multiagent/test_base.py index 4e8a5dd06..1a9592c7f 100644 --- a/tests/strands/multiagent/test_base.py +++ b/tests/strands/multiagent/test_base.py @@ -239,3 +239,79 @@ def test_serialize_node_result_for_persist(agent_result): assert "result" in serialized_exception assert serialized_exception["result"]["type"] == "exception" assert serialized_exception["result"]["message"] == "Test error" + + +def test_multi_agent_result_str_single_node(): + """Test MultiAgentResult __str__ with a single node result.""" + agent_result = AgentResult( + message={"role": "assistant", "content": [{"text": "Hello from agent"}]}, + stop_reason="end_turn", + state={}, + metrics={}, + ) + node_result = NodeResult(result=agent_result, status=Status.COMPLETED) + multi_result = MultiAgentResult(status=Status.COMPLETED, results={"node1": node_result}) + + assert str(multi_result) == "Hello from agent\n" + + +def test_multi_agent_result_str_multiple_nodes(): + """Test MultiAgentResult __str__ with multiple node results.""" + agent_result1 = AgentResult( + message={"role": "assistant", "content": [{"text": "Response 1"}]}, + stop_reason="end_turn", + state={}, + metrics={}, + ) + agent_result2 = AgentResult( + message={"role": "assistant", "content": [{"text": "Response 2"}]}, + stop_reason="end_turn", + state={}, + metrics={}, + ) + node1 = NodeResult(result=agent_result1, status=Status.COMPLETED) + node2 = NodeResult(result=agent_result2, status=Status.COMPLETED) + multi_result = MultiAgentResult(status=Status.COMPLETED, results={"node1": node1, "node2": node2}) + + result_str = str(multi_result) + assert "Response 1" in result_str + assert "Response 2" in result_str + + +def test_multi_agent_result_str_empty(): + """Test MultiAgentResult __str__ with no results.""" + multi_result = MultiAgentResult(status=Status.COMPLETED, results={}) + assert str(multi_result) == "" + + +def test_multi_agent_result_str_with_exception_node(): + """Test MultiAgentResult __str__ skips exception nodes.""" + agent_result = AgentResult( + message={"role": "assistant", "content": [{"text": "Good response"}]}, + stop_reason="end_turn", + state={}, + metrics={}, + ) + node_ok = NodeResult(result=agent_result, status=Status.COMPLETED) + node_fail = NodeResult(result=Exception("Something failed"), status=Status.FAILED) + multi_result = MultiAgentResult(status=Status.COMPLETED, results={"ok": node_ok, "fail": node_fail}) + + result_str = str(multi_result) + assert "Good response" in result_str + assert "Something failed" not in result_str + + +def test_multi_agent_result_str_nested(): + """Test MultiAgentResult __str__ with nested MultiAgentResult.""" + inner_agent = AgentResult( + message={"role": "assistant", "content": [{"text": "Nested response"}]}, + stop_reason="end_turn", + state={}, + metrics={}, + ) + inner_node = NodeResult(result=inner_agent, status=Status.COMPLETED) + inner_multi = MultiAgentResult(status=Status.COMPLETED, results={"inner": inner_node}) + outer_node = NodeResult(result=inner_multi, status=Status.COMPLETED) + outer_multi = MultiAgentResult(status=Status.COMPLETED, results={"outer": outer_node}) + + assert "Nested response" in str(outer_multi)