Skip to content

Commit

Permalink
Create a CommandExecutor abstract class (All-Hands-AI#874)
Browse files Browse the repository at this point in the history
* Create abstract CommandExecutor class

* Use CommandExecutor for Sandbox
  • Loading branch information
foragerr committed Apr 7, 2024
1 parent e52bf5a commit 6e3b554
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
24 changes: 24 additions & 0 deletions opendevin/controller/command_executor.py
Original file line number Diff line number Diff line change
@@ -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
9 changes: 4 additions & 5 deletions opendevin/controller/command_manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from typing import List

from opendevin.observation import CmdOutputObservation
from opendevin.sandbox.sandbox import DockerInteractive

Expand All @@ -13,7 +12,7 @@ def __init__(
):
self.directory = dir
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:
Expand All @@ -31,7 +30,7 @@ def _run_immediately(self, command: str) -> CmdOutputObservation:
def _run_background(self, command: str) -> CmdOutputObservation:
bg_cmd = self.shell.execute_in_background(command)
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=command,
exit_code=0,
Expand All @@ -40,7 +39,7 @@ def _run_background(self, command: str) -> CmdOutputObservation:
def kill_command(self, id: int) -> CmdOutputObservation:
cmd = self.shell.kill_background(id)
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=cmd.command,
exit_code=0,
Expand All @@ -50,7 +49,7 @@ def get_background_obs(self) -> List[CmdOutputObservation]:
obs = []
for _id, cmd in self.shell.background_commands.items():
output = cmd.read_logs()
if output is not None and output != "":
if output is not None and output != '':
obs.append(
CmdOutputObservation(
content=output, command_id=_id, command=cmd.command
Expand Down
9 changes: 5 additions & 4 deletions opendevin/sandbox/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from opendevin import config
from opendevin.logging import opendevin_logger as logger
from opendevin.controller.command_executor import CommandExecutor

InputType = namedtuple('InputType', ['content'])
OutputType = namedtuple('OutputType', ['content'])
Expand Down Expand Up @@ -84,7 +85,7 @@ def read_logs(self) -> str:
return (logs + last_remains).decode('utf-8', errors='replace')


class DockerInteractive:
class DockerInteractive(CommandExecutor):
closed = False
cur_background_id = 0
background_commands: Dict[int, BackgroundCommand] = {}
Expand Down Expand Up @@ -127,7 +128,7 @@ def __init__(
else:
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():
self.restart_docker_container()
Expand Down Expand Up @@ -175,7 +176,7 @@ def run_command(container, command):
pid = self.get_pid(cmd)
if pid is not None:
self.container.exec_run(
f"kill -9 {pid}", workdir='/workspace')
f'kill -9 {pid}', workdir='/workspace')
return -1, f'Command: "{cmd}" timed out'
return exit_code, logs.decode('utf-8')

Expand Down Expand Up @@ -207,7 +208,7 @@ def kill_background(self, id: int) -> BackgroundCommand:
bg_cmd = self.background_commands[id]
if bg_cmd.pid is not None:
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()
self.background_commands.pop(id)
return bg_cmd
Expand Down

0 comments on commit 6e3b554

Please sign in to comment.