Skip to content
Open
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ evaluation/scripts/personamem

# benchmarks
benchmarks/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -47,6 +47,7 @@ share/python-wheels/
.installed.cfg
*.egg
MANIFEST
.run

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
9 changes: 0 additions & 9 deletions .vscode/settings.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
user_id: "root"
chat_model:
backend: "huggingface"
config:
model_name_or_path: "Qwen/Qwen3-1.7B"
temperature: 0.1
remove_think_prefix: true
max_tokens: 4096
mem_reader:
backend: "simple_struct"
config:
llm:
backend: "openai"
config:
model_name_or_path: "gpt-4o-mini"
temperature: 0.8
max_tokens: 4096
top_p: 0.9
top_k: 50
remove_think_prefix: true
api_key: "sk-xxxxxx"
api_base: "https://api.openai.com/v1"
embedder:
backend: "ollama"
config:
model_name_or_path: "nomic-embed-text:latest"
chunker:
backend: "sentence"
config:
tokenizer_or_token_counter: "gpt2"
chunk_size: 512
chunk_overlap: 128
min_sentences_per_chunk: 1
mem_scheduler:
backend: "optimized_scheduler"
config:
top_k: 10
act_mem_update_interval: 30
context_window_size: 10
thread_pool_max_workers: 10
consume_interval_seconds: 1
working_mem_monitor_capacity: 20
activation_mem_monitor_capacity: 5
enable_parallel_dispatch: true
enable_activation_memory: true
max_turns_window: 20
top_k: 5
enable_textual_memory: true
enable_activation_memory: true
enable_parametric_memory: false
enable_mem_scheduler: true
109 changes: 109 additions & 0 deletions examples/mem_scheduler/debug_text_mem_replace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import json
import shutil
import sys

from pathlib import Path

from memos_w_scheduler_for_test import init_task

from memos.configs.mem_cube import GeneralMemCubeConfig
from memos.configs.mem_os import MOSConfig
from memos.configs.mem_scheduler import AuthConfig
from memos.log import get_logger
from memos.mem_cube.general import GeneralMemCube
from memos.mem_scheduler.analyzer.mos_for_test_scheduler import MOSForTestScheduler


FILE_PATH = Path(__file__).absolute()
BASE_DIR = FILE_PATH.parent.parent.parent
sys.path.insert(0, str(BASE_DIR))

# Enable execution from any working directory

logger = get_logger(__name__)

if __name__ == "__main__":
# set up data
conversations, questions = init_task()

# set configs
mos_config = MOSConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/memos_config_w_optimized_scheduler_and_openai.yaml"
)

mem_cube_config = GeneralMemCubeConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/mem_cube_config.yaml"
)

# default local graphdb uri
if AuthConfig.default_config_exists():
auth_config = AuthConfig.from_local_config()

mos_config.mem_reader.config.llm.config.api_key = auth_config.openai.api_key
mos_config.mem_reader.config.llm.config.api_base = auth_config.openai.base_url

mem_cube_config.text_mem.config.graph_db.config.uri = auth_config.graph_db.uri
mem_cube_config.text_mem.config.graph_db.config.user = auth_config.graph_db.user
mem_cube_config.text_mem.config.graph_db.config.password = auth_config.graph_db.password
mem_cube_config.text_mem.config.graph_db.config.db_name = auth_config.graph_db.db_name
mem_cube_config.text_mem.config.graph_db.config.auto_create = (
auth_config.graph_db.auto_create
)

# Initialization
mos = MOSForTestScheduler(mos_config)

user_id = "user_1"
mos.create_user(user_id)

mem_cube_id = "mem_cube_5"
mem_cube_name_or_path = f"{BASE_DIR}/outputs/mem_scheduler/{user_id}/{mem_cube_id}"

if Path(mem_cube_name_or_path).exists():
shutil.rmtree(mem_cube_name_or_path)
print(f"{mem_cube_name_or_path} is not empty, and has been removed.")

mem_cube = GeneralMemCube(mem_cube_config)
mem_cube.dump(mem_cube_name_or_path)
mos.register_mem_cube(
mem_cube_name_or_path=mem_cube_name_or_path, mem_cube_id=mem_cube_id, user_id=user_id
)

mos.add(conversations, user_id=user_id, mem_cube_id=mem_cube_id)

# Add interfering conversations
file_path = Path(f"{BASE_DIR}/examples/data/mem_scheduler/scene_data.json")
scene_data = json.load(file_path.open("r", encoding="utf-8"))
mos.add(scene_data[0], user_id=user_id, mem_cube_id=mem_cube_id)
mos.add(scene_data[1], user_id=user_id, mem_cube_id=mem_cube_id)

# Test the replace_working_memory functionality
print("\n--- Testing replace_working_memory ---")

# Get current working memories
text_mem_base = mem_cube.text_mem
if text_mem_base is not None:
working_memories_before = text_mem_base.get_working_memory()
print(f"Working memories before replacement: {len(working_memories_before)}")

# Create filtered memories (simulate what the scheduler would do)
# Keep only memories related to Max
filtered_memories = [working_memories_before[1], working_memories_before[4]]

text_mem_base.replace_working_memory(memories=filtered_memories)

# Check working memory after replacement
working_memories_after = text_mem_base.get_working_memory()
print(f"Working memories after replacement: {len(working_memories_after)}")

if len(working_memories_after) == len(filtered_memories):
print("✅ SUCCESS: Working memory count matches filtered memories")
else:
print(
f"❌ FAILED: Expected {len(filtered_memories)}, got {len(working_memories_after)}"
)

else:
print("❌ text_mem is None - not properly initialized")

mos.mem_scheduler.stop()
85 changes: 85 additions & 0 deletions examples/mem_scheduler/memos_w_optimized_scheduler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import shutil
import sys

from pathlib import Path

from memos_w_scheduler import init_task, show_web_logs

from memos.configs.mem_cube import GeneralMemCubeConfig
from memos.configs.mem_os import MOSConfig
from memos.configs.mem_scheduler import AuthConfig
from memos.log import get_logger
from memos.mem_cube.general import GeneralMemCube
from memos.mem_os.main import MOS


FILE_PATH = Path(__file__).absolute()
BASE_DIR = FILE_PATH.parent.parent.parent
sys.path.insert(0, str(BASE_DIR)) # Enable execution from any working directory

logger = get_logger(__name__)


def run_with_scheduler_init():
print("==== run_with_automatic_scheduler_init ====")
conversations, questions = init_task()

# set configs
mos_config = MOSConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/memos_config_w_optimized_scheduler_and_openai.yaml"
)

mem_cube_config = GeneralMemCubeConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/mem_cube_config.yaml"
)

# default local graphdb uri
if AuthConfig.default_config_exists():
auth_config = AuthConfig.from_local_config()

mos_config.mem_reader.config.llm.config.api_key = auth_config.openai.api_key
mos_config.mem_reader.config.llm.config.api_base = auth_config.openai.base_url

mem_cube_config.text_mem.config.graph_db.config.uri = auth_config.graph_db.uri
mem_cube_config.text_mem.config.graph_db.config.user = auth_config.graph_db.user
mem_cube_config.text_mem.config.graph_db.config.password = auth_config.graph_db.password
mem_cube_config.text_mem.config.graph_db.config.db_name = auth_config.graph_db.db_name
mem_cube_config.text_mem.config.graph_db.config.auto_create = (
auth_config.graph_db.auto_create
)

# Initialization
mos = MOS(mos_config)

user_id = "user_1"
mos.create_user(user_id)

mem_cube_id = "mem_cube_5"
mem_cube_name_or_path = f"{BASE_DIR}/outputs/mem_scheduler/{user_id}/{mem_cube_id}"

if Path(mem_cube_name_or_path).exists():
shutil.rmtree(mem_cube_name_or_path)
print(f"{mem_cube_name_or_path} is not empty, and has been removed.")

mem_cube = GeneralMemCube(mem_cube_config)
mem_cube.dump(mem_cube_name_or_path)
mos.register_mem_cube(
mem_cube_name_or_path=mem_cube_name_or_path, mem_cube_id=mem_cube_id, user_id=user_id
)

mos.add(conversations, user_id=user_id, mem_cube_id=mem_cube_id)

for item in questions:
print("===== Chat Start =====")
query = item["question"]
print(f"Query:\n {query}\n")
response = mos.chat(query=query, user_id=user_id)
print(f"Answer:\n {response}\n")

show_web_logs(mem_scheduler=mos.mem_scheduler)

mos.mem_scheduler.stop()


if __name__ == "__main__":
run_with_scheduler_init()
87 changes: 87 additions & 0 deletions examples/mem_scheduler/memos_w_optimized_scheduler_for_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import json
import shutil
import sys

from pathlib import Path

from memos_w_scheduler_for_test import init_task

from memos.configs.mem_cube import GeneralMemCubeConfig
from memos.configs.mem_os import MOSConfig
from memos.configs.mem_scheduler import AuthConfig
from memos.log import get_logger
from memos.mem_cube.general import GeneralMemCube
from memos.mem_scheduler.analyzer.mos_for_test_scheduler import MOSForTestScheduler


FILE_PATH = Path(__file__).absolute()
BASE_DIR = FILE_PATH.parent.parent.parent
sys.path.insert(0, str(BASE_DIR))

# Enable execution from any working directory

logger = get_logger(__name__)

if __name__ == "__main__":
# set up data
conversations, questions = init_task()

# set configs
mos_config = MOSConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/memos_config_w_optimized_scheduler_and_openai.yaml"
)

mem_cube_config = GeneralMemCubeConfig.from_yaml_file(
f"{BASE_DIR}/examples/data/config/mem_scheduler/mem_cube_config.yaml"
)

# default local graphdb uri
if AuthConfig.default_config_exists():
auth_config = AuthConfig.from_local_config()

mos_config.mem_reader.config.llm.config.api_key = auth_config.openai.api_key
mos_config.mem_reader.config.llm.config.api_base = auth_config.openai.base_url

mem_cube_config.text_mem.config.graph_db.config.uri = auth_config.graph_db.uri
mem_cube_config.text_mem.config.graph_db.config.user = auth_config.graph_db.user
mem_cube_config.text_mem.config.graph_db.config.password = auth_config.graph_db.password
mem_cube_config.text_mem.config.graph_db.config.db_name = auth_config.graph_db.db_name
mem_cube_config.text_mem.config.graph_db.config.auto_create = (
auth_config.graph_db.auto_create
)

# Initialization
mos = MOSForTestScheduler(mos_config)

user_id = "user_1"
mos.create_user(user_id)

mem_cube_id = "mem_cube_5"
mem_cube_name_or_path = f"{BASE_DIR}/outputs/mem_scheduler/{user_id}/{mem_cube_id}"

if Path(mem_cube_name_or_path).exists():
shutil.rmtree(mem_cube_name_or_path)
print(f"{mem_cube_name_or_path} is not empty, and has been removed.")

mem_cube = GeneralMemCube(mem_cube_config)
mem_cube.dump(mem_cube_name_or_path)
mos.register_mem_cube(
mem_cube_name_or_path=mem_cube_name_or_path, mem_cube_id=mem_cube_id, user_id=user_id
)

mos.add(conversations, user_id=user_id, mem_cube_id=mem_cube_id)

# Add interfering conversations
file_path = Path(f"{BASE_DIR}/examples/data/mem_scheduler/scene_data.json")
scene_data = json.load(file_path.open("r", encoding="utf-8"))
mos.add(scene_data[0], user_id=user_id, mem_cube_id=mem_cube_id)
mos.add(scene_data[1], user_id=user_id, mem_cube_id=mem_cube_id)

for item in questions:
print("===== Chat Start =====")
query = item["question"]
print(f"Query:\n {query}\n")
response = mos.chat(query=query, user_id=user_id)
print(f"Answer:\n {response}\n")

mos.mem_scheduler.stop()
2 changes: 1 addition & 1 deletion examples/mem_scheduler/memos_w_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


if TYPE_CHECKING:
from memos.mem_scheduler.schemas import (
from memos.mem_scheduler.schemas.message_schemas import (
ScheduleLogForWebItem,
)

Expand Down
Loading
Loading