Fix history loading when state was corrupt/non-existent (#5946)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Engel Nyst 2024-12-31 22:46:35 +01:00 committed by GitHub
parent d29cc61aa2
commit 40d8245089
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 5 deletions

View File

@ -730,12 +730,20 @@ class AgentController:
# - the previous session, in which case it has history
# - from a parent agent, in which case it has no history
# - None / a new state
# If state is None, we create a brand new state and still load the event stream so we can restore the history
if state is None:
self.state = State(
inputs={},
max_iterations=max_iterations,
confirmation_mode=confirmation_mode,
)
self.state.start_id = 0
self.log(
'debug',
f'AgentController {self.id} - created new state. start_id: {self.state.start_id}',
)
else:
self.state = state
@ -747,7 +755,8 @@ class AgentController:
f'AgentController {self.id} initializing history from event {self.state.start_id}',
)
self._init_history()
# Always load from the event stream to avoid losing history
self._init_history()
def _init_history(self) -> None:
"""Initializes the agent's history from the event stream.

View File

@ -269,11 +269,26 @@ class AgentSession:
headless_mode=False,
status_callback=self._status_callback,
)
# Note: We now attempt to restore the state from session here,
# but if it fails, we fall back to None and still initialize the controller
# with a fresh state. That way, the controller will always load events from the event stream
# even if the state file was corrupt.
restored_state = None
try:
agent_state = State.restore_from_session(self.sid, self.file_store)
controller.set_initial_state(agent_state, max_iterations, confirmation_mode)
logger.debug(f'Restored agent state from session, sid: {self.sid}')
restored_state = State.restore_from_session(self.sid, self.file_store)
except Exception as e:
logger.debug(f'State could not be restored: {e}')
if self.event_stream.get_latest_event_id() > 0:
# if we have events, we should have a state
logger.warning(f'State could not be restored: {e}')
# Set the initial state through the controller.
controller.set_initial_state(restored_state, max_iterations, confirmation_mode)
if restored_state:
logger.debug(f'Restored agent state from session, sid: {self.sid}')
else:
logger.debug('New session state created.')
logger.debug('Agent controller initialized.')
return controller

View File

@ -13,6 +13,8 @@ def mock_event_stream():
stream = MagicMock()
# Mock get_events to return an empty list by default
stream.get_events.return_value = []
# Mock get_latest_event_id to return a valid integer
stream.get_latest_event_id.return_value = 0
return stream