MemoryOS 2.0.3__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.
- memoryos-2.0.3.dist-info/METADATA +418 -0
- memoryos-2.0.3.dist-info/RECORD +315 -0
- memoryos-2.0.3.dist-info/WHEEL +4 -0
- memoryos-2.0.3.dist-info/entry_points.txt +3 -0
- memoryos-2.0.3.dist-info/licenses/LICENSE +201 -0
- memos/__init__.py +20 -0
- memos/api/client.py +571 -0
- memos/api/config.py +1018 -0
- memos/api/context/dependencies.py +50 -0
- memos/api/exceptions.py +53 -0
- memos/api/handlers/__init__.py +62 -0
- memos/api/handlers/add_handler.py +158 -0
- memos/api/handlers/base_handler.py +194 -0
- memos/api/handlers/chat_handler.py +1401 -0
- memos/api/handlers/component_init.py +388 -0
- memos/api/handlers/config_builders.py +190 -0
- memos/api/handlers/feedback_handler.py +93 -0
- memos/api/handlers/formatters_handler.py +237 -0
- memos/api/handlers/memory_handler.py +316 -0
- memos/api/handlers/scheduler_handler.py +497 -0
- memos/api/handlers/search_handler.py +222 -0
- memos/api/handlers/suggestion_handler.py +117 -0
- memos/api/mcp_serve.py +614 -0
- memos/api/middleware/request_context.py +101 -0
- memos/api/product_api.py +38 -0
- memos/api/product_models.py +1206 -0
- memos/api/routers/__init__.py +1 -0
- memos/api/routers/product_router.py +477 -0
- memos/api/routers/server_router.py +394 -0
- memos/api/server_api.py +44 -0
- memos/api/start_api.py +433 -0
- memos/chunkers/__init__.py +4 -0
- memos/chunkers/base.py +24 -0
- memos/chunkers/charactertext_chunker.py +41 -0
- memos/chunkers/factory.py +24 -0
- memos/chunkers/markdown_chunker.py +62 -0
- memos/chunkers/sentence_chunker.py +54 -0
- memos/chunkers/simple_chunker.py +50 -0
- memos/cli.py +113 -0
- memos/configs/__init__.py +0 -0
- memos/configs/base.py +82 -0
- memos/configs/chunker.py +59 -0
- memos/configs/embedder.py +88 -0
- memos/configs/graph_db.py +236 -0
- memos/configs/internet_retriever.py +100 -0
- memos/configs/llm.py +151 -0
- memos/configs/mem_agent.py +54 -0
- memos/configs/mem_chat.py +81 -0
- memos/configs/mem_cube.py +105 -0
- memos/configs/mem_os.py +83 -0
- memos/configs/mem_reader.py +91 -0
- memos/configs/mem_scheduler.py +385 -0
- memos/configs/mem_user.py +70 -0
- memos/configs/memory.py +324 -0
- memos/configs/parser.py +38 -0
- memos/configs/reranker.py +18 -0
- memos/configs/utils.py +8 -0
- memos/configs/vec_db.py +80 -0
- memos/context/context.py +355 -0
- memos/dependency.py +52 -0
- memos/deprecation.py +262 -0
- memos/embedders/__init__.py +0 -0
- memos/embedders/ark.py +95 -0
- memos/embedders/base.py +106 -0
- memos/embedders/factory.py +29 -0
- memos/embedders/ollama.py +77 -0
- memos/embedders/sentence_transformer.py +49 -0
- memos/embedders/universal_api.py +51 -0
- memos/exceptions.py +30 -0
- memos/graph_dbs/__init__.py +0 -0
- memos/graph_dbs/base.py +274 -0
- memos/graph_dbs/factory.py +27 -0
- memos/graph_dbs/item.py +46 -0
- memos/graph_dbs/nebular.py +1794 -0
- memos/graph_dbs/neo4j.py +1942 -0
- memos/graph_dbs/neo4j_community.py +1058 -0
- memos/graph_dbs/polardb.py +5446 -0
- memos/hello_world.py +97 -0
- memos/llms/__init__.py +0 -0
- memos/llms/base.py +25 -0
- memos/llms/deepseek.py +13 -0
- memos/llms/factory.py +38 -0
- memos/llms/hf.py +443 -0
- memos/llms/hf_singleton.py +114 -0
- memos/llms/ollama.py +135 -0
- memos/llms/openai.py +222 -0
- memos/llms/openai_new.py +198 -0
- memos/llms/qwen.py +13 -0
- memos/llms/utils.py +14 -0
- memos/llms/vllm.py +218 -0
- memos/log.py +237 -0
- memos/mem_agent/base.py +19 -0
- memos/mem_agent/deepsearch_agent.py +391 -0
- memos/mem_agent/factory.py +36 -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 +30 -0
- memos/mem_cube/general.py +240 -0
- memos/mem_cube/navie.py +172 -0
- memos/mem_cube/utils.py +169 -0
- memos/mem_feedback/base.py +15 -0
- memos/mem_feedback/feedback.py +1192 -0
- memos/mem_feedback/simple_feedback.py +40 -0
- memos/mem_feedback/utils.py +230 -0
- memos/mem_os/client.py +5 -0
- memos/mem_os/core.py +1203 -0
- memos/mem_os/main.py +582 -0
- memos/mem_os/product.py +1608 -0
- memos/mem_os/product_server.py +455 -0
- memos/mem_os/utils/default_config.py +359 -0
- memos/mem_os/utils/format_utils.py +1403 -0
- memos/mem_os/utils/reference_utils.py +162 -0
- memos/mem_reader/__init__.py +0 -0
- memos/mem_reader/base.py +47 -0
- memos/mem_reader/factory.py +53 -0
- memos/mem_reader/memory.py +298 -0
- memos/mem_reader/multi_modal_struct.py +965 -0
- memos/mem_reader/read_multi_modal/__init__.py +43 -0
- memos/mem_reader/read_multi_modal/assistant_parser.py +311 -0
- memos/mem_reader/read_multi_modal/base.py +273 -0
- memos/mem_reader/read_multi_modal/file_content_parser.py +826 -0
- memos/mem_reader/read_multi_modal/image_parser.py +359 -0
- memos/mem_reader/read_multi_modal/multi_modal_parser.py +252 -0
- memos/mem_reader/read_multi_modal/string_parser.py +139 -0
- memos/mem_reader/read_multi_modal/system_parser.py +327 -0
- memos/mem_reader/read_multi_modal/text_content_parser.py +131 -0
- memos/mem_reader/read_multi_modal/tool_parser.py +210 -0
- memos/mem_reader/read_multi_modal/user_parser.py +218 -0
- memos/mem_reader/read_multi_modal/utils.py +358 -0
- memos/mem_reader/simple_struct.py +912 -0
- memos/mem_reader/strategy_struct.py +163 -0
- memos/mem_reader/utils.py +157 -0
- memos/mem_scheduler/__init__.py +0 -0
- memos/mem_scheduler/analyzer/__init__.py +0 -0
- memos/mem_scheduler/analyzer/api_analyzer.py +714 -0
- memos/mem_scheduler/analyzer/eval_analyzer.py +219 -0
- memos/mem_scheduler/analyzer/mos_for_test_scheduler.py +571 -0
- memos/mem_scheduler/analyzer/scheduler_for_eval.py +280 -0
- memos/mem_scheduler/base_scheduler.py +1319 -0
- memos/mem_scheduler/general_modules/__init__.py +0 -0
- memos/mem_scheduler/general_modules/api_misc.py +137 -0
- memos/mem_scheduler/general_modules/base.py +80 -0
- memos/mem_scheduler/general_modules/init_components_for_scheduler.py +425 -0
- memos/mem_scheduler/general_modules/misc.py +313 -0
- memos/mem_scheduler/general_modules/scheduler_logger.py +389 -0
- memos/mem_scheduler/general_modules/task_threads.py +315 -0
- memos/mem_scheduler/general_scheduler.py +1495 -0
- memos/mem_scheduler/memory_manage_modules/__init__.py +5 -0
- memos/mem_scheduler/memory_manage_modules/memory_filter.py +306 -0
- memos/mem_scheduler/memory_manage_modules/retriever.py +547 -0
- memos/mem_scheduler/monitors/__init__.py +0 -0
- memos/mem_scheduler/monitors/dispatcher_monitor.py +366 -0
- memos/mem_scheduler/monitors/general_monitor.py +394 -0
- memos/mem_scheduler/monitors/task_schedule_monitor.py +254 -0
- memos/mem_scheduler/optimized_scheduler.py +410 -0
- memos/mem_scheduler/orm_modules/__init__.py +0 -0
- memos/mem_scheduler/orm_modules/api_redis_model.py +518 -0
- memos/mem_scheduler/orm_modules/base_model.py +729 -0
- memos/mem_scheduler/orm_modules/monitor_models.py +261 -0
- memos/mem_scheduler/orm_modules/redis_model.py +699 -0
- memos/mem_scheduler/scheduler_factory.py +23 -0
- memos/mem_scheduler/schemas/__init__.py +0 -0
- memos/mem_scheduler/schemas/analyzer_schemas.py +52 -0
- memos/mem_scheduler/schemas/api_schemas.py +233 -0
- memos/mem_scheduler/schemas/general_schemas.py +55 -0
- memos/mem_scheduler/schemas/message_schemas.py +173 -0
- memos/mem_scheduler/schemas/monitor_schemas.py +406 -0
- memos/mem_scheduler/schemas/task_schemas.py +132 -0
- memos/mem_scheduler/task_schedule_modules/__init__.py +0 -0
- memos/mem_scheduler/task_schedule_modules/dispatcher.py +740 -0
- memos/mem_scheduler/task_schedule_modules/local_queue.py +247 -0
- memos/mem_scheduler/task_schedule_modules/orchestrator.py +74 -0
- memos/mem_scheduler/task_schedule_modules/redis_queue.py +1385 -0
- memos/mem_scheduler/task_schedule_modules/task_queue.py +162 -0
- memos/mem_scheduler/utils/__init__.py +0 -0
- memos/mem_scheduler/utils/api_utils.py +77 -0
- memos/mem_scheduler/utils/config_utils.py +100 -0
- memos/mem_scheduler/utils/db_utils.py +50 -0
- memos/mem_scheduler/utils/filter_utils.py +176 -0
- memos/mem_scheduler/utils/metrics.py +125 -0
- memos/mem_scheduler/utils/misc_utils.py +290 -0
- memos/mem_scheduler/utils/monitor_event_utils.py +67 -0
- memos/mem_scheduler/utils/status_tracker.py +229 -0
- memos/mem_scheduler/webservice_modules/__init__.py +0 -0
- memos/mem_scheduler/webservice_modules/rabbitmq_service.py +485 -0
- memos/mem_scheduler/webservice_modules/redis_service.py +380 -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 +502 -0
- memos/mem_user/persistent_factory.py +98 -0
- memos/mem_user/persistent_user_manager.py +260 -0
- memos/mem_user/redis_persistent_user_manager.py +225 -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 +56 -0
- memos/memories/activation/kv.py +292 -0
- memos/memories/activation/vllmkv.py +219 -0
- memos/memories/base.py +19 -0
- memos/memories/factory.py +42 -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 +92 -0
- memos/memories/textual/general.py +236 -0
- memos/memories/textual/item.py +304 -0
- memos/memories/textual/naive.py +187 -0
- memos/memories/textual/prefer_text_memory/__init__.py +0 -0
- memos/memories/textual/prefer_text_memory/adder.py +504 -0
- memos/memories/textual/prefer_text_memory/config.py +106 -0
- memos/memories/textual/prefer_text_memory/extractor.py +221 -0
- memos/memories/textual/prefer_text_memory/factory.py +85 -0
- memos/memories/textual/prefer_text_memory/retrievers.py +177 -0
- memos/memories/textual/prefer_text_memory/spliter.py +132 -0
- memos/memories/textual/prefer_text_memory/utils.py +93 -0
- memos/memories/textual/preference.py +344 -0
- memos/memories/textual/simple_preference.py +161 -0
- memos/memories/textual/simple_tree.py +69 -0
- memos/memories/textual/tree.py +459 -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/handler.py +184 -0
- memos/memories/textual/tree_text_memory/organize/manager.py +518 -0
- memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +238 -0
- memos/memories/textual/tree_text_memory/organize/reorganizer.py +622 -0
- memos/memories/textual/tree_text_memory/retrieve/__init__.py +0 -0
- memos/memories/textual/tree_text_memory/retrieve/advanced_searcher.py +364 -0
- memos/memories/textual/tree_text_memory/retrieve/bm25_util.py +186 -0
- memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +419 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +270 -0
- memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +102 -0
- memos/memories/textual/tree_text_memory/retrieve/reasoner.py +61 -0
- memos/memories/textual/tree_text_memory/retrieve/recall.py +497 -0
- memos/memories/textual/tree_text_memory/retrieve/reranker.py +111 -0
- memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +16 -0
- memos/memories/textual/tree_text_memory/retrieve/retrieve_utils.py +472 -0
- memos/memories/textual/tree_text_memory/retrieve/searcher.py +848 -0
- memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +135 -0
- memos/memories/textual/tree_text_memory/retrieve/utils.py +54 -0
- memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +387 -0
- memos/memos_tools/dinding_report_bot.py +453 -0
- memos/memos_tools/lockfree_dict.py +120 -0
- memos/memos_tools/notification_service.py +44 -0
- memos/memos_tools/notification_utils.py +142 -0
- memos/memos_tools/singleton.py +174 -0
- memos/memos_tools/thread_safe_dict.py +310 -0
- memos/memos_tools/thread_safe_dict_segment.py +382 -0
- memos/multi_mem_cube/__init__.py +0 -0
- memos/multi_mem_cube/composite_cube.py +86 -0
- memos/multi_mem_cube/single_cube.py +874 -0
- memos/multi_mem_cube/views.py +54 -0
- memos/parsers/__init__.py +0 -0
- memos/parsers/base.py +15 -0
- memos/parsers/factory.py +21 -0
- memos/parsers/markitdown.py +28 -0
- memos/reranker/__init__.py +4 -0
- memos/reranker/base.py +25 -0
- memos/reranker/concat.py +103 -0
- memos/reranker/cosine_local.py +102 -0
- memos/reranker/factory.py +72 -0
- memos/reranker/http_bge.py +324 -0
- memos/reranker/http_bge_strategy.py +327 -0
- memos/reranker/noop.py +19 -0
- memos/reranker/strategies/__init__.py +4 -0
- memos/reranker/strategies/base.py +61 -0
- memos/reranker/strategies/concat_background.py +94 -0
- memos/reranker/strategies/concat_docsource.py +110 -0
- memos/reranker/strategies/dialogue_common.py +109 -0
- memos/reranker/strategies/factory.py +31 -0
- memos/reranker/strategies/single_turn.py +107 -0
- memos/reranker/strategies/singleturn_outmem.py +98 -0
- memos/settings.py +10 -0
- memos/templates/__init__.py +0 -0
- memos/templates/advanced_search_prompts.py +211 -0
- memos/templates/cloud_service_prompt.py +107 -0
- memos/templates/instruction_completion.py +66 -0
- memos/templates/mem_agent_prompts.py +85 -0
- memos/templates/mem_feedback_prompts.py +822 -0
- memos/templates/mem_reader_prompts.py +1096 -0
- memos/templates/mem_reader_strategy_prompts.py +238 -0
- memos/templates/mem_scheduler_prompts.py +626 -0
- memos/templates/mem_search_prompts.py +93 -0
- memos/templates/mos_prompts.py +403 -0
- memos/templates/prefer_complete_prompt.py +735 -0
- memos/templates/tool_mem_prompts.py +139 -0
- memos/templates/tree_reorganize_prompts.py +230 -0
- memos/types/__init__.py +34 -0
- memos/types/general_types.py +151 -0
- memos/types/openai_chat_completion_types/__init__.py +15 -0
- memos/types/openai_chat_completion_types/chat_completion_assistant_message_param.py +56 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_image_param.py +27 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_input_audio_param.py +23 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_param.py +43 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_refusal_param.py +16 -0
- memos/types/openai_chat_completion_types/chat_completion_content_part_text_param.py +16 -0
- memos/types/openai_chat_completion_types/chat_completion_message_custom_tool_call_param.py +27 -0
- memos/types/openai_chat_completion_types/chat_completion_message_function_tool_call_param.py +32 -0
- memos/types/openai_chat_completion_types/chat_completion_message_param.py +18 -0
- memos/types/openai_chat_completion_types/chat_completion_message_tool_call_union_param.py +15 -0
- memos/types/openai_chat_completion_types/chat_completion_system_message_param.py +36 -0
- memos/types/openai_chat_completion_types/chat_completion_tool_message_param.py +30 -0
- memos/types/openai_chat_completion_types/chat_completion_user_message_param.py +34 -0
- memos/utils.py +123 -0
- memos/vec_dbs/__init__.py +0 -0
- memos/vec_dbs/base.py +117 -0
- memos/vec_dbs/factory.py +23 -0
- memos/vec_dbs/item.py +50 -0
- memos/vec_dbs/milvus.py +654 -0
- memos/vec_dbs/qdrant.py +355 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
from typing import TypeVar
|
|
2
|
+
|
|
3
|
+
from sqlalchemy import Index
|
|
4
|
+
from sqlalchemy.engine import Engine
|
|
5
|
+
|
|
6
|
+
from memos.log import get_logger
|
|
7
|
+
from memos.mem_scheduler.schemas.monitor_schemas import (
|
|
8
|
+
MemoryMonitorItem,
|
|
9
|
+
MemoryMonitorManager,
|
|
10
|
+
QueryMonitorItem,
|
|
11
|
+
QueryMonitorQueue,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from .base_model import BaseDBManager, LockableORM
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
logger = get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
# Type variables for generic type hints
|
|
20
|
+
T = TypeVar("T") # The model type (MemoryMonitorManager, QueryMonitorManager, etc.)
|
|
21
|
+
ORM = TypeVar("ORM") # The ORM model type
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MemoryMonitorManagerORM(LockableORM):
|
|
25
|
+
"""ORM model for MemoryMonitorManager persistence
|
|
26
|
+
|
|
27
|
+
This table stores serialized MemoryMonitorManager instances with
|
|
28
|
+
proper indexing for efficient user and memory cube lookups.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
__tablename__ = "memory_monitor_manager"
|
|
32
|
+
|
|
33
|
+
# Database indexes for performance optimization
|
|
34
|
+
__table_args__ = (Index("idx_memory_monitor_user_memcube", "user_id", "mem_cube_id"),)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class QueryMonitorQueueORM(LockableORM):
|
|
38
|
+
"""ORM model for QueryMonitorQueue persistence
|
|
39
|
+
|
|
40
|
+
This table stores serialized QueryMonitorQueue instances with
|
|
41
|
+
proper indexing for efficient user and memory cube lookups.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
__tablename__ = "query_monitor_queue"
|
|
45
|
+
|
|
46
|
+
# Database indexes for performance optimization
|
|
47
|
+
__table_args__ = (Index("idx_query_monitor_user_memcube", "user_id", "mem_cube_id"),)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class DBManagerForMemoryMonitorManager(BaseDBManager):
|
|
51
|
+
"""Database manager for MemoryMonitorManager objects
|
|
52
|
+
|
|
53
|
+
This class handles persistence, synchronization, and locking
|
|
54
|
+
for MemoryMonitorManager instances in the database.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
engine: Engine,
|
|
60
|
+
user_id: str | None = None,
|
|
61
|
+
mem_cube_id: str | None = None,
|
|
62
|
+
obj: MemoryMonitorManager | None = None,
|
|
63
|
+
lock_timeout: int = 10,
|
|
64
|
+
):
|
|
65
|
+
"""
|
|
66
|
+
Initialize the MemoryMonitorManager database manager.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
engine: SQLAlchemy engine instance
|
|
70
|
+
user_id: Unique identifier for the user
|
|
71
|
+
mem_cube_id: Unique identifier for the memory cube
|
|
72
|
+
obj: Optional MemoryMonitorManager instance to manage
|
|
73
|
+
lock_timeout: Timeout in seconds for lock acquisition
|
|
74
|
+
"""
|
|
75
|
+
super().__init__(
|
|
76
|
+
engine=engine, user_id=user_id, mem_cube_id=mem_cube_id, lock_timeout=lock_timeout
|
|
77
|
+
)
|
|
78
|
+
self.obj: MemoryMonitorManager | None = obj
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def orm_class(self) -> type[MemoryMonitorManagerORM]:
|
|
82
|
+
return MemoryMonitorManagerORM
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def obj_class(self) -> type[MemoryMonitorManager]:
|
|
86
|
+
return MemoryMonitorManager
|
|
87
|
+
|
|
88
|
+
def merge_items(
|
|
89
|
+
self,
|
|
90
|
+
orm_instance: MemoryMonitorManagerORM,
|
|
91
|
+
obj_instance: MemoryMonitorManager,
|
|
92
|
+
size_limit: int,
|
|
93
|
+
):
|
|
94
|
+
"""Merge memory monitor items from database with current object
|
|
95
|
+
|
|
96
|
+
This method combines items from the database with items in the current
|
|
97
|
+
object, prioritizing current object items and applying size limits.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
orm_instance: ORM instance containing serialized database data
|
|
101
|
+
obj_instance: Current MemoryMonitorManager instance
|
|
102
|
+
size_limit: Maximum number of items to keep after merge
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Updated obj_instance with merged items
|
|
106
|
+
"""
|
|
107
|
+
logger.debug(f"Starting merge_items for MemoryMonitorManager with size_limit={size_limit}")
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
# Deserialize the database instance
|
|
111
|
+
db_instance: MemoryMonitorManager = MemoryMonitorManager.from_json(
|
|
112
|
+
orm_instance.serialized_data
|
|
113
|
+
)
|
|
114
|
+
except Exception as e:
|
|
115
|
+
logger.error(f"Failed to deserialize database instance: {e}", exc_info=True)
|
|
116
|
+
logger.warning("Skipping merge due to deserialization error, using current object only")
|
|
117
|
+
return obj_instance
|
|
118
|
+
|
|
119
|
+
# Merge items - prioritize existing ones in current object
|
|
120
|
+
merged_items: list[MemoryMonitorItem] = []
|
|
121
|
+
seen_ids = set()
|
|
122
|
+
|
|
123
|
+
# First, add all items from current object (higher priority)
|
|
124
|
+
for item in obj_instance.memories:
|
|
125
|
+
if item.item_id not in seen_ids:
|
|
126
|
+
merged_items.append(item)
|
|
127
|
+
seen_ids.add(item.item_id)
|
|
128
|
+
|
|
129
|
+
# Then, add items from database that aren't in current object
|
|
130
|
+
for item in db_instance.memories:
|
|
131
|
+
if item.item_id not in seen_ids:
|
|
132
|
+
merged_items.append(item)
|
|
133
|
+
seen_ids.add(item.item_id)
|
|
134
|
+
|
|
135
|
+
# Apply size limit if specified (keep most recent items)
|
|
136
|
+
if size_limit is not None and size_limit > 0:
|
|
137
|
+
try:
|
|
138
|
+
# Sort by sorting_score descending (highest priority first) and take top N
|
|
139
|
+
# Note: MemoryMonitorItem doesn't have timestamp, so we use sorting_score instead
|
|
140
|
+
merged_items = sorted(merged_items, key=lambda x: x.sorting_score, reverse=True)[
|
|
141
|
+
:size_limit
|
|
142
|
+
]
|
|
143
|
+
logger.debug(f"Applied size limit of {size_limit}, kept {len(merged_items)} items")
|
|
144
|
+
except AttributeError as e:
|
|
145
|
+
logger.error(f"Error sorting MemoryMonitorItem objects: {e}")
|
|
146
|
+
logger.error(
|
|
147
|
+
"Available attributes: "
|
|
148
|
+
+ ", ".join(dir(merged_items[0]) if merged_items else [])
|
|
149
|
+
)
|
|
150
|
+
raise
|
|
151
|
+
except Exception as e:
|
|
152
|
+
logger.error(f"Unexpected error during sorting: {e}")
|
|
153
|
+
raise
|
|
154
|
+
|
|
155
|
+
# Update the object with merged items
|
|
156
|
+
obj_instance.memories = merged_items
|
|
157
|
+
|
|
158
|
+
logger.info(
|
|
159
|
+
f"Merged {len(merged_items)} memory items for {obj_instance} (size_limit: {size_limit})"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return obj_instance
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class DBManagerForQueryMonitorQueue(BaseDBManager):
|
|
166
|
+
"""Database manager for QueryMonitorQueue objects
|
|
167
|
+
|
|
168
|
+
This class handles persistence, synchronization, and locking
|
|
169
|
+
for QueryMonitorQueue instances in the database.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def __init__(
|
|
173
|
+
self,
|
|
174
|
+
engine: Engine,
|
|
175
|
+
user_id: str | None = None,
|
|
176
|
+
mem_cube_id: str | None = None,
|
|
177
|
+
obj: QueryMonitorQueue | None = None,
|
|
178
|
+
lock_timeout: int = 10,
|
|
179
|
+
):
|
|
180
|
+
"""
|
|
181
|
+
Initialize the QueryMonitorQueue database manager.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
engine: SQLAlchemy engine instance
|
|
185
|
+
user_id: Unique identifier for the user
|
|
186
|
+
mem_cube_id: Unique identifier for the memory cube
|
|
187
|
+
obj: Optional QueryMonitorQueue instance to manage
|
|
188
|
+
lock_timeout: Timeout in seconds for lock acquisition
|
|
189
|
+
"""
|
|
190
|
+
super().__init__(
|
|
191
|
+
engine=engine, user_id=user_id, mem_cube_id=mem_cube_id, lock_timeout=lock_timeout
|
|
192
|
+
)
|
|
193
|
+
self.obj: QueryMonitorQueue | None = obj
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def orm_class(self) -> type[QueryMonitorQueueORM]:
|
|
197
|
+
return QueryMonitorQueueORM
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def obj_class(self) -> type[QueryMonitorQueue]:
|
|
201
|
+
return QueryMonitorQueue
|
|
202
|
+
|
|
203
|
+
def merge_items(
|
|
204
|
+
self, orm_instance: QueryMonitorQueueORM, obj_instance: QueryMonitorQueue, size_limit: int
|
|
205
|
+
):
|
|
206
|
+
"""Merge query monitor items from database with current queue
|
|
207
|
+
|
|
208
|
+
This method combines items from the database with items in the current
|
|
209
|
+
queue, prioritizing current queue items and applying size limits.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
orm_instance: ORM instance containing serialized database data
|
|
213
|
+
obj_instance: Current QueryMonitorQueue instance
|
|
214
|
+
size_limit: Maximum number of items to keep after merge
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Updated obj_instance with merged items
|
|
218
|
+
"""
|
|
219
|
+
try:
|
|
220
|
+
# Deserialize the database instance
|
|
221
|
+
db_instance: QueryMonitorQueue = QueryMonitorQueue.from_json(
|
|
222
|
+
orm_instance.serialized_data
|
|
223
|
+
)
|
|
224
|
+
except Exception as e:
|
|
225
|
+
logger.error(f"Failed to deserialize database instance: {e}")
|
|
226
|
+
logger.warning("Skipping merge due to deserialization error, using current object only")
|
|
227
|
+
return obj_instance
|
|
228
|
+
|
|
229
|
+
# Merge items - prioritize existing ones in current object
|
|
230
|
+
merged_items: list[QueryMonitorItem] = []
|
|
231
|
+
seen_ids = set()
|
|
232
|
+
|
|
233
|
+
# First, add all items from current queue (higher priority)
|
|
234
|
+
for item in obj_instance.get_queue_content_without_pop():
|
|
235
|
+
if item.item_id not in seen_ids:
|
|
236
|
+
merged_items.append(item)
|
|
237
|
+
seen_ids.add(item.item_id)
|
|
238
|
+
|
|
239
|
+
# Then, add items from database queue that aren't in current queue
|
|
240
|
+
for item in db_instance.get_queue_content_without_pop():
|
|
241
|
+
if item.item_id not in seen_ids:
|
|
242
|
+
merged_items.append(item)
|
|
243
|
+
seen_ids.add(item.item_id)
|
|
244
|
+
|
|
245
|
+
# Apply size limit if specified (keep most recent items)
|
|
246
|
+
if size_limit is not None and size_limit > 0:
|
|
247
|
+
# Sort by timestamp descending (newest first) and take top N
|
|
248
|
+
merged_items = sorted(merged_items, key=lambda x: x.timestamp, reverse=True)[
|
|
249
|
+
:size_limit
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
# Update the queue with merged items
|
|
253
|
+
obj_instance.clear() # Clear existing items
|
|
254
|
+
for item in merged_items:
|
|
255
|
+
obj_instance.put(item) # Add merged items back
|
|
256
|
+
|
|
257
|
+
logger.info(
|
|
258
|
+
f"Merged {len(merged_items)} query items for {obj_instance} (size_limit: {size_limit})"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return obj_instance
|