{"version":3,"file":"zep.cjs","names":["HumanMessage","SystemMessage","AIMessage","ChatMessage","ZepClient","NotFoundError","BaseMemory","Message"],"sources":["../../src/memory/zep.ts"],"sourcesContent":["import {\n  Memory as BaseMemory,\n  Message,\n  NotFoundError,\n  ZepClient,\n} from \"@getzep/zep-js\";\nimport {\n  InputValues,\n  OutputValues,\n  MemoryVariables,\n  getInputValue,\n  getOutputValue,\n} from \"@langchain/core/memory\";\nimport {\n  getBufferString,\n  AIMessage,\n  BaseMessage,\n  ChatMessage,\n  HumanMessage,\n  SystemMessage,\n} from \"@langchain/core/messages\";\nimport { BaseChatMemory, BaseChatMemoryInput } from \"./chat_memory.js\";\n\n// Simple type for processed Zep memory data\ninterface ZepMemoryData {\n  messages: Array<{\n    role: string;\n    content: string;\n  }>;\n  summary?: {\n    content?: string;\n  };\n}\n\n/**\n * Extracts summary from Zep memory and composes a system prompt.\n * @param memory - The memory object containing potential summary.\n * @returns A string containing the summary as a system prompt.\n */\nexport const zepMemoryContextToSystemPrompt = (memory: ZepMemoryData) => {\n  let systemPrompt = \"\";\n\n  // Extract summary, if present\n  if (memory.summary && memory.summary?.content) {\n    systemPrompt += memory.summary.content;\n  }\n\n  return systemPrompt;\n};\n\n/**\n * Condenses Zep memory context into a single HumanMessage.\n * This is particularly useful for models like Claude that have limitations with system messages\n * (e.g., Anthropic's Claude only supports one system message and doesn't support multiple user messages in a row).\n *\n * @param memory - The memory object containing conversation history.\n * @param humanPrefix - The prefix to use for human messages (default: \"Human\").\n * @param aiPrefix - The prefix to use for AI messages (default: \"AI\").\n * @returns A HumanMessage containing the condensed memory context.\n */\nexport const condenseZepMemoryIntoHumanMessage = (memory: ZepMemoryData) => {\n  const systemPrompt = zepMemoryContextToSystemPrompt(memory);\n\n  let concatMessages = \"\";\n\n  // Add message history to the prompt, if present\n  if (memory.messages) {\n    concatMessages = memory.messages\n      .map((msg) => `${msg.role}: ${msg.content}`)\n      .join(\"\\n\");\n  }\n\n  return new HumanMessage(\n    `${systemPrompt ? `${systemPrompt}\\n` : \"\"}${concatMessages}`\n  );\n};\n\n/**\n * Converts Zep Memory to a list of BaseMessages, preserving the structure.\n * Creates a SystemMessage from summary and facts, and converts the rest of the messages\n * to their corresponding message types.\n *\n * @param memory - The memory object containing conversation history.\n * @param humanPrefix - The prefix to use for human messages (default: \"Human\").\n * @param aiPrefix - The prefix to use for AI messages (default: \"AI\").\n * @returns An array of BaseMessage objects representing the conversation history.\n */\nexport const zepMemoryToMessages = (\n  memory: ZepMemoryData,\n  humanPrefix = \"Human\",\n  aiPrefix = \"AI\"\n) => {\n  const systemPrompt = zepMemoryContextToSystemPrompt(memory);\n\n  let messages: BaseMessage[] = systemPrompt\n    ? [new SystemMessage(systemPrompt)]\n    : [];\n\n  if (memory && memory.messages) {\n    messages = messages.concat(\n      memory.messages\n        .filter((m) => m.content)\n        .map((message) => {\n          const { content, role } = message;\n          if (role === humanPrefix) {\n            return new HumanMessage(content);\n          } else if (role === aiPrefix) {\n            return new AIMessage(content);\n          } else {\n            // default to generic ChatMessage\n            return new ChatMessage(content, role);\n          }\n        })\n    );\n  }\n\n  return messages;\n};\n\n/**\n * Interface defining the structure of the input data for the ZepMemory\n * class. It includes properties like humanPrefix, aiPrefix, memoryKey,\n * baseURL, sessionId, apiKey, and separateMessages.\n */\nexport interface ZepMemoryInput extends BaseChatMemoryInput {\n  humanPrefix?: string;\n\n  aiPrefix?: string;\n\n  memoryKey?: string;\n\n  baseURL: string;\n\n  sessionId: string;\n\n  // apiKey is optional.\n  apiKey?: string;\n\n  /**\n   * Whether to return separate messages for chat history with a SystemMessage containing facts and summary,\n   * or return a single HumanMessage with the entire memory context.\n   * Defaults to true (preserving message types) for backward compatibility.\n   *\n   * Keep as true for models that fully support system messages.\n   * Set to false for models like Claude that have limitations with system messages.\n   */\n  separateMessages?: boolean;\n}\n\n/**\n * Class used to manage the memory of a chat session, including loading\n * and saving the chat history, and clearing the memory when needed. It\n * uses the ZepClient to interact with the Zep service for managing the\n * chat session's memory.\n *\n * The class provides options for handling different LLM requirements:\n * - Use separateMessages=true (default) for models that fully support system messages\n * - Use separateMessages=false for models like Claude that have limitations with system messages\n *\n * @example\n * ```typescript\n * const sessionId = randomUUID();\n * const zepURL = \"http://your-zep-url\";\n *\n * // Initialize ZepMemory with session ID, base URL, and API key\n * const memory = new ZepMemory({\n *   sessionId,\n *   baseURL: zepURL,\n *   apiKey: \"change_this_key\",\n *   // Set to false for models like Claude that have limitations with system messages\n *   // Defaults to true for backward compatibility\n *   separateMessages: false,\n * });\n *\n * // Create a ChatOpenAI model instance with specific parameters\n * const model = new ChatOpenAI({\n *   model: \"gpt-3.5-turbo\",\n *   temperature: 0,\n * });\n *\n * // Create a ConversationChain with the model and memory\n * const chain = new ConversationChain({ llm: model, memory });\n *\n * // Example of calling the chain with an input\n * const res1 = await chain.call({ input: \"Hi! I'm Jim.\" });\n * console.log({ res1 });\n *\n * // Follow-up call to the chain to demonstrate memory usage\n * const res2 = await chain.call({ input: \"What did I just say my name was?\" });\n * console.log({ res2 });\n *\n * // Output the session ID and the current state of memory\n * console.log(\"Session ID: \", sessionId);\n * console.log(\"Memory: \", await memory.loadMemoryVariables({}));\n *\n * ```\n */\nexport class ZepMemory extends BaseChatMemory implements ZepMemoryInput {\n  humanPrefix = \"Human\";\n\n  aiPrefix = \"AI\";\n\n  memoryKey = \"history\";\n\n  baseURL: string;\n\n  sessionId: string;\n\n  zepClientPromise: Promise<ZepClient>;\n\n  private readonly zepInitFailMsg = \"ZepClient is not initialized\";\n\n  /**\n   * Whether to return separate messages for chat history with a SystemMessage containing facts and summary,\n   * or return a single HumanMessage with the entire memory context.\n   * Defaults to true (preserving message types) for backward compatibility.\n   *\n   * Keep as true for models that fully support system messages.\n   * Set to false for models like Claude that have limitations with system messages.\n   */\n  separateMessages: boolean;\n\n  constructor(fields: ZepMemoryInput) {\n    super({\n      returnMessages: fields?.returnMessages ?? false,\n      inputKey: fields?.inputKey,\n      outputKey: fields?.outputKey,\n    });\n\n    this.humanPrefix = fields.humanPrefix ?? this.humanPrefix;\n    this.aiPrefix = fields.aiPrefix ?? this.aiPrefix;\n    this.memoryKey = fields.memoryKey ?? this.memoryKey;\n    this.baseURL = fields.baseURL;\n    this.sessionId = fields.sessionId;\n    this.separateMessages = fields.separateMessages ?? true;\n    this.zepClientPromise = ZepClient.init(this.baseURL, fields.apiKey);\n  }\n\n  get memoryKeys() {\n    return [this.memoryKey];\n  }\n\n  /**\n   * Method that retrieves the chat history from the Zep service and formats\n   * it into a list of messages.\n   * @param values Input values for the method.\n   * @returns Promise that resolves with the chat history formatted into a list of messages.\n   */\n  async loadMemoryVariables(values: InputValues): Promise<MemoryVariables> {\n    // use either lastN provided by developer or undefined to use the\n    // server preset.\n\n    // Wait for ZepClient to be initialized\n    const zepClient = await this.zepClientPromise;\n    if (!zepClient) {\n      throw new Error(this.zepInitFailMsg);\n    }\n\n    const lastN = values.lastN ?? undefined;\n\n    let memory: BaseMemory | null = null;\n    try {\n      memory = await zepClient.memory.getMemory(this.sessionId, lastN);\n    } catch (error) {\n      // eslint-disable-next-line no-instanceof/no-instanceof\n      if (error instanceof NotFoundError) {\n        const result = this.returnMessages\n          ? { [this.memoryKey]: [] }\n          : { [this.memoryKey]: \"\" };\n        return result;\n      } else {\n        throw error;\n      }\n    }\n\n    // Convert BaseMemory to ZepMemoryData\n    const memoryData: ZepMemoryData = {\n      messages:\n        memory?.messages.map((msg: Message) => ({\n          role: msg.role,\n          content: msg.content,\n        })) || [],\n      summary: memory?.summary,\n    };\n\n    if (this.returnMessages) {\n      return {\n        [this.memoryKey]: this.separateMessages\n          ? zepMemoryToMessages(memoryData, this.humanPrefix, this.aiPrefix)\n          : [condenseZepMemoryIntoHumanMessage(memoryData)],\n      };\n    }\n    return {\n      [this.memoryKey]: this.separateMessages\n        ? getBufferString(\n            zepMemoryToMessages(memoryData, this.humanPrefix, this.aiPrefix),\n            this.humanPrefix,\n            this.aiPrefix\n          )\n        : condenseZepMemoryIntoHumanMessage(memoryData).content,\n    };\n  }\n\n  /**\n   * Method that saves the input and output messages to the Zep service.\n   * @param inputValues Input messages to be saved.\n   * @param outputValues Output messages to be saved.\n   * @returns Promise that resolves when the messages have been saved.\n   */\n  async saveContext(\n    inputValues: InputValues,\n    outputValues: OutputValues\n  ): Promise<void> {\n    const input = getInputValue(inputValues, this.inputKey);\n    const output = getOutputValue(outputValues, this.outputKey);\n\n    // Create new Memory and Message instances\n    const memory = new BaseMemory({\n      messages: [\n        new Message({\n          role: this.humanPrefix,\n          content: `${input}`,\n        }),\n        new Message({\n          role: this.aiPrefix,\n          content: `${output}`,\n        }),\n      ],\n    });\n\n    // Wait for ZepClient to be initialized\n    const zepClient = await this.zepClientPromise;\n    if (!zepClient) {\n      throw new Error(this.zepInitFailMsg);\n    }\n\n    // Add the new memory to the session using the ZepClient\n    if (this.sessionId) {\n      try {\n        await zepClient.memory.addMemory(this.sessionId, memory);\n      } catch (error) {\n        console.error(\"Error adding memory: \", error);\n      }\n    }\n\n    // Call the superclass's saveContext method\n    await super.saveContext(inputValues, outputValues);\n  }\n\n  /**\n   * Method that deletes the chat history from the Zep service.\n   * @returns Promise that resolves when the chat history has been deleted.\n   */\n  async clear(): Promise<void> {\n    // Wait for ZepClient to be initialized\n    const zepClient = await this.zepClientPromise;\n    if (!zepClient) {\n      throw new Error(this.zepInitFailMsg);\n    }\n\n    try {\n      await zepClient.memory.deleteMemory(this.sessionId);\n    } catch (error) {\n      console.error(\"Error deleting session: \", error);\n    }\n\n    // Clear the superclass's chat history\n    await super.clear();\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,MAAa,kCAAkC,WAA0B;CACvE,IAAI,eAAe;AAGnB,KAAI,OAAO,WAAW,OAAO,SAAS,QACpC,iBAAgB,OAAO,QAAQ;AAGjC,QAAO;;;;;;;;;;;;AAaT,MAAa,qCAAqC,WAA0B;CAC1E,MAAM,eAAe,+BAA+B,OAAO;CAE3D,IAAI,iBAAiB;AAGrB,KAAI,OAAO,SACT,kBAAiB,OAAO,SACrB,KAAK,QAAQ,GAAG,IAAI,KAAK,IAAI,IAAI,UAAU,CAC3C,KAAK,KAAK;AAGf,QAAO,IAAIA,yBAAAA,aACT,GAAG,eAAe,GAAG,aAAa,MAAM,KAAK,iBAC9C;;;;;;;;;;;;AAaH,MAAa,uBACX,QACA,cAAc,SACd,WAAW,SACR;CACH,MAAM,eAAe,+BAA+B,OAAO;CAE3D,IAAI,WAA0B,eAC1B,CAAC,IAAIC,yBAAAA,cAAc,aAAa,CAAC,GACjC,EAAE;AAEN,KAAI,UAAU,OAAO,SACnB,YAAW,SAAS,OAClB,OAAO,SACJ,QAAQ,MAAM,EAAE,QAAQ,CACxB,KAAK,YAAY;EAChB,MAAM,EAAE,SAAS,SAAS;AAC1B,MAAI,SAAS,YACX,QAAO,IAAID,yBAAAA,aAAa,QAAQ;WACvB,SAAS,SAClB,QAAO,IAAIE,yBAAAA,UAAU,QAAQ;MAG7B,QAAO,IAAIC,yBAAAA,YAAY,SAAS,KAAK;GAEvC,CACL;AAGH,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFT,IAAa,YAAb,cAAA,2BAAA,oBAA+B,eAAyC;CACtE,cAAc;CAEd,WAAW;CAEX,YAAY;CAEZ;CAEA;CAEA;CAEA,iBAAkC;;;;;;;;;CAUlC;CAEA,YAAY,QAAwB;AAClC,QAAM;GACJ,gBAAgB,QAAQ,kBAAkB;GAC1C,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACpB,CAAC;AAEF,OAAK,cAAc,OAAO,eAAe,KAAK;AAC9C,OAAK,WAAW,OAAO,YAAY,KAAK;AACxC,OAAK,YAAY,OAAO,aAAa,KAAK;AAC1C,OAAK,UAAU,OAAO;AACtB,OAAK,YAAY,OAAO;AACxB,OAAK,mBAAmB,OAAO,oBAAoB;AACnD,OAAK,mBAAmBC,eAAAA,UAAU,KAAK,KAAK,SAAS,OAAO,OAAO;;CAGrE,IAAI,aAAa;AACf,SAAO,CAAC,KAAK,UAAU;;;;;;;;CASzB,MAAM,oBAAoB,QAA+C;EAKvE,MAAM,YAAY,MAAM,KAAK;AAC7B,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,KAAK,eAAe;EAGtC,MAAM,QAAQ,OAAO,SAAS,KAAA;EAE9B,IAAI,SAA4B;AAChC,MAAI;AACF,YAAS,MAAM,UAAU,OAAO,UAAU,KAAK,WAAW,MAAM;WACzD,OAAO;AAEd,OAAI,iBAAiBC,eAAAA,cAInB,QAHe,KAAK,iBAChB,GAAG,KAAK,YAAY,EAAE,EAAE,GACxB,GAAG,KAAK,YAAY,IAAI;OAG5B,OAAM;;EAKV,MAAM,aAA4B;GAChC,UACE,QAAQ,SAAS,KAAK,SAAkB;IACtC,MAAM,IAAI;IACV,SAAS,IAAI;IACd,EAAE,IAAI,EAAE;GACX,SAAS,QAAQ;GAClB;AAED,MAAI,KAAK,eACP,QAAO,GACJ,KAAK,YAAY,KAAK,mBACnB,oBAAoB,YAAY,KAAK,aAAa,KAAK,SAAS,GAChE,CAAC,kCAAkC,WAAW,CAAC,EACpD;AAEH,SAAO,GACJ,KAAK,YAAY,KAAK,oBAAA,GAAA,yBAAA,iBAEjB,oBAAoB,YAAY,KAAK,aAAa,KAAK,SAAS,EAChE,KAAK,aACL,KAAK,SACN,GACD,kCAAkC,WAAW,CAAC,SACnD;;;;;;;;CASH,MAAM,YACJ,aACA,cACe;EACf,MAAM,SAAA,GAAA,uBAAA,eAAsB,aAAa,KAAK,SAAS;EACvD,MAAM,UAAA,GAAA,uBAAA,gBAAwB,cAAc,KAAK,UAAU;EAG3D,MAAM,SAAS,IAAIC,eAAAA,OAAW,EAC5B,UAAU,CACR,IAAIC,eAAAA,QAAQ;GACV,MAAM,KAAK;GACX,SAAS,GAAG;GACb,CAAC,EACF,IAAIA,eAAAA,QAAQ;GACV,MAAM,KAAK;GACX,SAAS,GAAG;GACb,CAAC,CACH,EACF,CAAC;EAGF,MAAM,YAAY,MAAM,KAAK;AAC7B,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,KAAK,eAAe;AAItC,MAAI,KAAK,UACP,KAAI;AACF,SAAM,UAAU,OAAO,UAAU,KAAK,WAAW,OAAO;WACjD,OAAO;AACd,WAAQ,MAAM,yBAAyB,MAAM;;AAKjD,QAAM,MAAM,YAAY,aAAa,aAAa;;;;;;CAOpD,MAAM,QAAuB;EAE3B,MAAM,YAAY,MAAM,KAAK;AAC7B,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,KAAK,eAAe;AAGtC,MAAI;AACF,SAAM,UAAU,OAAO,aAAa,KAAK,UAAU;WAC5C,OAAO;AACd,WAAQ,MAAM,4BAA4B,MAAM;;AAIlD,QAAM,MAAM,OAAO"}