Skip to content

Commit

Permalink
I made dump showing more message and added a count (the last x)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
oderwat committed Nov 1, 2023
1 parent 2df36ad commit 6184d3e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 27 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,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
Expand Down
72 changes: 54 additions & 18 deletions memgpt/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ async def memory_message(msg):
print(f"{Fore.LIGHTMAGENTA_EX}{Style.BRIGHT}🧠 {Fore.LIGHTMAGENTA_EX}{msg}{Style.RESET_ALL}")


async def system_message(msg):
printd(f"{Fore.MAGENTA}{Style.BRIGHT}🖥️ [system] {Fore.MAGENTA}{msg}{Style.RESET_ALL}")
async def system_message(msg, dump=False):
if DEBUG:
printd(f"{Fore.MAGENTA}{Style.BRIGHT}🖥️ [system] {Fore.MAGENTA}{msg}{Style.RESET_ALL}")
elif dump:
print(f"{Fore.MAGENTA}{Style.BRIGHT}🖥️ [system] {Fore.MAGENTA}{msg}{Style.RESET_ALL}")


async def user_message(msg, raw=False):
async def user_message(msg, raw=False, dump=False):
if isinstance(msg, str):
if raw:
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg}{Style.RESET_ALL}")
Expand All @@ -48,22 +51,30 @@ async def user_message(msg, raw=False):
printd(f"Warning: failed to parse user message into json")
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg}{Style.RESET_ALL}")
return

if msg_json["type"] == "user_message":
msg_json.pop("type")
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg_json}{Style.RESET_ALL}")
elif msg_json["type"] == "heartbeat":
else: # not what we thought it is
return
msg_type = msg_json["type"]
if msg_type == "user_message":
if dump:
message = msg_json.get("message")
print(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{message}{Style.RESET_ALL}")
else:
msg_json.pop("type")
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg_json}{Style.RESET_ALL}")
elif msg_type == "heartbeat":
if DEBUG:
msg_json.pop("type")
printd(f"{Fore.GREEN}{Style.BRIGHT}💓 {Fore.GREEN}{msg_json}{Style.RESET_ALL}")
elif msg_json["type"] == "system_message":
elif msg_type == "system_message":
msg_json.pop("type")
printd(f"{Fore.GREEN}{Style.BRIGHT}🖥️ {Fore.GREEN}{msg_json}{Style.RESET_ALL}")
elif msg_type == "login":
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg_json}{Style.RESET_ALL}")
else:
printd(f"{Fore.GREEN}{Style.BRIGHT}🧑 {Fore.GREEN}{msg_json}{Style.RESET_ALL}")


async def function_message(msg):
async def function_message(msg, dump=False):
if isinstance(msg, dict):
printd(f"{Fore.RED}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
return
Expand Down Expand Up @@ -106,32 +117,57 @@ async def function_message(msg):
try:
msg_dict = json.loads(msg)
if "status" in msg_dict and msg_dict["status"] == "OK":
printd(f"{Fore.GREEN}{Style.BRIGHT}⚡ [function] {Fore.GREEN}{msg}{Style.RESET_ALL}")
if dump:
print(f"{Fore.GREEN}{Style.BRIGHT}{Fore.GREEN}OK{Style.RESET_ALL}")
else:
printd(f"{Fore.GREEN}{Style.BRIGHT}⚡ [function] {Fore.GREEN}{msg}{Style.RESET_ALL}")
elif "status" in msg_dict and msg_dict["status"] != "OK":
if dump:
status = msg_dict["status"]
print(f"{Fore.GREEN}{Style.BRIGHT}{Fore.RED}{status}{Style.RESET_ALL}")
else:
printd(f"{Fore.GREEN}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
else:
if dump:
printd(f"{Fore.GREEN}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
else:
printd(f"{Fore.GREEN}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
except Exception:
printd(f"Warning: did not recognize function message {type(msg)} {msg}")
printd(f"{Fore.RED}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
if dump:
printd(f"Warning: did not recognize function message {type(msg)} {msg}")
printd(f"{Fore.RED}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")
else:
print(f"Warning: did not recognize function message {type(msg)} {msg}")
print(f"{Fore.RED}{Style.BRIGHT}⚡ [function] {Fore.RED}{msg}{Style.RESET_ALL}")


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"]

if role == "system":
await system_message(content)
await system_message(content, dump=dump)
elif role == "assistant":
# Differentiate between internal monologue, function calls, and messages
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, dump=dump)
elif role == "function":
await function_message(content)
await function_message(content, dump=dump)
else:
print(f"Unknown role: {content}")

Expand Down
17 changes: 10 additions & 7 deletions memgpt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from rich.console import Console
from prettytable import PrettyTable
from .interface import print_messages

console = Console()

Expand Down Expand Up @@ -446,18 +447,20 @@ async def run_agent_loop(memgpt_agent, first, no_verify=False, cfg=None, legacy=
load(memgpt_agent=memgpt_agent, filename=filename)
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 print_messages(memgpt_agent.messages, dump=True)
else:
await 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)}")
Expand Down Expand Up @@ -553,7 +556,7 @@ async def run_agent_loop(memgpt_agent, first, no_verify=False, cfg=None, legacy=
("/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"),
Expand Down

0 comments on commit 6184d3e

Please sign in to comment.