| | import time
|
| | from typing import Dict, List, Any, Optional, Union
|
| |
|
| | class MemoryManager:
|
| | """Memory management for the autonomous AI agent
|
| |
|
| | This module provides capabilities for:
|
| | 1. Storing and retrieving conversation history
|
| | 2. Managing context windows
|
| | 3. Implementing forgetting mechanisms
|
| | 4. Prioritizing important information
|
| | """
|
| |
|
| | def __init__(self, max_history_length: int = 20):
|
| | """Initialize the memory manager
|
| |
|
| | Args:
|
| | max_history_length: Maximum number of conversation turns to store
|
| | """
|
| | self.conversation_history = []
|
| | self.max_history_length = max_history_length
|
| | self.important_facts = []
|
| | self.max_facts = 50
|
| | self.session_data = {}
|
| |
|
| | def add_message(self, role: str, content: str) -> None:
|
| | """Add a message to the conversation history
|
| |
|
| | Args:
|
| | role: The role of the message sender (user or assistant)
|
| | content: The content of the message
|
| | """
|
| | self.conversation_history.append({
|
| | "role": role,
|
| | "content": content,
|
| | "timestamp": time.time()
|
| | })
|
| |
|
| |
|
| | if len(self.conversation_history) > self.max_history_length * 2:
|
| | self.conversation_history = self.conversation_history[-self.max_history_length*2:]
|
| |
|
| | def get_conversation_history(self, max_turns: Optional[int] = None) -> List[Dict[str, Any]]:
|
| | """Get the conversation history
|
| |
|
| | Args:
|
| | max_turns: Maximum number of turns to retrieve (None for all)
|
| |
|
| | Returns:
|
| | List of conversation messages
|
| | """
|
| | if max_turns is None:
|
| | return self.conversation_history
|
| | else:
|
| |
|
| | max_messages = max_turns * 2
|
| | return self.conversation_history[-max_messages:]
|
| |
|
| | def format_conversation_for_prompt(self, max_turns: Optional[int] = None) -> str:
|
| | """Format the conversation history for inclusion in a prompt
|
| |
|
| | Args:
|
| | max_turns: Maximum number of turns to include
|
| |
|
| | Returns:
|
| | Formatted conversation string
|
| | """
|
| | history = self.get_conversation_history(max_turns)
|
| | formatted = ""
|
| |
|
| | for msg in history:
|
| | formatted += f"{msg['role']}: {msg['content']}\n"
|
| |
|
| | return formatted
|
| |
|
| | def add_important_fact(self, fact: str, source: str) -> None:
|
| | """Add an important fact to memory
|
| |
|
| | Args:
|
| | fact: The important fact to remember
|
| | source: The source of the fact (e.g., user, inference)
|
| | """
|
| | self.important_facts.append({
|
| | "fact": fact,
|
| | "source": source,
|
| | "timestamp": time.time()
|
| | })
|
| |
|
| |
|
| | if len(self.important_facts) > self.max_facts:
|
| | self.important_facts = self.important_facts[-self.max_facts:]
|
| |
|
| | def get_important_facts(self) -> List[Dict[str, Any]]:
|
| | """Get the list of important facts
|
| |
|
| | Returns:
|
| | List of important facts
|
| | """
|
| | return self.important_facts
|
| |
|
| | def format_facts_for_prompt(self) -> str:
|
| | """Format important facts for inclusion in a prompt
|
| |
|
| | Returns:
|
| | Formatted facts string
|
| | """
|
| | if not self.important_facts:
|
| | return ""
|
| |
|
| | formatted = "Important information I know about the user and context:\n"
|
| |
|
| |
|
| | sorted_facts = sorted(self.important_facts, key=lambda x: x.get('timestamp', 0), reverse=True)
|
| |
|
| |
|
| | user_facts = [fact for fact in sorted_facts if fact.get('source') == 'user']
|
| | inference_facts = [fact for fact in sorted_facts if fact.get('source') == 'inference']
|
| |
|
| |
|
| | for i, fact in enumerate(user_facts):
|
| | formatted += f"{i+1}. {fact['fact']} (from user)\n"
|
| |
|
| |
|
| | start_idx = len(user_facts) + 1
|
| | for i, fact in enumerate(inference_facts):
|
| | formatted += f"{start_idx + i}. {fact['fact']} (inferred)\n"
|
| |
|
| | return formatted
|
| |
|
| | def store_session_data(self, key: str, value: Any) -> None:
|
| | """Store data for the current session
|
| |
|
| | Args:
|
| | key: The key to store the data under
|
| | value: The data to store
|
| | """
|
| | self.session_data[key] = {
|
| | "value": value,
|
| | "timestamp": time.time()
|
| | }
|
| |
|
| | def get_session_data(self, key: str) -> Optional[Any]:
|
| | """Retrieve data from the current session
|
| |
|
| | Args:
|
| | key: The key to retrieve data for
|
| |
|
| | Returns:
|
| | The stored data, or None if not found
|
| | """
|
| | if key in self.session_data:
|
| | return self.session_data[key]["value"]
|
| | else:
|
| | return None
|
| |
|
| | def clear_conversation_history(self) -> None:
|
| | """Clear the conversation history"""
|
| | self.conversation_history = []
|
| |
|
| | def clear_all_memory(self) -> None:
|
| | """Clear all memory (conversation history, facts, and session data)"""
|
| | self.conversation_history = []
|
| | self.important_facts = []
|
| | self.session_data = {}
|
| |
|
| | def get_memory_stats(self) -> Dict[str, Any]:
|
| | """Get statistics about the agent's memory usage
|
| |
|
| | Returns:
|
| | Dictionary containing memory statistics
|
| | """
|
| | return {
|
| | "conversation_turns": len(self.conversation_history) // 2,
|
| | "important_facts": len(self.important_facts),
|
| | "session_data_keys": list(self.session_data.keys()),
|
| | "memory_usage": {
|
| | "conversation": len(str(self.conversation_history)),
|
| | "facts": len(str(self.important_facts)),
|
| | "session": len(str(self.session_data))
|
| | }
|
| | } |