MemoryOS 0.2.0__py3-none-any.whl → 0.2.2__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.

Files changed (114) hide show
  1. {memoryos-0.2.0.dist-info → memoryos-0.2.2.dist-info}/METADATA +67 -26
  2. memoryos-0.2.2.dist-info/RECORD +169 -0
  3. memoryos-0.2.2.dist-info/entry_points.txt +3 -0
  4. memos/__init__.py +1 -1
  5. memos/api/config.py +562 -0
  6. memos/api/context/context.py +147 -0
  7. memos/api/context/dependencies.py +90 -0
  8. memos/api/exceptions.py +28 -0
  9. memos/api/mcp_serve.py +502 -0
  10. memos/api/product_api.py +35 -0
  11. memos/api/product_models.py +163 -0
  12. memos/api/routers/__init__.py +1 -0
  13. memos/api/routers/product_router.py +386 -0
  14. memos/chunkers/sentence_chunker.py +8 -2
  15. memos/cli.py +113 -0
  16. memos/configs/embedder.py +27 -0
  17. memos/configs/graph_db.py +132 -3
  18. memos/configs/internet_retriever.py +6 -0
  19. memos/configs/llm.py +47 -0
  20. memos/configs/mem_cube.py +1 -1
  21. memos/configs/mem_os.py +5 -0
  22. memos/configs/mem_reader.py +9 -0
  23. memos/configs/mem_scheduler.py +107 -7
  24. memos/configs/mem_user.py +58 -0
  25. memos/configs/memory.py +5 -4
  26. memos/dependency.py +52 -0
  27. memos/embedders/ark.py +92 -0
  28. memos/embedders/factory.py +4 -0
  29. memos/embedders/sentence_transformer.py +8 -2
  30. memos/embedders/universal_api.py +32 -0
  31. memos/graph_dbs/base.py +11 -3
  32. memos/graph_dbs/factory.py +4 -0
  33. memos/graph_dbs/nebular.py +1364 -0
  34. memos/graph_dbs/neo4j.py +333 -124
  35. memos/graph_dbs/neo4j_community.py +300 -0
  36. memos/llms/base.py +9 -0
  37. memos/llms/deepseek.py +54 -0
  38. memos/llms/factory.py +10 -1
  39. memos/llms/hf.py +170 -13
  40. memos/llms/hf_singleton.py +114 -0
  41. memos/llms/ollama.py +4 -0
  42. memos/llms/openai.py +67 -1
  43. memos/llms/qwen.py +63 -0
  44. memos/llms/vllm.py +153 -0
  45. memos/log.py +1 -1
  46. memos/mem_cube/general.py +77 -16
  47. memos/mem_cube/utils.py +109 -0
  48. memos/mem_os/core.py +251 -51
  49. memos/mem_os/main.py +94 -12
  50. memos/mem_os/product.py +1220 -43
  51. memos/mem_os/utils/default_config.py +352 -0
  52. memos/mem_os/utils/format_utils.py +1401 -0
  53. memos/mem_reader/simple_struct.py +18 -10
  54. memos/mem_scheduler/base_scheduler.py +441 -40
  55. memos/mem_scheduler/general_scheduler.py +249 -248
  56. memos/mem_scheduler/modules/base.py +14 -5
  57. memos/mem_scheduler/modules/dispatcher.py +67 -4
  58. memos/mem_scheduler/modules/misc.py +104 -0
  59. memos/mem_scheduler/modules/monitor.py +240 -50
  60. memos/mem_scheduler/modules/rabbitmq_service.py +319 -0
  61. memos/mem_scheduler/modules/redis_service.py +32 -22
  62. memos/mem_scheduler/modules/retriever.py +167 -23
  63. memos/mem_scheduler/modules/scheduler_logger.py +255 -0
  64. memos/mem_scheduler/mos_for_test_scheduler.py +140 -0
  65. memos/mem_scheduler/schemas/__init__.py +0 -0
  66. memos/mem_scheduler/schemas/general_schemas.py +43 -0
  67. memos/mem_scheduler/{modules/schemas.py → schemas/message_schemas.py} +63 -61
  68. memos/mem_scheduler/schemas/monitor_schemas.py +329 -0
  69. memos/mem_scheduler/utils/__init__.py +0 -0
  70. memos/mem_scheduler/utils/filter_utils.py +176 -0
  71. memos/mem_scheduler/utils/misc_utils.py +61 -0
  72. memos/mem_user/factory.py +94 -0
  73. memos/mem_user/mysql_persistent_user_manager.py +271 -0
  74. memos/mem_user/mysql_user_manager.py +500 -0
  75. memos/mem_user/persistent_factory.py +96 -0
  76. memos/mem_user/persistent_user_manager.py +260 -0
  77. memos/mem_user/user_manager.py +4 -4
  78. memos/memories/activation/item.py +29 -0
  79. memos/memories/activation/kv.py +10 -3
  80. memos/memories/activation/vllmkv.py +219 -0
  81. memos/memories/factory.py +2 -0
  82. memos/memories/textual/base.py +1 -1
  83. memos/memories/textual/general.py +43 -97
  84. memos/memories/textual/item.py +5 -33
  85. memos/memories/textual/tree.py +22 -12
  86. memos/memories/textual/tree_text_memory/organize/conflict.py +9 -5
  87. memos/memories/textual/tree_text_memory/organize/manager.py +26 -18
  88. memos/memories/textual/tree_text_memory/organize/redundancy.py +25 -44
  89. memos/memories/textual/tree_text_memory/organize/relation_reason_detector.py +50 -48
  90. memos/memories/textual/tree_text_memory/organize/reorganizer.py +81 -56
  91. memos/memories/textual/tree_text_memory/retrieve/internet_retriever.py +6 -3
  92. memos/memories/textual/tree_text_memory/retrieve/internet_retriever_factory.py +2 -0
  93. memos/memories/textual/tree_text_memory/retrieve/recall.py +0 -1
  94. memos/memories/textual/tree_text_memory/retrieve/reranker.py +2 -2
  95. memos/memories/textual/tree_text_memory/retrieve/retrieval_mid_structs.py +2 -0
  96. memos/memories/textual/tree_text_memory/retrieve/searcher.py +52 -28
  97. memos/memories/textual/tree_text_memory/retrieve/task_goal_parser.py +42 -15
  98. memos/memories/textual/tree_text_memory/retrieve/utils.py +11 -7
  99. memos/memories/textual/tree_text_memory/retrieve/xinyusearch.py +62 -58
  100. memos/memos_tools/dinding_report_bot.py +422 -0
  101. memos/memos_tools/notification_service.py +44 -0
  102. memos/memos_tools/notification_utils.py +96 -0
  103. memos/parsers/markitdown.py +8 -2
  104. memos/settings.py +3 -1
  105. memos/templates/mem_reader_prompts.py +66 -23
  106. memos/templates/mem_scheduler_prompts.py +126 -43
  107. memos/templates/mos_prompts.py +87 -0
  108. memos/templates/tree_reorganize_prompts.py +85 -30
  109. memos/vec_dbs/base.py +12 -0
  110. memos/vec_dbs/qdrant.py +46 -20
  111. memoryos-0.2.0.dist-info/RECORD +0 -128
  112. memos/mem_scheduler/utils.py +0 -26
  113. {memoryos-0.2.0.dist-info → memoryos-0.2.2.dist-info}/LICENSE +0 -0
  114. {memoryos-0.2.0.dist-info → memoryos-0.2.2.dist-info}/WHEEL +0 -0
@@ -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()
@@ -0,0 +1,28 @@
1
+ import logging
2
+
3
+ from fastapi.requests import Request
4
+ from fastapi.responses import JSONResponse
5
+
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class APIExceptionHandler:
11
+ """Centralized exception handling for MemOS APIs."""
12
+
13
+ @staticmethod
14
+ async def value_error_handler(request: Request, exc: ValueError):
15
+ """Handle ValueError exceptions globally."""
16
+ return JSONResponse(
17
+ status_code=400,
18
+ content={"code": 400, "message": str(exc), "data": None},
19
+ )
20
+
21
+ @staticmethod
22
+ async def global_exception_handler(request: Request, exc: Exception):
23
+ """Handle all unhandled exceptions globally."""
24
+ logger.exception("Unhandled error:")
25
+ return JSONResponse(
26
+ status_code=500,
27
+ content={"code": 500, "message": str(exc), "data": None},
28
+ )