mdb-engine 0.7.2__py3-none-any.whl → 0.7.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.
- mdb_engine/__init__.py +1 -9
- mdb_engine/cli/main.py +1 -1
- mdb_engine/memory/service.py +30 -50
- mdb_engine/routing/websockets.py +45 -6
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/METADATA +1 -15
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/RECORD +10 -10
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/WHEEL +0 -0
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/entry_points.txt +0 -0
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/licenses/LICENSE +0 -0
- {mdb_engine-0.7.2.dist-info → mdb_engine-0.7.3.dist-info}/top_level.txt +0 -0
mdb_engine/__init__.py
CHANGED
|
@@ -81,15 +81,7 @@ from .repositories import Entity, MongoRepository, Repository, UnitOfWork
|
|
|
81
81
|
# Utilities
|
|
82
82
|
from .utils import clean_mongo_doc, clean_mongo_docs
|
|
83
83
|
|
|
84
|
-
__version__ =
|
|
85
|
-
"0.7.2" # Memory service update functionality
|
|
86
|
-
# - ADDED: Memory service update() method for in-place memory updates
|
|
87
|
-
# - ADDED: Support for updating memory content and metadata while preserving IDs
|
|
88
|
-
# - ADDED: Automatic embedding recomputation via Mem0's update method
|
|
89
|
-
# - ADDED: Comprehensive unit tests for memory update functionality (17 tests)
|
|
90
|
-
# - ENHANCED: Memory service now uses Mem0's native update method exclusively
|
|
91
|
-
# - REMOVED: Direct MongoDB update fallback (simplified implementation)
|
|
92
|
-
)
|
|
84
|
+
__version__ = "0.7.3"
|
|
93
85
|
|
|
94
86
|
__all__ = [
|
|
95
87
|
# Core Engine
|
mdb_engine/cli/main.py
CHANGED
mdb_engine/memory/service.py
CHANGED
|
@@ -268,10 +268,13 @@ class Mem0MemoryService:
|
|
|
268
268
|
if isinstance(messages, str):
|
|
269
269
|
messages = [{"role": "user", "content": messages}]
|
|
270
270
|
|
|
271
|
-
# Merge metadata
|
|
272
271
|
final_metadata = dict(metadata) if metadata else {}
|
|
273
272
|
|
|
274
273
|
# CRITICAL: Database indexing relies on these fields being in metadata
|
|
274
|
+
# Include user_id in metadata ONLY if provided (supports non-SSO use cases)
|
|
275
|
+
if user_id:
|
|
276
|
+
final_metadata["user_id"] = str(user_id)
|
|
277
|
+
|
|
275
278
|
if bucket_id:
|
|
276
279
|
final_metadata["bucket_id"] = bucket_id
|
|
277
280
|
final_metadata["context_id"] = bucket_id # Backwards compatibility
|
|
@@ -279,7 +282,6 @@ class Mem0MemoryService:
|
|
|
279
282
|
if bucket_type:
|
|
280
283
|
final_metadata["bucket_type"] = bucket_type
|
|
281
284
|
|
|
282
|
-
# Store raw_content in metadata if provided (metadata convenience)
|
|
283
285
|
if raw_content:
|
|
284
286
|
final_metadata["raw_content"] = raw_content
|
|
285
287
|
|
|
@@ -502,12 +504,12 @@ class Mem0MemoryService:
|
|
|
502
504
|
memory_id: The ID of the memory to update (required)
|
|
503
505
|
user_id: The user ID who owns the memory (for scoping and security)
|
|
504
506
|
memory: New memory content as a string (optional)
|
|
505
|
-
data: Alternative parameter name for memory content
|
|
507
|
+
data: Alternative parameter name for memory content.
|
|
506
508
|
Can be a string or dict with 'memory'/'text'/'content' key.
|
|
507
509
|
messages: Alternative way to provide content as messages (optional).
|
|
508
510
|
Can be a string or list of dicts with 'content' key.
|
|
509
|
-
metadata: Metadata updates
|
|
510
|
-
|
|
511
|
+
metadata: Metadata updates (optional, but NOT SUPPORTED by Mem0 update API).
|
|
512
|
+
This parameter is accepted for API consistency but will be ignored.
|
|
511
513
|
**kwargs: Additional arguments passed to Mem0 operations
|
|
512
514
|
|
|
513
515
|
Returns:
|
|
@@ -535,16 +537,14 @@ class Mem0MemoryService:
|
|
|
535
537
|
)
|
|
536
538
|
```
|
|
537
539
|
"""
|
|
538
|
-
# Input validation
|
|
539
540
|
if not memory_id or not isinstance(memory_id, str) or not memory_id.strip():
|
|
540
541
|
raise ValueError("memory_id is required and must be a non-empty string")
|
|
541
542
|
|
|
542
543
|
try:
|
|
543
|
-
# Normalize data parameter (
|
|
544
|
+
# Normalize data parameter (alternative to memory parameter)
|
|
544
545
|
normalized_memory = self._normalize_content_input(memory, data, messages)
|
|
545
546
|
normalized_metadata = self._normalize_metadata_input(metadata, data)
|
|
546
547
|
|
|
547
|
-
# Verify memory exists before attempting update
|
|
548
548
|
existing_memory = self.get(memory_id=memory_id, user_id=user_id, **kwargs)
|
|
549
549
|
if not existing_memory:
|
|
550
550
|
logger.warning(
|
|
@@ -675,46 +675,21 @@ class Mem0MemoryService:
|
|
|
675
675
|
"""
|
|
676
676
|
Update memory using Mem0's built-in update method.
|
|
677
677
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
- Automatic embedding recomputation when content changes
|
|
681
|
-
- Metadata merging
|
|
682
|
-
- User scoping for security
|
|
678
|
+
Note: Mem0's update() only supports content updates (text parameter).
|
|
679
|
+
Metadata updates are not supported by the Mem0 API.
|
|
683
680
|
|
|
684
681
|
Args:
|
|
685
682
|
memory_id: Memory ID to update
|
|
686
|
-
user_id: User ID for scoping
|
|
683
|
+
user_id: User ID for scoping (not used in update call)
|
|
687
684
|
memory: New memory content (normalized)
|
|
688
|
-
metadata: Metadata to merge (
|
|
685
|
+
metadata: Metadata to merge (ignored - not supported by Mem0 update API)
|
|
689
686
|
**kwargs: Additional arguments passed to Mem0
|
|
690
687
|
|
|
691
688
|
Returns:
|
|
692
689
|
Updated memory dict or None if not found
|
|
693
|
-
|
|
694
|
-
Raises:
|
|
695
|
-
Various exceptions from Mem0 if update fails
|
|
696
690
|
"""
|
|
697
|
-
#
|
|
698
|
-
|
|
699
|
-
# update(memory_id, text=None, metadata=None, user_id=None, **kwargs)
|
|
700
|
-
update_kwargs: dict[str, Any] = {"memory_id": memory_id}
|
|
701
|
-
|
|
702
|
-
# Add user_id for scoping (Mem0 supports this)
|
|
703
|
-
if user_id:
|
|
704
|
-
update_kwargs["user_id"] = str(user_id)
|
|
705
|
-
|
|
706
|
-
# Add text/content if provided
|
|
707
|
-
# Mem0 uses "text" parameter for content
|
|
708
|
-
if memory:
|
|
709
|
-
update_kwargs["text"] = memory
|
|
710
|
-
|
|
711
|
-
# Add metadata if provided
|
|
712
|
-
# Mem0 merges metadata automatically
|
|
713
|
-
if metadata is not None:
|
|
714
|
-
update_kwargs["metadata"] = metadata
|
|
715
|
-
|
|
716
|
-
# Pass through any additional kwargs
|
|
717
|
-
update_kwargs.update(kwargs)
|
|
691
|
+
# Filter out user_id from kwargs to prevent passing it as a direct parameter
|
|
692
|
+
filtered_kwargs = {k: v for k, v in kwargs.items() if k != "user_id"}
|
|
718
693
|
|
|
719
694
|
logger.debug(
|
|
720
695
|
f"Calling mem0.update() for memory_id={memory_id}",
|
|
@@ -726,24 +701,29 @@ class Mem0MemoryService:
|
|
|
726
701
|
},
|
|
727
702
|
)
|
|
728
703
|
|
|
729
|
-
|
|
730
|
-
|
|
704
|
+
if metadata:
|
|
705
|
+
logger.warning(
|
|
706
|
+
f"Metadata update requested for memory {memory_id} but Mem0 update() "
|
|
707
|
+
f"does not support metadata parameter. Metadata will not be updated."
|
|
708
|
+
)
|
|
709
|
+
|
|
710
|
+
update_kwargs = {"memory_id": memory_id}
|
|
711
|
+
if memory:
|
|
712
|
+
update_kwargs["data"] = memory
|
|
713
|
+
update_kwargs.update(filtered_kwargs)
|
|
714
|
+
|
|
731
715
|
result = self.memory.update(**update_kwargs)
|
|
732
716
|
|
|
733
|
-
#
|
|
734
|
-
#
|
|
717
|
+
# Note: Mem0's update() doesn't support metadata parameter
|
|
718
|
+
# Metadata updates would require direct MongoDB access, which we avoid
|
|
719
|
+
|
|
720
|
+
# Normalize result to dict
|
|
735
721
|
if isinstance(result, dict):
|
|
736
722
|
return result
|
|
737
723
|
elif isinstance(result, list) and len(result) > 0:
|
|
738
|
-
# If list, return first item
|
|
739
724
|
return result[0] if isinstance(result[0], dict) else None
|
|
740
725
|
else:
|
|
741
|
-
|
|
742
|
-
logger.debug(
|
|
743
|
-
f"Mem0 update returned unexpected format: {type(result)}",
|
|
744
|
-
extra={"memory_id": memory_id},
|
|
745
|
-
)
|
|
746
|
-
return None
|
|
726
|
+
return self.get(memory_id=memory_id)
|
|
747
727
|
|
|
748
728
|
def _normalize_result(self, result: Any) -> list[dict[str, Any]]:
|
|
749
729
|
"""Normalize Mem0's return type (dict vs list)."""
|
mdb_engine/routing/websockets.py
CHANGED
|
@@ -472,19 +472,58 @@ async def _validate_websocket_origin_in_handler(websocket: Any, app_slug: str) -
|
|
|
472
472
|
|
|
473
473
|
# Normalize origin for comparison
|
|
474
474
|
def normalize_origin(orig: str) -> str:
|
|
475
|
-
"""
|
|
475
|
+
"""
|
|
476
|
+
Normalize origin handling localhost variants and protocol differences.
|
|
477
|
+
|
|
478
|
+
Handles:
|
|
479
|
+
- Protocol conversion: ws/wss -> http/https (browsers send http/https)
|
|
480
|
+
- Localhost normalization: 127.0.0.1, 0.0.0.0, ::1 -> localhost
|
|
481
|
+
- Docker IP normalization: container IPs -> localhost (in development)
|
|
482
|
+
- Port normalization: removes :80 and :443
|
|
483
|
+
"""
|
|
476
484
|
if not orig:
|
|
477
485
|
return orig
|
|
486
|
+
import os
|
|
478
487
|
import re
|
|
479
488
|
|
|
480
|
-
normalized =
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
489
|
+
normalized = orig.lower()
|
|
490
|
+
|
|
491
|
+
# Normalize protocol: convert ws/wss to http/https for comparison
|
|
492
|
+
# WebSocket origins come as http/https from browsers, but configs may use ws/wss
|
|
493
|
+
normalized = re.sub(r"^ws://", "http://", normalized)
|
|
494
|
+
normalized = re.sub(r"^wss://", "https://", normalized)
|
|
495
|
+
|
|
496
|
+
# Check if we're in development/Docker environment
|
|
497
|
+
is_dev = (
|
|
498
|
+
os.getenv("ENVIRONMENT", "").lower() in ["development", "dev"]
|
|
499
|
+
or os.getenv("G_NOME_ENV", "").lower() in ["development", "dev"]
|
|
500
|
+
or os.path.exists("/.dockerenv") # Docker container indicator
|
|
485
501
|
)
|
|
502
|
+
|
|
503
|
+
# Normalize localhost variants
|
|
504
|
+
# In development/Docker, also normalize common Docker IP ranges to localhost
|
|
505
|
+
if is_dev:
|
|
506
|
+
# Match localhost, 127.0.0.1, 0.0.0.0, ::1, and Docker container IPs
|
|
507
|
+
# Docker typically uses 172.17.0.0/16 or 172.20.0.0/16
|
|
508
|
+
normalized = re.sub(
|
|
509
|
+
r"://(0\.0\.0\.0|127\.0\.0\.1|localhost|::1|172\.(17|20)\.\d+\.\d+)",
|
|
510
|
+
"://localhost",
|
|
511
|
+
normalized,
|
|
512
|
+
flags=re.IGNORECASE,
|
|
513
|
+
)
|
|
514
|
+
else:
|
|
515
|
+
# Production: only normalize standard localhost variants
|
|
516
|
+
normalized = re.sub(
|
|
517
|
+
r"://(0\.0\.0\.0|127\.0\.0\.1|localhost|::1)",
|
|
518
|
+
"://localhost",
|
|
519
|
+
normalized,
|
|
520
|
+
flags=re.IGNORECASE,
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
# Remove default ports
|
|
486
524
|
normalized = re.sub(r":80$", "", normalized)
|
|
487
525
|
normalized = re.sub(r":443$", "", normalized)
|
|
526
|
+
|
|
488
527
|
return normalized.rstrip("/")
|
|
489
528
|
|
|
490
529
|
normalized_origin = normalize_origin(origin)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mdb-engine
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: MongoDB Engine
|
|
5
5
|
Home-page: https://github.com/ranfysvalle02/mdb-engine
|
|
6
6
|
Author: Fabian Valle
|
|
@@ -72,20 +72,6 @@ Dynamic: requires-python
|
|
|
72
72
|
[](https://www.python.org/downloads/)
|
|
73
73
|
[](https://opensource.org/licenses/AGPL-3.0)
|
|
74
74
|
|
|
75
|
-
## 🎉 What's New in v0.7.0
|
|
76
|
-
|
|
77
|
-
**FastAPI Native WebSocket Support**: MDB-Engine now uses FastAPI's `APIRouter` approach for WebSocket registration in both single-app and multi-app modes. This provides:
|
|
78
|
-
|
|
79
|
-
- ✅ **Full FastAPI Feature Support**: Dependency injection, OpenAPI documentation, request/response models
|
|
80
|
-
- ✅ **Consistency**: Same registration pattern across single-app and multi-app modes
|
|
81
|
-
- ✅ **Best Practices**: Follows FastAPI's recommended WebSocket registration patterns
|
|
82
|
-
- ✅ **Better Maintainability**: Uses FastAPI abstractions instead of low-level Starlette APIs
|
|
83
|
-
- ✅ **Route Priority**: WebSocket routes registered before mounted apps ensure proper routing
|
|
84
|
-
|
|
85
|
-
**Value**: This change ensures WebSocket endpoints benefit from all FastAPI features, making your code more maintainable and consistent with FastAPI best practices.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
75
|
## 🎯 manifest.json: The Key to Everything
|
|
90
76
|
|
|
91
77
|
**`manifest.json` is the foundation of your application.** It's a single configuration file that defines your app's identity, data structure, authentication, indexes, and services. Everything flows from this file.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
mdb_engine/README.md,sha256=T3EFGcPopY9LslYW3lxgG3hohWkAOmBNbYG0FDMUJiY,3502
|
|
2
|
-
mdb_engine/__init__.py,sha256=
|
|
2
|
+
mdb_engine/__init__.py,sha256=AwWt-MyzGNDl_2YEkTO0-x15qnUw3tF-oiOJJAYGkIs,3097
|
|
3
3
|
mdb_engine/config.py,sha256=DTAyxfKB8ogyI0v5QR9Y-SJOgXQr_eDBCKxNBSqEyLc,7269
|
|
4
4
|
mdb_engine/constants.py,sha256=eaotvW57TVOg7rRbLziGrVNoP7adgw_G9iVByHezc_A,7837
|
|
5
5
|
mdb_engine/dependencies.py,sha256=MJuYQhZ9ZGzXlip1ha5zba9Rvn04HDPWahJFJH81Q2s,14107
|
|
@@ -35,7 +35,7 @@ mdb_engine/auth/utils.py,sha256=YkexCo0xV37mpOJUI32cntRHVOUUS7r19TIMPWHcgpA,2734
|
|
|
35
35
|
mdb_engine/auth/websocket_sessions.py,sha256=7eFNagY2K3Rp1x7d_cO5JcpT-DrYkc__cmVhl6pAC2M,15081
|
|
36
36
|
mdb_engine/auth/websocket_tickets.py,sha256=VoIArcnQBtYqXRMs-5m7NSvCJB1dEeHrLl7j7yG-H-A,9887
|
|
37
37
|
mdb_engine/cli/__init__.py,sha256=PANRi4THmL34d1mawlqxIrnuItXMdqoMTq5Z1zHd7rM,301
|
|
38
|
-
mdb_engine/cli/main.py,sha256=
|
|
38
|
+
mdb_engine/cli/main.py,sha256=qDVVUJOXajdZmbId9AIGBS380U7OlhA8ILrAIfURbSE,811
|
|
39
39
|
mdb_engine/cli/utils.py,sha256=bNRGJgdzxUjXAOVe1aoxWJ5M_IqtAE-eW4pfAkwiDDM,2760
|
|
40
40
|
mdb_engine/cli/commands/__init__.py,sha256=ZSzMhKdV9ILD5EbOSxDV9nURHo1e4bQ0c8AWpqsTEqM,115
|
|
41
41
|
mdb_engine/cli/commands/generate.py,sha256=VEcn7qNQkIPQlLEK3oXUBgYMwD-G0FyomXQcWTtKsbs,17304
|
|
@@ -76,7 +76,7 @@ mdb_engine/indexes/helpers.py,sha256=tJHqDm18jKLrW-P2ofmnUnaf4_-V5xDLjqP_WU8W9MM
|
|
|
76
76
|
mdb_engine/indexes/manager.py,sha256=ekrYBfKD-GOBpZMjXIZWSQ7UPLgrD5BINYzVteWkSI8,32508
|
|
77
77
|
mdb_engine/memory/README.md,sha256=Xa7pYut4zgZyRcb2TALcucMVAHCAu9uNGBKSwE7stY8,14764
|
|
78
78
|
mdb_engine/memory/__init__.py,sha256=e4kAYgxd_-WAH8GovTwjEBO9hvASu_kXEupMgksAL-U,1008
|
|
79
|
-
mdb_engine/memory/service.py,sha256=
|
|
79
|
+
mdb_engine/memory/service.py,sha256=huWIjHAsV-g_Cs9djRkd8v5ZgnqiXqtNEbNjAgMfzs4,28846
|
|
80
80
|
mdb_engine/observability/README.md,sha256=CMgQaC1H8ESmCitfbhJifz6-XoXH_FPNE4MvuZ-oFas,13085
|
|
81
81
|
mdb_engine/observability/__init__.py,sha256=jjLsrW6Gy2ayrbfLrgHsDB61NxWWkYLHwv0q-N3fxjA,1213
|
|
82
82
|
mdb_engine/observability/health.py,sha256=ORjxF_rHYA9vCoxUqel5p0n9g3PLmHsHQn68Q402b6g,9212
|
|
@@ -88,12 +88,12 @@ mdb_engine/repositories/mongo.py,sha256=Wg32_6v0KHAHumhz5z8QkoqJRWAMJFA7Y2lYIJ7L
|
|
|
88
88
|
mdb_engine/repositories/unit_of_work.py,sha256=XvmwGOspEDj4hsfOULPsQKjB1QZqh83TJo6vGV4tiqU,5118
|
|
89
89
|
mdb_engine/routing/README.md,sha256=zk-Wux-QpuWWhprfVeiUREv8PEDJZNgh2QblXIa4v4M,14201
|
|
90
90
|
mdb_engine/routing/__init__.py,sha256=reupjHi_RTc2ZBA4AH5XzobAmqy4EQIsfSUcTkFknUM,2438
|
|
91
|
-
mdb_engine/routing/websockets.py,sha256=
|
|
91
|
+
mdb_engine/routing/websockets.py,sha256=w0m1XMpXKPpPrEBcZNIj8B8PwWeTNrseUZE1P8cipdM,53441
|
|
92
92
|
mdb_engine/utils/__init__.py,sha256=lDxQSGqkV4fVw5TWIk6FA6_eey_ZnEtMY0fir3cpAe8,236
|
|
93
93
|
mdb_engine/utils/mongo.py,sha256=Oqtv4tQdpiiZzrilGLEYQPo8Vmh8WsTQypxQs8Of53s,3369
|
|
94
|
-
mdb_engine-0.7.
|
|
95
|
-
mdb_engine-0.7.
|
|
96
|
-
mdb_engine-0.7.
|
|
97
|
-
mdb_engine-0.7.
|
|
98
|
-
mdb_engine-0.7.
|
|
99
|
-
mdb_engine-0.7.
|
|
94
|
+
mdb_engine-0.7.3.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
95
|
+
mdb_engine-0.7.3.dist-info/METADATA,sha256=3XBbRELougI8lJsaJ1A02SuhIpsv2ojQspD2XidEXbo,18843
|
|
96
|
+
mdb_engine-0.7.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
97
|
+
mdb_engine-0.7.3.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
|
|
98
|
+
mdb_engine-0.7.3.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
|
|
99
|
+
mdb_engine-0.7.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|