[docs]classCombinedMemory(BaseMemory):"""Combining multiple memories' data together."""memories:List[BaseMemory]"""For tracking all the memories that should be accessed."""@field_validator("memories")@classmethoddefcheck_repeated_memory_variable(cls,value:List[BaseMemory])->List[BaseMemory]:all_variables:Set[str]=set()forvalinvalue:overlap=all_variables.intersection(val.memory_variables)ifoverlap:raiseValueError(f"The same variables {overlap} are found in multiple""memory object, which is not allowed by CombinedMemory.")all_variables|=set(val.memory_variables)returnvalue@field_validator("memories")@classmethoddefcheck_input_key(cls,value:List[BaseMemory])->List[BaseMemory]:"""Check that if memories are of type BaseChatMemory that input keys exist."""forvalinvalue:ifisinstance(val,BaseChatMemory):ifval.input_keyisNone:warnings.warn("When using CombinedMemory, ""input keys should be so the input is known. "f" Was not set on {val}")returnvalue@propertydefmemory_variables(self)->List[str]:"""All the memory variables that this instance provides.""""""Collected from the all the linked memories."""memory_variables=[]formemoryinself.memories:memory_variables.extend(memory.memory_variables)returnmemory_variables
[docs]defload_memory_variables(self,inputs:Dict[str,Any])->Dict[str,str]:"""Load all vars from sub-memories."""memory_data:Dict[str,Any]={}# Collect vars from all sub-memoriesformemoryinself.memories:data=memory.load_memory_variables(inputs)forkey,valueindata.items():ifkeyinmemory_data:raiseValueError(f"The variable {key} is repeated in the CombinedMemory.")memory_data[key]=valuereturnmemory_data
[docs]defsave_context(self,inputs:Dict[str,Any],outputs:Dict[str,str])->None:"""Save context from this session for every memory."""# Save context for all sub-memoriesformemoryinself.memories:memory.save_context(inputs,outputs)
[docs]defclear(self)->None:"""Clear context from this session for every memory."""formemoryinself.memories:memory.clear()