From 5e34038831be9d1176e7d00e494ddb314e7448e2 Mon Sep 17 00:00:00 2001 From: yzlin Date: Tue, 2 Apr 2024 12:08:39 +0800 Subject: [PATCH] log datatype change --- metagpt/logs.py | 18 +++++++++++++++--- metagpt/schema.py | 6 ++++-- metagpt/tools/libs/terminal.py | 16 ++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/metagpt/logs.py b/metagpt/logs.py index e547ebb76..f102c1be3 100644 --- a/metagpt/logs.py +++ b/metagpt/logs.py @@ -13,10 +13,22 @@ from datetime import datetime from functools import partial from loguru import logger as _logger +from pydantic import BaseModel, Field from metagpt.const import METAGPT_ROOT +class ToolLogItem(BaseModel): + type_: str = Field(alias="type", default="str", description="Data type of `value` field.") + name: str + value: str + + +TOOL_LOG_END_MARKER = ToolLogItem( + type="str", name="end_marker", value="#END#" +) # A special log item to suggest the end of a stream log + + def define_log_level(print_level="INFO", logfile_level="DEBUG", name: str = None): """Adjust the log level to above level""" current_date = datetime.now() @@ -36,9 +48,9 @@ def log_llm_stream(msg): _llm_stream_log(msg) -def log_tool_output(output: dict, tool_name: str = ""): +def log_tool_output(output: ToolLogItem | list[ToolLogItem], tool_name: str = ""): """interface for logging tool output, can be set to log tool output in different ways to different places with set_tool_output_logfunc""" - _tool_output_log(output, tool_name) + _tool_output_log(output=output, tool_name=tool_name) def set_llm_stream_logfunc(func): @@ -54,4 +66,4 @@ def set_tool_output_logfunc(func): _llm_stream_log = partial(print, end="") -_tool_output_log = partial(print, end="") +_tool_output_log = lambda output, tool_name: print(output) diff --git a/metagpt/schema.py b/metagpt/schema.py index d944a4199..ebd0e5be3 100644 --- a/metagpt/schema.py +++ b/metagpt/schema.py @@ -45,7 +45,7 @@ from metagpt.const import ( SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO, ) -from metagpt.logs import log_tool_output, logger +from metagpt.logs import ToolLogItem, log_tool_output, logger from metagpt.repo_parser import DotClassInfo from metagpt.utils.common import any_to_str, any_to_str_set, import_class from metagpt.utils.exceptions import handle_exception @@ -434,7 +434,9 @@ class Plan(BaseModel): self.tasks = final_tasks log_tool_output( - {"output": "\n\n".join([f"Task {task.task_id}: {task.instruction}" for task in self.tasks])}, + ToolLogItem( + name="output", value="\n\n".join([f"Task {task.task_id}: {task.instruction}" for task in self.tasks]) + ), tool_name="Plan", ) diff --git a/metagpt/tools/libs/terminal.py b/metagpt/tools/libs/terminal.py index 2b1657bdd..a23ebb86a 100644 --- a/metagpt/tools/libs/terminal.py +++ b/metagpt/tools/libs/terminal.py @@ -1,6 +1,6 @@ import subprocess -from metagpt.logs import log_tool_output +from metagpt.logs import TOOL_LOG_END_MARKER, ToolLogItem, log_tool_output from metagpt.tools.tool_registry import register_tool @@ -11,7 +11,6 @@ class Terminal: def __init__(self): self.shell_command = ["bash"] # FIXME: should consider windows support later self.command_terminator = "\n" - self.end_marker = "#END_MARKER#" # Start a persistent shell process self.process = subprocess.Popen( @@ -40,17 +39,22 @@ class Terminal: # Send the command self.process.stdin.write(cmd + self.command_terminator) self.process.stdin.write( - f'echo "{self.end_marker}"' + self.command_terminator + f'echo "{TOOL_LOG_END_MARKER.value}"' + self.command_terminator ) # Unique marker to signal command end self.process.stdin.flush() - log_tool_output(output={"cmd": cmd + self.command_terminator}, tool_name="Terminal") # log the command + log_tool_output( + output=ToolLogItem(name="cmd", value=cmd + self.command_terminator), tool_name="Terminal" + ) # log the command # Read the output until the unique marker is found while True: line = self.process.stdout.readline() - if line.strip() == self.end_marker: + if line.strip() == TOOL_LOG_END_MARKER.value: + log_tool_output(TOOL_LOG_END_MARKER) break - log_tool_output(output={"output": line}, tool_name="Terminal") # log stdout in real-time + log_tool_output( + output=ToolLogItem(name="output", value=line), tool_name="Terminal" + ) # log stdout in real-time cmd_output.append(line) return "".join(cmd_output)