
    iu9                     |    d Z ddlZddlZddlmZ ddlmZmZmZmZ 	 ddl	Z
dZ G d d      Zy# e$ r dZdZ
Y w xY w)	z>JSON-based memory store for user feedback and session history.    N)datetime)DictAnyListOptionalTFc            
          e Zd ZdZ	 	 d#dededefdZdeeef   fdZdedefd	Z	d
eeef   fdZ
deeef   fdZd
eeef   fdZdedeeef   deeeef      deeef   fdZdeeeef      fdZdedej"                  fdZdedej"                  fdZdedeeeef      fdZ	 	 d$dedeee      deee      fdZdedeeeee   f      fdZdedej"                  deeef   fd Zdedeeeef      fd!Zdedeeeef      fd"Zy)%MemoryStorezFJSON-based memory store for storing user feedback and session history.pathuser_memory_pathintent_memory_pathc                    || _         || _        || _        t        j                  t        j                   j                  |      d       t        j                  t        j                   j                  |      d       t        j                  t        j                   j                  |      d       t        j                   j                  |      s2t        |dd      5 }t        j                  dg i|dd	       d
d
d
       t        j                   j                  |      s0t        |dd      5 }t        j                  i |dd	       d
d
d
       t        j                   j                  |      s1t        |dd      5 }t        j                  i |dd	       d
d
d
       y
y
# 1 sw Y   xY w# 1 sw Y   fxY w# 1 sw Y   y
xY w)a  Initialize memory store.
        
        Args:
            path: Path to the JSON file storing history
            user_memory_path: Path to the JSON file storing user vectors
            intent_memory_path: Path to the JSON file storing intent vectors
        T)exist_okwutf-8encodingsessions   Findentensure_asciiN)
r
   r   r   osmakedirsdirnameexistsopenjsondump)selfr
   r   r   fs        C   /home/ubuntu/codebase/yexijia/保研/colocation_mvp/memory/store.py__init__zMemoryStore.__init__   sA    	 0"4
BGGOOD)D9
BGGOO$45E
BGGOO$67$G ww~~d#dC'2a		:r*AaeL 3 ww~~./&g>!		"a> ? ww~~01(#@A		"a> A@ 2 32 ?> A@s$   F#0F/?F;#F,/F8;Greturnc                 l   	 t        | j                  dd      5 }t        j                  |      cddd       S # 1 sw Y   yxY w# t        j                  $ rZ}ddl}|j                  t              }|j                  d|j                   d       t        | j                  dd      5 }|j                         }ddd       n# 1 sw Y   nxY wddl}|j                  dd	      }|j                  d
d	|      }	 t        j                  |      }d|v r?|j                  dg       D ]*  }d|v s|d   D ]  }	t        |	t               sd|	v s|	d=  , | j#                  |       |j%                  d       |cY d}~S # t        j                  $ r |j'                  d       dg icY cY d}~S w xY wd}~ww xY w)zqLoad history from JSON file.
        
        Returns:
            Dictionary containing session history
        rr   r   Nr   zJSON file corrupted at z, attempting to fix...z\"embedding\":\s*[^,\n}]*,?\n? z\"embedding\":\s*\nr   shown_patterns	embeddingzJSON file fixed and savedz/Cannot fix JSON file, returning empty structure)r   r
   r   loadJSONDecodeErrorlogging	getLogger__name__warningposreadresubloadsget
isinstancedictsaveinfoerror)
r   r    er+   loggercontentr1   datasessionpatterns
             r!   r)   zMemoryStore.load1   sw   %	(diiw71yy| 877## "	(&&x0FNN4QUUG;QRS diiw71&&( 877 ff>GLGff3RAG(zz'*%#'88J#;+w6+23C+D#-gt#<PWAW(/(< ,E $< 		$78'' (NO"B''(?"	(s   A 9	A AA A F3AF.)C:	F.C	1F.:2E;-E;E;*E;5F3;(F+#F.$F3*F++F..F3objc                    t         rdt        |t        j                        r|j	                         S t        |t        j
                  t        j                  f      r|j                         S t        |t              r3|j                         D ci c]  \  }}|| j                  |       c}}S t        |t              r|D cg c]  }| j                  |       c}S |S c c}}w c c}w )zRecursively clean object to make it JSON serializable.
        
        Args:
            obj: Object to clean
            
        Returns:
            JSON-serializable object
        )NUMPY_AVAILABLEr5   npndarraytolistintegerfloatingitemr6   items_clean_for_jsonlist)r   r@   kvrH   s        r!   rJ   zMemoryStore._clean_for_json^   s     #rzz*zz|#C"**bkk!:;xxz!c4 ;>99;G;41aAt++A..;GGT";>?34D((.3??J H @s   CC%r=   c                     | j                  |      }t        | j                  dd      5 }t        j                  ||dd       ddd       y# 1 sw Y   yxY w)zrSave history to JSON file.
        
        Args:
            data: Dictionary containing session history
        r   r   r   r   Fr   N)rJ   r   r
   r   r   )r   r=   cleaned_datar    s       r!   r7   zMemoryStore.savex   sD     ++D1$))S73qIIlAaeD 433s   AAc                     t        | j                  dd      5 }t        j                  |      cddd       S # 1 sw Y   yxY w)z|Load user memory (vectors) from JSON file.
        
        Returns:
            Dictionary containing user vectors
        r%   r   r   N)r   r   r   r)   )r   r    s     r!   load_user_memoryzMemoryStore.load_user_memory   s0     $''w?199Q< @??s	   8Ac                     t        | j                  dd      5 }t        j                  ||dd       ddd       y# 1 sw Y   yxY w)z}Save user memory (vectors) to JSON file.
        
        Args:
            data: Dictionary containing user vectors
        r   r   r   r   Fr   N)r   r   r   r   )r   r=   r    s      r!   save_user_memoryzMemoryStore.save_user_memory   s7     $''w?1IIdAae< @??s	   <Aqueryparamspatternsfeedbackc                    | j                         }g }|D ]G  }|j                         }d|v r|d= d|v rd|vr|d   r|d   dd ng |d<   |d= |j                  |       I i }	|j                         D ]  \  }
}t	        |t
              rg |	|
<   |D ]~  }t	        |t              r3|j                         }d|v r|d= d|v r|d= |	|
   j                  |       Ft	        |t
              r|	|
   j                  |       k|	|
   j                  |        ||	|
<    t        j                         j                  d      ||||	d}|d   j                  |       | j                  |       y)	zAdd a new session to history.
        
        Args:
            query: User's query
            params: Extracted mining parameters
            patterns: Patterns shown to user
            feedback: User feedback (like/dislike)
        r(   table_instancestable_instances_sampleN   %Y-%m-%d %H:%M:%S)timerT   rU   r'   rW   r   )r)   copyappendrI   r5   rK   r6   r   nowstrftimer7   )r   rT   rU   rV   rW   r=   cleaned_patternsr?   pattern_copycleaned_feedbackkeyvaluerH   	item_copyr>   s                  r!   add_sessionzMemoryStore.add_session   s    yy{ G"<<>Ll* - L0+<?dp  rC  eD\J[=\]_^_=`  JLL!9: !23##L1   "..*JC%&(* %!D!$-$(IIK	&)3 )+ 6,	9 )*; <(-44Y?#D$/(-44T:(-44T: " ). %% +* LLN++,?@.(
 	Z(		$    c                 F    | j                         }|j                  dg       S )z`Get all historical sessions.
        
        Returns:
            List of all sessions
        r   )r)   r4   )r   r=   s     r!   get_all_sessionszMemoryStore.get_all_sessions   s      yy{xx
B''ri   user_idvectorc                     | j                         }||vr	g g g d||<   t        |t        j                        r|j	                         n|}||   d   j                  |       | j                  |       y)zAdd a positive (liked) pattern vector to user memory.
        
        Args:
            user_id: User identifier
            vector: Pattern embedding vector
        positivenegativehistoryrp   NrQ   r5   rC   rD   rE   r_   rS   r   rl   rm   memoryvector_lists        r!   add_positivezMemoryStore.add_positive   o     &&(& F7O *4FBJJ)GfmmoVw
#**;7f%ri   c                     | j                         }||vr	g g g d||<   t        |t        j                        r|j	                         n|}||   d   j                  |       | j                  |       y)zAdd a negative (disliked) pattern vector to user memory.
        
        Args:
            user_id: User identifier
            vector: Pattern embedding vector
        ro   rq   Nrs   rt   s        r!   add_negativezMemoryStore.add_negative   rx   ri   c                 D    | j                         }|j                  |      S )zGet user profile (positive and negative vectors).
        
        Args:
            user_id: User identifier
            
        Returns:
            Dictionary with 'positive' and 'negative' lists of vectors, or None if user not found
        rQ   r4   )r   rl   ru   s      r!   get_user_profilezMemoryStore.get_user_profile  s!     &&(zz'""ri   Nlikeddislikedc                     | j                         }||vrg g d||<   |rt        |      ng |rt        |      ng d||   d<   | j                  |       y)a$  Save user preference feature names (for preference-weighted scoring, e.g. 2025 adaptive fusion).
        
        Args:
            user_id: User identifier
            liked: List of feature names user likes (e.g. POI types)
            disliked: List of feature names user dislikes
        )rp   rq   )likedislikepreference_featuresN)rQ   rK   rS   )r   rl   r~   r   ru   s        r!   save_preference_featuresz$MemoryStore.save_preference_features  s_     &&(& +-2>F7O#(DKb)1tH~r2
w-. 	f%ri   c                 l    | j                         }|j                  |      }|sy|j                  d      S )zGet user preference feature names (for preference-weighted scoring).
        
        Args:
            user_id: User identifier
            
        Returns:
            Dict with 'like' and 'dislike' lists of feature names, or None if not set
        Nr   r|   )r   rl   ru   profiles       r!   get_preference_featuresz#MemoryStore.get_preference_features%  s6     &&(**W%{{011ri   u_llmintent_jsonc                    	 t         j                  j                  | j                        r7t	        | j                  dd      5 }t        j                  |      }ddd       ni }t        |t        j                        r|j                         n|}||t        j                         j                  d      d|<   t	        | j                  dd      5 }t        j                  ||dd	
       ddd       ddl}|j!                  t"              }|j%                  d|        y# 1 sw Y   xY w# 1 sw Y   CxY w# t&        $ r9}	ddl}|j!                  t"              }|j)                  d|	 d       Y d}	~	yd}	~	ww xY w)zSave intent vector and intent JSON to intent memory.
        
        Args:
            user_id: User identifier
            u_llm: LLM-generated initial user preference vector
            intent_json: Intent JSON from IntentEncoder
        r%   r   r   Nr\   )r   intent
created_atr   r   Fr   r   zSaved intent for user zError saving intent: Texc_info)r   r
   r   r   r   r   r)   r5   rC   rD   rE   r   r`   ra   r   r+   r,   r-   r8   	Exceptionr9   )
r   rl   r   r   r    intent_memory
u_llm_listr+   r;   r:   s
             r!   save_intentzMemoryStore.save_intent4  s@   	Eww~~d556$113IQ$(IIaLM JI !# ,6eRZZ+HeJ $%&lln556IJ&M'" d--sWE		-15I F &&x0FKK0	:;+ JI  FE  	E&&x0FLL04tLDD	EsI   AD: D"A9D: D.,5D: "D+'D: .D73D: :	E</E77E<c                    	 t         j                  j                  | j                        syt	        | j                  dd      5 }t        j                  |      }ddd       j                  |      S # 1 sw Y   xY w# t        $ r9}ddl	}|j                  t              }|j                  d| d       Y d}~yd}~ww xY w)	zLoad intent vector and intent JSON for a user.
        
        Args:
            user_id: User identifier
            
        Returns:
            Dictionary with 'u_llm' (vector as list) and 'intent' (JSON), or None if not found
        Nr%   r   r   r   zError loading intent: Tr   )r   r
   r   r   r   r   r)   r4   r   r+   r,   r-   r9   )r   rl   r    r   r:   r+   r;   s          r!   load_intentzMemoryStore.load_intent[  s    	77>>$"9"9:d--sWE $		! F !$$W-- FE
  	&&x0FLL1!5LE		s4   )A? A? A3A? 3A<8A? ?	C/B<<Cc                 p    | j                         }|j                  |      }|g S |j                  dg       S )zGet iteration round history for a user (for Stage4).
        
        Args:
            user_id: User identifier
            
        Returns:
            List of round history dictionaries
        roundsr|   )r   rl   ru   user_profiles       r!   get_round_historyzMemoryStore.get_round_historys  s@     &&(zz'*I "--ri   )zmemory/history.jsonzmemory/user_memory.jsonzmemory/intent_memory.json)NN)r-   
__module____qualname____doc__strr"   r   r   r)   rJ   r7   rQ   rS   r   rh   rk   rC   rD   rw   rz   r   r}   r   r   r   r   r    ri   r!   r	   r	      s   PRk+F?S ?C ?%(?<+(d38n +(Z3 3 4
Ec3h 
E $sCx.  =T#s(^ =: :d38n :!$sCx.1:=A#s(^:x($tCH~"6 (&C & &,&C & &,
# 
#c3h0H 
# SWBF& &HT#Y<O &,4T#Y,?&$2s 2xS$s)^@T7U 2%E3 %Erzz %ESRUX %EN3 8DcN+C 0. .d38n1E .ri   r	   )r   r   r   r   typingr   r   r   r   numpyrC   rB   ImportErrorr	   r   ri   r!   <module>r      sK    D  	  , ,Or. r.  O	Bs   / 	;;