{"version":3,"file":"violation_of_expectations_chain.cjs","names":["BaseChain","JsonOutputFunctionsParser","StringOutputParser","HumanMessage","PREDICT_NEXT_USER_MESSAGE_FUNCTION","PREDICT_NEXT_USER_MESSAGE_PROMPT","PREDICTION_VIOLATIONS_FUNCTION","PREDICTION_VIOLATIONS_PROMPT","GENERATE_REVISED_PREDICTION_PROMPT","GENERATE_FACTS_PROMPT"],"sources":["../../../../src/experimental/chains/violation_of_expectations/violation_of_expectations_chain.ts"],"sourcesContent":["import type { BaseRetrieverInterface } from \"@langchain/core/retrievers\";\nimport { ChatOpenAI } from \"@langchain/openai\";\nimport {\n  BaseMessage,\n  HumanMessage,\n  isBaseMessage,\n} from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport { StringOutputParser } from \"@langchain/core/output_parsers\";\nimport { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { JsonOutputFunctionsParser } from \"../../../output_parsers/openai_functions.js\";\nimport { BaseChain, ChainInputs } from \"../../../chains/base.js\";\nimport {\n  GetPredictionViolationsResponse,\n  MessageChunkResult,\n  PREDICTION_VIOLATIONS_FUNCTION,\n  PREDICT_NEXT_USER_MESSAGE_FUNCTION,\n  PredictNextUserMessageResponse,\n} from \"./types.js\";\nimport {\n  GENERATE_FACTS_PROMPT,\n  GENERATE_REVISED_PREDICTION_PROMPT,\n  PREDICTION_VIOLATIONS_PROMPT,\n  PREDICT_NEXT_USER_MESSAGE_PROMPT,\n} from \"./violation_of_expectations_prompt.js\";\n\n/**\n * Interface for the input parameters of the ViolationOfExpectationsChain class.\n */\nexport interface ViolationOfExpectationsChainInput extends ChainInputs {\n  /**\n   * The retriever to use for retrieving stored\n   * thoughts and insights.\n   */\n  retriever: BaseRetrieverInterface;\n  /**\n   * The LLM to use\n   */\n  llm: ChatOpenAI;\n}\n\n/**\n * Chain that generates key insights/facts of a user based on a\n * a chat conversation with an AI.\n */\nexport class ViolationOfExpectationsChain\n  extends BaseChain\n  implements ViolationOfExpectationsChainInput\n{\n  static lc_name() {\n    return \"ViolationOfExpectationsChain\";\n  }\n\n  _chainType(): string {\n    return \"violation_of_expectation_chain\";\n  }\n\n  chatHistoryKey = \"chat_history\";\n\n  thoughtsKey = \"thoughts\";\n\n  get inputKeys() {\n    return [this.chatHistoryKey];\n  }\n\n  get outputKeys() {\n    return [this.thoughtsKey];\n  }\n\n  retriever: BaseRetrieverInterface;\n\n  llm: ChatOpenAI;\n\n  jsonOutputParser: JsonOutputFunctionsParser;\n\n  stringOutputParser: StringOutputParser;\n\n  constructor(fields: ViolationOfExpectationsChainInput) {\n    super(fields);\n    this.retriever = fields.retriever;\n    this.llm = fields.llm;\n    this.jsonOutputParser = new JsonOutputFunctionsParser();\n    this.stringOutputParser = new StringOutputParser();\n  }\n\n  getChatHistoryString(chatHistory: BaseMessage[]): string {\n    return chatHistory\n      .map((chatMessage) => {\n        if (chatMessage._getType() === \"human\") {\n          return `Human: ${chatMessage.content}`;\n        } else if (chatMessage._getType() === \"ai\") {\n          return `AI: ${chatMessage.content}`;\n        } else {\n          return `${chatMessage.content}`;\n        }\n      })\n      .join(\"\\n\");\n  }\n\n  removeDuplicateStrings(strings: Array<string>): Array<string> {\n    return [...new Set(strings)];\n  }\n\n  /**\n   * This method breaks down the chat history into chunks of messages.\n   * Each chunk consists of a sequence of messages ending with an AI message and the subsequent user response, if any.\n   *\n   * @param {BaseMessage[]} chatHistory - The chat history to be chunked.\n   *\n   * @returns {MessageChunkResult[]} An array of message chunks. Each chunk includes a sequence of messages and the subsequent user response.\n   *\n   * @description\n   * The method iterates over the chat history and pushes each message into a temporary array.\n   * When it encounters an AI message, it checks for a subsequent user message.\n   * If a user message is found, it is considered as the user response to the AI message.\n   * If no user message is found after the AI message, the user response is undefined.\n   * The method then pushes the chunk (sequence of messages and user response) into the result array.\n   * This process continues until all messages in the chat history have been processed.\n   */\n  chunkMessagesByAIResponse(chatHistory: BaseMessage[]): MessageChunkResult[] {\n    const newArray: MessageChunkResult[] = [];\n    const tempArray: BaseMessage[] = [];\n\n    chatHistory.forEach((item, index) => {\n      tempArray.push(item);\n      if (item._getType() === \"ai\") {\n        let userResponse: BaseMessage | undefined = chatHistory[index + 1];\n        if (!userResponse || userResponse._getType() !== \"human\") {\n          userResponse = undefined;\n        }\n\n        newArray.push({\n          chunkedMessages: tempArray,\n          userResponse: userResponse\n            ? new HumanMessage(userResponse)\n            : undefined,\n        });\n      }\n    });\n\n    return newArray;\n  }\n\n  /**\n   * This method processes a chat history to generate insights about the user.\n   *\n   * @param {ChainValues} values - The input values for the chain. It should contain a key for chat history.\n   * @param {CallbackManagerForChainRun} [runManager] - Optional callback manager for the chain run.\n   *\n   * @returns {Promise<ChainValues>} A promise that resolves to a list of insights about the user.\n   *\n   * @throws {Error} If the chat history key is not found in the input values or if the chat history is not an array of BaseMessages.\n   *\n   * @description\n   * The method performs the following steps:\n   * 1. Checks if the chat history key is present in the input values and if the chat history is an array of BaseMessages.\n   * 2. Breaks the chat history into chunks of messages.\n   * 3. For each chunk, it generates an initial prediction for the user's next message.\n   * 4. For each prediction, it generates insights and prediction violations, and regenerates the prediction based on the violations.\n   * 5. For each set of messages, it generates a fact/insight about the user.\n   * The method returns a list of these insights.\n   */\n  async _call(\n    values: ChainValues,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<ChainValues> {\n    if (!(this.chatHistoryKey in values)) {\n      throw new Error(`Chat history key ${this.chatHistoryKey} not found`);\n    }\n\n    const chatHistory: unknown[] = values[this.chatHistoryKey];\n\n    const isEveryMessageBaseMessage = chatHistory.every((message) =>\n      isBaseMessage(message)\n    );\n    if (!isEveryMessageBaseMessage) {\n      throw new Error(\"Chat history must be an array of BaseMessages\");\n    }\n\n    const messageChunks = this.chunkMessagesByAIResponse(\n      chatHistory as BaseMessage[]\n    );\n\n    // Generate the initial prediction for every user message.\n    const userPredictions = await Promise.all(\n      messageChunks.map(async (chatHistoryChunk) => ({\n        userPredictions: await this.predictNextUserMessage(\n          chatHistoryChunk.chunkedMessages\n        ),\n        userResponse: chatHistoryChunk.userResponse,\n        runManager,\n      }))\n    );\n\n    // Generate insights, and prediction violations for every user message.\n    // This call also regenerates the prediction based on the violations.\n    const predictionViolations = await Promise.all(\n      userPredictions.map((prediction) =>\n        this.getPredictionViolations({\n          userPredictions: prediction.userPredictions,\n          userResponse: prediction.userResponse,\n          runManager,\n        })\n      )\n    );\n\n    // Generate a fact/insight about the user for every set of messages.\n    const insights = await Promise.all(\n      predictionViolations.map((violation) =>\n        this.generateFacts({\n          userResponse: violation.userResponse,\n          predictions: {\n            revisedPrediction: violation.revisedPrediction,\n            explainedPredictionErrors: violation.explainedPredictionErrors,\n          },\n        })\n      )\n    );\n\n    return {\n      insights,\n    };\n  }\n\n  /**\n   * This method predicts the next user message based on the chat history.\n   *\n   * @param {BaseMessage[]} chatHistory - The chat history based on which the next user message is predicted.\n   * @param {CallbackManagerForChainRun} [runManager] - Optional callback manager for the chain run.\n   *\n   * @returns {Promise<PredictNextUserMessageResponse>} A promise that resolves to the predicted next user message, the user state, and any insights.\n   *\n   * @throws {Error} If the response from the language model does not contain the expected keys: 'userState', 'predictedUserMessage', and 'insights'.\n   */\n  private async predictNextUserMessage(\n    chatHistory: BaseMessage[],\n    runManager?: CallbackManagerForChainRun\n  ): Promise<PredictNextUserMessageResponse> {\n    const messageString = this.getChatHistoryString(chatHistory);\n\n    const llmWithFunctions = this.llm\n      .bindTools([PREDICT_NEXT_USER_MESSAGE_FUNCTION])\n      .withConfig({\n        function_call: { name: PREDICT_NEXT_USER_MESSAGE_FUNCTION.name },\n      });\n\n    const chain = PREDICT_NEXT_USER_MESSAGE_PROMPT.pipe(llmWithFunctions).pipe(\n      this.jsonOutputParser\n    );\n\n    const res = await chain.invoke(\n      {\n        chat_history: messageString,\n      },\n      runManager?.getChild(\"prediction\")\n    );\n\n    if (\n      !(\n        \"userState\" in res &&\n        \"predictedUserMessage\" in res &&\n        \"insights\" in res\n      )\n    ) {\n      throw new Error(`Invalid response from LLM: ${JSON.stringify(res)}`);\n    }\n\n    const predictionResponse = res as PredictNextUserMessageResponse;\n\n    // Query the retriever for relevant insights. Use the generates insights as a query.\n    const retrievedDocs = await this.retrieveRelevantInsights(\n      predictionResponse.insights\n    );\n    const relevantDocs = this.removeDuplicateStrings([\n      ...predictionResponse.insights,\n      ...retrievedDocs,\n    ]);\n\n    return {\n      ...predictionResponse,\n      insights: relevantDocs,\n    };\n  }\n\n  /**\n   * Retrieves relevant insights based on the provided insights.\n   *\n   * @param {Array<string>} insights - An array of insights to be used for retrieving relevant documents.\n   *\n   * @returns {Promise<Array<string>>} A promise that resolves to an array of relevant insights content.\n   */\n  private async retrieveRelevantInsights(\n    insights: Array<string>\n  ): Promise<Array<string>> {\n    // Only extract the first relevant doc from the retriever. We don't need more than one.\n    const relevantInsightsDocuments = await Promise.all(\n      insights.map(async (insight) => {\n        const relevantInsight = await this.retriever.invoke(insight);\n        return relevantInsight[0];\n      })\n    );\n\n    const relevantInsightsContent = relevantInsightsDocuments.map(\n      (document) => document.pageContent\n    );\n\n    return relevantInsightsContent;\n  }\n\n  /**\n   * This method generates prediction violations based on the predicted and actual user responses.\n   * It also generates a revised prediction based on the identified violations.\n   *\n   * @param {Object} params - The parameters for the method.\n   * @param {PredictNextUserMessageResponse} params.userPredictions - The predicted user message, user state, and insights.\n   * @param {BaseMessage} [params.userResponse] - The actual user response.\n   * @param {CallbackManagerForChainRun} [params.runManager] - Optional callback manager for the chain run.\n   *\n   * @returns {Promise<{ userResponse: BaseMessage | undefined; revisedPrediction: string; explainedPredictionErrors: Array<string>; }>} A promise that resolves to an object containing the actual user response, the revised prediction, and the explained prediction errors.\n   *\n   * @throws {Error} If the response from the language model does not contain the expected keys: 'violationExplanation', 'explainedPredictionErrors', and 'accuratePrediction'.\n   */\n  private async getPredictionViolations({\n    userPredictions,\n    userResponse,\n    runManager,\n  }: {\n    userPredictions: PredictNextUserMessageResponse;\n    userResponse?: BaseMessage;\n    runManager?: CallbackManagerForChainRun;\n  }): Promise<GetPredictionViolationsResponse> {\n    const llmWithFunctions = this.llm\n      .bindTools([PREDICTION_VIOLATIONS_FUNCTION])\n      .withConfig({\n        function_call: { name: PREDICTION_VIOLATIONS_FUNCTION.name },\n      });\n\n    const chain = PREDICTION_VIOLATIONS_PROMPT.pipe(llmWithFunctions).pipe(\n      this.jsonOutputParser\n    );\n\n    if (typeof userResponse?.content !== \"string\") {\n      throw new Error(\"This chain does not support non-string model output.\");\n    }\n    const res = (await chain.invoke(\n      {\n        predicted_output: userPredictions.predictedUserMessage,\n        actual_output: userResponse?.content ?? \"\",\n        user_insights: userPredictions.insights.join(\"\\n\"),\n      },\n      runManager?.getChild(\"prediction_violations\")\n    )) as Awaited<{\n      violationExplanation: string;\n      explainedPredictionErrors: Array<string>;\n      accuratePrediction: boolean;\n    }>;\n\n    // Generate a revised prediction based on violations.\n    const revisedPrediction = await this.generateRevisedPrediction({\n      originalPrediction: userPredictions.predictedUserMessage,\n      explainedPredictionErrors: res.explainedPredictionErrors,\n      userInsights: userPredictions.insights,\n      runManager,\n    });\n\n    return {\n      userResponse,\n      revisedPrediction,\n      explainedPredictionErrors: res.explainedPredictionErrors,\n    };\n  }\n\n  /**\n   * This method generates a revised prediction based on the original prediction, explained prediction errors, and user insights.\n   *\n   * @param {Object} params - The parameters for the method.\n   * @param {string} params.originalPrediction - The original prediction made by the model.\n   * @param {Array<string>} params.explainedPredictionErrors - An array of explained prediction errors.\n   * @param {Array<string>} params.userInsights - An array of insights about the user.\n   * @param {CallbackManagerForChainRun} [params.runManager] - Optional callback manager for the chain run.\n   *\n   * @returns {Promise<string>} A promise that resolves to a revised prediction.\n   */\n  private async generateRevisedPrediction({\n    originalPrediction,\n    explainedPredictionErrors,\n    userInsights,\n    runManager,\n  }: {\n    originalPrediction: string;\n    explainedPredictionErrors: Array<string>;\n    userInsights: Array<string>;\n    runManager?: CallbackManagerForChainRun;\n  }): Promise<string> {\n    const revisedPredictionChain = GENERATE_REVISED_PREDICTION_PROMPT.pipe(\n      this.llm\n    ).pipe(this.stringOutputParser);\n\n    const revisedPredictionRes = await revisedPredictionChain.invoke(\n      {\n        prediction: originalPrediction,\n        explained_prediction_errors: explainedPredictionErrors.join(\"\\n\"),\n        user_insights: userInsights.join(\"\\n\"),\n      },\n      runManager?.getChild(\"prediction_revision\")\n    );\n\n    return revisedPredictionRes;\n  }\n\n  /**\n   * This method generates facts or insights about the user based on the revised prediction, explained prediction errors, and the user's response.\n   *\n   * @param {Object} params - The parameters for the method.\n   * @param {BaseMessage} [params.userResponse] - The actual user response.\n   * @param {Object} params.predictions - The revised prediction and explained prediction errors.\n   * @param {string} params.predictions.revisedPrediction - The revised prediction made by the model.\n   * @param {Array<string>} params.predictions.explainedPredictionErrors - An array of explained prediction errors.\n   * @param {CallbackManagerForChainRun} [params.runManager] - Optional callback manager for the chain run.\n   *\n   * @returns {Promise<string>} A promise that resolves to a string containing the generated facts or insights about the user.\n   */\n  private async generateFacts({\n    userResponse,\n    predictions,\n    runManager,\n  }: {\n    userResponse?: BaseMessage;\n    /**\n     * Optional if the prediction was accurate.\n     */\n    predictions: {\n      revisedPrediction: string;\n      explainedPredictionErrors: Array<string>;\n    };\n    runManager?: CallbackManagerForChainRun;\n  }): Promise<string> {\n    const chain = GENERATE_FACTS_PROMPT.pipe(this.llm).pipe(\n      this.stringOutputParser\n    );\n\n    if (typeof userResponse?.content !== \"string\") {\n      throw new Error(\"This chain does not support non-string model output.\");\n    }\n    const res = await chain.invoke(\n      {\n        prediction_violations: predictions.explainedPredictionErrors.join(\"\\n\"),\n        prediction: predictions.revisedPrediction,\n        user_message: userResponse?.content ?? \"\",\n      },\n      runManager?.getChild(\"generate_facts\")\n    );\n\n    return res;\n  }\n\n  /**\n   * Static method that creates a ViolationOfExpectationsChain instance from a\n   * ChatOpenAI and retriever. It also accepts optional options\n   * to customize the chain.\n   *\n   * @param llm The ChatOpenAI instance.\n   * @param retriever The retriever used for similarity search.\n   * @param options Optional options to customize the chain.\n   *\n   * @returns A new instance of ViolationOfExpectationsChain.\n   */\n  static fromLLM(\n    llm: ChatOpenAI,\n    retriever: BaseRetrieverInterface,\n    options?: Partial<\n      Omit<ViolationOfExpectationsChainInput, \"llm\" | \"retriever\">\n    >\n  ): ViolationOfExpectationsChain {\n    return new this({\n      retriever,\n      llm,\n      ...options,\n    });\n  }\n}\n"],"mappings":"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"}