Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions mem0/configs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Initialize configs package and expose settings."""

from mem0.configs.settings import settings

__all__ = ["settings"]
44 changes: 44 additions & 0 deletions mem0/configs/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Settings module for mem0 configuration management.
"""

from typing import Any, Dict

from mem0.configs.base import MemoryConfig


class Settings:
"""Settings class to manage configuration."""

def __init__(self):
"""Initialize settings with default configuration."""
self.config = {}
self._memory_config = MemoryConfig()

def configure(self, config: Dict[str, Any]) -> None:
"""
Configure settings with provided configuration.
Args:
config: Dictionary containing configuration settings
"""
self.config.update(config)

@property
def memory_config(self) -> MemoryConfig:
"""Get the memory configuration."""
return self._memory_config

@memory_config.setter
def memory_config(self, config: MemoryConfig) -> None:
"""
Set the memory configuration.
Args:
config: MemoryConfig instance
"""
self._memory_config = config


# Create a singleton instance
settings = Settings()
2 changes: 1 addition & 1 deletion mem0/memory/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ def _get_all_from_vector_store(self, filters, limit):
memories_result = self.vector_store.list(filters=filters, limit=limit)
actual_memories = (
memories_result[0]
if isinstance(memories_result, (tuple, list)) and len(memories_result) > 0
if isinstance(memories_result, (tuple)) and len(memories_result) > 0
else memories_result
)

Expand Down
38 changes: 26 additions & 12 deletions mem0/memory/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@
import re

from mem0.configs.prompts import (
AGENT_MEMORY_EXTRACTION_PROMPT,
FACT_RETRIEVAL_PROMPT,
USER_MEMORY_EXTRACTION_PROMPT,
AGENT_MEMORY_EXTRACTION_PROMPT,
)


def get_fact_retrieval_messages(message, is_agent_memory=False):
"""Get fact retrieval messages based on the memory type.

Args:
message: The message content to extract facts from
is_agent_memory: If True, use agent memory extraction prompt, else use user memory extraction prompt

Returns:
tuple: (system_prompt, user_prompt)
"""
if is_agent_memory:
return AGENT_MEMORY_EXTRACTION_PROMPT, f"Input:\n{message}"
else:
return USER_MEMORY_EXTRACTION_PROMPT, f"Input:\n{message}"
from mem0.configs import settings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not how we are planning to introduce the config, there are set of parameters for every provider - ollama, lmstudio where thinking mode toggle can be configured, this is a prompt based mechanism and not a config base.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Vedant817 please look at the comments here, this seems to be unresolved.


base_prompt = AGENT_MEMORY_EXTRACTION_PROMPT if is_agent_memory else USER_MEMORY_EXTRACTION_PROMPT

# Add thinking mode instruction if enabled
if settings.config.get("llm", {}).get("config", {}).get("use_thinking_mode", False):
base_prompt = "Think step-by-step:\n" + base_prompt

return base_prompt, f"Input:\n{message}"


def get_fact_retrieval_messages_legacy(message):
Expand Down Expand Up @@ -64,22 +69,32 @@ def remove_code_blocks(content: str) -> str:
"""
pattern = r"^```[a-zA-Z0-9]*\n([\s\S]*?)\n```$"
match = re.match(pattern, content.strip())
match_res=match.group(1).strip() if match else content.strip()
match_res = match.group(1).strip() if match else content.strip()
return re.sub(r"<think>.*?</think>", "", match_res, flags=re.DOTALL).strip()



def extract_json(text):
"""
Extracts JSON content from a string, removing enclosing triple backticks and optional 'json' tag if present.
If no code block is found, returns the text as-is.
"""
text = text.strip()
if not text:
return "{}" # Return empty JSON object for empty input to avoid parse errors

# Existing regex for code blocks
match = re.search(r"```(?:json)?\s*(.*?)\s*```", text, re.DOTALL)
if match:
json_str = match.group(1)
json_str = match.group(1).strip()
else:
json_str = text # assume it's raw JSON
json_str = text

# New: Try to find JSON-like substring if full text isn't valid
if not json_str.startswith("{"):
json_match = re.search(r"\{.*\}", json_str, re.DOTALL)
if json_match:
json_str = json_match.group(0)

return json_str


Expand Down Expand Up @@ -205,4 +220,3 @@ def sanitize_relationship_for_cypher(relationship) -> str:
sanitized = sanitized.replace(old, new)

return re.sub(r"_+", "_", sanitized).strip("_")