Ver código fonte

Bugfix by added config to disable plugin initialization for Persistent sandbox (#2179)

* refactored source bashrc logic

* added initialize_plugins config

---------

Co-authored-by: Graham Neubig <neubig@gmail.com>
மனோஜ்குமார் பழனிச்சாமி 1 ano atrás
pai
commit
4e479038f9

+ 1 - 0
opendevin/core/config.py

@@ -179,6 +179,7 @@ class AppConfig(metaclass=Singleton):
     disable_color: bool = False
     sandbox_user_id: int = os.getuid() if hasattr(os, 'getuid') else 1000
     sandbox_timeout: int = 120
+    initialize_plugins: bool = True
     persist_sandbox: bool = False
     ssh_port: int = 63710
     ssh_password: str | None = None

+ 1 - 6
opendevin/core/main.py

@@ -91,12 +91,7 @@ async def main(
         event_stream=event_stream,
     )
     runtime = ServerRuntime(event_stream=event_stream, sandbox=sandbox)
-
-    if runtime.sandbox.is_initial_session:
-        logger.info('Initializing plugins in the sandbox')
-        runtime.init_sandbox_plugins(controller.agent.sandbox_plugins)
-    else:
-        logger.info('Plugins are already initialized in the sandbox')
+    runtime.init_sandbox_plugins(controller.agent.sandbox_plugins)
     runtime.init_runtime_tools(controller.agent.runtime_tools, is_async=False)
 
     await event_stream.add_event(MessageAction(content=task), EventSource.USER)

+ 45 - 35
opendevin/runtime/plugins/mixin.py

@@ -9,6 +9,9 @@ from opendevin.runtime.plugins.requirement import PluginRequirement
 class SandboxProtocol(Protocol):
     # https://stackoverflow.com/questions/51930339/how-do-i-correctly-add-type-hints-to-mixin-classes
 
+    @property
+    def initialize_plugins(self) -> bool: ...
+
     def execute(
         self, cmd: str, stream: bool = False
     ) -> tuple[int, str | CancellableStream]: ...
@@ -25,41 +28,48 @@ class PluginMixin:
         if hasattr(self, 'plugin_initialized') and self.plugin_initialized:
             return
 
-        # clean-up ~/.bashrc and touch ~/.bashrc
-        exit_code, output = self.execute('rm -f ~/.bashrc && touch ~/.bashrc')
-
-        for requirement in requirements:
-            # copy over the files
-            self.copy_to(requirement.host_src, requirement.sandbox_dest, recursive=True)
-            logger.info(
-                f'Copied files from [{requirement.host_src}] to [{requirement.sandbox_dest}] inside sandbox.'
-            )
-
-            # Execute the bash script
-            abs_path_to_bash_script = os.path.join(
-                requirement.sandbox_dest, requirement.bash_script_path
-            )
-            logger.info(
-                f'Initializing plugin [{requirement.name}] by executing [{abs_path_to_bash_script}] in the sandbox.'
-            )
-            exit_code, output = self.execute(abs_path_to_bash_script, stream=True)
-            if isinstance(output, CancellableStream):
-                for line in output:
-                    if line.endswith('\n'):
-                        line = line[:-1]
-                _exit_code = output.exit_code()
-                output.close()
-                if _exit_code != 0:
-                    raise RuntimeError(
-                        f'Failed to initialize plugin {requirement.name} with exit code {_exit_code} and output {output}'
-                    )
-                logger.info(f'Plugin {requirement.name} initialized successfully')
-            else:
-                if exit_code != 0:
-                    raise RuntimeError(
-                        f'Failed to initialize plugin {requirement.name} with exit code {exit_code} and output: {output}'
-                    )
-                logger.info(f'Plugin {requirement.name} initialized successfully.')
+        if self.initialize_plugins:
+            logger.info('Initializing plugins in the sandbox')
+
+            # clean-up ~/.bashrc and touch ~/.bashrc
+            exit_code, output = self.execute('rm -f ~/.bashrc && touch ~/.bashrc')
+
+            for requirement in requirements:
+                # copy over the files
+                self.copy_to(
+                    requirement.host_src, requirement.sandbox_dest, recursive=True
+                )
+                logger.info(
+                    f'Copied files from [{requirement.host_src}] to [{requirement.sandbox_dest}] inside sandbox.'
+                )
+
+                # Execute the bash script
+                abs_path_to_bash_script = os.path.join(
+                    requirement.sandbox_dest, requirement.bash_script_path
+                )
+                logger.info(
+                    f'Initializing plugin [{requirement.name}] by executing [{abs_path_to_bash_script}] in the sandbox.'
+                )
+                exit_code, output = self.execute(abs_path_to_bash_script, stream=True)
+                if isinstance(output, CancellableStream):
+                    for line in output:
+                        if line.endswith('\n'):
+                            line = line[:-1]
+                    _exit_code = output.exit_code()
+                    output.close()
+                    if _exit_code != 0:
+                        raise RuntimeError(
+                            f'Failed to initialize plugin {requirement.name} with exit code {_exit_code} and output {output}'
+                        )
+                    logger.info(f'Plugin {requirement.name} initialized successfully')
+                else:
+                    if exit_code != 0:
+                        raise RuntimeError(
+                            f'Failed to initialize plugin {requirement.name} with exit code {exit_code} and output: {output}'
+                        )
+                    logger.info(f'Plugin {requirement.name} initialized successfully.')
+        else:
+            logger.info('Skipping plugin initialization in the sandbox')
 
         if len(requirements) > 0:
             exit_code, output = self.execute('source ~/.bashrc')

+ 1 - 0
opendevin/runtime/sandbox.py

@@ -20,6 +20,7 @@ class Sandbox(ABC, PluginMixin):
                 self.add_to_env(sandbox_key, os.environ[key])
         if config.enable_auto_lint:
             self.add_to_env('ENABLE_AUTO_LINT', 'true')
+        self.initialize_plugins: bool = config.initialize_plugins
 
     def add_to_env(self, key: str, value: str):
         self._env[key] = value

+ 1 - 6
opendevin/server/session/agent.py

@@ -101,12 +101,7 @@ class AgentSession:
                 logger.warning(
                     'CodeActAgent requires DockerSSHBox as sandbox! Using other sandbox that are not stateful (LocalBox, DockerExecBox) will not work properly.'
                 )
-
-        if self.runtime.sandbox.is_initial_session:
-            logger.info('Initializing plugins in the sandbox')
-            self.runtime.init_sandbox_plugins(agent.sandbox_plugins)
-        else:
-            logger.info('Plugins are already initialized in the sandbox')
+        self.runtime.init_sandbox_plugins(agent.sandbox_plugins)
         self.runtime.init_runtime_tools(agent.runtime_tools)
 
         self.controller = AgentController(