Skip to content

4.0 Memory Management Module

Lumi Bunny edited this page Aug 12, 2025 · 1 revision

This module implements a MemoryManager system that stores and retrieves user data in an organized file structure. It's the "brain" of the chatbot that remembers everything about each user: their preferences, conversations, reminders, important memories, etc.

Overview of memory_manager.py

This memory management system provides the chatbot with persistent and organized memory structures. It's like giving BunnyBot a proper brain that remembers and learns from every interaction.

The key features of this memory management module are:

Organized Storage

  • Each user gets their own folder and data
  • Clear separation of different data types
  • Easy to backup/migrate individual users

Flexible Querying

  • Filter memories by importance, category, or time
  • Search memories by keywords
  • Get additional context relevant to the current conversation

Scalable

  • File-based: No database and vector store setup needed
  • JSON format: Text files are easier to read for humans than databases with vector embeddings, easily debuggable
  • Modular design: Easy to extend with other functions and modules as they are integrated into the app

1. Imports and Setup

This module uses a couple of libraries:

  • json: For saving/loading data files.
  • datetime: For timestamps and time-based filtering.
  • pathlib: For clean file path handling.
  • dataclasses: For structured data.
  • PreferenceResult: Imports from preferences import PreferenceResult

2. MemoryEntry Class

Individual Memory Storage

@dataclass
class MemoryEntry:
    content: str             # What happened/was said
    timestamp: datetime      # When it happened
    importance: float        # How important (0.0-1.0)
    category: str            # Type: conversation, fact, preference, etc.
    tags: List[str]          # Keywords for searching
    context: Optional[str]   # Additional context

Key Methods:

  • to_dict(): Converts to dictionary for JSON saving.
  • from_dict(): Creates MemoryEntry from loaded JSON data.

This is a clean way to handle JSON serialization and is an easier setup than vector stores.

3. MemoryManager Class

The Main System

This class manages ALL user data using a clean and organized file structure.

The file structure it creates:

user_data/
├── {user_id}/
│   ├── profile/
│   │   ├── personal_info.json        # Basic user info
│   │   ├── preferences.json          # Likes/dislikes from PreferenceExtractor
│   │   └── important_memories.json   # Key memories
│   ├── conversations/
│   │   ├── summaries/                # Daily conversation summaries
│   │   └── raw_chats/                # Full chat logs
│   └── agent_data/
│       ├── reminders.json            # User reminders
│       ├── notes.json                # Agent notes
│       └── mood_tracking.json        # Mood patterns

4. Core Methods and Breakdown

Setup & Utility Methods

init()

  • Sets up base directory(user_data/ by default)
  • Creates the folder if it does not exist

_ensure_user_structure()

  • Creates all necessary folders for a user
  • Initializes with default JSON files with empty structures (ready for use)
  • Smart default structure: Creates preference categories upon setup (food, games, activities, etc)

_save_json() & _load_json()

  • Safe JSON file operations with error handling
  • UTF-8 encoding for international characters

Preference Management

save_preferences()

  • Takes PreferenceResult objects from the PreferenceExtractor
  • Organizes them by category and type
  • Avoids duplicates: Won't add "pizza" twice to "food/likes"
  • Example: Saves "I love pizza" as food.loves = ["pizza"]

get_preferences()

  • Retrieves user preferences
  • Can filter by category: get_preferences(user_id, "food")
  • Returns structured data: {"likes": [...], "dislikes": [...], "loves": [...], "hates": [...]}

Memory Management

add_memory()

  • Stores important events/facts about the user
  • Parameters:
    • content: What to remember
    • category: Type of memory (conversation, fact, etc.)
    • importance: A score of 0.0-1.0
    • tags: Keywords for later searching
    • context: Additional details

get_memories()

  • Retrieves memories with powerful filtering:
    • By category: Only "conversation memories
    • By importance: Only memories above 0.6 importance
    • By time: Only from the last 7 days (can be modified based on usage needs)
  • Sorts by: Importance + recency (most important recent memories first)

Conversation Management

save_conversation_summary()

  • Saves daily conversation summaries
  • Stores: Summary text, main topics discussed, date
  • File naming: 2025-08-09_summary.json

get_recent_summaries()

  • Gets conversation summaries from the last N days
  • Sorted by date (newest first)

Agent Data Management

add_reminder() & get_reminders()

  • Reminders system: "Remind me to call mom tomorrow"
  • Features: Due dates, priority levels, completion tracking
  • Filtering: Can exclude completed reminders

Advanced Features

find_relevant_memories()

  • Keyword-based search (no complex functions or AI needed)
  • Scoring system:
    • Content word matches: +1 point each
    • Tag word matches: +2 points each (tags are more important)
    • Base importance score: +importance value
  • Returns: Top 5 most relevant memories

get_context_for_conversation()

  • The key method for the chatbot conversations!
  • Returns comprehensive context:
    • Recent important memories (last 7 days, importance 0.6)
    • Relevant preferences for current topic
    • Active reminders
    • Conversation patterns

get_user_stats()

  • Dashboard data: How much data exists for each user
  • Counts: Total preferences, memories, reminders, conversation summaries

5. How MemoryManager Integrates with PreferenceExtractor

Here's the beautiful integration:

  1. User says: "I love pizza but I hate olives"
  2. PreferenceExtractor creates: 2 PreferenceResult objects
  3. MemoryManager.save_preferences() stores them as:
{
  "food": {
    "loves": ["pizza"],
    "hates": ["olives"]
  }
}
  1. Later conversations can be retrieved via `get_preferences("food")

6. Example Usage Flow

# Initialize
memory_manager = MemoryManager()

# After preference extraction
preferences = preference_extractor.extract_preferences("I love pizza", "user123")
memory_manager.save_preferences("user123", preferences)

# During conversation
context = memory_manager.get_context_for_conversation("user123", "food")
# Returns: recent memories, food preferences, active reminders

# Add important memory
memory_manager.add_memory(
    "user123", 
    "User mentioned they're vegetarian", 
    "fact", 
    importance=0.8,
    tags=["diet", "vegetarian"]
)

7. Future Updates to MemoryManager:

  1. Addition of more categories to the agent_data folder (as needed)
  2. Connecting this module with the LLM chat via bunnyChat.py
  3. Possible use cases for conversation summaries for future chats between the same user and BunnyBot

8. Why Importance Scores Matter

The importance scoring system (0.0-1.0) is crucial for intelligent memory prioritization and efficient retrieval.

Importance Score Guidelines:

  • 0.9-1.0: Critical life events, emergencies, major decisions
  • 0.7-0.8: Important facts, strong preferences, significant conversations
  • 0.5-0.6: Regular conversation topics, moderate preferences
  • 0.3-0.4: Minor mentions, casual topics
  • 0.1-0.2: Background noise, very casual remarks

How Scores Are Used:

  • Memory retrieval: get_memories() can filter by minimum importance (default 0.6 for conversations)
  • Search ranking: find_relevant_memories() adds importance to keyword match scores
  • Context generation: get_context_for_conversation() prioritizes high-importance memories
  • Storage efficiency: Future cleanup can remove low-importance old memories

Example Importance Scoring:

# High importance (0.8)
"User mentioned they're getting married next month"

# Medium importance (0.6) 
"User said they love Italian food"

# Low importance (0.3)
"User mentioned the weather is nice today"

9. Tag Strategy Best Practices

Tags are the key to effective memory search - they act as keywords that make memories discoverable later.

Effective Tagging Principles:

  • Be specific: Use ["vegetarian", "diet"] not just ["food"]
  • Include synonyms: ["gaming", "video games", "entertainment"]
  • Add context: ["work", "stress", "deadline"] for work-related concerns
  • Use categories: ["health", "appointment", "dentist"] for medical topics

Tag Categories to Consider:

  • Topics: food, games, work, family, health, travel
  • Emotions: happy, stressed, excited, worried, frustrated
  • Actions: appointment, reminder, goal, decision, plan
  • People: mom, friend, coworker, doctor (if mentioned)
  • Time: urgent, future, recurring, deadline

How Tags Enhance Search:

# Memory with good tags:
memory_manager.add_memory(
    "user123",
    "User is stressed about job interview tomorrow",
    "conversation", 
    importance=0.7,
    tags=["work", "interview", "stress", "tomorrow", "career"]
)

# Later search: "work stress" finds this memory easily
# Tag matches get 2x weight in scoring algorithm

10. Memory Decay and Cleanup System

The MemoryManager includes intelligent cleanup to prevent data bloat while preserving important information.

Automatic Cleanup Features:

  • cleanup_old_data() removes old conversation files (default: 90 days)
  • Preserves important memories regardless of age
  • Keeps high-importance conversation summaries
  • Removes raw chat logs but maintains summaries

What Gets Cleaned vs. Preserved:

Cleaned Up:

  • Raw chat files older than 90 days
  • Low-importance conversation summaries
  • Temporary conversation data

Always Preserved:

  • All entries in important_memories.json
  • User preferences (never expire)
  • Active reminders
  • High-importance conversation summaries

Manual Cleanup Control:

# Clean data older than 30 days instead of default 90
cleanup_stats = memory_manager.cleanup_old_data("user123", days_to_keep=30)
# Returns: {"summaries_removed": 5, "raw_chats_removed": 12}

Memory Decay Philosophy:

  • Conversations fade - daily chats become less relevant over time
  • Facts persist - important user information never expires
  • Preferences evolve - but old preferences aren't deleted, just updated
  • Context matters - recent memories get priority in conversation context

11. Module Dependencies and Integration

The MemoryManager is the central hub that connects multiple system components:

Modules That Depend on MemoryManager:

1. BunnyChat (Main Chat System)

  • Imports: from memory import MemoryManager
  • Uses: Context-aware responses, conversation summaries, user stats
  • Integration: Initializes MemoryManager in __init__(), calls get_context_for_conversation() for enhanced responses

2. PreferenceExtractor

  • Relationship: Provides PreferenceResult objects to MemoryManager
  • Integration: save_preferences() stores extracted preferences by category
  • Data flow: User input → PreferenceExtractor → MemoryManager → Persistent storage

3. InterestTracker

  • Imports: Receives MemoryManager instance in constructor
  • Uses: add_memory() to store interest observations as memories
  • Integration: Tracks conversation topics and stores them for long-term analysis

4. Flask Web App (app.py)

  • Imports: from bunnyChat import BunnyChat (which includes MemoryManager)
  • Uses: Web interface for chat interactions with memory-aware responses

Data Flow Architecture:

User Input → BunnyChat → PreferenceExtractor → MemoryManager
                    ↓         ↓                      ↓
                InterestTracker → MemoryManager → File Storage
                                      ↓
                              Context for LLM Response

Integration Points:

  • Initialization: All modules receive MemoryManager instance
  • Data storage: Preferences, interests, and memories all flow through MemoryManager
  • Context retrieval: Chat system pulls user context for personalized responses
  • Statistics: Web interface can display user memory stats via get_user_stats()

Future Integration Opportunities:

  • Mood tracking: Could integrate with mood detection modules
  • Thinking module: Could store internal thoughts and reasoning chains
  • Voice interface: STT/TTS modules could benefit from user preference context

Clone this wiki locally