
    qi>)                     "   d Z ddlmZmZmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZmZ ddlmZmZ 	 dd	lmZmZ  G d de      Zy# e$ r7Z ej8                  d
e         ej8                  d        ede       dZ[ww xY w)zMem0 memory service integration for Pipecat.

This module provides a memory service that integrates with Mem0 to store
and retrieve conversational memories, enhancing LLM context with relevant
historical information.
    )AnyDictListOptional)logger)	BaseModelField)FrameLLMContextFrameLLMMessagesFrame)
LLMContext)OpenAILLMContextOpenAILLMContextFrame)FrameDirectionFrameProcessor)MemoryMemoryClientzException: zhIn order to use Mem0, you need to `pip install mem0ai`. Also, set the environment variable MEM0_API_KEY.zMissing module: Nc                       e Zd ZdZ G d de      Zdddddddddee   deeee	f      dee   d	ee   d
ee   dee   dee   f fdZ
deeee	f      fdZdedeeee	f      fdZdeez  defdZdedef fdZ xZS )Mem0MemoryServicea  A standalone memory service that integrates with Mem0.

    This service intercepts message frames in the pipeline, stores them in Mem0,
    and enhances context with relevant memories before passing them downstream.
    Supports both local and cloud-based Mem0 configurations.
    c                       e Zd ZU dZ edd      Zeed<    eddd	      Ze	ed
<    ed      Z
eed<    ed      Zeed<    ed      Zeed<    ed      Zeed<   y)Mem0MemoryService.InputParamsa  Configuration parameters for Mem0 memory service.

        Parameters:
            search_limit: Maximum number of memories to retrieve per query.
            search_threshold: Minimum similarity threshold for memory retrieval.
            api_version: API version to use for Mem0 client operations.
            system_prompt: Prefix text for memory context messages.
            add_as_system_message: Whether to add memories as system messages.
            position: Position to insert memory messages in context.
        
      )defaultgesearch_limitg?g        g      ?)r   r   lesearch_thresholdv2)r   api_versionz-Based on previous conversations, I recall: 

system_promptTadd_as_system_messagepositionN)__name__
__module____qualname____doc__r	   r   int__annotations__r   floatr    strr!   r"   boolr#        N/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/mem0/memory.pyInputParamsr   -   sl    		 ""3c3"'"D%D .S."+\]s]&+D&9t9a(#(r.   r0   N)api_keylocal_configuser_idagent_idrun_idparamshostr1   r2   r3   r4   r5   r6   r7   c                .   t         |           |xs i }|xs t        j                         }|rt	        j
                  |      | _        nt        ||      | _        t        |||g      st        d      || _
        || _        || _        |j                  | _        |j                  | _        |j                  | _        |j                   | _        |j"                  | _        |j$                  | _        d| _        t)        j*                  d|d|d|       y)a  Initialize the Mem0 memory service.

        Args:
            api_key: The API key for accessing Mem0's cloud API.
            local_config: Local configuration for Mem0 client (alternative to cloud API).
            user_id: The user ID to associate with memories in Mem0.
            agent_id: The agent ID to associate with memories in Mem0.
            run_id: The run ID to associate with memories in Mem0.
            params: Configuration parameters for memory retrieval and storage.
            host: The host of the Mem0 server.

        Raises:
            ValueError: If none of user_id, agent_id, or run_id are provided.
        )r1   r7   z=At least one of user_id, agent_id, or run_id must be providedNz+Initialized Mem0MemoryService with user_id=z, agent_id=z	, run_id=)super__init__r   r0   r   from_configmemory_clientr   any
ValueErrorr3   r4   r5   r   r   r    r!   r"   r#   
last_queryr   info)	selfr1   r2   r3   r4   r5   r6   r7   	__class__s	           r/   r:   zMem0MemoryService.__init__@   s    4 	#)r:,88:!'!3!3L!AD!-gD!IDGXv./\]] "// & 7 7!--#11%+%A%A"B'<h[PZSYR[\]r.   messagesc                 n   	 t        j                  dt        |       d       |ddidd}dD ]  }t        | |      st        | |      ||<     t	        | j
                  t              r|d=  | j
                  j                  di | y
# t        $ r"}t        j                  d	|        Y d
}~y
d
}~ww xY w)zvStore messages in Mem0.

        Args:
            messages: List of message dictionaries to store in memory.
        zStoring z messages in Mem0platformpipecatv1.1)rC   metadataoutput_format)r3   r4   r5   rI   z Error storing messages in Mem0: Nr-   )
r   debuglengetattr
isinstancer<   r   add	Exceptionerror)rA   rC   r6   ides        r/   _store_messagesz!Mem0MemoryService._store_messagess   s    	ALL8CM?2CDE$'3!'F
 8 34$!(r!2F2J3 $,,f5?+"D"",V, 	ALL;A3?@@	As   ;B	 A
B	 		B4B//B4queryreturnc                     	 t        j                  d|        t        | j                  t              rs|| j
                  | j                  | j                  | j                  d}|j                         D ci c]  \  }}|	|| }}} | j                  j                  di |}nd| j
                  fd| j                  fd| j                  fg}|D cg c]  \  }}|	||i }	}}|	rd|	ini }
| j                  j                  ||
| j                  | j                  | j                  d	      }t        j                  d
t        |       d       |S c c}}w c c}}w # t        $ r$}t        j                  d|        g cY d}~S d}~ww xY w)zRetrieve relevant memories from Mem0.

        Args:
            query: The query to search for relevant memories.

        Returns:
            List of relevant memory dictionaries matching the query.
        zRetrieving memories for query: )rT   r3   r4   r5   limitNr3   r4   r5   ORrG   )rT   filtersversiontop_k	thresholdrI   z
Retrieved z memories from Mem0z%Error retrieving memories from Mem0: r-   )r   rJ   rM   r<   r   r3   r4   r5   r   itemssearchr    r   rK   rO   rP   )rA   rT   r6   kvresultsid_pairsnamevalueclausesrY   rR   s               r/   _retrieve_memoriesz$Mem0MemoryService._retrieve_memories   s   !	LL:5'BC$,,f5"#|| $"kk!.. ,2<<>K41aQ]!Q$KK3$,,33=f= -/t{{+
 =EZ[T5HYD%=ZZ-44/",,33# ,,++"33"( 4  LL:c'l^3FGHN) L [  	LL@DEI	sJ   A5E  7
EEAE  
E E&A-E  E   	F)FFFcontextc                    | j                   |k(  ry|| _         | j                  |      }|sy| j                  }t        |d   d      D ]   \  }}|| d|j	                  dd       dz  }" | j
                  r|j                  d|d	       n|j                  d
|d	       t        j                  dt        |       d       y)zEnhance the LLM context with relevant memories.

        Args:
            context: The LLM context to enhance with memory information.
            query: The query to search for relevant memories.
        Nra   r   z. memory z

system)rolecontentuserzEnhanced context with z	 memories)
r?   rf   r!   	enumerategetr"   add_messager   rJ   rK   )rA   rg   rT   memoriesmemory_textiri   s          r/   _enhance_context_with_memoriesz0Mem0MemoryService._enhance_context_with_memories   s     ??e#**51 (("8I#6: 	BIAvaS6::h#;"<DAAK	B %%k JK K HI-c(m_IFGr.   frame	directionc                   K   t         	|   ||       d{    d}d}t        |t        t        f      r|j
                  }n't        |t              r|j                  }t        |      }|r	 |j                         }d}t        |      D ]I  }|j                  d      dk(  st        |j                  d      t              s8|j                  d      } n |r#| j                  ||       | j                  |       |1| j                  t        |j                                      d{    n| j                  |       d{    yy| j                  ||       d{    y7 M7 >7 &# t         $ rL}| j#                  dt        |       |       d{  7   | j                  |       d{  7   Y d}~yd}~ww xY w7 dw)zProcess incoming frames, intercept context frames for memory integration.

        Args:
            frame: The incoming frame to process.
            direction: The direction of frame flow in the pipeline.
        Nrl   rn   rm   zError processing with Mem0: )	error_msg	exception)r9   process_framerM   r   r   rg   r   rC   r   get_messagesreversedrp   r+   ru   rS   
push_framerO   
push_error)
rA   rv   rw   rg   rC   context_messageslatest_user_messagemessagerR   rB   s
            r/   r{   zMem0MemoryService.process_frame   s     g#E9555eo/DEFmmG/0~~H *G-#*#7#7#9 &*#'(89 G{{6*f4GKKPYDZ\_9`.5kk).D+
 '77ATU(()9: '//*:7;O;O;Q*RSSS //%000 T //%333S 	6< T 1 -oo <SVHEQR &    ooe,,,	- 4s   GE$AG-4E+ "E+ A&E+ (E')E+ E)E+ GGG'E+ )E+ +	G 4"F;FF;0F31F;6G;G  G)r$   r%   r&   r'   r   r0   r   r+   r   r   r:   r   rS   rf   r   r   ru   r
   r   r{   __classcell__)rB   s   @r/   r   r   %   s   )i ), "&15!%"& $(,"1^ #1^ tCH~.	1^
 #1^ 3-1^ 1^ %1^ sm1^fAT#s(^(< A0* *T#s(^0D *XHjCS6S H\_ H<04 04> 04 04r.   r   )r'   typingr   r   r   r   logurur   pydanticr   r	   pipecat.frames.framesr
   r   r   *pipecat.processors.aggregators.llm_contextr   1pipecat.processors.aggregators.openai_llm_contextr   r   "pipecat.processors.frame_processorr   r   mem0r   r   ModuleNotFoundErrorrR   rP   rO   r   r-   r.   r/   <module>r      s    - ,  % J J A N,)`4 `4  ,FLL;qc"#FLLr &qc*
++,s   A B2B		B