[docs]classTeachability(Memory):""" Gives an AssistantAgent the ability to learn quickly from user teachings, hints, and advice. Steps for usage: 1. Instantiate MemoryController. 2. Instantiate Teachability, passing the memory controller as a parameter. 3. Instantiate an AssistantAgent, passing the teachability instance (wrapped in a list) as the memory parameter. 4. Use the AssistantAgent as usual, such as for chatting with the user. """def__init__(self,memory_controller:"MemoryController",name:str|None=None)->None:"""Initialize Teachability."""self._memory_controller=memory_controllerself._logger=memory_controller.loggerself._name=nameor"teachability"@propertydefname(self)->str:"""Get the memory instance identifier."""returnself._namedef_extract_text(self,content_item:str|MemoryContent)->str:"""Extract searchable text from content."""ifisinstance(content_item,str):returncontent_itemcontent=content_item.contentmime_type=content_item.mime_typeifmime_typein[MemoryMimeType.TEXT,MemoryMimeType.MARKDOWN]:returnstr(content)elifmime_type==MemoryMimeType.JSON:ifisinstance(content,dict):# Store original JSON string representationreturnstr(content).lower()raiseValueError("JSON content must be a dict")elifisinstance(content,Image):raiseValueError("Image content cannot be converted to text")else:raiseValueError(f"Unsupported content type: {mime_type}")
[docs]asyncdefupdate_context(self,model_context:ChatCompletionContext,)->UpdateContextResult:""" Extracts any advice from the last user turn to be stored in memory, and adds any relevant memories to the model context. """self._logger.enter_function()# Extract text from the user's last messagemessages=awaitmodel_context.get_messages()ifnotmessages:self._logger.leave_function()returnUpdateContextResult(memories=MemoryQueryResult(results=[]))last_message=messages[-1]last_user_text=last_message.contentifisinstance(last_message.content,str)elsestr(last_message)# Add any relevant memories to the chat historyquery_results=awaitself.query(last_user_text)ifquery_results.results:memory_strings=[f"{i}. {str(memory.content)}"fori,memoryinenumerate(query_results.results,1)]memory_context="\nPotentially relevant memories:\n"+"\n".join(memory_strings)awaitmodel_context.add_message(UserMessage(content=memory_context,source="user"))# Add any user advice to memoryawaitself._memory_controller.consider_memo_storage(last_user_text)self._logger.leave_function()returnUpdateContextResult(memories=query_results)
[docs]asyncdefadd(self,content:MemoryContent,cancellation_token:CancellationToken|None=None)->None:""" Tries to extract any advice from the passed content and add it to memory. """self._logger.enter_function()# Extract text from the incoming contenttext=self._extract_text(content)# Check for advice to add to memory for later turns.awaitself._memory_controller.consider_memo_storage(text)self._logger.leave_function()
[docs]asyncdefquery(self,query:str|MemoryContent,cancellation_token:CancellationToken|None=None,**kwargs:Any,)->MemoryQueryResult:""" Returns any memories that seem relevant to the query. """self._logger.enter_function()task=self._extract_text(query)memory_results:list[MemoryContent]=[]filtered_memos=awaitself._memory_controller.retrieve_relevant_memos(task=task)filtered_insights=[memo.insightformemoinfiltered_memos]forinsightinfiltered_insights:self._logger.info(f"Insight: {insight}")memory_content=MemoryContent(content=insight,mime_type="MemoryMimeType.TEXT",metadata={},)memory_results.append(memory_content)self._logger.leave_function()returnMemoryQueryResult(results=memory_results)
[docs]asyncdefclear(self)->None:"""Clear all entries from memory."""self._memory_controller.reset_memory()
[docs]asyncdefclose(self)->None:"""Clean up memory resources."""pass# No cleanup needed for this memory implementation