
    i,                         d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZmZmZmZ d dlZd dlZ ej(                  e      Z G d de      Zy)    N)List)MemoryStoreConfig)SimpleMemoryConfig)
MemoryBaseMemoryContentSnapshot
MemoryItemMemoryWritePayloadc                        e Zd Zdef fdZdedefdZdedefdZddZdd	Z	d
ede
dededee   f
dZdededefdZdededefdZdededefdZdededefdZdeddfdZ xZS )SimpleMemorystorec                     |j                  t              }|st        d      t        |   |       || _        d| _        d| _        | j
                  j                  | _        d| _	        d| _
        y )Nz9SimpleMemory requires a simple memory store configurationzQuery: {input}zInput: {input}
Output: {output}i     )	as_configr   
ValueErrorsuper__init__configretrieve_promptupdate_promptmemory_pathmax_content_lengthmin_content_length)selfr   r   	__class__s      T/Users/bowang/.openclaw/workspace/ChatDev/runtime/node/agent/memory/simple_memory.pyr   zSimpleMemory.__init__   si    !34XYY/?;;22 #&"$    contentreturnc                    t        j                  dd|j                               }t        |      dk  r|S t        j                  dd|      }t        j                  dd|      }t        j                  dd|      }t        j                  dd|      }t        j                  d	|      }|D cg c]9  }t        |j                               | j
                  k\  s*|j                         ; }}|s|d
| j                   S dj                  |d
d       }t        |      | j                  kD  r|d
| j                   dz   }|j                         S c c}w )z3Extract key content while stripping redundant text.z\s+ d   z(?:Agent|Model) Role:.*?\n\n u$   (?:You are|你是一位).*?(?:,|，)u/   (?:User will input|用户会输入).*?(?:,|，)u%   (?:You need to|你需要).*?(?:,|，)z[\u3002\uff01\uff1f\uff1b\n]Nu   。   z...)resubstriplensplitr   r   join)r   r   	sentencesskey_sentencesextracted_contents         r   _extract_key_contentz!SimpleMemory._extract_key_content&   s9    &&gmmo6 w<3N &&8"gF&&NPRT[\&&\^`bij&&LbRYZ HH<gF	,5cIqQWWY4KbKb9bIc 3D3344 %MM-*;< !D$;$;; 12J43J3J Ke S &&(( ds   ,+EEc                 l    t        j                  |j                  d            j                         dd S )z/Generate a content hash used for deduplication.zutf-8N   )hashlibmd5encode	hexdigest)r   r   s     r   _generate_content_hashz#SimpleMemory._generate_content_hashD   s*    {{7>>'23==?CCr   Nc                    | j                   rt        j                  j                  | j                         r| j                   j	                  d      rj	 t        | j                         5 }t        j                  |      }d d d        g }D ]'  }	 |j                  t        j                  |             ) || _        y y y y # 1 sw Y   BxY w# t        $ r Y Lw xY w# t        $ r
 g | _        Y y w xY w)N.json)r   ospathexistsendswithopenjsonloadappendr   	from_dict	Exceptioncontents)r   fileraw_datarB   raws        r   r>   zSimpleMemory.loadH   s    t/?/? @TEUEUE^E^_fEg#$**+t#yyH ,#C! 
(<(<S(AB $
 !) Fh @++ % ! !  # "#sN   C 'B>=C $C
1	C >CC 
	CC CC C,+C,c                    | j                   r| j                   j                  d      rt        j                  t        j                  j                  | j                         d       t        | j                   d      5 }t        j                  | j                  D cg c]  }|j                          c}|dd       d d d        y y y c c}w # 1 sw Y   y xY w)Nr7   T)exist_okw   F)indentensure_ascii)r   r;   r8   makedirsr9   dirnamer<   r=   dumprB   to_dict)r   rC   items      r   savezSimpleMemory.saveW   s     0 0 9 9' BKK(8(89DId&&,		dmmDmd4<<>mDdSTchi -, !C E -,s   <CC
1CCC
agent_rolequerytop_ksimilarity_thresholdc                 `   | j                         dk(  s| j                  sg S | j                  j                  |j                        }| j                  |      }| j                  j                  |      }t        |t              r%t        j                  |t        j                        }|j                  dd      }t        j                  |       |j                  d   }g }g }	| j                   D ]  }
|
j                  t#        |
j                        |k7  r6t$        j'                  d|
j(                  t#        |
j                        |       ^|j+                  |
j                         |	j+                  |
        |sg S t        j                  |t        j                        }t        j,                  |j                  d         }|j/                  |       t1        |dz  t#        |	            }|j3                  ||      \  }}g }t5        t#        |d               D ]]  }|d   |   }|d   |   }|dk7  s||k\  s|	|   }
| j7                  ||
j8                        }d|z  d	|z  z   }|j+                  |
|f       _ |j;                  d
 d       |d | D 
cg c]  \  }
}|
	 }}
}|S c c}}
w )Nr   )inputdtype   z8Skipping memory item %s: embedding dim %d != expected %dr#   gffffff?333333?c                     | d   S )NrZ    )xs    r   <lambda>z'SimpleMemory.retrieve.<locals>.<lambda>   s    adr   T)keyreverse)count_memories	embeddingr   formattextr.   get_embedding
isinstancelistnparrayfloat32reshapefaissnormalize_L2shaperB   r'   loggerwarningidr?   IndexFlatIPaddminsearchrange_calculate_semantic_similaritycontent_summarysort)r   rR   rS   rT   rU   
query_textinputs_embeddingexpected_dimmemory_embeddingsvalid_itemsrP   indexretrieval_ksimilaritiesindices
candidatesiidx
similaritysemantic_scorecombined_scorescoreresultss                          r   retrievezSimpleMemory.retrieve]   sz     A%T^^I ))00uzz0B
..z:
>>77
C&-!xx(8

K+33Ar:+,'--a0MMD~~)t~~&,6NNRT^^!4l !((8""4( " !IHH%6bjjI !!"3"9"9!"<=		#$ %!)S%56 %-={ Kg 
s71:'A!*Q-C%a+JbyZ+??"3'!%!D!DZQUQeQe!f!$z!1C.4H!H!!4"89 ( 	ND9+5fu+=>+=KD%4+=> ?s   J*c                    |j                         }|j                         }t        |j                               }t        |j                               }|r|sd}n%||z  }||z  }	|	rt        |      t        |	      z  nd}| j	                  ||      }
| j                  ||      }| j                  ||      }d|z  d|
z  z   d|z  z   d|z  z   }t        |d      S )z$Compute a semantic similarity value.        g?r\   g?皙?      ?)lowersetr(   r'   _calculate_lcs_similarity_calculate_keyword_similarity_calculate_length_factorrv   )r   rS   r   query_lowercontent_lowerquery_wordscontent_wordsjaccard_simintersectionunionlcs_simkeyword_simlength_factorfinal_scores                 r   ry   z+SimpleMemory._calculate_semantic_similarity   s     kkm +++-.M//12-K&6L-/E<A#l+c%j8sK 00mL 88mT 55k=Q [(Gm$K'( M)*
 ;$$r   s1s2c                    t        |      t        |      }}t        |dz         D cg c]  }dg|dz   z   }}t        d|dz         D ]c  }t        d|dz         D ]O  }||dz
     ||dz
     k(  r||dz
     |dz
     dz   ||   |<   ,t        ||dz
     |   ||   |dz
           ||   |<   Q e ||   |   }	t        t        |      t        |            dkD  r!|	t        t        |      t        |            z  S dS c c}w )z.Compute longest common subsequence similarity.rZ   r   r   )r'   rx   max)
r   r   r   mn_dpr   j
lcs_lengths
             r   r   z&SimpleMemory._calculate_lcs_similarity   s   2wB1%*1q5\2\qcQUm\2q!a%A1a!e_ac7b1g%!!A#wqs|a/BqE!H"2ac71:r!uQqSz:BqE!H	 % ! U1X
58R#b'5JQ5NzCBR11WTWW 3s   C:c                     t        d |j                         D              }t        d |j                         D              }|sy||z  }t        |      t        |      z  S )z!Compute keyword match similarity.c              3   >   K   | ]  }t        |      d k\  s|  ywrI   Nr'   .0words     r   	<genexpr>z=SimpleMemory._calculate_keyword_similarity.<locals>.<genexpr>   s     Nmds4yA~Tm   c              3   >   K   | ]  }t        |      d k\  s|  ywr   r   r   s     r   r   z=SimpleMemory._calculate_keyword_similarity.<locals>.<genexpr>   s     R3t9PQ>tr   r   )r   r(   r'   )r   rS   r   query_keywordscontent_keywordsmatchess         r   r   z*SimpleMemory._calculate_keyword_similarity   sV     NekkmNNRRR #337|c.111r   c                     t        |      }t        |      }|dk(  ryd}d}||z  }||cxk  r|k  ry ||k  r||z  S t        d||z        S )z1Penalize matches that deviate too much in length.r   r   g      ?g       @r   r   )r'   r   )r   rS   r   	query_lencontent_lenideal_ratio_minideal_ratio_maxratios           r   r   z%SimpleMemory._calculate_length_factor   so    J	'l! i'e66 7_$?**sOe344r   payloadc                    | j                   sy |j                  }|r|j                  j                         sy | j                  j                  |j                  |j                        }| j                  |      }t        |      | j                  k  ry | j                  |      }| j                  D ]$  }| j                  |j                        }||k(  s$ y  | j                   j                  |      }t        |t              r%t!        j"                  |t         j$                        }|y t!        j"                  |t         j$                        j'                  dd      }	t)        j*                  |	       |j,                  |j                  xs dd d t        |      |j/                         d}
t1        | dt3        t5        j4                                ||
|	j7                         d	   |j8                  |
      }| j                  j;                  |       d}t        | j                        |kD  r| j                  | d  | _        y y )N)rW   outputrX   rZ   r[   r"      )rR   input_previewcontent_lengthattachmentsr   r   )rs   rz   metadatard   input_snapshotoutput_snapshoti  )rd   r   rf   r&   r   re   inputs_textr.   r'   r   r5   rB   rz   rg   rh   ri   rj   rk   rl   rm   rn   ro   rR   attachment_overviewr   inttimetolistr   r?   )r   r   snapshotraw_contentr-   content_hashexisting_itemexisting_hashembedding_vectorembedding_arrayr   memory_itemmax_memoriess                r   updatezSimpleMemory.update   s   ~~**x}}224((//%%== 0 
 !55kB !D$;$;;223DE!]]M 778U8UVM, +
  >>778IJ&-!xx(8

K#((#32::FNNqRTU?+ ",,%117R#>!"34#779	
 !qTYY[!1 23-%,,.q1"11$
 	[)t}}, MM<-.9DM -r   )r   N)__name__
__module____qualname__r   r   strr.   r5   r>   rQ   r   r   floatr   r   r   ry   r   r   r   r	   r   __classcell__)r   s   @r   r   r      s   %/ %)C )C )<Dc Dc D#jBB %B 	B
 $B 
j	BH %C  %#  %%  %DXC XS XU X
23 
2 
2 
25c 5C 5E 5*3:0 3:T 3:r   r   )r1   r=   loggingr8   r$   r   typingr   entity.configsr   entity.configs.node.memoryr   %runtime.node.agent.memory.memory_baser   r   r   r	   rn   numpyrj   	getLoggerr   rq   r   r^   r   r   <module>r      sR       	 	   , 9   			8	$P:: P:r   