This document provides comprehensive API documentation for all public interfaces in the Universal Memory Layer.
- ConversationManager
- MemoryStore
- Data Models
- Configuration
- LLM Clients
- Embedding Providers
- Error Handling
The main orchestration class for managing LLM interactions with memory.
Location: universal_memory_layer.conversation_manager
ConversationManager(config: Optional[MemoryConfig] = None)Parameters:
config(Optional[MemoryConfig]): Memory configuration. If None, uses default configuration.
Example:
from universal_memory_layer.conversation_manager import ConversationManager
from universal_memory_layer.models.config import MemoryConfig
# With default configuration
manager = ConversationManager()
# With custom configuration
config = MemoryConfig(database_path="./custom.db")
manager = ConversationManager(config)Initialize the conversation manager and memory store. Must be called before using other methods.
Raises:
ConversationManagerError: If initialization fails
Example:
manager = ConversationManager()
manager.initialize()chat(message: str, model: Optional[str] = None, use_memory: bool = True, context_strategy: Union[str, ContextStrategy] = ContextStrategy.RECENT, context_count: Optional[int] = None, store_interaction: bool = True) -> str
Main chat method that coordinates LLM clients and memory.
Parameters:
message(str): User message to send to the LLMmodel(Optional[str]): Model to use. If None, uses current modeluse_memory(bool): Whether to retrieve and use context from memorycontext_strategy(Union[str, ContextStrategy]): Strategy for context retrieval ('recent', 'relevant', 'hybrid')context_count(Optional[int]): Number of context messages to retrievestore_interaction(bool): Whether to store this interaction in memory
Returns:
str: LLM response
Raises:
ConversationManagerError: If chat operation fails
Example:
# Basic chat
response = manager.chat("Hello, how are you?")
# Chat with specific model and context strategy
response = manager.chat(
"Tell me about machine learning",
model="chatgpt",
context_strategy="relevant",
context_count=5
)
# Chat without storing interaction
response = manager.chat(
"What's the weather?",
store_interaction=False
)get_context(query: str, strategy: Union[str, ContextStrategy] = ContextStrategy.RECENT, k: Optional[int] = None, recent_count: Optional[int] = None, relevant_count: Optional[int] = None) -> List[Message]
Retrieve context messages using specified strategy.
Parameters:
query(str): Query text for relevant context retrievalstrategy(Union[str, ContextStrategy]): Context retrieval strategyk(Optional[int]): Number of messages to retrieve (overrides strategy-specific counts)recent_count(Optional[int]): Number of recent messages for recent/hybrid strategiesrelevant_count(Optional[int]): Number of relevant messages for relevant/hybrid strategies
Returns:
List[Message]: List of Message objects ordered appropriately for the strategy
Raises:
ConversationManagerError: If context retrieval fails
Example:
# Get recent messages
recent = manager.get_context("", strategy="recent", k=5)
# Get relevant messages
relevant = manager.get_context("machine learning", strategy="relevant", k=3)
# Get hybrid context
hybrid = manager.get_context(
"neural networks",
strategy="hybrid",
recent_count=3,
relevant_count=5
)Switch to a different LLM model.
Parameters:
model(str): Name of the model to switch to
Raises:
ConversationManagerError: If model is not available
Example:
manager.switch_model("claude")
manager.switch_model("gpt-4")Get list of available LLM models.
Returns:
List[str]: List of available model names
Example:
models = manager.get_available_models()
print(f"Available models: {models}")Get the currently selected model.
Returns:
Optional[str]: Current model name or None if no model is selected
Example:
current = manager.get_current_model()
print(f"Current model: {current}")Clear all stored conversation memory.
Parameters:
confirm(bool): Must be True to actually clear data (safety measure)
Raises:
ConversationManagerError: If clearing fails
Example:
# Clear memory (requires confirmation)
manager.clear_memory(confirm=True)Get statistics about the memory store.
Returns:
Dict[str, Any]: Dictionary containing memory statistics
Raises:
ConversationManagerError: If getting stats fails
Example:
stats = manager.get_memory_stats()
print(f"Total messages: {stats['total_messages']}")
print(f"Available models: {stats['available_models']}")ConversationManager supports context manager protocol:
with ConversationManager() as manager:
response = manager.chat("Hello!")
print(response)
# Automatic cleanup on exitHandles persistent storage and retrieval of conversation messages with semantic search capabilities.
Location: universal_memory_layer.storage.memory_store
MemoryStore(config: Optional[MemoryConfig] = None)Parameters:
config(Optional[MemoryConfig]): Memory configuration. If None, uses default configuration.
Initialize all components of the memory store.
Raises:
MemoryStoreError: If initialization fails
store_message(content: str, role: str, model: str, metadata: Optional[Dict[str, Any]] = None, generate_embedding: bool = True) -> str
Store a message with optional embedding generation.
Parameters:
content(str): Message contentrole(str): Message role ('user' or 'assistant')model(str): Model name that generated/received the messagemetadata(Optional[Dict[str, Any]]): Optional metadata dictionarygenerate_embedding(bool): Whether to generate embeddings for semantic search
Returns:
str: Message ID of the stored message
Raises:
MemoryStoreError: If storing message fails
Example:
message_id = memory.store_message(
content="Hello world",
role="user",
model="chatgpt",
metadata={"session": "test"},
generate_embedding=True
)Retrieve recent messages in chronological order.
Parameters:
n(int): Number of recent messages to retrieve. If None, uses config default.
Returns:
List[Message]: List of Message objects ordered chronologically (oldest first)
Raises:
MemoryStoreError: If retrieval fails
Example:
recent_messages = memory.get_recent(10)
for msg in recent_messages:
print(f"{msg.role}: {msg.content}")get_relevant(query: str, k: int = None, strategy: str = 'hybrid', score_threshold: float = 0.1) -> List[Message]
Retrieve relevant messages using semantic search.
Parameters:
query(str): Search query textk(int): Number of results to return. If None, uses config default.strategy(str): Search strategy ('semantic', 'recent', or 'hybrid')score_threshold(float): Minimum similarity score for semantic results
Returns:
List[Message]: List of Message objects ordered by relevance
Raises:
MemoryStoreError: If search fails
Example:
relevant = memory.get_relevant(
query="machine learning",
k=5,
strategy="semantic",
score_threshold=0.2
)Generate embedding for given text.
Parameters:
text(str): Text to generate embedding for
Returns:
List[float]: List of floats representing the embedding vector
Raises:
MemoryStoreError: If embedding generation fails
Retrieve a specific message by ID.
Parameters:
message_id(str): ID of the message to retrieve
Returns:
Optional[Message]: Message object if found, None otherwise
Raises:
MemoryStoreError: If retrieval fails
Get comprehensive statistics about the memory store.
Returns:
Dict[str, Any]: Dictionary containing various statistics
Example:
stats = memory.get_stats()
print(f"Total messages: {stats['total_messages']}")
print(f"Embedding provider: {stats['embedding_provider']}")Location: universal_memory_layer.models.message
@dataclass
class Message:
id: str
content: str
role: str # 'user' or 'assistant'
model: str
timestamp: datetime
embedding_id: Optional[str] = None
metadata: Dict[str, Any] = field(default_factory=dict)Example:
from universal_memory_layer.models.message import Message
from datetime import datetime
message = Message(
id="msg_123",
content="Hello world",
role="user",
model="chatgpt",
timestamp=datetime.now(),
metadata={"session": "test"}
)Location: universal_memory_layer.models.conversation
@dataclass
class Conversation:
id: str
title: str
created_at: datetime
last_updated: datetime
messages: List[Message] = field(default_factory=list)Location: universal_memory_layer.models.config
Configuration model with environment variable support.
@dataclass
class MemoryConfig:
# Database settings
database_path: str = "memory.db"
vector_store_path: str = "vector_store.faiss"
# Embedding settings
embedding_provider: str = "openai"
embedding_model: str = "text-embedding-ada-002"
# Context settings
max_context_length: int = 4000
default_recent_count: int = 3
default_relevant_count: int = 5
# API Keys
openai_api_key: str = ""
anthropic_api_key: str = ""
google_api_key: str = ""
# Hugging Face settings
huggingface_model_path: str = "sentence-transformers/all-MiniLM-L6-v2"
huggingface_cache_dir: Optional[str] = NoneCheck if API key is available for the given provider.
Parameters:
provider(str): Provider name ('openai', 'anthropic', 'google')
Returns:
bool: True if API key is available and non-empty
Example:
config = MemoryConfig()
if config.has_api_key("openai"):
print("OpenAI API key is configured")Convert configuration to dictionary (excluding sensitive API keys).
Returns:
Dict[str, Any]: Configuration dictionary
Create MemoryConfig from dictionary.
Parameters:
config_dict(Dict[str, Any]): Dictionary containing configuration valuesload_from_env(bool): Whether to load from environment variables
Returns:
MemoryConfig: MemoryConfig instance
All configuration can be set via environment variables:
| Variable | Description | Default |
|---|---|---|
OPENAI_API_KEY |
OpenAI API key | "" |
ANTHROPIC_API_KEY |
Anthropic API key | "" |
GOOGLE_API_KEY |
Google API key | "" |
UML_DATABASE_PATH |
SQLite database path | "memory.db" |
UML_VECTOR_STORE_PATH |
FAISS index path | "vector_store.faiss" |
UML_EMBEDDING_PROVIDER |
Embedding provider | "openai" |
UML_EMBEDDING_MODEL |
Embedding model name | "text-embedding-ada-002" |
UML_MAX_CONTEXT_LENGTH |
Max context length | 4000 |
UML_DEFAULT_RECENT_COUNT |
Default recent count | 3 |
UML_DEFAULT_RELEVANT_COUNT |
Default relevant count | 5 |
UML_HF_MODEL_PATH |
Hugging Face model path | "sentence-transformers/all-MiniLM-L6-v2" |
UML_HF_CACHE_DIR |
Hugging Face cache directory | None |
UML_LOG_LEVEL |
Logging level | "WARNING" |
Location: universal_memory_layer.clients.base
class BaseLLMClient:
def chat(self, message: str, context: List[str] = None) -> str:
"""Send message with context to LLM and return response"""
pass
def format_prompt(self, message: str, context: List[str]) -> str:
"""Format message and context into model-specific prompt"""
passLocation: universal_memory_layer.clients.chatgpt_client
ChatGPTClient(api_key: str, model: str = "gpt-3.5-turbo")Location: universal_memory_layer.clients.claude_client
ClaudeClient(api_key: str, model: str = "claude-3-sonnet-20240229")Location: universal_memory_layer.clients.gemini_client
GeminiClient(api_key: str, model: str = "gemini-pro")Location: universal_memory_layer.embeddings.base
class BaseEmbeddingProvider:
def generate_embedding(self, text: str) -> List[float]:
"""Generate embedding vector for given text"""
pass
def get_dimension(self) -> int:
"""Return embedding dimension for vector store setup"""
passLocation: universal_memory_layer.embeddings.openai_provider
OpenAIEmbeddingProvider(api_key: str, model: str = "text-embedding-ada-002")Location: universal_memory_layer.embeddings.huggingface_provider
HuggingFaceEmbeddingProvider(
model_name: str = "sentence-transformers/all-MiniLM-L6-v2",
cache_dir: Optional[str] = None
)UMLError (base exception)
├── ConversationError
│ └── ConversationManagerError
├── StorageError
│ └── MemoryStoreError
├── LLMClientError
├── EmbeddingError
└── CLIError
Location: universal_memory_layer.errors
@handle_errors(
error_mapping={
SpecificError: GeneralError,
Exception: UMLError
}
)
def my_function():
# Function implementation
passresult = safe_execute(
func=risky_function,
args=(arg1, arg2),
kwargs={'key': 'value'},
default_return=None,
error_message="Operation failed"
)try:
manager = ConversationManager()
manager.initialize()
except ConversationManagerError as e:
if "API key not found" in str(e):
print("Please set your API keys in environment variables")try:
memory.store_message("test", "user", "chatgpt")
except MemoryStoreError as e:
if "database" in str(e).lower():
print("Database error - check file permissions")try:
response = manager.chat("Hello")
except ConversationManagerError as e:
if "timeout" in str(e).lower():
print("Network timeout - check your connection")# Recommended pattern for resource management
with ConversationManager() as manager:
response = manager.chat("Hello!")
print(response)from universal_memory_layer.errors import ConversationManagerError
try:
manager = ConversationManager()
manager.initialize()
response = manager.chat("Hello!")
except ConversationManagerError as e:
print(f"Conversation error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")# Load configuration from environment
config = MemoryConfig() # Automatically loads from env vars
# Or create custom configuration
config = MemoryConfig(
database_path="./custom.db",
embedding_provider="huggingface",
max_context_length=8000
)
manager = ConversationManager(config)# Process multiple messages efficiently
messages = ["Hello", "How are you?", "Tell me a joke"]
with ConversationManager() as manager:
for msg in messages:
response = manager.chat(msg)
print(f"Q: {msg}")
print(f"A: {response}\n")