diff --git a/openhands/controller/agent_controller.py b/openhands/controller/agent_controller.py index 21065f5e92..8078855330 100644 --- a/openhands/controller/agent_controller.py +++ b/openhands/controller/agent_controller.py @@ -5,7 +5,7 @@ import traceback from typing import Callable, ClassVar, Type import litellm -from litellm.exceptions import ContextWindowExceededError +from litellm.exceptions import BadRequestError, ContextWindowExceededError from openhands.controller.agent import Agent from openhands.controller.state.state import State, TrafficControlState @@ -509,15 +509,24 @@ class AgentController: EventSource.AGENT, ) return - except ContextWindowExceededError: - # When context window is exceeded, keep roughly half of agent interactions - self.state.history = self._apply_conversation_window(self.state.history) + except (ContextWindowExceededError, BadRequestError) as e: + # FIXME: this is a hack until a litellm fix is confirmed + # Check if this is a nested context window error + error_str = str(e).lower() + if ( + 'contextwindowexceedederror' in error_str + or 'prompt is too long' in error_str + or isinstance(e, ContextWindowExceededError) + ): + # When context window is exceeded, keep roughly half of agent interactions + self.state.history = self._apply_conversation_window(self.state.history) - # Save the ID of the first event in our truncated history for future reloading - if self.state.history: - self.state.start_id = self.state.history[0].id - # Don't add error event - let the agent retry with reduced context - return + # Save the ID of the first event in our truncated history for future reloading + if self.state.history: + self.state.start_id = self.state.history[0].id + # Don't add error event - let the agent retry with reduced context + return + raise if action.runnable: if self.state.confirmation_mode and (