[docs]@deprecated(since="0.3.8",removal="1.0",alternative_import="langchain_neo4j.Neo4jChatMessageHistory",)classNeo4jChatMessageHistory(BaseChatMessageHistory):"""Chat message history stored in a Neo4j database."""
[docs]def__init__(self,session_id:Union[str,int],url:Optional[str]=None,username:Optional[str]=None,password:Optional[str]=None,database:str="neo4j",node_label:str="Session",window:int=3,*,graph:Optional[Neo4jGraph]=None,):try:importneo4jexceptImportError:raiseImportError("Could not import neo4j python package. ""Please install it with `pip install neo4j`.")# Make sure session id is not nullifnotsession_id:raiseValueError("Please ensure that the session_id parameter is provided")# Graph object takes precedent over env or input paramsifgraph:self._driver=graph._driverself._database=graph._databaseelse:# Handle if the credentials are environment variablesurl=get_from_dict_or_env({"url":url},"url","NEO4J_URI")username=get_from_dict_or_env({"username":username},"username","NEO4J_USERNAME")password=get_from_dict_or_env({"password":password},"password","NEO4J_PASSWORD")database=get_from_dict_or_env({"database":database},"database","NEO4J_DATABASE","neo4j")self._driver=neo4j.GraphDatabase.driver(url,auth=(username,password))self._database=database# Verify connectiontry:self._driver.verify_connectivity()exceptneo4j.exceptions.ServiceUnavailable:raiseValueError("Could not connect to Neo4j database. ""Please ensure that the url is correct")exceptneo4j.exceptions.AuthError:raiseValueError("Could not connect to Neo4j database. ""Please ensure that the username and password are correct")self._session_id=session_idself._node_label=node_labelself._window=window# Create session nodeself._driver.execute_query(f"MERGE (s:`{self._node_label}` {{id:$session_id}})",{"session_id":self._session_id},).summary
@propertydefmessages(self)->List[BaseMessage]:"""Retrieve the messages from Neo4j"""query=(f"MATCH (s:`{self._node_label}`)-[:LAST_MESSAGE]->(last_message) ""WHERE s.id = $session_id MATCH p=(last_message)<-[:NEXT*0.."f"{self._window*2}]-() WITH p, length(p) AS length ""ORDER BY length DESC LIMIT 1 UNWIND reverse(nodes(p)) AS node ""RETURN {data:{content: node.content}, type:node.type} AS result")records,_,_=self._driver.execute_query(query,{"session_id":self._session_id})messages=messages_from_dict([el["result"]forelinrecords])returnmessages@messages.setterdefmessages(self,messages:List[BaseMessage])->None:raiseNotImplementedError("Direct assignment to 'messages' is not allowed."" Use the 'add_messages' instead.")
[docs]defadd_message(self,message:BaseMessage)->None:"""Append the message to the record in Neo4j"""query=(f"MATCH (s:`{self._node_label}`) WHERE s.id = $session_id ""OPTIONAL MATCH (s)-[lm:LAST_MESSAGE]->(last_message) ""CREATE (s)-[:LAST_MESSAGE]->(new:Message) ""SET new += {type:$type, content:$content} ""WITH new, lm, last_message WHERE last_message IS NOT NULL ""CREATE (last_message)-[:NEXT]->(new) ""DELETE lm")self._driver.execute_query(query,{"type":message.type,"content":message.content,"session_id":self._session_id,},).summary
[docs]defclear(self)->None:"""Clear session memory from Neo4j"""query=(f"MATCH (s:`{self._node_label}`)-[:LAST_MESSAGE]->(last_message) ""WHERE s.id = $session_id MATCH p=(last_message)<-[:NEXT]-() ""WITH p, length(p) AS length ORDER BY length DESC LIMIT 1 ""UNWIND nodes(p) as node DETACH DELETE node;")self._driver.execute_query(query,{"session_id":self._session_id}).summary