From 27623a1d013fc4c74ed6e831cbbd8c02e6d910b7 Mon Sep 17 00:00:00 2001 From: Lucas Gomide Date: Mon, 21 Jul 2025 23:08:07 -0300 Subject: [PATCH] feat: remove duplicate print on LLM call error (#3183) By improving litellm handler error / outputs Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com> --- src/crewai/agents/crew_agent_executor.py | 7 ++----- src/crewai/llm.py | 6 ++---- src/crewai/utilities/agent_utils.py | 11 ++++++----- tests/agent_test.py | 9 --------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/crewai/agents/crew_agent_executor.py b/src/crewai/agents/crew_agent_executor.py index 37fee24e2..858a4bf09 100644 --- a/src/crewai/agents/crew_agent_executor.py +++ b/src/crewai/agents/crew_agent_executor.py @@ -120,11 +120,8 @@ class CrewAgentExecutor(CrewAgentExecutorMixin): raise except Exception as e: handle_unknown_error(self._printer, e) - if e.__class__.__module__.startswith("litellm"): - # Do not retry on litellm errors - raise e - else: - raise e + raise + if self.ask_for_human_input: formatted_answer = self._handle_human_feedback(formatted_answer) diff --git a/src/crewai/llm.py b/src/crewai/llm.py index 4113a6c62..42c56f6e7 100644 --- a/src/crewai/llm.py +++ b/src/crewai/llm.py @@ -59,6 +59,7 @@ from crewai.utilities.exceptions.context_window_exceeding_exception import ( load_dotenv() +litellm.suppress_debug_info = True class FilteredStream(io.TextIOBase): _lock = None @@ -76,9 +77,7 @@ class FilteredStream(io.TextIOBase): # Skip common noisy LiteLLM banners and any other lines that contain "litellm" if ( - "give feedback / get help" in lower_s - or "litellm.info:" in lower_s - or "litellm" in lower_s + "litellm.info:" in lower_s or "Consider using a smaller input or implementing a text splitting strategy" in lower_s ): return 0 @@ -1005,7 +1004,6 @@ class LLM(BaseLLM): self, event=LLMCallFailedEvent(error=str(e), from_task=from_task, from_agent=from_agent), ) - logging.error(f"LiteLLM call failed: {str(e)}") raise def _handle_emit_call_events(self, response: Any, call_type: LLMCallType, from_task: Optional[Any] = None, from_agent: Optional[Any] = None, messages: str | list[dict[str, Any]] | None = None): diff --git a/src/crewai/utilities/agent_utils.py b/src/crewai/utilities/agent_utils.py index 6e18b2d7c..40fa5ea07 100644 --- a/src/crewai/utilities/agent_utils.py +++ b/src/crewai/utilities/agent_utils.py @@ -157,10 +157,6 @@ def get_llm_response( from_agent=from_agent, ) except Exception as e: - printer.print( - content=f"Error during LLM call: {e}", - color="red", - ) raise e if not answer: printer.print( @@ -232,12 +228,17 @@ def handle_unknown_error(printer: Any, exception: Exception) -> None: printer: Printer instance for output exception: The exception that occurred """ + error_message = str(exception) + + if "litellm" in error_message: + return + printer.print( content="An unknown error occurred. Please check the details below.", color="red", ) printer.print( - content=f"Error details: {exception}", + content=f"Error details: {error_message}", color="red", ) diff --git a/tests/agent_test.py b/tests/agent_test.py index e460a94e7..bc9eed6bc 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -2010,7 +2010,6 @@ def test_crew_agent_executor_litellm_auth_error(): from litellm.exceptions import AuthenticationError from crewai.agents.tools_handler import ToolsHandler - from crewai.utilities import Printer # Create an agent and executor agent = Agent( @@ -2043,7 +2042,6 @@ def test_crew_agent_executor_litellm_auth_error(): # Mock the LLM call to raise AuthenticationError with ( patch.object(LLM, "call") as mock_llm_call, - patch.object(Printer, "print") as mock_printer, pytest.raises(AuthenticationError) as exc_info, ): mock_llm_call.side_effect = AuthenticationError( @@ -2057,13 +2055,6 @@ def test_crew_agent_executor_litellm_auth_error(): } ) - # Verify error handling messages - error_message = f"Error during LLM call: {str(mock_llm_call.side_effect)}" - mock_printer.assert_any_call( - content=error_message, - color="red", - ) - # Verify the call was only made once (no retries) mock_llm_call.assert_called_once()