Skip to content

toadlyBroodle/engram

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 Engram

Engram - An RLM-style memory layer for AI conversations. The LLM actively queries its memory through tools, enabling iterative retrieval and reasoning over stored knowledge.

Engram Demo

An engram is the physical trace of a memory in the brain.

✨ Key Features

  • Active Memory Retrieval: LLM decides what to search, when to search, and can follow memory links
  • Tool-Based Access: Memory exposed as callable tools, not passive context injection
  • Iterative Reasoning: Multiple tool calls per turn enable building understanding
  • Semantic Search: FAISS-based vector storage with sentence transformer embeddings
  • Async Extraction: Background MemMan agent extracts new memories from conversations
  • Memory Reinforcement: Similar memories are reinforced, increasing importance over time
  • Local-First: All data stored locally, works offline after initial setup

πŸ”„ RLM vs Passive RAG

Old approach (Passive RAG):

user_message β†’ vector_search(message) β†’ inject top-5 β†’ LLM responds

New approach (RLM-style):

user_message β†’ LLM with tools β†’ LLM calls search_memory() β†’ gets results β†’
                              β†’ LLM calls get_related_memories() β†’ follows links β†’
                              β†’ LLM synthesizes and responds

The key difference: the LLM decides what to look up and can iteratively build understanding, rather than receiving a fixed context injection.

πŸ“¦ Installation

cd engram
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Set your API key:

export GEMINI_API_KEY=your-api-key
# Or place in .env file

πŸš€ Quick Start

Interactive Chat

python brain.py

With verbose mode to see tool calls:

python brain.py --verbose

CLI Commands

# Search memories
python brain.py --search "python patterns"

# Add a memory manually
python brain.py --add "Always use type hints in function signatures"

# Remove a memory by ID
python brain.py --remove abc123

# Show statistics
python brain.py --stats

In-Chat Commands

/help          Show available commands
/memories      Search your memories
/recent        Show recent memories
/stats         Show session statistics
/add <text>    Manually add a memory
/quit          Exit the chat

Memory Visualizer

Monitor memory state in real-time during conversations:

# In a separate terminal
python memory_visualizer.py

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     User Message                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MemoryAgent                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                    β”‚
β”‚  β”‚ 1. CALL LLM         β”‚ LLM receives message + tool access β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                    β”‚
β”‚            β”‚                                                β”‚
β”‚            β–Ό                                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ 2. TOOL CALLS       │───▢│ search_memory()          β”‚   β”‚
β”‚  β”‚    (iterative)      β”‚    β”‚ get_related_memories()   β”‚   β”‚
β”‚  β”‚                     │◀───│ get_recent_memories()    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚ store_memory()           β”‚   β”‚
β”‚            β”‚                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚            β–Ό                            β”‚                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚                   β”‚
β”‚  β”‚ 3. SYNTHESIZE       β”‚ LLM reasons    β”‚                   β”‚
β”‚  β”‚    RESPONSE         β”‚ over results   β”‚                   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β–Ό                   β”‚
β”‚                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚                              β”‚ VectorMemory (FAISS)     β”‚   β”‚
β”‚                              β”‚ Semantic storage         β”‚   β”‚
β”‚                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ 4. EXTRACT (async)  │───▢│ MemMan Agent (LLM)       β”‚   β”‚
β”‚  β”‚    Queue extraction β”‚    β”‚ Analyze & store memories β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Assistant Response                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components

Component File Purpose
MemoryAgent memory_agent.py RLM-style agent with tool-based memory access
MemoryTools memory_tools.py Tool definitions for memory operations
MemoryExtractor memory_extractor.py MemMan Agent - async LLM-powered memory extraction
VectorMemory engram_pkg/core.py FAISS vector storage and semantic search
MemoryVisualizer memory_visualizer.py Real-time CLI memory visualization

Memory Tools

The LLM has access to these tools:

Tool Description
search_memory(query, limit) Semantic search over all memories
get_related_memories(memory_id, limit) Follow memory links to related content
get_recent_memories(hours, limit) Get recently stored memories
store_memory(content, importance, tags) Store new information

πŸ€– MemMan Agent

The MemMan (Memory Manager) Agent is a background LLM-powered worker that intelligently manages memory extraction:

  • Async Processing: Runs in a separate thread, never blocking the main conversation
  • LLM Intelligence: Uses a fast/cheap model (Gemini Flash Lite) to analyze each exchange
  • Smart Filtering: Decides what's actually worth remembering vs. transient chatter
  • Memory Types: Extracts preferences, facts, decisions, and insights
  • Memory Reinforcement: When similar memories are detected, reinforces them

MemMan output appears in real-time during chat:

MemMan: πŸ’Ύ New (imp:0.70): User prefers dark mode in applications...
MemMan: πŸ”„ Reinforced (acc:3, imp:0.65β†’0.72): Working on ProjectX...

πŸ“Š Memory Schema

@dataclass
class MemoryEntry:
    id: str                    # Unique identifier
    content: str               # Memory content
    timestamp: datetime        # Creation time
    importance: float          # 0.0 to 1.0
    tags: List[str]           # Categorization tags
    context: Dict[str, Any]   # Additional metadata
    access_count: int         # Usage tracking
    last_accessed: datetime   # Last retrieval time
    related_memories: List[str]  # IDs of related memories
    embedding: List[float]    # Vector representation

πŸ”§ Configuration

Environment Variables

Variable Description Default
GEMINI_API_KEY Google Gemini API key Required

AgentConfig Options

from memory_agent import MemoryAgent, AgentConfig

config = AgentConfig(
    memory_path="vector_memory",        # Storage location
    model="gemini-2.0-flash",           # Main LLM model
    extraction_model="gemini-2.0-flash-lite",  # Extraction model
    max_tool_calls=10,                  # Max tool calls per turn
    extraction_enabled=True,            # Enable async extraction
    verbose=False                       # Show tool calls
)

agent = MemoryAgent(config=config)

πŸ“ Project Structure

engram/
β”œβ”€β”€ brain.py              # CLI chat interface
β”œβ”€β”€ memory_agent.py       # RLM-style agent with tool access
β”œβ”€β”€ memory_tools.py       # Memory tool definitions
β”œβ”€β”€ memory_extractor.py   # MemMan Agent - async LLM memory management
β”œβ”€β”€ memory_proxy.py       # Legacy passive proxy (deprecated)
β”œβ”€β”€ memory_integration.py # Memory integration layer
β”œβ”€β”€ memory_context.py     # Context-aware retrieval
β”œβ”€β”€ memory_visualizer.py  # Real-time memory TUI
β”œβ”€β”€ context_window_manager.py # Token management
β”œβ”€β”€ engram_pkg/           # Core package
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ core.py           # VectorMemory class
β”‚   β”œβ”€β”€ context.py
β”‚   β”œβ”€β”€ integration.py
β”‚   └── cli.py
β”œβ”€β”€ vector_memory/        # Data storage
β”‚   β”œβ”€β”€ metadata.pkl
β”‚   └── faiss_index.bin
└── requirements.txt

πŸ“ License

MIT License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages