{"version":3,"file":"neo4j.cjs","names":["BaseListChatMessageHistory","neo4j","auth","props: Neo4jChatMessageHistoryConfigInput","record: Record","message: BaseMessage"],"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;AACb;AAED,IAAa,0BAAb,MAAa,gCAAgCA,yDAA2B;CACtE,eAAyB;EAAC;EAAa;EAAU;EAAW;CAAQ;CAEpE;CAEA;CAEA;CAEA;CAEA,AAAQ;CAER,YAAY,EACV,0BAAoB,EACpB,mBAAmB,cAAc,kBACjC,mBAAmB,cAAc,kBACjC,KACA,UACA,UACA,aAAa,cAAc,YACQ,EAAE;EACrC,OAAO;EAEP,KAAK,YAAY;EACjB,KAAK,mBAAmB;EACxB,KAAK,mBAAmB;EACxB,KAAK,aAAa;AAElB,MAAI,OAAO,YAAY,SACrB,KAAI;GACF,KAAK,SAASC,qBAAM,OAAO,KAAKC,kBAAK,MAAM,UAAU,SAAS,CAAC;EAChE,SAAQ,GAAG;GACV,MAAM,QAAQ;AACd,SAAM,IAAI,MACR,CAAC,uFAAuF,EAAE,MAAM,SAAS;EAE5G;MAED,OAAM,IAAI,MAAM;CAEnB;CAED,aAAa,WACXC,OACkC;EAClC,MAAM,WAAW,IAAI,wBAAwB;AAE7C,MAAI;GACF,MAAM,SAAS,oBAAoB;EACpC,SAAQ,GAAG;GACV,MAAM,QAAQ;AACd,SAAM,IAAI,MACR,CAAC,2DAA2D,EAAE,MAAM,SAAS;EAEhF;AAED,SAAO;CACR;CAED,MAAM,qBAA0C;EAC9C,MAAM,eAAe,MAAM,KAAK,OAAO,eAAe;AACtD,SAAO;CACR;CAED,MAAM,cAAsC;EAC1C,MAAM,yBAAyB,CAAC;yBACX,EAAE,KAAK,iBAAiB;;;uCAGV,EAAE,KAAK,aAAa,IAAI,EAAE;;;;;IAK7D,CAAC;AAED,MAAI;GACF,MAAM,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,aACpC,wBACA,EACE,WAAW,KAAK,UACjB,EACF;GACD,MAAM,UAAU,QAAQ,IAAI,CAACC,WAAmB,OAAO,IAAI,SAAS,CAAC;AAErE,yEAAuC,QAAQ;EAChD,SAAQ,GAAG;GACV,MAAM,QAAQ;AACd,SAAM,IAAI,MAAM,CAAC,qCAAqC,EAAE,MAAM,SAAS;EACxE;CACF;CAED,MAAM,WAAWC,SAAqC;EACpD,MAAM,wBAAwB,CAAC;yBACV,EAAE,KAAK,iBAAiB;;;4DAGW,EAAE,KAAK,iBAAiB;;;;;;IAMhF,CAAC;AAED,MAAI;GACF,MAAM,KAAK,OAAO,aAAa,uBAAuB;IACpD,WAAW,KAAK;IAChB,MAAM,QAAQ,SAAS;IACvB,SAAS,QAAQ;GAClB,EAAC;EACH,SAAQ,GAAG;GACV,MAAM,QAAQ;AACd,SAAM,IAAI,MAAM,CAAC,oCAAoC,EAAE,MAAM,SAAS;EACvE;CACF;CAED,MAAM,QAAQ;EACZ,MAAM,2BAA2B,CAAC;2BACX,EAAE,KAAK,iBAAiB;;;IAG/C,CAAC;AAED,MAAI;GACF,MAAM,KAAK,OAAO,aAAa,0BAA0B,EACvD,WAAW,KAAK,UACjB,EAAC;EACH,SAAQ,GAAG;GACV,MAAM,QAAQ;AACd,SAAM,IAAI,MACR,CAAC,2CAA2C,EAAE,MAAM,SAAS;EAEhE;CACF;CAED,MAAM,QAAQ;EACZ,MAAM,KAAK,OAAO,OAAO;CAC1B;AACF"}