Mem0 1.0.0 (#3545)

This commit is contained in:
Parshva Daftari
2025-10-16 15:50:20 +05:30
committed by GitHub
parent 8f5151c344
commit 394203d1b5
77 changed files with 3445 additions and 990 deletions
+60
View File
@@ -10,6 +10,12 @@ from mem0.configs.llms.lmstudio import LMStudioConfig
from mem0.configs.llms.ollama import OllamaConfig
from mem0.configs.llms.openai import OpenAIConfig
from mem0.configs.llms.vllm import VllmConfig
from mem0.configs.rerankers.base import BaseRerankerConfig
from mem0.configs.rerankers.cohere import CohereRerankerConfig
from mem0.configs.rerankers.sentence_transformer import SentenceTransformerRerankerConfig
from mem0.configs.rerankers.zero_entropy import ZeroEntropyRerankerConfig
from mem0.configs.rerankers.llm import LLMRerankerConfig
from mem0.configs.rerankers.huggingface import HuggingFaceRerankerConfig
from mem0.embeddings.mock import MockEmbeddings
@@ -219,3 +225,57 @@ class GraphStoreFactory:
except (ImportError, AttributeError) as e:
raise ImportError(f"Could not import MemoryGraph for provider '{provider_name}': {e}")
return GraphClass(config)
class RerankerFactory:
"""
Factory for creating reranker instances with appropriate configurations.
Supports provider-specific configs following the same pattern as other factories.
"""
# Provider mappings with their config classes
provider_to_class = {
"cohere": ("mem0.reranker.cohere_reranker.CohereReranker", CohereRerankerConfig),
"sentence_transformer": ("mem0.reranker.sentence_transformer_reranker.SentenceTransformerReranker", SentenceTransformerRerankerConfig),
"zero_entropy": ("mem0.reranker.zero_entropy_reranker.ZeroEntropyReranker", ZeroEntropyRerankerConfig),
"llm_reranker": ("mem0.reranker.llm_reranker.LLMReranker", LLMRerankerConfig),
"huggingface": ("mem0.reranker.huggingface_reranker.HuggingFaceReranker", HuggingFaceRerankerConfig),
}
@classmethod
def create(cls, provider_name: str, config: Optional[Union[BaseRerankerConfig, Dict]] = None, **kwargs):
"""
Create a reranker instance based on the provider and configuration.
Args:
provider_name: The reranker provider (e.g., 'cohere', 'sentence_transformer')
config: Configuration object or dictionary
**kwargs: Additional configuration parameters
Returns:
Reranker instance configured for the specified provider
Raises:
ImportError: If the provider class cannot be imported
ValueError: If the provider is not supported
"""
if provider_name not in cls.provider_to_class:
raise ValueError(f"Unsupported reranker provider: {provider_name}")
class_path, config_class = cls.provider_to_class[provider_name]
# Handle configuration
if config is None:
config = config_class(**kwargs)
elif isinstance(config, dict):
config = config_class(**config, **kwargs)
elif not isinstance(config, BaseRerankerConfig):
raise ValueError(f"Config must be a {config_class.__name__} instance or dict")
# Import and create the reranker class
try:
reranker_class = load_class(class_path)
except (ImportError, AttributeError) as e:
raise ImportError(f"Could not import reranker for provider '{provider_name}': {e}")
return reranker_class(config)
+167
View File
@@ -0,0 +1,167 @@
import os
import json
from typing import Optional, Dict, Any
try:
from google.oauth2 import service_account
from google.auth import default
import google.auth.credentials
except ImportError:
raise ImportError("google-auth is required for GCP authentication. Install with: pip install google-auth")
class GCPAuthenticator:
"""
Centralized GCP authentication handler that supports multiple credential methods.
Priority order:
1. service_account_json (dict) - In-memory service account credentials
2. credentials_path (str) - Path to service account JSON file
3. Environment variables (GOOGLE_APPLICATION_CREDENTIALS)
4. Default credentials (for environments like GCE, Cloud Run, etc.)
"""
@staticmethod
def get_credentials(
service_account_json: Optional[Dict[str, Any]] = None,
credentials_path: Optional[str] = None,
scopes: Optional[list] = None
) -> tuple[google.auth.credentials.Credentials, Optional[str]]:
"""
Get Google credentials using the priority order defined above.
Args:
service_account_json: Service account credentials as a dictionary
credentials_path: Path to service account JSON file
scopes: List of OAuth scopes (optional)
Returns:
tuple: (credentials, project_id)
Raises:
ValueError: If no valid credentials are found
"""
credentials = None
project_id = None
# Method 1: Service account JSON (in-memory)
if service_account_json:
credentials = service_account.Credentials.from_service_account_info(
service_account_json, scopes=scopes
)
project_id = service_account_json.get("project_id")
# Method 2: Service account file path
elif credentials_path and os.path.isfile(credentials_path):
credentials = service_account.Credentials.from_service_account_file(
credentials_path, scopes=scopes
)
# Extract project_id from the file
with open(credentials_path, 'r') as f:
cred_data = json.load(f)
project_id = cred_data.get("project_id")
# Method 3: Environment variable path
elif os.getenv("GOOGLE_APPLICATION_CREDENTIALS"):
env_path = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
if os.path.isfile(env_path):
credentials = service_account.Credentials.from_service_account_file(
env_path, scopes=scopes
)
# Extract project_id from the file
with open(env_path, 'r') as f:
cred_data = json.load(f)
project_id = cred_data.get("project_id")
# Method 4: Default credentials (GCE, Cloud Run, etc.)
if not credentials:
try:
credentials, project_id = default(scopes=scopes)
except Exception as e:
raise ValueError(
f"No valid GCP credentials found. Please provide one of:\n"
f"1. service_account_json parameter (dict)\n"
f"2. credentials_path parameter (file path)\n"
f"3. GOOGLE_APPLICATION_CREDENTIALS environment variable\n"
f"4. Default credentials (if running on GCP)\n"
f"Error: {e}"
)
return credentials, project_id
@staticmethod
def setup_vertex_ai(
service_account_json: Optional[Dict[str, Any]] = None,
credentials_path: Optional[str] = None,
project_id: Optional[str] = None,
location: str = "us-central1"
) -> str:
"""
Initialize Vertex AI with proper authentication.
Args:
service_account_json: Service account credentials as dict
credentials_path: Path to service account JSON file
project_id: GCP project ID (optional, will be auto-detected)
location: GCP location/region
Returns:
str: The project ID being used
Raises:
ValueError: If authentication fails
"""
try:
import vertexai
except ImportError:
raise ImportError("google-cloud-aiplatform is required for Vertex AI. Install with: pip install google-cloud-aiplatform")
credentials, detected_project_id = GCPAuthenticator.get_credentials(
service_account_json=service_account_json,
credentials_path=credentials_path,
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
# Use provided project_id or fall back to detected one
final_project_id = project_id or detected_project_id or os.getenv("GOOGLE_CLOUD_PROJECT")
if not final_project_id:
raise ValueError("Project ID could not be determined. Please provide project_id parameter or set GOOGLE_CLOUD_PROJECT environment variable.")
vertexai.init(project=final_project_id, location=location, credentials=credentials)
return final_project_id
@staticmethod
def get_genai_client(
service_account_json: Optional[Dict[str, Any]] = None,
credentials_path: Optional[str] = None,
api_key: Optional[str] = None
):
"""
Get a Google GenAI client with authentication.
Args:
service_account_json: Service account credentials as dict
credentials_path: Path to service account JSON file
api_key: API key (takes precedence over service account)
Returns:
Google GenAI client instance
"""
try:
from google.genai import Client as GenAIClient
except ImportError:
raise ImportError("google-genai is required. Install with: pip install google-genai")
# If API key is provided, use it directly
if api_key:
return GenAIClient(api_key=api_key)
# Otherwise, try service account authentication
credentials, _ = GCPAuthenticator.get_credentials(
service_account_json=service_account_json,
credentials_path=credentials_path,
scopes=["https://www.googleapis.com/auth/generative-language"]
)
return GenAIClient(credentials=credentials)