| | """ |
| | OmniCoreX Memory Manager |
| | |
| | Advanced memory and context management utility to handle short-term and long-term knowledge retention, |
| | supporting adaptive reasoning and continual learning within the OmniCoreX AI system. |
| | |
| | Features: |
| | - Dual memory layers: short-term working memory and long-term persistent memory. |
| | - Efficient retrieval with similarity search (vector-based) for context relevance. |
| | - Context window management for input conditioning. |
| | - Supports updating, forgetting, and pruning memory entries. |
| | - Interfaces for integration with external vector stores or databases. |
| | """ |
| |
|
| | import time |
| | from typing import Any, Dict, List, Optional, Tuple |
| | import numpy as np |
| | from collections import deque |
| | from threading import RLock |
| |
|
| | class MemoryEntry: |
| | """ |
| | Represents a single memory record with timestamp, content and optional embedding vector. |
| | """ |
| | def __init__(self, content: Any, embedding: Optional[np.ndarray] = None): |
| | self.content = content |
| | self.embedding = embedding |
| | self.timestamp = time.time() |
| |
|
| | def __repr__(self): |
| | return f"MemoryEntry timestamp={self.timestamp} content={self.content}>" |
| |
|
| | class ShortTermMemory: |
| | """ |
| | Short-term working memory implemented as a fixed-size deque for recent context. |
| | """ |
| | def __init__(self, max_size: int = 50): |
| | self.max_size = max_size |
| | self.memory = deque(maxlen=max_size) |
| | self.lock = RLock() |
| |
|
| | def add(self, content: Any, embedding: Optional[np.ndarray] = None): |
| | with self.lock: |
| | entry = MemoryEntry(content, embedding) |
| | self.memory.append(entry) |
| |
|
| | def get_recent(self, n: Optional[int] = None) -> List[MemoryEntry]: |
| | with self.lock: |
| | if n is None or n > len(self.memory): |
| | return list(self.memory) |
| | else: |
| | return list(self.memory)[-n:] |
| |
|
| | def clear(self): |
| | with self.lock: |
| | self.memory.clear() |
| |
|
| | class LongTermMemory: |
| | """ |
| | Long-term memory stores past knowledge persistently. |
| | This simple implementation stores entries with embeddings for similarity search. |
| | """ |
| |
|
| | def __init__(self): |
| | self.entries: List[MemoryEntry] = [] |
| | self.lock = RLock() |
| |
|
| | def add(self, content: Any, embedding: Optional[np.ndarray] = None): |
| | with self.lock: |
| | entry = MemoryEntry(content, embedding) |
| | self.entries.append(entry) |
| |
|
| | def retrieve_similar(self, query_embedding: np.ndarray, top_k: int = 5) -> List[MemoryEntry]: |
| | """ |
| | Retrieve top-k memory entries most similar to the query embedding using cosine similarity. |
| | |
| | Args: |
| | query_embedding: numpy array vector. |
| | top_k: Number of top similar entries to return. |
| | |
| | Returns: |
| | List of MemoryEntry objects. |
| | """ |
| | with self.lock: |
| | if not self.entries or query_embedding is None: |
| | return [] |
| |
|
| | embeddings = np.array([e.embedding for e in self.entries if e.embedding is not None]) |
| | if embeddings.size == 0: |
| | return [] |
| |
|
| | |
| | norm_embeddings = embeddings / np.linalg.norm(embeddings, axis=1, keepdims=True) |
| | norm_query = query_embedding / np.linalg.norm(query_embedding) |
| |
|
| | |
| | similarities = np.dot(norm_embeddings, norm_query) |
| | top_indices = similarities.argsort()[-top_k:][::-1] |
| |
|
| | return [self.entries[i] for i in top_indices] |
| |
|
| | def prune_older_than(self, max_age_seconds: float): |
| | """ |
| | Remove entries older than max_age_seconds from now. |
| | |
| | Args: |
| | max_age_seconds: Maximum age to keep entries. |
| | """ |
| | current_time = time.time() |
| | with self.lock: |
| | self.entries = [e for e in self.entries if current_time - e.timestamp = max_age_seconds] |
| |
|
| | def clear(self): |
| | with self.lock: |
| | self.entries.clear() |
| |
|
| |
|
| | class MemoryManager: |
| | """ |
| | Combined manager providing unified interface over short-term and long-term memory. |
| | |
| | Supports addition, retrieval, context building, and pruning. |
| | """ |
| |
|
| | def __init__(self, |
| | short_term_size: int = 50, |
| | long_term_prune_age: float = 60 * 60 * 24 * 7, |
| | embedding_function: Optional[Callable[[Any], np.ndarray]] = None): |
| | """ |
| | Initialize MemoryManager. |
| | |
| | Args: |
| | short_term_size: Max entries in short-term memory. |
| | long_term_prune_age: Max age for pruning long-term memory in seconds. |
| | embedding_function: Callable converting text/content to vector embeddings. |
| | """ |
| | self.short_term = ShortTermMemory(max_size=short_term_size) |
| | self.long_term = LongTermMemory() |
| | self.prune_age = long_term_prune_age |
| | self.embedding_function = embedding_function |
| |
|
| | def add_memory(self, content: Any): |
| | """ |
| | Add a memory record to short-term and long-term memory with embedding. |
| | |
| | Args: |
| | content: Content string or data representing memory. |
| | """ |
| | embedding = None |
| | if self.embedding_function is not None: |
| | try: |
| | embedding = self.embedding_function(content) |
| | except Exception as e: |
| | embedding = None |
| |
|
| | self.short_term.add(content, embedding) |
| | self.long_term.add(content, embedding) |
| |
|
| | def get_recent(self, n: Optional[int] = None) -> List[Any]: |
| | """ |
| | Retrieves recent content entries from short-term memory. |
| | |
| | Args: |
| | n: Number of recent entries to retrieve. |
| | |
| | Returns: |
| | List of content objects. |
| | """ |
| | entries = self.short_term.get_recent(n) |
| | return [e.content for e in entries] |
| |
|
| | def retrieve_similar(self, query_content: Any, top_k: int = 5) -> List[Any]: |
| | """ |
| | Retrieve top-k long term similar memories based on query content. |
| | |
| | Args: |
| | query_content: Query string or data. |
| | top_k: Number of matches to retrieve. |
| | |
| | Returns: |
| | List of content objects. |
| | """ |
| | if self.embedding_function is None: |
| | return [] |
| |
|
| | try: |
| | query_emb = self.embedding_function(query_content) |
| | except Exception: |
| | return [] |
| |
|
| | top_entries = self.long_term.retrieve_similar(query_emb, top_k) |
| | return [e.content for e in top_entries] |
| |
|
| | def prune_long_term(self): |
| | """ |
| | Prune old entries from long-term memory. |
| | """ |
| | self.long_term.prune_older_than(self.prune_age) |
| |
|
| | def clear_all(self): |
| | """ |
| | Clear both short-term and long-term memories. |
| | """ |
| | self.short_term.clear() |
| | self.long_term.clear() |
| |
|
| |
|
| | if __name__ == "__main__": |
| | |
| |
|
| | def dummy_embedding_func(text: str) -> np.ndarray: |
| | |
| | vec = np.array([ord(c) for c in text], dtype=np.float32) |
| | if vec.size == 0: |
| | return np.zeros(10) |
| | vec = vec / (np.linalg.norm(vec) + 1e-9) |
| | |
| | if vec.size 10: |
| | vec = np.pad(vec, (0, 10 - vec.size)) |
| | else: |
| | vec = vec[:10] |
| | return vec |
| |
|
| | mem_manager = MemoryManager(short_term_size=5, long_term_prune_age=60*60*24*30, embedding_function=dummy_embedding_func) |
| |
|
| | print("Adding memories...") |
| | mem_manager.add_memory("Learned about AI models.") |
| | mem_manager.add_memory("OmniCoreX is powerful.") |
| | mem_manager.add_memory("Recall adaptive reasoning.") |
| | mem_manager.add_memory("Real-time decision making enabled.") |
| | mem_manager.add_memory("Deep multi-modal integration.") |
| |
|
| | print("Recent memories:") |
| | for mem in mem_manager.get_recent(): |
| | print("-", mem) |
| |
|
| | print("Retrieving similar memories for query 'adaptive AI':") |
| | similars = mem_manager.retrieve_similar("adaptive AI", top_k=3) |
| | for s in similars: |
| | print("*", s) |
| |
|
| | print("Pruning memories older than prune age...") |
| | mem_manager.prune_long_term() |
| | print("Memory manager demo completed.") |
| |
|