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,100 @@
|
|
|
1
|
+
"""Configuration classes for internet retrievers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, ClassVar
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, field_validator, model_validator
|
|
6
|
+
|
|
7
|
+
from memos.configs.base import BaseConfig
|
|
8
|
+
from memos.exceptions import ConfigurationError
|
|
9
|
+
from memos.mem_reader.factory import MemReaderConfigFactory
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseInternetRetrieverConfig(BaseConfig):
|
|
13
|
+
"""Base configuration class for internet retrievers."""
|
|
14
|
+
|
|
15
|
+
api_key: str = Field(..., description="API key for the search service")
|
|
16
|
+
search_engine_id: str | None = Field(
|
|
17
|
+
None, description="Search engine ID (required for Google Custom Search)"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GoogleCustomSearchConfig(BaseInternetRetrieverConfig):
|
|
22
|
+
"""Configuration class for Google Custom Search API."""
|
|
23
|
+
|
|
24
|
+
search_engine_id: str = Field(..., description="Google Custom Search Engine ID (cx parameter)")
|
|
25
|
+
max_results: int = Field(default=20, description="Maximum number of results to retrieve")
|
|
26
|
+
num_per_request: int = Field(
|
|
27
|
+
default=10, description="Number of results per API request (max 10 for Google)"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class BingSearchConfig(BaseInternetRetrieverConfig):
|
|
32
|
+
"""Configuration class for Bing Search API."""
|
|
33
|
+
|
|
34
|
+
endpoint: str = Field(
|
|
35
|
+
default="https://api.bing.microsoft.com/v7.0/search", description="Bing Search API endpoint"
|
|
36
|
+
)
|
|
37
|
+
max_results: int = Field(default=20, description="Maximum number of results to retrieve")
|
|
38
|
+
num_per_request: int = Field(default=10, description="Number of results per API request")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class XinyuSearchConfig(BaseInternetRetrieverConfig):
|
|
42
|
+
"""Configuration class for Xinyu Search API."""
|
|
43
|
+
|
|
44
|
+
search_engine_id: str | None = Field(
|
|
45
|
+
None, description="Not used for Xinyu Search (kept for compatibility)"
|
|
46
|
+
)
|
|
47
|
+
max_results: int = Field(default=20, description="Maximum number of results to retrieve")
|
|
48
|
+
num_per_request: int = Field(
|
|
49
|
+
default=10, description="Number of results per API request (not used for Xinyu)"
|
|
50
|
+
)
|
|
51
|
+
reader: MemReaderConfigFactory = Field(
|
|
52
|
+
...,
|
|
53
|
+
default_factory=MemReaderConfigFactory,
|
|
54
|
+
description="Reader configuration",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class BochaSearchConfig(BaseInternetRetrieverConfig):
|
|
59
|
+
"""Configuration class for Bocha Search API."""
|
|
60
|
+
|
|
61
|
+
max_results: int = Field(default=20, description="Maximum number of results to retrieve")
|
|
62
|
+
num_per_request: int = Field(default=10, description="Number of results per API request")
|
|
63
|
+
reader: MemReaderConfigFactory = Field(
|
|
64
|
+
...,
|
|
65
|
+
default_factory=MemReaderConfigFactory,
|
|
66
|
+
description="Reader configuration",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class InternetRetrieverConfigFactory(BaseConfig):
|
|
71
|
+
"""Factory class for creating internet retriever configurations."""
|
|
72
|
+
|
|
73
|
+
backend: str | None = Field(
|
|
74
|
+
None, description="Backend for internet retriever (google, bing, etc.)"
|
|
75
|
+
)
|
|
76
|
+
config: dict[str, Any] | None = Field(
|
|
77
|
+
None, description="Configuration for the internet retriever backend"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
81
|
+
"google": GoogleCustomSearchConfig,
|
|
82
|
+
"bing": BingSearchConfig,
|
|
83
|
+
"xinyu": XinyuSearchConfig,
|
|
84
|
+
"bocha": BochaSearchConfig,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@field_validator("backend")
|
|
88
|
+
@classmethod
|
|
89
|
+
def validate_backend(cls, backend: str | None) -> str | None:
|
|
90
|
+
"""Validate the backend field."""
|
|
91
|
+
if backend is not None and backend not in cls.backend_to_class:
|
|
92
|
+
raise ConfigurationError(f"Invalid internet retriever backend: {backend}")
|
|
93
|
+
return backend
|
|
94
|
+
|
|
95
|
+
@model_validator(mode="after")
|
|
96
|
+
def create_config(self) -> "InternetRetrieverConfigFactory":
|
|
97
|
+
if self.backend is not None:
|
|
98
|
+
config_class = self.backend_to_class[self.backend]
|
|
99
|
+
self.config = config_class(**self.config)
|
|
100
|
+
return self
|
memos/configs/llm.py
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
from typing import Any, ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, field_validator, model_validator
|
|
4
|
+
|
|
5
|
+
from memos.configs.base import BaseConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseLLMConfig(BaseConfig):
|
|
9
|
+
"""Base configuration class for LLMs."""
|
|
10
|
+
|
|
11
|
+
model_name_or_path: str = Field(..., description="Model name or path")
|
|
12
|
+
temperature: float = Field(default=0.7, description="Temperature for sampling")
|
|
13
|
+
max_tokens: int = Field(default=8192, description="Maximum number of tokens to generate")
|
|
14
|
+
top_p: float = Field(default=0.95, description="Top-p sampling parameter")
|
|
15
|
+
top_k: int = Field(default=50, description="Top-k sampling parameter")
|
|
16
|
+
remove_think_prefix: bool = Field(
|
|
17
|
+
default=False,
|
|
18
|
+
description="Remove content within think tags from the generated text",
|
|
19
|
+
)
|
|
20
|
+
default_headers: dict[str, Any] | None = Field(
|
|
21
|
+
default=None, description="Default headers for LLM requests"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class OpenAILLMConfig(BaseLLMConfig):
|
|
26
|
+
api_key: str = Field(..., description="API key for OpenAI")
|
|
27
|
+
api_base: str = Field(
|
|
28
|
+
default="https://api.openai.com/v1", description="Base URL for OpenAI API"
|
|
29
|
+
)
|
|
30
|
+
extra_body: Any = Field(default=None, description="extra body")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class OpenAIResponsesLLMConfig(BaseLLMConfig):
|
|
34
|
+
api_key: str = Field(..., description="API key for OpenAI")
|
|
35
|
+
api_base: str = Field(
|
|
36
|
+
default="https://api.openai.com/v1", description="Base URL for OpenAI responses API"
|
|
37
|
+
)
|
|
38
|
+
extra_body: Any = Field(default=None, description="extra body")
|
|
39
|
+
enable_thinking: bool = Field(
|
|
40
|
+
default=False,
|
|
41
|
+
description="Enable reasoning outputs from vLLM",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class QwenLLMConfig(BaseLLMConfig):
|
|
46
|
+
api_key: str = Field(..., description="API key for DashScope (Qwen)")
|
|
47
|
+
api_base: str = Field(
|
|
48
|
+
default="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
|
49
|
+
description="Base URL for Qwen OpenAI-compatible API",
|
|
50
|
+
)
|
|
51
|
+
extra_body: Any = Field(default=None, description="extra body")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class DeepSeekLLMConfig(BaseLLMConfig):
|
|
55
|
+
api_key: str = Field(..., description="API key for DeepSeek")
|
|
56
|
+
api_base: str = Field(
|
|
57
|
+
default="https://api.deepseek.com",
|
|
58
|
+
description="Base URL for DeepSeek OpenAI-compatible API",
|
|
59
|
+
)
|
|
60
|
+
extra_body: Any = Field(default=None, description="Extra options for API")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AzureLLMConfig(BaseLLMConfig):
|
|
64
|
+
base_url: str = Field(
|
|
65
|
+
default="https://api.openai.azure.com/",
|
|
66
|
+
description="Base URL for Azure OpenAI API",
|
|
67
|
+
)
|
|
68
|
+
api_version: str = Field(
|
|
69
|
+
default="2024-03-01-preview",
|
|
70
|
+
description="API version for Azure OpenAI",
|
|
71
|
+
)
|
|
72
|
+
api_key: str = Field(..., description="API key for Azure OpenAI")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class AzureResponsesLLMConfig(BaseLLMConfig):
|
|
76
|
+
base_url: str = Field(
|
|
77
|
+
default="https://api.openai.azure.com/",
|
|
78
|
+
description="Base URL for Azure OpenAI API",
|
|
79
|
+
)
|
|
80
|
+
api_version: str = Field(
|
|
81
|
+
default="2024-03-01-preview",
|
|
82
|
+
description="API version for Azure OpenAI",
|
|
83
|
+
)
|
|
84
|
+
api_key: str = Field(..., description="API key for Azure OpenAI")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class OllamaLLMConfig(BaseLLMConfig):
|
|
88
|
+
api_base: str = Field(
|
|
89
|
+
default="http://localhost:11434",
|
|
90
|
+
description="Base URL for Ollama API",
|
|
91
|
+
)
|
|
92
|
+
enable_thinking: bool = Field(
|
|
93
|
+
default=False,
|
|
94
|
+
description="Enable reasoning outputs from Ollama",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class HFLLMConfig(BaseLLMConfig):
|
|
99
|
+
do_sample: bool = Field(
|
|
100
|
+
default=False,
|
|
101
|
+
description="Whether to use sampling (if False, always greedy/argmax decoding)",
|
|
102
|
+
)
|
|
103
|
+
add_generation_prompt: bool = Field(
|
|
104
|
+
default=True,
|
|
105
|
+
description="Apply generation template for the conversation",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class VLLMLLMConfig(BaseLLMConfig):
|
|
110
|
+
api_key: str = Field(default="", description="API key for vLLM (optional for local server)")
|
|
111
|
+
api_base: str = Field(
|
|
112
|
+
default="http://localhost:8088/v1",
|
|
113
|
+
description="Base URL for vLLM API",
|
|
114
|
+
)
|
|
115
|
+
enable_thinking: bool = Field(
|
|
116
|
+
default=False,
|
|
117
|
+
description="Enable reasoning outputs from vLLM",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class LLMConfigFactory(BaseConfig):
|
|
122
|
+
"""Factory class for creating LLM configurations."""
|
|
123
|
+
|
|
124
|
+
backend: str = Field(..., description="Backend for LLM")
|
|
125
|
+
config: dict[str, Any] = Field(..., description="Configuration for the LLM backend")
|
|
126
|
+
|
|
127
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
128
|
+
"openai": OpenAILLMConfig,
|
|
129
|
+
"ollama": OllamaLLMConfig,
|
|
130
|
+
"azure": AzureLLMConfig,
|
|
131
|
+
"huggingface": HFLLMConfig,
|
|
132
|
+
"vllm": VLLMLLMConfig,
|
|
133
|
+
"huggingface_singleton": HFLLMConfig, # Add singleton support
|
|
134
|
+
"qwen": QwenLLMConfig,
|
|
135
|
+
"deepseek": DeepSeekLLMConfig,
|
|
136
|
+
"openai_new": OpenAIResponsesLLMConfig,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@field_validator("backend")
|
|
140
|
+
@classmethod
|
|
141
|
+
def validate_backend(cls, backend: str) -> str:
|
|
142
|
+
"""Validate the backend field."""
|
|
143
|
+
if backend not in cls.backend_to_class:
|
|
144
|
+
raise ValueError(f"Invalid backend: {backend}")
|
|
145
|
+
return backend
|
|
146
|
+
|
|
147
|
+
@model_validator(mode="after")
|
|
148
|
+
def create_config(self) -> "LLMConfigFactory":
|
|
149
|
+
config_class = self.backend_to_class[self.backend]
|
|
150
|
+
self.config = config_class(**self.config)
|
|
151
|
+
return self
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from typing import Any, ClassVar
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, field_validator, model_validator
|
|
4
|
+
|
|
5
|
+
from memos.configs.base import BaseConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseAgentConfig(BaseConfig):
|
|
9
|
+
"""Base configuration class for agents."""
|
|
10
|
+
|
|
11
|
+
agent_name: str = Field(..., description="Name of the agent")
|
|
12
|
+
description: str | None = Field(default=None, description="Description of the agent")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SimpleAgentConfig(BaseAgentConfig):
|
|
16
|
+
"""Simple agent configuration class."""
|
|
17
|
+
|
|
18
|
+
max_iterations: int = Field(
|
|
19
|
+
default=10, description="Maximum number of iterations for the agent"
|
|
20
|
+
)
|
|
21
|
+
timeout: int = Field(default=30, description="Timeout in seconds for agent execution")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DeepSearchAgentConfig(BaseAgentConfig):
|
|
25
|
+
"""Deep search agent configuration class."""
|
|
26
|
+
|
|
27
|
+
max_iterations: int = Field(default=3, description="Maximum number of iterations for the agent")
|
|
28
|
+
timeout: int = Field(default=30, description="Timeout in seconds for agent execution")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MemAgentConfigFactory(BaseConfig):
|
|
32
|
+
"""Factory class for creating agent configurations."""
|
|
33
|
+
|
|
34
|
+
backend: str = Field(..., description="Backend for agent")
|
|
35
|
+
config: dict[str, Any] = Field(..., description="Configuration for the agent backend")
|
|
36
|
+
|
|
37
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
38
|
+
"simple": SimpleAgentConfig,
|
|
39
|
+
"deep_search": DeepSearchAgentConfig,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@field_validator("backend")
|
|
43
|
+
@classmethod
|
|
44
|
+
def validate_backend(cls, backend: str) -> str:
|
|
45
|
+
"""Validate the backend field."""
|
|
46
|
+
if backend not in cls.backend_to_class:
|
|
47
|
+
raise ValueError(f"Invalid backend: {backend}")
|
|
48
|
+
return backend
|
|
49
|
+
|
|
50
|
+
@model_validator(mode="after")
|
|
51
|
+
def create_config(self) -> "MemAgentConfigFactory":
|
|
52
|
+
config_class = self.backend_to_class[self.backend]
|
|
53
|
+
self.config = config_class(**self.config)
|
|
54
|
+
return self
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Any, ClassVar
|
|
5
|
+
|
|
6
|
+
from pydantic import Field, field_validator, model_validator
|
|
7
|
+
|
|
8
|
+
from memos.configs.base import BaseConfig
|
|
9
|
+
from memos.configs.llm import LLMConfigFactory
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseMemChatConfig(BaseConfig):
|
|
13
|
+
"""Base configuration class for MemChat."""
|
|
14
|
+
|
|
15
|
+
user_id: str = Field(..., description="User ID for the MemChat")
|
|
16
|
+
session_id: str = Field(
|
|
17
|
+
default_factory=lambda: str(uuid.uuid4()), description="Session ID for the MemChat"
|
|
18
|
+
)
|
|
19
|
+
created_at: datetime = Field(
|
|
20
|
+
default_factory=datetime.now,
|
|
21
|
+
description="Creation timestamp for the MemChat",
|
|
22
|
+
)
|
|
23
|
+
config_filename: str = Field(
|
|
24
|
+
default="config.json",
|
|
25
|
+
description="Filename for storing the MemChat configuration",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SimpleMemChatConfig(BaseMemChatConfig):
|
|
30
|
+
"""Simple MemChat configuration class."""
|
|
31
|
+
|
|
32
|
+
chat_llm: LLMConfigFactory = Field(
|
|
33
|
+
...,
|
|
34
|
+
default_factory=LLMConfigFactory,
|
|
35
|
+
description="LLM configuration for the MemChat",
|
|
36
|
+
)
|
|
37
|
+
max_turns_window: int = Field(
|
|
38
|
+
default=15,
|
|
39
|
+
description="Maximum number of turns to keep in the conversation history",
|
|
40
|
+
)
|
|
41
|
+
top_k: int = Field(
|
|
42
|
+
default=5,
|
|
43
|
+
description="Maximum number of memories to retrieve for each query",
|
|
44
|
+
)
|
|
45
|
+
enable_textual_memory: bool = Field(
|
|
46
|
+
default=False,
|
|
47
|
+
description="Enable textual memory for the MemChat",
|
|
48
|
+
)
|
|
49
|
+
enable_activation_memory: bool = Field(
|
|
50
|
+
default=False,
|
|
51
|
+
description="Enable activation memory for the MemChat",
|
|
52
|
+
)
|
|
53
|
+
enable_parametric_memory: bool = Field(
|
|
54
|
+
default=False,
|
|
55
|
+
description="Enable parametric memory for the MemChat",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class MemChatConfigFactory(BaseConfig):
|
|
60
|
+
"""Factory class for creating MemChat configurations."""
|
|
61
|
+
|
|
62
|
+
backend: str = Field(..., description="Backend for MemChat")
|
|
63
|
+
config: dict[str, Any] = Field(..., description="Configuration for the MemChat backend")
|
|
64
|
+
|
|
65
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
66
|
+
"simple": SimpleMemChatConfig,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@field_validator("backend")
|
|
70
|
+
@classmethod
|
|
71
|
+
def validate_backend(cls, backend: str) -> str:
|
|
72
|
+
"""Validate the backend field."""
|
|
73
|
+
if backend not in cls.backend_to_class:
|
|
74
|
+
raise ValueError(f"Invalid backend: {backend}")
|
|
75
|
+
return backend
|
|
76
|
+
|
|
77
|
+
@model_validator(mode="after")
|
|
78
|
+
def create_config(self) -> "MemChatConfigFactory":
|
|
79
|
+
config_class = self.backend_to_class[self.backend]
|
|
80
|
+
self.config = config_class(**self.config)
|
|
81
|
+
return self
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from pydantic import Field, field_validator
|
|
4
|
+
|
|
5
|
+
from memos.configs.base import BaseConfig
|
|
6
|
+
from memos.configs.memory import (
|
|
7
|
+
MemoryConfigFactory,
|
|
8
|
+
)
|
|
9
|
+
from memos.exceptions import ConfigurationError
|
|
10
|
+
from memos.log import get_logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
logger = get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseMemCubeConfig(BaseConfig):
|
|
17
|
+
"""Base configuration class for MemCube."""
|
|
18
|
+
|
|
19
|
+
model_schema: str = Field(
|
|
20
|
+
"NOT_SET",
|
|
21
|
+
description="Schema for configuration. This value will be automatically set.",
|
|
22
|
+
exclude=False,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
config_filename: str = Field(
|
|
26
|
+
"config.json",
|
|
27
|
+
description="Filename for storing MemCube configuration",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class GeneralMemCubeConfig(BaseMemCubeConfig):
|
|
32
|
+
"""General MemCube memory configuration class."""
|
|
33
|
+
|
|
34
|
+
user_id: str = Field(
|
|
35
|
+
"default_user",
|
|
36
|
+
description="User ID for the MemCube. This is used to distinguish between different users' memories.",
|
|
37
|
+
)
|
|
38
|
+
cube_id: str = Field(
|
|
39
|
+
str(uuid.uuid4()),
|
|
40
|
+
description="Cube ID for the MemCube. This is used to distinguish between different MemCubes.",
|
|
41
|
+
)
|
|
42
|
+
text_mem: MemoryConfigFactory = Field(
|
|
43
|
+
...,
|
|
44
|
+
default_factory=MemoryConfigFactory,
|
|
45
|
+
description="Configuration for the textual memory",
|
|
46
|
+
)
|
|
47
|
+
act_mem: MemoryConfigFactory = Field(
|
|
48
|
+
...,
|
|
49
|
+
default_factory=MemoryConfigFactory,
|
|
50
|
+
description="Configuration for the activation memory",
|
|
51
|
+
)
|
|
52
|
+
para_mem: MemoryConfigFactory = Field(
|
|
53
|
+
...,
|
|
54
|
+
default_factory=MemoryConfigFactory,
|
|
55
|
+
description="Configuration for the parametric memory",
|
|
56
|
+
)
|
|
57
|
+
pref_mem: MemoryConfigFactory = Field(
|
|
58
|
+
...,
|
|
59
|
+
default_factory=MemoryConfigFactory,
|
|
60
|
+
description="Configuration for the preference memory",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@field_validator("text_mem")
|
|
64
|
+
@classmethod
|
|
65
|
+
def validate_text_mem(cls, text_mem: MemoryConfigFactory) -> MemoryConfigFactory:
|
|
66
|
+
"""Validate the text_mem field."""
|
|
67
|
+
allowed_backends = ["naive_text", "general_text", "tree_text", "uninitialized"]
|
|
68
|
+
if text_mem.backend not in allowed_backends:
|
|
69
|
+
raise ConfigurationError(
|
|
70
|
+
f"GeneralMemCubeConfig requires text_mem backend to be one of {allowed_backends}, got '{text_mem.backend}'"
|
|
71
|
+
)
|
|
72
|
+
return text_mem
|
|
73
|
+
|
|
74
|
+
@field_validator("act_mem")
|
|
75
|
+
@classmethod
|
|
76
|
+
def validate_act_mem(cls, act_mem: MemoryConfigFactory) -> MemoryConfigFactory:
|
|
77
|
+
"""Validate the act_mem field."""
|
|
78
|
+
allowed_backends = ["kv_cache", "vllm_kv_cache", "uninitialized"]
|
|
79
|
+
if act_mem.backend not in allowed_backends:
|
|
80
|
+
raise ConfigurationError(
|
|
81
|
+
f"GeneralMemCubeConfig requires act_mem backend to be one of {allowed_backends}, got '{act_mem.backend}'"
|
|
82
|
+
)
|
|
83
|
+
return act_mem
|
|
84
|
+
|
|
85
|
+
@field_validator("para_mem")
|
|
86
|
+
@classmethod
|
|
87
|
+
def validate_para_mem(cls, para_mem: MemoryConfigFactory) -> MemoryConfigFactory:
|
|
88
|
+
"""Validate the para_mem field."""
|
|
89
|
+
allowed_backends = ["lora", "uninitialized"]
|
|
90
|
+
if para_mem.backend not in allowed_backends:
|
|
91
|
+
raise ConfigurationError(
|
|
92
|
+
f"GeneralMemCubeConfig requires para_mem backend to be one of {allowed_backends}, got '{para_mem.backend}'"
|
|
93
|
+
)
|
|
94
|
+
return para_mem
|
|
95
|
+
|
|
96
|
+
@field_validator("pref_mem")
|
|
97
|
+
@classmethod
|
|
98
|
+
def validate_pref_mem(cls, pref_mem: MemoryConfigFactory) -> MemoryConfigFactory:
|
|
99
|
+
"""Validate the pref_mem field."""
|
|
100
|
+
allowed_backends = ["pref_text", "uninitialized"]
|
|
101
|
+
if pref_mem.backend not in allowed_backends:
|
|
102
|
+
raise ConfigurationError(
|
|
103
|
+
f"GeneralMemCubeConfig requires pref_mem backend to be one of {allowed_backends}, got '{pref_mem.backend}'"
|
|
104
|
+
)
|
|
105
|
+
return pref_mem
|
memos/configs/mem_os.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, model_validator
|
|
6
|
+
|
|
7
|
+
from memos.configs.base import BaseConfig
|
|
8
|
+
from memos.configs.llm import LLMConfigFactory
|
|
9
|
+
from memos.configs.mem_reader import MemReaderConfigFactory
|
|
10
|
+
from memos.configs.mem_scheduler import SchedulerConfigFactory
|
|
11
|
+
from memos.configs.mem_user import UserManagerConfigFactory
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MOSConfig(BaseConfig):
|
|
15
|
+
user_id: str = Field(
|
|
16
|
+
default="root",
|
|
17
|
+
description="User ID for the MOS. This is used to distinguish between different users' memories.",
|
|
18
|
+
)
|
|
19
|
+
session_id: str = Field(
|
|
20
|
+
default=str(uuid.uuid4()),
|
|
21
|
+
description="Session ID for the MOS. This is used to distinguish between different dialogue",
|
|
22
|
+
)
|
|
23
|
+
chat_model: LLMConfigFactory = Field(
|
|
24
|
+
...,
|
|
25
|
+
default_factory=LLMConfigFactory,
|
|
26
|
+
description="LLM configuration for the chat model in the MOS",
|
|
27
|
+
)
|
|
28
|
+
mem_reader: MemReaderConfigFactory = Field(
|
|
29
|
+
...,
|
|
30
|
+
default_factory=MemReaderConfigFactory,
|
|
31
|
+
description="MemReader configuration for the MOS",
|
|
32
|
+
)
|
|
33
|
+
mem_scheduler: SchedulerConfigFactory | None = Field(
|
|
34
|
+
default=None,
|
|
35
|
+
description="Memory scheduler configuration for managing memory operations",
|
|
36
|
+
)
|
|
37
|
+
user_manager: UserManagerConfigFactory = Field(
|
|
38
|
+
default_factory=lambda: UserManagerConfigFactory(backend="sqlite", config={}),
|
|
39
|
+
description="User manager configuration for database operations",
|
|
40
|
+
)
|
|
41
|
+
max_turns_window: int = Field(
|
|
42
|
+
default=15,
|
|
43
|
+
description="Maximum number of turns to keep in the conversation history",
|
|
44
|
+
)
|
|
45
|
+
top_k: int = Field(
|
|
46
|
+
default=5,
|
|
47
|
+
description="Maximum number of memories to retrieve for each query",
|
|
48
|
+
)
|
|
49
|
+
enable_textual_memory: bool = Field(
|
|
50
|
+
default=True,
|
|
51
|
+
description="Enable textual memory for the MemChat",
|
|
52
|
+
)
|
|
53
|
+
enable_activation_memory: bool = Field(
|
|
54
|
+
default=False,
|
|
55
|
+
description="Enable activation memory for the MemChat",
|
|
56
|
+
)
|
|
57
|
+
enable_parametric_memory: bool = Field(
|
|
58
|
+
default=False,
|
|
59
|
+
description="Enable parametric memory for the MemChat",
|
|
60
|
+
)
|
|
61
|
+
enable_preference_memory: bool = Field(
|
|
62
|
+
default=False,
|
|
63
|
+
description="Enable preference memory for the MemChat",
|
|
64
|
+
)
|
|
65
|
+
enable_mem_scheduler: bool = Field(
|
|
66
|
+
default=False,
|
|
67
|
+
description="Enable memory scheduler for automated memory management",
|
|
68
|
+
)
|
|
69
|
+
PRO_MODE: bool = Field(
|
|
70
|
+
default=False,
|
|
71
|
+
description="Enable PRO mode for complex query decomposition",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class MemOSConfigFactory(BaseConfig):
|
|
76
|
+
"""Factory class for creating Memos configurations."""
|
|
77
|
+
|
|
78
|
+
config: dict[str, Any] = Field(..., description="Configuration for the MemOS backend")
|
|
79
|
+
|
|
80
|
+
@model_validator(mode="after")
|
|
81
|
+
def create_config(self) -> "MemOSConfigFactory":
|
|
82
|
+
self.config = MOSConfig(**self.config)
|
|
83
|
+
return self
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Any, ClassVar
|
|
3
|
+
|
|
4
|
+
from pydantic import ConfigDict, Field, field_validator, model_validator
|
|
5
|
+
|
|
6
|
+
from memos.configs.base import BaseConfig
|
|
7
|
+
from memos.configs.chunker import ChunkerConfigFactory
|
|
8
|
+
from memos.configs.embedder import EmbedderConfigFactory
|
|
9
|
+
from memos.configs.llm import LLMConfigFactory
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseMemReaderConfig(BaseConfig):
|
|
13
|
+
"""Base configuration class for MemReader."""
|
|
14
|
+
|
|
15
|
+
created_at: datetime = Field(
|
|
16
|
+
default_factory=datetime.now, description="Creation timestamp for the MemReader"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
@field_validator("created_at", mode="before")
|
|
20
|
+
@classmethod
|
|
21
|
+
def parse_datetime(cls, value):
|
|
22
|
+
"""Parse datetime from string if needed."""
|
|
23
|
+
if isinstance(value, str):
|
|
24
|
+
return datetime.fromisoformat(value.replace("Z", "+00:00"))
|
|
25
|
+
return value
|
|
26
|
+
|
|
27
|
+
llm: LLMConfigFactory = Field(..., description="LLM configuration for the MemReader")
|
|
28
|
+
embedder: EmbedderConfigFactory = Field(
|
|
29
|
+
..., description="Embedder configuration for the MemReader"
|
|
30
|
+
)
|
|
31
|
+
chunker: ChunkerConfigFactory = Field(
|
|
32
|
+
..., description="Chunker configuration for the MemReader"
|
|
33
|
+
)
|
|
34
|
+
remove_prompt_example: bool = Field(
|
|
35
|
+
default=False,
|
|
36
|
+
description="whether remove example in memory extraction prompt to save token",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
chat_chunker: dict[str, Any] = Field(
|
|
40
|
+
default=None, description="Configuration for the MemReader chat chunk strategy"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SimpleStructMemReaderConfig(BaseMemReaderConfig):
|
|
45
|
+
"""SimpleStruct MemReader configuration class."""
|
|
46
|
+
|
|
47
|
+
# Allow passing additional fields without raising validation errors
|
|
48
|
+
model_config = ConfigDict(extra="allow", strict=True)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class MultiModalStructMemReaderConfig(BaseMemReaderConfig):
|
|
52
|
+
"""MultiModalStruct MemReader configuration class."""
|
|
53
|
+
|
|
54
|
+
direct_markdown_hostnames: list[str] | None = Field(
|
|
55
|
+
default=None,
|
|
56
|
+
description="List of hostnames that should return markdown directly without parsing. "
|
|
57
|
+
"If None, reads from FILE_PARSER_DIRECT_MARKDOWN_HOSTNAMES environment variable.",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class StrategyStructMemReaderConfig(BaseMemReaderConfig):
|
|
62
|
+
"""StrategyStruct MemReader configuration class."""
|
|
63
|
+
|
|
64
|
+
model_config = ConfigDict(extra="allow", strict=True)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class MemReaderConfigFactory(BaseConfig):
|
|
68
|
+
"""Factory class for creating MemReader configurations."""
|
|
69
|
+
|
|
70
|
+
backend: str = Field(..., description="Backend for MemReader")
|
|
71
|
+
config: dict[str, Any] = Field(..., description="Configuration for the MemReader backend")
|
|
72
|
+
|
|
73
|
+
backend_to_class: ClassVar[dict[str, Any]] = {
|
|
74
|
+
"simple_struct": SimpleStructMemReaderConfig,
|
|
75
|
+
"multimodal_struct": MultiModalStructMemReaderConfig,
|
|
76
|
+
"strategy_struct": StrategyStructMemReaderConfig,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@field_validator("backend")
|
|
80
|
+
@classmethod
|
|
81
|
+
def validate_backend(cls, backend: str) -> str:
|
|
82
|
+
"""Validate the backend field."""
|
|
83
|
+
if backend not in cls.backend_to_class:
|
|
84
|
+
raise ValueError(f"Invalid backend: {backend}")
|
|
85
|
+
return backend
|
|
86
|
+
|
|
87
|
+
@model_validator(mode="after")
|
|
88
|
+
def create_config(self) -> "MemReaderConfigFactory":
|
|
89
|
+
config_class = self.backend_to_class[self.backend]
|
|
90
|
+
self.config = config_class(**self.config)
|
|
91
|
+
return self
|