diff --git a/lib/crewai/src/crewai/utilities/agent_utils.py b/lib/crewai/src/crewai/utilities/agent_utils.py index 241bd6cd4..62326afc1 100644 --- a/lib/crewai/src/crewai/utilities/agent_utils.py +++ b/lib/crewai/src/crewai/utilities/agent_utils.py @@ -1592,11 +1592,11 @@ def execute_single_native_tool_call( color="green", ) - # Check result_as_answer is_result_as_answer = bool( original_tool and hasattr(original_tool, "result_as_answer") and original_tool.result_as_answer + and not error_event_emitted ) return NativeToolCallResult( diff --git a/lib/crewai/tests/utilities/test_agent_utils.py b/lib/crewai/tests/utilities/test_agent_utils.py index 42de64fe6..72b2ca340 100644 --- a/lib/crewai/tests/utilities/test_agent_utils.py +++ b/lib/crewai/tests/utilities/test_agent_utils.py @@ -17,6 +17,8 @@ from crewai.utilities.agent_utils import ( _format_messages_for_summary, _split_messages_into_chunks, convert_tools_to_openai_schema, + execute_single_native_tool_call, + NativeToolCallResult, parse_tool_call_args, summarize_messages, ) @@ -1033,3 +1035,46 @@ class TestParseToolCallArgs: _, error = parse_tool_call_args("{bad json}", "tool", "call_7") assert error is not None assert set(error.keys()) == {"call_id", "func_name", "result", "from_cache", "original_tool"} + + +class TestExecuteSingleNativeToolCall: + """Tests for execute_single_native_tool_call.""" + + def test_result_as_answer_false_on_tool_error(self) -> None: + """When a tool with result_as_answer=True raises, result_as_answer must be False. + + Regression test for https://github.com/crewAIInc/crewAI/issues/5156 + """ + from unittest.mock import MagicMock + + class FailingTool(BaseTool): + name: str = "failing_tool" + description: str = "A tool that always fails" + result_as_answer: bool = True + + def _run(self, **kwargs: Any) -> str: + raise RuntimeError("intentional failure") + + tool = FailingTool() + tool_call = MagicMock() + tool_call.id = "call_1" + tool_call.function.name = "failing_tool" + tool_call.function.arguments = "{}" + + result = execute_single_native_tool_call( + tool_call, + available_functions={"failing_tool": tool._run}, + original_tools=[tool], + structured_tools=None, + tools_handler=None, + agent=None, + task=None, + crew=None, + event_source=MagicMock(), + printer=None, + verbose=False, + ) + + assert isinstance(result, NativeToolCallResult) + assert result.result_as_answer is False + assert "Error executing tool" in result.result