MemoryOS 0.0.1__py3-none-any.whl → 0.1.12__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.
- memoryos-0.1.12.dist-info/METADATA +257 -0
- memoryos-0.1.12.dist-info/RECORD +117 -0
- memos/__init__.py +20 -1
- memos/api/start_api.py +420 -0
- memos/chunkers/__init__.py +4 -0
- memos/chunkers/base.py +24 -0
- memos/chunkers/factory.py +22 -0
- memos/chunkers/sentence_chunker.py +35 -0
- memos/configs/__init__.py +0 -0
- memos/configs/base.py +82 -0
- memos/configs/chunker.py +45 -0
- memos/configs/embedder.py +53 -0
- memos/configs/graph_db.py +45 -0
- memos/configs/llm.py +71 -0
- memos/configs/mem_chat.py +81 -0
- memos/configs/mem_cube.py +89 -0
- memos/configs/mem_os.py +70 -0
- memos/configs/mem_reader.py +53 -0
- memos/configs/mem_scheduler.py +78 -0
- memos/configs/memory.py +190 -0
- memos/configs/parser.py +38 -0
- memos/configs/utils.py +8 -0
- memos/configs/vec_db.py +64 -0
- memos/deprecation.py +262 -0
- memos/embedders/__init__.py +0 -0
- memos/embedders/base.py +15 -0
- memos/embedders/factory.py +23 -0
- memos/embedders/ollama.py +74 -0
- memos/embedders/sentence_transformer.py +40 -0
- memos/exceptions.py +30 -0
- memos/graph_dbs/__init__.py +0 -0
- memos/graph_dbs/base.py +215 -0
- memos/graph_dbs/factory.py +21 -0
- memos/graph_dbs/neo4j.py +827 -0
- memos/hello_world.py +97 -0
- memos/llms/__init__.py +0 -0
- memos/llms/base.py +16 -0
- memos/llms/factory.py +25 -0
- memos/llms/hf.py +231 -0
- memos/llms/ollama.py +82 -0
- memos/llms/openai.py +34 -0
- memos/llms/utils.py +14 -0
- memos/log.py +78 -0
- memos/mem_chat/__init__.py +0 -0
- memos/mem_chat/base.py +30 -0
- memos/mem_chat/factory.py +21 -0
- memos/mem_chat/simple.py +200 -0
- memos/mem_cube/__init__.py +0 -0
- memos/mem_cube/base.py +29 -0
- memos/mem_cube/general.py +146 -0
- memos/mem_cube/utils.py +24 -0
- memos/mem_os/client.py +5 -0
- memos/mem_os/core.py +819 -0
- memos/mem_os/main.py +12 -0
- memos/mem_os/product.py +89 -0
- memos/mem_reader/__init__.py +0 -0
- memos/mem_reader/base.py +27 -0
- memos/mem_reader/factory.py +21 -0
- memos/mem_reader/memory.py +298 -0
- memos/mem_reader/simple_struct.py +241 -0
- memos/mem_scheduler/__init__.py +0 -0
- memos/mem_scheduler/base_scheduler.py +164 -0
- memos/mem_scheduler/general_scheduler.py +305 -0
- memos/mem_scheduler/modules/__init__.py +0 -0
- memos/mem_scheduler/modules/base.py +74 -0
- memos/mem_scheduler/modules/dispatcher.py +103 -0
- memos/mem_scheduler/modules/monitor.py +82 -0
- memos/mem_scheduler/modules/redis_service.py +146 -0
- memos/mem_scheduler/modules/retriever.py +41 -0
- memos/mem_scheduler/modules/schemas.py +146 -0
- memos/mem_scheduler/scheduler_factory.py +21 -0
- memos/mem_scheduler/utils.py +26 -0
- memos/mem_user/user_manager.py +478 -0
- memos/memories/__init__.py +0 -0
- memos/memories/activation/__init__.py +0 -0
- memos/memories/activation/base.py +42 -0
- memos/memories/activation/item.py +25 -0
- memos/memories/activation/kv.py +232 -0
- memos/memories/base.py +19 -0
- memos/memories/factory.py +34 -0
- memos/memories/parametric/__init__.py +0 -0
- memos/memories/parametric/base.py +19 -0
- memos/memories/parametric/item.py +11 -0
- memos/memories/parametric/lora.py +41 -0
- memos/memories/textual/__init__.py +0 -0
- memos/memories/textual/base.py +89 -0
- memos/memories/textual/general.py +286 -0
- memos/memories/textual/item.py +167 -0
- memos/memories/textual/naive.py +185 -0
- memos/memories/textual/tree.py +289 -0
- memos/memories/textual/tree_text_memory/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/organize/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/organize/manager.py +305 -0
- memos/memories/textual/tree_text_memory/retrieve/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/retrieve/reasoner.py +64 -0
- memos/memories/textual/tree_text_memory/retrieve/recall.py +158 -0
- memos/memories/textual/tree_text_memory/retrieve/reranker.py +111 -0
- memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +13 -0
- memos/memories/textual/tree_text_memory/retrieve/searcher.py +166 -0
- memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +68 -0
- memos/memories/textual/tree_text_memory/retrieve/utils.py +48 -0
- memos/parsers/__init__.py +0 -0
- memos/parsers/base.py +15 -0
- memos/parsers/factory.py +19 -0
- memos/parsers/markitdown.py +22 -0
- memos/settings.py +8 -0
- memos/templates/__init__.py +0 -0
- memos/templates/mem_reader_prompts.py +98 -0
- memos/templates/mem_scheduler_prompts.py +65 -0
- memos/types.py +55 -0
- memos/vec_dbs/__init__.py +0 -0
- memos/vec_dbs/base.py +105 -0
- memos/vec_dbs/factory.py +21 -0
- memos/vec_dbs/item.py +43 -0
- memos/vec_dbs/qdrant.py +292 -0
- memoryos-0.0.1.dist-info/METADATA +0 -53
- memoryos-0.0.1.dist-info/RECORD +0 -5
- {memoryos-0.0.1.dist-info → memoryos-0.1.12.dist-info}/LICENSE +0 -0
- {memoryos-0.0.1.dist-info → memoryos-0.1.12.dist-info}/WHEEL +0 -0
memos/graph_dbs/base.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
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, content: 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
|
+
content: 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]) -> 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
|
+
"""
|
|
29
|
+
|
|
30
|
+
@abstractmethod
|
|
31
|
+
def delete_node(self, id: str) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Delete a node from the graph.
|
|
34
|
+
Args:
|
|
35
|
+
id: Node identifier to delete.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# Edge (Relationship) Management
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def add_edge(self, source_id: str, target_id: str, type: str) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Create an edge from source node to target node.
|
|
43
|
+
Args:
|
|
44
|
+
source_id: ID of the source node.
|
|
45
|
+
target_id: ID of the target node.
|
|
46
|
+
type: Relationship type (e.g., 'FOLLOWS', 'CAUSES', 'PARENT').
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def delete_edge(self, source_id: str, target_id: str, type: str) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Delete a specific edge between two nodes.
|
|
53
|
+
Args:
|
|
54
|
+
source_id: ID of the source node.
|
|
55
|
+
target_id: ID of the target node.
|
|
56
|
+
type: Relationship type to remove.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def edge_exists(self, source_id: str, target_id: str, type: str) -> bool:
|
|
61
|
+
"""
|
|
62
|
+
Check if an edge exists between two nodes.
|
|
63
|
+
Args:
|
|
64
|
+
source_id: ID of the source node.
|
|
65
|
+
target_id: ID of the target node.
|
|
66
|
+
type: Relationship type.
|
|
67
|
+
Returns:
|
|
68
|
+
True if the edge exists, otherwise False.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
# Graph Query & Reasoning
|
|
72
|
+
@abstractmethod
|
|
73
|
+
def get_node(self, id: str) -> dict[str, Any] | None:
|
|
74
|
+
"""
|
|
75
|
+
Retrieve the metadata and content of a node.
|
|
76
|
+
Args:
|
|
77
|
+
id: Node identifier.
|
|
78
|
+
Returns:
|
|
79
|
+
Dictionary of node fields, or None if not found.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def get_neighbors(
|
|
84
|
+
self, id: str, type: str, direction: Literal["in", "out", "both"] = "out"
|
|
85
|
+
) -> list[str]:
|
|
86
|
+
"""
|
|
87
|
+
Get connected node IDs in a specific direction and relationship type.
|
|
88
|
+
Args:
|
|
89
|
+
id: Source node ID.
|
|
90
|
+
type: Relationship type.
|
|
91
|
+
direction: Edge direction to follow ('out', 'in', or 'both').
|
|
92
|
+
Returns:
|
|
93
|
+
List of neighboring node IDs.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
@abstractmethod
|
|
97
|
+
def get_path(self, source_id: str, target_id: str, max_depth: int = 3) -> list[str]:
|
|
98
|
+
"""
|
|
99
|
+
Get the path of nodes from source to target within a limited depth.
|
|
100
|
+
Args:
|
|
101
|
+
source_id: Starting node ID.
|
|
102
|
+
target_id: Target node ID.
|
|
103
|
+
max_depth: Maximum path length to traverse.
|
|
104
|
+
Returns:
|
|
105
|
+
Ordered list of node IDs along the path.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
@abstractmethod
|
|
109
|
+
def get_subgraph(self, center_id: str, depth: int = 2) -> list[str]:
|
|
110
|
+
"""
|
|
111
|
+
Retrieve a local subgraph centered at a given node.
|
|
112
|
+
Args:
|
|
113
|
+
center_id: Center node ID.
|
|
114
|
+
depth: Radius to include neighboring nodes.
|
|
115
|
+
Returns:
|
|
116
|
+
List of node IDs in the subgraph.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
@abstractmethod
|
|
120
|
+
def get_context_chain(self, id: str, type: str = "FOLLOWS") -> list[str]:
|
|
121
|
+
"""
|
|
122
|
+
Get the ordered context chain starting from a node, following a relationship type.
|
|
123
|
+
Args:
|
|
124
|
+
id: Starting node ID.
|
|
125
|
+
type: Relationship type to follow (e.g., 'FOLLOWS').
|
|
126
|
+
Returns:
|
|
127
|
+
List of ordered node IDs in the chain.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# Search / recall operations
|
|
131
|
+
@abstractmethod
|
|
132
|
+
def search_by_embedding(self, vector: list[float], top_k: int = 5) -> list[dict]:
|
|
133
|
+
"""
|
|
134
|
+
Retrieve node IDs based on vector similarity.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
vector (list[float]): The embedding vector representing query semantics.
|
|
138
|
+
top_k (int): Number of top similar nodes to retrieve.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
list[dict]: A list of dicts with 'id' and 'score', ordered by similarity.
|
|
142
|
+
|
|
143
|
+
Notes:
|
|
144
|
+
- This method may internally call a VecDB (e.g., Qdrant) or store embeddings in the graph DB itself.
|
|
145
|
+
- Commonly used for RAG recall stage to find semantically similar memories.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
@abstractmethod
|
|
149
|
+
def get_by_metadata(self, filters: dict[str, Any]) -> list[str]:
|
|
150
|
+
"""
|
|
151
|
+
Retrieve node IDs that match given metadata filters.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
filters (dict[str, Any]): A dictionary of attribute-value filters.
|
|
155
|
+
Example: {"topic": "psychology", "importance": 2}
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
list[str]: Node IDs whose metadata match the filter conditions.
|
|
159
|
+
|
|
160
|
+
Notes:
|
|
161
|
+
- Supports structured querying such as tag/category/importance/time filtering.
|
|
162
|
+
- Can be used for faceted recall or prefiltering before embedding rerank.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
# Structure Maintenance
|
|
166
|
+
@abstractmethod
|
|
167
|
+
def deduplicate_nodes(self) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Deduplicate redundant or semantically similar nodes.
|
|
170
|
+
This typically involves identifying nodes with identical or near-identical content.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
@abstractmethod
|
|
174
|
+
def detect_conflicts(self) -> list[tuple[str, str]]:
|
|
175
|
+
"""
|
|
176
|
+
Detect conflicting nodes based on logical or semantic inconsistency.
|
|
177
|
+
Returns:
|
|
178
|
+
A list of (node_id1, node_id2) tuples that conflict.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
@abstractmethod
|
|
182
|
+
def merge_nodes(self, id1: str, id2: str) -> str:
|
|
183
|
+
"""
|
|
184
|
+
Merge two similar or duplicate nodes into one.
|
|
185
|
+
Args:
|
|
186
|
+
id1: First node ID.
|
|
187
|
+
id2: Second node ID.
|
|
188
|
+
Returns:
|
|
189
|
+
ID of the resulting merged node.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
# Utilities
|
|
193
|
+
@abstractmethod
|
|
194
|
+
def clear(self) -> None:
|
|
195
|
+
"""
|
|
196
|
+
Clear the entire graph.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
@abstractmethod
|
|
200
|
+
def export_graph(self) -> dict[str, Any]:
|
|
201
|
+
"""
|
|
202
|
+
Export the entire graph as a serializable dictionary.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
A dictionary containing all nodes and edges.
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
@abstractmethod
|
|
209
|
+
def import_graph(self, data: dict[str, Any]) -> None:
|
|
210
|
+
"""
|
|
211
|
+
Import the entire graph from a serialized dictionary.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
data: A dictionary containing all nodes and edges to be loaded.
|
|
215
|
+
"""
|
|
@@ -0,0 +1,21 @@
|
|
|
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.neo4j import Neo4jGraphDB
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GraphStoreFactory(BaseGraphDB):
|
|
9
|
+
"""Factory for creating graph store instances."""
|
|
10
|
+
|
|
11
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
12
|
+
"neo4j": Neo4jGraphDB,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_config(cls, config_factory: GraphDBConfigFactory) -> BaseGraphDB:
|
|
17
|
+
backend = config_factory.backend
|
|
18
|
+
if backend not in cls.backend_to_class:
|
|
19
|
+
raise ValueError(f"Unsupported graph database backend: {backend}")
|
|
20
|
+
graph_class = cls.backend_to_class[backend]
|
|
21
|
+
return graph_class(config_factory.config)
|