MemoryOS 0.2.1__py3-none-any.whl → 1.0.0__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.

Potentially problematic release.


This version of MemoryOS might be problematic. Click here for more details.

Files changed (92) hide show
  1. {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/METADATA +7 -1
  2. {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/RECORD +87 -64
  3. memos/__init__.py +1 -1
  4. memos/api/config.py +158 -69
  5. memos/api/context/context.py +147 -0
  6. memos/api/context/dependencies.py +101 -0
  7. memos/api/product_models.py +5 -1
  8. memos/api/routers/product_router.py +54 -26
  9. memos/configs/graph_db.py +49 -1
  10. memos/configs/internet_retriever.py +19 -0
  11. memos/configs/mem_os.py +5 -0
  12. memos/configs/mem_reader.py +9 -0
  13. memos/configs/mem_scheduler.py +54 -18
  14. memos/configs/mem_user.py +58 -0
  15. memos/graph_dbs/base.py +38 -3
  16. memos/graph_dbs/factory.py +2 -0
  17. memos/graph_dbs/nebular.py +1612 -0
  18. memos/graph_dbs/neo4j.py +18 -9
  19. memos/log.py +6 -1
  20. memos/mem_cube/utils.py +13 -6
  21. memos/mem_os/core.py +157 -37
  22. memos/mem_os/main.py +2 -2
  23. memos/mem_os/product.py +252 -201
  24. memos/mem_os/utils/default_config.py +1 -1
  25. memos/mem_os/utils/format_utils.py +281 -70
  26. memos/mem_os/utils/reference_utils.py +133 -0
  27. memos/mem_reader/simple_struct.py +13 -5
  28. memos/mem_scheduler/base_scheduler.py +239 -266
  29. memos/mem_scheduler/{modules → general_modules}/base.py +4 -5
  30. memos/mem_scheduler/{modules → general_modules}/dispatcher.py +57 -21
  31. memos/mem_scheduler/general_modules/misc.py +104 -0
  32. memos/mem_scheduler/{modules → general_modules}/rabbitmq_service.py +12 -10
  33. memos/mem_scheduler/{modules → general_modules}/redis_service.py +1 -1
  34. memos/mem_scheduler/general_modules/retriever.py +199 -0
  35. memos/mem_scheduler/general_modules/scheduler_logger.py +261 -0
  36. memos/mem_scheduler/general_scheduler.py +243 -80
  37. memos/mem_scheduler/monitors/__init__.py +0 -0
  38. memos/mem_scheduler/monitors/dispatcher_monitor.py +305 -0
  39. memos/mem_scheduler/{modules/monitor.py → monitors/general_monitor.py} +106 -57
  40. memos/mem_scheduler/mos_for_test_scheduler.py +23 -20
  41. memos/mem_scheduler/schemas/__init__.py +0 -0
  42. memos/mem_scheduler/schemas/general_schemas.py +44 -0
  43. memos/mem_scheduler/schemas/message_schemas.py +149 -0
  44. memos/mem_scheduler/schemas/monitor_schemas.py +337 -0
  45. memos/mem_scheduler/utils/__init__.py +0 -0
  46. memos/mem_scheduler/utils/filter_utils.py +176 -0
  47. memos/mem_scheduler/utils/misc_utils.py +102 -0
  48. memos/mem_user/factory.py +94 -0
  49. memos/mem_user/mysql_persistent_user_manager.py +271 -0
  50. memos/mem_user/mysql_user_manager.py +500 -0
  51. memos/mem_user/persistent_factory.py +96 -0
  52. memos/mem_user/user_manager.py +4 -4
  53. memos/memories/activation/item.py +5 -1
  54. memos/memories/activation/kv.py +20 -8
  55. memos/memories/textual/base.py +2 -2
  56. memos/memories/textual/general.py +36 -92
  57. memos/memories/textual/item.py +5 -33
  58. memos/memories/textual/tree.py +13 -7
  59. memos/memories/textual/tree_text_memory/organize/{conflict.py → handler.py} +34 -50
  60. memos/memories/textual/tree_text_memory/organize/manager.py +8 -96
  61. memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +49 -43
  62. memos/memories/textual/tree_text_memory/organize/reorganizer.py +107 -142
  63. memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +229 -0
  64. memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +6 -3
  65. memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +11 -0
  66. memos/memories/textual/tree_text_memory/retrieve/recall.py +15 -8
  67. memos/memories/textual/tree_text_memory/retrieve/reranker.py +1 -1
  68. memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +2 -0
  69. memos/memories/textual/tree_text_memory/retrieve/searcher.py +191 -116
  70. memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +47 -15
  71. memos/memories/textual/tree_text_memory/retrieve/utils.py +11 -7
  72. memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +62 -58
  73. memos/memos_tools/dinding_report_bot.py +422 -0
  74. memos/memos_tools/lockfree_dict.py +120 -0
  75. memos/memos_tools/notification_service.py +44 -0
  76. memos/memos_tools/notification_utils.py +96 -0
  77. memos/memos_tools/thread_safe_dict.py +288 -0
  78. memos/settings.py +3 -1
  79. memos/templates/mem_reader_prompts.py +4 -1
  80. memos/templates/mem_scheduler_prompts.py +62 -15
  81. memos/templates/mos_prompts.py +116 -0
  82. memos/templates/tree_reorganize_prompts.py +24 -17
  83. memos/utils.py +19 -0
  84. memos/mem_scheduler/modules/misc.py +0 -39
  85. memos/mem_scheduler/modules/retriever.py +0 -268
  86. memos/mem_scheduler/modules/schemas.py +0 -328
  87. memos/mem_scheduler/utils.py +0 -75
  88. memos/memories/textual/tree_text_memory/organize/redundancy.py +0 -193
  89. {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/LICENSE +0 -0
  90. {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/WHEEL +0 -0
  91. {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/entry_points.txt +0 -0
  92. /memos/mem_scheduler/{modules → general_modules}/__init__.py +0 -0
@@ -0,0 +1,133 @@
1
+ def split_continuous_references(text: str) -> str:
2
+ """
3
+ Split continuous reference tags into individual reference tags.
4
+
5
+ Converts patterns like [1:92ff35fb, 4:bfe6f044] to [1:92ff35fb] [4:bfe6f044]
6
+
7
+ Only processes text if:
8
+ 1. '[' appears exactly once
9
+ 2. ']' appears exactly once
10
+ 3. Contains commas between '[' and ']'
11
+
12
+ Args:
13
+ text (str): Text containing reference tags
14
+
15
+ Returns:
16
+ str: Text with split reference tags, or original text if conditions not met
17
+ """
18
+ # Early return if text is empty
19
+ if not text:
20
+ return text
21
+ # Check if '[' appears exactly once
22
+ if text.count("[") != 1:
23
+ return text
24
+ # Check if ']' appears exactly once
25
+ if text.count("]") != 1:
26
+ return text
27
+ # Find positions of brackets
28
+ open_bracket_pos = text.find("[")
29
+ close_bracket_pos = text.find("]")
30
+
31
+ # Check if brackets are in correct order
32
+ if open_bracket_pos >= close_bracket_pos:
33
+ return text
34
+ # Extract content between brackets
35
+ content_between_brackets = text[open_bracket_pos + 1 : close_bracket_pos]
36
+ # Check if there's a comma between brackets
37
+ if "," not in content_between_brackets:
38
+ return text
39
+ text = text.replace(content_between_brackets, content_between_brackets.replace(", ", "]["))
40
+ text = text.replace(content_between_brackets, content_between_brackets.replace(",", "]["))
41
+
42
+ return text
43
+
44
+
45
+ def process_streaming_references_complete(text_buffer: str) -> tuple[str, str]:
46
+ """
47
+ Complete streaming reference processing to ensure reference tags are never split.
48
+
49
+ Args:
50
+ text_buffer (str): The accumulated text buffer.
51
+
52
+ Returns:
53
+ tuple[str, str]: (processed_text, remaining_buffer)
54
+ """
55
+ import re
56
+
57
+ # Pattern to match complete reference tags: [refid:memoriesID]
58
+ complete_pattern = r"\[\d+:[^\]]+\]"
59
+
60
+ # Find all complete reference tags
61
+ complete_matches = list(re.finditer(complete_pattern, text_buffer))
62
+
63
+ if complete_matches:
64
+ # Find the last complete tag
65
+ last_match = complete_matches[-1]
66
+ end_pos = last_match.end()
67
+
68
+ # Check if there's any incomplete reference after the last complete one
69
+ remaining_text = text_buffer[end_pos:]
70
+
71
+ # Look for potential incomplete reference patterns after the last complete tag
72
+ incomplete_pattern = r"\[\d*:?[^\]]*$"
73
+ if re.search(incomplete_pattern, remaining_text):
74
+ # There's a potential incomplete reference, find where it starts
75
+ incomplete_match = re.search(incomplete_pattern, remaining_text)
76
+ if incomplete_match:
77
+ incomplete_start = end_pos + incomplete_match.start()
78
+ processed_text = text_buffer[:incomplete_start]
79
+ remaining_buffer = text_buffer[incomplete_start:]
80
+
81
+ # Apply reference splitting to the processed text
82
+ processed_text = split_continuous_references(processed_text)
83
+ return processed_text, remaining_buffer
84
+
85
+ # No incomplete reference after the last complete tag, process all
86
+ processed_text = split_continuous_references(text_buffer)
87
+ return processed_text, ""
88
+
89
+ # Check for incomplete reference tags - be more specific about what constitutes a potential reference
90
+ # Look for opening bracket with number and colon that could be a reference tag
91
+ opening_pattern = r"\[\d+:"
92
+ opening_matches = list(re.finditer(opening_pattern, text_buffer))
93
+
94
+ if opening_matches:
95
+ # Find the last opening tag
96
+ last_opening = opening_matches[-1]
97
+ opening_start = last_opening.start()
98
+
99
+ # Check if this might be a complete reference tag (has closing bracket after the pattern)
100
+ remaining_text = text_buffer[last_opening.end() :]
101
+ if "]" in remaining_text:
102
+ # This looks like a complete reference tag, process it
103
+ processed_text = split_continuous_references(text_buffer)
104
+ return processed_text, ""
105
+ else:
106
+ # Incomplete reference tag, keep it in buffer
107
+ processed_text = text_buffer[:opening_start]
108
+ processed_text = split_continuous_references(processed_text)
109
+ return processed_text, text_buffer[opening_start:]
110
+
111
+ # More sophisticated check for potential reference patterns
112
+ # Only hold back text if we see a pattern that could be the start of a reference tag
113
+ potential_ref_pattern = r"\[\d*:?$" # Matches [, [1, [12:, etc. at end of buffer
114
+ if re.search(potential_ref_pattern, text_buffer):
115
+ # Find the position of the potential reference start
116
+ match = re.search(potential_ref_pattern, text_buffer)
117
+ if match:
118
+ ref_start = match.start()
119
+ processed_text = text_buffer[:ref_start]
120
+ processed_text = split_continuous_references(processed_text)
121
+ return processed_text, text_buffer[ref_start:]
122
+
123
+ # Check for standalone [ only at the very end of the buffer
124
+ # This prevents cutting off mathematical expressions like [ \Delta U = Q - W ]
125
+ if text_buffer.endswith("["):
126
+ # Only hold back the single [ character
127
+ processed_text = text_buffer[:-1]
128
+ processed_text = split_continuous_references(processed_text)
129
+ return processed_text, "["
130
+
131
+ # No reference-like patterns found, process all text
132
+ processed_text = split_continuous_references(text_buffer)
133
+ return processed_text, ""
@@ -58,9 +58,13 @@ class SimpleStructMemReader(BaseMemReader, ABC):
58
58
  metadata=TreeNodeTextualMemoryMetadata(
59
59
  user_id=info.get("user_id"),
60
60
  session_id=info.get("session_id"),
61
- memory_type=memory_i_raw.get("memory_type", ""),
61
+ memory_type=memory_i_raw.get("memory_type", "")
62
+ .replace("长期记忆", "LongTermMemory")
63
+ .replace("用户记忆", "UserMemory"),
62
64
  status="activated",
63
- tags=memory_i_raw.get("tags", ""),
65
+ tags=memory_i_raw.get("tags", [])
66
+ if type(memory_i_raw.get("tags", [])) is list
67
+ else [],
64
68
  key=memory_i_raw.get("key", ""),
65
69
  embedding=self.embedder.embed([memory_i_raw.get("value", "")])[0],
66
70
  usage=[],
@@ -176,8 +180,12 @@ class SimpleStructMemReader(BaseMemReader, ABC):
176
180
  elif type == "doc":
177
181
  for item in scene_data:
178
182
  try:
179
- parsed_text = parser.parse(item)
180
- results.append({"file": item, "text": parsed_text})
183
+ if not isinstance(item, str):
184
+ parsed_text = parser.parse(item)
185
+ results.append({"file": "pure_text", "text": parsed_text})
186
+ else:
187
+ parsed_text = item
188
+ results.append({"file": item, "text": parsed_text})
181
189
  except Exception as e:
182
190
  print(f"Error parsing file {item}: {e!s}")
183
191
 
@@ -214,7 +222,7 @@ class SimpleStructMemReader(BaseMemReader, ABC):
214
222
  session_id=info.get("session_id"),
215
223
  memory_type="LongTermMemory",
216
224
  status="activated",
217
- tags=chunk_res["tags"],
225
+ tags=chunk_res["tags"] if type(chunk_res["tags"]) is list else [],
218
226
  key=chunk_res["key"],
219
227
  embedding=self.embedder.embed([chunk_res["value"]])[0],
220
228
  usage=[],