runtime.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from typing import Callable, Optional
  2. from openhands.core.config import AppConfig
  3. from openhands.events.action import (
  4. FileReadAction,
  5. FileWriteAction,
  6. )
  7. from openhands.events.observation import (
  8. ErrorObservation,
  9. FileReadObservation,
  10. FileWriteObservation,
  11. Observation,
  12. )
  13. from openhands.events.stream import EventStream
  14. from openhands.runtime.e2b.filestore import E2BFileStore
  15. from openhands.runtime.e2b.sandbox import E2BSandbox
  16. from openhands.runtime.plugins import PluginRequirement
  17. from openhands.runtime.runtime import Runtime
  18. from openhands.runtime.utils.files import insert_lines, read_lines
  19. class E2BRuntime(Runtime):
  20. def __init__(
  21. self,
  22. config: AppConfig,
  23. event_stream: EventStream,
  24. sid: str = 'default',
  25. plugins: list[PluginRequirement] | None = None,
  26. sandbox: E2BSandbox | None = None,
  27. status_message_callback: Optional[Callable] = None,
  28. ):
  29. super().__init__(
  30. config,
  31. event_stream,
  32. sid,
  33. plugins,
  34. status_message_callback=status_message_callback,
  35. )
  36. if sandbox is None:
  37. self.sandbox = E2BSandbox()
  38. if not isinstance(self.sandbox, E2BSandbox):
  39. raise ValueError('E2BRuntime requires an E2BSandbox')
  40. self.file_store = E2BFileStore(self.sandbox.filesystem)
  41. def read(self, action: FileReadAction) -> Observation:
  42. content = self.file_store.read(action.path)
  43. lines = read_lines(content.split('\n'), action.start, action.end)
  44. code_view = ''.join(lines)
  45. return FileReadObservation(code_view, path=action.path)
  46. def write(self, action: FileWriteAction) -> Observation:
  47. if action.start == 0 and action.end == -1:
  48. self.file_store.write(action.path, action.content)
  49. return FileWriteObservation(content='', path=action.path)
  50. files = self.file_store.list(action.path)
  51. if action.path in files:
  52. all_lines = self.file_store.read(action.path).split('\n')
  53. new_file = insert_lines(
  54. action.content.split('\n'), all_lines, action.start, action.end
  55. )
  56. self.file_store.write(action.path, ''.join(new_file))
  57. return FileWriteObservation('', path=action.path)
  58. else:
  59. # FIXME: we should create a new file here
  60. return ErrorObservation(f'File not found: {action.path}')