OpenHands/opendevin/controller.py
Robert Brennan 4aa24eb41d
Server working with agent library (#97)
* server working with agent library

* update readme

* add messages to events

* factor out steps

* fix websocket messages

* allow user to run arbitrary actions

* allow user to run commands before a task is started

* fix main.py

* check JSON

* handle errors in controller better

* fix memory issue

* better error handling and task cancellation

* fix monologue len

* fix imports

* remove server from lint check

* fix lint issues

* fix lint errors
2024-03-24 22:24:44 +08:00

69 lines
2.3 KiB
Python

import asyncio
from opendevin.lib.command_manager import CommandManager
from opendevin.lib.event import Event
def print_callback(event):
print(event.str_truncated(), flush=True)
class AgentController:
def __init__(self, agent, workdir, max_iterations=100, callbacks=[]):
self.agent = agent
self.max_iterations = max_iterations
self.background_commands = []
self.command_manager = CommandManager(workdir)
self.callbacks = callbacks
self.callbacks.append(self.agent.add_event)
self.callbacks.append(print_callback)
async def add_user_event(self, event: Event):
await self.handle_action(event)
async def start_loop(self, task):
try:
self.agent.instruction = task
for i in range(self.max_iterations):
print("STEP", i, flush=True)
done = await self.step()
if done:
print("FINISHED", flush=True)
break
except Exception as e:
print("Error in loop", e, flush=True)
pass
async def step(self) -> bool:
log_events = self.command_manager.get_background_events()
for event in log_events:
await self.run_callbacks(event)
try:
action_event = self.agent.step(self.command_manager)
except Exception as e:
action_event = Event('error', {'error': str(e)})
if action_event is None:
action_event = Event('error', {'error': "Agent did not return an event"})
await self.handle_action(action_event)
return action_event.action == 'finish'
async def handle_action(self, event: Event):
print("=== HANDLING EVENT ===", flush=True)
await self.run_callbacks(event)
print("--- EVENT OUTPUT ---", flush=True)
output_event = event.run(self)
await self.run_callbacks(output_event)
async def run_callbacks(self, event):
if event is None:
return
for callback in self.callbacks:
idx = self.callbacks.index(callback)
try:
callback(event)
except Exception as e:
print("Callback error:" + str(idx), e, flush=True)
pass
await asyncio.sleep(0.001) # Give back control for a tick, so we can await in callbacks