{"version":3,"file":"summary_buffer.cjs","names":["BaseConversationSummaryMemory"],"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;AACxD,QAAM,OAAO;AAEb,OAAK,gBAAgB,QAAQ,iBAAiB,KAAK;;CAGrD,IAAI,aAAa;AACf,SAAO,CAAC,KAAK,UAAU;;;;;;;;;CAUzB,MAAM,oBAAoB,GAA2C;EACnE,IAAI,SAAS,MAAM,KAAK,YAAY,aAAa;AACjD,MAAI,KAAK,oBACP,UAAS,CACP,IAAI,KAAK,wBAAwB,KAAK,oBAAoB,EAC1D,GAAG,OACJ;EAGH,IAAI;AACJ,MAAI,KAAK,eACP,eAAc;MAEd,gBAAA,GAAA,yBAAA,iBAA8B,QAAQ,KAAK,aAAa,KAAK,SAAS;AAGxE,SAAO,GAAG,KAAK,YAAY,aAAa;;;;;;;;;;CAW1C,MAAM,YACJ,aACA,cACe;AACf,QAAM,MAAM,YAAY,aAAa,aAAa;AAClD,QAAM,KAAK,OAAO;;;;;;;;;CAUpB,MAAM,QAAQ;EAEZ,IAAI,SAAS,MAAM,KAAK,YAAY,aAAa;AACjD,MAAI,KAAK,oBACP,UAAS,CACP,IAAI,KAAK,wBAAwB,KAAK,oBAAoB,EAC1D,GAAG,OACJ;EAGH,IAAI,mBAAmB,MAAM,KAAK,IAAI,cAAA,GAAA,yBAAA,iBACpB,QAAQ,KAAK,aAAa,KAAK,SAAS,CACzD;AAED,MAAI,mBAAmB,KAAK,eAAe;GACzC,MAAM,eAAe,EAAE;AACvB,UAAO,mBAAmB,KAAK,eAAe;IAC5C,MAAM,gBAAgB,OAAO,OAAO;AACpC,QAAI,eAAe;AACjB,kBAAa,KAAK,cAAc;AAChC,wBAAmB,MAAM,KAAK,IAAI,cAAA,GAAA,yBAAA,iBAChB,QAAQ,KAAK,aAAa,KAAK,SAAS,CACzD;;;AAGL,QAAK,sBAAsB,MAAM,KAAK,kBACpC,cACA,KAAK,oBACN;;;;;;;CAQL,MAAM,QAAQ;AACZ,QAAM,MAAM,OAAO;AACnB,OAAK,sBAAsB"}