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.
- memoryos-0.1.13.dist-info/METADATA +288 -0
- memoryos-0.1.13.dist-info/RECORD +122 -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/internet_retriever.py +81 -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 +74 -0
- memos/configs/mem_reader.py +53 -0
- memos/configs/mem_scheduler.py +78 -0
- memos/configs/memory.py +195 -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 +503 -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 +488 -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 +321 -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/internet_retriever.py +263 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +89 -0
- memos/memories/textual/tree_text_memory/retrieve/reasoner.py +61 -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 +208 -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/memories/textual/tree_text_memory/retrieve/xinyusearch.py +335 -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/templates/mos_prompts.py +63 -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.13.dist-info}/LICENSE +0 -0
- {memoryos-0.0.1.dist-info → memoryos-0.1.13.dist-info}/WHEEL +0 -0
memos/mem_chat/simple.py
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from memos.configs.mem_chat import SimpleMemChatConfig
|
|
6
|
+
from memos.llms.factory import LLMFactory
|
|
7
|
+
from memos.log import get_logger
|
|
8
|
+
from memos.mem_chat.base import BaseMemChat
|
|
9
|
+
from memos.mem_cube.base import BaseMemCube
|
|
10
|
+
from memos.memories.activation.kv import move_dynamic_cache_htod
|
|
11
|
+
from memos.memories.textual.item import TextualMemoryItem
|
|
12
|
+
from memos.types import ChatHistory, MessageList
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
logger = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SimpleMemChat(BaseMemChat):
|
|
19
|
+
"""Simple MemChat class."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: SimpleMemChatConfig):
|
|
22
|
+
"""Initialize the MemChat with the given configuration."""
|
|
23
|
+
self.config = config
|
|
24
|
+
self.chat_llm = LLMFactory.from_config(config.chat_llm)
|
|
25
|
+
self._mem_cube = None
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def mem_cube(self) -> BaseMemCube:
|
|
29
|
+
"""The memory cube associated with this MemChat."""
|
|
30
|
+
return self._mem_cube
|
|
31
|
+
|
|
32
|
+
@mem_cube.setter
|
|
33
|
+
def mem_cube(self, value: BaseMemCube) -> None:
|
|
34
|
+
"""The memory cube associated with this MemChat."""
|
|
35
|
+
self._mem_cube = value
|
|
36
|
+
|
|
37
|
+
def run(self) -> None:
|
|
38
|
+
"""Run the MemChat."""
|
|
39
|
+
|
|
40
|
+
# Start MemChat
|
|
41
|
+
|
|
42
|
+
print(
|
|
43
|
+
"\n📢 [System] " + "Simple MemChat is running.\n"
|
|
44
|
+
"Commands: 'bye' to quit, 'clear' to clear chat history, 'mem' to show all memories, 'export' to export chat history\n",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
messages = []
|
|
48
|
+
while True:
|
|
49
|
+
# Get user input
|
|
50
|
+
|
|
51
|
+
user_input = input("👤 [You] ").strip()
|
|
52
|
+
print()
|
|
53
|
+
|
|
54
|
+
if user_input.lower() == "bye":
|
|
55
|
+
break
|
|
56
|
+
elif user_input.lower() == "clear":
|
|
57
|
+
messages = []
|
|
58
|
+
print("📢 [System] Chat history cleared.")
|
|
59
|
+
continue
|
|
60
|
+
elif user_input.lower() == "mem":
|
|
61
|
+
if self.config.enable_textual_memory:
|
|
62
|
+
all_memories = self.mem_cube.text_mem.get_all()
|
|
63
|
+
print(f"🧠 [Memory] \n{self._str_memories(all_memories)}\n")
|
|
64
|
+
else:
|
|
65
|
+
print("📢 [System] Textual memory is not enabled.\n")
|
|
66
|
+
continue
|
|
67
|
+
elif user_input.lower() == "export":
|
|
68
|
+
if messages:
|
|
69
|
+
filepath = self._export_chat_history(messages)
|
|
70
|
+
print(f"📢 [System] Chat history exported to: {filepath}\n")
|
|
71
|
+
else:
|
|
72
|
+
print("📢 [System] No chat history to export.\n")
|
|
73
|
+
continue
|
|
74
|
+
elif user_input == "":
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
# Get memories
|
|
78
|
+
|
|
79
|
+
if self.config.enable_textual_memory:
|
|
80
|
+
memories = self.mem_cube.text_mem.search(user_input, top_k=self.config.top_k)
|
|
81
|
+
print(
|
|
82
|
+
f"🧠 [Memory] Searched memories:\n{self._str_memories(memories, mode='concise')}\n"
|
|
83
|
+
)
|
|
84
|
+
system_prompt = self._build_system_prompt(memories)
|
|
85
|
+
else:
|
|
86
|
+
system_prompt = self._build_system_prompt()
|
|
87
|
+
current_messages = [
|
|
88
|
+
{"role": "system", "content": system_prompt},
|
|
89
|
+
*messages,
|
|
90
|
+
{"role": "user", "content": user_input},
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
if self.config.enable_activation_memory:
|
|
94
|
+
past_key_values = None
|
|
95
|
+
loaded_kv_cache_item = next(
|
|
96
|
+
iter(self.mem_cube.act_mem.kv_cache_memories.values()), None
|
|
97
|
+
)
|
|
98
|
+
if loaded_kv_cache_item is not None:
|
|
99
|
+
# If has loaded kv cache, we move it to device before inferring.
|
|
100
|
+
# Currently, we move only single kv cache item
|
|
101
|
+
past_key_values = loaded_kv_cache_item
|
|
102
|
+
past_key_values.kv_cache = move_dynamic_cache_htod(
|
|
103
|
+
past_key_values.kv_cache, self.chat_llm.model.device
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Generate response
|
|
107
|
+
response = self.chat_llm.generate(
|
|
108
|
+
current_messages,
|
|
109
|
+
past_key_values=past_key_values.kv_cache if past_key_values else None,
|
|
110
|
+
)
|
|
111
|
+
else:
|
|
112
|
+
# Generate response without activation memory
|
|
113
|
+
response = self.chat_llm.generate(current_messages)
|
|
114
|
+
|
|
115
|
+
print(f"🤖 [Assistant] {response}\n")
|
|
116
|
+
messages.append({"role": "user", "content": user_input})
|
|
117
|
+
messages.append({"role": "assistant", "content": response})
|
|
118
|
+
messages = messages[
|
|
119
|
+
-self.config.max_turns_window :
|
|
120
|
+
] # Keep only recent messages to avoid context overflow
|
|
121
|
+
|
|
122
|
+
# Extract memories
|
|
123
|
+
|
|
124
|
+
if self.config.enable_textual_memory:
|
|
125
|
+
new_memories = self.mem_cube.text_mem.extract(messages[-2:])
|
|
126
|
+
for memory in new_memories:
|
|
127
|
+
memory.metadata.user_id = self.config.user_id
|
|
128
|
+
memory.metadata.session_id = self.config.session_id
|
|
129
|
+
memory.metadata.status = "activated"
|
|
130
|
+
self.mem_cube.text_mem.add(new_memories)
|
|
131
|
+
print(
|
|
132
|
+
f"🧠 [Memory] Stored {len(new_memories)} new memory(ies):\n"
|
|
133
|
+
f"{self._str_memories(new_memories, 'concise')}\n"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Stop MemChat
|
|
137
|
+
|
|
138
|
+
print("📢 [System] MemChat has stopped.")
|
|
139
|
+
|
|
140
|
+
def _build_system_prompt(self, memories: list | None = None) -> str:
|
|
141
|
+
"""Build system prompt with optional memories context."""
|
|
142
|
+
base_prompt = (
|
|
143
|
+
"You are a knowledgeable and helpful AI assistant. "
|
|
144
|
+
"You have access to conversation memories that help you provide more personalized responses. "
|
|
145
|
+
"Use the memories to understand the user's context, preferences, and past interactions. "
|
|
146
|
+
"If memories are provided, reference them naturally when relevant, but don't explicitly mention having memories."
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
if memories:
|
|
150
|
+
memory_context = "\n\n## Memories:\n"
|
|
151
|
+
for i, memory in enumerate(memories, 1):
|
|
152
|
+
memory_context += f"{i}. ({memory.metadata.memory_time}) {memory.memory}\n"
|
|
153
|
+
return base_prompt + memory_context
|
|
154
|
+
|
|
155
|
+
return base_prompt
|
|
156
|
+
|
|
157
|
+
def _str_memories(
|
|
158
|
+
self, memories: list[TextualMemoryItem], mode: Literal["concise", "full"] = "full"
|
|
159
|
+
) -> str:
|
|
160
|
+
"""Format memories for display."""
|
|
161
|
+
if not memories:
|
|
162
|
+
return "No memories."
|
|
163
|
+
if mode == "concise":
|
|
164
|
+
return "\n".join(f"{i + 1}. {memory.memory}" for i, memory in enumerate(memories))
|
|
165
|
+
elif mode == "full":
|
|
166
|
+
return "\n".join(f"{i + 1}. {memory}" for i, memory in enumerate(memories))
|
|
167
|
+
|
|
168
|
+
def _export_chat_history(self, messages: MessageList, output_dir: str = "chat_exports") -> str:
|
|
169
|
+
"""Export chat history to JSON file.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
messages: List of chat messages
|
|
173
|
+
output_dir: Directory to save the export file
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
Path to the exported JSON file
|
|
177
|
+
"""
|
|
178
|
+
# Create output directory if it doesn't exist
|
|
179
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
180
|
+
|
|
181
|
+
# Generate filename with user_id and timestamp
|
|
182
|
+
timestamp = self.config.created_at.strftime("%Y%m%d_%H%M%S")
|
|
183
|
+
filename = f"{self.config.user_id}_{timestamp}_chat_history.json"
|
|
184
|
+
filepath = os.path.join(output_dir, filename)
|
|
185
|
+
|
|
186
|
+
# Prepare export data
|
|
187
|
+
export_data = ChatHistory(
|
|
188
|
+
user_id=self.config.user_id,
|
|
189
|
+
session_id=self.config.session_id,
|
|
190
|
+
created_at=self.config.created_at,
|
|
191
|
+
total_messages=len(messages),
|
|
192
|
+
chat_history=messages,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# Write to JSON file
|
|
196
|
+
with open(filepath, "w", encoding="utf-8") as f:
|
|
197
|
+
f.write(export_data.model_dump_json(indent=4, exclude_none=True, warnings="none"))
|
|
198
|
+
|
|
199
|
+
logger.info(f"Chat history exported to {filepath}")
|
|
200
|
+
return filepath
|
|
File without changes
|
memos/mem_cube/base.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from memos.configs.mem_cube import BaseMemCubeConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from memos.memories.activation.base import BaseActMemory
|
|
9
|
+
from memos.memories.parametric.base import BaseParaMemory
|
|
10
|
+
from memos.memories.textual.base import BaseTextMemory
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BaseMemCube(ABC):
|
|
14
|
+
"""Base class for all MemCube implementations."""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def __init__(self, config: BaseMemCubeConfig):
|
|
18
|
+
"""Initialize the MemCube with the given configuration."""
|
|
19
|
+
self.text_mem: BaseTextMemory
|
|
20
|
+
self.act_mem: BaseActMemory
|
|
21
|
+
self.para_mem: BaseParaMemory
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def load(self, dir: str) -> None:
|
|
25
|
+
"""Load memories from a directory."""
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def dump(self, dir: str) -> None:
|
|
29
|
+
"""Dump memories to a directory."""
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from memos.configs.mem_cube import GeneralMemCubeConfig
|
|
4
|
+
from memos.configs.utils import get_json_file_model_schema
|
|
5
|
+
from memos.exceptions import ConfigurationError, MemCubeError
|
|
6
|
+
from memos.log import get_logger
|
|
7
|
+
from memos.mem_cube.base import BaseMemCube
|
|
8
|
+
from memos.mem_cube.utils import download_repo
|
|
9
|
+
from memos.memories.activation.base import BaseActMemory
|
|
10
|
+
from memos.memories.factory import MemoryFactory
|
|
11
|
+
from memos.memories.parametric.base import BaseParaMemory
|
|
12
|
+
from memos.memories.textual.base import BaseTextMemory
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
logger = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GeneralMemCube(BaseMemCube):
|
|
19
|
+
"""MemCube is a box for loading and dumping three types of memories."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: GeneralMemCubeConfig):
|
|
22
|
+
"""Initialize the MemCube with a configuration."""
|
|
23
|
+
self.config = config
|
|
24
|
+
self._text_mem: BaseTextMemory | None = (
|
|
25
|
+
MemoryFactory.from_config(config.text_mem)
|
|
26
|
+
if config.text_mem.backend != "uninitialized"
|
|
27
|
+
else None
|
|
28
|
+
)
|
|
29
|
+
self._act_mem: BaseActMemory | None = (
|
|
30
|
+
MemoryFactory.from_config(config.act_mem)
|
|
31
|
+
if config.act_mem.backend != "uninitialized"
|
|
32
|
+
else None
|
|
33
|
+
)
|
|
34
|
+
self._para_mem: BaseParaMemory | None = (
|
|
35
|
+
MemoryFactory.from_config(config.para_mem)
|
|
36
|
+
if config.para_mem.backend != "uninitialized"
|
|
37
|
+
else None
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def load(self, dir: str) -> None:
|
|
41
|
+
"""Load memories.
|
|
42
|
+
Args:
|
|
43
|
+
dir (str): The directory containing the memory files.
|
|
44
|
+
"""
|
|
45
|
+
loaded_schema = get_json_file_model_schema(os.path.join(dir, self.config.config_filename))
|
|
46
|
+
if loaded_schema != self.config.model_schema:
|
|
47
|
+
raise ConfigurationError(
|
|
48
|
+
f"Configuration schema mismatch. Expected {self.config.model_schema}, "
|
|
49
|
+
f"but found {loaded_schema}."
|
|
50
|
+
)
|
|
51
|
+
self.text_mem.load(dir) if self.text_mem else None
|
|
52
|
+
self.act_mem.load(dir) if self.act_mem else None
|
|
53
|
+
self.para_mem.load(dir) if self.para_mem else None
|
|
54
|
+
|
|
55
|
+
logger.info(f"MemCube loaded successfully from {dir}")
|
|
56
|
+
|
|
57
|
+
def dump(self, dir: str) -> None:
|
|
58
|
+
"""Dump memories.
|
|
59
|
+
Args:
|
|
60
|
+
dir (str): The directory where the memory files will be saved.
|
|
61
|
+
"""
|
|
62
|
+
if os.path.exists(dir) and os.listdir(dir):
|
|
63
|
+
raise MemCubeError(
|
|
64
|
+
f"Directory {dir} is not empty. Please provide an empty directory for dumping."
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
self.config.to_json_file(os.path.join(dir, self.config.config_filename))
|
|
68
|
+
self.text_mem.dump(dir) if self.text_mem else None
|
|
69
|
+
self.act_mem.dump(dir) if self.act_mem else None
|
|
70
|
+
self.para_mem.dump(dir) if self.para_mem else None
|
|
71
|
+
|
|
72
|
+
logger.info(f"MemCube dumped successfully to {dir}")
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def init_from_dir(dir: str) -> "GeneralMemCube":
|
|
76
|
+
"""Create a MemCube instance from a MemCube directory.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
dir (str): The directory containing the memory files.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
MemCube: An instance of MemCube loaded with memories from the specified directory.
|
|
83
|
+
"""
|
|
84
|
+
config_path = os.path.join(dir, "config.json")
|
|
85
|
+
config = GeneralMemCubeConfig.from_json_file(config_path)
|
|
86
|
+
mem_cube = GeneralMemCube(config)
|
|
87
|
+
mem_cube.load(dir)
|
|
88
|
+
return mem_cube
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def init_from_remote_repo(
|
|
92
|
+
cube_id: str, base_url: str = "https://huggingface.co/datasets"
|
|
93
|
+
) -> "GeneralMemCube":
|
|
94
|
+
"""Create a MemCube instance from a remote repository.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
repo (str): The repository name.
|
|
98
|
+
base_url (str): The base URL of the remote repository.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
MemCube: An instance of MemCube loaded with memories from the specified remote repository.
|
|
102
|
+
"""
|
|
103
|
+
dir = download_repo(cube_id, base_url)
|
|
104
|
+
return GeneralMemCube.init_from_dir(dir)
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def text_mem(self) -> "BaseTextMemory | None":
|
|
108
|
+
"""Get the textual memory."""
|
|
109
|
+
if self._text_mem is None:
|
|
110
|
+
logger.warning("Textual memory is not initialized. Returning None.")
|
|
111
|
+
return self._text_mem
|
|
112
|
+
|
|
113
|
+
@text_mem.setter
|
|
114
|
+
def text_mem(self, value: BaseTextMemory) -> None:
|
|
115
|
+
"""Set the textual memory."""
|
|
116
|
+
if not isinstance(value, BaseTextMemory):
|
|
117
|
+
raise TypeError(f"Expected BaseTextMemory, got {type(value).__name__}")
|
|
118
|
+
self._text_mem = value
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def act_mem(self) -> "BaseActMemory | None":
|
|
122
|
+
"""Get the activation memory."""
|
|
123
|
+
if self._act_mem is None:
|
|
124
|
+
logger.warning("Activation memory is not initialized. Returning None.")
|
|
125
|
+
return self._act_mem
|
|
126
|
+
|
|
127
|
+
@act_mem.setter
|
|
128
|
+
def act_mem(self, value: BaseActMemory) -> None:
|
|
129
|
+
"""Set the activation memory."""
|
|
130
|
+
if not isinstance(value, BaseActMemory):
|
|
131
|
+
raise TypeError(f"Expected BaseActMemory, got {type(value).__name__}")
|
|
132
|
+
self._act_mem = value
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def para_mem(self) -> "BaseParaMemory | None":
|
|
136
|
+
"""Get the parametric memory."""
|
|
137
|
+
if self._para_mem is None:
|
|
138
|
+
logger.warning("Parametric memory is not initialized. Returning None.")
|
|
139
|
+
return self._para_mem
|
|
140
|
+
|
|
141
|
+
@para_mem.setter
|
|
142
|
+
def para_mem(self, value: BaseParaMemory) -> None:
|
|
143
|
+
"""Set the parametric memory."""
|
|
144
|
+
if not isinstance(value, BaseParaMemory):
|
|
145
|
+
raise TypeError(f"Expected BaseParaMemory, got {type(value).__name__}")
|
|
146
|
+
self._para_mem = value
|
memos/mem_cube/utils.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import tempfile
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def download_repo(repo: str, base_url: str, dir: str | None = None) -> str:
|
|
6
|
+
"""Download a repository from a remote source.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
repo (str): The repository name.
|
|
10
|
+
base_url (str): The base URL of the remote repository.
|
|
11
|
+
dir (str, optional): The directory where the repository will be downloaded. If None, a temporary directory will be created.
|
|
12
|
+
If a directory is provided, it will be used instead of creating a temporary one.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
str: The local directory where the repository is downloaded.
|
|
16
|
+
"""
|
|
17
|
+
if dir is None:
|
|
18
|
+
dir = tempfile.mkdtemp()
|
|
19
|
+
repo_url = f"{base_url}/{repo}"
|
|
20
|
+
|
|
21
|
+
# Clone the repo
|
|
22
|
+
subprocess.run(["git", "clone", repo_url, dir], check=True)
|
|
23
|
+
|
|
24
|
+
return dir
|