command_manager.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from typing import List
  2. from opendevin.observation import CmdOutputObservation
  3. from opendevin.sandbox.sandbox import DockerInteractive
  4. class CommandManager:
  5. def __init__(self, dir: str, container_image: str | None = None,):
  6. self.directory = dir
  7. self.shell = DockerInteractive(id="default", workspace_dir=dir, container_image=container_image)
  8. def run_command(self, command: str, background=False) -> CmdOutputObservation:
  9. if background:
  10. return self._run_background(command)
  11. else:
  12. return self._run_immediately(command)
  13. def _run_immediately(self, command: str) -> CmdOutputObservation:
  14. exit_code, output = self.shell.execute(command)
  15. return CmdOutputObservation(
  16. command_id=-1,
  17. content=output,
  18. command=command,
  19. exit_code=exit_code
  20. )
  21. def _run_background(self, command: str) -> CmdOutputObservation:
  22. bg_cmd = self.shell.execute_in_background(command)
  23. return CmdOutputObservation(
  24. content=f"Background command started. To stop it, send a `kill` action with id {bg_cmd.id}",
  25. command_id=bg_cmd.id,
  26. command=command,
  27. exit_code=0
  28. )
  29. def kill_command(self, id: int) -> CmdOutputObservation:
  30. cmd = self.shell.kill_background(id)
  31. return CmdOutputObservation(
  32. content=f"Background command with id {id} has been killed.",
  33. command_id=id,
  34. command=cmd.command,
  35. exit_code=0
  36. )
  37. def get_background_obs(self) -> List[CmdOutputObservation]:
  38. obs = []
  39. for _id, cmd in self.shell.background_commands.items():
  40. output = cmd.read_logs()
  41. if output is not None and output != "":
  42. obs.append(
  43. CmdOutputObservation(
  44. content=output, command_id=_id, command=cmd.command
  45. )
  46. )
  47. return obs