Sfoglia il codice sorgente

Create a CommandExecutor abstract class (#874)

* Create abstract CommandExecutor class

* Use CommandExecutor for Sandbox
RaGe 1 anno fa
parent
commit
6e3b554317

+ 24 - 0
opendevin/controller/command_executor.py

@@ -0,0 +1,24 @@
+from typing import Tuple
+from abc import ABC, abstractmethod
+
+
+class CommandExecutor(ABC):
+    @abstractmethod
+    def execute(self, cmd: str) -> Tuple[int, str]:
+        pass
+
+    @abstractmethod
+    def execute_in_background(self, cmd: str):
+        pass
+
+    @abstractmethod
+    def kill_background(self, id: int):
+        pass
+
+    @abstractmethod
+    def read_logs(self, id: int) -> str:
+        pass
+
+    @abstractmethod
+    def close(self):
+        pass

+ 4 - 5
opendevin/controller/command_manager.py

@@ -1,5 +1,4 @@
 from typing import List
 from typing import List
-
 from opendevin.observation import CmdOutputObservation
 from opendevin.observation import CmdOutputObservation
 from opendevin.sandbox.sandbox import DockerInteractive
 from opendevin.sandbox.sandbox import DockerInteractive
 
 
@@ -13,7 +12,7 @@ class CommandManager:
     ):
     ):
         self.directory = dir
         self.directory = dir
         self.shell = DockerInteractive(
         self.shell = DockerInteractive(
-            id=(id or "default"), workspace_dir=dir, container_image=container_image
+            id=(id or 'default'), workspace_dir=dir, container_image=container_image
         )
         )
 
 
     def run_command(self, command: str, background=False) -> CmdOutputObservation:
     def run_command(self, command: str, background=False) -> CmdOutputObservation:
@@ -31,7 +30,7 @@ class CommandManager:
     def _run_background(self, command: str) -> CmdOutputObservation:
     def _run_background(self, command: str) -> CmdOutputObservation:
         bg_cmd = self.shell.execute_in_background(command)
         bg_cmd = self.shell.execute_in_background(command)
         return CmdOutputObservation(
         return CmdOutputObservation(
-            content=f"Background command started. To stop it, send a `kill` action with id {bg_cmd.id}",
+            content=f'Background command started. To stop it, send a `kill` action with id {bg_cmd.id}',
             command_id=bg_cmd.id,
             command_id=bg_cmd.id,
             command=command,
             command=command,
             exit_code=0,
             exit_code=0,
@@ -40,7 +39,7 @@ class CommandManager:
     def kill_command(self, id: int) -> CmdOutputObservation:
     def kill_command(self, id: int) -> CmdOutputObservation:
         cmd = self.shell.kill_background(id)
         cmd = self.shell.kill_background(id)
         return CmdOutputObservation(
         return CmdOutputObservation(
-            content=f"Background command with id {id} has been killed.",
+            content=f'Background command with id {id} has been killed.',
             command_id=id,
             command_id=id,
             command=cmd.command,
             command=cmd.command,
             exit_code=0,
             exit_code=0,
@@ -50,7 +49,7 @@ class CommandManager:
         obs = []
         obs = []
         for _id, cmd in self.shell.background_commands.items():
         for _id, cmd in self.shell.background_commands.items():
             output = cmd.read_logs()
             output = cmd.read_logs()
-            if output is not None and output != "":
+            if output is not None and output != '':
                 obs.append(
                 obs.append(
                     CmdOutputObservation(
                     CmdOutputObservation(
                         content=output, command_id=_id, command=cmd.command
                         content=output, command_id=_id, command=cmd.command

+ 5 - 4
opendevin/sandbox/sandbox.py

@@ -12,6 +12,7 @@ import concurrent.futures
 
 
 from opendevin import config
 from opendevin import config
 from opendevin.logging import opendevin_logger as logger
 from opendevin.logging import opendevin_logger as logger
+from opendevin.controller.command_executor import CommandExecutor
 
 
 InputType = namedtuple('InputType', ['content'])
 InputType = namedtuple('InputType', ['content'])
 OutputType = namedtuple('OutputType', ['content'])
 OutputType = namedtuple('OutputType', ['content'])
@@ -84,7 +85,7 @@ class BackgroundCommand:
         return (logs + last_remains).decode('utf-8', errors='replace')
         return (logs + last_remains).decode('utf-8', errors='replace')
 
 
 
 
-class DockerInteractive:
+class DockerInteractive(CommandExecutor):
     closed = False
     closed = False
     cur_background_id = 0
     cur_background_id = 0
     background_commands: Dict[int, BackgroundCommand] = {}
     background_commands: Dict[int, BackgroundCommand] = {}
@@ -127,7 +128,7 @@ class DockerInteractive:
         else:
         else:
             self.container_image = container_image
             self.container_image = container_image
 
 
-        self.container_name = f"sandbox-{self.instance_id}"
+        self.container_name = f'sandbox-{self.instance_id}'
 
 
         if not self.is_container_running():
         if not self.is_container_running():
             self.restart_docker_container()
             self.restart_docker_container()
@@ -175,7 +176,7 @@ class DockerInteractive:
                 pid = self.get_pid(cmd)
                 pid = self.get_pid(cmd)
                 if pid is not None:
                 if pid is not None:
                     self.container.exec_run(
                     self.container.exec_run(
-                        f"kill -9 {pid}", workdir='/workspace')
+                        f'kill -9 {pid}', workdir='/workspace')
                 return -1, f'Command: "{cmd}" timed out'
                 return -1, f'Command: "{cmd}" timed out'
         return exit_code, logs.decode('utf-8')
         return exit_code, logs.decode('utf-8')
 
 
@@ -207,7 +208,7 @@ class DockerInteractive:
         bg_cmd = self.background_commands[id]
         bg_cmd = self.background_commands[id]
         if bg_cmd.pid is not None:
         if bg_cmd.pid is not None:
             self.container.exec_run(
             self.container.exec_run(
-                f"kill -9 {bg_cmd.pid}", workdir='/workspace')
+                f'kill -9 {bg_cmd.pid}', workdir='/workspace')
         bg_cmd.result.output.close()
         bg_cmd.result.output.close()
         self.background_commands.pop(id)
         self.background_commands.pop(id)
         return bg_cmd
         return bg_cmd