MemoryOS 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of MemoryOS might be problematic. Click here for more details.
- {memoryos-0.2.1 → memoryos-0.2.2}/PKG-INFO +2 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/pyproject.toml +2 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/__init__.py +1 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/config.py +156 -65
- memoryos-0.2.2/src/memos/api/context/context.py +147 -0
- memoryos-0.2.2/src/memos/api/context/dependencies.py +90 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/product_models.py +5 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/routers/product_router.py +54 -26
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/graph_db.py +49 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/internet_retriever.py +6 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/mem_os.py +5 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/mem_reader.py +9 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/mem_scheduler.py +18 -4
- memoryos-0.2.2/src/memos/configs/mem_user.py +58 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/base.py +9 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/factory.py +2 -0
- memoryos-0.2.2/src/memos/graph_dbs/nebular.py +1364 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/neo4j.py +4 -4
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/log.py +1 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_cube/utils.py +13 -6
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/core.py +140 -30
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/main.py +1 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/product.py +266 -152
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/utils/format_utils.py +314 -67
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_reader/simple_struct.py +13 -5
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/base_scheduler.py +220 -250
- memoryos-0.2.2/src/memos/mem_scheduler/general_scheduler.py +306 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/base.py +5 -5
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/dispatcher.py +6 -9
- memoryos-0.2.2/src/memos/mem_scheduler/modules/misc.py +104 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/monitor.py +52 -41
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/rabbitmq_service.py +9 -7
- memoryos-0.2.2/src/memos/mem_scheduler/modules/retriever.py +185 -0
- memoryos-0.2.2/src/memos/mem_scheduler/modules/scheduler_logger.py +255 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/mos_for_test_scheduler.py +16 -19
- memoryos-0.2.2/src/memos/mem_scheduler/schemas/general_schemas.py +43 -0
- memoryos-0.2.2/src/memos/mem_scheduler/schemas/message_schemas.py +148 -0
- memoryos-0.2.2/src/memos/mem_scheduler/schemas/monitor_schemas.py +329 -0
- memoryos-0.2.2/src/memos/mem_scheduler/utils/filter_utils.py +176 -0
- memoryos-0.2.2/src/memos/mem_scheduler/utils/misc_utils.py +61 -0
- memoryos-0.2.2/src/memos/mem_user/factory.py +94 -0
- memoryos-0.2.2/src/memos/mem_user/mysql_persistent_user_manager.py +271 -0
- memoryos-0.2.2/src/memos/mem_user/mysql_user_manager.py +500 -0
- memoryos-0.2.2/src/memos/mem_user/persistent_factory.py +96 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_user/user_manager.py +4 -4
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/activation/item.py +4 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/base.py +1 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/general.py +35 -91
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/item.py +5 -33
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree.py +13 -7
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/organize/conflict.py +4 -2
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +47 -43
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/organize/reorganizer.py +8 -5
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +6 -3
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +2 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +2 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/searcher.py +46 -23
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +42 -15
- memoryos-0.2.2/src/memos/memories/textual/tree_text_memory/retrieve/utils.py +52 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +62 -58
- memoryos-0.2.2/src/memos/memos_tools/dinding_report_bot.py +422 -0
- memoryos-0.2.2/src/memos/memos_tools/notification_service.py +44 -0
- memoryos-0.2.2/src/memos/memos_tools/notification_utils.py +96 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/settings.py +3 -1
- memoryos-0.2.2/src/memos/templates/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/templates/mem_reader_prompts.py +2 -1
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/templates/mem_scheduler_prompts.py +41 -7
- memoryos-0.2.2/src/memos/templates/mos_prompts.py +150 -0
- memoryos-0.2.2/src/memos/vec_dbs/__init__.py +0 -0
- memoryos-0.2.1/src/memos/mem_scheduler/general_scheduler.py +0 -186
- memoryos-0.2.1/src/memos/mem_scheduler/modules/misc.py +0 -39
- memoryos-0.2.1/src/memos/mem_scheduler/modules/retriever.py +0 -268
- memoryos-0.2.1/src/memos/mem_scheduler/modules/schemas.py +0 -328
- memoryos-0.2.1/src/memos/mem_scheduler/utils.py +0 -75
- memoryos-0.2.1/src/memos/memories/textual/tree_text_memory/retrieve/utils.py +0 -48
- memoryos-0.2.1/src/memos/templates/mos_prompts.py +0 -63
- {memoryos-0.2.1 → memoryos-0.2.2}/LICENSE +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/README.md +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/exceptions.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/mcp_serve.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/product_api.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/routers/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/api/start_api.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/chunkers/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/chunkers/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/chunkers/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/chunkers/sentence_chunker.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/cli.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/chunker.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/embedder.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/llm.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/mem_chat.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/mem_cube.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/memory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/parser.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/utils.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/configs/vec_db.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/dependency.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/deprecation.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/ark.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/ollama.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/sentence_transformer.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/embedders/universal_api.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/exceptions.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/item.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/graph_dbs/neo4j_community.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/hello_world.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/deepseek.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/hf.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/hf_singleton.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/ollama.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/openai.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/qwen.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/utils.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/llms/vllm.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_chat/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_chat/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_chat/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_chat/simple.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_cube/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_cube/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_cube/general.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/client.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_os/utils/default_config.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_reader/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_reader/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_reader/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_reader/memory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/modules/redis_service.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_scheduler/scheduler_factory.py +0 -0
- {memoryos-0.2.1/src/memos/memories → memoryos-0.2.2/src/memos/mem_scheduler/schemas}/__init__.py +0 -0
- {memoryos-0.2.1/src/memos/memories/activation → memoryos-0.2.2/src/memos/mem_scheduler/utils}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/mem_user/persistent_user_manager.py +0 -0
- {memoryos-0.2.1/src/memos/memories/parametric → memoryos-0.2.2/src/memos/memories}/__init__.py +0 -0
- {memoryos-0.2.1/src/memos/memories/textual → memoryos-0.2.2/src/memos/memories/activation}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/activation/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/activation/kv.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/activation/vllmkv.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/factory.py +0 -0
- {memoryos-0.2.1/src/memos/memories/textual/tree_text_memory → memoryos-0.2.2/src/memos/memories/parametric}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/parametric/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/parametric/item.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/parametric/lora.py +0 -0
- {memoryos-0.2.1/src/memos/memories/textual/tree_text_memory/organize → memoryos-0.2.2/src/memos/memories/textual}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/naive.py +0 -0
- {memoryos-0.2.1/src/memos/memories/textual/tree_text_memory/retrieve → memoryos-0.2.2/src/memos/memories/textual/tree_text_memory}/__init__.py +0 -0
- {memoryos-0.2.1/src/memos/parsers → memoryos-0.2.2/src/memos/memories/textual/tree_text_memory/organize}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/organize/manager.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/organize/redundancy.py +0 -0
- {memoryos-0.2.1/src/memos/templates → memoryos-0.2.2/src/memos/memories/textual/tree_text_memory/retrieve}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/reasoner.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/recall.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/memories/textual/tree_text_memory/retrieve/reranker.py +0 -0
- {memoryos-0.2.1/src/memos/vec_dbs → memoryos-0.2.2/src/memos/parsers}/__init__.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/parsers/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/parsers/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/parsers/markitdown.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/templates/tree_reorganize_prompts.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/types.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/vec_dbs/base.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/vec_dbs/factory.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/vec_dbs/item.py +0 -0
- {memoryos-0.2.1 → memoryos-0.2.2}/src/memos/vec_dbs/qdrant.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: MemoryOS
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Intelligence Begins with Memory
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: memory,llm,language model,memoryOS,agent,kv cache,lora
|
|
@@ -35,6 +35,7 @@ Requires-Dist: ollama (>=0.4.8,<0.5.0)
|
|
|
35
35
|
Requires-Dist: openai (>=1.77.0,<2.0.0)
|
|
36
36
|
Requires-Dist: pika (>=1.3.2,<2.0.0) ; extra == "all"
|
|
37
37
|
Requires-Dist: pika (>=1.3.2,<2.0.0) ; extra == "mem-scheduler"
|
|
38
|
+
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
|
38
39
|
Requires-Dist: qdrant-client (>=1.14.2,<2.0.0) ; extra == "all"
|
|
39
40
|
Requires-Dist: redis (>=6.2.0,<7.0.0) ; extra == "all"
|
|
40
41
|
Requires-Dist: redis (>=6.2.0,<7.0.0) ; extra == "mem-scheduler"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
##############################################################################
|
|
5
5
|
|
|
6
6
|
name = "MemoryOS"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Intelligence Begins with Memory"
|
|
9
9
|
license = {text = "Apache-2.0"}
|
|
10
10
|
readme = "README.md"
|
|
@@ -44,6 +44,7 @@ dependencies = [
|
|
|
44
44
|
"sqlalchemy (>=2.0.41,<3.0.0)", # SQL toolkit
|
|
45
45
|
"scikit-learn (>=1.7.0,<2.0.0)", # Machine learning
|
|
46
46
|
"fastmcp (>=2.10.5,<3.0.0)",
|
|
47
|
+
"python-dateutil (>=2.9.0.post0,<3.0.0)",
|
|
47
48
|
]
|
|
48
49
|
|
|
49
50
|
[project.urls]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import os
|
|
2
3
|
|
|
3
4
|
from typing import Any
|
|
@@ -115,6 +116,48 @@ class APIConfig:
|
|
|
115
116
|
},
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
@staticmethod
|
|
120
|
+
def get_internet_config() -> dict[str, Any]:
|
|
121
|
+
"""Get embedder configuration."""
|
|
122
|
+
return {
|
|
123
|
+
"backend": "xinyu",
|
|
124
|
+
"config": {
|
|
125
|
+
"api_key": os.getenv("XINYU_API_KEY"),
|
|
126
|
+
"search_engine_id": os.getenv("XINYU_SEARCH_ENGINE_ID"),
|
|
127
|
+
"max_results": 15,
|
|
128
|
+
"num_per_request": 10,
|
|
129
|
+
"reader": {
|
|
130
|
+
"backend": "simple_struct",
|
|
131
|
+
"config": {
|
|
132
|
+
"llm": {
|
|
133
|
+
"backend": "openai",
|
|
134
|
+
"config": {
|
|
135
|
+
"model_name_or_path": os.getenv("MEMRADER_MODEL"),
|
|
136
|
+
"temperature": 0.6,
|
|
137
|
+
"max_tokens": 5000,
|
|
138
|
+
"top_p": 0.95,
|
|
139
|
+
"top_k": 20,
|
|
140
|
+
"api_key": "EMPTY",
|
|
141
|
+
"api_base": os.getenv("MEMRADER_API_BASE"),
|
|
142
|
+
"remove_think_prefix": True,
|
|
143
|
+
"extra_body": {"chat_template_kwargs": {"enable_thinking": False}},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
"embedder": APIConfig.get_embedder_config(),
|
|
147
|
+
"chunker": {
|
|
148
|
+
"backend": "sentence",
|
|
149
|
+
"config": {
|
|
150
|
+
"tokenizer_or_token_counter": "gpt2",
|
|
151
|
+
"chunk_size": 512,
|
|
152
|
+
"chunk_overlap": 128,
|
|
153
|
+
"min_sentences_per_chunk": 1,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
|
|
118
161
|
@staticmethod
|
|
119
162
|
def get_neo4j_community_config(user_id: str | None = None) -> dict[str, Any]:
|
|
120
163
|
"""Get Neo4j community configuration."""
|
|
@@ -126,14 +169,14 @@ class APIConfig:
|
|
|
126
169
|
"user_name": f"memos{user_id.replace('-', '')}",
|
|
127
170
|
"auto_create": True,
|
|
128
171
|
"use_multi_db": False,
|
|
129
|
-
"embedding_dimension": 3072,
|
|
172
|
+
"embedding_dimension": int(os.getenv("EMBEDDING_DIMENSION", 3072)),
|
|
130
173
|
"vec_config": {
|
|
131
174
|
# Pass nested config to initialize external vector DB
|
|
132
175
|
# If you use qdrant, please use Server instead of local mode.
|
|
133
176
|
"backend": "qdrant",
|
|
134
177
|
"config": {
|
|
135
178
|
"collection_name": "neo4j_vec_db",
|
|
136
|
-
"vector_dimension": 3072,
|
|
179
|
+
"vector_dimension": int(os.getenv("EMBEDDING_DIMENSION", 3072)),
|
|
137
180
|
"distance_metric": "cosine",
|
|
138
181
|
"host": "localhost",
|
|
139
182
|
"port": 6333,
|
|
@@ -159,7 +202,7 @@ class APIConfig:
|
|
|
159
202
|
"password": os.getenv("NEO4J_PASSWORD", "12345678"),
|
|
160
203
|
"auto_create": True,
|
|
161
204
|
"use_multi_db": True,
|
|
162
|
-
"embedding_dimension": 3072,
|
|
205
|
+
"embedding_dimension": int(os.getenv("EMBEDDING_DIMENSION", 3072)),
|
|
163
206
|
}
|
|
164
207
|
|
|
165
208
|
@staticmethod
|
|
@@ -173,7 +216,33 @@ class APIConfig:
|
|
|
173
216
|
"user_name": f"memos{user_id.replace('-', '')}",
|
|
174
217
|
"auto_create": True,
|
|
175
218
|
"use_multi_db": False,
|
|
176
|
-
"embedding_dimension": 3072,
|
|
219
|
+
"embedding_dimension": int(os.getenv("EMBEDDING_DIMENSION", 3072)),
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def get_nebular_config(user_id: str | None = None) -> dict[str, Any]:
|
|
224
|
+
"""Get Nebular configuration."""
|
|
225
|
+
return {
|
|
226
|
+
"uri": json.loads(os.getenv("NEBULAR_HOSTS", '["localhost"]')),
|
|
227
|
+
"user": os.getenv("NEBULAR_USER", "root"),
|
|
228
|
+
"password": os.getenv("NEBULAR_PASSWORD", "xxxxxx"),
|
|
229
|
+
"space": os.getenv("NEBULAR_SPACE", "shared-tree-textual-memory"),
|
|
230
|
+
"user_name": f"memos{user_id.replace('-', '')}",
|
|
231
|
+
"use_multi_db": False,
|
|
232
|
+
"auto_create": True,
|
|
233
|
+
"embedding_dimension": int(os.getenv("EMBEDDING_DIMENSION", 3072)),
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def get_mysql_config() -> dict[str, Any]:
|
|
238
|
+
"""Get MySQL configuration."""
|
|
239
|
+
return {
|
|
240
|
+
"host": os.getenv("MYSQL_HOST", "localhost"),
|
|
241
|
+
"port": int(os.getenv("MYSQL_PORT", "3306")),
|
|
242
|
+
"username": os.getenv("MYSQL_USERNAME", "root"),
|
|
243
|
+
"password": os.getenv("MYSQL_PASSWORD", "12345678"),
|
|
244
|
+
"database": os.getenv("MYSQL_DATABASE", "memos_users"),
|
|
245
|
+
"charset": os.getenv("MYSQL_CHARSET", "utf8mb4"),
|
|
177
246
|
}
|
|
178
247
|
|
|
179
248
|
@staticmethod
|
|
@@ -212,6 +281,34 @@ class APIConfig:
|
|
|
212
281
|
"""Check if default cube config is enabled via environment variable."""
|
|
213
282
|
return os.getenv("MOS_ENABLE_DEFAULT_CUBE_CONFIG", "false").lower() == "true"
|
|
214
283
|
|
|
284
|
+
@staticmethod
|
|
285
|
+
def is_dingding_bot_enabled() -> bool:
|
|
286
|
+
"""Check if DingDing bot is enabled via environment variable."""
|
|
287
|
+
return os.getenv("ENABLE_DINGDING_BOT", "false").lower() == "true"
|
|
288
|
+
|
|
289
|
+
@staticmethod
|
|
290
|
+
def get_dingding_bot_config() -> dict[str, Any] | None:
|
|
291
|
+
"""Get DingDing bot configuration if enabled."""
|
|
292
|
+
if not APIConfig.is_dingding_bot_enabled():
|
|
293
|
+
return None
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
"enabled": True,
|
|
297
|
+
"access_token_user": os.getenv("DINGDING_ACCESS_TOKEN_USER", ""),
|
|
298
|
+
"secret_user": os.getenv("DINGDING_SECRET_USER", ""),
|
|
299
|
+
"access_token_error": os.getenv("DINGDING_ACCESS_TOKEN_ERROR", ""),
|
|
300
|
+
"secret_error": os.getenv("DINGDING_SECRET_ERROR", ""),
|
|
301
|
+
"robot_code": os.getenv("DINGDING_ROBOT_CODE", ""),
|
|
302
|
+
"app_key": os.getenv("DINGDING_APP_KEY", ""),
|
|
303
|
+
"app_secret": os.getenv("DINGDING_APP_SECRET", ""),
|
|
304
|
+
"oss_endpoint": os.getenv("OSS_ENDPOINT", ""),
|
|
305
|
+
"oss_region": os.getenv("OSS_REGION", ""),
|
|
306
|
+
"oss_bucket_name": os.getenv("OSS_BUCKET_NAME", ""),
|
|
307
|
+
"oss_access_key_id": os.getenv("OSS_ACCESS_KEY_ID", ""),
|
|
308
|
+
"oss_access_key_secret": os.getenv("OSS_ACCESS_KEY_SECRET", ""),
|
|
309
|
+
"oss_public_base_url": os.getenv("OSS_PUBLIC_BASE_URL", ""),
|
|
310
|
+
}
|
|
311
|
+
|
|
215
312
|
@staticmethod
|
|
216
313
|
def get_product_default_config() -> dict[str, Any]:
|
|
217
314
|
"""Get default configuration for Product API."""
|
|
@@ -224,6 +321,7 @@ class APIConfig:
|
|
|
224
321
|
"vllm": vllm_config,
|
|
225
322
|
}
|
|
226
323
|
backend = os.getenv("MOS_CHAT_MODEL_PROVIDER", "openai")
|
|
324
|
+
mysql_config = APIConfig.get_mysql_config()
|
|
227
325
|
config = {
|
|
228
326
|
"user_id": os.getenv("MOS_USER_ID", "root"),
|
|
229
327
|
"chat_model": {"backend": backend, "config": backend_model[backend]},
|
|
@@ -260,6 +358,13 @@ class APIConfig:
|
|
|
260
358
|
else:
|
|
261
359
|
config["enable_mem_scheduler"] = False
|
|
262
360
|
|
|
361
|
+
# Add user manager configuration if enabled
|
|
362
|
+
if os.getenv("MOS_USER_MANAGER_BACKEND", "sqlite").lower() == "mysql":
|
|
363
|
+
config["user_manager"] = {
|
|
364
|
+
"backend": "mysql",
|
|
365
|
+
"config": mysql_config,
|
|
366
|
+
}
|
|
367
|
+
|
|
263
368
|
return config
|
|
264
369
|
|
|
265
370
|
@staticmethod
|
|
@@ -300,9 +405,9 @@ class APIConfig:
|
|
|
300
405
|
def create_user_config(user_name: str, user_id: str) -> tuple[MOSConfig, GeneralMemCube]:
|
|
301
406
|
"""Create configuration for a specific user."""
|
|
302
407
|
openai_config = APIConfig.get_openai_config()
|
|
303
|
-
|
|
304
408
|
qwen_config = APIConfig.qwen_config()
|
|
305
409
|
vllm_config = APIConfig.vllm_config()
|
|
410
|
+
mysql_config = APIConfig.get_mysql_config()
|
|
306
411
|
backend = os.getenv("MOS_CHAT_MODEL_PROVIDER", "openai")
|
|
307
412
|
backend_model = {
|
|
308
413
|
"openai": openai_config,
|
|
@@ -341,7 +446,6 @@ class APIConfig:
|
|
|
341
446
|
"top_k": 30,
|
|
342
447
|
"max_turns_window": 20,
|
|
343
448
|
}
|
|
344
|
-
|
|
345
449
|
# Add scheduler configuration if enabled
|
|
346
450
|
if APIConfig.is_scheduler_enabled():
|
|
347
451
|
config_dict["mem_scheduler"] = APIConfig.get_scheduler_config()
|
|
@@ -349,11 +453,32 @@ class APIConfig:
|
|
|
349
453
|
else:
|
|
350
454
|
config_dict["enable_mem_scheduler"] = False
|
|
351
455
|
|
|
456
|
+
# Add user manager configuration if enabled
|
|
457
|
+
if os.getenv("MOS_USER_MANAGER_BACKEND", "sqlite").lower() == "mysql":
|
|
458
|
+
config_dict["user_manager"] = {
|
|
459
|
+
"backend": "mysql",
|
|
460
|
+
"config": mysql_config,
|
|
461
|
+
}
|
|
462
|
+
|
|
352
463
|
default_config = MOSConfig(**config_dict)
|
|
353
464
|
|
|
354
|
-
|
|
355
|
-
|
|
465
|
+
neo4j_community_config = APIConfig.get_neo4j_community_config(user_id)
|
|
466
|
+
neo4j_config = APIConfig.get_neo4j_config(user_id)
|
|
467
|
+
nebular_config = APIConfig.get_nebular_config(user_id)
|
|
468
|
+
internet_config = (
|
|
469
|
+
APIConfig.get_internet_config()
|
|
470
|
+
if os.getenv("ENABLE_INTERNET", "false").lower() == "true"
|
|
471
|
+
else None
|
|
472
|
+
)
|
|
473
|
+
graph_db_backend_map = {
|
|
474
|
+
"neo4j-community": neo4j_community_config,
|
|
475
|
+
"neo4j": neo4j_config,
|
|
476
|
+
"nebular": nebular_config,
|
|
477
|
+
}
|
|
478
|
+
graph_db_backend = os.getenv("NEO4J_BACKEND", "neo4j-community").lower()
|
|
479
|
+
if graph_db_backend in graph_db_backend_map:
|
|
356
480
|
# Create MemCube config
|
|
481
|
+
|
|
357
482
|
default_cube_config = GeneralMemCubeConfig.model_validate(
|
|
358
483
|
{
|
|
359
484
|
"user_id": user_id,
|
|
@@ -364,10 +489,11 @@ class APIConfig:
|
|
|
364
489
|
"extractor_llm": {"backend": "openai", "config": openai_config},
|
|
365
490
|
"dispatcher_llm": {"backend": "openai", "config": openai_config},
|
|
366
491
|
"graph_db": {
|
|
367
|
-
"backend":
|
|
368
|
-
"config":
|
|
492
|
+
"backend": graph_db_backend,
|
|
493
|
+
"config": graph_db_backend_map[graph_db_backend],
|
|
369
494
|
},
|
|
370
495
|
"embedder": APIConfig.get_embedder_config(),
|
|
496
|
+
"internet_retriever": internet_config,
|
|
371
497
|
},
|
|
372
498
|
},
|
|
373
499
|
"act_mem": {}
|
|
@@ -377,31 +503,7 @@ class APIConfig:
|
|
|
377
503
|
}
|
|
378
504
|
)
|
|
379
505
|
else:
|
|
380
|
-
|
|
381
|
-
# Create MemCube config
|
|
382
|
-
default_cube_config = GeneralMemCubeConfig.model_validate(
|
|
383
|
-
{
|
|
384
|
-
"user_id": user_id,
|
|
385
|
-
"cube_id": f"{user_name}_default_cube",
|
|
386
|
-
"text_mem": {
|
|
387
|
-
"backend": "tree_text",
|
|
388
|
-
"config": {
|
|
389
|
-
"extractor_llm": {"backend": "openai", "config": openai_config},
|
|
390
|
-
"dispatcher_llm": {"backend": "openai", "config": openai_config},
|
|
391
|
-
"graph_db": {
|
|
392
|
-
"backend": "neo4j",
|
|
393
|
-
"config": neo4j_config,
|
|
394
|
-
},
|
|
395
|
-
"embedder": APIConfig.get_embedder_config(),
|
|
396
|
-
},
|
|
397
|
-
},
|
|
398
|
-
"act_mem": {}
|
|
399
|
-
if os.getenv("ENABLE_ACTIVATION_MEMORY", "false").lower() == "false"
|
|
400
|
-
else APIConfig.get_activation_vllm_config(),
|
|
401
|
-
"para_mem": {},
|
|
402
|
-
}
|
|
403
|
-
)
|
|
404
|
-
|
|
506
|
+
raise ValueError(f"Invalid Neo4j backend: {graph_db_backend}")
|
|
405
507
|
default_mem_cube = GeneralMemCube(default_cube_config)
|
|
406
508
|
return default_config, default_mem_cube
|
|
407
509
|
|
|
@@ -416,9 +518,21 @@ class APIConfig:
|
|
|
416
518
|
return None
|
|
417
519
|
|
|
418
520
|
openai_config = APIConfig.get_openai_config()
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
521
|
+
neo4j_community_config = APIConfig.get_neo4j_community_config(user_id="default")
|
|
522
|
+
neo4j_config = APIConfig.get_neo4j_config(user_id="default")
|
|
523
|
+
nebular_config = APIConfig.get_nebular_config(user_id="default")
|
|
524
|
+
graph_db_backend_map = {
|
|
525
|
+
"neo4j-community": neo4j_community_config,
|
|
526
|
+
"neo4j": neo4j_config,
|
|
527
|
+
"nebular": nebular_config,
|
|
528
|
+
}
|
|
529
|
+
internet_config = (
|
|
530
|
+
APIConfig.get_internet_config()
|
|
531
|
+
if os.getenv("ENABLE_INTERNET", "false").lower() == "true"
|
|
532
|
+
else None
|
|
533
|
+
)
|
|
534
|
+
graph_db_backend = os.getenv("NEO4J_BACKEND", "neo4j-community").lower()
|
|
535
|
+
if graph_db_backend in graph_db_backend_map:
|
|
422
536
|
return GeneralMemCubeConfig.model_validate(
|
|
423
537
|
{
|
|
424
538
|
"user_id": "default",
|
|
@@ -429,12 +543,13 @@ class APIConfig:
|
|
|
429
543
|
"extractor_llm": {"backend": "openai", "config": openai_config},
|
|
430
544
|
"dispatcher_llm": {"backend": "openai", "config": openai_config},
|
|
431
545
|
"graph_db": {
|
|
432
|
-
"backend":
|
|
433
|
-
"config":
|
|
546
|
+
"backend": graph_db_backend,
|
|
547
|
+
"config": graph_db_backend_map[graph_db_backend],
|
|
434
548
|
},
|
|
435
549
|
"embedder": APIConfig.get_embedder_config(),
|
|
436
550
|
"reorganize": os.getenv("MOS_ENABLE_REORGANIZE", "false").lower()
|
|
437
551
|
== "true",
|
|
552
|
+
"internet_retriever": internet_config,
|
|
438
553
|
},
|
|
439
554
|
},
|
|
440
555
|
"act_mem": {}
|
|
@@ -444,28 +559,4 @@ class APIConfig:
|
|
|
444
559
|
}
|
|
445
560
|
)
|
|
446
561
|
else:
|
|
447
|
-
|
|
448
|
-
return GeneralMemCubeConfig.model_validate(
|
|
449
|
-
{
|
|
450
|
-
"user_id": "default",
|
|
451
|
-
"cube_id": "default_cube",
|
|
452
|
-
"text_mem": {
|
|
453
|
-
"backend": "tree_text",
|
|
454
|
-
"config": {
|
|
455
|
-
"extractor_llm": {"backend": "openai", "config": openai_config},
|
|
456
|
-
"dispatcher_llm": {"backend": "openai", "config": openai_config},
|
|
457
|
-
"graph_db": {
|
|
458
|
-
"backend": "neo4j",
|
|
459
|
-
"config": neo4j_config,
|
|
460
|
-
},
|
|
461
|
-
"embedder": APIConfig.get_embedder_config(),
|
|
462
|
-
"reorganize": os.getenv("MOS_ENABLE_REORGANIZE", "false").lower()
|
|
463
|
-
== "true",
|
|
464
|
-
},
|
|
465
|
-
},
|
|
466
|
-
"act_mem": {}
|
|
467
|
-
if os.getenv("ENABLE_ACTIVATION_MEMORY", "false").lower() == "false"
|
|
468
|
-
else APIConfig.get_activation_vllm_config(),
|
|
469
|
-
"para_mem": {},
|
|
470
|
-
}
|
|
471
|
-
)
|
|
562
|
+
raise ValueError(f"Invalid Neo4j backend: {graph_db_backend}")
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Global request context management for trace_id and request-scoped data.
|
|
3
|
+
|
|
4
|
+
This module provides optional trace_id functionality that can be enabled
|
|
5
|
+
when using the API components. It uses ContextVar to ensure thread safety
|
|
6
|
+
and request isolation.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import uuid
|
|
10
|
+
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from contextvars import ContextVar
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Global context variable for request-scoped data
|
|
17
|
+
_request_context: ContextVar[dict[str, Any] | None] = ContextVar("request_context", default=None)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class RequestContext:
|
|
21
|
+
"""
|
|
22
|
+
Request-scoped context object that holds trace_id and other request data.
|
|
23
|
+
|
|
24
|
+
This provides a Flask g-like object for FastAPI applications.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, trace_id: str | None = None):
|
|
28
|
+
self.trace_id = trace_id or str(uuid.uuid4())
|
|
29
|
+
self._data: dict[str, Any] = {}
|
|
30
|
+
|
|
31
|
+
def set(self, key: str, value: Any) -> None:
|
|
32
|
+
"""Set a value in the context."""
|
|
33
|
+
self._data[key] = value
|
|
34
|
+
|
|
35
|
+
def get(self, key: str, default: Any | None = None) -> Any:
|
|
36
|
+
"""Get a value from the context."""
|
|
37
|
+
return self._data.get(key, default)
|
|
38
|
+
|
|
39
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
40
|
+
if name.startswith("_") or name == "trace_id":
|
|
41
|
+
super().__setattr__(name, value)
|
|
42
|
+
else:
|
|
43
|
+
if not hasattr(self, "_data"):
|
|
44
|
+
super().__setattr__(name, value)
|
|
45
|
+
else:
|
|
46
|
+
self._data[name] = value
|
|
47
|
+
|
|
48
|
+
def __getattr__(self, name: str) -> Any:
|
|
49
|
+
if hasattr(self, "_data") and name in self._data:
|
|
50
|
+
return self._data[name]
|
|
51
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
|
|
52
|
+
|
|
53
|
+
def to_dict(self) -> dict[str, Any]:
|
|
54
|
+
"""Convert context to dictionary."""
|
|
55
|
+
return {"trace_id": self.trace_id, "data": self._data.copy()}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def set_request_context(context: RequestContext) -> None:
|
|
59
|
+
"""
|
|
60
|
+
Set the current request context.
|
|
61
|
+
|
|
62
|
+
This is typically called by the API dependency injection system.
|
|
63
|
+
"""
|
|
64
|
+
_request_context.set(context.to_dict())
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_current_trace_id() -> str | None:
|
|
68
|
+
"""
|
|
69
|
+
Get the current request's trace_id.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The trace_id if available, None otherwise.
|
|
73
|
+
"""
|
|
74
|
+
context = _request_context.get()
|
|
75
|
+
if context:
|
|
76
|
+
return context.get("trace_id")
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_current_context() -> RequestContext | None:
|
|
81
|
+
"""
|
|
82
|
+
Get the current request context.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
The current RequestContext if available, None otherwise.
|
|
86
|
+
"""
|
|
87
|
+
context_dict = _request_context.get()
|
|
88
|
+
if context_dict:
|
|
89
|
+
ctx = RequestContext(trace_id=context_dict.get("trace_id"))
|
|
90
|
+
ctx._data = context_dict.get("data", {}).copy()
|
|
91
|
+
return ctx
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def require_context() -> RequestContext:
|
|
96
|
+
"""
|
|
97
|
+
Get the current request context, raising an error if not available.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
The current RequestContext.
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
RuntimeError: If called outside of a request context.
|
|
104
|
+
"""
|
|
105
|
+
context = get_current_context()
|
|
106
|
+
if context is None:
|
|
107
|
+
raise RuntimeError(
|
|
108
|
+
"No request context available. This function must be called within a request handler."
|
|
109
|
+
)
|
|
110
|
+
return context
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# Type for trace_id getter function
|
|
114
|
+
TraceIdGetter = Callable[[], str | None]
|
|
115
|
+
|
|
116
|
+
# Global variable to hold the trace_id getter function
|
|
117
|
+
_trace_id_getter: TraceIdGetter | None = None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def set_trace_id_getter(getter: TraceIdGetter) -> None:
|
|
121
|
+
"""
|
|
122
|
+
Set a custom trace_id getter function.
|
|
123
|
+
|
|
124
|
+
This allows the logging system to retrieve trace_id without importing
|
|
125
|
+
API-specific modules.
|
|
126
|
+
"""
|
|
127
|
+
global _trace_id_getter
|
|
128
|
+
_trace_id_getter = getter
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_trace_id_for_logging() -> str | None:
|
|
132
|
+
"""
|
|
133
|
+
Get trace_id for logging purposes.
|
|
134
|
+
|
|
135
|
+
This function is used by the logging system and will use either
|
|
136
|
+
the custom getter function or fall back to the default context.
|
|
137
|
+
"""
|
|
138
|
+
if _trace_id_getter:
|
|
139
|
+
try:
|
|
140
|
+
return _trace_id_getter()
|
|
141
|
+
except Exception:
|
|
142
|
+
pass
|
|
143
|
+
return get_current_trace_id()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# Initialize the default trace_id getter
|
|
147
|
+
set_trace_id_getter(get_current_trace_id)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from fastapi import Depends, Header, Request
|
|
4
|
+
|
|
5
|
+
from memos.api.context.context import RequestContext, set_request_context
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
# Type alias for the RequestContext from context module
|
|
11
|
+
G = RequestContext
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_trace_id_from_header(
|
|
15
|
+
trace_id: str | None = Header(None, alias="trace-id"),
|
|
16
|
+
x_trace_id: str | None = Header(None, alias="x-trace-id"),
|
|
17
|
+
g_trace_id: str | None = Header(None, alias="g-trace-id"),
|
|
18
|
+
) -> str | None:
|
|
19
|
+
"""
|
|
20
|
+
Extract trace_id from various possible headers.
|
|
21
|
+
|
|
22
|
+
Priority: g-trace-id > x-trace-id > trace-id
|
|
23
|
+
"""
|
|
24
|
+
return g_trace_id or x_trace_id or trace_id
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_request_context(
|
|
28
|
+
request: Request, trace_id: str | None = Depends(get_trace_id_from_header)
|
|
29
|
+
) -> RequestContext:
|
|
30
|
+
"""
|
|
31
|
+
Get request context object with trace_id and request metadata.
|
|
32
|
+
|
|
33
|
+
This function creates a RequestContext and automatically sets it
|
|
34
|
+
in the global context for use throughout the request lifecycle.
|
|
35
|
+
"""
|
|
36
|
+
# Create context object
|
|
37
|
+
ctx = RequestContext(trace_id=trace_id)
|
|
38
|
+
|
|
39
|
+
# Set the context globally for this request
|
|
40
|
+
set_request_context(ctx)
|
|
41
|
+
|
|
42
|
+
# Log request start
|
|
43
|
+
logger.info(f"Request started with trace_id: {ctx.trace_id}")
|
|
44
|
+
|
|
45
|
+
# Add request metadata to context
|
|
46
|
+
ctx.set("method", request.method)
|
|
47
|
+
ctx.set("path", request.url.path)
|
|
48
|
+
ctx.set("client_ip", request.client.host if request.client else None)
|
|
49
|
+
|
|
50
|
+
return ctx
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_g_object(trace_id: str | None = Depends(get_trace_id_from_header)) -> G:
|
|
54
|
+
"""
|
|
55
|
+
Get Flask g-like object for the current request.
|
|
56
|
+
|
|
57
|
+
This creates a RequestContext and sets it globally for access
|
|
58
|
+
throughout the request lifecycle.
|
|
59
|
+
"""
|
|
60
|
+
g = RequestContext(trace_id=trace_id)
|
|
61
|
+
set_request_context(g)
|
|
62
|
+
logger.info(f"Request g object created with trace_id: {g.trace_id}")
|
|
63
|
+
return g
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_current_g() -> G | None:
|
|
67
|
+
"""
|
|
68
|
+
Get the current request's g object from anywhere in the application.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The current request's g object if available, None otherwise.
|
|
72
|
+
"""
|
|
73
|
+
from memos.context import get_current_context
|
|
74
|
+
|
|
75
|
+
return get_current_context()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def require_g() -> G:
|
|
79
|
+
"""
|
|
80
|
+
Get the current request's g object, raising an error if not available.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The current request's g object.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
RuntimeError: If called outside of a request context.
|
|
87
|
+
"""
|
|
88
|
+
from memos.context import require_context
|
|
89
|
+
|
|
90
|
+
return require_context()
|
|
@@ -83,11 +83,12 @@ class ChatRequest(BaseRequest):
|
|
|
83
83
|
query: str = Field(..., description="Chat query message")
|
|
84
84
|
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
|
|
85
85
|
history: list[MessageDict] | None = Field(None, description="Chat history")
|
|
86
|
+
internet_search: bool = Field(True, description="Whether to use internet search")
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
class UserCreate(BaseRequest):
|
|
89
90
|
user_name: str | None = Field(None, description="Name of the user")
|
|
90
|
-
role: str = Field("
|
|
91
|
+
role: str = Field("USER", description="Role of the user")
|
|
91
92
|
user_id: str = Field(..., description="User ID")
|
|
92
93
|
|
|
93
94
|
|
|
@@ -142,6 +143,8 @@ class MemoryCreateRequest(BaseRequest):
|
|
|
142
143
|
memory_content: str | None = Field(None, description="Memory content to store")
|
|
143
144
|
doc_path: str | None = Field(None, description="Path to document to store")
|
|
144
145
|
mem_cube_id: str | None = Field(None, description="Cube ID")
|
|
146
|
+
source: str | None = Field(None, description="Source of the memory")
|
|
147
|
+
user_profile: bool = Field(False, description="User profile memory")
|
|
145
148
|
|
|
146
149
|
|
|
147
150
|
class SearchRequest(BaseRequest):
|
|
@@ -150,6 +153,7 @@ class SearchRequest(BaseRequest):
|
|
|
150
153
|
user_id: str = Field(..., description="User ID")
|
|
151
154
|
query: str = Field(..., description="Search query")
|
|
152
155
|
mem_cube_id: str | None = Field(None, description="Cube ID to search in")
|
|
156
|
+
top_k: int = Field(10, description="Number of results to return")
|
|
153
157
|
|
|
154
158
|
|
|
155
159
|
class SuggestionRequest(BaseRequest):
|