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,280 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from functools import wraps
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
7
|
+
|
|
8
|
+
from memos.log import get_logger
|
|
9
|
+
from memos.mem_scheduler.general_scheduler import GeneralScheduler
|
|
10
|
+
from memos.mem_scheduler.schemas.monitor_schemas import QueryMonitorItem
|
|
11
|
+
from memos.mem_scheduler.schemas.task_schemas import (
|
|
12
|
+
DEFAULT_MAX_QUERY_KEY_WORDS,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from memos.memories.textual.tree import TextualMemoryItem
|
|
18
|
+
from memos.types import UserID
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
logger = get_logger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SchedulerForEval(GeneralScheduler):
|
|
25
|
+
"""
|
|
26
|
+
A scheduler class that inherits from GeneralScheduler and provides evaluation-specific functionality.
|
|
27
|
+
This class extends GeneralScheduler with evaluation methods.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Class variable to store timing information for all instances
|
|
31
|
+
timer_cache: ClassVar[dict[str, dict[str, Any]]] = {}
|
|
32
|
+
|
|
33
|
+
def __init__(self, config):
|
|
34
|
+
"""
|
|
35
|
+
Initialize the SchedulerForEval with the same configuration as GeneralScheduler.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
config: Configuration object for the scheduler
|
|
39
|
+
"""
|
|
40
|
+
super().__init__(config)
|
|
41
|
+
# Initialize instance timer_cache
|
|
42
|
+
self.timer_cache = {}
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def time_it(func_name: str | None = None):
|
|
46
|
+
"""
|
|
47
|
+
Static method decorator to measure function execution time and store in timer_cache.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
func_name: Custom name for the function in timer_cache. If None, uses function.__name__
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def decorator(func):
|
|
54
|
+
@wraps(func)
|
|
55
|
+
def wrapper(self, *args, **kwargs):
|
|
56
|
+
# Get function name
|
|
57
|
+
name = func_name or func.__name__
|
|
58
|
+
|
|
59
|
+
# Start timing
|
|
60
|
+
start_time = time.time()
|
|
61
|
+
result = func(self, *args, **kwargs)
|
|
62
|
+
end_time = time.time()
|
|
63
|
+
|
|
64
|
+
# Calculate execution time
|
|
65
|
+
exec_time = end_time - start_time
|
|
66
|
+
|
|
67
|
+
# Format time as HH:MM:SS.mmm
|
|
68
|
+
hours = int(exec_time // 3600)
|
|
69
|
+
minutes = int((exec_time % 3600) // 60)
|
|
70
|
+
seconds = exec_time % 60
|
|
71
|
+
|
|
72
|
+
if hours > 0:
|
|
73
|
+
time_str = f"{hours:02d}:{minutes:02d}:{seconds:06.3f}"
|
|
74
|
+
else:
|
|
75
|
+
time_str = f"{minutes:02d}:{seconds:06.3f}"
|
|
76
|
+
|
|
77
|
+
# Store in timer_cache
|
|
78
|
+
if not hasattr(self, "timer_cache"):
|
|
79
|
+
self.timer_cache = {}
|
|
80
|
+
|
|
81
|
+
self.timer_cache[name] = {
|
|
82
|
+
"time_str": time_str,
|
|
83
|
+
"seconds": exec_time,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
logger.info(f"{name} executed in {time_str}")
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
return wrapper
|
|
90
|
+
|
|
91
|
+
return decorator
|
|
92
|
+
|
|
93
|
+
def get_timer_summary(self) -> str:
|
|
94
|
+
"""
|
|
95
|
+
Get a summary of all timed functions.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Formatted string with timing information
|
|
99
|
+
"""
|
|
100
|
+
if not self.timer_cache:
|
|
101
|
+
return "No timing data available."
|
|
102
|
+
|
|
103
|
+
summary = "=== Timing Summary ===\n"
|
|
104
|
+
for func_name, data in self.timer_cache.items():
|
|
105
|
+
summary += f"{func_name}: {data['time_str']} (at {data['timestamp']})\n"
|
|
106
|
+
|
|
107
|
+
return summary
|
|
108
|
+
|
|
109
|
+
def clear_timer_cache(self):
|
|
110
|
+
"""Clear the timer cache."""
|
|
111
|
+
self.timer_cache.clear()
|
|
112
|
+
|
|
113
|
+
@time_it("update_working_memory")
|
|
114
|
+
def update_working_memory_for_eval(
|
|
115
|
+
self, query: str, user_id: UserID | str, top_k: int
|
|
116
|
+
) -> list[str]:
|
|
117
|
+
"""
|
|
118
|
+
Update working memory based on query and return the updated memory list.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
query: The query string
|
|
122
|
+
user_id: User identifier
|
|
123
|
+
top_k: Number of top memories to return
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
List of memory strings from updated working memory
|
|
127
|
+
"""
|
|
128
|
+
self.monitor.register_query_monitor_if_not_exists(
|
|
129
|
+
user_id=user_id, mem_cube_id=self.current_mem_cube_id
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
query_keywords = self.monitor.extract_query_keywords(query=query)
|
|
133
|
+
logger.info(f'Extract keywords "{query_keywords}" from query "{query}"')
|
|
134
|
+
|
|
135
|
+
item = QueryMonitorItem(
|
|
136
|
+
user_id=user_id,
|
|
137
|
+
mem_cube_id=self.current_mem_cube_id,
|
|
138
|
+
query_text=query,
|
|
139
|
+
keywords=query_keywords,
|
|
140
|
+
max_keywords=DEFAULT_MAX_QUERY_KEY_WORDS,
|
|
141
|
+
)
|
|
142
|
+
query_db_manager = self.monitor.query_monitors[user_id][self.current_mem_cube_id]
|
|
143
|
+
query_db_manager.obj.put(item=item)
|
|
144
|
+
# Sync with database after adding new item
|
|
145
|
+
query_db_manager.sync_with_orm()
|
|
146
|
+
logger.debug(f"Queries in monitor are {query_db_manager.obj.get_queries_with_timesort()}.")
|
|
147
|
+
|
|
148
|
+
queries = [query]
|
|
149
|
+
|
|
150
|
+
# recall
|
|
151
|
+
mem_cube = self.current_mem_cube
|
|
152
|
+
text_mem_base = mem_cube.text_mem
|
|
153
|
+
|
|
154
|
+
cur_working_memory: list[TextualMemoryItem] = text_mem_base.get_working_memory()
|
|
155
|
+
text_working_memory: list[str] = [w_m.memory for w_m in cur_working_memory]
|
|
156
|
+
intent_result = self.monitor.detect_intent(
|
|
157
|
+
q_list=queries, text_working_memory=text_working_memory
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if intent_result["trigger_retrieval"]:
|
|
161
|
+
missing_evidences = intent_result["missing_evidences"]
|
|
162
|
+
num_evidence = len(missing_evidences)
|
|
163
|
+
k_per_evidence = max(1, top_k // max(1, num_evidence))
|
|
164
|
+
new_candidates = []
|
|
165
|
+
for item in missing_evidences:
|
|
166
|
+
logger.info(f"missing_evidences: {item}")
|
|
167
|
+
results: list[TextualMemoryItem] = self.retriever.search(
|
|
168
|
+
query=item,
|
|
169
|
+
mem_cube=mem_cube,
|
|
170
|
+
top_k=k_per_evidence,
|
|
171
|
+
method=self.search_method,
|
|
172
|
+
)
|
|
173
|
+
logger.info(
|
|
174
|
+
f"search results for {missing_evidences}: {[one.memory for one in results]}"
|
|
175
|
+
)
|
|
176
|
+
new_candidates.extend(results)
|
|
177
|
+
logger.info(
|
|
178
|
+
f"missing_evidences: {missing_evidences} and get {len(new_candidates)} new candidate memories."
|
|
179
|
+
)
|
|
180
|
+
else:
|
|
181
|
+
new_candidates = []
|
|
182
|
+
logger.info(f"intent_result: {intent_result}. not triggered")
|
|
183
|
+
|
|
184
|
+
# rerank
|
|
185
|
+
new_order_working_memory = self.replace_working_memory(
|
|
186
|
+
user_id=user_id,
|
|
187
|
+
mem_cube_id=self.current_mem_cube_id,
|
|
188
|
+
mem_cube=self.current_mem_cube,
|
|
189
|
+
original_memory=cur_working_memory,
|
|
190
|
+
new_memory=new_candidates,
|
|
191
|
+
)
|
|
192
|
+
new_order_working_memory = new_order_working_memory[:top_k]
|
|
193
|
+
logger.info(f"size of new_order_working_memory: {len(new_order_working_memory)}")
|
|
194
|
+
|
|
195
|
+
return [m.memory for m in new_order_working_memory]
|
|
196
|
+
|
|
197
|
+
@time_it("memory_answer_ability")
|
|
198
|
+
def evaluate_memory_answer_ability(
|
|
199
|
+
self, query: str, memory_texts: list[str], top_k: int = 100
|
|
200
|
+
) -> bool:
|
|
201
|
+
"""
|
|
202
|
+
Use LLM to evaluate whether the given memories can answer the query.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
query: The query string to evaluate
|
|
206
|
+
memory_texts: List of memory texts to check against
|
|
207
|
+
top_k: Maximum number of memories to consider for evaluation
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
Boolean indicating whether the memories can answer the query
|
|
211
|
+
"""
|
|
212
|
+
# Limit the number of memories to evaluate
|
|
213
|
+
limited_memories = memory_texts[:top_k] if memory_texts else []
|
|
214
|
+
|
|
215
|
+
# Build prompt using the template
|
|
216
|
+
prompt = self.monitor.build_prompt(
|
|
217
|
+
template_name="memory_answer_ability_evaluation",
|
|
218
|
+
query=query,
|
|
219
|
+
memory_list="\n".join([f"- {memory}" for memory in limited_memories])
|
|
220
|
+
if limited_memories
|
|
221
|
+
else "No memories available",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Use the process LLM to generate response
|
|
225
|
+
response = self.monitor._process_llm.generate([{"role": "user", "content": prompt}])
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
# Extract JSON response
|
|
229
|
+
from memos.mem_scheduler.utils.misc_utils import extract_json_obj
|
|
230
|
+
|
|
231
|
+
result = extract_json_obj(response)
|
|
232
|
+
|
|
233
|
+
# Validate response structure
|
|
234
|
+
if "result" in result:
|
|
235
|
+
logger.info(
|
|
236
|
+
f"Memory answer ability evaluation result: {result['result']}, reason: {result.get('reason', 'No reason provided')}"
|
|
237
|
+
)
|
|
238
|
+
return result["result"]
|
|
239
|
+
else:
|
|
240
|
+
logger.warning(f"Invalid response structure from LLM: {result}")
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
except Exception as e:
|
|
244
|
+
logger.error(
|
|
245
|
+
f"Failed to parse LLM response for memory answer ability evaluation: {response}. Error: {e}"
|
|
246
|
+
)
|
|
247
|
+
# Fallback: return False if we can't determine answer ability
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
@time_it("search_for_eval")
|
|
251
|
+
def search_for_eval(
|
|
252
|
+
self, query: str, user_id: UserID | str, top_k: int, scheduler_flag: bool = True
|
|
253
|
+
) -> list[str]:
|
|
254
|
+
"""
|
|
255
|
+
Original search_for_eval function refactored to use the new decomposed functions.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
query: The query string
|
|
259
|
+
user_id: User identifier
|
|
260
|
+
top_k: Number of top memories to return
|
|
261
|
+
scheduler_flag: Whether to update working memory or just evaluate
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Tuple of (memory_list, can_answer_boolean)
|
|
265
|
+
"""
|
|
266
|
+
if not scheduler_flag:
|
|
267
|
+
# Get current working memory without updating
|
|
268
|
+
mem_cube = self.current_mem_cube
|
|
269
|
+
text_mem_base = mem_cube.text_mem
|
|
270
|
+
cur_working_memory: list[TextualMemoryItem] = text_mem_base.get_working_memory()
|
|
271
|
+
text_working_memory: list[str] = [w_m.memory for w_m in cur_working_memory]
|
|
272
|
+
|
|
273
|
+
return text_working_memory
|
|
274
|
+
else:
|
|
275
|
+
# Update working memory and get the result
|
|
276
|
+
updated_memories = self.update_working_memory_for_eval(
|
|
277
|
+
query=query, user_id=user_id, top_k=top_k
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
return updated_memories
|