From 0d204e2d291365adb1a83bd477b278b3b470f1a4 Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Mon, 25 Mar 2024 11:13:17 -0500 Subject: [PATCH] add NullAction to potentially handle for chat scenario --- opendevin/action/__init__.py | 3 ++- opendevin/action/base.py | 9 +++++++++ opendevin/controller/__init__.py | 10 +++++----- opendevin/server/session.py | 4 ++++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/opendevin/action/__init__.py b/opendevin/action/__init__.py index 450187202c0b..814842cac5eb 100644 --- a/opendevin/action/__init__.py +++ b/opendevin/action/__init__.py @@ -1,4 +1,4 @@ -from .base import Action +from .base import Action, NullAction from .bash import CmdRunAction, CmdKillAction from .browse import BrowseURLAction from .fileop import FileReadAction, FileWriteAction @@ -6,6 +6,7 @@ __all__ = [ "Action", + "NullAction", "CmdRunAction", "CmdKillAction", "BrowseURLAction", diff --git a/opendevin/action/base.py b/opendevin/action/base.py index d6dbc7890e04..4932a43f53e8 100644 --- a/opendevin/action/base.py +++ b/opendevin/action/base.py @@ -34,3 +34,12 @@ class NotExecutableAction(Action): @property def executable(self) -> bool: return False + +class NullAction(NotExecutableAction): + """An action that does nothing. + This is used when the agent need to receive user follow-up messages from the frontend. + """ + + @property + def message(self) -> str: + return "No action" diff --git a/opendevin/controller/__init__.py b/opendevin/controller/__init__.py index 28defaedccdf..9f71050f352c 100644 --- a/opendevin/controller/__init__.py +++ b/opendevin/controller/__init__.py @@ -5,6 +5,7 @@ from opendevin.agent import Agent from opendevin.action import ( Action, + NullAction, FileReadAction, FileWriteAction, AgentFinishAction, @@ -18,10 +19,6 @@ from .command_manager import CommandManager -def print_callback(event): - print(event, flush=True) - - class AgentController: def __init__( self, @@ -34,8 +31,8 @@ def __init__( self.max_iterations = max_iterations self.workdir = workdir self.command_manager = CommandManager(workdir) - self.state_updated_info: List[Tuple[Action, Observation]] = [] self.callbacks = callbacks + self.state_updated_info: List[Tuple[Action, Observation]] = [] def get_current_state(self) -> State: # update observations & actions @@ -46,6 +43,9 @@ def get_current_state(self) -> State: self.state_updated_info = [] return state + def add_observation(self, observation: Observation): + self.state_updated_info.append((NullAction(), observation)) + async def start_loop(self, task_instruction: str): try: self.agent.instruction = task_instruction diff --git a/opendevin/server/session.py b/opendevin/server/session.py index b8b54776a768..37c83a492732 100644 --- a/opendevin/server/session.py +++ b/opendevin/server/session.py @@ -20,6 +20,7 @@ ) from opendevin.observation import ( Observation, + UserMessageObservation ) # NOTE: this is a temporary solution - but hopefully we can use Action/Observation throughout the codebase @@ -95,6 +96,9 @@ async def start_listening(self): else: if self.controller is None: await self.send_error("No agent started. Please wait a second...") + + elif event["action"] == "chat": + self.controller.add_observation(UserMessageObservation(event["message"])) else: # TODO: we only need to implement user message for now # since even Devin does not support having the user taking other