77
88from __future__ import annotations
99
10+ import asyncio
1011import logging
1112from abc import ABC , abstractmethod
1213from typing import Optional , Tuple , Union
4647from infra_layer .adapters .out .persistence .repository .user_profile_raw_repository import (
4748 UserProfileRawRepository ,
4849)
50+ from infra_layer .adapters .out .persistence .repository .global_user_profile_raw_repository import (
51+ GlobalUserProfileRawRepository ,
52+ )
4953from api_specs .dtos import FetchMemResponse
5054from api_specs .memory_models import (
5155 MemoryType ,
5256 BaseMemoryModel ,
5357 ProfileModel ,
58+ GlobalUserProfileModel ,
59+ CombinedProfileModel ,
5460 PreferenceModel ,
5561 EpisodicMemoryModel ,
5662 BehaviorHistoryModel ,
@@ -111,6 +117,7 @@ def __init__(self):
111117 self ._event_log_repo = None
112118 self ._foresight_record_repo = None
113119 self ._user_profile_repo = None
120+ self ._global_user_profile_repo = None
114121 logger .info ("FetchMemoryServiceImpl initialized" )
115122
116123 def _get_repositories (self ):
@@ -131,6 +138,10 @@ def _get_repositories(self):
131138 self ._foresight_record_repo = get_bean_by_type (ForesightRecordRawRepository )
132139 if self ._user_profile_repo is None :
133140 self ._user_profile_repo = get_bean_by_type (UserProfileRawRepository )
141+ if self ._global_user_profile_repo is None :
142+ self ._global_user_profile_repo = get_bean_by_type (
143+ GlobalUserProfileRawRepository
144+ )
134145
135146 async def _get_user_details_cache (self , group_id : str ) -> dict :
136147 """
@@ -228,6 +239,28 @@ def _convert_user_profile(self, user_profile) -> ProfileModel:
228239 updated_at = user_profile .updated_at ,
229240 )
230241
242+ def _convert_global_user_profile (
243+ self , global_user_profile
244+ ) -> GlobalUserProfileModel :
245+ """Convert global user profile document to GlobalUserProfileModel
246+
247+ Args:
248+ global_user_profile: Global user profile document
249+
250+ Returns:
251+ GlobalUserProfileModel instance
252+ """
253+ return GlobalUserProfileModel (
254+ id = str (global_user_profile .id ),
255+ user_id = global_user_profile .user_id ,
256+ profile_data = global_user_profile .profile_data ,
257+ custom_profile_data = global_user_profile .custom_profile_data ,
258+ confidence = global_user_profile .confidence ,
259+ memcell_count = global_user_profile .memcell_count ,
260+ created_at = global_user_profile .created_at ,
261+ updated_at = global_user_profile .updated_at ,
262+ )
263+
231264 def _convert_preferences_from_core_memory (
232265 self , core_memory
233266 ) -> list [PreferenceModel ]:
@@ -602,14 +635,49 @@ async def find_memories(
602635 case MemoryType .PROFILE :
603636 # Profile: supports user_id and group_id filtering, no time filtering
604637 # Uses created_at/updated_at fields (not time range filterable)
605- user_profiles = await self ._user_profile_repo .find_by_filters (
638+ # Also fetches global_user_profile and returns CombinedProfileModel
639+
640+ # Fetch user_profiles and global_user_profile concurrently
641+ user_profiles_task = self ._user_profile_repo .find_by_filters (
606642 user_id = user_id , group_id = group_id , limit = limit
607643 )
608644
609- memories = [
645+ global_profile_task = None
646+ if user_id and user_id != MAGIC_ALL :
647+ global_profile_task = (
648+ self ._global_user_profile_repo .get_by_user_id (
649+ user_id = user_id
650+ )
651+ )
652+
653+ # Execute concurrently
654+ if global_profile_task :
655+ user_profiles , global_user_profile = await asyncio .gather (
656+ user_profiles_task , global_profile_task
657+ )
658+ else :
659+ user_profiles = await user_profiles_task
660+ global_user_profile = None
661+
662+ profile_models = [
610663 self ._convert_user_profile (up ) for up in user_profiles [:limit ]
611664 ]
612665
666+ global_profile_model = None
667+ if global_user_profile :
668+ global_profile_model = self ._convert_global_user_profile (
669+ global_user_profile
670+ )
671+
672+ # Return CombinedProfileModel containing both profiles
673+ combined_profile = CombinedProfileModel (
674+ user_id = user_id ,
675+ group_id = group_id ,
676+ profiles = profile_models ,
677+ global_profile = global_profile_model ,
678+ )
679+ memories = [combined_profile ]
680+
613681 case MemoryType .BASE_MEMORY :
614682 # Base memory: extract basic information from core memory
615683 # Does NOT support group_id or time filtering (single record per user)
0 commit comments