Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page Refresh now restarts agent loop if status is STOPPED or ERROR #6829

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion openhands/runtime/impl/docker/docker_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ async def connect(self):
'error',
f'Container {self.container_name} not found.',
)
raise e
raise AgentRuntimeDisconnectedError from e
if self.runtime_container_image is None:
if self.base_container_image is None:
raise ValueError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ async def maybe_start_agent_loop(
config=self.config,
sio=self.sio,
user_id=user_id,
status_message_callback=self._status_message_callback,
)
self._local_agent_loops_by_sid[sid] = session
asyncio.create_task(session.initialize_agent(settings, initial_user_msg))
Expand Down Expand Up @@ -274,6 +275,11 @@ async def _close_session(self, sid: str):
await session.close()
logger.info(f'closed_session:{session.sid}')

async def _status_message_callback(self, sid: str, msg_type: str, id: str):
if msg_type == 'error' and id == 'STATUS$ERROR_RUNTIME_DISCONNECTED':
# If there is no runtime, stop the agent loop. We may need to delete the runtime in question...
asyncio.create_task(self._close_session(sid))

@classmethod
def get_instance(
cls,
Expand Down
4 changes: 0 additions & 4 deletions openhands/server/session/agent_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,6 @@ async def close(self):
if self.security_analyzer is not None:
await self.security_analyzer.close()

async def stop_agent_loop_for_error(self):
if self.controller is not None:
await self.controller.set_agent_state_to(AgentState.ERROR)

def _create_security_analyzer(self, security_analyzer: str | None):
"""Creates a SecurityAnalyzer instance that will be used to analyze the agent actions

Expand Down
9 changes: 8 additions & 1 deletion openhands/server/session/session.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
import time
from copy import deepcopy
from typing import Callable

import socketio

Expand Down Expand Up @@ -49,6 +50,7 @@ def __init__(
file_store: FileStore,
sio: socketio.AsyncServer | None,
user_id: str | None = None,
status_message_callback: Callable | None = None,
):
self.sid = sid
self.sio = sio
Expand All @@ -67,6 +69,7 @@ def __init__(
self.config = deepcopy(config)
self.loop = asyncio.get_event_loop()
self.user_id = user_id
self._status_message_callback = status_message_callback

async def close(self):
if self.sio:
Expand Down Expand Up @@ -242,7 +245,11 @@ async def send_error(self, message: str):
async def _send_status_message(self, msg_type: str, id: str, message: str):
"""Sends a status message to the client."""
if msg_type == 'error':
await self.agent_session.stop_agent_loop_for_error()
controller = self.agent_session.controller
if controller is not None:
await controller.set_agent_state_to(AgentState.ERROR)
if self._status_message_callback:
await self._status_message_callback(self.sid, msg_type, id)
await self.send(
{'status_update': True, 'type': msg_type, 'id': id, 'message': message}
)
Expand Down
Loading