{"version":3,"file":"transformers.cjs","names":["RunnableLambda","convertToChunk","isBaseMessageChunk","HumanMessage","HumanMessageChunk","AIMessage","AIMessageChunk","SystemMessage","SystemMessageChunk","ToolMessage","ToolMessageChunk","FunctionMessage","FunctionMessageChunk","ChatMessage","ChatMessageChunk","RemoveMessage"],"sources":["../../src/messages/transformers.ts"],"sourcesContent":["import { BaseDocumentTransformer } from \"../documents/transformers.js\";\nimport { BaseLanguageModel } from \"../language_models/base.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { AIMessage, AIMessageChunk, AIMessageChunkFields } from \"./ai.js\";\nimport {\n  BaseMessage,\n  BaseMessageChunk,\n  BaseMessageFields,\n  isBaseMessageChunk,\n} from \"./base.js\";\nimport { ChatMessage, ChatMessageChunk, ChatMessageFields } from \"./chat.js\";\nimport {\n  FunctionMessage,\n  FunctionMessageChunk,\n  FunctionMessageFields,\n} from \"./function.js\";\nimport { HumanMessage, HumanMessageChunk } from \"./human.js\";\nimport { MessageType } from \"./message.js\";\nimport { RemoveMessage } from \"./modifier.js\";\nimport { SystemMessage, SystemMessageChunk } from \"./system.js\";\nimport { ToolMessage, ToolMessageChunk, ToolMessageFields } from \"./tool.js\";\nimport { convertToChunk } from \"./utils.js\";\n\nexport type MessageUnion =\n  | typeof HumanMessage\n  | typeof AIMessage\n  | typeof SystemMessage\n  | typeof ChatMessage\n  | typeof FunctionMessage\n  | typeof ToolMessage\n  | typeof RemoveMessage;\nexport type MessageChunkUnion =\n  | typeof HumanMessageChunk\n  | typeof AIMessageChunk\n  | typeof SystemMessageChunk\n  | typeof FunctionMessageChunk\n  | typeof ToolMessageChunk\n  | typeof ChatMessageChunk\n  | typeof RemoveMessage; // RemoveMessage does not have a chunk class.\nexport type MessageTypeOrClass = MessageType | MessageUnion | MessageChunkUnion;\n\nconst _isMessageType = (msg: BaseMessage, types: MessageTypeOrClass[]) => {\n  const typesAsStrings = [\n    ...new Set<string>(\n      types?.map((t) => {\n        if (typeof t === \"string\") {\n          return t;\n        }\n        // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        const instantiatedMsgClass = new (t as any)({});\n        if (\n          !(\"getType\" in instantiatedMsgClass) ||\n          typeof instantiatedMsgClass.getType !== \"function\"\n        ) {\n          throw new Error(\"Invalid type provided.\");\n        }\n        return instantiatedMsgClass.getType();\n      })\n    ),\n  ];\n  const msgType = msg.getType();\n  return typesAsStrings.some((t) => t === msgType);\n};\n\nexport interface FilterMessagesFields {\n  /**\n   * @param {string[] | undefined} includeNames Message names to include.\n   */\n  includeNames?: string[];\n  /**\n   * @param {string[] | undefined} excludeNames Messages names to exclude.\n   */\n  excludeNames?: string[];\n  /**\n   * @param {(MessageType | BaseMessage)[] | undefined} includeTypes Message types to include. Can be specified as string names (e.g.\n   *     \"system\", \"human\", \"ai\", ...) or as BaseMessage classes (e.g.\n   *     SystemMessage, HumanMessage, AIMessage, ...).\n   */\n  includeTypes?: MessageTypeOrClass[];\n  /**\n   * @param {(MessageType | BaseMessage)[] | undefined} excludeTypes Message types to exclude. Can be specified as string names (e.g.\n   *     \"system\", \"human\", \"ai\", ...) or as BaseMessage classes (e.g.\n   *     SystemMessage, HumanMessage, AIMessage, ...).\n   */\n  excludeTypes?: MessageTypeOrClass[];\n  /**\n   * @param {string[] | undefined} includeIds Message IDs to include.\n   */\n  includeIds?: string[];\n  /**\n   * @param {string[] | undefined} excludeIds Message IDs to exclude.\n   */\n  excludeIds?: string[];\n}\n\n/**\n * Filter messages based on name, type or id.\n *\n * @param {BaseMessage[] | FilterMessagesFields} messagesOrOptions - Either an array of BaseMessage objects to filter or the filtering options. If an array is provided, the `options` parameter should also be supplied. If filtering options are provided, a RunnableLambda is returned.\n * @param {FilterMessagesFields} [options] - Optional filtering options. Should only be provided if `messagesOrOptions` is an array of BaseMessage objects.\n * @returns A list of Messages that meets at least one of the include conditions and none\n *     of the exclude conditions, or a RunnableLambda which does the same. If no include conditions are specified then\n *     anything that is not explicitly excluded will be included.\n * @throws {Error} If two incompatible arguments are provided.\n *\n * @example\n * ```typescript\n * import { filterMessages, AIMessage, HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n *\n * const messages = [\n *   new SystemMessage(\"you're a good assistant.\"),\n *   new HumanMessage({ content: \"what's your name\", id: \"foo\", name: \"example_user\" }),\n *   new AIMessage({ content: \"steve-o\", id: \"bar\", name: \"example_assistant\" }),\n *   new HumanMessage({ content: \"what's your favorite color\", id: \"baz\" }),\n *   new AIMessage({ content: \"silicon blue\" , id: \"blah\" }),\n * ];\n *\n * filterMessages(messages, {\n *   includeNames: [\"example_user\", \"example_assistant\"],\n *   includeTypes: [\"system\"],\n *   excludeIds: [\"bar\"],\n * });\n * ```\n *\n * The above example would return:\n * ```typescript\n * [\n *   new SystemMessage(\"you're a good assistant.\"),\n *   new HumanMessage({ content: \"what's your name\", id: \"foo\", name: \"example_user\" }),\n * ]\n * ```\n */\nexport function filterMessages(\n  options?: FilterMessagesFields\n): Runnable<BaseMessage[], BaseMessage[]>;\nexport function filterMessages(\n  messages: BaseMessage[],\n  options?: FilterMessagesFields\n): BaseMessage[];\nexport function filterMessages(\n  messagesOrOptions?: BaseMessage[] | FilterMessagesFields,\n  options?: FilterMessagesFields\n): BaseMessage[] | Runnable<BaseMessage[], BaseMessage[]> {\n  if (Array.isArray(messagesOrOptions)) {\n    return _filterMessages(messagesOrOptions, options);\n  }\n  return RunnableLambda.from((input: BaseMessage[]): BaseMessage[] => {\n    return _filterMessages(input, messagesOrOptions);\n  });\n}\n\nfunction _filterMessages(\n  messages: BaseMessage[],\n  options: FilterMessagesFields = {}\n): BaseMessage[] {\n  const {\n    includeNames,\n    excludeNames,\n    includeTypes,\n    excludeTypes,\n    includeIds,\n    excludeIds,\n  } = options;\n\n  const filtered: BaseMessage[] = [];\n\n  for (const msg of messages) {\n    if (excludeNames && msg.name && excludeNames.includes(msg.name)) {\n      continue;\n    } else if (excludeTypes && _isMessageType(msg, excludeTypes)) {\n      continue;\n    } else if (excludeIds && msg.id && excludeIds.includes(msg.id)) {\n      continue;\n    }\n\n    // default to inclusion when no inclusion criteria given.\n    if (!(includeTypes || includeIds || includeNames)) {\n      filtered.push(msg);\n    } else if (\n      includeNames &&\n      msg.name &&\n      includeNames.some((iName) => iName === msg.name)\n    ) {\n      filtered.push(msg);\n    } else if (includeTypes && _isMessageType(msg, includeTypes)) {\n      filtered.push(msg);\n    } else if (includeIds && msg.id && includeIds.some((id) => id === msg.id)) {\n      filtered.push(msg);\n    }\n  }\n\n  return filtered;\n}\n\n/**\n * Merge consecutive Messages of the same type.\n *\n * **NOTE**: ToolMessages are not merged, as each has a distinct tool call id that\n * can't be merged.\n *\n * @param {BaseMessage[] | undefined} messages Sequence of Message-like objects to merge. Optional. If not provided, a RunnableLambda is returned.\n * @returns List of BaseMessages with consecutive runs of message types merged into single\n *     messages, or a RunnableLambda which returns a list of BaseMessages If two messages being merged both have string contents, the merged\n *     content is a concatenation of the two strings with a new-line separator. If at\n *     least one of the messages has a list of content blocks, the merged content is a\n *     list of content blocks.\n *\n * @example\n * ```typescript\n * import { mergeMessageRuns, AIMessage, HumanMessage, SystemMessage, ToolCall } from \"@langchain/core/messages\";\n *\n * const messages = [\n *   new SystemMessage(\"you're a good assistant.\"),\n *   new HumanMessage({ content: \"what's your favorite color\", id: \"foo\" }),\n *   new HumanMessage({ content: \"wait your favorite food\", id: \"bar\" }),\n *   new AIMessage({\n *     content: \"my favorite colo\",\n *     tool_calls: [{ name: \"blah_tool\", args: { x: 2 }, id: \"123\" }],\n *     id: \"baz\",\n *   }),\n *   new AIMessage({\n *     content: [{ type: \"text\", text: \"my favorite dish is lasagna\" }],\n *     tool_calls: [{ name: \"blah_tool\", args: { x: -10 }, id: \"456\" }],\n *     id: \"blur\",\n *   }),\n * ];\n *\n * mergeMessageRuns(messages);\n * ```\n *\n * The above example would return:\n * ```typescript\n * [\n *   new SystemMessage(\"you're a good assistant.\"),\n *   new HumanMessage({\n *     content: \"what's your favorite colorwait your favorite food\",\n *     id: \"foo\",\n *   }),\n *   new AIMessage({\n *     content: [\n *       { type: \"text\", text: \"my favorite colo\" },\n *       { type: \"text\", text: \"my favorite dish is lasagna\" },\n *     ],\n *     tool_calls: [\n *       { name: \"blah_tool\", args: { x: 2 }, id: \"123\" },\n *       { name: \"blah_tool\", args: { x: -10 }, id: \"456\" },\n *     ],\n *     id: \"baz\",\n *   }),\n * ]\n * ```\n */\nexport function mergeMessageRuns(): Runnable<BaseMessage[], BaseMessage[]>;\nexport function mergeMessageRuns(messages: BaseMessage[]): BaseMessage[];\nexport function mergeMessageRuns(\n  messages?: BaseMessage[]\n): BaseMessage[] | Runnable<BaseMessage[], BaseMessage[]> {\n  if (Array.isArray(messages)) {\n    return _mergeMessageRuns(messages);\n  }\n  return RunnableLambda.from(_mergeMessageRuns);\n}\n\nfunction _mergeMessageRuns(messages: BaseMessage[]): BaseMessage[] {\n  if (!messages.length) {\n    return [];\n  }\n  const merged: BaseMessage[] = [];\n  for (const msg of messages) {\n    const curr = msg;\n    const last = merged.pop();\n    if (!last) {\n      merged.push(curr);\n    } else if (\n      curr.getType() === \"tool\" ||\n      !(curr.getType() === last.getType())\n    ) {\n      merged.push(last, curr);\n    } else {\n      const lastChunk = convertToChunk(last) as BaseMessageChunk;\n      const currChunk = convertToChunk(curr) as BaseMessageChunk;\n      const mergedChunks = lastChunk.concat(currChunk);\n      if (\n        typeof lastChunk.content === \"string\" &&\n        typeof currChunk.content === \"string\"\n      ) {\n        mergedChunks.content = `${lastChunk.content}\\n${currChunk.content}`;\n      }\n      merged.push(_chunkToMsg(mergedChunks));\n    }\n  }\n  return merged;\n}\n\n// Since we can not import from `@langchain/textsplitters` we need\n// to reconstruct the interface here.\ninterface _TextSplitterInterface extends BaseDocumentTransformer {\n  splitText(text: string): Promise<string[]>;\n}\n\nexport interface TrimMessagesFields {\n  /**\n   * @param {number} maxTokens Max token count of trimmed messages.\n   */\n  maxTokens: number;\n  /**\n   * @param {((messages: BaseMessage[]) => number) | ((messages: BaseMessage[]) => Promise<number>) | BaseLanguageModel} tokenCounter\n   * Function or LLM for counting tokens in an array of `BaseMessage`s.\n   * If a `BaseLanguageModel` is passed in then `BaseLanguageModel.getNumTokens()` will be used.\n   */\n  tokenCounter:\n    | ((messages: BaseMessage[]) => number)\n    | ((messages: BaseMessage[]) => Promise<number>)\n    | BaseLanguageModel;\n  /**\n   * @param {\"first\" | \"last\"} [strategy=\"last\"] Strategy for trimming.\n   * - \"first\": Keep the first <= n_count tokens of the messages.\n   * - \"last\": Keep the last <= n_count tokens of the messages.\n   * @default \"last\"\n   */\n  strategy?: \"first\" | \"last\";\n  /**\n   * @param {boolean} [allowPartial=false] Whether to split a message if only part of the message can be included.\n   * If `strategy: \"last\"` then the last partial contents of a message are included.\n   * If `strategy: \"first\"` then the first partial contents of a message are included.\n   * @default false\n   */\n  allowPartial?: boolean;\n  /**\n   * @param {MessageTypeOrClass | MessageTypeOrClass[]} [endOn] The message type to end on.\n   * If specified then every message after the last occurrence of this type is ignored.\n   * If `strategy === \"last\"` then this is done before we attempt to get the last `maxTokens`.\n   * If `strategy === \"first\"` then this is done after we get the first `maxTokens`.\n   * Can be specified as string names (e.g. \"system\", \"human\", \"ai\", ...) or as `BaseMessage` classes\n   * (e.g. `SystemMessage`, `HumanMessage`, `AIMessage`, ...). Can be a single type or an array of types.\n   */\n  endOn?: MessageTypeOrClass | MessageTypeOrClass[];\n  /**\n   * @param {MessageTypeOrClass | MessageTypeOrClass[]} [startOn] The message type to start on.\n   * Should only be specified if `strategy: \"last\"`. If specified then every message before the first occurrence\n   * of this type is ignored. This is done after we trim the initial messages to the last `maxTokens`.\n   * Does not apply to a `SystemMessage` at index 0 if `includeSystem: true`.\n   * Can be specified as string names (e.g. \"system\", \"human\", \"ai\", ...) or as `BaseMessage` classes\n   * (e.g. `SystemMessage`, `HumanMessage`, `AIMessage`, ...). Can be a single type or an array of types.\n   */\n  startOn?: MessageTypeOrClass | MessageTypeOrClass[];\n  /**\n   * @param {boolean} [includeSystem=false] Whether to keep the `SystemMessage` if there is one at index 0.\n   * Should only be specified if `strategy: \"last\"`.\n   * @default false\n   */\n  includeSystem?: boolean;\n  /**\n   * @param {((text: string) => string[]) | BaseDocumentTransformer} [textSplitter] Function or `BaseDocumentTransformer` for\n   * splitting the string contents of a message. Only used if `allowPartial: true`.\n   * If `strategy: \"last\"` then the last split tokens from a partial message will be included.\n   * If `strategy: \"first\"` then the first split tokens from a partial message will be included.\n   * Token splitter assumes that separators are kept, so that split contents can be directly concatenated\n   * to recreate the original text. Defaults to splitting on newlines.\n   */\n  textSplitter?:\n    | ((text: string) => string[])\n    | ((text: string) => Promise<string[]>)\n    | _TextSplitterInterface;\n}\n\n/**\n * Trim messages to be below a token count.\n *\n * @param {BaseMessage[]} messages Array of `BaseMessage` instances to trim.\n * @param {TrimMessagesFields} options Trimming options.\n * @returns An array of trimmed `BaseMessage`s or a `Runnable` that takes a sequence of `BaseMessage`-like objects and returns\n *     an array of trimmed `BaseMessage`s.\n * @throws {Error} If two incompatible arguments are specified or an unrecognized `strategy` is specified.\n *\n * @example\n * ```typescript\n * import { trimMessages, AIMessage, BaseMessage, HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n *\n * const messages = [\n *   new SystemMessage(\"This is a 4 token text. The full message is 10 tokens.\"),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"first\",\n *   }),\n *   new AIMessage({\n *     content: [\n *       { type: \"text\", text: \"This is the FIRST 4 token block.\" },\n *       { type: \"text\", text: \"This is the SECOND 4 token block.\" },\n *     ],\n *     id: \"second\",\n *   }),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"third\",\n *   }),\n *   new AIMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"fourth\",\n *   }),\n * ];\n *\n * function dummyTokenCounter(messages: BaseMessage[]): number {\n *   // treat each message like it adds 3 default tokens at the beginning\n *   // of the message and at the end of the message. 3 + 4 + 3 = 10 tokens\n *   // per message.\n *\n *   const defaultContentLen = 4;\n *   const defaultMsgPrefixLen = 3;\n *   const defaultMsgSuffixLen = 3;\n *\n *   let count = 0;\n *   for (const msg of messages) {\n *     if (typeof msg.content === \"string\") {\n *       count += defaultMsgPrefixLen + defaultContentLen + defaultMsgSuffixLen;\n *     }\n *     if (Array.isArray(msg.content)) {\n *       count +=\n *         defaultMsgPrefixLen +\n *         msg.content.length * defaultContentLen +\n *         defaultMsgSuffixLen;\n *     }\n *   }\n *   return count;\n * }\n * ```\n *\n * First 30 tokens, not allowing partial messages:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 30,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"first\",\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"first\",\n *   }),\n * ]\n * ```\n *\n * First 30 tokens, allowing partial messages:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 30,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"first\",\n *   allowPartial: true,\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"first\",\n *   }),\n *   new AIMessage({\n *     content: [{ type: \"text\", text: \"This is the FIRST 4 token block.\" }],\n *     id: \"second\",\n *   }),\n * ]\n * ```\n *\n * First 30 tokens, allowing partial messages, have to end on HumanMessage:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 30,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"first\",\n *   allowPartial: true,\n *   endOn: \"human\",\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"first\",\n *   }),\n * ]\n * ```\n *\n * Last 30 tokens, including system message, not allowing partial messages:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 30,\n *   includeSystem: true,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"last\",\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"third\",\n *   }),\n *   new AIMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"fourth\",\n *   }),\n * ]\n * ```\n *\n * Last 40 tokens, including system message, allowing partial messages:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 40,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"last\",\n *   allowPartial: true,\n *   includeSystem: true,\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new AIMessage({\n *     content: [{ type: \"text\", text: \"This is the FIRST 4 token block.\" }],\n *     id: \"second\",\n *   }),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"third\",\n *   }),\n *   new AIMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"fourth\",\n *   }),\n * ]\n * ```\n *\n * Last 30 tokens, including system message, allowing partial messages, end on HumanMessage:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 30,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"last\",\n *   endOn: \"human\",\n *   includeSystem: true,\n *   allowPartial: true,\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new AIMessage({\n *     content: [{ type: \"text\", text: \"This is the FIRST 4 token block.\" }],\n *     id: \"second\",\n *   }),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"third\",\n *   }),\n * ]\n * ```\n *\n * Last 40 tokens, including system message, allowing partial messages, start on HumanMessage:\n * ```typescript\n * await trimMessages(messages, {\n *   maxTokens: 40,\n *   tokenCounter: dummyTokenCounter,\n *   strategy: \"last\",\n *   includeSystem: true,\n *   allowPartial: true,\n *   startOn: \"human\",\n * });\n * ```\n *\n * Output:\n * ```typescript\n * [\n *   new SystemMessage(\n *     \"This is a 4 token text. The full message is 10 tokens.\"\n *   ),\n *   new HumanMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"third\",\n *   }),\n *   new AIMessage({\n *     content: \"This is a 4 token text. The full message is 10 tokens.\",\n *     id: \"fourth\",\n *   }),\n * ]\n * ```\n */\nexport function trimMessages(\n  options: TrimMessagesFields\n): Runnable<BaseMessage[], BaseMessage[]>;\nexport function trimMessages(\n  messages: BaseMessage[],\n  options: TrimMessagesFields\n): Promise<BaseMessage[]>;\nexport function trimMessages(\n  messagesOrOptions: BaseMessage[] | TrimMessagesFields,\n  options?: TrimMessagesFields\n): Promise<BaseMessage[]> | Runnable<BaseMessage[], BaseMessage[]> {\n  if (Array.isArray(messagesOrOptions)) {\n    const messages = messagesOrOptions;\n    if (!options) {\n      throw new Error(\"Options parameter is required when providing messages.\");\n    }\n    return _trimMessagesHelper(messages, options);\n  } else {\n    const trimmerOptions = messagesOrOptions;\n    return RunnableLambda.from((input: BaseMessage[]) =>\n      _trimMessagesHelper(input, trimmerOptions)\n    ).withConfig({\n      runName: \"trim_messages\",\n    });\n  }\n}\n\nasync function _trimMessagesHelper(\n  messages: BaseMessage[],\n  options: TrimMessagesFields\n): Promise<Array<BaseMessage>> {\n  const {\n    maxTokens,\n    tokenCounter,\n    strategy = \"last\",\n    allowPartial = false,\n    endOn,\n    startOn,\n    includeSystem = false,\n    textSplitter,\n  } = options;\n  if (startOn && strategy === \"first\") {\n    throw new Error(\n      \"`startOn` should only be specified if `strategy` is 'last'.\"\n    );\n  }\n  if (includeSystem && strategy === \"first\") {\n    throw new Error(\n      \"`includeSystem` should only be specified if `strategy` is 'last'.\"\n    );\n  }\n\n  let listTokenCounter: (msgs: BaseMessage[]) => Promise<number>;\n  if (\"getNumTokens\" in tokenCounter) {\n    listTokenCounter = async (msgs: BaseMessage[]): Promise<number> => {\n      const tokenCounts = await Promise.all(\n        msgs.map((msg) => tokenCounter.getNumTokens(msg.content))\n      );\n      return tokenCounts.reduce((sum, count) => sum + count, 0);\n    };\n  } else {\n    listTokenCounter = async (msgs: BaseMessage[]): Promise<number> =>\n      tokenCounter(msgs);\n  }\n\n  let textSplitterFunc: (text: string) => Promise<string[]> =\n    defaultTextSplitter;\n  if (textSplitter) {\n    if (\"splitText\" in textSplitter) {\n      textSplitterFunc = textSplitter.splitText;\n    } else {\n      textSplitterFunc = async (text: string): Promise<string[]> =>\n        textSplitter(text);\n    }\n  }\n\n  if (strategy === \"first\") {\n    return _firstMaxTokens(messages, {\n      maxTokens,\n      tokenCounter: listTokenCounter,\n      textSplitter: textSplitterFunc,\n      partialStrategy: allowPartial ? \"first\" : undefined,\n      endOn,\n    });\n  } else if (strategy === \"last\") {\n    return _lastMaxTokens(messages, {\n      maxTokens,\n      tokenCounter: listTokenCounter,\n      textSplitter: textSplitterFunc,\n      allowPartial,\n      includeSystem,\n      startOn,\n      endOn,\n    });\n  } else {\n    throw new Error(\n      `Unrecognized strategy: '${strategy}'. Must be one of 'first' or 'last'.`\n    );\n  }\n}\n\nasync function _firstMaxTokens(\n  messages: BaseMessage[],\n  options: {\n    maxTokens: number;\n    tokenCounter: (messages: BaseMessage[]) => Promise<number>;\n    textSplitter: (text: string) => Promise<string[]>;\n    partialStrategy?: \"first\" | \"last\";\n    endOn?: MessageTypeOrClass | MessageTypeOrClass[];\n  }\n): Promise<BaseMessage[]> {\n  const { maxTokens, tokenCounter, textSplitter, partialStrategy, endOn } =\n    options;\n  let messagesCopy = [...messages];\n  let idx = 0;\n  for (let i = 0; i < messagesCopy.length; i += 1) {\n    const remainingMessages = i > 0 ? messagesCopy.slice(0, -i) : messagesCopy;\n    if ((await tokenCounter(remainingMessages)) <= maxTokens) {\n      idx = messagesCopy.length - i;\n      break;\n    }\n  }\n  if (idx < messagesCopy.length && partialStrategy) {\n    let includedPartial = false;\n    if (Array.isArray(messagesCopy[idx].content)) {\n      const excluded = messagesCopy[idx];\n      if (typeof excluded.content === \"string\") {\n        throw new Error(\"Expected content to be an array.\");\n      }\n\n      const numBlock = excluded.content.length;\n      const reversedContent =\n        partialStrategy === \"last\"\n          ? [...excluded.content].reverse()\n          : excluded.content;\n      for (let i = 1; i <= numBlock; i += 1) {\n        const partialContent =\n          partialStrategy === \"first\"\n            ? reversedContent.slice(0, i)\n            : reversedContent.slice(-i);\n        const fields = Object.fromEntries(\n          Object.entries(excluded).filter(\n            ([k]) => k !== \"type\" && !k.startsWith(\"lc_\")\n          )\n        ) as BaseMessageFields;\n        const updatedMessage = _switchTypeToMessage(excluded.getType(), {\n          ...fields,\n          content: partialContent,\n        });\n        const slicedMessages = [...messagesCopy.slice(0, idx), updatedMessage];\n        if ((await tokenCounter(slicedMessages)) <= maxTokens) {\n          messagesCopy = slicedMessages;\n          idx += 1;\n          includedPartial = true;\n        } else {\n          break;\n        }\n      }\n      if (includedPartial && partialStrategy === \"last\") {\n        excluded.content = [...reversedContent].reverse();\n      }\n    }\n    if (!includedPartial) {\n      const excluded = messagesCopy[idx];\n      let text: string | undefined;\n      if (\n        Array.isArray(excluded.content) &&\n        excluded.content.some(\n          (block) => typeof block === \"string\" || block.type === \"text\"\n        )\n      ) {\n        const textBlock = excluded.content.find(\n          (block) => block.type === \"text\" && block.text\n        ) as { type: \"text\"; text: string } | undefined;\n        text = textBlock?.text;\n      } else if (typeof excluded.content === \"string\") {\n        text = excluded.content;\n      }\n      if (text) {\n        const splitTexts = await textSplitter(text);\n        const numSplits = splitTexts.length;\n        if (partialStrategy === \"last\") {\n          splitTexts.reverse();\n        }\n        for (let _ = 0; _ < numSplits - 1; _ += 1) {\n          splitTexts.pop();\n          excluded.content = splitTexts.join(\"\");\n          if (\n            (await tokenCounter([...messagesCopy.slice(0, idx), excluded])) <=\n            maxTokens\n          ) {\n            if (partialStrategy === \"last\") {\n              excluded.content = [...splitTexts].reverse().join(\"\");\n            }\n            messagesCopy = [...messagesCopy.slice(0, idx), excluded];\n            idx += 1;\n            break;\n          }\n        }\n      }\n    }\n  }\n\n  if (endOn) {\n    const endOnArr = Array.isArray(endOn) ? endOn : [endOn];\n    while (idx > 0 && !_isMessageType(messagesCopy[idx - 1], endOnArr)) {\n      idx -= 1;\n    }\n  }\n\n  return messagesCopy.slice(0, idx);\n}\n\nasync function _lastMaxTokens(\n  messages: BaseMessage[],\n  options: {\n    maxTokens: number;\n    tokenCounter: (messages: BaseMessage[]) => Promise<number>;\n    textSplitter: (text: string) => Promise<string[]>;\n    /**\n     * @default {false}\n     */\n    allowPartial?: boolean;\n    /**\n     * @default {false}\n     */\n    includeSystem?: boolean;\n    startOn?: MessageTypeOrClass | MessageTypeOrClass[];\n    endOn?: MessageTypeOrClass | MessageTypeOrClass[];\n  }\n): Promise<BaseMessage[]> {\n  const {\n    allowPartial = false,\n    includeSystem = false,\n    endOn,\n    startOn,\n    ...rest\n  } = options;\n\n  // Create a copy of messages to avoid mutation\n  let messagesCopy = messages.map((message) => {\n    const fields = Object.fromEntries(\n      Object.entries(message).filter(\n        ([k]) => k !== \"type\" && !k.startsWith(\"lc_\")\n      )\n    ) as BaseMessageFields;\n    return _switchTypeToMessage(\n      message.getType(),\n      fields,\n      isBaseMessageChunk(message)\n    );\n  });\n\n  if (endOn) {\n    const endOnArr = Array.isArray(endOn) ? endOn : [endOn];\n    while (\n      messagesCopy.length > 0 &&\n      !_isMessageType(messagesCopy[messagesCopy.length - 1], endOnArr)\n    ) {\n      messagesCopy = messagesCopy.slice(0, -1);\n    }\n  }\n\n  const swappedSystem =\n    includeSystem && messagesCopy[0]?.getType() === \"system\";\n  let reversed_ = swappedSystem\n    ? messagesCopy.slice(0, 1).concat(messagesCopy.slice(1).reverse())\n    : messagesCopy.reverse();\n\n  reversed_ = await _firstMaxTokens(reversed_, {\n    ...rest,\n    partialStrategy: allowPartial ? \"last\" : undefined,\n    endOn: startOn,\n  });\n\n  if (swappedSystem) {\n    return [reversed_[0], ...reversed_.slice(1).reverse()];\n  } else {\n    return reversed_.reverse();\n  }\n}\n\nconst _MSG_CHUNK_MAP: Record<\n  MessageType,\n  {\n    message: MessageUnion;\n    messageChunk: MessageChunkUnion;\n  }\n> = {\n  human: {\n    message: HumanMessage,\n    messageChunk: HumanMessageChunk,\n  },\n  ai: {\n    message: AIMessage,\n    messageChunk: AIMessageChunk,\n  },\n  system: {\n    message: SystemMessage,\n    messageChunk: SystemMessageChunk,\n  },\n  developer: {\n    message: SystemMessage,\n    messageChunk: SystemMessageChunk,\n  },\n  tool: {\n    message: ToolMessage,\n    messageChunk: ToolMessageChunk,\n  },\n  function: {\n    message: FunctionMessage,\n    messageChunk: FunctionMessageChunk,\n  },\n  generic: {\n    message: ChatMessage,\n    messageChunk: ChatMessageChunk,\n  },\n  remove: {\n    message: RemoveMessage,\n    messageChunk: RemoveMessage, // RemoveMessage does not have a chunk class.\n  },\n};\n\nfunction _switchTypeToMessage(\n  messageType: MessageType,\n  fields: BaseMessageFields\n): BaseMessage;\nfunction _switchTypeToMessage(\n  messageType: MessageType,\n  fields: BaseMessageFields,\n  returnChunk: true\n): BaseMessageChunk;\nfunction _switchTypeToMessage(\n  messageType: MessageType,\n  fields: BaseMessageFields,\n  returnChunk?: boolean\n): BaseMessageChunk | BaseMessage;\nfunction _switchTypeToMessage(\n  messageType: MessageType,\n  fields: BaseMessageFields,\n  returnChunk?: boolean\n): BaseMessageChunk | BaseMessage {\n  let chunk: BaseMessageChunk | undefined;\n  let msg: BaseMessage | undefined;\n\n  switch (messageType) {\n    case \"human\":\n      if (returnChunk) {\n        chunk = new HumanMessageChunk(fields);\n      } else {\n        msg = new HumanMessage(fields);\n      }\n      break;\n    case \"ai\":\n      if (returnChunk) {\n        let aiChunkFields: AIMessageChunkFields = {\n          ...fields,\n        };\n        if (\"tool_calls\" in aiChunkFields) {\n          aiChunkFields = {\n            ...aiChunkFields,\n            tool_call_chunks: aiChunkFields.tool_calls?.map((tc) => ({\n              ...tc,\n              type: \"tool_call_chunk\",\n              index: undefined,\n              args: JSON.stringify(tc.args),\n            })),\n          };\n        }\n        chunk = new AIMessageChunk(aiChunkFields);\n      } else {\n        msg = new AIMessage(fields);\n      }\n      break;\n    case \"system\":\n      if (returnChunk) {\n        chunk = new SystemMessageChunk(fields);\n      } else {\n        msg = new SystemMessage(fields);\n      }\n      break;\n    case \"developer\":\n      if (returnChunk) {\n        chunk = new SystemMessageChunk({\n          ...fields,\n          additional_kwargs: {\n            ...fields.additional_kwargs,\n            __openai_role__: \"developer\",\n          },\n        });\n      } else {\n        msg = new SystemMessage({\n          ...fields,\n          additional_kwargs: {\n            ...fields.additional_kwargs,\n            __openai_role__: \"developer\",\n          },\n        });\n      }\n      break;\n    case \"tool\":\n      if (\"tool_call_id\" in fields) {\n        if (returnChunk) {\n          chunk = new ToolMessageChunk(fields as ToolMessageFields);\n        } else {\n          msg = new ToolMessage(fields as ToolMessageFields);\n        }\n      } else {\n        throw new Error(\n          \"Can not convert ToolMessage to ToolMessageChunk if 'tool_call_id' field is not defined.\"\n        );\n      }\n      break;\n    case \"function\":\n      if (returnChunk) {\n        chunk = new FunctionMessageChunk(fields as FunctionMessageFields);\n      } else {\n        if (!fields.name) {\n          throw new Error(\"FunctionMessage must have a 'name' field\");\n        }\n        msg = new FunctionMessage(fields as FunctionMessageFields);\n      }\n      break;\n    case \"generic\":\n      if (\"role\" in fields) {\n        if (returnChunk) {\n          chunk = new ChatMessageChunk(fields as ChatMessageFields);\n        } else {\n          msg = new ChatMessage(fields as ChatMessageFields);\n        }\n      } else {\n        throw new Error(\n          \"Can not convert ChatMessage to ChatMessageChunk if 'role' field is not defined.\"\n        );\n      }\n      break;\n    default:\n      throw new Error(`Unrecognized message type ${messageType}`);\n  }\n\n  if (returnChunk && chunk) {\n    return chunk;\n  }\n  if (msg) {\n    return msg;\n  }\n  throw new Error(`Unrecognized message type ${messageType}`);\n}\n\nfunction _chunkToMsg(chunk: BaseMessageChunk): BaseMessage {\n  const chunkType = chunk.getType();\n  let msg: BaseMessage | undefined;\n  const fields = Object.fromEntries(\n    Object.entries(chunk).filter(\n      ([k]) => ![\"type\", \"tool_call_chunks\"].includes(k) && !k.startsWith(\"lc_\")\n    )\n  ) as BaseMessageFields;\n\n  if (chunkType in _MSG_CHUNK_MAP) {\n    msg = _switchTypeToMessage(chunkType, fields);\n  }\n\n  if (!msg) {\n    throw new Error(\n      `Unrecognized message chunk class ${chunkType}. Supported classes are ${Object.keys(\n        _MSG_CHUNK_MAP\n      )}`\n    );\n  }\n\n  return msg;\n}\n\n/**\n * The default text splitter function that splits text by newlines.\n *\n * @param {string} text\n * @returns A promise that resolves to an array of strings split by newlines.\n */\nexport function defaultTextSplitter(text: string): Promise<string[]> {\n  const splits = text.split(\"\\n\");\n  return Promise.resolve([\n    ...splits.slice(0, -1).map((s) => `${s}\\n`),\n    splits[splits.length - 1],\n  ]);\n}\n"],"mappings":"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"}