command_manager.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from typing import List
  2. from opendevin.observation import CmdOutputObservation
  3. from opendevin.sandbox.sandbox import DockerInteractive
  4. class BackgroundCommand:
  5. def __init__(self, id: int, command: str, dir: str):
  6. self.command = command
  7. self.id = id
  8. self.shell = DockerInteractive(id=str(id), workspace_dir=dir)
  9. self.shell.execute_in_background(command)
  10. def get_logs(self) -> str:
  11. # TODO: get an exit code if process is exited
  12. return self.shell.read_logs()
  13. class CommandManager:
  14. def __init__(self, dir):
  15. self.cur_id = 0
  16. self.directory = dir
  17. self.background_commands = {}
  18. self.shell = DockerInteractive(id="default", workspace_dir=dir)
  19. def run_command(self, command: str, background=False) -> CmdOutputObservation:
  20. if background:
  21. return self._run_background(command)
  22. else:
  23. return self._run_immediately(command)
  24. def _run_immediately(self, command: str) -> CmdOutputObservation:
  25. exit_code, output = self.shell.execute(command)
  26. return CmdOutputObservation(
  27. content=output,
  28. command_id=self.cur_id,
  29. command=command,
  30. exit_code=exit_code
  31. )
  32. def _run_background(self, command: str) -> CmdOutputObservation:
  33. bg_cmd = BackgroundCommand(self.cur_id, command, self.directory)
  34. self.cur_id += 1
  35. self.background_commands[bg_cmd.id] = bg_cmd
  36. return CmdOutputObservation(
  37. content=f"Background command started. To stop it, send a `kill` action with id {bg_cmd.id}",
  38. command_id=bg_cmd.id,
  39. command=command,
  40. exit_code=0
  41. )
  42. def kill_command(self, id: int):
  43. # TODO: get log events before killing
  44. self.background_commands[id].shell.close()
  45. del self.background_commands[id]
  46. def get_background_obs(self) -> List[CmdOutputObservation]:
  47. obs = []
  48. for _id, cmd in self.background_commands.items():
  49. output = cmd.get_logs()
  50. obs.append(
  51. CmdOutputObservation(
  52. content=output, command_id=_id, command=cmd.command
  53. )
  54. )
  55. return obs