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,43 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal, TypeAlias
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+ from .chat_completion_content_part_image_param import ChatCompletionContentPartImageParam
8
+ from .chat_completion_content_part_input_audio_param import ChatCompletionContentPartInputAudioParam
9
+ from .chat_completion_content_part_text_param import ChatCompletionContentPartTextParam
10
+
11
+
12
+ __all__ = ["ChatCompletionContentPartParam", "File", "FileFile"]
13
+
14
+
15
+ class FileFile(TypedDict, total=False):
16
+ file_data: str
17
+ """
18
+ The base64 encoded file data, used when passing the file to the model as a
19
+ string.
20
+ or a url.
21
+ or just string which is the content of the file.
22
+ """
23
+
24
+ file_id: str
25
+ """The ID of an uploaded file to use as input."""
26
+
27
+ filename: str
28
+ """The name of the file, used when passing the file to the model as a string."""
29
+
30
+
31
+ class File(TypedDict, total=False):
32
+ file: Required[FileFile]
33
+
34
+ type: Required[Literal["file"]]
35
+ """The type of the content part. Always `file`."""
36
+
37
+
38
+ ChatCompletionContentPartParam: TypeAlias = (
39
+ ChatCompletionContentPartTextParam
40
+ | ChatCompletionContentPartImageParam
41
+ | ChatCompletionContentPartInputAudioParam
42
+ | File
43
+ )
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+
8
+ __all__ = ["ChatCompletionContentPartRefusalParam"]
9
+
10
+
11
+ class ChatCompletionContentPartRefusalParam(TypedDict, total=False):
12
+ refusal: Required[str]
13
+ """The refusal message generated by the model."""
14
+
15
+ type: Required[Literal["refusal"]]
16
+ """The type of the content part."""
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+
8
+ __all__ = ["ChatCompletionContentPartTextParam"]
9
+
10
+
11
+ class ChatCompletionContentPartTextParam(TypedDict, total=False):
12
+ text: Required[str]
13
+ """The text content."""
14
+
15
+ type: Required[Literal["text"]]
16
+ """The type of the content part."""
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+
8
+ __all__ = ["ChatCompletionMessageCustomToolCallParam", "Custom"]
9
+
10
+
11
+ class Custom(TypedDict, total=False):
12
+ input: Required[str]
13
+ """The input for the custom tool call generated by the model."""
14
+
15
+ name: Required[str]
16
+ """The name of the custom tool to call."""
17
+
18
+
19
+ class ChatCompletionMessageCustomToolCallParam(TypedDict, total=False):
20
+ id: Required[str]
21
+ """The ID of the tool call."""
22
+
23
+ custom: Required[Custom]
24
+ """The custom tool that the model called."""
25
+
26
+ type: Required[Literal["custom"]]
27
+ """The type of the tool. Always `custom`."""
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from typing_extensions import Required, TypedDict
6
+
7
+
8
+ __all__ = ["ChatCompletionMessageFunctionToolCallParam", "Function"]
9
+
10
+
11
+ class Function(TypedDict, total=False):
12
+ arguments: Required[str]
13
+ """
14
+ The arguments to call the function with, as generated by the model in JSON
15
+ format. Note that the model does not always generate valid JSON, and may
16
+ hallucinate parameters not defined by your function schema. Validate the
17
+ arguments in your code before calling your function.
18
+ """
19
+
20
+ name: Required[str]
21
+ """The name of the function to call."""
22
+
23
+
24
+ class ChatCompletionMessageFunctionToolCallParam(TypedDict, total=False):
25
+ id: Required[str]
26
+ """The ID of the tool call."""
27
+
28
+ function: Required[Function]
29
+ """The function that the model called."""
30
+
31
+ type: Required[Literal["function"]]
32
+ """The type of the tool. Currently, only `function` is supported."""
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypeAlias
4
+
5
+ from .chat_completion_assistant_message_param import ChatCompletionAssistantMessageParam
6
+ from .chat_completion_system_message_param import ChatCompletionSystemMessageParam
7
+ from .chat_completion_tool_message_param import ChatCompletionToolMessageParam
8
+ from .chat_completion_user_message_param import ChatCompletionUserMessageParam
9
+
10
+
11
+ __all__ = ["ChatCompletionMessageParam"]
12
+
13
+ ChatCompletionMessageParam: TypeAlias = (
14
+ ChatCompletionSystemMessageParam
15
+ | ChatCompletionUserMessageParam
16
+ | ChatCompletionAssistantMessageParam
17
+ | ChatCompletionToolMessageParam
18
+ )
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypeAlias
4
+
5
+ from .chat_completion_message_custom_tool_call_param import ChatCompletionMessageCustomToolCallParam
6
+ from .chat_completion_message_function_tool_call_param import (
7
+ ChatCompletionMessageFunctionToolCallParam,
8
+ )
9
+
10
+
11
+ __all__ = ["ChatCompletionMessageToolCallUnionParam"]
12
+
13
+ ChatCompletionMessageToolCallUnionParam: TypeAlias = (
14
+ ChatCompletionMessageFunctionToolCallParam | ChatCompletionMessageCustomToolCallParam
15
+ )
@@ -0,0 +1,36 @@
1
+ # ruff: noqa: TC001, TC003
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal
6
+
7
+ from typing_extensions import Required, TypedDict
8
+
9
+ from .chat_completion_content_part_text_param import ChatCompletionContentPartTextParam
10
+
11
+
12
+ __all__ = ["ChatCompletionSystemMessageParam"]
13
+
14
+
15
+ class ChatCompletionSystemMessageParam(TypedDict, total=False):
16
+ content: Required[
17
+ str | list[ChatCompletionContentPartTextParam] | ChatCompletionContentPartTextParam
18
+ ]
19
+ """The contents of the system message."""
20
+
21
+ role: Required[Literal["system"]]
22
+ """The role of the messages author, in this case `system`."""
23
+
24
+ name: str
25
+ """An optional name for the participant.
26
+
27
+ Provides the model information to differentiate between participants of the same
28
+ role.
29
+ """
30
+
31
+ chat_time: str | None
32
+ """Optional timestamp for the message, format is not
33
+ restricted, it can be any vague or precise time string."""
34
+
35
+ message_id: str | None
36
+ """Optional unique identifier for the message"""
@@ -0,0 +1,30 @@
1
+ # ruff: noqa: TC001, TC003
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal
6
+
7
+ from typing_extensions import Required, TypedDict
8
+
9
+ from .chat_completion_content_part_param import ChatCompletionContentPartParam
10
+
11
+
12
+ __all__ = ["ChatCompletionToolMessageParam"]
13
+
14
+
15
+ class ChatCompletionToolMessageParam(TypedDict, total=False):
16
+ content: Required[str | list[ChatCompletionContentPartParam] | ChatCompletionContentPartParam]
17
+ """The contents of the tool message."""
18
+
19
+ role: Required[Literal["tool"]]
20
+ """The role of the messages author, in this case `tool`."""
21
+
22
+ tool_call_id: Required[str]
23
+ """Tool call that this message is responding to."""
24
+
25
+ chat_time: str | None
26
+ """Optional timestamp for the message, format is not
27
+ restricted, it can be any vague or precise time string."""
28
+
29
+ message_id: str | None
30
+ """Optional unique identifier for the message"""
@@ -0,0 +1,34 @@
1
+ # ruff: noqa: TC001, TC003
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal
6
+
7
+ from typing_extensions import Required, TypedDict
8
+
9
+ from .chat_completion_content_part_param import ChatCompletionContentPartParam
10
+
11
+
12
+ __all__ = ["ChatCompletionUserMessageParam"]
13
+
14
+
15
+ class ChatCompletionUserMessageParam(TypedDict, total=False):
16
+ content: Required[str | list[ChatCompletionContentPartParam] | ChatCompletionContentPartParam]
17
+ """The contents of the user message."""
18
+
19
+ role: Required[Literal["user"]]
20
+ """The role of the messages author, in this case `user`."""
21
+
22
+ name: str
23
+ """An optional name for the participant.
24
+
25
+ Provides the model information to differentiate between participants of the same
26
+ role.
27
+ """
28
+
29
+ chat_time: str | None
30
+ """Optional timestamp for the message, format is not
31
+ restricted, it can be any vague or precise time string."""
32
+
33
+ message_id: str | None
34
+ """Optional unique identifier for the message"""
memos/utils.py ADDED
@@ -0,0 +1,123 @@
1
+ import functools
2
+ import time
3
+ import traceback
4
+
5
+ from memos.log import get_logger
6
+
7
+
8
+ logger = get_logger(__name__)
9
+
10
+
11
+ def timed_with_status(
12
+ func=None,
13
+ *,
14
+ log_prefix="",
15
+ log_args=None,
16
+ log_extra_args=None,
17
+ fallback=None,
18
+ ):
19
+ """
20
+ Parameters:
21
+ - log: enable timing logs (default True)
22
+ - log_prefix: prefix; falls back to function name
23
+ - log_args: names to include in logs (str or list/tuple of str), values are taken from kwargs by name.
24
+ - log_extra_args:
25
+ - can be a dict: fixed contextual fields that are always attached to logs;
26
+ - or a callable: like `fn(*args, **kwargs) -> dict`, used to dynamically generate contextual fields at runtime.
27
+ """
28
+
29
+ if isinstance(log_args, str):
30
+ effective_log_args = [log_args]
31
+ else:
32
+ effective_log_args = list(log_args) if log_args else []
33
+
34
+ def decorator(fn):
35
+ @functools.wraps(fn)
36
+ def wrapper(*args, **kwargs):
37
+ start = time.perf_counter()
38
+ exc_type = None
39
+ exc_message = None
40
+ result = None
41
+ success_flag = False
42
+
43
+ try:
44
+ result = fn(*args, **kwargs)
45
+ success_flag = True
46
+ return result
47
+ except Exception as e:
48
+ exc_type = type(e)
49
+ stack_info = "".join(traceback.format_stack()[:-1])
50
+ exc_message = f"{stack_info}{traceback.format_exc()}"
51
+ success_flag = False
52
+
53
+ if fallback is not None and callable(fallback):
54
+ result = fallback(e, *args, **kwargs)
55
+ return result
56
+ finally:
57
+ elapsed_ms = (time.perf_counter() - start) * 1000.0
58
+
59
+ ctx_parts = []
60
+ # 1) Collect parameters from kwargs by name
61
+ for key in effective_log_args:
62
+ val = kwargs.get(key)
63
+ ctx_parts.append(f"{key}={val}")
64
+
65
+ # 2) Support log_extra_args as dict or callable, so we can dynamically
66
+ # extract values from self or other runtime context
67
+ extra_items = {}
68
+ try:
69
+ if callable(log_extra_args):
70
+ extra_items = log_extra_args(*args, **kwargs) or {}
71
+ elif isinstance(log_extra_args, dict):
72
+ extra_items = log_extra_args
73
+ except Exception as e:
74
+ logger.warning(f"[TIMER_WITH_STATUS] log_extra_args callback error: {e!r}")
75
+
76
+ if extra_items:
77
+ ctx_parts.extend(f"{key}={val}" for key, val in extra_items.items())
78
+
79
+ ctx_str = f" [{', '.join(ctx_parts)}]" if ctx_parts else ""
80
+
81
+ status = "SUCCESS" if success_flag else "FAILED"
82
+ status_info = f", status: {status}"
83
+ if not success_flag and exc_type is not None:
84
+ status_info += (
85
+ f", error_type: {exc_type.__name__}, error_message: {exc_message}"
86
+ )
87
+
88
+ msg = (
89
+ f"[TIMER_WITH_STATUS] {log_prefix or fn.__name__} "
90
+ f"took {elapsed_ms:.0f} ms{status_info}, args: {ctx_str}"
91
+ )
92
+
93
+ logger.info(msg)
94
+
95
+ return wrapper
96
+
97
+ if func is None:
98
+ return decorator
99
+ return decorator(func)
100
+
101
+
102
+ def timed(func=None, *, log=True, log_prefix=""):
103
+ def decorator(fn):
104
+ def wrapper(*args, **kwargs):
105
+ start = time.perf_counter()
106
+ result = fn(*args, **kwargs)
107
+ elapsed_ms = (time.perf_counter() - start) * 1000.0
108
+
109
+ if log is not True:
110
+ return result
111
+
112
+ # 100ms threshold
113
+ if elapsed_ms >= 100.0:
114
+ logger.info(f"[TIMER] {log_prefix or fn.__name__} took {elapsed_ms:.0f} ms")
115
+
116
+ return result
117
+
118
+ return wrapper
119
+
120
+ # Handle both @timed and @timed(log=True) cases
121
+ if func is None:
122
+ return decorator
123
+ return decorator(func)
File without changes
memos/vec_dbs/base.py ADDED
@@ -0,0 +1,117 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any
3
+
4
+ from memos.configs.vec_db import BaseVecDBConfig
5
+ from memos.vec_dbs.item import VecDBItem
6
+
7
+
8
+ class BaseVecDB(ABC):
9
+ """Base class for all vector databases."""
10
+
11
+ @abstractmethod
12
+ def __init__(self, config: BaseVecDBConfig):
13
+ """Initialize the vector database with the given configuration."""
14
+
15
+ # Collection management methods
16
+
17
+ @abstractmethod
18
+ def create_collection(self) -> None:
19
+ """Create a new collection/index with specified parameters."""
20
+
21
+ @abstractmethod
22
+ def list_collections(self) -> list[str]:
23
+ """List all collections/indexes."""
24
+
25
+ @abstractmethod
26
+ def delete_collection(self, name: str) -> None:
27
+ """Delete a collection/index."""
28
+
29
+ @abstractmethod
30
+ def collection_exists(self, name: str) -> bool:
31
+ """Check if a collection/index exists."""
32
+
33
+ # Vector management methods
34
+
35
+ @abstractmethod
36
+ def search(
37
+ self,
38
+ query_vector: list[float],
39
+ top_k: int,
40
+ filter: dict[str, Any] | None = None,
41
+ ) -> list[VecDBItem]:
42
+ """
43
+ Search for similar items in the vector database.
44
+
45
+ Args:
46
+ query_vector: Single vector to search
47
+ top_k: Number of results to return
48
+ filter: payload filters (may not be supported by all implementations)
49
+
50
+ Returns:
51
+ List of search results with distance scores and payloads.
52
+ """
53
+
54
+ @abstractmethod
55
+ def get_by_id(self, id: str) -> VecDBItem | None:
56
+ """Get an item from the vector database."""
57
+
58
+ @abstractmethod
59
+ def get_by_ids(self, ids: list[str]) -> list[VecDBItem]:
60
+ """Get multiple items by their IDs."""
61
+
62
+ @abstractmethod
63
+ def get_by_filter(self, filter: dict[str, Any]) -> list[VecDBItem]:
64
+ """
65
+ Retrieve all items that match the given filter criteria.
66
+
67
+ Args:
68
+ filter: Payload filters to match against stored items
69
+
70
+ Returns:
71
+ List of items including vectors and payloads that match the filter
72
+ """
73
+
74
+ @abstractmethod
75
+ def get_all(self) -> list[VecDBItem]:
76
+ """Retrieve all items in the vector database."""
77
+
78
+ @abstractmethod
79
+ def count(self, filter: dict[str, Any] | None = None) -> int:
80
+ """Count items in the database, optionally with filter."""
81
+
82
+ @abstractmethod
83
+ def add(self, data: list[VecDBItem | dict[str, Any]]) -> None:
84
+ """
85
+ Add data to the vector database.
86
+
87
+ Args:
88
+ data: List of VecDBItem objects or dictionaries containing:
89
+ - 'id': unique identifier
90
+ - 'vector': embedding vector
91
+ - 'payload': additional fields for filtering/retrieval
92
+ """
93
+
94
+ @abstractmethod
95
+ def update(self, id: str, data: VecDBItem | dict[str, Any]) -> None:
96
+ """Update an item in the vector database."""
97
+
98
+ @abstractmethod
99
+ def upsert(self, data: list[VecDBItem | dict[str, Any]]) -> None:
100
+ """
101
+ Add or update data in the vector database.
102
+
103
+ If an item with the same ID exists, it will be updated.
104
+ Otherwise, it will be added as a new item.
105
+ """
106
+
107
+ @abstractmethod
108
+ def delete(self, ids: list[str]) -> None:
109
+ """Delete items from the vector database."""
110
+
111
+ @abstractmethod
112
+ def ensure_payload_indexes(self, fields: list[str]) -> None:
113
+ """
114
+ Create payload indexes for specified fields in the collection.
115
+ Args:
116
+ fields (list[str]): List of field names to index (as keyword).
117
+ """
@@ -0,0 +1,23 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from memos.configs.vec_db import VectorDBConfigFactory
4
+ from memos.vec_dbs.base import BaseVecDB
5
+ from memos.vec_dbs.milvus import MilvusVecDB
6
+ from memos.vec_dbs.qdrant import QdrantVecDB
7
+
8
+
9
+ class VecDBFactory(BaseVecDB):
10
+ """Factory class for creating Vector Database instances."""
11
+
12
+ backend_to_class: ClassVar[dict[str, Any]] = {
13
+ "qdrant": QdrantVecDB,
14
+ "milvus": MilvusVecDB,
15
+ }
16
+
17
+ @classmethod
18
+ def from_config(cls, config_factory: VectorDBConfigFactory) -> BaseVecDB:
19
+ backend = config_factory.backend
20
+ if backend not in cls.backend_to_class:
21
+ raise ValueError(f"Invalid backend: {backend}")
22
+ vec_db_class = cls.backend_to_class[backend]
23
+ return vec_db_class(config_factory.config)
memos/vec_dbs/item.py ADDED
@@ -0,0 +1,50 @@
1
+ """Defines vector database item types."""
2
+
3
+ import uuid
4
+
5
+ from typing import Any
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
8
+
9
+
10
+ class VecDBItem(BaseModel):
11
+ """Represents a single item in the vector database.
12
+
13
+ This serves as a standardized format for vector database items across different
14
+ vector database implementations (Qdrant, FAISS, Weaviate, etc.).
15
+ """
16
+
17
+ id: str = Field(default=str(uuid.uuid4()), description="Unique identifier for the item")
18
+ vector: list[float] | None = Field(default=None, description="Embedding vector")
19
+ payload: dict[str, Any] | None = Field(
20
+ default=None, description="Additional payload for filtering/retrieval"
21
+ )
22
+ score: float | None = Field(
23
+ default=None, description="Similarity score (used in search results)"
24
+ )
25
+
26
+ model_config = ConfigDict(extra="forbid")
27
+
28
+ @field_validator("id")
29
+ @classmethod
30
+ def validate_id(cls, v):
31
+ """Validate that ID is a valid UUID."""
32
+ if not isinstance(v, str) or not uuid.UUID(v, version=4):
33
+ raise ValueError("ID must be a valid UUID string")
34
+ return v
35
+
36
+ @classmethod
37
+ def from_dict(cls, data: dict[str, Any]) -> "VecDBItem":
38
+ """Create VecDBItem from dictionary."""
39
+ return cls(**data)
40
+
41
+ def to_dict(self) -> dict[str, Any]:
42
+ """Convert to dictionary format."""
43
+ return self.model_dump(exclude_none=True)
44
+
45
+
46
+ class MilvusVecDBItem(VecDBItem):
47
+ """Represents a single item in the Milvus vector database."""
48
+
49
+ memory: str | None = Field(default=None, description="Memory string")
50
+ original_text: str | None = Field(default=None, description="Original text content")