Quellcode durchsuchen

BrowserEnv: init exception handling (#2050)

* BrowserEnv: init exception handling

* Revert irrelevant changes

* Remove type ignore
Boxuan Li vor 1 Jahr
Ursprung
Commit
91f313c914

+ 13 - 0
opendevin/core/exceptions.py

@@ -58,6 +58,19 @@ class TaskInvalidStateError(Exception):
         super().__init__(message)
 
 
+class BrowserInitException(Exception):
+    def __init__(self, message='Failed to initialize browser environment'):
+        super().__init__(message)
+
+
+class BrowserUnavailableException(Exception):
+    def __init__(
+        self,
+        message='Browser environment is not available, please check if has been initialized',
+    ):
+        super().__init__(message)
+
+
 # These exceptions get sent back to the LLM
 class AgentMalformedActionError(Exception):
     def __init__(self, message='Malformed response'):

+ 4 - 6
opendevin/runtime/browser/browser_env.py

@@ -12,13 +12,10 @@ import numpy as np
 from browsergym.utils.obs import flatten_dom_to_str
 from PIL import Image
 
+from opendevin.core.exceptions import BrowserInitException
 from opendevin.core.logger import opendevin_logger as logger
 
 
-class BrowserException(Exception):
-    pass
-
-
 class BrowserEnv:
     def __init__(self):
         self.html_text_converter = html2text.HTML2Text()
@@ -38,7 +35,8 @@ class BrowserEnv:
         logger.info('Starting browser env...')
         self.process.start()
         if not self.check_alive():
-            raise BrowserException('Failed to start browser environment.')
+            self.close()
+            raise BrowserInitException('Failed to start browser environment.')
         atexit.register(self.close)
 
     def browser_process(self):
@@ -93,7 +91,7 @@ class BrowserEnv:
                 if response_id == unique_request_id:
                     return obs
 
-    def check_alive(self, timeout: float = 10):
+    def check_alive(self, timeout: float = 60):
         self.agent_side.send(('IS_ALIVE', None))
         if self.agent_side.poll(timeout=timeout):
             response_id, _ = self.agent_side.recv()

+ 11 - 2
opendevin/runtime/runtime.py

@@ -2,6 +2,8 @@ import asyncio
 from abc import abstractmethod
 
 from opendevin.core.config import config
+from opendevin.core.exceptions import BrowserInitException
+from opendevin.core.logger import opendevin_logger as logger
 from opendevin.events import EventSource, EventStream, EventStreamSubscriber
 from opendevin.events.action import (
     Action,
@@ -71,7 +73,13 @@ class Runtime:
         else:
             self.sandbox = sandbox
             self._is_external_sandbox = True
-        self.browser = BrowserEnv()
+        self.browser: BrowserEnv | None = None
+        try:
+            self.browser = BrowserEnv()
+        except BrowserInitException:
+            logger.warn(
+                'Failed to start browser environment, web browsing functionality will not work'
+            )
         self.file_store = InMemoryFileStore()
         self.event_stream = event_stream
         self.event_stream.subscribe(EventStreamSubscriber.RUNTIME, self.on_event)
@@ -80,7 +88,8 @@ class Runtime:
     def close(self):
         if not self._is_external_sandbox:
             self.sandbox.close()
-        self.browser.close()
+        if self.browser is not None:
+            self.browser.close()
         self._bg_task.cancel()
 
     def init_sandbox_plugins(self, plugins: list[PluginRequirement]) -> None:

+ 4 - 1
opendevin/runtime/server/browse.py

@@ -1,11 +1,14 @@
 import os
 
+from opendevin.core.exceptions import BrowserUnavailableException
 from opendevin.core.schema import ActionType
 from opendevin.events.observation import BrowserOutputObservation
 from opendevin.runtime.browser.browser_env import BrowserEnv
 
 
-async def browse(action, browser: BrowserEnv) -> BrowserOutputObservation:  # type: ignore
+async def browse(action, browser: BrowserEnv | None) -> BrowserOutputObservation:
+    if browser is None:
+        raise BrowserUnavailableException()
     if action.action == ActionType.BROWSE:
         # legacy BrowseURLAction
         asked_url = action.url