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.
- {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/METADATA +7 -1
- {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/RECORD +87 -64
- memos/__init__.py +1 -1
- memos/api/config.py +158 -69
- memos/api/context/context.py +147 -0
- memos/api/context/dependencies.py +101 -0
- memos/api/product_models.py +5 -1
- memos/api/routers/product_router.py +54 -26
- memos/configs/graph_db.py +49 -1
- memos/configs/internet_retriever.py +19 -0
- memos/configs/mem_os.py +5 -0
- memos/configs/mem_reader.py +9 -0
- memos/configs/mem_scheduler.py +54 -18
- memos/configs/mem_user.py +58 -0
- memos/graph_dbs/base.py +38 -3
- memos/graph_dbs/factory.py +2 -0
- memos/graph_dbs/nebular.py +1612 -0
- memos/graph_dbs/neo4j.py +18 -9
- memos/log.py +6 -1
- memos/mem_cube/utils.py +13 -6
- memos/mem_os/core.py +157 -37
- memos/mem_os/main.py +2 -2
- memos/mem_os/product.py +252 -201
- memos/mem_os/utils/default_config.py +1 -1
- memos/mem_os/utils/format_utils.py +281 -70
- memos/mem_os/utils/reference_utils.py +133 -0
- memos/mem_reader/simple_struct.py +13 -5
- memos/mem_scheduler/base_scheduler.py +239 -266
- memos/mem_scheduler/{modules → general_modules}/base.py +4 -5
- memos/mem_scheduler/{modules → general_modules}/dispatcher.py +57 -21
- memos/mem_scheduler/general_modules/misc.py +104 -0
- memos/mem_scheduler/{modules → general_modules}/rabbitmq_service.py +12 -10
- memos/mem_scheduler/{modules → general_modules}/redis_service.py +1 -1
- memos/mem_scheduler/general_modules/retriever.py +199 -0
- memos/mem_scheduler/general_modules/scheduler_logger.py +261 -0
- memos/mem_scheduler/general_scheduler.py +243 -80
- memos/mem_scheduler/monitors/__init__.py +0 -0
- memos/mem_scheduler/monitors/dispatcher_monitor.py +305 -0
- memos/mem_scheduler/{modules/monitor.py → monitors/general_monitor.py} +106 -57
- memos/mem_scheduler/mos_for_test_scheduler.py +23 -20
- memos/mem_scheduler/schemas/__init__.py +0 -0
- memos/mem_scheduler/schemas/general_schemas.py +44 -0
- memos/mem_scheduler/schemas/message_schemas.py +149 -0
- memos/mem_scheduler/schemas/monitor_schemas.py +337 -0
- memos/mem_scheduler/utils/__init__.py +0 -0
- memos/mem_scheduler/utils/filter_utils.py +176 -0
- memos/mem_scheduler/utils/misc_utils.py +102 -0
- memos/mem_user/factory.py +94 -0
- memos/mem_user/mysql_persistent_user_manager.py +271 -0
- memos/mem_user/mysql_user_manager.py +500 -0
- memos/mem_user/persistent_factory.py +96 -0
- memos/mem_user/user_manager.py +4 -4
- memos/memories/activation/item.py +5 -1
- memos/memories/activation/kv.py +20 -8
- memos/memories/textual/base.py +2 -2
- memos/memories/textual/general.py +36 -92
- memos/memories/textual/item.py +5 -33
- memos/memories/textual/tree.py +13 -7
- memos/memories/textual/tree_text_memory/organize/{conflict.py → handler.py} +34 -50
- memos/memories/textual/tree_text_memory/organize/manager.py +8 -96
- memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +49 -43
- memos/memories/textual/tree_text_memory/organize/reorganizer.py +107 -142
- memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +229 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +6 -3
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +11 -0
- memos/memories/textual/tree_text_memory/retrieve/recall.py +15 -8
- memos/memories/textual/tree_text_memory/retrieve/reranker.py +1 -1
- memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +2 -0
- memos/memories/textual/tree_text_memory/retrieve/searcher.py +191 -116
- memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +47 -15
- memos/memories/textual/tree_text_memory/retrieve/utils.py +11 -7
- memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +62 -58
- memos/memos_tools/dinding_report_bot.py +422 -0
- memos/memos_tools/lockfree_dict.py +120 -0
- memos/memos_tools/notification_service.py +44 -0
- memos/memos_tools/notification_utils.py +96 -0
- memos/memos_tools/thread_safe_dict.py +288 -0
- memos/settings.py +3 -1
- memos/templates/mem_reader_prompts.py +4 -1
- memos/templates/mem_scheduler_prompts.py +62 -15
- memos/templates/mos_prompts.py +116 -0
- memos/templates/tree_reorganize_prompts.py +24 -17
- memos/utils.py +19 -0
- memos/mem_scheduler/modules/misc.py +0 -39
- memos/mem_scheduler/modules/retriever.py +0 -268
- memos/mem_scheduler/modules/schemas.py +0 -328
- memos/mem_scheduler/utils.py +0 -75
- memos/memories/textual/tree_text_memory/organize/redundancy.py +0 -193
- {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/LICENSE +0 -0
- {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/WHEEL +0 -0
- {memoryos-0.2.1.dist-info → memoryos-1.0.0.dist-info}/entry_points.txt +0 -0
- /memos/mem_scheduler/{modules → general_modules}/__init__.py +0 -0
memos/configs/mem_scheduler.py
CHANGED
|
@@ -6,12 +6,12 @@ from typing import Any, ClassVar
|
|
|
6
6
|
from pydantic import ConfigDict, Field, field_validator, model_validator
|
|
7
7
|
|
|
8
8
|
from memos.configs.base import BaseConfig
|
|
9
|
-
from memos.mem_scheduler.
|
|
9
|
+
from memos.mem_scheduler.general_modules.misc import DictConversionMixin
|
|
10
|
+
from memos.mem_scheduler.schemas.general_schemas import (
|
|
10
11
|
BASE_DIR,
|
|
11
12
|
DEFAULT_ACT_MEM_DUMP_PATH,
|
|
12
13
|
DEFAULT_CONSUME_INTERVAL_SECONDS,
|
|
13
14
|
DEFAULT_THREAD__POOL_MAX_WORKERS,
|
|
14
|
-
DictConversionMixin,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
|
|
@@ -21,7 +21,6 @@ class BaseSchedulerConfig(BaseConfig):
|
|
|
21
21
|
top_k: int = Field(
|
|
22
22
|
default=10, description="Number of top candidates to consider in initial retrieval"
|
|
23
23
|
)
|
|
24
|
-
top_n: int = Field(default=5, description="Number of final results to return after processing")
|
|
25
24
|
enable_parallel_dispatch: bool = Field(
|
|
26
25
|
default=True, description="Whether to enable parallel message processing using thread pool"
|
|
27
26
|
)
|
|
@@ -44,19 +43,26 @@ class BaseSchedulerConfig(BaseConfig):
|
|
|
44
43
|
|
|
45
44
|
|
|
46
45
|
class GeneralSchedulerConfig(BaseSchedulerConfig):
|
|
46
|
+
model_config = ConfigDict(extra="ignore", strict=True)
|
|
47
47
|
act_mem_update_interval: int | None = Field(
|
|
48
48
|
default=300, description="Interval in seconds for updating activation memory"
|
|
49
49
|
)
|
|
50
50
|
context_window_size: int | None = Field(
|
|
51
|
-
default=
|
|
51
|
+
default=10, description="Size of the context window for conversation history"
|
|
52
52
|
)
|
|
53
53
|
act_mem_dump_path: str | None = Field(
|
|
54
54
|
default=DEFAULT_ACT_MEM_DUMP_PATH, # Replace with DEFAULT_ACT_MEM_DUMP_PATH
|
|
55
55
|
description="File path for dumping activation memory",
|
|
56
56
|
)
|
|
57
|
-
|
|
57
|
+
enable_activation_memory: bool = Field(
|
|
58
58
|
default=False, description="Whether to enable automatic activation memory updates"
|
|
59
59
|
)
|
|
60
|
+
working_mem_monitor_capacity: int = Field(
|
|
61
|
+
default=30, description="Capacity of the working memory monitor"
|
|
62
|
+
)
|
|
63
|
+
activation_mem_monitor_capacity: int = Field(
|
|
64
|
+
default=20, description="Capacity of the activation memory monitor"
|
|
65
|
+
)
|
|
60
66
|
|
|
61
67
|
|
|
62
68
|
class SchedulerConfigFactory(BaseConfig):
|
|
@@ -105,7 +111,20 @@ class RabbitMQConfig(
|
|
|
105
111
|
|
|
106
112
|
|
|
107
113
|
class GraphDBAuthConfig(BaseConfig):
|
|
108
|
-
uri: str = Field(
|
|
114
|
+
uri: str = Field(
|
|
115
|
+
default="bolt://localhost:7687",
|
|
116
|
+
description="URI for graph database access (e.g., bolt://host:port)",
|
|
117
|
+
)
|
|
118
|
+
user: str = Field(default="neo4j", description="Username for graph database authentication")
|
|
119
|
+
password: str = Field(
|
|
120
|
+
default="",
|
|
121
|
+
description="Password for graph database authentication",
|
|
122
|
+
min_length=8, # 建议密码最小长度
|
|
123
|
+
)
|
|
124
|
+
db_name: str = Field(default="neo4j", description="Database name to connect to")
|
|
125
|
+
auto_create: bool = Field(
|
|
126
|
+
default=True, description="Whether to automatically create the database if it doesn't exist"
|
|
127
|
+
)
|
|
109
128
|
|
|
110
129
|
|
|
111
130
|
class OpenAIConfig(BaseConfig):
|
|
@@ -123,29 +142,46 @@ class AuthConfig(BaseConfig, DictConversionMixin):
|
|
|
123
142
|
)
|
|
124
143
|
|
|
125
144
|
@classmethod
|
|
126
|
-
def
|
|
145
|
+
def from_local_config(cls, config_path: str | Path | None = None) -> "AuthConfig":
|
|
127
146
|
"""
|
|
128
|
-
Load configuration from YAML file
|
|
147
|
+
Load configuration from either a YAML or JSON file based on file extension.
|
|
148
|
+
|
|
149
|
+
Automatically detects file type (YAML or JSON) from the file extension
|
|
150
|
+
and uses the appropriate parser. If no path is provided, uses the default
|
|
151
|
+
configuration path (YAML) or its JSON counterpart.
|
|
129
152
|
|
|
130
153
|
Args:
|
|
131
|
-
config_path:
|
|
154
|
+
config_path: Optional path to configuration file.
|
|
155
|
+
If not provided, uses default configuration path.
|
|
132
156
|
|
|
133
157
|
Returns:
|
|
134
|
-
AuthConfig instance
|
|
158
|
+
AuthConfig instance populated with data from the configuration file.
|
|
135
159
|
|
|
136
160
|
Raises:
|
|
137
|
-
FileNotFoundError: If
|
|
138
|
-
ValueError: If
|
|
161
|
+
FileNotFoundError: If the specified or default configuration file does not exist.
|
|
162
|
+
ValueError: If file extension is not .yaml/.yml or .json, or if parsing fails.
|
|
139
163
|
"""
|
|
140
|
-
|
|
164
|
+
# Determine config path
|
|
141
165
|
if config_path is None:
|
|
142
166
|
config_path = cls.default_config_path
|
|
143
167
|
|
|
144
|
-
#
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
# Validate file existence
|
|
169
|
+
config_path_obj = Path(config_path)
|
|
170
|
+
if not config_path_obj.exists():
|
|
171
|
+
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
|
172
|
+
|
|
173
|
+
# Get file extension and determine parser
|
|
174
|
+
file_ext = config_path_obj.suffix.lower()
|
|
175
|
+
|
|
176
|
+
if file_ext in (".yaml", ".yml"):
|
|
177
|
+
return cls.from_yaml_file(yaml_path=str(config_path_obj))
|
|
178
|
+
elif file_ext == ".json":
|
|
179
|
+
return cls.from_json_file(json_path=str(config_path_obj))
|
|
180
|
+
else:
|
|
181
|
+
raise ValueError(
|
|
182
|
+
f"Unsupported file format: {file_ext}. "
|
|
183
|
+
"Please use YAML (.yaml, .yml) or JSON (.json) files."
|
|
184
|
+
)
|
|
149
185
|
|
|
150
186
|
def set_openai_config_to_environment(self):
|
|
151
187
|
# Set environment variables
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Any, ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
4
|
+
|
|
5
|
+
from memos.configs.base import BaseConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseUserManagerConfig(BaseConfig):
|
|
9
|
+
"""Base configuration class for user managers."""
|
|
10
|
+
|
|
11
|
+
user_id: str = Field(default="root", description="Default user ID for initialization")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SQLiteUserManagerConfig(BaseUserManagerConfig):
|
|
15
|
+
"""SQLite user manager configuration."""
|
|
16
|
+
|
|
17
|
+
db_path: str | None = Field(
|
|
18
|
+
default=None,
|
|
19
|
+
description="Path to SQLite database file. If None, uses default path in MEMOS_DIR",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MySQLUserManagerConfig(BaseUserManagerConfig):
|
|
24
|
+
"""MySQL user manager configuration."""
|
|
25
|
+
|
|
26
|
+
host: str = Field(default="localhost", description="MySQL server host")
|
|
27
|
+
port: int = Field(default=3306, description="MySQL server port")
|
|
28
|
+
username: str = Field(default="root", description="MySQL username")
|
|
29
|
+
password: str = Field(default="", description="MySQL password")
|
|
30
|
+
database: str = Field(default="memos_users", description="MySQL database name")
|
|
31
|
+
charset: str = Field(default="utf8mb4", description="MySQL charset")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class UserManagerConfigFactory(BaseModel):
|
|
35
|
+
"""Factory for user manager configurations."""
|
|
36
|
+
|
|
37
|
+
backend: str = Field(default="sqlite", description="Backend for user manager")
|
|
38
|
+
config: dict[str, Any] = Field(
|
|
39
|
+
default_factory=dict, description="Configuration for the user manager backend"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
43
|
+
"sqlite": SQLiteUserManagerConfig,
|
|
44
|
+
"mysql": MySQLUserManagerConfig,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@field_validator("backend")
|
|
48
|
+
@classmethod
|
|
49
|
+
def validate_backend(cls, backend: str) -> str:
|
|
50
|
+
if backend not in cls.backend_to_class:
|
|
51
|
+
raise ValueError(f"Unsupported user manager backend: {backend}")
|
|
52
|
+
return backend
|
|
53
|
+
|
|
54
|
+
@model_validator(mode="after")
|
|
55
|
+
def instantiate_config(self):
|
|
56
|
+
config_class = self.backend_to_class[self.backend]
|
|
57
|
+
self.config = config_class(**self.config)
|
|
58
|
+
return self
|
memos/graph_dbs/base.py
CHANGED
|
@@ -70,15 +70,27 @@ class BaseGraphDB(ABC):
|
|
|
70
70
|
|
|
71
71
|
# Graph Query & Reasoning
|
|
72
72
|
@abstractmethod
|
|
73
|
-
def get_node(self, id: str) -> dict[str, Any] | None:
|
|
73
|
+
def get_node(self, id: str, include_embedding: bool = False) -> dict[str, Any] | None:
|
|
74
74
|
"""
|
|
75
75
|
Retrieve the metadata and content of a node.
|
|
76
76
|
Args:
|
|
77
77
|
id: Node identifier.
|
|
78
|
+
include_embedding: with/without embedding
|
|
78
79
|
Returns:
|
|
79
80
|
Dictionary of node fields, or None if not found.
|
|
80
81
|
"""
|
|
81
82
|
|
|
83
|
+
@abstractmethod
|
|
84
|
+
def get_nodes(self, id: str, include_embedding: bool = False) -> dict[str, Any] | None:
|
|
85
|
+
"""
|
|
86
|
+
Retrieve the metadata and memory of a list of nodes.
|
|
87
|
+
Args:
|
|
88
|
+
ids: List of Node identifier.
|
|
89
|
+
include_embedding: with/without embedding
|
|
90
|
+
Returns:
|
|
91
|
+
list[dict]: Parsed node records containing 'id', 'memory', and 'metadata'.
|
|
92
|
+
"""
|
|
93
|
+
|
|
82
94
|
@abstractmethod
|
|
83
95
|
def get_neighbors(
|
|
84
96
|
self, id: str, type: str, direction: Literal["in", "out", "both"] = "out"
|
|
@@ -146,7 +158,7 @@ class BaseGraphDB(ABC):
|
|
|
146
158
|
"""
|
|
147
159
|
|
|
148
160
|
@abstractmethod
|
|
149
|
-
def get_by_metadata(self, filters: dict[str, Any]) -> list[str]:
|
|
161
|
+
def get_by_metadata(self, filters: list[dict[str, Any]]) -> list[str]:
|
|
150
162
|
"""
|
|
151
163
|
Retrieve node IDs that match given metadata filters.
|
|
152
164
|
|
|
@@ -162,6 +174,16 @@ class BaseGraphDB(ABC):
|
|
|
162
174
|
- Can be used for faceted recall or prefiltering before embedding rerank.
|
|
163
175
|
"""
|
|
164
176
|
|
|
177
|
+
@abstractmethod
|
|
178
|
+
def get_structure_optimization_candidates(
|
|
179
|
+
self, scope: str, include_embedding: bool = False
|
|
180
|
+
) -> list[dict]:
|
|
181
|
+
"""
|
|
182
|
+
Find nodes that are likely candidates for structure optimization:
|
|
183
|
+
- Isolated nodes, nodes with empty background, or nodes with exactly one child.
|
|
184
|
+
- Plus: the child of any parent node that has exactly one child.
|
|
185
|
+
"""
|
|
186
|
+
|
|
165
187
|
# Structure Maintenance
|
|
166
188
|
@abstractmethod
|
|
167
189
|
def deduplicate_nodes(self) -> None:
|
|
@@ -197,7 +219,7 @@ class BaseGraphDB(ABC):
|
|
|
197
219
|
"""
|
|
198
220
|
|
|
199
221
|
@abstractmethod
|
|
200
|
-
def export_graph(self) -> dict[str, Any]:
|
|
222
|
+
def export_graph(self, include_embedding: bool = False) -> dict[str, Any]:
|
|
201
223
|
"""
|
|
202
224
|
Export the entire graph as a serializable dictionary.
|
|
203
225
|
|
|
@@ -213,3 +235,16 @@ class BaseGraphDB(ABC):
|
|
|
213
235
|
Args:
|
|
214
236
|
data: A dictionary containing all nodes and edges to be loaded.
|
|
215
237
|
"""
|
|
238
|
+
|
|
239
|
+
@abstractmethod
|
|
240
|
+
def get_all_memory_items(self, scope: str, include_embedding: bool = False) -> list[dict]:
|
|
241
|
+
"""
|
|
242
|
+
Retrieve all memory items of a specific memory_type.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
scope (str): Must be one of 'WorkingMemory', 'LongTermMemory', or 'UserMemory'.
|
|
246
|
+
include_embedding: with/without embedding
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
list[dict]: Full list of memory items under this scope.
|
|
250
|
+
"""
|
memos/graph_dbs/factory.py
CHANGED
|
@@ -2,6 +2,7 @@ from typing import Any, ClassVar
|
|
|
2
2
|
|
|
3
3
|
from memos.configs.graph_db import GraphDBConfigFactory
|
|
4
4
|
from memos.graph_dbs.base import BaseGraphDB
|
|
5
|
+
from memos.graph_dbs.nebular import NebulaGraphDB
|
|
5
6
|
from memos.graph_dbs.neo4j import Neo4jGraphDB
|
|
6
7
|
from memos.graph_dbs.neo4j_community import Neo4jCommunityGraphDB
|
|
7
8
|
|
|
@@ -12,6 +13,7 @@ class GraphStoreFactory(BaseGraphDB):
|
|
|
12
13
|
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
13
14
|
"neo4j": Neo4jGraphDB,
|
|
14
15
|
"neo4j-community": Neo4jCommunityGraphDB,
|
|
16
|
+
"nebular": NebulaGraphDB,
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
@classmethod
|