{"version":3,"file":"history.cjs","names":["RunnableBinding","RunnableLambda","RunnablePassthrough","isBaseMessage","HumanMessage","AIMessage"],"sources":["../../src/runnables/history.ts"],"sourcesContent":["import {\n  BaseChatMessageHistory,\n  BaseListChatMessageHistory,\n} from \"../chat_history.js\";\nimport {\n  AIMessage,\n  BaseMessage,\n  HumanMessage,\n  isBaseMessage,\n} from \"../messages/index.js\";\nimport { Run } from \"../tracers/base.js\";\nimport {\n  Runnable,\n  RunnableBinding,\n  type RunnableBindingArgs,\n  RunnableLambda,\n} from \"./base.js\";\nimport { RunnableConfig } from \"./config.js\";\nimport { RunnablePassthrough } from \"./passthrough.js\";\n\ntype GetSessionHistoryCallable = (\n  // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n  ...args: Array<any>\n) =>\n  | Promise<BaseChatMessageHistory | BaseListChatMessageHistory>\n  | BaseChatMessageHistory\n  | BaseListChatMessageHistory;\n\nexport interface RunnableWithMessageHistoryInputs<\n  RunInput,\n  RunOutput,\n> extends Omit<RunnableBindingArgs<RunInput, RunOutput>, \"bound\" | \"config\"> {\n  runnable: Runnable<RunInput, RunOutput>;\n  getMessageHistory: GetSessionHistoryCallable;\n  inputMessagesKey?: string;\n  outputMessagesKey?: string;\n  historyMessagesKey?: string;\n  config?: RunnableConfig;\n}\n\n/**\n * Wraps a LCEL chain and manages history. It appends input messages\n * and chain outputs as history, and adds the current history messages to\n * the chain input.\n *\n * @deprecated Use LangGraph's built-in persistence instead.\n *\n * @example\n * ```typescript\n * // pnpm install @langchain/anthropic @langchain/classic\n *\n * import {\n *   ChatPromptTemplate,\n *   MessagesPlaceholder,\n * } from \"@langchain/core/prompts\";\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n * import { ChatMessageHistory } from \"@langchain/classic/stores/message/in_memory\";\n *\n * const prompt = ChatPromptTemplate.fromMessages([\n *   [\"system\", \"You're an assistant who's good at {ability}\"],\n *   new MessagesPlaceholder(\"history\"),\n *   [\"human\", \"{question}\"],\n * ]);\n *\n * const chain = prompt.pipe(new ChatAnthropic({}));\n *\n * const chainWithHistory = new RunnableWithMessageHistory({\n *   runnable: chain,\n *   getMessageHistory: (sessionId) =>\n *     new UpstashRedisChatMessageHistory({\n *       sessionId,\n *       config: {\n *         url: process.env.UPSTASH_REDIS_REST_URL!,\n *         token: process.env.UPSTASH_REDIS_REST_TOKEN!,\n *       },\n *     }),\n *   inputMessagesKey: \"question\",\n *   historyMessagesKey: \"history\",\n * });\n *\n * const result = await chainWithHistory.invoke(\n *   {\n *     ability: \"math\",\n *     question: \"What does cosine mean?\",\n *   },\n *   {\n *     configurable: {\n *       sessionId: \"some_string_identifying_a_user\",\n *     },\n *   }\n * );\n *\n * const result2 = await chainWithHistory.invoke(\n *   {\n *     ability: \"math\",\n *     question: \"What's its inverse?\",\n *   },\n *   {\n *     configurable: {\n *       sessionId: \"some_string_identifying_a_user\",\n *     },\n *   }\n * );\n * ```\n */\nexport class RunnableWithMessageHistory<\n  RunInput,\n  RunOutput,\n> extends RunnableBinding<RunInput, RunOutput> {\n  runnable: Runnable<RunInput, RunOutput>;\n\n  inputMessagesKey?: string;\n\n  outputMessagesKey?: string;\n\n  historyMessagesKey?: string;\n\n  getMessageHistory: GetSessionHistoryCallable;\n\n  constructor(fields: RunnableWithMessageHistoryInputs<RunInput, RunOutput>) {\n    let historyChain: Runnable = RunnableLambda.from((input, options) =>\n      this._enterHistory(input, options ?? {})\n    ).withConfig({ runName: \"loadHistory\" });\n\n    const messagesKey = fields.historyMessagesKey ?? fields.inputMessagesKey;\n    if (messagesKey) {\n      historyChain = RunnablePassthrough.assign({\n        [messagesKey]: historyChain,\n      }).withConfig({ runName: \"insertHistory\" });\n    }\n\n    const bound = historyChain\n      .pipe(\n        fields.runnable.withListeners({\n          onEnd: (run, config) => this._exitHistory(run, config ?? {}),\n        })\n      )\n      .withConfig({ runName: \"RunnableWithMessageHistory\" });\n\n    const config = fields.config ?? {};\n\n    super({\n      ...fields,\n      config,\n      bound,\n    });\n    this.runnable = fields.runnable;\n    this.getMessageHistory = fields.getMessageHistory;\n    this.inputMessagesKey = fields.inputMessagesKey;\n    this.outputMessagesKey = fields.outputMessagesKey;\n    this.historyMessagesKey = fields.historyMessagesKey;\n  }\n\n  _getInputMessages(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    inputValue: string | BaseMessage | Array<BaseMessage> | Record<string, any>\n  ): Array<BaseMessage> {\n    let parsedInputValue;\n    if (\n      typeof inputValue === \"object\" &&\n      !Array.isArray(inputValue) &&\n      !isBaseMessage(inputValue)\n    ) {\n      let key;\n      if (this.inputMessagesKey) {\n        key = this.inputMessagesKey;\n      } else if (Object.keys(inputValue).length === 1) {\n        key = Object.keys(inputValue)[0];\n      } else {\n        key = \"input\";\n      }\n      if (Array.isArray(inputValue[key]) && Array.isArray(inputValue[key][0])) {\n        parsedInputValue = inputValue[key][0];\n      } else {\n        parsedInputValue = inputValue[key];\n      }\n    } else {\n      parsedInputValue = inputValue;\n    }\n    if (typeof parsedInputValue === \"string\") {\n      return [new HumanMessage(parsedInputValue)];\n    } else if (Array.isArray(parsedInputValue)) {\n      return parsedInputValue;\n    } else if (isBaseMessage(parsedInputValue)) {\n      return [parsedInputValue];\n    } else {\n      throw new Error(\n        `Expected a string, BaseMessage, or array of BaseMessages.\\nGot ${JSON.stringify(\n          parsedInputValue,\n          null,\n          2\n        )}`\n      );\n    }\n  }\n\n  _getOutputMessages(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    outputValue: string | BaseMessage | Array<BaseMessage> | Record<string, any>\n  ): Array<BaseMessage> {\n    let parsedOutputValue;\n    if (\n      !Array.isArray(outputValue) &&\n      !isBaseMessage(outputValue) &&\n      typeof outputValue !== \"string\"\n    ) {\n      let key;\n      if (this.outputMessagesKey !== undefined) {\n        key = this.outputMessagesKey;\n      } else if (Object.keys(outputValue).length === 1) {\n        key = Object.keys(outputValue)[0];\n      } else {\n        key = \"output\";\n      }\n      // If you are wrapping a chat model directly\n      // The output is actually this weird generations object\n      if (outputValue.generations !== undefined) {\n        parsedOutputValue = outputValue.generations[0][0].message;\n      } else {\n        parsedOutputValue = outputValue[key];\n      }\n    } else {\n      parsedOutputValue = outputValue;\n    }\n\n    if (typeof parsedOutputValue === \"string\") {\n      return [new AIMessage(parsedOutputValue)];\n    } else if (Array.isArray(parsedOutputValue)) {\n      return parsedOutputValue;\n    } else if (isBaseMessage(parsedOutputValue)) {\n      return [parsedOutputValue];\n    } else {\n      throw new Error(\n        `Expected a string, BaseMessage, or array of BaseMessages. Received: ${JSON.stringify(\n          parsedOutputValue,\n          null,\n          2\n        )}`\n      );\n    }\n  }\n\n  async _enterHistory(\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    input: any,\n    kwargs?: RunnableConfig\n  ): Promise<BaseMessage[]> {\n    const history = kwargs?.configurable?.messageHistory;\n    const messages = await history.getMessages();\n    if (this.historyMessagesKey === undefined) {\n      return messages.concat(this._getInputMessages(input));\n    }\n    return messages;\n  }\n\n  async _exitHistory(run: Run, config: RunnableConfig): Promise<void> {\n    const history = config.configurable?.messageHistory;\n\n    // Get input messages\n    let inputs;\n    // Chat model inputs are nested arrays\n    if (Array.isArray(run.inputs) && Array.isArray(run.inputs[0])) {\n      inputs = run.inputs[0];\n    } else {\n      inputs = run.inputs;\n    }\n    let inputMessages = this._getInputMessages(inputs);\n    // If historic messages were prepended to the input messages, remove them to\n    // avoid adding duplicate messages to history.\n    if (this.historyMessagesKey === undefined) {\n      const existingMessages = await history.getMessages();\n      inputMessages = inputMessages.slice(existingMessages.length);\n    }\n    // Get output messages\n    const outputValue = run.outputs;\n    if (!outputValue) {\n      throw new Error(\n        `Output values from 'Run' undefined. Run: ${JSON.stringify(\n          run,\n          null,\n          2\n        )}`\n      );\n    }\n    const outputMessages = this._getOutputMessages(outputValue);\n    await history.addMessages([...inputMessages, ...outputMessages]);\n  }\n\n  async _mergeConfig(...configs: Array<RunnableConfig | undefined>) {\n    const config = await super._mergeConfig(...configs);\n    // Extract sessionId\n    if (!config.configurable || !config.configurable.sessionId) {\n      const exampleInput = {\n        [this.inputMessagesKey ?? \"input\"]: \"foo\",\n      };\n      const exampleConfig = { configurable: { sessionId: \"123\" } };\n      throw new Error(\n        `sessionId is required. Pass it in as part of the config argument to .invoke() or .stream()\\n` +\n          `eg. chain.invoke(${JSON.stringify(exampleInput)}, ${JSON.stringify(\n            exampleConfig\n          )})`\n      );\n    }\n    // attach messageHistory\n    const { sessionId } = config.configurable;\n    config.configurable.messageHistory =\n      await this.getMessageHistory(sessionId);\n    return config;\n  }\n}\n"],"mappings":"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"}