I made dump showing more messages and added a count (the last x) (#204)

* I made dump showing more message and added a count (the last x)

There seem to be some changes about the implementation so that the
current dump message helper functions do not show a lot of useful info.

I changed it so that you can `dump 5` (last 5 messages) and that it will
print user readable output. This lets you get some more understanding about
what is going on.

As some messages are still not shown I also show the index (reverse) of the
printed message, so one can see what to "pop" to reach a special point
without geting into the drumpraw.

* black

* patch

---------

Co-authored-by: Charles Packer <packercharles@gmail.com>
This commit is contained in:
Hans Raaf
2023-11-04 04:47:23 +01:00
committed by GitHub
parent 94893b4bd5
commit 9189a7bf26
4 changed files with 38 additions and 22 deletions

View File

@@ -291,8 +291,8 @@ While using MemGPT via the CLI (not Discord!) you can run various commands:
save a checkpoint of the current agent/conversation state
/load
load a saved checkpoint
/dump
view the current message log (see the contents of main context)
/dump <count>
view the last <count> messages (all if <count> is omitted)
/memory
print the current contents of agent memory
/pop

View File

@@ -57,7 +57,7 @@ async def system_message(msg):
print(fstr.format(msg=msg))
async def user_message(msg, raw=False):
async def user_message(msg, raw=False, debug=DEBUG):
def print_user_message(icon, msg, printf=print):
if STRIP_UI:
printf(f"{icon} {msg}")
@@ -78,12 +78,11 @@ async def user_message(msg, raw=False):
printd(f"Warning: failed to parse user message into json")
printd_user_message("🧑", msg)
return
if msg_json["type"] == "user_message":
msg_json.pop("type")
printd_user_message("🧑", msg_json)
elif msg_json["type"] == "heartbeat":
if DEBUG:
if debug:
msg_json.pop("type")
printd_user_message("💓", msg_json)
elif msg_json["type"] == "system_message":
@@ -93,7 +92,7 @@ async def user_message(msg, raw=False):
printd_user_message("🧑", msg_json)
async def function_message(msg):
async def function_message(msg, debug=DEBUG):
def print_function_message(icon, msg, color=Fore.RED, printf=print):
if STRIP_UI:
printf(f"{icon} [function] {msg}")
@@ -101,7 +100,7 @@ async def function_message(msg):
printf(f"{color}{Style.BRIGHT}{icon} [function] {color}{msg}{Style.RESET_ALL}")
def printd_function_message(icon, msg, color=Fore.RED):
return print_function_message(icon, msg, color, printf=printd)
return print_function_message(icon, msg, color, printf=(print if debug else printd))
if isinstance(msg, dict):
printd_function_message("", msg)
@@ -112,7 +111,7 @@ async def function_message(msg):
elif msg.startswith("Error: "):
printd_function_message("🔴", msg)
elif msg.startswith("Running "):
if DEBUG:
if debug:
printd_function_message("", msg)
else:
if "memory" in msg:
@@ -150,14 +149,20 @@ async def function_message(msg):
try:
msg_dict = json.loads(msg)
if "status" in msg_dict and msg_dict["status"] == "OK":
printd_function_message("", msg, color=Fore.GREEN)
printd_function_message("", str(msg), color=Fore.GREEN)
else:
printd_function_message("", str(msg), color=Fore.RED)
except Exception:
printd(f"Warning: did not recognize function message {type(msg)} {msg}")
printd_function_message(msg)
print(f"Warning: did not recognize function message {type(msg)} {msg}")
printd_function_message("", msg)
async def print_messages(message_sequence):
async def print_messages(message_sequence, dump=False):
idx = len(message_sequence)
for msg in message_sequence:
if dump:
print(f"[{idx}] ", end="")
idx -= 1
role = msg["role"]
content = msg["content"]
@@ -168,14 +173,17 @@ async def print_messages(message_sequence):
if msg.get("function_call"):
if content is not None:
await internal_monologue(content)
await function_message(msg["function_call"])
# I think the next one is not up to date
# await function_message(msg["function_call"])
args = json.loads(msg["function_call"].get("arguments"))
await assistant_message(args.get("message"))
# assistant_message(content)
else:
await internal_monologue(content)
elif role == "user":
await user_message(content)
await user_message(content, debug=dump)
elif role == "function":
await function_message(content)
await function_message(content, debug=dump)
else:
print(f"Unknown role: {content}")

View File

@@ -14,6 +14,7 @@ import typer
from rich.console import Console
from prettytable import PrettyTable
from .interface import print_messages
console = Console()
@@ -470,18 +471,20 @@ async def run_agent_loop(memgpt_agent, first, no_verify=False, cfg=None, strip_u
)
continue
elif user_input.lower() == "/dump":
await memgpt.interface.print_messages(memgpt_agent.messages)
elif user_input.lower() == "/dump" or user_input.lower().startswith("/dump "):
# Check if there's an additional argument that's an integer
command = user_input.strip().split()
amount = int(command[1]) if len(command) > 1 and command[1].isdigit() else 0
if amount == 0:
await memgpt.interface.print_messages(memgpt_agent.messages, dump=True)
else:
await memgpt.interface.print_messages(memgpt_agent.messages[-min(amount, len(memgpt_agent.messages)) :], dump=True)
continue
elif user_input.lower() == "/dumpraw":
await memgpt.interface.print_messages_raw(memgpt_agent.messages)
continue
elif user_input.lower() == "/dump1":
await memgpt.interface.print_messages(memgpt_agent.messages[-1])
continue
elif user_input.lower() == "/memory":
print(f"\nDumping memory contents:\n")
print(f"{str(memgpt_agent.memory)}")
@@ -583,7 +586,7 @@ USER_COMMANDS = [
("/exit", "exit the CLI"),
("/save", "save a checkpoint of the current agent/conversation state"),
("/load", "load a saved checkpoint"),
("/dump", "view the current message log (see the contents of main context)"),
("/dump <count>", "view the last <count> messages (all if <count> is omitted)"),
("/memory", "print the current contents of agent memory"),
("/pop", "undo the last message in the conversation"),
("/heartbeat", "send a heartbeat system message to the agent"),

View File

@@ -40,6 +40,11 @@ def test_legacy_cli_sequence():
child.sendline("/load")
child.expect("Loaded persistence manager", timeout=TIMEOUT)
child.sendline("/dump") # just testing no-crash
# child.expect("", timeout=TIMEOUT)
child.sendline("/dump 3") # just testing no-crash
child.sendline("/exit")
child.expect("Finished.", timeout=TIMEOUT)