controller.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import asyncio
  2. from opendevin.lib.command_manager import CommandManager
  3. from opendevin.lib.event import Event
  4. def print_callback(event):
  5. print(event.str_truncated(), flush=True)
  6. class AgentController:
  7. def __init__(self, agent, workdir, max_iterations=100, callbacks=[]):
  8. self.agent = agent
  9. self.max_iterations = max_iterations
  10. self.background_commands = []
  11. self.command_manager = CommandManager(workdir)
  12. self.callbacks = callbacks
  13. self.callbacks.append(self.agent.add_event)
  14. self.callbacks.append(print_callback)
  15. async def add_user_event(self, event: Event):
  16. await self.handle_action(event)
  17. async def start_loop(self, task):
  18. try:
  19. self.agent.instruction = task
  20. for i in range(self.max_iterations):
  21. print("STEP", i, flush=True)
  22. done = await self.step()
  23. if done:
  24. print("FINISHED", flush=True)
  25. break
  26. except Exception as e:
  27. print("Error in loop", e, flush=True)
  28. pass
  29. async def step(self) -> bool:
  30. log_events = self.command_manager.get_background_events()
  31. for event in log_events:
  32. await self.run_callbacks(event)
  33. try:
  34. action_event = self.agent.step(self.command_manager)
  35. except Exception as e:
  36. action_event = Event('error', {'error': str(e)})
  37. if action_event is None:
  38. action_event = Event('error', {'error': "Agent did not return an event"})
  39. await self.handle_action(action_event)
  40. return action_event.action == 'finish'
  41. async def handle_action(self, event: Event):
  42. print("=== HANDLING EVENT ===", flush=True)
  43. await self.run_callbacks(event)
  44. print("--- EVENT OUTPUT ---", flush=True)
  45. output_event = event.run(self)
  46. await self.run_callbacks(output_event)
  47. async def run_callbacks(self, event):
  48. if event is None:
  49. return
  50. for callback in self.callbacks:
  51. idx = self.callbacks.index(callback)
  52. try:
  53. callback(event)
  54. except Exception as e:
  55. print("Callback error:" + str(idx), e, flush=True)
  56. pass
  57. await asyncio.sleep(0.001) # Give back control for a tick, so we can await in callbacks