{"version":3,"file":"multi_retrieval_qa.cjs","names":["MultiRouteChain","zipEntries","RouterOutputParser","z","PromptTemplate","STRUCTURED_MULTI_RETRIEVAL_ROUTER_TEMPLATE","LLMRouterChain","RetrievalQAChain","ConversationChain","DEFAULT_TEMPLATE"],"sources":["../../../src/chains/router/multi_retrieval_qa.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { interpolateFString, PromptTemplate } from \"@langchain/core/prompts\";\nimport { MultiRouteChain, MultiRouteChainInput } from \"./multi_route.js\";\nimport { BaseChain } from \"../../chains/base.js\";\nimport { LLMRouterChain } from \"./llm_router.js\";\nimport {\n  ConversationChain,\n  DEFAULT_TEMPLATE,\n} from \"../../chains/conversation.js\";\nimport { STRUCTURED_MULTI_RETRIEVAL_ROUTER_TEMPLATE } from \"./multi_retrieval_prompt.js\";\nimport { zipEntries } from \"./utils.js\";\nimport {\n  RetrievalQAChain,\n  RetrievalQAChainInput,\n} from \"../../chains/retrieval_qa.js\";\nimport { RouterOutputParser } from \"../../output_parsers/router.js\";\n\n/**\n * A type that represents the default values for the MultiRetrievalQAChain\n * class. It includes optional properties for the default retriever,\n * default prompt, and default chain.\n */\nexport type MultiRetrievalDefaults = {\n  defaultRetriever?: BaseRetrieverInterface;\n  defaultPrompt?: PromptTemplate;\n  defaultChain?: BaseChain;\n};\n\n/**\n * A class that represents a multi-retrieval question answering chain in\n * the LangChain framework. It extends the MultiRouteChain class and\n * provides additional functionality specific to multi-retrieval QA\n * chains.\n * @example\n * ```typescript\n * const multiRetrievalQAChain = MultiRetrievalQAChain.fromLLMAndRetrievers(\n *   new ChatOpenAI({ model: \"gpt-4o-mini\" }),\n *   {\n *     retrieverNames: [\"aqua teen\", \"mst3k\", \"animaniacs\"],\n *     retrieverDescriptions: [\n *       \"Good for answering questions about Aqua Teen Hunger Force theme song\",\n *       \"Good for answering questions about Mystery Science Theater 3000 theme song\",\n *       \"Good for answering questions about Animaniacs theme song\",\n *     ],\n *     retrievers: [\n *       new MemoryVectorStore().asRetriever(3),\n *       new MemoryVectorStore().asRetriever(3),\n *       new MemoryVectorStore().asRetriever(3),\n *     ],\n *     retrievalQAChainOpts: {\n *       returnSourceDocuments: true,\n *     },\n *   },\n * );\n *\n * const result = await multiRetrievalQAChain.call({\n *   input:\n *     \"In the Aqua Teen Hunger Force theme song, who calls himself the mike rula?\",\n * });\n *\n * console.log(result.sourceDocuments, result.text);\n * ```\n */\nexport class MultiRetrievalQAChain extends MultiRouteChain {\n  get outputKeys(): string[] {\n    return [\"result\"];\n  }\n\n  /**\n   * @deprecated Use `fromRetrieversAndPrompts` instead\n   */\n  static fromRetrievers(\n    llm: BaseLanguageModelInterface,\n    retrieverNames: string[],\n    retrieverDescriptions: string[],\n    retrievers: BaseRetrieverInterface[],\n    retrieverPrompts?: PromptTemplate[],\n    defaults?: MultiRetrievalDefaults,\n    options?: Omit<MultiRouteChainInput, \"defaultChain\">\n  ) {\n    return MultiRetrievalQAChain.fromLLMAndRetrievers(llm, {\n      retrieverNames,\n      retrieverDescriptions,\n      retrievers,\n      retrieverPrompts,\n      defaults,\n      multiRetrievalChainOpts: options,\n    });\n  }\n\n  /**\n   * A static method that creates an instance of MultiRetrievalQAChain from\n   * a BaseLanguageModel and a set of retrievers. It takes in optional\n   * parameters for the retriever names, descriptions, prompts, defaults,\n   * and additional options. It is an alternative method to fromRetrievers\n   * and provides more flexibility in configuring the underlying chains.\n   * @param llm A BaseLanguageModel instance.\n   * @param retrieverNames An array of retriever names.\n   * @param retrieverDescriptions An array of retriever descriptions.\n   * @param retrievers An array of BaseRetrieverInterface instances.\n   * @param retrieverPrompts An optional array of PromptTemplate instances for the retrievers.\n   * @param defaults An optional MultiRetrievalDefaults instance.\n   * @param multiRetrievalChainOpts Additional optional parameters for the multi-retrieval chain.\n   * @param retrievalQAChainOpts Additional optional parameters for the retrieval QA chain.\n   * @returns A new instance of MultiRetrievalQAChain.\n   */\n  static fromLLMAndRetrievers(\n    llm: BaseLanguageModelInterface,\n    {\n      retrieverNames,\n      retrieverDescriptions,\n      retrievers,\n      retrieverPrompts,\n      defaults,\n      multiRetrievalChainOpts,\n      retrievalQAChainOpts,\n    }: {\n      retrieverNames: string[];\n      retrieverDescriptions: string[];\n      retrievers: BaseRetrieverInterface[];\n      retrieverPrompts?: PromptTemplate[];\n      defaults?: MultiRetrievalDefaults;\n      multiRetrievalChainOpts?: Omit<MultiRouteChainInput, \"defaultChain\">;\n      retrievalQAChainOpts?: Partial<\n        Omit<RetrievalQAChainInput, \"retriever\" | \"combineDocumentsChain\">\n      > & {\n        prompt?: PromptTemplate;\n      };\n    }\n  ): MultiRetrievalQAChain {\n    const { defaultRetriever, defaultPrompt, defaultChain } = defaults ?? {};\n    if (defaultPrompt && !defaultRetriever) {\n      throw new Error(\n        \"`default_retriever` must be specified if `default_prompt` is \\nprovided. Received only `default_prompt`.\"\n      );\n    }\n    const destinations = zipEntries<[string, string]>(\n      retrieverNames,\n      retrieverDescriptions\n    ).map(([name, desc]) => `${name}: ${desc}`);\n\n    const structuredOutputParserSchema = z.object({\n      destination: z\n        .string()\n        .optional()\n        .describe('name of the question answering system to use or \"DEFAULT\"'),\n      next_inputs: z\n        .object({\n          query: z\n            .string()\n            .describe(\"a potentially modified version of the original input\"),\n        })\n        .describe(\"input to be fed to the next model\"),\n    });\n\n    const outputParser = new RouterOutputParser<\n      typeof structuredOutputParserSchema\n    >(structuredOutputParserSchema);\n\n    const destinationsStr = destinations.join(\"\\n\");\n    const routerTemplate = interpolateFString(\n      STRUCTURED_MULTI_RETRIEVAL_ROUTER_TEMPLATE(\n        outputParser.getFormatInstructions({ interpolationDepth: 4 })\n      ),\n      {\n        destinations: destinationsStr,\n      }\n    );\n    const routerPrompt = new PromptTemplate({\n      template: routerTemplate,\n      inputVariables: [\"input\"],\n      outputParser,\n    });\n\n    const routerChain = LLMRouterChain.fromLLM(llm, routerPrompt);\n    const prompts = retrieverPrompts ?? retrievers.map(() => null);\n    const destinationChains = zipEntries<\n      [string, BaseRetrieverInterface, PromptTemplate | null]\n    >(retrieverNames, retrievers, prompts).reduce(\n      (acc, [name, retriever, prompt]) => {\n        const opt: Partial<RetrievalQAChainInput> & {\n          prompt?: PromptTemplate;\n        } = retrievalQAChainOpts ?? {};\n        if (prompt) {\n          opt.prompt = prompt;\n        }\n        acc[name] = RetrievalQAChain.fromLLM(llm, retriever, opt);\n        return acc;\n      },\n      {} as { [name: string]: RetrievalQAChain }\n    );\n\n    let _defaultChain;\n    if (defaultChain) {\n      _defaultChain = defaultChain;\n    } else if (defaultRetriever) {\n      _defaultChain = RetrievalQAChain.fromLLM(llm, defaultRetriever, {\n        ...retrievalQAChainOpts,\n        prompt: defaultPrompt,\n      });\n    } else {\n      const promptTemplate = DEFAULT_TEMPLATE.replace(\"input\", \"query\");\n      const prompt = new PromptTemplate({\n        template: promptTemplate,\n        inputVariables: [\"history\", \"query\"],\n      });\n      _defaultChain = new ConversationChain({\n        llm,\n        prompt,\n        outputKey: \"result\",\n      });\n    }\n\n    return new MultiRetrievalQAChain({\n      ...multiRetrievalChainOpts,\n      routerChain,\n      destinationChains,\n      defaultChain: _defaultChain,\n    });\n  }\n\n  _chainType(): string {\n    return \"multi_retrieval_qa_chain\";\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,IAAa,wBAAb,MAAa,8BAA8BA,oBAAAA,gBAAgB;CACzD,IAAI,aAAuB;AACzB,SAAO,CAAC,SAAS;;;;;CAMnB,OAAO,eACL,KACA,gBACA,uBACA,YACA,kBACA,UACA,SACA;AACA,SAAO,sBAAsB,qBAAqB,KAAK;GACrD;GACA;GACA;GACA;GACA;GACA,yBAAyB;GAC1B,CAAC;;;;;;;;;;;;;;;;;;CAmBJ,OAAO,qBACL,KACA,EACE,gBACA,uBACA,YACA,kBACA,UACA,yBACA,wBAcqB;EACvB,MAAM,EAAE,kBAAkB,eAAe,iBAAiB,YAAY,EAAE;AACxE,MAAI,iBAAiB,CAAC,iBACpB,OAAM,IAAI,MACR,2GACD;EAEH,MAAM,eAAeC,cAAAA,WACnB,gBACA,sBACD,CAAC,KAAK,CAAC,MAAM,UAAU,GAAG,KAAK,IAAI,OAAO;EAgB3C,MAAM,eAAe,IAAIC,eAAAA,mBAdYC,OAAAA,EAAE,OAAO;GAC5C,aAAaA,OAAAA,EACV,QAAQ,CACR,UAAU,CACV,SAAS,8DAA4D;GACxE,aAAaA,OAAAA,EACV,OAAO,EACN,OAAOA,OAAAA,EACJ,QAAQ,CACR,SAAS,uDAAuD,EACpE,CAAC,CACD,SAAS,oCAAoC;GACjD,CAAC,CAI6B;EAE/B,MAAM,kBAAkB,aAAa,KAAK,KAAK;EAS/C,MAAM,eAAe,IAAIC,wBAAAA,eAAe;GACtC,WAAA,GAAA,wBAAA,oBARAC,+BAAAA,2CACE,aAAa,sBAAsB,EAAE,oBAAoB,GAAG,CAAC,CAC9D,EACD,EACE,cAAc,iBACf,CACF;GAGC,gBAAgB,CAAC,QAAQ;GACzB;GACD,CAAC;EAEF,MAAM,cAAcC,mBAAAA,eAAe,QAAQ,KAAK,aAAa;EAE7D,MAAM,oBAAoBL,cAAAA,WAExB,gBAAgB,YAHF,oBAAoB,WAAW,UAAU,KAAK,CAGxB,CAAC,QACpC,KAAK,CAAC,MAAM,WAAW,YAAY;GAClC,MAAM,MAEF,wBAAwB,EAAE;AAC9B,OAAI,OACF,KAAI,SAAS;AAEf,OAAI,QAAQM,qBAAAA,iBAAiB,QAAQ,KAAK,WAAW,IAAI;AACzD,UAAO;KAET,EAAE,CACH;EAED,IAAI;AACJ,MAAI,aACF,iBAAgB;WACP,iBACT,iBAAgBA,qBAAAA,iBAAiB,QAAQ,KAAK,kBAAkB;GAC9D,GAAG;GACH,QAAQ;GACT,CAAC;MAOF,iBAAgB,IAAIC,qBAAAA,kBAAkB;GACpC;GACA,QANa,IAAIJ,wBAAAA,eAAe;IAChC,UAFqBK,qBAAAA,iBAAiB,QAAQ,SAAS,QAAQ;IAG/D,gBAAgB,CAAC,WAAW,QAAQ;IACrC,CAAC;GAIA,WAAW;GACZ,CAAC;AAGJ,SAAO,IAAI,sBAAsB;GAC/B,GAAG;GACH;GACA;GACA,cAAc;GACf,CAAC;;CAGJ,aAAqB;AACnB,SAAO"}