@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 45.1 kB
Source Map (JSON)
{"version":3,"file":"transformers.cjs","names":["msg: BaseMessage","types: MessageTypeOrClass[]","messagesOrOptions?: BaseMessage[] | FilterMessagesFields","options?: FilterMessagesFields","RunnableLambda","input: BaseMessage[]","messages: BaseMessage[]","options: FilterMessagesFields","filtered: BaseMessage[]","messages?: BaseMessage[]","merged: BaseMessage[]","convertToChunk","messagesOrOptions: BaseMessage[] | TrimMessagesFields","options?: TrimMessagesFields","options: TrimMessagesFields","listTokenCounter: (msgs: BaseMessage[]) => Promise<number>","msgs: BaseMessage[]","textSplitterFunc: (text: string) => Promise<string[]>","text: string","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 }","text: string | undefined","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 }","isBaseMessageChunk","_MSG_CHUNK_MAP: Record<\n MessageType,\n {\n message: MessageUnion;\n messageChunk: MessageChunkUnion;\n }\n>","HumanMessage","HumanMessageChunk","AIMessage","AIMessageChunk","SystemMessage","SystemMessageChunk","ToolMessage","ToolMessageChunk","FunctionMessage","FunctionMessageChunk","ChatMessage","ChatMessageChunk","RemoveMessage","messageType: MessageType","fields: BaseMessageFields","returnChunk?: boolean","chunk: BaseMessageChunk | undefined","msg: BaseMessage | undefined","aiChunkFields: AIMessageChunkFields","chunk: BaseMessageChunk"],"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 // eslint-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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"}