Compare commits

...

1 Commits

Author SHA1 Message Date
openhands
faa988084c Fix issue #5601: [Bug]: timing out causes the agent to stop 2024-12-31 21:09:21 +00:00
5 changed files with 49 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ from openhands.events.observation.files import (
from openhands.events.observation.observation import Observation
from openhands.events.observation.reject import UserRejectObservation
from openhands.events.observation.success import SuccessObservation
from openhands.events.observation.timeout import TimeoutObservation
__all__ = [
'Observation',
@@ -30,4 +31,5 @@ __all__ = [
'AgentDelegateObservation',
'SuccessObservation',
'UserRejectObservation',
'TimeoutObservation',
]

View File

@@ -0,0 +1,13 @@
from openhands.events.observation.observation import Observation
class TimeoutObservation(Observation):
"""Observation returned when an action times out but should not be treated as a fatal error."""
observation = 'timeout'
def __init__(self, message: str):
super().__init__(content=message)
def __str__(self) -> str:
return f'[Timeout] {self.content}'

View File

@@ -15,6 +15,7 @@ from openhands.events.observation.files import (
from openhands.events.observation.observation import Observation
from openhands.events.observation.reject import UserRejectObservation
from openhands.events.observation.success import SuccessObservation
from openhands.events.observation.timeout import TimeoutObservation
observations = (
NullObservation,
@@ -29,6 +30,7 @@ observations = (
ErrorObservation,
AgentStateChangedObservation,
UserRejectObservation,
TimeoutObservation,
)
OBSERVATION_TYPE_TO_CLASS = {

View File

@@ -28,6 +28,7 @@ from openhands.events.observation import (
ErrorObservation,
NullObservation,
Observation,
TimeoutObservation,
UserRejectObservation,
)
from openhands.events.serialization import event_to_dict, observation_from_dict
@@ -261,7 +262,7 @@ class ActionExecutionClient(Runtime):
obs = observation_from_dict(output)
obs._cause = action.id # type: ignore[attr-defined]
except requests.Timeout:
raise AgentRuntimeTimeoutError(
return TimeoutObservation(
f'Runtime failed to return execute_action before the requested timeout of {action.timeout}s'
)

View File

@@ -0,0 +1,30 @@
import pytest
from unittest.mock import Mock
from openhands.events.action import CmdRunAction
from openhands.events.observation import TimeoutObservation
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
from requests.exceptions import Timeout
def test_timeout_observation():
"""Test that a command timeout returns a TimeoutObservation."""
# Create a mock runtime
runtime = Mock(spec=ActionExecutionClient)
# Configure the mock to return a TimeoutObservation
runtime.send_action_for_execution.return_value = TimeoutObservation(
"Runtime failed to return execute_action before the requested timeout of 2s"
)
# Run a command that will timeout
action = CmdRunAction(command="sleep 10")
action.timeout = 2 # Set timeout after creation
obs = runtime.send_action_for_execution(action)
# Verify the result
assert isinstance(obs, TimeoutObservation)
assert "timeout" in str(obs).lower()
assert "2s" in str(obs)