MemoryOS 1.0.0__py3-none-any.whl → 1.0.1__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.
Potentially problematic release.
This version of MemoryOS might be problematic. Click here for more details.
- {memoryos-1.0.0.dist-info → memoryos-1.0.1.dist-info}/METADATA +2 -1
- {memoryos-1.0.0.dist-info → memoryos-1.0.1.dist-info}/RECORD +42 -33
- memos/__init__.py +1 -1
- memos/api/config.py +25 -0
- memos/api/context/context_thread.py +96 -0
- memos/api/context/dependencies.py +0 -11
- memos/api/middleware/request_context.py +94 -0
- memos/api/product_api.py +5 -1
- memos/api/product_models.py +16 -0
- memos/api/routers/product_router.py +39 -3
- memos/api/start_api.py +3 -0
- memos/configs/memory.py +13 -0
- memos/configs/reranker.py +18 -0
- memos/graph_dbs/base.py +4 -2
- memos/graph_dbs/nebular.py +215 -68
- memos/graph_dbs/neo4j.py +14 -12
- memos/graph_dbs/neo4j_community.py +6 -3
- memos/llms/vllm.py +2 -0
- memos/log.py +120 -8
- memos/mem_os/core.py +30 -2
- memos/mem_os/product.py +386 -146
- memos/mem_os/utils/reference_utils.py +20 -0
- memos/mem_reader/simple_struct.py +112 -43
- memos/mem_user/mysql_user_manager.py +4 -2
- memos/memories/textual/item.py +1 -1
- memos/memories/textual/tree.py +31 -1
- memos/memories/textual/tree_text_memory/retrieve/bochasearch.py +3 -1
- memos/memories/textual/tree_text_memory/retrieve/recall.py +53 -3
- memos/memories/textual/tree_text_memory/retrieve/searcher.py +74 -14
- memos/memories/textual/tree_text_memory/retrieve/utils.py +6 -4
- memos/memos_tools/notification_utils.py +46 -0
- memos/reranker/__init__.py +4 -0
- memos/reranker/base.py +24 -0
- memos/reranker/cosine_local.py +95 -0
- memos/reranker/factory.py +43 -0
- memos/reranker/http_bge.py +99 -0
- memos/reranker/noop.py +16 -0
- memos/templates/mem_reader_prompts.py +289 -40
- memos/templates/mos_prompts.py +133 -60
- {memoryos-1.0.0.dist-info → memoryos-1.0.1.dist-info}/LICENSE +0 -0
- {memoryos-1.0.0.dist-info → memoryos-1.0.1.dist-info}/WHEEL +0 -0
- {memoryos-1.0.0.dist-info → memoryos-1.0.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: MemoryOS
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
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
|
|
@@ -311,6 +311,7 @@ MemOS is licensed under the [Apache 2.0 License](./LICENSE).
|
|
|
311
311
|
Stay up to date with the latest MemOS announcements, releases, and community highlights.
|
|
312
312
|
|
|
313
313
|
|
|
314
|
+
- **2025-09-10** - 🎉 *MemOS v1.0.1 (Group Q&A Bot)*: Group Q&A bot based on MemOS Cube, updated KV-Cache performance comparison data across different GPU deployment schemes, optimized test benchmarks and statistics, added plaintext memory Reranker sorting, optimized plaintext memory hallucination issues, and Playground version updates. [Try PlayGround](https://memos-playground.openmem.net/login/)
|
|
314
315
|
- **2025-08-07** - 🎉 *MemOS v1.0.0 (MemCube Release)*: First MemCube with word game demo, LongMemEval evaluation, BochaAISearchRetriever integration, NebulaGraph support, enhanced search capabilities, and official Playground launch.
|
|
315
316
|
- **2025-07-29** – 🎉 *MemOS v0.2.2 (Nebula Update)*: Internet search+Nebula DB integration, refactored memory scheduler, KV Cache stress tests, MemCube Cookbook release (CN/EN), and 4b/1.7b/0.6b memory ops models.
|
|
316
317
|
- **2025-07-21** – 🎉 *MemOS v0.2.1 (Neo Release)*: Lightweight Neo version with plaintext+KV Cache functionality, Docker/multi-tenant support, MCP expansion, and new Cookbook/Mud game examples.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
memos/__init__.py,sha256=
|
|
2
|
-
memos/api/config.py,sha256=
|
|
1
|
+
memos/__init__.py,sha256=EKtqQioVRZ2gNPD65cxhBbX-ZhswH1EBGMj2G6roYME,575
|
|
2
|
+
memos/api/config.py,sha256=Gx3g5jPZ_8EUPTTvA7h14tKL7VYe4FI4NybCTuylWuE,24513
|
|
3
3
|
memos/api/context/context.py,sha256=HBMeg3-e-rOJXMU7aR0JCsEIECuefEx8eyFT-1sSG9c,4158
|
|
4
|
-
memos/api/context/
|
|
4
|
+
memos/api/context/context_thread.py,sha256=T3Vdu7m1l8JMmoUBop1ykyrbH-oZ-_6FnymXsawmLis,3121
|
|
5
|
+
memos/api/context/dependencies.py,sha256=byLwmFsocQufcmi5WFg2j6XjWv9k4PCozCV7uRdCO3M,2468
|
|
5
6
|
memos/api/exceptions.py,sha256=MfTNXwLwJE7tHwNVTHlJsB3kF14oA0JfA1-S8xrZEus,833
|
|
6
7
|
memos/api/mcp_serve.py,sha256=GtJDZYx4yxKMs4sCddKJbRAjgsbRunr6S2nAT-KeBMs,21270
|
|
7
|
-
memos/api/
|
|
8
|
-
memos/api/
|
|
8
|
+
memos/api/middleware/request_context.py,sha256=8tkyIQkgBnGRM_X33CaM6x1M4jsprPMmYspTtRT20u8,2834
|
|
9
|
+
memos/api/product_api.py,sha256=6JrQRIGj1UrFxcHL2myA5_4li6Tf5S5ynja5rX3XhYU,1129
|
|
10
|
+
memos/api/product_models.py,sha256=aZJov3NqAaLpRLGPIg-GK6G00X-NvK2QyuOkQdCCmo8,6449
|
|
9
11
|
memos/api/routers/__init__.py,sha256=nbduRsr-7RkfBIYEBkbYkpB-7GG7QZgNfEQwLHbDXpI,21
|
|
10
|
-
memos/api/routers/product_router.py,sha256=
|
|
11
|
-
memos/api/start_api.py,sha256=
|
|
12
|
+
memos/api/routers/product_router.py,sha256=jeosTAJzwWkqo0Ev2eaHQex-LQtyI9LRLhLIvFDiOyw,17160
|
|
13
|
+
memos/api/start_api.py,sha256=rVXMPEQy9r1PiVzHO3LJCf2qSsb0Mv0tklUJMQMBP8A,14776
|
|
12
14
|
memos/chunkers/__init__.py,sha256=7lZOTN3e9Yp5XBsDX5wnWJ3tY126cRU9GmfevzJXAtU,67
|
|
13
15
|
memos/chunkers/base.py,sha256=z0rG5vM7FGremQdSZ_3jlTGbsDtlkWAYWdtSAGqpaR4,655
|
|
14
16
|
memos/chunkers/factory.py,sha256=ixpYz41GG3SZW-1ynLvfbhOZ0aGnFi2wUIYT4_Uxh30,693
|
|
@@ -27,8 +29,9 @@ memos/configs/mem_os.py,sha256=FGrBaFWGUdCKkb4MFDRz9hCE7hydLd0XEFgUrqEhQJw,2755
|
|
|
27
29
|
memos/configs/mem_reader.py,sha256=hTLFdmPhPIY70Fh_s4ptTGJ3LN-B9n111QG1kboxoNk,2307
|
|
28
30
|
memos/configs/mem_scheduler.py,sha256=kLE1JZM2IkzpsEdvJ0D0w3MNbjsqfB_--EvdZomHB5s,7644
|
|
29
31
|
memos/configs/mem_user.py,sha256=U0UzCvTacUOxeajJMfXAWWy3a0l52B4LUhH_L7U1VQ4,2036
|
|
30
|
-
memos/configs/memory.py,sha256=
|
|
32
|
+
memos/configs/memory.py,sha256=wWrDvO67evM4Pn-utqneliIsJlap0ddNhdEH1Vn8HbA,7636
|
|
31
33
|
memos/configs/parser.py,sha256=dy-QoevJbCnkJePKgpzR4oziOzYnS4jB6XH-YrpeMns,1145
|
|
34
|
+
memos/configs/reranker.py,sha256=8IbKPPNUcGq9uGhgXcx41eYjDJr1lZKv89UKrA9v-Ck,459
|
|
32
35
|
memos/configs/utils.py,sha256=X9NQ6-xURsZROAdS3WT96phVfHcOHgDPOo2Yq68QoKM,242
|
|
33
36
|
memos/configs/vec_db.py,sha256=Gjhhda94pyTDjyJGe2Z6rVEqH4FtViiwq1-7QWhjarM,2335
|
|
34
37
|
memos/dependency.py,sha256=T5jhi9J6EQvx41dP8ma6hdCNn86d1amEP1iMASnrVbA,1842
|
|
@@ -42,12 +45,12 @@ memos/embedders/sentence_transformer.py,sha256=QJoW7qMbvAzmMUXzIhMHXVFnDFurfzxdo
|
|
|
42
45
|
memos/embedders/universal_api.py,sha256=BpmLL18y2neEAIE4CdC-1qr0uOEOJ6o7V_zycdkJmZk,1270
|
|
43
46
|
memos/exceptions.py,sha256=UnBoZUYdwb1KoQPE-pXSLT4yOjkwxse9fx0rb_MhEzo,531
|
|
44
47
|
memos/graph_dbs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
memos/graph_dbs/base.py,sha256=
|
|
48
|
+
memos/graph_dbs/base.py,sha256=0NXdXII-UmX_bqUhBVpFdxRURLAK8sIFFZg51J9QzV0,8293
|
|
46
49
|
memos/graph_dbs/factory.py,sha256=N1NaABiNnYvnsB-L82LrQaLvND5seCabFdSDsD8LoyA,932
|
|
47
50
|
memos/graph_dbs/item.py,sha256=BfK17hA_hHu7I348jWugP_rb9GS5hpKfgqtYGGHBohk,1450
|
|
48
|
-
memos/graph_dbs/nebular.py,sha256=
|
|
49
|
-
memos/graph_dbs/neo4j.py,sha256=
|
|
50
|
-
memos/graph_dbs/neo4j_community.py,sha256=
|
|
51
|
+
memos/graph_dbs/nebular.py,sha256=AgoMapzTVSbuIz4-mTwj9aBhepS8PkcxJp9_s4uWitI,63674
|
|
52
|
+
memos/graph_dbs/neo4j.py,sha256=sBlFCibQOtfO8c6bYQl_K9VsphJorfzx97UMQnrZs3E,42491
|
|
53
|
+
memos/graph_dbs/neo4j_community.py,sha256=lWvfSo_-Dt3ST4vmBQiaziZDtQHV9CwY0qmWajOSPsc,11521
|
|
51
54
|
memos/hello_world.py,sha256=RV1vXfK1_U_xAvSusqc-4A8wk3yr8WEQ9q88dmBxvnI,3057
|
|
52
55
|
memos/llms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
56
|
memos/llms/base.py,sha256=CF60OpXdSLf-B5bHhQTnomMEkrNCg-SHauu1vo8HpeU,798
|
|
@@ -59,8 +62,8 @@ memos/llms/ollama.py,sha256=r1HMvSvG_m8gFfwLJhTriJdB6VzKEqz9f9JFs2RJGTw,2732
|
|
|
59
62
|
memos/llms/openai.py,sha256=yOcdG320q0JFLi7ipHDXoPWpvyeOMFwbzrnXtk2xqec,3832
|
|
60
63
|
memos/llms/qwen.py,sha256=RFVoC_hxFe4dhCQ583fbTcT1AC3jDrKH0r6cDsZ0Cmo,2459
|
|
61
64
|
memos/llms/utils.py,sha256=OcbM9iSpFJpio7sTT5wvxVx-JnqjIx7eSgiRk7dt0ZI,292
|
|
62
|
-
memos/llms/vllm.py,sha256=
|
|
63
|
-
memos/log.py,sha256=
|
|
65
|
+
memos/llms/vllm.py,sha256=9ZEgTUyRk86Wp2deQH0o1oW2GbHQ7C3evi-McELyT2Q,5792
|
|
66
|
+
memos/log.py,sha256=bmOqq0lH-FkLOlNnYtppqdchkDTz7AjJuSuGUKhsxXQ,6362
|
|
64
67
|
memos/mem_chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
68
|
memos/mem_chat/base.py,sha256=LICB_mwUkdCVKb_r33GEPbrEr-2v3dEnI54cAvhcEew,830
|
|
66
69
|
memos/mem_chat/factory.py,sha256=KKCDG9FrpfY2hD3iJ4GM9x8dN09dyhstP1cOUH_knrY,720
|
|
@@ -70,17 +73,17 @@ memos/mem_cube/base.py,sha256=NoZKz16oO5AAnJ0alcY52Z1c3C1rbGRe8Znz0CCzDnw,864
|
|
|
70
73
|
memos/mem_cube/general.py,sha256=w1HbDIM7MD6Pu_Pbv4KHgQlxOMaCHvvJk_tmA9rZ_q8,8370
|
|
71
74
|
memos/mem_cube/utils.py,sha256=gDwiRo9VEvaTaRDzjWOGAH13ALRRV9bvUG7A-wy4KTA,5522
|
|
72
75
|
memos/mem_os/client.py,sha256=0M-WRTlQr7fDAYtq4B8dsMR0PfmyvD-ySMhKcW3Umd0,43
|
|
73
|
-
memos/mem_os/core.py,sha256=
|
|
76
|
+
memos/mem_os/core.py,sha256=3PccrYDzheOKDW8_ZAwzXKvR8Rz4JHfvrdG4vSu6Ttg,45543
|
|
74
77
|
memos/mem_os/main.py,sha256=zjgQy80QN70Xt6GHqn5zw-_2jOT6RWMCh9Yx-3zZuyw,24534
|
|
75
|
-
memos/mem_os/product.py,sha256=
|
|
78
|
+
memos/mem_os/product.py,sha256=_tloS0ncPx04qfwKbggNFQzk0VL5Nqx6uHQriAFZYzI,58877
|
|
76
79
|
memos/mem_os/utils/default_config.py,sha256=OdDCyrE3-duSK0vMfO4AelGUwMt14ffHKMrvki0YKlI,12273
|
|
77
80
|
memos/mem_os/utils/format_utils.py,sha256=QaxImCM0E27l2tkRLzWM1s8vSp3MO_LNaY0APHgV35o,49883
|
|
78
|
-
memos/mem_os/utils/reference_utils.py,sha256=
|
|
81
|
+
memos/mem_os/utils/reference_utils.py,sha256=RtVwcuG3zFaxtMxY4S1_S8XWKQ7hO5UtXMswORBxyy0,6129
|
|
79
82
|
memos/mem_reader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
83
|
memos/mem_reader/base.py,sha256=SSuaD3J88XbHsME1Qa-EAgZ57xApPHPHppMSeeS3JZ4,957
|
|
81
84
|
memos/mem_reader/factory.py,sha256=emKnId9BhScSkqCZyLSLWntixnU3wAMIOVdsRpHldJA,766
|
|
82
85
|
memos/mem_reader/memory.py,sha256=f3fAjrs8Jf6mBZWTgzkEZle7XjDwTJHxM1L2sOb85Tg,13288
|
|
83
|
-
memos/mem_reader/simple_struct.py,sha256=
|
|
86
|
+
memos/mem_reader/simple_struct.py,sha256=TTYGOVt5WNwRpaHF0TW6VkVC98HbeS9-IA6dpIlHmpY,11864
|
|
84
87
|
memos/mem_scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
88
|
memos/mem_scheduler/base_scheduler.py,sha256=wxBmdsJUmiufQLEfqflb4EUs9h9JE1EcMdsr_CA-LKE,23255
|
|
86
89
|
memos/mem_scheduler/general_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -106,7 +109,7 @@ memos/mem_scheduler/utils/filter_utils.py,sha256=GsEsVjB6zZbF2gITxXN1DWTLoLG-d8A
|
|
|
106
109
|
memos/mem_scheduler/utils/misc_utils.py,sha256=zOCpwzCrj0mfiW7BoWiTFEPj-dzdcYZnqMDtKDGO0kc,2765
|
|
107
110
|
memos/mem_user/factory.py,sha256=zdC-208YYU4dpUaMpICzNbhMTiLaJDxLJoq4bl-6YiU,2956
|
|
108
111
|
memos/mem_user/mysql_persistent_user_manager.py,sha256=fSndxW6MR7u9ImWCPq-gsuFb2TYX1BXF6Kkv1FCS6Fw,9257
|
|
109
|
-
memos/mem_user/mysql_user_manager.py,sha256=
|
|
112
|
+
memos/mem_user/mysql_user_manager.py,sha256=Q_3FxNTw8Vf6uPotHk4YUooa8EVo0jBFTFBKJHPm_6o,16331
|
|
110
113
|
memos/mem_user/persistent_factory.py,sha256=0_k3KgvVESOAoD35ecwY77Dam-rfaFlly9oL-eMFmhk,3170
|
|
111
114
|
memos/mem_user/persistent_user_manager.py,sha256=oKQ6uXlT6v-bWTe99E5mNoPvs9FOxPtaMzNL4zujzP0,8760
|
|
112
115
|
memos/mem_user/user_manager.py,sha256=-Dwo8oR0AbnCGY9s3utm2ZqOvTJCpDTF5hlkvPRNiqA,15654
|
|
@@ -125,9 +128,9 @@ memos/memories/parametric/lora.py,sha256=TqSI2OjmFi-XXCeM-MchSwh1sAhOwL7_JnOwSy9
|
|
|
125
128
|
memos/memories/textual/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
126
129
|
memos/memories/textual/base.py,sha256=5AQ0oR1rLd7yiwIKPxt2OmAlL6mWhwUl_U8zuafoDfI,2827
|
|
127
130
|
memos/memories/textual/general.py,sha256=exHPHejBE6jZNLm8pT951sIko8hAqNdOaHZdnNdfzBA,8877
|
|
128
|
-
memos/memories/textual/item.py,sha256=
|
|
131
|
+
memos/memories/textual/item.py,sha256=GR6V0GNn32W-pYtwSvmz5F6kTh39Yp4XrQm-cEghL2I,5259
|
|
129
132
|
memos/memories/textual/naive.py,sha256=Z_gfbxI6cQGJ_raOTQic4fnpo493Xq3yEQ8qDV4xplo,6954
|
|
130
|
-
memos/memories/textual/tree.py,sha256=
|
|
133
|
+
memos/memories/textual/tree.py,sha256=7RwwWYm5c_F0pNMnQDjcCV01NGb_t-yN_kU8EMZjB9g,14826
|
|
131
134
|
memos/memories/textual/tree_text_memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
132
135
|
memos/memories/textual/tree_text_memory/organize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
136
|
memos/memories/textual/tree_text_memory/organize/handler.py,sha256=l7WuwWvubGzgaOSUBS0VNjSQU2JxtjwLMtKHxpms8NQ,8139
|
|
@@ -135,31 +138,37 @@ memos/memories/textual/tree_text_memory/organize/manager.py,sha256=r-0O9hS3y3oQr
|
|
|
135
138
|
memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py,sha256=udqQEFZb6TiarB-Rya1N7fKiWHtXiLkggh8bFKIlDjU,8816
|
|
136
139
|
memos/memories/textual/tree_text_memory/organize/reorganizer.py,sha256=txBC6uo3fId4RaTJeTJEg4V3Q-jrIP0jBHqVQkjjAqc,22719
|
|
137
140
|
memos/memories/textual/tree_text_memory/retrieve/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
|
-
memos/memories/textual/tree_text_memory/retrieve/bochasearch.py,sha256=
|
|
141
|
+
memos/memories/textual/tree_text_memory/retrieve/bochasearch.py,sha256=Nh9nbOD3MPcofD4jM0Mihb7cjE17VTvPEsuuMTzisM4,8258
|
|
139
142
|
memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py,sha256=aD2bujlVBWzDa9ZfB9vdB9Hq2erCpc426AVcolItWIM,8656
|
|
140
143
|
memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py,sha256=3-hJwpGrAAag7z772QBvW9ZBvNI_od5GO1nRv5Q3GbQ,3767
|
|
141
144
|
memos/memories/textual/tree_text_memory/retrieve/reasoner.py,sha256=5csoGjviFbN9RJ8dm3B6kjvoC8xbPD8UMiGusefHaf0,2228
|
|
142
|
-
memos/memories/textual/tree_text_memory/retrieve/recall.py,sha256=
|
|
145
|
+
memos/memories/textual/tree_text_memory/retrieve/recall.py,sha256=oGTp-14af1ZCHd8zkKP4vZ9F6gb3F9hGPdGp70AtiVA,7841
|
|
143
146
|
memos/memories/textual/tree_text_memory/retrieve/reranker.py,sha256=GIo_ZqA8Oea-L58Md724ak7Oq2fCnLfBWBUvMWiD7mY,3727
|
|
144
147
|
memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py,sha256=CvGfdwtOwC78OWKb1nOg_tsPualirsRfbtA58_kxNpA,433
|
|
145
|
-
memos/memories/textual/tree_text_memory/retrieve/searcher.py,sha256=
|
|
148
|
+
memos/memories/textual/tree_text_memory/retrieve/searcher.py,sha256=18o-qlcLI0Fv6H-wRYcPf3ez6kcVjUt37TIbzEl7naM,12854
|
|
146
149
|
memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py,sha256=vqgyczpS5As9zmljX9YF7TL0fgpl_T22FN5qV_AbcS8,3733
|
|
147
|
-
memos/memories/textual/tree_text_memory/retrieve/utils.py,sha256=
|
|
150
|
+
memos/memories/textual/tree_text_memory/retrieve/utils.py,sha256=ISdSJEq_HqtPEqmTRQO6dXx7ioDWrbLi7mrrep4iQDw,2191
|
|
148
151
|
memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py,sha256=x-nlZJ84shgAq9FqQR3YvE6iTMY_B7Pc0YaiGEqM1rc,10518
|
|
149
152
|
memos/memos_tools/dinding_report_bot.py,sha256=kXmooO_wUpwErT6Obql-SQu8lbt0XnM_58znIeQt734,14735
|
|
150
153
|
memos/memos_tools/lockfree_dict.py,sha256=A2hFUSyjTIauiXONYzr7zFZfGlOF9J9cqrfzDNBaw_w,3811
|
|
151
154
|
memos/memos_tools/notification_service.py,sha256=CZ7tZI6m0A063ON0MVEOUb9uontggvrvBLOMzorD0cI,1125
|
|
152
|
-
memos/memos_tools/notification_utils.py,sha256=
|
|
155
|
+
memos/memos_tools/notification_utils.py,sha256=uHrDOXEW-WUJcoeR7gVhr2BVjNYUxIjz8cCve5F1PPs,3747
|
|
153
156
|
memos/memos_tools/thread_safe_dict.py,sha256=5hhKndKntYIriTIkmaDaehmojuOMhEkVl4WAc2QLfHM,8252
|
|
154
157
|
memos/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
155
158
|
memos/parsers/base.py,sha256=AWgWIZzReDiTqiv6z08_9aG2KHVzc4Bdr0Lowz0mWVI,435
|
|
156
159
|
memos/parsers/factory.py,sha256=hPKTR0wVgMQ5Z9ZL-a9FyHWCpz9UcrG2oSEDYBAoB3g,704
|
|
157
160
|
memos/parsers/markitdown.py,sha256=SDwmZYC6LyiwdU79yuj6mWNMkQx9YrZzZEHU-4JzBwQ,863
|
|
161
|
+
memos/reranker/__init__.py,sha256=bq3LWhVg6LdK50Hx6jOM-eWEaNM0mX4_JuHNfYgUqE0,69
|
|
162
|
+
memos/reranker/base.py,sha256=bl9W-CqtlAs2k7loPvd3TRqq6Illybt6IosqrYw0DHw,573
|
|
163
|
+
memos/reranker/cosine_local.py,sha256=tOqL6WIUxkFriaROV0hKtJQ-b79BGGYD4Ow1VE0x0g0,2970
|
|
164
|
+
memos/reranker/factory.py,sha256=RMBKOLSgmhfvbhCqU8CnQrXR7176zjq04VD6PMDrxuk,1321
|
|
165
|
+
memos/reranker/http_bge.py,sha256=BFlRMqspV856EGinjkI_Vr2oo6YBeF00uDy_eeTT-k0,3254
|
|
166
|
+
memos/reranker/noop.py,sha256=OOy3d_AHydCm5BH4VNHEfq_vDE-D-WBgwSKIp8GQloo,414
|
|
158
167
|
memos/settings.py,sha256=BYOaqhzReu2yjbwrZqx9-uMwoipkj5Clc6VthnBYOvY,225
|
|
159
168
|
memos/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
160
|
-
memos/templates/mem_reader_prompts.py,sha256=
|
|
169
|
+
memos/templates/mem_reader_prompts.py,sha256=B1sWIuZbIQM1zTv-VAWDsHUNLdO1O6fCy9WdhLMq2Aw,26875
|
|
161
170
|
memos/templates/mem_scheduler_prompts.py,sha256=ty_H9TARf5sQogHSJoRYQmrS6w0xs51mMcKNjkExdFc,5034
|
|
162
|
-
memos/templates/mos_prompts.py,sha256=
|
|
171
|
+
memos/templates/mos_prompts.py,sha256=yqpf8n0ObJPrJjXg4x-Nxsd0_pr0cDhdyCOopI7sgbI,18321
|
|
163
172
|
memos/templates/tree_reorganize_prompts.py,sha256=FJRIwT2A4d5EnoPhNuzDFdMWpbNLlJEIfLZP69RBlDM,12112
|
|
164
173
|
memos/types.py,sha256=N7XBYxDTdc50KEsS6YxHvYgs23ykGsZ-wNnaJBVdVi4,1791
|
|
165
174
|
memos/utils.py,sha256=uB-8_5V16M7yNeAYXOIPaXwxeceUu4d_5yofLA6vbaE,428
|
|
@@ -168,8 +177,8 @@ memos/vec_dbs/base.py,sha256=gbw7Gb_zs8Yx8kJIx6aTM-Ylsb4qLkVOFB-iwNJW6Sw,3564
|
|
|
168
177
|
memos/vec_dbs/factory.py,sha256=Noa4caqzPT9b59i2jzdpAHFCSHiMfDmgRox1POkRRfE,710
|
|
169
178
|
memos/vec_dbs/item.py,sha256=mLrcHF0nWtMCUjScBgaeeSqabQ3vJhKr_6wrU_g25ns,1425
|
|
170
179
|
memos/vec_dbs/qdrant.py,sha256=4KAiSZ64Ulz8EeT2o1DpNDRwnKRF4iiaJbZdq-xrn0c,11052
|
|
171
|
-
memoryos-1.0.
|
|
172
|
-
memoryos-1.0.
|
|
173
|
-
memoryos-1.0.
|
|
174
|
-
memoryos-1.0.
|
|
175
|
-
memoryos-1.0.
|
|
180
|
+
memoryos-1.0.1.dist-info/LICENSE,sha256=FU-b6N8tVc7dzUZGyNjUIG1Ihnrh2iuBziq4a1Gl8HU,11358
|
|
181
|
+
memoryos-1.0.1.dist-info/METADATA,sha256=PvCovFOrn2QX_LoH22DuSjJQZwgl9rxgjVJvCfQMfxo,16011
|
|
182
|
+
memoryos-1.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
183
|
+
memoryos-1.0.1.dist-info/entry_points.txt,sha256=p54si8po81Yb-NK2lx5Z0lNr8QV7-5IECtkC6c8MJmI,40
|
|
184
|
+
memoryos-1.0.1.dist-info/RECORD,,
|
memos/__init__.py
CHANGED
memos/api/config.py
CHANGED
|
@@ -90,6 +90,29 @@ class APIConfig:
|
|
|
90
90
|
},
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
@staticmethod
|
|
94
|
+
def get_reranker_config() -> dict[str, Any]:
|
|
95
|
+
"""Get embedder configuration."""
|
|
96
|
+
embedder_backend = os.getenv("MOS_RERANKER_BACKEND", "http_bge")
|
|
97
|
+
|
|
98
|
+
if embedder_backend == "http_bge":
|
|
99
|
+
return {
|
|
100
|
+
"backend": "http_bge",
|
|
101
|
+
"config": {
|
|
102
|
+
"url": os.getenv("MOS_RERANKER_URL"),
|
|
103
|
+
"model": "bge-reranker-v2-m3",
|
|
104
|
+
"timeout": 10,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
else:
|
|
108
|
+
return {
|
|
109
|
+
"backend": "cosine_local",
|
|
110
|
+
"config": {
|
|
111
|
+
"level_weights": {"topic": 1.0, "concept": 1.0, "fact": 1.0},
|
|
112
|
+
"level_field": "background",
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
93
116
|
@staticmethod
|
|
94
117
|
def get_embedder_config() -> dict[str, Any]:
|
|
95
118
|
"""Get embedder configuration."""
|
|
@@ -492,6 +515,7 @@ class APIConfig:
|
|
|
492
515
|
},
|
|
493
516
|
"embedder": APIConfig.get_embedder_config(),
|
|
494
517
|
"internet_retriever": internet_config,
|
|
518
|
+
"reranker": APIConfig.get_reranker_config(),
|
|
495
519
|
},
|
|
496
520
|
},
|
|
497
521
|
"act_mem": {}
|
|
@@ -545,6 +569,7 @@ class APIConfig:
|
|
|
545
569
|
"config": graph_db_backend_map[graph_db_backend],
|
|
546
570
|
},
|
|
547
571
|
"embedder": APIConfig.get_embedder_config(),
|
|
572
|
+
"reranker": APIConfig.get_reranker_config(),
|
|
548
573
|
"reorganize": os.getenv("MOS_ENABLE_REORGANIZE", "false").lower()
|
|
549
574
|
== "true",
|
|
550
575
|
"internet_retriever": internet_config,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import threading
|
|
3
|
+
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
6
|
+
from typing import Any, TypeVar
|
|
7
|
+
|
|
8
|
+
from memos.api.context.context import (
|
|
9
|
+
RequestContext,
|
|
10
|
+
get_current_context,
|
|
11
|
+
get_current_trace_id,
|
|
12
|
+
set_request_context,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
T = TypeVar("T")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ContextThread(threading.Thread):
|
|
20
|
+
"""
|
|
21
|
+
Thread class that automatically propagates the main thread's trace_id to child threads.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, target, args=(), kwargs=None, **thread_kwargs):
|
|
25
|
+
super().__init__(**thread_kwargs)
|
|
26
|
+
self.target = target
|
|
27
|
+
self.args = args
|
|
28
|
+
self.kwargs = kwargs or {}
|
|
29
|
+
|
|
30
|
+
self.main_trace_id = get_current_trace_id()
|
|
31
|
+
self.main_context = get_current_context()
|
|
32
|
+
|
|
33
|
+
def run(self):
|
|
34
|
+
# Create a new RequestContext with the main thread's trace_id
|
|
35
|
+
if self.main_context:
|
|
36
|
+
# Copy the context data
|
|
37
|
+
child_context = RequestContext(trace_id=self.main_trace_id)
|
|
38
|
+
child_context._data = self.main_context._data.copy()
|
|
39
|
+
|
|
40
|
+
# Set the context in the child thread
|
|
41
|
+
set_request_context(child_context)
|
|
42
|
+
|
|
43
|
+
# Run the target function
|
|
44
|
+
self.target(*self.args, **self.kwargs)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ContextThreadPoolExecutor(ThreadPoolExecutor):
|
|
48
|
+
"""
|
|
49
|
+
ThreadPoolExecutor that automatically propagates the main thread's trace_id to worker threads.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def submit(self, fn: Callable[..., T], *args: Any, **kwargs: Any) -> Any:
|
|
53
|
+
"""
|
|
54
|
+
Submit a callable to be executed with the given arguments.
|
|
55
|
+
Automatically propagates the current thread's context to the worker thread.
|
|
56
|
+
"""
|
|
57
|
+
main_trace_id = get_current_trace_id()
|
|
58
|
+
main_context = get_current_context()
|
|
59
|
+
|
|
60
|
+
@functools.wraps(fn)
|
|
61
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
62
|
+
if main_context:
|
|
63
|
+
# Create and set new context in worker thread
|
|
64
|
+
child_context = RequestContext(trace_id=main_trace_id)
|
|
65
|
+
child_context._data = main_context._data.copy()
|
|
66
|
+
set_request_context(child_context)
|
|
67
|
+
|
|
68
|
+
return fn(*args, **kwargs)
|
|
69
|
+
|
|
70
|
+
return super().submit(wrapper, *args, **kwargs)
|
|
71
|
+
|
|
72
|
+
def map(
|
|
73
|
+
self,
|
|
74
|
+
fn: Callable[..., T],
|
|
75
|
+
*iterables: Any,
|
|
76
|
+
timeout: float | None = None,
|
|
77
|
+
chunksize: int = 1,
|
|
78
|
+
) -> Any:
|
|
79
|
+
"""
|
|
80
|
+
Returns an iterator equivalent to map(fn, iter).
|
|
81
|
+
Automatically propagates the current thread's context to worker threads.
|
|
82
|
+
"""
|
|
83
|
+
main_trace_id = get_current_trace_id()
|
|
84
|
+
main_context = get_current_context()
|
|
85
|
+
|
|
86
|
+
@functools.wraps(fn)
|
|
87
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
88
|
+
if main_context:
|
|
89
|
+
# Create and set new context in worker thread
|
|
90
|
+
child_context = RequestContext(trace_id=main_trace_id)
|
|
91
|
+
child_context._data = main_context._data.copy()
|
|
92
|
+
set_request_context(child_context)
|
|
93
|
+
|
|
94
|
+
return fn(*args, **kwargs)
|
|
95
|
+
|
|
96
|
+
return super().map(wrapper, *iterables, timeout=timeout, chunksize=chunksize)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import os
|
|
3
2
|
|
|
4
3
|
from fastapi import Depends, Header, Request
|
|
5
4
|
|
|
@@ -25,13 +24,6 @@ def get_trace_id_from_header(
|
|
|
25
24
|
return g_trace_id or x_trace_id or trace_id
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
def generate_trace_id() -> str:
|
|
29
|
-
"""
|
|
30
|
-
Get a random trace_id.
|
|
31
|
-
"""
|
|
32
|
-
return os.urandom(16).hex()
|
|
33
|
-
|
|
34
|
-
|
|
35
27
|
def get_request_context(
|
|
36
28
|
request: Request, trace_id: str | None = Depends(get_trace_id_from_header)
|
|
37
29
|
) -> RequestContext:
|
|
@@ -65,9 +57,6 @@ def get_g_object(trace_id: str | None = Depends(get_trace_id_from_header)) -> G:
|
|
|
65
57
|
This creates a RequestContext and sets it globally for access
|
|
66
58
|
throughout the request lifecycle.
|
|
67
59
|
"""
|
|
68
|
-
if trace_id is None:
|
|
69
|
-
trace_id = generate_trace_id()
|
|
70
|
-
|
|
71
60
|
g = RequestContext(trace_id=trace_id)
|
|
72
61
|
set_request_context(g)
|
|
73
62
|
logger.info(f"Request g object created with trace_id: {g.trace_id}")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Request context middleware for automatic trace_id injection.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
|
|
10
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
11
|
+
from starlette.requests import Request
|
|
12
|
+
from starlette.responses import Response
|
|
13
|
+
|
|
14
|
+
from memos.api.context.context import RequestContext, set_request_context
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def generate_trace_id() -> str:
|
|
21
|
+
"""Generate a random trace_id."""
|
|
22
|
+
return os.urandom(16).hex()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def extract_trace_id_from_headers(request: Request) -> str | None:
|
|
26
|
+
"""Extract trace_id from various possible headers with priority: g-trace-id > x-trace-id > trace-id."""
|
|
27
|
+
trace_id = request.headers.get("g-trace-id")
|
|
28
|
+
if trace_id:
|
|
29
|
+
return trace_id
|
|
30
|
+
|
|
31
|
+
trace_id = request.headers.get("x-trace-id")
|
|
32
|
+
if trace_id:
|
|
33
|
+
return trace_id
|
|
34
|
+
|
|
35
|
+
trace_id = request.headers.get("trace-id")
|
|
36
|
+
if trace_id:
|
|
37
|
+
return trace_id
|
|
38
|
+
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class RequestContextMiddleware(BaseHTTPMiddleware):
|
|
43
|
+
"""
|
|
44
|
+
Middleware to automatically inject request context for every HTTP request.
|
|
45
|
+
|
|
46
|
+
This middleware:
|
|
47
|
+
1. Extracts trace_id from headers or generates a new one
|
|
48
|
+
2. Creates a RequestContext and sets it globally
|
|
49
|
+
3. Ensures the context is available throughout the request lifecycle
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
53
|
+
# Extract or generate trace_id
|
|
54
|
+
trace_id = extract_trace_id_from_headers(request)
|
|
55
|
+
if not trace_id:
|
|
56
|
+
trace_id = generate_trace_id()
|
|
57
|
+
|
|
58
|
+
# Create and set request context
|
|
59
|
+
context = RequestContext(trace_id=trace_id)
|
|
60
|
+
set_request_context(context)
|
|
61
|
+
|
|
62
|
+
# Add request metadata to context
|
|
63
|
+
context.set("method", request.method)
|
|
64
|
+
context.set("path", request.url.path)
|
|
65
|
+
context.set("client_ip", request.client.host if request.client else None)
|
|
66
|
+
|
|
67
|
+
# Log request start with parameters
|
|
68
|
+
params_log = {}
|
|
69
|
+
|
|
70
|
+
# Get query parameters
|
|
71
|
+
if request.query_params:
|
|
72
|
+
params_log["query_params"] = dict(request.query_params)
|
|
73
|
+
|
|
74
|
+
# Get request body if it's available
|
|
75
|
+
try:
|
|
76
|
+
params_log = await request.json()
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.error(f"Error getting request body: {e}")
|
|
79
|
+
# If body is not JSON or empty, ignore it
|
|
80
|
+
|
|
81
|
+
logger.info(
|
|
82
|
+
f"Request started: {request.method} {request.url.path} - Parameters: {params_log}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Process the request
|
|
86
|
+
response = await call_next(request)
|
|
87
|
+
|
|
88
|
+
# Log request completion with output
|
|
89
|
+
logger.info(f"Request completed: {request.url.path}, status: {response.status_code}")
|
|
90
|
+
|
|
91
|
+
# Add trace_id to response headers for debugging
|
|
92
|
+
response.headers["x-trace-id"] = trace_id
|
|
93
|
+
|
|
94
|
+
return response
|
memos/api/product_api.py
CHANGED
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
from fastapi import FastAPI
|
|
4
4
|
|
|
5
5
|
from memos.api.exceptions import APIExceptionHandler
|
|
6
|
+
from memos.api.middleware.request_context import RequestContextMiddleware
|
|
6
7
|
from memos.api.routers.product_router import router as product_router
|
|
7
8
|
|
|
8
9
|
|
|
@@ -13,9 +14,12 @@ logger = logging.getLogger(__name__)
|
|
|
13
14
|
app = FastAPI(
|
|
14
15
|
title="MemOS Product REST APIs",
|
|
15
16
|
description="A REST API for managing multiple users with MemOS Product.",
|
|
16
|
-
version="1.0.
|
|
17
|
+
version="1.0.1",
|
|
17
18
|
)
|
|
18
19
|
|
|
20
|
+
# Add request context middleware (must be added first)
|
|
21
|
+
app.add_middleware(RequestContextMiddleware)
|
|
22
|
+
|
|
19
23
|
# Include routers
|
|
20
24
|
app.include_router(product_router)
|
|
21
25
|
|
memos/api/product_models.py
CHANGED
|
@@ -84,6 +84,21 @@ class ChatRequest(BaseRequest):
|
|
|
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
86
|
internet_search: bool = Field(True, description="Whether to use internet search")
|
|
87
|
+
moscube: bool = Field(False, description="Whether to use MemOSCube")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ChatCompleteRequest(BaseRequest):
|
|
91
|
+
"""Request model for chat operations."""
|
|
92
|
+
|
|
93
|
+
user_id: str = Field(..., description="User ID")
|
|
94
|
+
query: str = Field(..., description="Chat query message")
|
|
95
|
+
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
|
|
96
|
+
history: list[MessageDict] | None = Field(None, description="Chat history")
|
|
97
|
+
internet_search: bool = Field(False, description="Whether to use internet search")
|
|
98
|
+
moscube: bool = Field(False, description="Whether to use MemOSCube")
|
|
99
|
+
base_prompt: str | None = Field(None, description="Base prompt to use for chat")
|
|
100
|
+
top_k: int = Field(10, description="Number of results to return")
|
|
101
|
+
threshold: float = Field(0.5, description="Threshold for filtering references")
|
|
87
102
|
|
|
88
103
|
|
|
89
104
|
class UserCreate(BaseRequest):
|
|
@@ -161,3 +176,4 @@ class SuggestionRequest(BaseRequest):
|
|
|
161
176
|
|
|
162
177
|
user_id: str = Field(..., description="User ID")
|
|
163
178
|
language: Literal["zh", "en"] = Field("zh", description="Language for suggestions")
|
|
179
|
+
message: list[MessageDict] | None = Field(None, description="List of messages to store.")
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import logging
|
|
3
2
|
import traceback
|
|
4
3
|
|
|
5
4
|
from datetime import datetime
|
|
@@ -12,6 +11,7 @@ from memos.api.config import APIConfig
|
|
|
12
11
|
from memos.api.context.dependencies import G, get_g_object
|
|
13
12
|
from memos.api.product_models import (
|
|
14
13
|
BaseResponse,
|
|
14
|
+
ChatCompleteRequest,
|
|
15
15
|
ChatRequest,
|
|
16
16
|
GetMemoryRequest,
|
|
17
17
|
MemoryCreateRequest,
|
|
@@ -25,11 +25,12 @@ from memos.api.product_models import (
|
|
|
25
25
|
UserRegisterResponse,
|
|
26
26
|
)
|
|
27
27
|
from memos.configs.mem_os import MOSConfig
|
|
28
|
+
from memos.log import get_logger
|
|
28
29
|
from memos.mem_os.product import MOSProduct
|
|
29
30
|
from memos.memos_tools.notification_service import get_error_bot_function, get_online_bot_function
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
logger =
|
|
33
|
+
logger = get_logger(__name__)
|
|
33
34
|
|
|
34
35
|
router = APIRouter(prefix="/product", tags=["Product API"])
|
|
35
36
|
|
|
@@ -148,7 +149,9 @@ def get_suggestion_queries_post(suggestion_req: SuggestionRequest):
|
|
|
148
149
|
try:
|
|
149
150
|
mos_product = get_mos_product_instance()
|
|
150
151
|
suggestions = mos_product.get_suggestion_query(
|
|
151
|
-
user_id=suggestion_req.user_id,
|
|
152
|
+
user_id=suggestion_req.user_id,
|
|
153
|
+
language=suggestion_req.language,
|
|
154
|
+
message=suggestion_req.message,
|
|
152
155
|
)
|
|
153
156
|
return SuggestionResponse(
|
|
154
157
|
message="Suggestions retrieved successfully", data={"query": suggestions}
|
|
@@ -246,6 +249,7 @@ def chat(chat_req: ChatRequest):
|
|
|
246
249
|
cube_id=chat_req.mem_cube_id,
|
|
247
250
|
history=chat_req.history,
|
|
248
251
|
internet_search=chat_req.internet_search,
|
|
252
|
+
moscube=chat_req.moscube,
|
|
249
253
|
)
|
|
250
254
|
|
|
251
255
|
except Exception as e:
|
|
@@ -273,6 +277,38 @@ def chat(chat_req: ChatRequest):
|
|
|
273
277
|
raise HTTPException(status_code=500, detail=str(traceback.format_exc())) from err
|
|
274
278
|
|
|
275
279
|
|
|
280
|
+
@router.post("/chat/complete", summary="Chat with MemOS (Complete Response)")
|
|
281
|
+
def chat_complete(chat_req: ChatCompleteRequest):
|
|
282
|
+
"""Chat with MemOS for a specific user. Returns complete response (non-streaming)."""
|
|
283
|
+
try:
|
|
284
|
+
mos_product = get_mos_product_instance()
|
|
285
|
+
|
|
286
|
+
# Collect all responses from the generator
|
|
287
|
+
content, references = mos_product.chat(
|
|
288
|
+
query=chat_req.query,
|
|
289
|
+
user_id=chat_req.user_id,
|
|
290
|
+
cube_id=chat_req.mem_cube_id,
|
|
291
|
+
history=chat_req.history,
|
|
292
|
+
internet_search=chat_req.internet_search,
|
|
293
|
+
moscube=chat_req.moscube,
|
|
294
|
+
base_prompt=chat_req.base_prompt,
|
|
295
|
+
top_k=chat_req.top_k,
|
|
296
|
+
threshold=chat_req.threshold,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
# Return the complete response
|
|
300
|
+
return {
|
|
301
|
+
"message": "Chat completed successfully",
|
|
302
|
+
"data": {"response": content, "references": references},
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
except ValueError as err:
|
|
306
|
+
raise HTTPException(status_code=404, detail=str(traceback.format_exc())) from err
|
|
307
|
+
except Exception as err:
|
|
308
|
+
logger.error(f"Failed to start chat: {traceback.format_exc()}")
|
|
309
|
+
raise HTTPException(status_code=500, detail=str(traceback.format_exc())) from err
|
|
310
|
+
|
|
311
|
+
|
|
276
312
|
@router.get("/users", summary="List all users", response_model=BaseResponse[list])
|
|
277
313
|
def list_users():
|
|
278
314
|
"""List all registered users."""
|
memos/api/start_api.py
CHANGED
|
@@ -9,6 +9,7 @@ from fastapi.requests import Request
|
|
|
9
9
|
from fastapi.responses import JSONResponse, RedirectResponse
|
|
10
10
|
from pydantic import BaseModel, Field
|
|
11
11
|
|
|
12
|
+
from memos.api.middleware.request_context import RequestContextMiddleware
|
|
12
13
|
from memos.configs.mem_os import MOSConfig
|
|
13
14
|
from memos.mem_os.main import MOS
|
|
14
15
|
from memos.mem_user.user_manager import UserManager, UserRole
|
|
@@ -78,6 +79,8 @@ app = FastAPI(
|
|
|
78
79
|
version="1.0.0",
|
|
79
80
|
)
|
|
80
81
|
|
|
82
|
+
app.add_middleware(RequestContextMiddleware)
|
|
83
|
+
|
|
81
84
|
|
|
82
85
|
class BaseRequest(BaseModel):
|
|
83
86
|
"""Base model for all requests."""
|
memos/configs/memory.py
CHANGED
|
@@ -7,6 +7,7 @@ from memos.configs.embedder import EmbedderConfigFactory
|
|
|
7
7
|
from memos.configs.graph_db import GraphDBConfigFactory
|
|
8
8
|
from memos.configs.internet_retriever import InternetRetrieverConfigFactory
|
|
9
9
|
from memos.configs.llm import LLMConfigFactory
|
|
10
|
+
from memos.configs.reranker import RerankerConfigFactory
|
|
10
11
|
from memos.configs.vec_db import VectorDBConfigFactory
|
|
11
12
|
from memos.exceptions import ConfigurationError
|
|
12
13
|
|
|
@@ -151,6 +152,10 @@ class TreeTextMemoryConfig(BaseTextMemoryConfig):
|
|
|
151
152
|
default_factory=EmbedderConfigFactory,
|
|
152
153
|
description="Embedder configuration for the memory embedding",
|
|
153
154
|
)
|
|
155
|
+
reranker: RerankerConfigFactory | None = Field(
|
|
156
|
+
None,
|
|
157
|
+
description="Reranker configuration (optional, defaults to cosine_local).",
|
|
158
|
+
)
|
|
154
159
|
graph_db: GraphDBConfigFactory = Field(
|
|
155
160
|
...,
|
|
156
161
|
default_factory=GraphDBConfigFactory,
|
|
@@ -166,6 +171,14 @@ class TreeTextMemoryConfig(BaseTextMemoryConfig):
|
|
|
166
171
|
description="Optional description for this memory configuration.",
|
|
167
172
|
)
|
|
168
173
|
|
|
174
|
+
memory_size: dict[str, Any] | None = Field(
|
|
175
|
+
default=None,
|
|
176
|
+
description=(
|
|
177
|
+
"Maximum item counts per memory bucket, e.g.: "
|
|
178
|
+
'{"WorkingMemory": 20, "LongTermMemory": 10000, "UserMemory": 10000}'
|
|
179
|
+
),
|
|
180
|
+
)
|
|
181
|
+
|
|
169
182
|
|
|
170
183
|
# ─── 3. Global Memory Config Factory ──────────────────────────────────────────
|
|
171
184
|
|