Files
OpenHands/opendevin/controller/command_manager.py
Boxuan Li dd32fa6f4a Unify linter behaviour across CI and pre-commit-hook (#1071)
* CI: Add autopep8 linter

Currently, we have autopep8 as part of pre-commit-hook. To ensure
consistent behaviour, we should have it in CI as well.

Moreover, pre-commit-hook contains a double-quote-string-fixer hook
which changes all double quotes to single quotes, but I do observe
some PRs with massive changes that do the opposite way. I suspect
that these authors 1) disable or circumvent the pre-commit-hook,
and 2) have other linters such as black in their IDE, which
automatically change all single quotes to double quotes. This
has caused a lot of unnecessary diff, made review really hard,
and led to a lot of conflicts.

* Use -diff for autopep8

* autopep8: Freeze version in CI

* Ultimate fix

* Remove pep8 long line disable workaround

* Fix lint.yml

* Fix all files under opendevin and agenthub
2024-04-14 00:19:56 -04:00

77 lines
2.7 KiB
Python

from typing import List
from opendevin import config
from opendevin.observation import CmdOutputObservation
from opendevin.sandbox import DockerExecBox, DockerSSHBox, Sandbox, LocalBox
from opendevin.schema import ConfigType
class CommandManager:
id: str
directory: str
shell: Sandbox
def __init__(
self,
sid: str,
directory: str,
container_image: str | None = None,
):
self.directory = directory
sandbox_type = config.get(ConfigType.SANDBOX_TYPE).lower()
if sandbox_type == 'exec':
self.shell = DockerExecBox(
sid=(sid or 'default'), workspace_dir=directory, container_image=container_image
)
elif sandbox_type == 'local':
self.shell = LocalBox(workspace_dir=directory)
elif sandbox_type == 'ssh':
self.shell = DockerSSHBox(
sid=(sid or 'default'), workspace_dir=directory, container_image=container_image
)
else:
raise ValueError(f'Invalid sandbox type: {sandbox_type}')
def run_command(self, command: str, background=False) -> CmdOutputObservation:
if background:
return self._run_background(command)
else:
return self._run_immediately(command)
def _run_immediately(self, command: str) -> CmdOutputObservation:
exit_code, output = self.shell.execute(command)
return CmdOutputObservation(
command_id=-1, content=output, command=command, exit_code=exit_code
)
def _run_background(self, command: str) -> CmdOutputObservation:
bg_cmd = self.shell.execute_in_background(command)
content = f'Background command started. To stop it, send a `kill` action with id {bg_cmd.id}'
return CmdOutputObservation(
content=content,
command_id=bg_cmd.id,
command=command,
exit_code=0,
)
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.',
command_id=id,
command=cmd.command,
exit_code=0,
)
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 != '':
obs.append(
CmdOutputObservation(
content=output, command_id=_id, command=cmd.command
)
)
return obs