{"version":3,"file":"summary_buffer.cjs","names":["BaseConversationSummaryMemory","getBufferString"],"sources":["../../src/memory/summary_buffer.ts"],"sourcesContent":["import { getBufferString } from \"@langchain/core/messages\";\nimport {\n  InputValues,\n  MemoryVariables,\n  OutputValues,\n} from \"@langchain/core/memory\";\nimport {\n  BaseConversationSummaryMemory,\n  BaseConversationSummaryMemoryInput,\n} from \"./summary.js\";\n\n/**\n * Interface for the input parameters of the\n * ConversationSummaryBufferMemory class.\n */\nexport interface ConversationSummaryBufferMemoryInput extends BaseConversationSummaryMemoryInput {\n  maxTokenLimit?: number;\n}\n\n/**\n * Class that extends BaseConversationSummaryMemory and implements\n * ConversationSummaryBufferMemoryInput. It manages the conversation\n * history in a LangChain application by maintaining a buffer of chat\n * messages and providing methods to load, save, prune, and clear the\n * memory.\n * @example\n * ```typescript\n * // Initialize the memory with a specific model and token limit\n * const memory = new ConversationSummaryBufferMemory({\n *   llm: new ChatOpenAI({ model: \"gpt-3.5-turbo-instruct\", temperature: 0 }),\n *   maxTokenLimit: 10,\n * });\n *\n * // Save conversation context to memory\n * await memory.saveContext({ input: \"hi\" }, { output: \"whats up\" });\n * await memory.saveContext({ input: \"not much you\" }, { output: \"not much\" });\n *\n * // Load the conversation history from memory\n * const history = await memory.loadMemoryVariables({});\n * console.log({ history });\n *\n * // Create a chat prompt using the conversation history\n * const chatPrompt = ChatPromptTemplate.fromMessages([\n *   SystemMessagePromptTemplate.fromTemplate(\n *     \"The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\",\n *   ),\n *   new MessagesPlaceholder(\"history\"),\n *   HumanMessagePromptTemplate.fromTemplate(\"{input}\"),\n * ]);\n *\n * // Initialize the conversation chain with the model, memory, and prompt\n * const chain = new ConversationChain({\n *   llm: new ChatOpenAI({ model: \"gpt-4o-mini\", temperature: 0.9, verbose: true }),\n *   memory: memory,\n *   prompt: chatPrompt,\n * });\n * ```\n */\nexport class ConversationSummaryBufferMemory\n  extends BaseConversationSummaryMemory\n  implements ConversationSummaryBufferMemoryInput\n{\n  movingSummaryBuffer = \"\";\n\n  maxTokenLimit = 2000;\n\n  constructor(fields: ConversationSummaryBufferMemoryInput) {\n    super(fields);\n\n    this.maxTokenLimit = fields?.maxTokenLimit ?? this.maxTokenLimit;\n  }\n\n  get memoryKeys() {\n    return [this.memoryKey];\n  }\n\n  /**\n   * Method that loads the chat messages from the memory and returns them as\n   * a string or as a list of messages, depending on the returnMessages\n   * property.\n   * @param _ InputValues object, not used in this method.\n   * @returns Promise that resolves with MemoryVariables object containing the loaded chat messages.\n   */\n  async loadMemoryVariables(_?: InputValues): Promise<MemoryVariables> {\n    let buffer = await this.chatHistory.getMessages();\n    if (this.movingSummaryBuffer) {\n      buffer = [\n        new this.summaryChatMessageClass(this.movingSummaryBuffer),\n        ...buffer,\n      ];\n    }\n\n    let finalBuffer;\n    if (this.returnMessages) {\n      finalBuffer = buffer;\n    } else {\n      finalBuffer = getBufferString(buffer, this.humanPrefix, this.aiPrefix);\n    }\n\n    return { [this.memoryKey]: finalBuffer };\n  }\n\n  /**\n   * Method that saves the context of the conversation, including the input\n   * and output values, and prunes the memory if it exceeds the maximum\n   * token limit.\n   * @param inputValues InputValues object containing the input values of the conversation.\n   * @param outputValues OutputValues object containing the output values of the conversation.\n   * @returns Promise that resolves when the context is saved and the memory is pruned.\n   */\n  async saveContext(\n    inputValues: InputValues,\n    outputValues: OutputValues\n  ): Promise<void> {\n    await super.saveContext(inputValues, outputValues);\n    await this.prune();\n  }\n\n  /**\n   * Method that prunes the memory if the total number of tokens in the\n   * buffer exceeds the maxTokenLimit. It removes messages from the\n   * beginning of the buffer until the total number of tokens is within the\n   * limit.\n   * @returns Promise that resolves when the memory is pruned.\n   */\n  async prune() {\n    // Prune buffer if it exceeds max token limit\n    let buffer = await this.chatHistory.getMessages();\n    if (this.movingSummaryBuffer) {\n      buffer = [\n        new this.summaryChatMessageClass(this.movingSummaryBuffer),\n        ...buffer,\n      ];\n    }\n\n    let currBufferLength = await this.llm.getNumTokens(\n      getBufferString(buffer, this.humanPrefix, this.aiPrefix)\n    );\n\n    if (currBufferLength > this.maxTokenLimit) {\n      const prunedMemory = [];\n      while (currBufferLength > this.maxTokenLimit) {\n        const poppedMessage = buffer.shift();\n        if (poppedMessage) {\n          prunedMemory.push(poppedMessage);\n          currBufferLength = await this.llm.getNumTokens(\n            getBufferString(buffer, this.humanPrefix, this.aiPrefix)\n          );\n        }\n      }\n      this.movingSummaryBuffer = await this.predictNewSummary(\n        prunedMemory,\n        this.movingSummaryBuffer\n      );\n    }\n  }\n\n  /**\n   * Method that clears the memory and resets the movingSummaryBuffer.\n   * @returns Promise that resolves when the memory is cleared.\n   */\n  async clear() {\n    await super.clear();\n    this.movingSummaryBuffer = \"\";\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,IAAa,kCAAb,cACUA,gBAAAA,8BAEV;CACE,sBAAsB;CAEtB,gBAAgB;CAEhB,YAAY,QAA8C;EACxD,MAAM,MAAM;EAEZ,KAAK,gBAAgB,QAAQ,iBAAiB,KAAK;CACrD;CAEA,IAAI,aAAa;EACf,OAAO,CAAC,KAAK,SAAS;CACxB;;;;;;;;CASA,MAAM,oBAAoB,GAA2C;EACnE,IAAI,SAAS,MAAM,KAAK,YAAY,YAAY;EAChD,IAAI,KAAK,qBACP,SAAS,CACP,IAAI,KAAK,wBAAwB,KAAK,mBAAmB,GACzD,GAAG,MACL;EAGF,IAAI;EACJ,IAAI,KAAK,gBACP,cAAc;OAEd,eAAA,GAAcC,yBAAAA,gBAAAA,CAAgB,QAAQ,KAAK,aAAa,KAAK,QAAQ;EAGvE,OAAO,GAAG,KAAK,YAAY,YAAY;CACzC;;;;;;;;;CAUA,MAAM,YACJ,aACA,cACe;EACf,MAAM,MAAM,YAAY,aAAa,YAAY;EACjD,MAAM,KAAK,MAAM;CACnB;;;;;;;;CASA,MAAM,QAAQ;EAEZ,IAAI,SAAS,MAAM,KAAK,YAAY,YAAY;EAChD,IAAI,KAAK,qBACP,SAAS,CACP,IAAI,KAAK,wBAAwB,KAAK,mBAAmB,GACzD,GAAG,MACL;EAGF,IAAI,mBAAmB,MAAM,KAAK,IAAI,cAAA,GACpCA,yBAAAA,gBAAAA,CAAgB,QAAQ,KAAK,aAAa,KAAK,QAAQ,CACzD;EAEA,IAAI,mBAAmB,KAAK,eAAe;GACzC,MAAM,eAAe,CAAC;GACtB,OAAO,mBAAmB,KAAK,eAAe;IAC5C,MAAM,gBAAgB,OAAO,MAAM;IACnC,IAAI,eAAe;KACjB,aAAa,KAAK,aAAa;KAC/B,mBAAmB,MAAM,KAAK,IAAI,cAAA,GAChCA,yBAAAA,gBAAAA,CAAgB,QAAQ,KAAK,aAAa,KAAK,QAAQ,CACzD;IACF;GACF;GACA,KAAK,sBAAsB,MAAM,KAAK,kBACpC,cACA,KAAK,mBACP;EACF;CACF;;;;;CAMA,MAAM,QAAQ;EACZ,MAAM,MAAM,MAAM;EAClB,KAAK,sBAAsB;CAC7B;AACF"}