MemoryOS 2.0.3__py3-none-any.whl

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 (315) hide show
  1. memoryos-2.0.3.dist-info/METADATA +418 -0
  2. memoryos-2.0.3.dist-info/RECORD +315 -0
  3. memoryos-2.0.3.dist-info/WHEEL +4 -0
  4. memoryos-2.0.3.dist-info/entry_points.txt +3 -0
  5. memoryos-2.0.3.dist-info/licenses/LICENSE +201 -0
  6. memos/__init__.py +20 -0
  7. memos/api/client.py +571 -0
  8. memos/api/config.py +1018 -0
  9. memos/api/context/dependencies.py +50 -0
  10. memos/api/exceptions.py +53 -0
  11. memos/api/handlers/__init__.py +62 -0
  12. memos/api/handlers/add_handler.py +158 -0
  13. memos/api/handlers/base_handler.py +194 -0
  14. memos/api/handlers/chat_handler.py +1401 -0
  15. memos/api/handlers/component_init.py +388 -0
  16. memos/api/handlers/config_builders.py +190 -0
  17. memos/api/handlers/feedback_handler.py +93 -0
  18. memos/api/handlers/formatters_handler.py +237 -0
  19. memos/api/handlers/memory_handler.py +316 -0
  20. memos/api/handlers/scheduler_handler.py +497 -0
  21. memos/api/handlers/search_handler.py +222 -0
  22. memos/api/handlers/suggestion_handler.py +117 -0
  23. memos/api/mcp_serve.py +614 -0
  24. memos/api/middleware/request_context.py +101 -0
  25. memos/api/product_api.py +38 -0
  26. memos/api/product_models.py +1206 -0
  27. memos/api/routers/__init__.py +1 -0
  28. memos/api/routers/product_router.py +477 -0
  29. memos/api/routers/server_router.py +394 -0
  30. memos/api/server_api.py +44 -0
  31. memos/api/start_api.py +433 -0
  32. memos/chunkers/__init__.py +4 -0
  33. memos/chunkers/base.py +24 -0
  34. memos/chunkers/charactertext_chunker.py +41 -0
  35. memos/chunkers/factory.py +24 -0
  36. memos/chunkers/markdown_chunker.py +62 -0
  37. memos/chunkers/sentence_chunker.py +54 -0
  38. memos/chunkers/simple_chunker.py +50 -0
  39. memos/cli.py +113 -0
  40. memos/configs/__init__.py +0 -0
  41. memos/configs/base.py +82 -0
  42. memos/configs/chunker.py +59 -0
  43. memos/configs/embedder.py +88 -0
  44. memos/configs/graph_db.py +236 -0
  45. memos/configs/internet_retriever.py +100 -0
  46. memos/configs/llm.py +151 -0
  47. memos/configs/mem_agent.py +54 -0
  48. memos/configs/mem_chat.py +81 -0
  49. memos/configs/mem_cube.py +105 -0
  50. memos/configs/mem_os.py +83 -0
  51. memos/configs/mem_reader.py +91 -0
  52. memos/configs/mem_scheduler.py +385 -0
  53. memos/configs/mem_user.py +70 -0
  54. memos/configs/memory.py +324 -0
  55. memos/configs/parser.py +38 -0
  56. memos/configs/reranker.py +18 -0
  57. memos/configs/utils.py +8 -0
  58. memos/configs/vec_db.py +80 -0
  59. memos/context/context.py +355 -0
  60. memos/dependency.py +52 -0
  61. memos/deprecation.py +262 -0
  62. memos/embedders/__init__.py +0 -0
  63. memos/embedders/ark.py +95 -0
  64. memos/embedders/base.py +106 -0
  65. memos/embedders/factory.py +29 -0
  66. memos/embedders/ollama.py +77 -0
  67. memos/embedders/sentence_transformer.py +49 -0
  68. memos/embedders/universal_api.py +51 -0
  69. memos/exceptions.py +30 -0
  70. memos/graph_dbs/__init__.py +0 -0
  71. memos/graph_dbs/base.py +274 -0
  72. memos/graph_dbs/factory.py +27 -0
  73. memos/graph_dbs/item.py +46 -0
  74. memos/graph_dbs/nebular.py +1794 -0
  75. memos/graph_dbs/neo4j.py +1942 -0
  76. memos/graph_dbs/neo4j_community.py +1058 -0
  77. memos/graph_dbs/polardb.py +5446 -0
  78. memos/hello_world.py +97 -0
  79. memos/llms/__init__.py +0 -0
  80. memos/llms/base.py +25 -0
  81. memos/llms/deepseek.py +13 -0
  82. memos/llms/factory.py +38 -0
  83. memos/llms/hf.py +443 -0
  84. memos/llms/hf_singleton.py +114 -0
  85. memos/llms/ollama.py +135 -0
  86. memos/llms/openai.py +222 -0
  87. memos/llms/openai_new.py +198 -0
  88. memos/llms/qwen.py +13 -0
  89. memos/llms/utils.py +14 -0
  90. memos/llms/vllm.py +218 -0
  91. memos/log.py +237 -0
  92. memos/mem_agent/base.py +19 -0
  93. memos/mem_agent/deepsearch_agent.py +391 -0
  94. memos/mem_agent/factory.py +36 -0
  95. memos/mem_chat/__init__.py +0 -0
  96. memos/mem_chat/base.py +30 -0
  97. memos/mem_chat/factory.py +21 -0
  98. memos/mem_chat/simple.py +200 -0
  99. memos/mem_cube/__init__.py +0 -0
  100. memos/mem_cube/base.py +30 -0
  101. memos/mem_cube/general.py +240 -0
  102. memos/mem_cube/navie.py +172 -0
  103. memos/mem_cube/utils.py +169 -0
  104. memos/mem_feedback/base.py +15 -0
  105. memos/mem_feedback/feedback.py +1192 -0
  106. memos/mem_feedback/simple_feedback.py +40 -0
  107. memos/mem_feedback/utils.py +230 -0
  108. memos/mem_os/client.py +5 -0
  109. memos/mem_os/core.py +1203 -0
  110. memos/mem_os/main.py +582 -0
  111. memos/mem_os/product.py +1608 -0
  112. memos/mem_os/product_server.py +455 -0
  113. memos/mem_os/utils/default_config.py +359 -0
  114. memos/mem_os/utils/format_utils.py +1403 -0
  115. memos/mem_os/utils/reference_utils.py +162 -0
  116. memos/mem_reader/__init__.py +0 -0
  117. memos/mem_reader/base.py +47 -0
  118. memos/mem_reader/factory.py +53 -0
  119. memos/mem_reader/memory.py +298 -0
  120. memos/mem_reader/multi_modal_struct.py +965 -0
  121. memos/mem_reader/read_multi_modal/__init__.py +43 -0
  122. memos/mem_reader/read_multi_modal/assistant_parser.py +311 -0
  123. memos/mem_reader/read_multi_modal/base.py +273 -0
  124. memos/mem_reader/read_multi_modal/file_content_parser.py +826 -0
  125. memos/mem_reader/read_multi_modal/image_parser.py +359 -0
  126. memos/mem_reader/read_multi_modal/multi_modal_parser.py +252 -0
  127. memos/mem_reader/read_multi_modal/string_parser.py +139 -0
  128. memos/mem_reader/read_multi_modal/system_parser.py +327 -0
  129. memos/mem_reader/read_multi_modal/text_content_parser.py +131 -0
  130. memos/mem_reader/read_multi_modal/tool_parser.py +210 -0
  131. memos/mem_reader/read_multi_modal/user_parser.py +218 -0
  132. memos/mem_reader/read_multi_modal/utils.py +358 -0
  133. memos/mem_reader/simple_struct.py +912 -0
  134. memos/mem_reader/strategy_struct.py +163 -0
  135. memos/mem_reader/utils.py +157 -0
  136. memos/mem_scheduler/__init__.py +0 -0
  137. memos/mem_scheduler/analyzer/__init__.py +0 -0
  138. memos/mem_scheduler/analyzer/api_analyzer.py +714 -0
  139. memos/mem_scheduler/analyzer/eval_analyzer.py +219 -0
  140. memos/mem_scheduler/analyzer/mos_for_test_scheduler.py +571 -0
  141. memos/mem_scheduler/analyzer/scheduler_for_eval.py +280 -0
  142. memos/mem_scheduler/base_scheduler.py +1319 -0
  143. memos/mem_scheduler/general_modules/__init__.py +0 -0
  144. memos/mem_scheduler/general_modules/api_misc.py +137 -0
  145. memos/mem_scheduler/general_modules/base.py +80 -0
  146. memos/mem_scheduler/general_modules/init_components_for_scheduler.py +425 -0
  147. memos/mem_scheduler/general_modules/misc.py +313 -0
  148. memos/mem_scheduler/general_modules/scheduler_logger.py +389 -0
  149. memos/mem_scheduler/general_modules/task_threads.py +315 -0
  150. memos/mem_scheduler/general_scheduler.py +1495 -0
  151. memos/mem_scheduler/memory_manage_modules/__init__.py +5 -0
  152. memos/mem_scheduler/memory_manage_modules/memory_filter.py +306 -0
  153. memos/mem_scheduler/memory_manage_modules/retriever.py +547 -0
  154. memos/mem_scheduler/monitors/__init__.py +0 -0
  155. memos/mem_scheduler/monitors/dispatcher_monitor.py +366 -0
  156. memos/mem_scheduler/monitors/general_monitor.py +394 -0
  157. memos/mem_scheduler/monitors/task_schedule_monitor.py +254 -0
  158. memos/mem_scheduler/optimized_scheduler.py +410 -0
  159. memos/mem_scheduler/orm_modules/__init__.py +0 -0
  160. memos/mem_scheduler/orm_modules/api_redis_model.py +518 -0
  161. memos/mem_scheduler/orm_modules/base_model.py +729 -0
  162. memos/mem_scheduler/orm_modules/monitor_models.py +261 -0
  163. memos/mem_scheduler/orm_modules/redis_model.py +699 -0
  164. memos/mem_scheduler/scheduler_factory.py +23 -0
  165. memos/mem_scheduler/schemas/__init__.py +0 -0
  166. memos/mem_scheduler/schemas/analyzer_schemas.py +52 -0
  167. memos/mem_scheduler/schemas/api_schemas.py +233 -0
  168. memos/mem_scheduler/schemas/general_schemas.py +55 -0
  169. memos/mem_scheduler/schemas/message_schemas.py +173 -0
  170. memos/mem_scheduler/schemas/monitor_schemas.py +406 -0
  171. memos/mem_scheduler/schemas/task_schemas.py +132 -0
  172. memos/mem_scheduler/task_schedule_modules/__init__.py +0 -0
  173. memos/mem_scheduler/task_schedule_modules/dispatcher.py +740 -0
  174. memos/mem_scheduler/task_schedule_modules/local_queue.py +247 -0
  175. memos/mem_scheduler/task_schedule_modules/orchestrator.py +74 -0
  176. memos/mem_scheduler/task_schedule_modules/redis_queue.py +1385 -0
  177. memos/mem_scheduler/task_schedule_modules/task_queue.py +162 -0
  178. memos/mem_scheduler/utils/__init__.py +0 -0
  179. memos/mem_scheduler/utils/api_utils.py +77 -0
  180. memos/mem_scheduler/utils/config_utils.py +100 -0
  181. memos/mem_scheduler/utils/db_utils.py +50 -0
  182. memos/mem_scheduler/utils/filter_utils.py +176 -0
  183. memos/mem_scheduler/utils/metrics.py +125 -0
  184. memos/mem_scheduler/utils/misc_utils.py +290 -0
  185. memos/mem_scheduler/utils/monitor_event_utils.py +67 -0
  186. memos/mem_scheduler/utils/status_tracker.py +229 -0
  187. memos/mem_scheduler/webservice_modules/__init__.py +0 -0
  188. memos/mem_scheduler/webservice_modules/rabbitmq_service.py +485 -0
  189. memos/mem_scheduler/webservice_modules/redis_service.py +380 -0
  190. memos/mem_user/factory.py +94 -0
  191. memos/mem_user/mysql_persistent_user_manager.py +271 -0
  192. memos/mem_user/mysql_user_manager.py +502 -0
  193. memos/mem_user/persistent_factory.py +98 -0
  194. memos/mem_user/persistent_user_manager.py +260 -0
  195. memos/mem_user/redis_persistent_user_manager.py +225 -0
  196. memos/mem_user/user_manager.py +488 -0
  197. memos/memories/__init__.py +0 -0
  198. memos/memories/activation/__init__.py +0 -0
  199. memos/memories/activation/base.py +42 -0
  200. memos/memories/activation/item.py +56 -0
  201. memos/memories/activation/kv.py +292 -0
  202. memos/memories/activation/vllmkv.py +219 -0
  203. memos/memories/base.py +19 -0
  204. memos/memories/factory.py +42 -0
  205. memos/memories/parametric/__init__.py +0 -0
  206. memos/memories/parametric/base.py +19 -0
  207. memos/memories/parametric/item.py +11 -0
  208. memos/memories/parametric/lora.py +41 -0
  209. memos/memories/textual/__init__.py +0 -0
  210. memos/memories/textual/base.py +92 -0
  211. memos/memories/textual/general.py +236 -0
  212. memos/memories/textual/item.py +304 -0
  213. memos/memories/textual/naive.py +187 -0
  214. memos/memories/textual/prefer_text_memory/__init__.py +0 -0
  215. memos/memories/textual/prefer_text_memory/adder.py +504 -0
  216. memos/memories/textual/prefer_text_memory/config.py +106 -0
  217. memos/memories/textual/prefer_text_memory/extractor.py +221 -0
  218. memos/memories/textual/prefer_text_memory/factory.py +85 -0
  219. memos/memories/textual/prefer_text_memory/retrievers.py +177 -0
  220. memos/memories/textual/prefer_text_memory/spliter.py +132 -0
  221. memos/memories/textual/prefer_text_memory/utils.py +93 -0
  222. memos/memories/textual/preference.py +344 -0
  223. memos/memories/textual/simple_preference.py +161 -0
  224. memos/memories/textual/simple_tree.py +69 -0
  225. memos/memories/textual/tree.py +459 -0
  226. memos/memories/textual/tree_text_memory/__init__.py +0 -0
  227. memos/memories/textual/tree_text_memory/organize/__init__.py +0 -0
  228. memos/memories/textual/tree_text_memory/organize/handler.py +184 -0
  229. memos/memories/textual/tree_text_memory/organize/manager.py +518 -0
  230. memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +238 -0
  231. memos/memories/textual/tree_text_memory/organize/reorganizer.py +622 -0
  232. memos/memories/textual/tree_text_memory/retrieve/__init__.py +0 -0
  233. memos/memories/textual/tree_text_memory/retrieve/advanced_searcher.py +364 -0
  234. memos/memories/textual/tree_text_memory/retrieve/bm25_util.py +186 -0
  235. memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +419 -0
  236. memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +270 -0
  237. memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +102 -0
  238. memos/memories/textual/tree_text_memory/retrieve/reasoner.py +61 -0
  239. memos/memories/textual/tree_text_memory/retrieve/recall.py +497 -0
  240. memos/memories/textual/tree_text_memory/retrieve/reranker.py +111 -0
  241. memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +16 -0
  242. memos/memories/textual/tree_text_memory/retrieve/retrieve_utils.py +472 -0
  243. memos/memories/textual/tree_text_memory/retrieve/searcher.py +848 -0
  244. memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +135 -0
  245. memos/memories/textual/tree_text_memory/retrieve/utils.py +54 -0
  246. memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +387 -0
  247. memos/memos_tools/dinding_report_bot.py +453 -0
  248. memos/memos_tools/lockfree_dict.py +120 -0
  249. memos/memos_tools/notification_service.py +44 -0
  250. memos/memos_tools/notification_utils.py +142 -0
  251. memos/memos_tools/singleton.py +174 -0
  252. memos/memos_tools/thread_safe_dict.py +310 -0
  253. memos/memos_tools/thread_safe_dict_segment.py +382 -0
  254. memos/multi_mem_cube/__init__.py +0 -0
  255. memos/multi_mem_cube/composite_cube.py +86 -0
  256. memos/multi_mem_cube/single_cube.py +874 -0
  257. memos/multi_mem_cube/views.py +54 -0
  258. memos/parsers/__init__.py +0 -0
  259. memos/parsers/base.py +15 -0
  260. memos/parsers/factory.py +21 -0
  261. memos/parsers/markitdown.py +28 -0
  262. memos/reranker/__init__.py +4 -0
  263. memos/reranker/base.py +25 -0
  264. memos/reranker/concat.py +103 -0
  265. memos/reranker/cosine_local.py +102 -0
  266. memos/reranker/factory.py +72 -0
  267. memos/reranker/http_bge.py +324 -0
  268. memos/reranker/http_bge_strategy.py +327 -0
  269. memos/reranker/noop.py +19 -0
  270. memos/reranker/strategies/__init__.py +4 -0
  271. memos/reranker/strategies/base.py +61 -0
  272. memos/reranker/strategies/concat_background.py +94 -0
  273. memos/reranker/strategies/concat_docsource.py +110 -0
  274. memos/reranker/strategies/dialogue_common.py +109 -0
  275. memos/reranker/strategies/factory.py +31 -0
  276. memos/reranker/strategies/single_turn.py +107 -0
  277. memos/reranker/strategies/singleturn_outmem.py +98 -0
  278. memos/settings.py +10 -0
  279. memos/templates/__init__.py +0 -0
  280. memos/templates/advanced_search_prompts.py +211 -0
  281. memos/templates/cloud_service_prompt.py +107 -0
  282. memos/templates/instruction_completion.py +66 -0
  283. memos/templates/mem_agent_prompts.py +85 -0
  284. memos/templates/mem_feedback_prompts.py +822 -0
  285. memos/templates/mem_reader_prompts.py +1096 -0
  286. memos/templates/mem_reader_strategy_prompts.py +238 -0
  287. memos/templates/mem_scheduler_prompts.py +626 -0
  288. memos/templates/mem_search_prompts.py +93 -0
  289. memos/templates/mos_prompts.py +403 -0
  290. memos/templates/prefer_complete_prompt.py +735 -0
  291. memos/templates/tool_mem_prompts.py +139 -0
  292. memos/templates/tree_reorganize_prompts.py +230 -0
  293. memos/types/__init__.py +34 -0
  294. memos/types/general_types.py +151 -0
  295. memos/types/openai_chat_completion_types/__init__.py +15 -0
  296. memos/types/openai_chat_completion_types/chat_completion_assistant_message_param.py +56 -0
  297. memos/types/openai_chat_completion_types/chat_completion_content_part_image_param.py +27 -0
  298. memos/types/openai_chat_completion_types/chat_completion_content_part_input_audio_param.py +23 -0
  299. memos/types/openai_chat_completion_types/chat_completion_content_part_param.py +43 -0
  300. memos/types/openai_chat_completion_types/chat_completion_content_part_refusal_param.py +16 -0
  301. memos/types/openai_chat_completion_types/chat_completion_content_part_text_param.py +16 -0
  302. memos/types/openai_chat_completion_types/chat_completion_message_custom_tool_call_param.py +27 -0
  303. memos/types/openai_chat_completion_types/chat_completion_message_function_tool_call_param.py +32 -0
  304. memos/types/openai_chat_completion_types/chat_completion_message_param.py +18 -0
  305. memos/types/openai_chat_completion_types/chat_completion_message_tool_call_union_param.py +15 -0
  306. memos/types/openai_chat_completion_types/chat_completion_system_message_param.py +36 -0
  307. memos/types/openai_chat_completion_types/chat_completion_tool_message_param.py +30 -0
  308. memos/types/openai_chat_completion_types/chat_completion_user_message_param.py +34 -0
  309. memos/utils.py +123 -0
  310. memos/vec_dbs/__init__.py +0 -0
  311. memos/vec_dbs/base.py +117 -0
  312. memos/vec_dbs/factory.py +23 -0
  313. memos/vec_dbs/item.py +50 -0
  314. memos/vec_dbs/milvus.py +654 -0
  315. memos/vec_dbs/qdrant.py +355 -0
@@ -0,0 +1,274 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Literal
3
+
4
+
5
+ class BaseGraphDB(ABC):
6
+ """
7
+ Abstract base class for a graph database interface used in a memory-augmented RAG system.
8
+ """
9
+
10
+ # Node (Memory) Management
11
+ @abstractmethod
12
+ def add_node(self, id: str, memory: str, metadata: dict[str, Any]) -> None:
13
+ """
14
+ Add a memory node to the graph.
15
+ Args:
16
+ id: Unique identifier for the memory node.
17
+ memory: Raw memory content (e.g., text).
18
+ metadata: Dictionary of metadata (e.g., timestamp, tags, source).
19
+ """
20
+
21
+ @abstractmethod
22
+ def update_node(self, id: str, fields: dict[str, Any], user_name: str | None = None) -> None:
23
+ """
24
+ Update attributes of an existing node.
25
+ Args:
26
+ id: Node identifier to be updated.
27
+ fields: Dictionary of fields to update.
28
+ user_name: given user_name
29
+ """
30
+
31
+ @abstractmethod
32
+ def delete_node(self, id: str) -> None:
33
+ """
34
+ Delete a node from the graph.
35
+ Args:
36
+ id: Node identifier to delete.
37
+ """
38
+
39
+ # Edge (Relationship) Management
40
+ @abstractmethod
41
+ def add_edge(self, source_id: str, target_id: str, type: str) -> None:
42
+ """
43
+ Create an edge from source node to target node.
44
+ Args:
45
+ source_id: ID of the source node.
46
+ target_id: ID of the target node.
47
+ type: Relationship type (e.g., 'FOLLOWS', 'CAUSES', 'PARENT').
48
+ """
49
+
50
+ @abstractmethod
51
+ def delete_edge(self, source_id: str, target_id: str, type: str) -> None:
52
+ """
53
+ Delete a specific edge between two nodes.
54
+ Args:
55
+ source_id: ID of the source node.
56
+ target_id: ID of the target node.
57
+ type: Relationship type to remove.
58
+ """
59
+
60
+ @abstractmethod
61
+ def edge_exists(self, source_id: str, target_id: str, type: str) -> bool:
62
+ """
63
+ Check if an edge exists between two nodes.
64
+ Args:
65
+ source_id: ID of the source node.
66
+ target_id: ID of the target node.
67
+ type: Relationship type.
68
+ Returns:
69
+ True if the edge exists, otherwise False.
70
+ """
71
+
72
+ # Graph Query & Reasoning
73
+ @abstractmethod
74
+ def get_node(self, id: str, include_embedding: bool = False, **kwargs) -> dict[str, Any] | None:
75
+ """
76
+ Retrieve the metadata and content of a node.
77
+ Args:
78
+ id: Node identifier.
79
+ include_embedding: with/without embedding
80
+ Returns:
81
+ Dictionary of node fields, or None if not found.
82
+ """
83
+
84
+ @abstractmethod
85
+ def get_nodes(
86
+ self, ids: list, include_embedding: bool = False, **kwargs
87
+ ) -> dict[str, Any] | None:
88
+ """
89
+ Retrieve the metadata and memory of a list of nodes.
90
+ Args:
91
+ ids: List of Node identifier.
92
+ include_embedding: with/without embedding
93
+ Returns:
94
+ list[dict]: Parsed node records containing 'id', 'memory', and 'metadata'.
95
+ """
96
+
97
+ @abstractmethod
98
+ def get_neighbors(
99
+ self, id: str, type: str, direction: Literal["in", "out", "both"] = "out"
100
+ ) -> list[str]:
101
+ """
102
+ Get connected node IDs in a specific direction and relationship type.
103
+ Args:
104
+ id: Source node ID.
105
+ type: Relationship type.
106
+ direction: Edge direction to follow ('out', 'in', or 'both').
107
+ Returns:
108
+ List of neighboring node IDs.
109
+ """
110
+
111
+ @abstractmethod
112
+ def get_path(self, source_id: str, target_id: str, max_depth: int = 3) -> list[str]:
113
+ """
114
+ Get the path of nodes from source to target within a limited depth.
115
+ Args:
116
+ source_id: Starting node ID.
117
+ target_id: Target node ID.
118
+ max_depth: Maximum path length to traverse.
119
+ Returns:
120
+ Ordered list of node IDs along the path.
121
+ """
122
+
123
+ @abstractmethod
124
+ def get_subgraph(self, center_id: str, depth: int = 2) -> list[str]:
125
+ """
126
+ Retrieve a local subgraph centered at a given node.
127
+ Args:
128
+ center_id: Center node ID.
129
+ depth: Radius to include neighboring nodes.
130
+ Returns:
131
+ List of node IDs in the subgraph.
132
+ """
133
+
134
+ @abstractmethod
135
+ def get_context_chain(self, id: str, type: str = "FOLLOWS") -> list[str]:
136
+ """
137
+ Get the ordered context chain starting from a node, following a relationship type.
138
+ Args:
139
+ id: Starting node ID.
140
+ type: Relationship type to follow (e.g., 'FOLLOWS').
141
+ Returns:
142
+ List of ordered node IDs in the chain.
143
+ """
144
+
145
+ # Search / recall operations
146
+ @abstractmethod
147
+ def search_by_embedding(self, vector: list[float], top_k: int = 5, **kwargs) -> list[dict]:
148
+ """
149
+ Retrieve node IDs based on vector similarity.
150
+
151
+ Args:
152
+ vector (list[float]): The embedding vector representing query semantics.
153
+ top_k (int): Number of top similar nodes to retrieve.
154
+
155
+ Returns:
156
+ list[dict]: A list of dicts with 'id' and 'score', ordered by similarity.
157
+
158
+ Notes:
159
+ - This method may internally call a VecDB (e.g., Qdrant) or store embeddings in the graph DB itself.
160
+ - Commonly used for RAG recall stage to find semantically similar memories.
161
+ """
162
+
163
+ @abstractmethod
164
+ def get_by_metadata(
165
+ self, filters: list[dict[str, Any]], status: str | None = None
166
+ ) -> list[str]:
167
+ """
168
+ Retrieve node IDs that match given metadata filters.
169
+
170
+ Args:
171
+ filters (dict[str, Any]): A dictionary of attribute-value filters.
172
+ Example: {"topic": "psychology", "importance": 2}
173
+ status (str, optional): Filter by status (e.g., 'activated', 'archived').
174
+ If None, no status filter is applied.
175
+
176
+ Returns:
177
+ list[str]: Node IDs whose metadata match the filter conditions.
178
+
179
+ Notes:
180
+ - Supports structured querying such as tag/category/importance/time filtering.
181
+ - Can be used for faceted recall or prefiltering before embedding rerank.
182
+ """
183
+
184
+ @abstractmethod
185
+ def get_structure_optimization_candidates(
186
+ self, scope: str, include_embedding: bool = False
187
+ ) -> list[dict]:
188
+ """
189
+ Find nodes that are likely candidates for structure optimization:
190
+ - Isolated nodes, nodes with empty background, or nodes with exactly one child.
191
+ - Plus: the child of any parent node that has exactly one child.
192
+ """
193
+
194
+ # Structure Maintenance
195
+ @abstractmethod
196
+ def deduplicate_nodes(self) -> None:
197
+ """
198
+ Deduplicate redundant or semantically similar nodes.
199
+ This typically involves identifying nodes with identical or near-identical content.
200
+ """
201
+
202
+ @abstractmethod
203
+ def detect_conflicts(self) -> list[tuple[str, str]]:
204
+ """
205
+ Detect conflicting nodes based on logical or semantic inconsistency.
206
+ Returns:
207
+ A list of (node_id1, node_id2) tuples that conflict.
208
+ """
209
+
210
+ @abstractmethod
211
+ def merge_nodes(self, id1: str, id2: str) -> str:
212
+ """
213
+ Merge two similar or duplicate nodes into one.
214
+ Args:
215
+ id1: First node ID.
216
+ id2: Second node ID.
217
+ Returns:
218
+ ID of the resulting merged node.
219
+ """
220
+
221
+ # Utilities
222
+ @abstractmethod
223
+ def clear(self) -> None:
224
+ """
225
+ Clear the entire graph.
226
+ """
227
+
228
+ @abstractmethod
229
+ def export_graph(self, include_embedding: bool = False) -> dict[str, Any]:
230
+ """
231
+ Export the entire graph as a serializable dictionary.
232
+
233
+ Returns:
234
+ A dictionary containing all nodes and edges.
235
+ """
236
+
237
+ @abstractmethod
238
+ def import_graph(self, data: dict[str, Any]) -> None:
239
+ """
240
+ Import the entire graph from a serialized dictionary.
241
+
242
+ Args:
243
+ data: A dictionary containing all nodes and edges to be loaded.
244
+ """
245
+
246
+ @abstractmethod
247
+ def get_all_memory_items(
248
+ self, scope: str, include_embedding: bool = False, status: str | None = None
249
+ ) -> list[dict]:
250
+ """
251
+ Retrieve all memory items of a specific memory_type.
252
+
253
+ Args:
254
+ scope (str): Must be one of 'WorkingMemory', 'LongTermMemory', or 'UserMemory'.
255
+ include_embedding: with/without embedding
256
+ status (str, optional): Filter by status (e.g., 'activated', 'archived').
257
+ If None, no status filter is applied.
258
+
259
+ Returns:
260
+ list[dict]: Full list of memory items under this scope.
261
+ """
262
+
263
+ @abstractmethod
264
+ def add_nodes_batch(self, nodes: list[dict[str, Any]], user_name: str | None = None) -> None:
265
+ """
266
+ Batch add multiple memory nodes to the graph.
267
+
268
+ Args:
269
+ nodes: List of node dictionaries, each containing:
270
+ - id: str - Node ID
271
+ - memory: str - Memory content
272
+ - metadata: dict[str, Any] - Node metadata
273
+ user_name: Optional user name (will use config default if not provided)
274
+ """
@@ -0,0 +1,27 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from memos.configs.graph_db import GraphDBConfigFactory
4
+ from memos.graph_dbs.base import BaseGraphDB
5
+ from memos.graph_dbs.nebular import NebulaGraphDB
6
+ from memos.graph_dbs.neo4j import Neo4jGraphDB
7
+ from memos.graph_dbs.neo4j_community import Neo4jCommunityGraphDB
8
+ from memos.graph_dbs.polardb import PolarDBGraphDB
9
+
10
+
11
+ class GraphStoreFactory(BaseGraphDB):
12
+ """Factory for creating graph store instances."""
13
+
14
+ backend_to_class: ClassVar[dict[str, Any]] = {
15
+ "neo4j": Neo4jGraphDB,
16
+ "neo4j-community": Neo4jCommunityGraphDB,
17
+ "nebular": NebulaGraphDB,
18
+ "polardb": PolarDBGraphDB,
19
+ }
20
+
21
+ @classmethod
22
+ def from_config(cls, config_factory: GraphDBConfigFactory) -> BaseGraphDB:
23
+ backend = config_factory.backend
24
+ if backend not in cls.backend_to_class:
25
+ raise ValueError(f"Unsupported graph database backend: {backend}")
26
+ graph_class = cls.backend_to_class[backend]
27
+ return graph_class(config_factory.config)
@@ -0,0 +1,46 @@
1
+ import uuid
2
+
3
+ from typing import Any, Literal
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
6
+
7
+ from memos.memories.textual.item import TextualMemoryItem
8
+
9
+
10
+ class GraphDBNode(TextualMemoryItem):
11
+ pass
12
+
13
+
14
+ class GraphDBEdge(BaseModel):
15
+ """Represents an edge in a graph database (corresponds to Neo4j relationship)."""
16
+
17
+ id: str = Field(
18
+ default_factory=lambda: str(uuid.uuid4()), description="Unique identifier for the edge"
19
+ )
20
+ source: str = Field(..., description="Source node ID")
21
+ target: str = Field(..., description="Target node ID")
22
+ type: Literal["RELATED", "PARENT"] = Field(
23
+ ..., description="Relationship type (must be one of 'RELATED', 'PARENT')"
24
+ )
25
+ properties: dict[str, Any] | None = Field(
26
+ default=None, description="Additional properties for the edge"
27
+ )
28
+
29
+ model_config = ConfigDict(extra="forbid")
30
+
31
+ @field_validator("id")
32
+ @classmethod
33
+ def validate_id(cls, v):
34
+ """Validate that ID is a valid UUID."""
35
+ if not isinstance(v, str) or not uuid.UUID(v, version=4):
36
+ raise ValueError("ID must be a valid UUID string")
37
+ return v
38
+
39
+ @classmethod
40
+ def from_dict(cls, data: dict[str, Any]) -> "GraphDBEdge":
41
+ """Create GraphDBEdge from dictionary."""
42
+ return cls(**data)
43
+
44
+ def to_dict(self) -> dict[str, Any]:
45
+ """Convert to dictionary format."""
46
+ return self.model_dump(exclude_none=True)