We have this memory module from a separate code base, what we need to adapt is the mechanism to consolidate memories and how we generate a summary.  

Right now we have two systems,  generate summary right now is only generating a "summary" of the user exchanges, but we need to make a summary for short memories and recent actions and append those into long term memories. 

This summary needs to be generated with an OpenAI API call with the data we want to summarize, and we need to be sure we manage the structures of these new summaries so they fit correctly in the current code base, so making sure the outputs are the same structure they already have. 

Here is how you call openAI API 


from openai import OpenAI
client = OpenAI()

completion = client.chat.completions.create(
  model="gpt-4o",
  messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello!"}
  ]
)

print(completion.choices[0].message)



here is part of our codebase for the memory manager:


# memory.py Autonomous AI 
# 
# TODO: Implement memory consolidation with OpenAI LLM

import json
from collections import deque
from datetime import datetime, timedelta
import os
import logging

logger = logging.getLogger(__name__)

class MemoryManager:
    def __init__(self, notes_db_path="notes/notes_db.json"):
        self.recent_actions = deque(maxlen=9)       # Stores the 50 most recent actions
        self.short_term_memory = deque(maxlen=15)   # Stores the 100 most recent actions
        self.long_term_memory = []                    # Stores consolidated memories
        self.exchanges = deque(maxlen=20)             # Stores the last 20 user-AI exchanges
        self.total_time_spent = timedelta()
        self.last_consolidation = datetime.now()
        self.current_room = "kitchen"                 # Initialize starting room
        self.notes_db_path = notes_db_path

        # Initialize notes database if it doesn't exist
        if not os.path.isfile(self.notes_db_path):
            with open(self.notes_db_path, 'w') as f:
                json.dump({"notes": []}, f, indent=4)
            logger.info(f"Notes database created at {self.notes_db_path}")
            print(f"Notes database created at {self.notes_db_path}")  # Optional

    def add_exchange(self, role: str, content: str):
        """
        Adds a user or assistant exchange to the exchanges deque.
        Compresses exchanges into a summary when the limit is reached.
        """
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        exchange_entry = {
            "timestamp": timestamp,
            "role": role,
            "content": content
        }
        self.exchanges.append(exchange_entry)
        self.recent_actions.append(f"[{timestamp}] {role.capitalize()}: {content}")
        self.short_term_memory.append(f"[{timestamp}] {role.capitalize()}: {content}")

        if len(self.exchanges) == self.exchanges.maxlen:
            self.compress_exchanges()

    def compress_exchanges(self):
        """
        Compresses the last 20 exchanges into a summary and appends it to long-term memory.
        """
        summary = self.generate_summary(list(self.exchanges))
        consolidated_summary = f"Compressed Exchanges Summary:\n{summary}"
        self.long_term_memory.append(consolidated_summary)
        logger.info("Compressed the last 20 exchanges into a summary.")
        print(f"Compressed Exchanges Summary: {summary}")  # Optional: Print summary

        # Clear the exchanges deque after compression
        self.exchanges.clear()

    def generate_summary(self, exchanges):
        """
        Generates a summary from the list of exchanges.
        For simplicity, concatenates the exchanges.
        """
        summary_lines = [f"[{ex['timestamp']}] {ex['role'].capitalize()}: {ex['content']}" for ex in exchanges]
        summary = " | ".join(summary_lines)
        return summary

    def add_action(self, action: str):
        """
        Adds an action to recent actions and short-term memory.
        """
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        action_entry = f"[{timestamp}] {action}"
        self.recent_actions.append(action_entry)
        self.short_term_memory.append(action_entry)
        logger.info(f"Action added: {action_entry}")
        print(f"Action added: {action_entry}")  # Optional: Print action

    def sleep_action(self, duration_hours: int):
        """
        Handles the sleep action by updating time spent and memory.
        """
        self.total_time_spent += timedelta(hours=duration_hours)
        summary = f"Slept for {duration_hours} hours."
        self.add_action(summary)

    def move_action(self, to_room: str):
        """
        Handles the move action by updating the current room and memory.
        """
        from_room = self.current_room
        self.current_room = to_room
        action = f"Moved from {from_room} to {to_room}."
        self.add_action(action)

    def take_note_action(self, content: str):
        """
        Handles taking a note by adding it to memory and saving to the JSON database.
        """
        action = f"Took a note: {content}"
        self.add_action(action)
        self.save_note(content)

    def save_note(self, content: str):
        """
        Saves a note to the JSON database.
        """
        try:
            with open(self.notes_db_path, 'r+') as f:
                data = json.load(f)
                data['notes'].append({
                    "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "content": content
                })
                f.seek(0)
                json.dump(data, f, indent=4)
            logger.info(f"Note saved: {content}")
            print(f"Note saved: {content}")  # Optional: Print note saving
        except Exception as e:
            logger.error(f"Failed to save note: {e}")
            print(f"Failed to save note: {e}")  # Optional: Print error

    def consolidate_memories(self):
        """
        Consolidates short-term memory into long-term memory periodically.
        """
        now = datetime.now()
        if now - self.last_consolidation > timedelta(hours=24):  # Consolidate every 24 hours
            if self.short_term_memory:
                consolidated_summary = "Consolidated Summary:\n"
                consolidated_summary += "\n".join(list(self.short_term_memory))
                self.long_term_memory.append(consolidated_summary)
                self.short_term_memory.clear()
                self.last_consolidation = now
                self.add_action("Memories have been consolidated into long-term memory.")
                logger.info("Short-term memory consolidated into long-term memory.")
                print("Short-term memory consolidated into long-term memory.")  # Optional: Print consolidation

    def get_memory(self) -> str:
        """
        Returns a string representation of the memory including long-term and short-term memories,
        exchanges summary, and recent actions.
        """
        self.consolidate_memories()
        memory = ""
        if self.long_term_memory:
            memory += "Long-Term Memory:\n"
            memory += "\n".join(self.long_term_memory)
            memory += "\n\n"
        memory += "Short-Term Memory:\n"
        memory += "\n".join(self.short_term_memory)
        memory += "\n\n"
        if self.exchanges:
            memory += "\n".join([f"[{ex['timestamp']}] {ex['role'].capitalize()}: {ex['content']}" for ex in self.exchanges])
        memory += f"\n\nCurrent Location: {self.current_room.capitalize()}"
        memory += "Recent Exchanges:\n"
        return memory