UNPKG

@langchain/core

Version:
199 lines (198 loc) 7.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertToChunk = exports.mapChatMessagesToStoredMessages = exports.mapStoredMessagesToChatMessages = exports.mapStoredMessageToChatMessage = exports.getBufferString = exports.coerceMessageLikeToMessage = void 0; const ai_js_1 = require("./ai.cjs"); const base_js_1 = require("./base.cjs"); const chat_js_1 = require("./chat.cjs"); const function_js_1 = require("./function.cjs"); const human_js_1 = require("./human.cjs"); const system_js_1 = require("./system.cjs"); const tool_js_1 = require("./tool.cjs"); function _constructMessageFromParams(params) { const { type, ...rest } = params; if (type === "human" || type === "user") { return new human_js_1.HumanMessage(rest); } else if (type === "ai" || type === "assistant") { return new ai_js_1.AIMessage(rest); } else if (type === "system") { return new system_js_1.SystemMessage(rest); } else { throw new Error(`Unable to coerce message from array: only human, AI, or system message coercion is currently supported.`); } } function coerceMessageLikeToMessage(messageLike) { if (typeof messageLike === "string") { return new human_js_1.HumanMessage(messageLike); } else if ((0, base_js_1.isBaseMessage)(messageLike)) { return messageLike; } if (Array.isArray(messageLike)) { const [type, content] = messageLike; return _constructMessageFromParams({ type, content }); } else { return _constructMessageFromParams(messageLike); } } exports.coerceMessageLikeToMessage = coerceMessageLikeToMessage; /** * This function is used by memory classes to get a string representation * of the chat message history, based on the message content and role. */ function getBufferString(messages, humanPrefix = "Human", aiPrefix = "AI") { const string_messages = []; for (const m of messages) { let role; if (m._getType() === "human") { role = humanPrefix; } else if (m._getType() === "ai") { role = aiPrefix; } else if (m._getType() === "system") { role = "System"; } else if (m._getType() === "function") { role = "Function"; } else if (m._getType() === "tool") { role = "Tool"; } else if (m._getType() === "generic") { role = m.role; } else { throw new Error(`Got unsupported message type: ${m._getType()}`); } const nameStr = m.name ? `${m.name}, ` : ""; const readableContent = typeof m.content === "string" ? m.content : JSON.stringify(m.content, null, 2); string_messages.push(`${role}: ${nameStr}${readableContent}`); } return string_messages.join("\n"); } exports.getBufferString = getBufferString; /** * Maps messages from an older format (V1) to the current `StoredMessage` * format. If the message is already in the `StoredMessage` format, it is * returned as is. Otherwise, it transforms the V1 message into a * `StoredMessage`. This function is important for maintaining * compatibility with older message formats. */ function mapV1MessageToStoredMessage(message) { // TODO: Remove this mapper when we deprecate the old message format. if (message.data !== undefined) { return message; } else { const v1Message = message; return { type: v1Message.type, data: { content: v1Message.text, role: v1Message.role, name: undefined, tool_call_id: undefined, }, }; } } function mapStoredMessageToChatMessage(message) { const storedMessage = mapV1MessageToStoredMessage(message); switch (storedMessage.type) { case "human": return new human_js_1.HumanMessage(storedMessage.data); case "ai": return new ai_js_1.AIMessage(storedMessage.data); case "system": return new system_js_1.SystemMessage(storedMessage.data); case "function": if (storedMessage.data.name === undefined) { throw new Error("Name must be defined for function messages"); } return new function_js_1.FunctionMessage(storedMessage.data); case "tool": if (storedMessage.data.tool_call_id === undefined) { throw new Error("Tool call ID must be defined for tool messages"); } return new tool_js_1.ToolMessage(storedMessage.data); case "generic": { if (storedMessage.data.role === undefined) { throw new Error("Role must be defined for chat messages"); } return new chat_js_1.ChatMessage(storedMessage.data); } default: throw new Error(`Got unexpected type: ${storedMessage.type}`); } } exports.mapStoredMessageToChatMessage = mapStoredMessageToChatMessage; /** * Transforms an array of `StoredMessage` instances into an array of * `BaseMessage` instances. It uses the `mapV1MessageToStoredMessage` * function to ensure all messages are in the `StoredMessage` format, then * creates new instances of the appropriate `BaseMessage` subclass based * on the type of each message. This function is used to prepare stored * messages for use in a chat context. */ function mapStoredMessagesToChatMessages(messages) { return messages.map(mapStoredMessageToChatMessage); } exports.mapStoredMessagesToChatMessages = mapStoredMessagesToChatMessages; /** * Transforms an array of `BaseMessage` instances into an array of * `StoredMessage` instances. It does this by calling the `toDict` method * on each `BaseMessage`, which returns a `StoredMessage`. This function * is used to prepare chat messages for storage. */ function mapChatMessagesToStoredMessages(messages) { return messages.map((message) => message.toDict()); } exports.mapChatMessagesToStoredMessages = mapChatMessagesToStoredMessages; function convertToChunk(message) { const type = message._getType(); if (type === "human") { // eslint-disable-next-line @typescript-eslint/no-use-before-define return new human_js_1.HumanMessageChunk({ ...message }); } else if (type === "ai") { let aiChunkFields = { ...message, }; if ("tool_calls" in aiChunkFields) { aiChunkFields = { ...aiChunkFields, tool_call_chunks: aiChunkFields.tool_calls?.map((tc) => ({ ...tc, type: "tool_call_chunk", index: undefined, args: JSON.stringify(tc.args), })), }; } // eslint-disable-next-line @typescript-eslint/no-use-before-define return new ai_js_1.AIMessageChunk({ ...aiChunkFields }); } else if (type === "system") { // eslint-disable-next-line @typescript-eslint/no-use-before-define return new system_js_1.SystemMessageChunk({ ...message }); } else if (type === "function") { // eslint-disable-next-line @typescript-eslint/no-use-before-define return new function_js_1.FunctionMessageChunk({ ...message }); // eslint-disable-next-line @typescript-eslint/no-use-before-define } else if (chat_js_1.ChatMessage.isInstance(message)) { // eslint-disable-next-line @typescript-eslint/no-use-before-define return new chat_js_1.ChatMessageChunk({ ...message }); } else { throw new Error("Unknown message type."); } } exports.convertToChunk = convertToChunk;