mem0ai-azure-mysql 0.1.116.4__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.4 → mem0ai_azure_mysql-0.1.116.5}/PKG-INFO +1 -1
  2. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/azure_openai.py +15 -3
  3. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/graph_memory.py +81 -37
  4. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/main.py +2 -0
  5. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/utils.py +21 -9
  6. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/pyproject.toml +1 -1
  7. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/.gitignore +0 -0
  8. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/README.md +0 -0
  9. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/__init__.py +0 -0
  10. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/__init__.py +0 -0
  11. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/main.py +0 -0
  12. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/project.py +0 -0
  13. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/client/utils.py +0 -0
  14. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/__init__.py +0 -0
  15. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/base.py +0 -0
  16. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/__init__.py +0 -0
  17. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/base.py +0 -0
  18. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/dbs/mysql.py +0 -0
  19. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/embeddings/__init__.py +0 -0
  20. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/embeddings/base.py +0 -0
  21. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/enums.py +0 -0
  22. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/__init__.py +0 -0
  23. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/anthropic.py +0 -0
  24. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/aws_bedrock.py +0 -0
  25. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/azure.py +0 -0
  26. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/base.py +0 -0
  27. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/deepseek.py +0 -0
  28. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/lmstudio.py +0 -0
  29. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/ollama.py +0 -0
  30. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/openai.py +0 -0
  31. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/llms/vllm.py +0 -0
  32. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/prompts.py +0 -0
  33. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/__init__.py +0 -0
  34. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/azure_ai_search.py +0 -0
  35. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/baidu.py +0 -0
  36. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/chroma.py +0 -0
  37. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/databricks.py +0 -0
  38. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/elasticsearch.py +0 -0
  39. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/faiss.py +0 -0
  40. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/langchain.py +0 -0
  41. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/milvus.py +0 -0
  42. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/mongodb.py +0 -0
  43. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/opensearch.py +0 -0
  44. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/pgvector.py +0 -0
  45. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/pinecone.py +0 -0
  46. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/qdrant.py +0 -0
  47. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/redis.py +0 -0
  48. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/supabase.py +0 -0
  49. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/upstash_vector.py +0 -0
  50. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/vertex_ai_vector_search.py +0 -0
  51. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/configs/vector_stores/weaviate.py +0 -0
  52. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/__init__.py +0 -0
  53. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/base.py +0 -0
  54. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/configs.py +0 -0
  55. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/dbs/mysql.py +0 -0
  56. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/__init__.py +0 -0
  57. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/aws_bedrock.py +0 -0
  58. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/base.py +0 -0
  59. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/configs.py +0 -0
  60. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/gemini.py +0 -0
  61. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/huggingface.py +0 -0
  62. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/langchain.py +0 -0
  63. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/lmstudio.py +0 -0
  64. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/mock.py +0 -0
  65. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/ollama.py +0 -0
  66. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/openai.py +0 -0
  67. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/together.py +0 -0
  68. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/embeddings/vertexai.py +0 -0
  69. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/__init__.py +0 -0
  70. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/configs.py +0 -0
  71. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/__init__.py +0 -0
  72. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/base.py +0 -0
  73. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/neptune/main.py +0 -0
  74. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/tools.py +0 -0
  75. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/graphs/utils.py +0 -0
  76. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/__init__.py +0 -0
  77. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/anthropic.py +0 -0
  78. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/aws_bedrock.py +0 -0
  79. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/azure_openai.py +0 -0
  80. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/azure_openai_structured.py +0 -0
  81. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/base.py +0 -0
  82. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/configs.py +0 -0
  83. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/deepseek.py +0 -0
  84. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/gemini.py +0 -0
  85. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/groq.py +0 -0
  86. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/langchain.py +0 -0
  87. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/litellm.py +0 -0
  88. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/lmstudio.py +0 -0
  89. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/ollama.py +0 -0
  90. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/openai.py +0 -0
  91. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/openai_structured.py +0 -0
  92. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/sarvam.py +0 -0
  93. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/together.py +0 -0
  94. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/vllm.py +0 -0
  95. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/llms/xai.py +0 -0
  96. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/__init__.py +0 -0
  97. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/base.py +0 -0
  98. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/kuzu_memory.py +0 -0
  99. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/memgraph_memory.py +0 -0
  100. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/setup.py +0 -0
  101. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/storage.py +0 -0
  102. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/memory/telemetry.py +0 -0
  103. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/proxy/__init__.py +0 -0
  104. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/proxy/main.py +0 -0
  105. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/utils/factory.py +0 -0
  106. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/__init__.py +0 -0
  107. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/azure_ai_search.py +0 -0
  108. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/baidu.py +0 -0
  109. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/base.py +0 -0
  110. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/chroma.py +0 -0
  111. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/configs.py +0 -0
  112. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/databricks.py +0 -0
  113. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/elasticsearch.py +0 -0
  114. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/faiss.py +0 -0
  115. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/langchain.py +0 -0
  116. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/milvus.py +0 -0
  117. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/mongodb.py +0 -0
  118. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/opensearch.py +0 -0
  119. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/pgvector.py +0 -0
  120. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/pinecone.py +0 -0
  121. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/qdrant.py +0 -0
  122. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/redis.py +0 -0
  123. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/supabase.py +0 -0
  124. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/upstash_vector.py +0 -0
  125. {mem0ai_azure_mysql-0.1.116.4 → mem0ai_azure_mysql-0.1.116.5}/mem0/vector_stores/vertex_ai_vector_search.py +0 -0
  126. {mem0ai_azure_mysql-0.1.116.4 → 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.4
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
@@ -10,6 +10,9 @@ from mem0.memory.utils import time_perf
10
10
 
11
11
 
12
12
  class AzureOpenAIEmbedding(EmbeddingBase):
13
+
14
+ cached_embeddings = {}
15
+
13
16
  def __init__(self, config: Optional[BaseEmbedderConfig] = None):
14
17
  super().__init__(config)
15
18
 
@@ -54,7 +57,9 @@ class AzureOpenAIEmbedding(EmbeddingBase):
54
57
  list: The embedding vector.
55
58
  """
56
59
  text = text.replace("\n", " ")
57
- 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]
58
63
 
59
64
  @time_perf
60
65
  def embed_in_batch(self, texts, memory_action: Optional[Literal["add", "search", "update"]] = None):
@@ -68,5 +73,12 @@ class AzureOpenAIEmbedding(EmbeddingBase):
68
73
  list: List of the embedding vector.
69
74
  """
70
75
  texts = [text.replace("\n", " ") for text in texts]
71
- resp = self.client.embeddings.create(input=texts, model=self.config.model)
72
- return [item.embedding for item in resp.data]
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]
@@ -318,52 +318,51 @@ class MemoryGraph:
318
318
  @time_perf
319
319
  def _search_graph_db(self, node_list, filters, limit=100):
320
320
  """Search similar nodes among and their respective incoming and outgoing relations."""
321
- result_relations = []
322
-
323
321
  # Build node properties for filtering
324
- node_props = ["user_id: $user_id"]
322
+ node_props = ["user_id: row.user_id"]
325
323
  if filters.get("agent_id"):
326
- node_props.append("agent_id: $agent_id")
324
+ node_props.append("agent_id: row.agent_id")
327
325
  if filters.get("run_id"):
328
- node_props.append("run_id: $run_id")
326
+ node_props.append("run_id: row.run_id")
329
327
  node_props_str = ", ".join(node_props)
330
328
  n_embeddings = self.embedding_model.embed_in_batch(node_list)
331
329
 
332
- for n_embedding in n_embeddings:
333
-
334
- cypher_query = f"""
335
- MATCH (n {self.node_label} {{{node_props_str}}})
336
- WHERE n.embedding IS NOT NULL
337
- WITH n, round(2 * vector.similarity.cosine(n.embedding, $n_embedding) - 1, 4) AS similarity // denormalize for backward compatibility
338
- WHERE similarity >= $threshold
339
- CALL {{
340
- WITH n
341
- MATCH (n)-[r]->(m {self.node_label} {{{node_props_str}}})
342
- 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
343
- UNION
344
- WITH n
345
- MATCH (n)<-[r]-(m {self.node_label} {{{node_props_str}}})
346
- 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
347
- }}
348
- WITH distinct source, source_id, relationship, relation_id, destination, destination_id, similarity
349
- RETURN source, source_id, relationship, relation_id, destination, destination_id, similarity
350
- ORDER BY similarity DESC
351
- LIMIT $limit
352
- """
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
+ """
353
350
 
354
- params = {
351
+ rows = []
352
+ for n_embedding in n_embeddings:
353
+ row = {
355
354
  "n_embedding": n_embedding,
356
355
  "threshold": self.threshold,
357
356
  "user_id": filters["user_id"],
358
- "limit": limit,
359
357
  }
360
358
  if filters.get("agent_id"):
361
- params["agent_id"] = filters["agent_id"]
359
+ row["agent_id"] = filters["agent_id"]
362
360
  if filters.get("run_id"):
363
- params["run_id"] = filters["run_id"]
364
-
365
- ans = self.graph.query(cypher_query, params=params)
366
- 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})
367
366
 
368
367
  # Remove duplicates, key is (source, relationship, destination)
369
368
  seen = set()
@@ -476,6 +475,39 @@ class MemoryGraph:
476
475
  agent_id = filters.get("agent_id", None)
477
476
  run_id = filters.get("run_id", None)
478
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
+
479
511
  for item in to_be_added:
480
512
  # entities
481
513
  source = item["source"]
@@ -491,12 +523,12 @@ class MemoryGraph:
491
523
  destination_extra_set = f", destination:`{destination_type}`" if self.node_label else ""
492
524
 
493
525
  # embeddings
494
- source_embedding = self.embedding_model.embed(source)
495
- dest_embedding = self.embedding_model.embed(destination)
526
+ source_embedding = embedding_map[source]
527
+ dest_embedding = embedding_map[destination]
496
528
 
497
529
  # search for the nodes with the closest embeddings
498
- source_node_search_result = self._search_source_node(source_embedding, filters, threshold=0.9)
499
- 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)
500
532
 
501
533
  # TODO: Create a cypher query and common params for all the cases
502
534
  if not destination_node_search_result and source_node_search_result:
@@ -542,6 +574,8 @@ class MemoryGraph:
542
574
  params["agent_id"] = agent_id
543
575
  if run_id:
544
576
  params["run_id"] = run_id
577
+
578
+ query_stats[1] += 1
545
579
 
546
580
  elif destination_node_search_result and not source_node_search_result:
547
581
  # Build source MERGE properties
@@ -586,6 +620,8 @@ class MemoryGraph:
586
620
  params["agent_id"] = agent_id
587
621
  if run_id:
588
622
  params["run_id"] = run_id
623
+
624
+ query_stats[2] += 1
589
625
 
590
626
  elif source_node_search_result and destination_node_search_result:
591
627
  cypher = f"""
@@ -614,6 +650,8 @@ class MemoryGraph:
614
650
  params["agent_id"] = agent_id
615
651
  if run_id:
616
652
  params["run_id"] = run_id
653
+
654
+ query_stats[3] += 1
617
655
 
618
656
  else:
619
657
  # Build dynamic MERGE props for both source and destination
@@ -662,8 +700,12 @@ class MemoryGraph:
662
700
  params["agent_id"] = agent_id
663
701
  if run_id:
664
702
  params["run_id"] = run_id
703
+
704
+ query_stats[4] += 1
705
+
665
706
  result = self.graph.query(cypher, params=params)
666
707
  results.append(result)
708
+ logger.warning(f"Add entities query stats: {query_stats}")
667
709
  return results
668
710
 
669
711
  def _remove_spaces_from_entities(self, entity_list):
@@ -674,6 +716,7 @@ class MemoryGraph:
674
716
  item["destination"] = item["destination"].lower().replace(" ", "_")
675
717
  return entity_list
676
718
 
719
+ @time_perf
677
720
  def _search_source_node(self, source_embedding, filters, threshold=0.9):
678
721
  # Build WHERE conditions
679
722
  where_conditions = ["source_candidate.embedding IS NOT NULL", "source_candidate.user_id = $user_id"]
@@ -711,6 +754,7 @@ class MemoryGraph:
711
754
  result = self.graph.query(cypher, params=params)
712
755
  return result
713
756
 
757
+ @time_perf
714
758
  def _search_destination_node(self, destination_embedding, filters, threshold=0.9):
715
759
  # Build WHERE conditions
716
760
  where_conditions = ["destination_candidate.embedding IS NOT NULL", "destination_candidate.user_id = $user_id"]
@@ -1122,6 +1122,7 @@ class AsyncMemory(MemoryBase):
1122
1122
 
1123
1123
  return {"results": vector_store_result}
1124
1124
 
1125
+ @time_perf
1125
1126
  async def _add_to_vector_store(
1126
1127
  self,
1127
1128
  messages: list,
@@ -1306,6 +1307,7 @@ class AsyncMemory(MemoryBase):
1306
1307
  )
1307
1308
  return returned_memories
1308
1309
 
1310
+ @time_perf
1309
1311
  async def _add_to_graph(self, messages, filters):
1310
1312
  added_entities = []
1311
1313
  if self.enable_graph:
@@ -2,6 +2,7 @@ import re
2
2
  import time
3
3
  import hashlib
4
4
  import logging
5
+ import asyncio
5
6
  from functools import wraps
6
7
 
7
8
  from mem0.configs.prompts import FACT_RETRIEVAL_PROMPT
@@ -189,12 +190,23 @@ def sanitize_relationship_for_cypher(relationship) -> str:
189
190
 
190
191
 
191
192
  def time_perf(func):
192
- @wraps(func)
193
- def wrapper(*args, **kwargs):
194
- start = time.perf_counter()
195
- result = func(*args, **kwargs)
196
- end = time.perf_counter()
197
- elapsed = end - start
198
- logger.debug(f"[{func.__name__}] executed in {elapsed:.6f} seconds")
199
- return result
200
- return wrapper
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.4"
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"