MemoryOS 0.0.1__py3-none-any.whl → 0.1.13__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 (124) hide show
  1. memoryos-0.1.13.dist-info/METADATA +288 -0
  2. memoryos-0.1.13.dist-info/RECORD +122 -0
  3. memos/__init__.py +20 -1
  4. memos/api/start_api.py +420 -0
  5. memos/chunkers/__init__.py +4 -0
  6. memos/chunkers/base.py +24 -0
  7. memos/chunkers/factory.py +22 -0
  8. memos/chunkers/sentence_chunker.py +35 -0
  9. memos/configs/__init__.py +0 -0
  10. memos/configs/base.py +82 -0
  11. memos/configs/chunker.py +45 -0
  12. memos/configs/embedder.py +53 -0
  13. memos/configs/graph_db.py +45 -0
  14. memos/configs/internet_retriever.py +81 -0
  15. memos/configs/llm.py +71 -0
  16. memos/configs/mem_chat.py +81 -0
  17. memos/configs/mem_cube.py +89 -0
  18. memos/configs/mem_os.py +74 -0
  19. memos/configs/mem_reader.py +53 -0
  20. memos/configs/mem_scheduler.py +78 -0
  21. memos/configs/memory.py +195 -0
  22. memos/configs/parser.py +38 -0
  23. memos/configs/utils.py +8 -0
  24. memos/configs/vec_db.py +64 -0
  25. memos/deprecation.py +262 -0
  26. memos/embedders/__init__.py +0 -0
  27. memos/embedders/base.py +15 -0
  28. memos/embedders/factory.py +23 -0
  29. memos/embedders/ollama.py +74 -0
  30. memos/embedders/sentence_transformer.py +40 -0
  31. memos/exceptions.py +30 -0
  32. memos/graph_dbs/__init__.py +0 -0
  33. memos/graph_dbs/base.py +215 -0
  34. memos/graph_dbs/factory.py +21 -0
  35. memos/graph_dbs/neo4j.py +827 -0
  36. memos/hello_world.py +97 -0
  37. memos/llms/__init__.py +0 -0
  38. memos/llms/base.py +16 -0
  39. memos/llms/factory.py +25 -0
  40. memos/llms/hf.py +231 -0
  41. memos/llms/ollama.py +82 -0
  42. memos/llms/openai.py +34 -0
  43. memos/llms/utils.py +14 -0
  44. memos/log.py +78 -0
  45. memos/mem_chat/__init__.py +0 -0
  46. memos/mem_chat/base.py +30 -0
  47. memos/mem_chat/factory.py +21 -0
  48. memos/mem_chat/simple.py +200 -0
  49. memos/mem_cube/__init__.py +0 -0
  50. memos/mem_cube/base.py +29 -0
  51. memos/mem_cube/general.py +146 -0
  52. memos/mem_cube/utils.py +24 -0
  53. memos/mem_os/client.py +5 -0
  54. memos/mem_os/core.py +819 -0
  55. memos/mem_os/main.py +503 -0
  56. memos/mem_os/product.py +89 -0
  57. memos/mem_reader/__init__.py +0 -0
  58. memos/mem_reader/base.py +27 -0
  59. memos/mem_reader/factory.py +21 -0
  60. memos/mem_reader/memory.py +298 -0
  61. memos/mem_reader/simple_struct.py +241 -0
  62. memos/mem_scheduler/__init__.py +0 -0
  63. memos/mem_scheduler/base_scheduler.py +164 -0
  64. memos/mem_scheduler/general_scheduler.py +305 -0
  65. memos/mem_scheduler/modules/__init__.py +0 -0
  66. memos/mem_scheduler/modules/base.py +74 -0
  67. memos/mem_scheduler/modules/dispatcher.py +103 -0
  68. memos/mem_scheduler/modules/monitor.py +82 -0
  69. memos/mem_scheduler/modules/redis_service.py +146 -0
  70. memos/mem_scheduler/modules/retriever.py +41 -0
  71. memos/mem_scheduler/modules/schemas.py +146 -0
  72. memos/mem_scheduler/scheduler_factory.py +21 -0
  73. memos/mem_scheduler/utils.py +26 -0
  74. memos/mem_user/user_manager.py +488 -0
  75. memos/memories/__init__.py +0 -0
  76. memos/memories/activation/__init__.py +0 -0
  77. memos/memories/activation/base.py +42 -0
  78. memos/memories/activation/item.py +25 -0
  79. memos/memories/activation/kv.py +232 -0
  80. memos/memories/base.py +19 -0
  81. memos/memories/factory.py +34 -0
  82. memos/memories/parametric/__init__.py +0 -0
  83. memos/memories/parametric/base.py +19 -0
  84. memos/memories/parametric/item.py +11 -0
  85. memos/memories/parametric/lora.py +41 -0
  86. memos/memories/textual/__init__.py +0 -0
  87. memos/memories/textual/base.py +89 -0
  88. memos/memories/textual/general.py +286 -0
  89. memos/memories/textual/item.py +167 -0
  90. memos/memories/textual/naive.py +185 -0
  91. memos/memories/textual/tree.py +321 -0
  92. memos/memories/textual/tree_text_memory/__init__.py +0 -0
  93. memos/memories/textual/tree_text_memory/organize/__init__.py +0 -0
  94. memos/memories/textual/tree_text_memory/organize/manager.py +305 -0
  95. memos/memories/textual/tree_text_memory/retrieve/__init__.py +0 -0
  96. memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +263 -0
  97. memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +89 -0
  98. memos/memories/textual/tree_text_memory/retrieve/reasoner.py +61 -0
  99. memos/memories/textual/tree_text_memory/retrieve/recall.py +158 -0
  100. memos/memories/textual/tree_text_memory/retrieve/reranker.py +111 -0
  101. memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +13 -0
  102. memos/memories/textual/tree_text_memory/retrieve/searcher.py +208 -0
  103. memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +68 -0
  104. memos/memories/textual/tree_text_memory/retrieve/utils.py +48 -0
  105. memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +335 -0
  106. memos/parsers/__init__.py +0 -0
  107. memos/parsers/base.py +15 -0
  108. memos/parsers/factory.py +19 -0
  109. memos/parsers/markitdown.py +22 -0
  110. memos/settings.py +8 -0
  111. memos/templates/__init__.py +0 -0
  112. memos/templates/mem_reader_prompts.py +98 -0
  113. memos/templates/mem_scheduler_prompts.py +65 -0
  114. memos/templates/mos_prompts.py +63 -0
  115. memos/types.py +55 -0
  116. memos/vec_dbs/__init__.py +0 -0
  117. memos/vec_dbs/base.py +105 -0
  118. memos/vec_dbs/factory.py +21 -0
  119. memos/vec_dbs/item.py +43 -0
  120. memos/vec_dbs/qdrant.py +292 -0
  121. memoryos-0.0.1.dist-info/METADATA +0 -53
  122. memoryos-0.0.1.dist-info/RECORD +0 -5
  123. {memoryos-0.0.1.dist-info → memoryos-0.1.13.dist-info}/LICENSE +0 -0
  124. {memoryos-0.0.1.dist-info → memoryos-0.1.13.dist-info}/WHEEL +0 -0
@@ -0,0 +1,292 @@
1
+ from typing import Any
2
+
3
+ from qdrant_client import QdrantClient
4
+ from qdrant_client.http import models
5
+ from qdrant_client.http.models import (
6
+ Distance,
7
+ FieldCondition,
8
+ Filter,
9
+ MatchValue,
10
+ PointStruct,
11
+ VectorParams,
12
+ )
13
+
14
+ from memos.configs.vec_db import QdrantVecDBConfig
15
+ from memos.log import get_logger
16
+ from memos.vec_dbs.base import BaseVecDB
17
+ from memos.vec_dbs.item import VecDBItem
18
+
19
+
20
+ logger = get_logger(__name__)
21
+
22
+
23
+ class QdrantVecDB(BaseVecDB):
24
+ """Qdrant vector database implementation."""
25
+
26
+ def __init__(self, config: QdrantVecDBConfig):
27
+ """Initialize the Qdrant vector database and the collection."""
28
+ self.config = config
29
+
30
+ # If both host and port are None, we are running in local mode
31
+ if self.config.host is None and self.config.port is None:
32
+ logger.warning(
33
+ "Qdrant is running in local mode (host and port are both None). "
34
+ "In local mode, there may be race conditions during concurrent reads/writes. "
35
+ "It is strongly recommended to deploy a standalone Qdrant server "
36
+ "(e.g., via Docker: https://qdrant.tech/documentation/quickstart/)."
37
+ )
38
+
39
+ self.client = QdrantClient(
40
+ host=self.config.host, port=self.config.port, path=self.config.path
41
+ )
42
+ self.create_collection()
43
+
44
+ def create_collection(self) -> None:
45
+ """Create a new collection with specified parameters."""
46
+
47
+ if self.collection_exists(self.config.collection_name):
48
+ collection_info = self.client.get_collection(self.config.collection_name)
49
+ logger.warning(
50
+ f"Collection '{self.config.collection_name}' (vector dimension: {collection_info.config.params.vectors.size}) already exists. Skipping creation."
51
+ )
52
+
53
+ return
54
+
55
+ # Map string distance metric to Qdrant Distance enum
56
+ distance_map = {
57
+ "cosine": Distance.COSINE,
58
+ "euclidean": Distance.EUCLID,
59
+ "dot": Distance.DOT,
60
+ }
61
+
62
+ self.client.create_collection(
63
+ collection_name=self.config.collection_name,
64
+ vectors_config=VectorParams(
65
+ size=self.config.vector_dimension,
66
+ distance=distance_map[self.config.distance_metric],
67
+ ),
68
+ )
69
+
70
+ logger.info(
71
+ f"Collection '{self.config.collection_name}' created with {self.config.vector_dimension} dimensions."
72
+ )
73
+
74
+ def list_collections(self) -> list[str]:
75
+ """List all collections."""
76
+ collections = self.client.get_collections()
77
+ return [collection.name for collection in collections.collections]
78
+
79
+ def delete_collection(self, name: str) -> None:
80
+ """Delete a collection."""
81
+ self.client.delete_collection(collection_name=name)
82
+
83
+ def collection_exists(self, name: str) -> bool:
84
+ """Check if a collection exists."""
85
+ try:
86
+ self.client.get_collection(collection_name=name)
87
+ return True
88
+ except Exception:
89
+ return False
90
+
91
+ def search(
92
+ self, query_vector: list[float], top_k: int, filter: dict[str, Any] | None = None
93
+ ) -> list[VecDBItem]:
94
+ """
95
+ Search for similar items in the database.
96
+
97
+ Args:
98
+ query_vector: Single vector to search
99
+ top_k: Number of results to return
100
+ filter: Payload filters
101
+
102
+ Returns:
103
+ List of search results with distance scores and payloads.
104
+ """
105
+ qdrant_filter = self._dict_to_filter(filter) if filter else None
106
+ response = self.client.search(
107
+ collection_name=self.config.collection_name,
108
+ query_vector=query_vector,
109
+ limit=top_k,
110
+ query_filter=qdrant_filter,
111
+ with_vectors=True,
112
+ with_payload=True,
113
+ )
114
+ logger.info(f"Qdrant search completed with {len(response)} results.")
115
+ return [
116
+ VecDBItem(
117
+ id=point.id,
118
+ vector=point.vector,
119
+ payload=point.payload,
120
+ score=point.score,
121
+ )
122
+ for point in response
123
+ ]
124
+
125
+ def _dict_to_filter(self, filter_dict: dict[str, Any]) -> Filter:
126
+ """Convert a dictionary filter to a Qdrant Filter object."""
127
+ conditions = []
128
+
129
+ for field, value in filter_dict.items():
130
+ # Simple exact match for now
131
+ # TODO: Extend this to support more complex conditions
132
+ conditions.append(FieldCondition(key=field, match=MatchValue(value=value)))
133
+
134
+ return Filter(must=conditions)
135
+
136
+ def get_by_id(self, id: str) -> VecDBItem | None:
137
+ """Get a single item by ID."""
138
+ response = self.client.retrieve(
139
+ collection_name=self.config.collection_name,
140
+ ids=[id],
141
+ with_payload=True,
142
+ with_vectors=True,
143
+ )
144
+
145
+ if not response:
146
+ return None
147
+
148
+ point = response[0]
149
+ return VecDBItem(
150
+ id=point.id,
151
+ vector=point.vector,
152
+ payload=point.payload,
153
+ )
154
+
155
+ def get_by_ids(self, ids: list[str]) -> list[VecDBItem]:
156
+ """Get multiple items by their IDs."""
157
+ response = self.client.retrieve(
158
+ collection_name=self.config.collection_name,
159
+ ids=ids,
160
+ with_payload=True,
161
+ with_vectors=True,
162
+ )
163
+
164
+ if not response:
165
+ return []
166
+
167
+ return [
168
+ VecDBItem(
169
+ id=point.id,
170
+ vector=point.vector,
171
+ payload=point.payload,
172
+ )
173
+ for point in response
174
+ ]
175
+
176
+ def get_by_filter(self, filter: dict[str, Any], scroll_limit: int = 100) -> list[VecDBItem]:
177
+ """
178
+ Retrieve all items that match the given filter criteria.
179
+
180
+ Args:
181
+ filter: Payload filters to match against stored items
182
+ scroll_limit: Maximum number of items to retrieve per scroll request
183
+
184
+ Returns:
185
+ List of items including vectors and payload that match the filter
186
+ """
187
+ qdrant_filter = self._dict_to_filter(filter) if filter else None
188
+ all_points = []
189
+ offset = None
190
+
191
+ # Use scroll to paginate through all matching points
192
+ while True:
193
+ points, offset = self.client.scroll(
194
+ collection_name=self.config.collection_name,
195
+ limit=scroll_limit,
196
+ scroll_filter=qdrant_filter,
197
+ offset=offset,
198
+ with_vectors=True,
199
+ with_payload=True,
200
+ )
201
+
202
+ if not points:
203
+ break
204
+
205
+ all_points.extend(points)
206
+
207
+ # Update offset for next iteration
208
+ if offset is None:
209
+ break
210
+
211
+ logger.info(f"Qdrant retrieve by filter completed with {len(all_points)} results.")
212
+ return [
213
+ VecDBItem(
214
+ id=point.id,
215
+ vector=point.vector,
216
+ payload=point.payload,
217
+ )
218
+ for point in all_points
219
+ ]
220
+
221
+ def get_all(self, scroll_limit=100) -> list[VecDBItem]:
222
+ """Retrieve all items in the vector database."""
223
+ return self.get_by_filter({}, scroll_limit=scroll_limit)
224
+
225
+ def count(self, filter: dict[str, Any] | None = None) -> int:
226
+ """Count items in the database, optionally with filter."""
227
+ qdrant_filter = None
228
+ if filter:
229
+ qdrant_filter = self._dict_to_filter(filter)
230
+
231
+ response = self.client.count(
232
+ collection_name=self.config.collection_name, count_filter=qdrant_filter
233
+ )
234
+
235
+ return response.count
236
+
237
+ def add(self, data: list[VecDBItem | dict[str, Any]]) -> None:
238
+ """
239
+ Add data to the vector database.
240
+
241
+ Args:
242
+ data: List of VecDBItem objects or dictionaries containing:
243
+ - 'id': unique identifier
244
+ - 'vector': embedding vector
245
+ - 'payload': additional fields for filtering/retrieval
246
+ """
247
+ points = []
248
+ for item in data:
249
+ if isinstance(item, dict):
250
+ item = item.copy()
251
+ item = VecDBItem.from_dict(item)
252
+ point = PointStruct(id=item.id, vector=item.vector, payload=item.payload)
253
+ points.append(point)
254
+
255
+ self.client.upsert(collection_name=self.config.collection_name, points=points)
256
+
257
+ def update(self, id: str, data: VecDBItem | dict[str, Any]) -> None:
258
+ """Update an item in the vector database."""
259
+
260
+ if isinstance(data, dict):
261
+ data = data.copy()
262
+ data = VecDBItem.from_dict(data)
263
+
264
+ if data.vector:
265
+ # For vector updates (with or without payload), use upsert with the same ID
266
+ self.client.upsert(
267
+ collection_name=self.config.collection_name,
268
+ points=[PointStruct(id=id, vector=data.vector, payload=data.payload)],
269
+ )
270
+ else:
271
+ # For payload-only updates
272
+ self.client.set_payload(
273
+ collection_name=self.config.collection_name, payload=data.payload, points=[id]
274
+ )
275
+
276
+ def upsert(self, data: list[VecDBItem | dict[str, Any]]) -> None:
277
+ """
278
+ Add or update data in the vector database.
279
+
280
+ If an item with the same ID exists, it will be updated.
281
+ Otherwise, it will be added as a new item.
282
+ """
283
+ # Qdrant's upsert operation already handles this logic
284
+ self.add(data)
285
+
286
+ def delete(self, ids: list[str]) -> None:
287
+ """Delete items from the vector database."""
288
+ point_ids: list[str | int] = ids
289
+ self.client.delete(
290
+ collection_name=self.config.collection_name,
291
+ points_selector=models.PointIdsList(points=point_ids),
292
+ )
@@ -1,53 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: MemoryOS
3
- Version: 0.0.1
4
- Summary: Empowering language models with memory.
5
- License: Apache-2.0
6
- Keywords: memory,llm,language model,memoryOS,agent
7
- Author: MemoryTensor
8
- Author-email: lizy@memtensor.cn
9
- Requires-Python: >=3.10,<4.0
10
- Classifier: License :: OSI Approved :: Apache Software License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Requires-Dist: chonkie (>=1.0.7,<2.0.0)
17
- Requires-Dist: markitdown[docx,pdf,pptx,xls,xlsx] (>=0.1.1,<0.2.0)
18
- Requires-Dist: ollama (>=0.4.8,<0.5.0)
19
- Requires-Dist: openai (>=1.77.0,<2.0.0)
20
- Requires-Dist: pre-commit (>=4.2.0,<5.0.0)
21
- Requires-Dist: pytest (>=8.3.5,<9.0.0)
22
- Requires-Dist: qdrant-client (>=1.14.2,<2.0.0)
23
- Requires-Dist: ruff (>=0.11.8,<0.12.0)
24
- Requires-Dist: transformers (>=4.51.3,<5.0.0)
25
- Project-URL: Repository, https://github.com/MemTensor/MemOS
26
- Description-Content-Type: text/markdown
27
-
28
- # MemOS
29
-
30
- Empowering language models with memory.
31
-
32
- ## Install
33
-
34
- ```bash
35
- pip install MemoryOS
36
- ```
37
-
38
- To use MemOS with Ollama, install the [Ollama CLI](https://ollama.com/download):
39
-
40
- ```bash
41
- curl -fsSL https://ollama.com/install.sh | sh
42
- ```
43
-
44
- If you need transformers, ensure [PyTorch](https://pytorch.org/get-started/locally/) is installed in your environment.
45
-
46
- ## Contributing
47
-
48
- Please read [contribution guidelines](.github/CONTRIBUTING.md) before contributing.
49
-
50
- ## Acknowledgments
51
-
52
- This project references the structure, code, and prompt from [mem0](https://github.com/mem0ai/mem0.git).
53
-
@@ -1,5 +0,0 @@
1
- memos/__init__.py,sha256=sXLh7g3KC4QCFxcZGBTpG2scR7hmmBsMjq6LqRptkRg,22
2
- memoryos-0.0.1.dist-info/LICENSE,sha256=FU-b6N8tVc7dzUZGyNjUIG1Ihnrh2iuBziq4a1Gl8HU,11358
3
- memoryos-0.0.1.dist-info/METADATA,sha256=7OcarRhjovbiJdkxLOVuB70BCDpvHxyfYv0ZyKT9yWk,1655
4
- memoryos-0.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
5
- memoryos-0.0.1.dist-info/RECORD,,