diff --git a/examples/agent_memory.py b/examples/agent_memory.py index 23df492..0234c57 100644 --- a/examples/agent_memory.py +++ b/examples/agent_memory.py @@ -30,7 +30,7 @@ def load_oceanbase_config(): Uses the auto_config() utility function to automatically load from .env. """ - oceanbase_env_path = os.path.join(os.path.dirname(__file__), '..', 'configs', '.env') + oceanbase_env_path = os.path.join(os.path.dirname(__file__), '..', '.env') if os.path.exists(oceanbase_env_path): load_dotenv(oceanbase_env_path, override=True) diff --git a/examples/basic_usage.py b/examples/basic_usage.py index cdd6ec7..f941a48 100644 --- a/examples/basic_usage.py +++ b/examples/basic_usage.py @@ -23,8 +23,8 @@ def main(): print("=" * 60) # Check if .env exists and load it - env_path = os.path.join(os.path.dirname(__file__), "..", "configs", ".env") - env_example_path = os.path.join(os.path.dirname(__file__), "..", "configs", "env.example") + env_path = os.path.join(os.path.dirname(__file__), "..", ".env") + env_example_path = os.path.join(os.path.dirname(__file__), "..", "env.example") if not os.path.exists(env_path): print(f"\n No .env file found at: {env_path}") diff --git a/examples/intelligent_memory_demo.py b/examples/intelligent_memory_demo.py index 90fff6d..a3fa38e 100644 --- a/examples/intelligent_memory_demo.py +++ b/examples/intelligent_memory_demo.py @@ -38,7 +38,7 @@ def load_config(): Uses the auto_config() utility function to automatically load from .env. """ - oceanbase_env_path = os.path.join(os.path.dirname(__file__), '..', 'configs', '.env') + oceanbase_env_path = os.path.join(os.path.dirname(__file__), '..', '.env') if os.path.exists(oceanbase_env_path): load_dotenv(oceanbase_env_path, override=True) diff --git a/src/powermem/core/async_memory.py b/src/powermem/core/async_memory.py index 866460b..cdea599 100644 --- a/src/powermem/core/async_memory.py +++ b/src/powermem/core/async_memory.py @@ -159,7 +159,8 @@ def __init__( # Extract embedder config embedder_config = self._get_component_config('embedder') - self.embedding = EmbedderFactory.create(self.embedding_provider, embedder_config, None) + # Pass vector_store_config so factory can extract embedding_model_dims for mock embeddings + self.embedding = EmbedderFactory.create(self.embedding_provider, embedder_config, vector_store_config) # Initialize storage adapter with embedding service # Automatically select adapter based on sub_stores configuration @@ -1339,10 +1340,12 @@ def _init_single_sub_store( if key not in sub_embedding_params and key in main_embedding_config: sub_embedding_params[key] = main_embedding_config[key] + # Create a config dict with embedding_model_dims for mock embeddings + sub_vector_config = {'embedding_model_dims': embedding_model_dims} sub_embedding = EmbedderFactory.create( sub_embedding_provider, sub_embedding_params, - None + sub_vector_config ) logger.info(f"Created sub embedding service for store {index}: {sub_embedding_provider}") else: diff --git a/src/powermem/core/memory.py b/src/powermem/core/memory.py index 69f2aab..c07e41b 100644 --- a/src/powermem/core/memory.py +++ b/src/powermem/core/memory.py @@ -228,7 +228,8 @@ def __init__( # Extract embedder config embedder_config = self._get_component_config('embedder') - self.embedding = EmbedderFactory.create(self.embedding_provider, embedder_config, None) + # Pass vector_store_config so factory can extract embedding_model_dims for mock embeddings + self.embedding = EmbedderFactory.create(self.embedding_provider, embedder_config, vector_store_config) # Initialize storage adapter with embedding service # Automatically select adapter based on sub_stores configuration @@ -1404,10 +1405,12 @@ def _init_single_sub_store( if key not in sub_embedding_params and key in main_embedding_config: sub_embedding_params[key] = main_embedding_config[key] + # Create a config dict with embedding_model_dims for mock embeddings + sub_vector_config = {'embedding_model_dims': embedding_model_dims} sub_embedding = EmbedderFactory.create( sub_embedding_provider, sub_embedding_params, - None + sub_vector_config ) logger.info(f"Created sub embedding service for store {index}: {sub_embedding_provider}") else: diff --git a/src/powermem/integrations/embeddings/factory.py b/src/powermem/integrations/embeddings/factory.py index e065476..8d6018f 100644 --- a/src/powermem/integrations/embeddings/factory.py +++ b/src/powermem/integrations/embeddings/factory.py @@ -34,11 +34,38 @@ class EmbedderFactory: @classmethod def create(cls, provider_name, config, vector_config: Optional[dict]): + # Helper function to extract dimension from vector_config (handles both dict and object) + def get_dimension_from_vector_config(vector_config, default=1536): + if not vector_config: + return default + if isinstance(vector_config, dict): + return vector_config.get('embedding_model_dims', default) + else: + return getattr(vector_config, 'embedding_model_dims', default) + # Handle mock provider directly if provider_name == "mock": - return MockEmbeddings() - if provider_name == "upstash_vector" and vector_config and vector_config.enable_embeddings: - return MockEmbeddings() + # Extract dimension from vector_config or embedder config, default to 1536 + dimension = 1536 # Default dimension + dimension = get_dimension_from_vector_config(vector_config, dimension) + if config: + dimension = config.get('embedding_dims', dimension) + return MockEmbeddings(dimension=dimension) + if provider_name == "upstash_vector" and vector_config: + # Check enable_embeddings (handles both dict and object) + enable_embeddings = False + if isinstance(vector_config, dict): + enable_embeddings = vector_config.get('enable_embeddings', False) + else: + enable_embeddings = getattr(vector_config, 'enable_embeddings', False) + + if enable_embeddings: + # Extract dimension from vector_config or embedder config, default to 1536 + dimension = 1536 # Default dimension + dimension = get_dimension_from_vector_config(vector_config, dimension) + if config: + dimension = config.get('embedding_dims', dimension) + return MockEmbeddings(dimension=dimension) class_type = cls.provider_to_class.get(provider_name) if class_type: embedder_instance = load_class(class_type) diff --git a/src/powermem/integrations/embeddings/mock.py b/src/powermem/integrations/embeddings/mock.py index 56a9e4b..941b993 100644 --- a/src/powermem/integrations/embeddings/mock.py +++ b/src/powermem/integrations/embeddings/mock.py @@ -4,8 +4,26 @@ class MockEmbeddings(EmbeddingBase): + def __init__(self, dimension: int = 1536): + """ + Initialize MockEmbeddings with specified dimension. + + Args: + dimension: Dimension of the mock embedding vector. Defaults to 1536 to match + common embedding models and OceanBase default. + """ + self.dimension = dimension + def embed(self, text, memory_action: Optional[Literal["add", "search", "update"]] = None): """ - Generate a mock embedding with dimension of 10. + Generate a mock embedding with the configured dimension. + + Returns a vector with values [0.1, 0.2, 0.3, ...] repeated to fill the dimension. """ - return [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] + # Generate a simple pattern that repeats to fill the dimension + base_values = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] + # Repeat the pattern to fill the required dimension + result = [] + for i in range(self.dimension): + result.append(base_values[i % len(base_values)]) + return result