mem0ai-azure-mysql 0.1.116.3__tar.gz → 0.1.116.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/PKG-INFO +1 -1
  2. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/azure_openai.py +30 -1
  3. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/base.py +13 -1
  4. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/graph_memory.py +90 -45
  5. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/main.py +5 -0
  6. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/utils.py +29 -1
  7. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/pyproject.toml +1 -1
  8. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/.gitignore +0 -0
  9. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/README.md +0 -0
  10. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/__init__.py +0 -0
  11. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/__init__.py +0 -0
  12. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/main.py +0 -0
  13. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/project.py +0 -0
  14. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/utils.py +0 -0
  15. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/__init__.py +0 -0
  16. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/base.py +0 -0
  17. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/__init__.py +0 -0
  18. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/base.py +0 -0
  19. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/mysql.py +0 -0
  20. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/embeddings/__init__.py +0 -0
  21. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/embeddings/base.py +0 -0
  22. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/enums.py +0 -0
  23. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/__init__.py +0 -0
  24. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/anthropic.py +0 -0
  25. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/aws_bedrock.py +0 -0
  26. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/azure.py +0 -0
  27. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/base.py +0 -0
  28. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/deepseek.py +0 -0
  29. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/lmstudio.py +0 -0
  30. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/ollama.py +0 -0
  31. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/openai.py +0 -0
  32. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/vllm.py +0 -0
  33. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/prompts.py +0 -0
  34. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/__init__.py +0 -0
  35. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/azure_ai_search.py +0 -0
  36. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/baidu.py +0 -0
  37. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/chroma.py +0 -0
  38. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/databricks.py +0 -0
  39. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/elasticsearch.py +0 -0
  40. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/faiss.py +0 -0
  41. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/langchain.py +0 -0
  42. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/milvus.py +0 -0
  43. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/mongodb.py +0 -0
  44. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/opensearch.py +0 -0
  45. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/pgvector.py +0 -0
  46. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/pinecone.py +0 -0
  47. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/qdrant.py +0 -0
  48. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/redis.py +0 -0
  49. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/supabase.py +0 -0
  50. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/upstash_vector.py +0 -0
  51. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/vertex_ai_vector_search.py +0 -0
  52. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/weaviate.py +0 -0
  53. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/__init__.py +0 -0
  54. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/base.py +0 -0
  55. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/configs.py +0 -0
  56. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/mysql.py +0 -0
  57. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/__init__.py +0 -0
  58. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/aws_bedrock.py +0 -0
  59. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/configs.py +0 -0
  60. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/gemini.py +0 -0
  61. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/huggingface.py +0 -0
  62. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/langchain.py +0 -0
  63. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/lmstudio.py +0 -0
  64. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/mock.py +0 -0
  65. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/ollama.py +0 -0
  66. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/openai.py +0 -0
  67. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/together.py +0 -0
  68. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/vertexai.py +0 -0
  69. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/__init__.py +0 -0
  70. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/configs.py +0 -0
  71. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/__init__.py +0 -0
  72. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/base.py +0 -0
  73. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/main.py +0 -0
  74. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/tools.py +0 -0
  75. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/utils.py +0 -0
  76. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/__init__.py +0 -0
  77. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/anthropic.py +0 -0
  78. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/aws_bedrock.py +0 -0
  79. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/azure_openai.py +0 -0
  80. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/azure_openai_structured.py +0 -0
  81. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/base.py +0 -0
  82. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/configs.py +0 -0
  83. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/deepseek.py +0 -0
  84. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/gemini.py +0 -0
  85. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/groq.py +0 -0
  86. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/langchain.py +0 -0
  87. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/litellm.py +0 -0
  88. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/lmstudio.py +0 -0
  89. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/ollama.py +0 -0
  90. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/openai.py +0 -0
  91. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/openai_structured.py +0 -0
  92. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/sarvam.py +0 -0
  93. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/together.py +0 -0
  94. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/vllm.py +0 -0
  95. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/xai.py +0 -0
  96. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/__init__.py +0 -0
  97. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/base.py +0 -0
  98. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/kuzu_memory.py +0 -0
  99. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/memgraph_memory.py +0 -0
  100. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/setup.py +0 -0
  101. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/storage.py +0 -0
  102. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/telemetry.py +0 -0
  103. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/proxy/__init__.py +0 -0
  104. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/proxy/main.py +0 -0
  105. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/utils/factory.py +0 -0
  106. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/__init__.py +0 -0
  107. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/azure_ai_search.py +0 -0
  108. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/baidu.py +0 -0
  109. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/base.py +0 -0
  110. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/chroma.py +0 -0
  111. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/configs.py +0 -0
  112. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/databricks.py +0 -0
  113. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/elasticsearch.py +0 -0
  114. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/faiss.py +0 -0
  115. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/langchain.py +0 -0
  116. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/milvus.py +0 -0
  117. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/mongodb.py +0 -0
  118. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/opensearch.py +0 -0
  119. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/pgvector.py +0 -0
  120. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/pinecone.py +0 -0
  121. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/qdrant.py +0 -0
  122. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/redis.py +0 -0
  123. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/supabase.py +0 -0
  124. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/upstash_vector.py +0 -0
  125. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/vertex_ai_vector_search.py +0 -0
  126. {mem0ai_azure_mysql-0.1.116.3 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/weaviate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mem0ai-azure-mysql
3
- Version: 0.1.116.3
3
+ Version: 0.1.116.5
4
4
  Summary: Long-term memory for AI Agents with Azure DefaultAzureCredential authentication and MySQL history database support
5
5
  Requires-Python: <4.0,>=3.9
6
6
  Requires-Dist: azure-identity>=1.23.1
@@ -6,9 +6,13 @@ from azure.identity import DefaultAzureCredential, get_bearer_token_provider
6
6
 
7
7
  from mem0.configs.embeddings.base import BaseEmbedderConfig
8
8
  from mem0.embeddings.base import EmbeddingBase
9
+ from mem0.memory.utils import time_perf
9
10
 
10
11
 
11
12
  class AzureOpenAIEmbedding(EmbeddingBase):
13
+
14
+ cached_embeddings = {}
15
+
12
16
  def __init__(self, config: Optional[BaseEmbedderConfig] = None):
13
17
  super().__init__(config)
14
18
 
@@ -41,6 +45,7 @@ class AzureOpenAIEmbedding(EmbeddingBase):
41
45
  **auth_kwargs,
42
46
  )
43
47
 
48
+ @time_perf
44
49
  def embed(self, text, memory_action: Optional[Literal["add", "search", "update"]] = None):
45
50
  """
46
51
  Get the embedding for the given text using OpenAI.
@@ -52,4 +57,28 @@ class AzureOpenAIEmbedding(EmbeddingBase):
52
57
  list: The embedding vector.
53
58
  """
54
59
  text = text.replace("\n", " ")
55
- return self.client.embeddings.create(input=[text], model=self.config.model).data[0].embedding
60
+ if text not in self.cached_embeddings:
61
+ self.cached_embeddings[text] = self.client.embeddings.create(input=[text], model=self.config.model).data[0].embedding
62
+ return self.cached_embeddings[text]
63
+
64
+ @time_perf
65
+ def embed_in_batch(self, texts, memory_action: Optional[Literal["add", "search", "update"]] = None):
66
+ """
67
+ Get the embedding for the given texts.
68
+
69
+ Args:
70
+ texts (list[str]): The text list to embed.
71
+ memory_action (optional): The type of embedding to use. Must be one of "add", "search", or "update". Defaults to None.
72
+ Returns:
73
+ list: List of the embedding vector.
74
+ """
75
+ texts = [text.replace("\n", " ") for text in texts]
76
+
77
+ # Use cached embeddings if available
78
+ uncached_texts = [text for text in texts if text not in self.cached_embeddings]
79
+ if uncached_texts:
80
+ uncached_embeddings = self.client.embeddings.create(input=uncached_texts, model=self.config.model)
81
+ for text, item in zip(uncached_texts, uncached_embeddings.data):
82
+ self.cached_embeddings[text] = item.embedding
83
+
84
+ return [self.cached_embeddings[text] for text in texts]
@@ -18,7 +18,7 @@ class EmbeddingBase(ABC):
18
18
  self.config = config
19
19
 
20
20
  @abstractmethod
21
- def embed(self, text, memory_action: Optional[Literal["add", "search", "update"]]):
21
+ def embed(self, text, memory_action: Optional[Literal["add", "search", "update"]]) -> list[float]:
22
22
  """
23
23
  Get the embedding for the given text.
24
24
 
@@ -29,3 +29,15 @@ class EmbeddingBase(ABC):
29
29
  list: The embedding vector.
30
30
  """
31
31
  pass
32
+
33
+ def embed_in_batch(self, texts, memory_action: Optional[Literal["add", "search", "update"]]) -> list[list[float]]:
34
+ """
35
+ Get the embedding for the given texts.
36
+
37
+ Args:
38
+ texts (list[str]): The text list to embed.
39
+ memory_action (optional): The type of embedding to use. Must be one of "add", "search", or "update". Defaults to None.
40
+ Returns:
41
+ list: List of the embedding vector.
42
+ """
43
+ return [self.embed(text, memory_action) for text in texts]
@@ -3,7 +3,7 @@ import time
3
3
 
4
4
  import cohere
5
5
 
6
- from mem0.memory.utils import format_entities, sanitize_relationship_for_cypher
6
+ from mem0.memory.utils import format_entities, sanitize_relationship_for_cypher, time_perf
7
7
 
8
8
  try:
9
9
  from langchain_neo4j import Neo4jGraph
@@ -114,8 +114,6 @@ class MemoryGraph:
114
114
  logger.info(f"Searching for query in neo4j: {query} with filters: {filters}")
115
115
  entity_type_map = self._retrieve_nodes_from_data(query, filters)
116
116
  search_output = self._search_graph_db(node_list=list(entity_type_map.keys()), filters=filters)
117
- print(f'entity_type_map: {entity_type_map}')
118
- print(f'search_output: {search_output}')
119
117
 
120
118
  if not search_output:
121
119
  return []
@@ -158,14 +156,12 @@ class MemoryGraph:
158
156
  base_url=rerank_config.get("base_url"),
159
157
  )
160
158
  docs = [f'{item["source"]} {item["relationship"]} {item["destination"]}' for item in search_output]
161
- print(f'docs: {docs}')
162
159
  response = co.rerank(
163
160
  model=rerank_config.get("model"),
164
161
  query=query,
165
162
  documents=docs,
166
163
  top_n=self.top_k,
167
164
  )
168
- print(f'response.results: {response.results}')
169
165
 
170
166
  reranked_results = []
171
167
  for result in response.results:
@@ -176,7 +172,6 @@ class MemoryGraph:
176
172
  original_output["destination"],
177
173
  result.relevance_score
178
174
  ])
179
- print(f'reranked_results: {reranked_results}')
180
175
  return reranked_results
181
176
 
182
177
  def delete_all(self, filters):
@@ -243,6 +238,7 @@ class MemoryGraph:
243
238
 
244
239
  return final_results
245
240
 
241
+ @time_perf
246
242
  def _retrieve_nodes_from_data(self, data, filters):
247
243
  """Extracts all the entities mentioned in the query."""
248
244
  _tools = [EXTRACT_ENTITIES_TOOL]
@@ -276,6 +272,7 @@ class MemoryGraph:
276
272
  logger.debug(f"Entity type map: {entity_type_map}\n search_results={search_results}")
277
273
  return entity_type_map
278
274
 
275
+ @time_perf
279
276
  def _establish_nodes_relations_from_data(self, data, filters, entity_type_map):
280
277
  """Establish relations among the extracted nodes."""
281
278
 
@@ -318,54 +315,54 @@ class MemoryGraph:
318
315
  logger.debug(f"Extracted entities: {entities}")
319
316
  return entities
320
317
 
318
+ @time_perf
321
319
  def _search_graph_db(self, node_list, filters, limit=100):
322
320
  """Search similar nodes among and their respective incoming and outgoing relations."""
323
- result_relations = []
324
-
325
321
  # Build node properties for filtering
326
- node_props = ["user_id: $user_id"]
322
+ node_props = ["user_id: row.user_id"]
327
323
  if filters.get("agent_id"):
328
- node_props.append("agent_id: $agent_id")
324
+ node_props.append("agent_id: row.agent_id")
329
325
  if filters.get("run_id"):
330
- node_props.append("run_id: $run_id")
326
+ node_props.append("run_id: row.run_id")
331
327
  node_props_str = ", ".join(node_props)
328
+ n_embeddings = self.embedding_model.embed_in_batch(node_list)
332
329
 
333
- for node in node_list:
334
- n_embedding = self.embedding_model.embed(node)
335
-
336
- cypher_query = f"""
337
- MATCH (n {self.node_label} {{{node_props_str}}})
338
- WHERE n.embedding IS NOT NULL
339
- WITH n, round(2 * vector.similarity.cosine(n.embedding, $n_embedding) - 1, 4) AS similarity // denormalize for backward compatibility
340
- WHERE similarity >= $threshold
341
- CALL {{
342
- WITH n
343
- MATCH (n)-[r]->(m {self.node_label} {{{node_props_str}}})
344
- RETURN n.name AS source, elementId(n) AS source_id, type(r) AS relationship, elementId(r) AS relation_id, m.name AS destination, elementId(m) AS destination_id
345
- UNION
346
- WITH n
347
- MATCH (n)<-[r]-(m {self.node_label} {{{node_props_str}}})
348
- RETURN m.name AS source, elementId(m) AS source_id, type(r) AS relationship, elementId(r) AS relation_id, n.name AS destination, elementId(n) AS destination_id
349
- }}
350
- WITH distinct source, source_id, relationship, relation_id, destination, destination_id, similarity
351
- RETURN source, source_id, relationship, relation_id, destination, destination_id, similarity
352
- ORDER BY similarity DESC
353
- LIMIT $limit
354
- """
330
+ cypher_query = f"""
331
+ UNWIND $rows AS row
332
+ MATCH (n {self.node_label} {{{node_props_str}}})
333
+ WHERE n.embedding IS NOT NULL
334
+ WITH n, row, round(2 * vector.similarity.cosine(n.embedding, row.n_embedding) - 1, 4) AS similarity // denormalize for backward compatibility
335
+ WHERE similarity >= row.threshold
336
+ CALL {{
337
+ WITH n, row
338
+ MATCH (n)-[r]->(m {self.node_label} {{{node_props_str}}})
339
+ RETURN n.name AS source, elementId(n) AS source_id, type(r) AS relationship, elementId(r) AS relation_id, m.name AS destination, elementId(m) AS destination_id
340
+ UNION
341
+ WITH n, row
342
+ MATCH (n)<-[r]-(m {self.node_label} {{{node_props_str}}})
343
+ RETURN m.name AS source, elementId(m) AS source_id, type(r) AS relationship, elementId(r) AS relation_id, n.name AS destination, elementId(n) AS destination_id
344
+ }}
345
+ WITH distinct source, source_id, relationship, relation_id, destination, destination_id, similarity
346
+ RETURN source, source_id, relationship, relation_id, destination, destination_id, similarity
347
+ ORDER BY similarity DESC
348
+ LIMIT {limit}
349
+ """
355
350
 
356
- params = {
351
+ rows = []
352
+ for n_embedding in n_embeddings:
353
+ row = {
357
354
  "n_embedding": n_embedding,
358
355
  "threshold": self.threshold,
359
356
  "user_id": filters["user_id"],
360
- "limit": limit,
361
357
  }
362
358
  if filters.get("agent_id"):
363
- params["agent_id"] = filters["agent_id"]
359
+ row["agent_id"] = filters["agent_id"]
364
360
  if filters.get("run_id"):
365
- params["run_id"] = filters["run_id"]
366
-
367
- ans = self.graph.query(cypher_query, params=params)
368
- result_relations.extend(ans)
361
+ row["run_id"] = filters["run_id"]
362
+
363
+ rows.append(row)
364
+
365
+ result_relations = self.graph.query(cypher_query, params={"rows": rows})
369
366
 
370
367
  # Remove duplicates, key is (source, relationship, destination)
371
368
  seen = set()
@@ -377,7 +374,8 @@ class MemoryGraph:
377
374
  unique_relations.append(rel)
378
375
 
379
376
  return unique_relations
380
-
377
+
378
+ @time_perf
381
379
  def _get_delete_entities_from_search_output(self, search_output, data, filters):
382
380
  """Get the entities to be deleted from the search output."""
383
381
  search_output_string = format_entities(search_output)
@@ -414,6 +412,7 @@ class MemoryGraph:
414
412
  logger.debug(f"Deleted relationships: {to_be_deleted}")
415
413
  return to_be_deleted
416
414
 
415
+ @time_perf
417
416
  def _delete_entities(self, to_be_deleted, filters):
418
417
  """Delete the entities from the graph."""
419
418
  user_id = filters["user_id"]
@@ -469,12 +468,46 @@ class MemoryGraph:
469
468
 
470
469
  return results
471
470
 
471
+ @time_perf
472
472
  def _add_entities(self, to_be_added, filters, entity_type_map):
473
473
  """Add the new entities to the graph. Merge the nodes if they already exist."""
474
474
  user_id = filters["user_id"]
475
475
  agent_id = filters.get("agent_id", None)
476
476
  run_id = filters.get("run_id", None)
477
477
  results = []
478
+
479
+ # Collect all entities which needs to be embedded
480
+ entities_to_embed = set()
481
+ for item in to_be_added:
482
+ entities_to_embed.add(item["source"])
483
+ entities_to_embed.add(item["destination"])
484
+ entities_to_embed = list(entities_to_embed)
485
+ embeddings = self.embedding_model.embed_in_batch(entities_to_embed)
486
+ embedding_map = {entity: embedding for entity, embedding in zip(entities_to_embed, embeddings)}
487
+
488
+ query_stats = {
489
+ 1: 0, 2: 0, 3: 0, 4: 0
490
+ }
491
+
492
+ queries = {
493
+ "only_source_found": {
494
+ "template": "",
495
+ "rows": []
496
+ },
497
+ "only_destination_found": {
498
+ "template": "",
499
+ "rows": []
500
+ },
501
+ "both_found": {
502
+ "template": "",
503
+ "rows": []
504
+ },
505
+ "none_found": {
506
+ "template": "",
507
+ "rows": []
508
+ },
509
+ }
510
+
478
511
  for item in to_be_added:
479
512
  # entities
480
513
  source = item["source"]
@@ -490,12 +523,12 @@ class MemoryGraph:
490
523
  destination_extra_set = f", destination:`{destination_type}`" if self.node_label else ""
491
524
 
492
525
  # embeddings
493
- source_embedding = self.embedding_model.embed(source)
494
- dest_embedding = self.embedding_model.embed(destination)
526
+ source_embedding = embedding_map[source]
527
+ dest_embedding = embedding_map[destination]
495
528
 
496
529
  # search for the nodes with the closest embeddings
497
- source_node_search_result = self._search_source_node(source_embedding, filters, threshold=0.9)
498
- destination_node_search_result = self._search_destination_node(dest_embedding, filters, threshold=0.9)
530
+ source_node_search_result = self._search_source_node(source_embedding, filters, threshold=self.threshold)
531
+ destination_node_search_result = self._search_destination_node(dest_embedding, filters, threshold=self.threshold)
499
532
 
500
533
  # TODO: Create a cypher query and common params for all the cases
501
534
  if not destination_node_search_result and source_node_search_result:
@@ -541,6 +574,8 @@ class MemoryGraph:
541
574
  params["agent_id"] = agent_id
542
575
  if run_id:
543
576
  params["run_id"] = run_id
577
+
578
+ query_stats[1] += 1
544
579
 
545
580
  elif destination_node_search_result and not source_node_search_result:
546
581
  # Build source MERGE properties
@@ -585,6 +620,8 @@ class MemoryGraph:
585
620
  params["agent_id"] = agent_id
586
621
  if run_id:
587
622
  params["run_id"] = run_id
623
+
624
+ query_stats[2] += 1
588
625
 
589
626
  elif source_node_search_result and destination_node_search_result:
590
627
  cypher = f"""
@@ -613,6 +650,8 @@ class MemoryGraph:
613
650
  params["agent_id"] = agent_id
614
651
  if run_id:
615
652
  params["run_id"] = run_id
653
+
654
+ query_stats[3] += 1
616
655
 
617
656
  else:
618
657
  # Build dynamic MERGE props for both source and destination
@@ -661,8 +700,12 @@ class MemoryGraph:
661
700
  params["agent_id"] = agent_id
662
701
  if run_id:
663
702
  params["run_id"] = run_id
703
+
704
+ query_stats[4] += 1
705
+
664
706
  result = self.graph.query(cypher, params=params)
665
707
  results.append(result)
708
+ logger.warning(f"Add entities query stats: {query_stats}")
666
709
  return results
667
710
 
668
711
  def _remove_spaces_from_entities(self, entity_list):
@@ -673,6 +716,7 @@ class MemoryGraph:
673
716
  item["destination"] = item["destination"].lower().replace(" ", "_")
674
717
  return entity_list
675
718
 
719
+ @time_perf
676
720
  def _search_source_node(self, source_embedding, filters, threshold=0.9):
677
721
  # Build WHERE conditions
678
722
  where_conditions = ["source_candidate.embedding IS NOT NULL", "source_candidate.user_id = $user_id"]
@@ -710,6 +754,7 @@ class MemoryGraph:
710
754
  result = self.graph.query(cypher, params=params)
711
755
  return result
712
756
 
757
+ @time_perf
713
758
  def _search_destination_node(self, destination_embedding, filters, threshold=0.9):
714
759
  # Build WHERE conditions
715
760
  where_conditions = ["destination_candidate.embedding IS NOT NULL", "destination_candidate.user_id = $user_id"]
@@ -29,6 +29,7 @@ from mem0.memory.utils import (
29
29
  parse_vision_messages,
30
30
  process_telemetry_filters,
31
31
  remove_code_blocks,
32
+ time_perf,
32
33
  )
33
34
  from mem0.utils.factory import (
34
35
  EmbedderFactory,
@@ -282,6 +283,7 @@ class Memory(MemoryBase):
282
283
 
283
284
  return {"results": vector_store_result}
284
285
 
286
+ @time_perf
285
287
  def _add_to_vector_store(self, messages, metadata, filters, infer):
286
288
  if not infer:
287
289
  returned_memories = []
@@ -451,6 +453,7 @@ class Memory(MemoryBase):
451
453
  )
452
454
  return returned_memories
453
455
 
456
+ @time_perf
454
457
  def _add_to_graph(self, messages, filters):
455
458
  added_entities = []
456
459
  if self.enable_graph:
@@ -1119,6 +1122,7 @@ class AsyncMemory(MemoryBase):
1119
1122
 
1120
1123
  return {"results": vector_store_result}
1121
1124
 
1125
+ @time_perf
1122
1126
  async def _add_to_vector_store(
1123
1127
  self,
1124
1128
  messages: list,
@@ -1303,6 +1307,7 @@ class AsyncMemory(MemoryBase):
1303
1307
  )
1304
1308
  return returned_memories
1305
1309
 
1310
+ @time_perf
1306
1311
  async def _add_to_graph(self, messages, filters):
1307
1312
  added_entities = []
1308
1313
  if self.enable_graph:
@@ -1,8 +1,13 @@
1
- import hashlib
2
1
  import re
2
+ import time
3
+ import hashlib
4
+ import logging
5
+ import asyncio
6
+ from functools import wraps
3
7
 
4
8
  from mem0.configs.prompts import FACT_RETRIEVAL_PROMPT
5
9
 
10
+ logger = logging.getLogger(__name__)
6
11
 
7
12
  def get_fact_retrieval_messages(message):
8
13
  return FACT_RETRIEVAL_PROMPT, f"Input:\n{message}"
@@ -182,3 +187,26 @@ def sanitize_relationship_for_cypher(relationship) -> str:
182
187
  sanitized = sanitized.replace(old, new)
183
188
 
184
189
  return re.sub(r"_+", "_", sanitized).strip("_")
190
+
191
+
192
+ def time_perf(func):
193
+ if asyncio.iscoroutinefunction(func):
194
+ @wraps(func)
195
+ async def async_wrapper(*args, **kwargs):
196
+ start = time.perf_counter()
197
+ result = await func(*args, **kwargs)
198
+ end = time.perf_counter()
199
+ elapsed = end - start
200
+ logger.warning(f"[{func.__name__}] executed in {elapsed:.6f} seconds")
201
+ return result
202
+ return async_wrapper
203
+ else:
204
+ @wraps(func)
205
+ def sync_wrapper(*args, **kwargs):
206
+ start = time.perf_counter()
207
+ result = func(*args, **kwargs)
208
+ end = time.perf_counter()
209
+ elapsed = end - start
210
+ logger.warning(f"[{func.__name__}] executed in {elapsed:.6f} seconds")
211
+ return result
212
+ return sync_wrapper
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mem0ai-azure-mysql"
7
- version = "0.1.116.3"
7
+ version = "0.1.116.5"
8
8
  description = "Long-term memory for AI Agents with Azure DefaultAzureCredential authentication and MySQL history database support"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9,<4.0"