{"version":3,"file":"neo4j.cjs","names":["BaseListChatMessageHistory","neo4j","auth"],"sources":["../../../src/stores/message/neo4j.ts"],"sourcesContent":["import neo4j, { Driver, Record, auth, type ServerInfo } from \"neo4j-driver\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { BaseListChatMessageHistory } from \"@langchain/core/chat_history\";\nimport {\n  BaseMessage,\n  mapStoredMessagesToChatMessages,\n} from \"@langchain/core/messages\";\n\nexport type Neo4jChatMessageHistoryConfigInput = {\n  sessionId?: string | number;\n  sessionNodeLabel?: string;\n  messageNodeLabel?: string;\n  url: string;\n  username: string;\n  password: string;\n  windowSize?: number;\n};\n\nconst defaultConfig = {\n  sessionNodeLabel: \"ChatSession\",\n  messageNodeLabel: \"ChatMessage\",\n  windowSize: 3,\n};\n\nexport class Neo4jChatMessageHistory extends BaseListChatMessageHistory {\n  lc_namespace: string[] = [\"langchain\", \"stores\", \"message\", \"neo4j\"];\n\n  sessionId: string | number;\n\n  sessionNodeLabel: string;\n\n  messageNodeLabel: string;\n\n  windowSize: number;\n\n  private driver: Driver;\n\n  constructor({\n    sessionId = uuidv4(),\n    sessionNodeLabel = defaultConfig.sessionNodeLabel,\n    messageNodeLabel = defaultConfig.messageNodeLabel,\n    url,\n    username,\n    password,\n    windowSize = defaultConfig.windowSize,\n  }: Neo4jChatMessageHistoryConfigInput) {\n    super();\n\n    this.sessionId = sessionId;\n    this.sessionNodeLabel = sessionNodeLabel;\n    this.messageNodeLabel = messageNodeLabel;\n    this.windowSize = windowSize;\n\n    if (url && username && password) {\n      try {\n        this.driver = neo4j.driver(url, auth.basic(username, password));\n      } catch (e) {\n        const error = e as Error;\n        throw new Error(\n          `Could not create a Neo4j driver instance. Please check the connection details.\\nCause: ${error.message}`\n        );\n      }\n    } else {\n      throw new Error(\"Neo4j connection details not provided.\");\n    }\n  }\n\n  static async initialize(\n    props: Neo4jChatMessageHistoryConfigInput\n  ): Promise<Neo4jChatMessageHistory> {\n    const instance = new Neo4jChatMessageHistory(props);\n\n    try {\n      await instance.verifyConnectivity();\n    } catch (e) {\n      const error = e as Error;\n      throw new Error(\n        `Could not verify connection to the Neo4j database.\\nCause: ${error.message}`\n      );\n    }\n\n    return instance;\n  }\n\n  async verifyConnectivity(): Promise<ServerInfo> {\n    const connectivity = await this.driver.getServerInfo();\n    return connectivity;\n  }\n\n  async getMessages(): Promise<BaseMessage[]> {\n    const getMessagesCypherQuery = `\n      MERGE (chatSession:${this.sessionNodeLabel} {id: $sessionId})\n      WITH chatSession\n      MATCH (chatSession)-[:LAST_MESSAGE]->(lastMessage)\n      MATCH p=(lastMessage)<-[:NEXT*0..${this.windowSize * 2 - 1}]-()\n      WITH p, length(p) AS length\n      ORDER BY length DESC LIMIT 1\n      UNWIND reverse(nodes(p)) AS node\n      RETURN {data:{content: node.content}, type:node.type} AS result\n    `;\n\n    try {\n      const { records } = await this.driver.executeQuery(\n        getMessagesCypherQuery,\n        {\n          sessionId: this.sessionId,\n        }\n      );\n      const results = records.map((record: Record) => record.get(\"result\"));\n\n      return mapStoredMessagesToChatMessages(results);\n    } catch (e) {\n      const error = e as Error;\n      throw new Error(`Ohno! Couldn't get messages.\\nCause: ${error.message}`);\n    }\n  }\n\n  async addMessage(message: BaseMessage): Promise<void> {\n    const addMessageCypherQuery = `\n      MERGE (chatSession:${this.sessionNodeLabel} {id: $sessionId})\n      WITH chatSession\n      OPTIONAL MATCH (chatSession)-[lastMessageRel:LAST_MESSAGE]->(lastMessage)\n      CREATE (chatSession)-[:LAST_MESSAGE]->(newLastMessage:${this.messageNodeLabel})\n      SET newLastMessage += {type:$type, content:$content}\n      WITH newLastMessage, lastMessageRel, lastMessage\n      WHERE lastMessage IS NOT NULL\n      CREATE (lastMessage)-[:NEXT]->(newLastMessage)\n      DELETE lastMessageRel\n    `;\n\n    try {\n      await this.driver.executeQuery(addMessageCypherQuery, {\n        sessionId: this.sessionId,\n        type: message.getType(),\n        content: message.content,\n      });\n    } catch (e) {\n      const error = e as Error;\n      throw new Error(`Ohno! Couldn't add message.\\nCause: ${error.message}`);\n    }\n  }\n\n  async clear() {\n    const clearMessagesCypherQuery = `\n      MATCH p=(chatSession:${this.sessionNodeLabel} {id: $sessionId})-[:LAST_MESSAGE]->(lastMessage)<-[:NEXT*0..]-()\n      UNWIND nodes(p) as node\n      DETACH DELETE node\n    `;\n\n    try {\n      await this.driver.executeQuery(clearMessagesCypherQuery, {\n        sessionId: this.sessionId,\n      });\n    } catch (e) {\n      const error = e as Error;\n      throw new Error(\n        `Ohno! Couldn't clear chat history.\\nCause: ${error.message}`\n      );\n    }\n  }\n\n  async close() {\n    await this.driver.close();\n  }\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAM,gBAAgB;CACpB,kBAAkB;CAClB,kBAAkB;CAClB,YAAY;CACb;AAED,IAAa,0BAAb,MAAa,gCAAgCA,6BAAAA,2BAA2B;CACtE,eAAyB;EAAC;EAAa;EAAU;EAAW;EAAQ;CAEpE;CAEA;CAEA;CAEA;CAEA;CAEA,YAAY,EACV,aAAA,GAAA,KAAA,KAAoB,EACpB,mBAAmB,cAAc,kBACjC,mBAAmB,cAAc,kBACjC,KACA,UACA,UACA,aAAa,cAAc,cACU;AACrC,SAAO;AAEP,OAAK,YAAY;AACjB,OAAK,mBAAmB;AACxB,OAAK,mBAAmB;AACxB,OAAK,aAAa;AAElB,MAAI,OAAO,YAAY,SACrB,KAAI;AACF,QAAK,SAASC,aAAAA,QAAM,OAAO,KAAKC,aAAAA,KAAK,MAAM,UAAU,SAAS,CAAC;WACxD,GAAG;AAEV,SAAM,IAAI,MACR,0FAFY,EAEoF,UACjG;;MAGH,OAAM,IAAI,MAAM,yCAAyC;;CAI7D,aAAa,WACX,OACkC;EAClC,MAAM,WAAW,IAAI,wBAAwB,MAAM;AAEnD,MAAI;AACF,SAAM,SAAS,oBAAoB;WAC5B,GAAG;AAEV,SAAM,IAAI,MACR,8DAFY,EAEwD,UACrE;;AAGH,SAAO;;CAGT,MAAM,qBAA0C;AAE9C,SADqB,MAAM,KAAK,OAAO,eAAe;;CAIxD,MAAM,cAAsC;EAC1C,MAAM,yBAAyB;2BACR,KAAK,iBAAiB;;;yCAGR,KAAK,aAAa,IAAI,EAAE;;;;;;AAO7D,MAAI;GACF,MAAM,EAAE,YAAY,MAAM,KAAK,OAAO,aACpC,wBACA,EACE,WAAW,KAAK,WACjB,CACF;AAGD,WAAA,GAAA,yBAAA,iCAFgB,QAAQ,KAAK,WAAmB,OAAO,IAAI,SAAS,CAAC,CAEtB;WACxC,GAAG;AAEV,SAAM,IAAI,MAAM,wCADF,EACgD,UAAU;;;CAI5E,MAAM,WAAW,SAAqC;EACpD,MAAM,wBAAwB;2BACP,KAAK,iBAAiB;;;8DAGa,KAAK,iBAAiB;;;;;;;AAQhF,MAAI;AACF,SAAM,KAAK,OAAO,aAAa,uBAAuB;IACpD,WAAW,KAAK;IAChB,MAAM,QAAQ,SAAS;IACvB,SAAS,QAAQ;IAClB,CAAC;WACK,GAAG;AAEV,SAAM,IAAI,MAAM,uCADF,EAC+C,UAAU;;;CAI3E,MAAM,QAAQ;EACZ,MAAM,2BAA2B;6BACR,KAAK,iBAAiB;;;;AAK/C,MAAI;AACF,SAAM,KAAK,OAAO,aAAa,0BAA0B,EACvD,WAAW,KAAK,WACjB,CAAC;WACK,GAAG;AAEV,SAAM,IAAI,MACR,8CAFY,EAEwC,UACrD;;;CAIL,MAAM,QAAQ;AACZ,QAAM,KAAK,OAAO,OAAO"}