{"version":3,"file":"cypher.cjs","names":["BaseChain","CYPHER_QA_PROMPT","CYPHER_GENERATION_PROMPT","LLMChain"],"sources":["../../../src/chains/graph_qa/cypher.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { LLMChain } from \"../llm_chain.js\";\nimport { BaseChain, ChainInputs } from \"../base.js\";\nimport { CYPHER_GENERATION_PROMPT, CYPHER_QA_PROMPT } from \"./prompts.js\";\nimport { logVersion020MigrationWarning } from \"../../util/entrypoint_deprecation.js\";\n\n/* #__PURE__ */ logVersion020MigrationWarning({\n  oldEntrypointName: \"chains/graph_qa/cypher\",\n  newPackageName: \"@langchain/community\",\n});\n\nexport const INTERMEDIATE_STEPS_KEY = \"intermediateSteps\";\n\nexport interface GraphCypherQAChainInput extends ChainInputs {\n  // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  graph: any;\n  cypherGenerationChain: LLMChain;\n  qaChain: LLMChain;\n  inputKey?: string;\n  outputKey?: string;\n  topK?: number;\n  returnIntermediateSteps?: boolean;\n  returnDirect?: boolean;\n}\n\nexport interface FromLLMInput {\n  // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  graph: any;\n  llm?: BaseLanguageModelInterface;\n  cypherLLM?: BaseLanguageModelInterface;\n  qaLLM?: BaseLanguageModelInterface;\n  qaPrompt?: BasePromptTemplate;\n  cypherPrompt?: BasePromptTemplate;\n  returnIntermediateSteps?: boolean;\n  returnDirect?: boolean;\n}\n\n/**\n * Chain for question-answering against a graph by generating Cypher statements.\n *\n * @example\n * ```typescript\n * const chain = new GraphCypherQAChain({\n *   llm: new ChatOpenAI({ model: \"gpt-4o-mini\", temperature: 0 }),\n *   graph: new Neo4jGraph(),\n * });\n * const res = await chain.invoke(\"Who played in Pulp Fiction?\");\n * ```\n *\n * @security\n * This chain will execute Cypher statements against the provided database.\n * Make sure that the database connection uses credentials\n * that are narrowly-scoped to only include necessary permissions.\n * Failure to do so may result in data corruption or loss, since the calling code\n * may attempt commands that would result in deletion, mutation of data\n * if appropriately prompted or reading sensitive data if such data is present in the database.\n * The best way to guard against such negative outcomes is to (as appropriate) limit the\n * permissions granted to the credentials used with this tool.\n *\n * See https://js.langchain.com/docs/security for more information.\n */\nexport class GraphCypherQAChain extends BaseChain {\n  // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  private graph: any;\n\n  private cypherGenerationChain: LLMChain;\n\n  private qaChain: LLMChain;\n\n  private inputKey = \"query\";\n\n  private outputKey = \"result\";\n\n  private topK = 10;\n\n  private returnDirect = false;\n\n  private returnIntermediateSteps = false;\n\n  constructor(props: GraphCypherQAChainInput) {\n    super(props);\n    const {\n      graph,\n      cypherGenerationChain,\n      qaChain,\n      inputKey,\n      outputKey,\n      topK,\n      returnIntermediateSteps,\n      returnDirect,\n    } = props;\n\n    this.graph = graph;\n    this.cypherGenerationChain = cypherGenerationChain;\n    this.qaChain = qaChain;\n\n    if (inputKey) {\n      this.inputKey = inputKey;\n    }\n    if (outputKey) {\n      this.outputKey = outputKey;\n    }\n    if (topK) {\n      this.topK = topK;\n    }\n    if (returnIntermediateSteps) {\n      this.returnIntermediateSteps = returnIntermediateSteps;\n    }\n    if (returnDirect) {\n      this.returnDirect = returnDirect;\n    }\n  }\n\n  _chainType() {\n    return \"graph_cypher_chain\" as const;\n  }\n\n  get inputKeys(): string[] {\n    return [this.inputKey];\n  }\n\n  get outputKeys(): string[] {\n    return [this.outputKey];\n  }\n\n  static fromLLM(props: FromLLMInput): GraphCypherQAChain {\n    const {\n      graph,\n      qaPrompt = CYPHER_QA_PROMPT,\n      cypherPrompt = CYPHER_GENERATION_PROMPT,\n      llm,\n      cypherLLM,\n      qaLLM,\n      returnIntermediateSteps = false,\n      returnDirect = false,\n    } = props;\n\n    if (!cypherLLM && !llm) {\n      throw new Error(\n        \"Either 'llm' or 'cypherLLM' parameters must be provided\"\n      );\n    }\n\n    if (!qaLLM && !llm) {\n      throw new Error(\"Either 'llm' or 'qaLLM' parameters must be provided\");\n    }\n\n    if (cypherLLM && qaLLM && llm) {\n      throw new Error(\n        \"You can specify up to two of 'cypherLLM', 'qaLLM', and 'llm', but not all three simultaneously.\"\n      );\n    }\n\n    const qaChain = new LLMChain({\n      llm: (qaLLM || llm) as BaseLanguageModelInterface,\n      prompt: qaPrompt,\n    });\n\n    const cypherGenerationChain = new LLMChain({\n      llm: (cypherLLM || llm) as BaseLanguageModelInterface,\n      prompt: cypherPrompt,\n    });\n\n    return new GraphCypherQAChain({\n      cypherGenerationChain,\n      qaChain,\n      graph,\n      returnIntermediateSteps,\n      returnDirect,\n    });\n  }\n\n  private extractCypher(text: string): string {\n    const pattern = /```(.*?)```/s;\n    const matches = text.match(pattern);\n    return matches ? matches[1] : text;\n  }\n\n  async _call(\n    values: ChainValues,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<ChainValues> {\n    const callbacks = runManager?.getChild();\n    const question = values[this.inputKey];\n\n    const intermediateSteps = [];\n\n    const generatedCypher = await this.cypherGenerationChain.call(\n      { question, schema: this.graph.getSchema() },\n      callbacks\n    );\n\n    const extractedCypher = this.extractCypher(generatedCypher.text);\n\n    await runManager?.handleText(`Generated Cypher:\\n`);\n    await runManager?.handleText(`${extractedCypher} green\\n`);\n\n    intermediateSteps.push({ query: extractedCypher });\n\n    let chainResult: ChainValues;\n    const context = await this.graph.query(extractedCypher, {\n      topK: this.topK,\n    });\n\n    if (this.returnDirect) {\n      chainResult = { [this.outputKey]: context };\n    } else {\n      await runManager?.handleText(\"Full Context:\\n\");\n      await runManager?.handleText(`${context} green\\n`);\n\n      intermediateSteps.push({ context });\n\n      const result = await this.qaChain.call(\n        { question, context: JSON.stringify(context) },\n        callbacks\n      );\n\n      chainResult = {\n        [this.outputKey]: result[this.qaChain.outputKey],\n      };\n    }\n\n    if (this.returnIntermediateSteps) {\n      chainResult[INTERMEDIATE_STEPS_KEY] = intermediateSteps;\n    }\n\n    return chainResult;\n  }\n}\n"],"mappings":";;;;;;;;;;;AAcA,MAAa,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;AAkDtC,IAAa,qBAAb,MAAa,2BAA2BA,aAAAA,UAAU;CAEhD;CAEA;CAEA;CAEA,WAAmB;CAEnB,YAAoB;CAEpB,OAAe;CAEf,eAAuB;CAEvB,0BAAkC;CAElC,YAAY,OAAgC;AAC1C,QAAM,MAAM;EACZ,MAAM,EACJ,OACA,uBACA,SACA,UACA,WACA,MACA,yBACA,iBACE;AAEJ,OAAK,QAAQ;AACb,OAAK,wBAAwB;AAC7B,OAAK,UAAU;AAEf,MAAI,SACF,MAAK,WAAW;AAElB,MAAI,UACF,MAAK,YAAY;AAEnB,MAAI,KACF,MAAK,OAAO;AAEd,MAAI,wBACF,MAAK,0BAA0B;AAEjC,MAAI,aACF,MAAK,eAAe;;CAIxB,aAAa;AACX,SAAO;;CAGT,IAAI,YAAsB;AACxB,SAAO,CAAC,KAAK,SAAS;;CAGxB,IAAI,aAAuB;AACzB,SAAO,CAAC,KAAK,UAAU;;CAGzB,OAAO,QAAQ,OAAyC;EACtD,MAAM,EACJ,OACA,WAAWC,gBAAAA,kBACX,eAAeC,gBAAAA,0BACf,KACA,WACA,OACA,0BAA0B,OAC1B,eAAe,UACb;AAEJ,MAAI,CAAC,aAAa,CAAC,IACjB,OAAM,IAAI,MACR,0DACD;AAGH,MAAI,CAAC,SAAS,CAAC,IACb,OAAM,IAAI,MAAM,sDAAsD;AAGxE,MAAI,aAAa,SAAS,IACxB,OAAM,IAAI,MACR,kGACD;EAGH,MAAM,UAAU,IAAIC,kBAAAA,SAAS;GAC3B,KAAM,SAAS;GACf,QAAQ;GACT,CAAC;AAOF,SAAO,IAAI,mBAAmB;GAC5B,uBAN4B,IAAIA,kBAAAA,SAAS;IACzC,KAAM,aAAa;IACnB,QAAQ;IACT,CAAC;GAIA;GACA;GACA;GACA;GACD,CAAC;;CAGJ,cAAsB,MAAsB;EAE1C,MAAM,UAAU,KAAK,MADL,eACmB;AACnC,SAAO,UAAU,QAAQ,KAAK;;CAGhC,MAAM,MACJ,QACA,YACsB;EACtB,MAAM,YAAY,YAAY,UAAU;EACxC,MAAM,WAAW,OAAO,KAAK;EAE7B,MAAM,oBAAoB,EAAE;EAE5B,MAAM,kBAAkB,MAAM,KAAK,sBAAsB,KACvD;GAAE;GAAU,QAAQ,KAAK,MAAM,WAAW;GAAE,EAC5C,UACD;EAED,MAAM,kBAAkB,KAAK,cAAc,gBAAgB,KAAK;AAEhE,QAAM,YAAY,WAAW,sBAAsB;AACnD,QAAM,YAAY,WAAW,GAAG,gBAAgB,UAAU;AAE1D,oBAAkB,KAAK,EAAE,OAAO,iBAAiB,CAAC;EAElD,IAAI;EACJ,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,iBAAiB,EACtD,MAAM,KAAK,MACZ,CAAC;AAEF,MAAI,KAAK,aACP,eAAc,GAAG,KAAK,YAAY,SAAS;OACtC;AACL,SAAM,YAAY,WAAW,kBAAkB;AAC/C,SAAM,YAAY,WAAW,GAAG,QAAQ,UAAU;AAElD,qBAAkB,KAAK,EAAE,SAAS,CAAC;GAEnC,MAAM,SAAS,MAAM,KAAK,QAAQ,KAChC;IAAE;IAAU,SAAS,KAAK,UAAU,QAAQ;IAAE,EAC9C,UACD;AAED,iBAAc,GACX,KAAK,YAAY,OAAO,KAAK,QAAQ,YACvC;;AAGH,MAAI,KAAK,wBACP,aAAY,0BAA0B;AAGxC,SAAO"}