From a6aa2d88cc120aececb4f1fff97ee31cb18fd894 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 26 Mar 2024 11:47:53 -0400 Subject: [PATCH] Fix messages in chat window (#185) * fix messages from server * fix observations * fix file path arg * revert session --- frontend/src/components/Terminal.tsx | 6 +++--- opendevin/action/fileop.py | 8 +++++--- opendevin/observation.py | 22 +++++++++++++++++----- opendevin/server/session.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/Terminal.tsx b/frontend/src/components/Terminal.tsx index c6d1d97102..b434d5f211 100644 --- a/frontend/src/components/Terminal.tsx +++ b/frontend/src/components/Terminal.tsx @@ -22,12 +22,12 @@ class JsonWebsocketAddon { }), ); this._socket.addEventListener("message", (event) => { - const { action, args } = JSON.parse(event.data); + const { action, args, observation, content } = JSON.parse(event.data); if (action === "run") { terminal.writeln(args.command); } - if (action === "output") { - args.output.split("\n").forEach((line: string) => { + if (observation === "run") { + content.split("\n").forEach((line: string) => { terminal.writeln(line); }); terminal.write("\n$ "); diff --git a/opendevin/action/fileop.py b/opendevin/action/fileop.py index fcf45cfce3..29279c1629 100644 --- a/opendevin/action/fileop.py +++ b/opendevin/action/fileop.py @@ -1,7 +1,7 @@ import os from dataclasses import dataclass -from opendevin.observation import Observation +from opendevin.observation import Observation, FileReadObservation from .base import ExecutableAction # This is the path where the workspace is mounted in the container @@ -19,10 +19,12 @@ class FileReadAction(ExecutableAction): path: str base_path: str = "" - def run(self, *args, **kwargs) -> Observation: + def run(self, *args, **kwargs) -> FileReadObservation: path = resolve_path(self.base_path, self.path) with open(path, 'r', encoding='utf-8') as file: - return Observation(file.read()) + return FileReadObservation( + path=path, + content=file.read()) @property def message(self) -> str: diff --git a/opendevin/observation.py b/opendevin/observation.py index 0e8c77a804..38aa4ea805 100644 --- a/opendevin/observation.py +++ b/opendevin/observation.py @@ -28,7 +28,7 @@ class Observation: @property def message(self) -> str: """Returns a message describing the observation.""" - return "The agent made an observation." + return "" @dataclass @@ -47,7 +47,19 @@ class CmdOutputObservation(Observation): @property def message(self) -> str: - return f'The agent observed command "{self.command}" executed with exit code {self.exit_code}.' + return f'Command `{self.command}` executed with exit code {self.exit_code}.' + +@dataclass +class FileReadObservation(Observation): + """ + This data class represents the content of a file. + """ + + path: str + + @property + def message(self) -> str: + return f"I read the file {self.path}." @dataclass @@ -62,7 +74,7 @@ class BrowserOutputObservation(Observation): @property def message(self) -> str: - return "The agent observed the browser output at URL." + return "Visited " + self.url @dataclass @@ -75,7 +87,7 @@ class UserMessageObservation(Observation): @property def message(self) -> str: - return "The agent received a message from the user." + return "" @dataclass @@ -88,7 +100,7 @@ class AgentMessageObservation(Observation): @property def message(self) -> str: - return "The agent received a message from itself." + return "" @dataclass diff --git a/opendevin/server/session.py b/opendevin/server/session.py index ca49f3f646..a53b14d51e 100644 --- a/opendevin/server/session.py +++ b/opendevin/server/session.py @@ -145,5 +145,33 @@ class Session: self.agent_task = asyncio.create_task(self.controller.start_loop(task), name="agent loop") def on_agent_event(self, event: Observation | Action): + # FIXME: we need better serialization event_dict = event.to_dict() + if "action" in event_dict: + if event_dict["action"] == "CmdRunAction": + event_dict["action"] = "run" + elif event_dict["action"] == "CmdKillAction": + event_dict["action"] = "kill" + elif event_dict["action"] == "BrowseURLAction": + event_dict["action"] = "browse" + elif event_dict["action"] == "FileReadAction": + event_dict["action"] = "read" + elif event_dict["action"] == "FileWriteAction": + event_dict["action"] = "write" + elif event_dict["action"] == "AgentFinishAction": + event_dict["action"] = "finish" + elif event_dict["action"] == "AgentRecallAction": + event_dict["action"] = "recall" + elif event_dict["action"] == "AgentThinkAction": + event_dict["action"] = "think" + if "observation" in event_dict: + if event_dict["observation"] == "UserMessageObservation": + event_dict["observation"] = "chat" + elif event_dict["observation"] == "AgentMessageObservation": + event_dict["observation"] = "chat" + elif event_dict["observation"] == "CmdOutputObservation": + event_dict["observation"] = "run" + elif event_dict["observation"] == "FileReadObservation": + event_dict["observation"] = "read" + asyncio.create_task(self.send(event_dict), name="send event in callback")