UNPKG

@maximai/maxim-js-langchain

Version:

This is the langchain wrapper built for (Maxim JS SDK)[https://www.npmjs.com/package/@maximai/maxim-js].

369 lines (368 loc) 16.4 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseLangchainModelAndParameters = parseLangchainModelAndParameters; exports.determineProvider = determineProvider; exports.parseMessage = parseMessage; exports.convertLLMResultToCompletionResult = convertLLMResultToCompletionResult; exports.parseTokenUsageForResult = parseTokenUsageForResult; exports.parseLangchainLLMError = parseLangchainLLMError; exports.maybeParseJSON = maybeParseJSON; exports.parseLangchainMessages = parseLangchainMessages; const messages_1 = require("@langchain/core/messages"); const uuid_1 = require("uuid"); function parseLangchainModelAndParameters(llm, metadata, extraParams) { let modelParams = (extraParams === null || extraParams === void 0 ? void 0 : extraParams["invocation_params"]) || {}; // bedrock returns inferenceConfig in extraParams if ("inferenceConfig" in modelParams && typeof modelParams["inferenceConfig"] === "object") { const { inferenceConfig } = modelParams, rest = __rest(modelParams, ["inferenceConfig"]); modelParams = Object.assign(Object.assign({}, inferenceConfig), rest); } let model = "unknown"; if ("model_name" in modelParams) { model = modelParams["model_name"]; modelParams === null || modelParams === void 0 ? true : delete modelParams["model_name"]; } else if ("model" in modelParams) { model = modelParams["model"]; modelParams === null || modelParams === void 0 ? true : delete modelParams["model"]; } else if ("model_id" in modelParams) { model = modelParams["model_id"]; modelParams === null || modelParams === void 0 ? true : delete modelParams["model_id"]; } if (model === "unknown") { if (metadata && "ls_model_name" in metadata && typeof metadata["ls_model_name"] === "string") { model = metadata["ls_model_name"]; } } return [model, Object.assign({}, modelParams)]; } function determineProvider(ids, metadata) { const mapper = (param) => { if (param.includes("azure")) return "azure"; if (param.includes("azure_openai")) return "azure"; if (param.includes("amazon_bedrock")) return "bedrock"; if (param.includes("bedrock")) return "bedrock"; if (param.includes("huggingface")) return "huggingface"; if (param.includes("together")) return "together"; if (param.includes("openai")) return "openai"; if (param.includes("anthropic")) return "anthropic"; if (param.includes("google")) return "google"; if (param.includes("groq")) return "groq"; return null; }; const provider = mapper(ids); if (provider !== null) { return provider; } if (metadata && "ls_provider" in metadata && typeof metadata["ls_provider"] === "string") { const lsProvider = metadata["ls_provider"]; const provider = mapper(lsProvider); if (provider !== null) { return provider; } } return "openai"; } function parseMessage(generation) { var _a; if (!("message" in generation)) { return undefined; } const message = generation.message; if (!message) { return undefined; } let toolCalls = undefined; if ((0, messages_1.isAIMessage)(message)) { const aiMessage = new messages_1.AIMessage(message); toolCalls = (_a = aiMessage["tool_calls"]) === null || _a === void 0 ? void 0 : _a.map((toolCall) => { return { type: "function", id: toolCall.id, function: { name: toolCall.name, arguments: JSON.stringify(toolCall.args), }, }; }); } return { role: "assistant", content: typeof message.content === "string" ? message.content : JSON.stringify(message.content), tool_calls: toolCalls, function_call: toolCalls, }; } function convertLLMResultToCompletionResult(result) { var _a, _b, _c, _d; let model = "unknown"; if (result.generations.length === 0) { return { id: (0, uuid_1.v4)(), object: "chat_completion", created: Math.floor(Date.now() / 1000), model, choices: [], usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0, }, }; } let finishReason = "stop"; if ((_a = result.llmOutput) === null || _a === void 0 ? void 0 : _a["stop_reason"]) { finishReason = result.llmOutput["stop_reason"]; // anthropic } const choices = result.generations[0].map((gen, index) => { var _a, _b; return ({ index, text: gen.text.trim() === "" ? undefined : gen.text.trim(), message: parseMessage(gen), logprobs: null, finish_reason: (_b = (_a = gen.generationInfo) === null || _a === void 0 ? void 0 : _a["finish_reason"]) !== null && _b !== void 0 ? _b : finishReason, }); }); const [gen] = result.generations[0]; if ("message" in gen) { const message = gen.message; model = (_c = (_b = message.response_metadata) === null || _b === void 0 ? void 0 : _b["model_name"]) !== null && _c !== void 0 ? _c : "unknown"; } return { id: (0, uuid_1.v4)(), object: ((_d = choices === null || choices === void 0 ? void 0 : choices[0]) === null || _d === void 0 ? void 0 : _d.text) ? "text_completion" : "chat_completion", created: Math.floor(Date.now() / 1000), model: model, choices, usage: parseTokenUsageForResult(result), }; } function parseTokenUsageForResult(result) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7; let usage = (_a = result.llmOutput) === null || _a === void 0 ? void 0 : _a["tokenUsage"]; if (usage) { const promptTokens = (_b = usage.promptTokens) !== null && _b !== void 0 ? _b : 0; const completionTokens = (_c = usage.completionTokens) !== null && _c !== void 0 ? _c : 0; const totalTokens = promptTokens + completionTokens; return { prompt_tokens: promptTokens, completion_tokens: completionTokens, total_tokens: totalTokens, }; } const llm_usage = (_d = result.llmOutput) === null || _d === void 0 ? void 0 : _d["usage"]; if (llm_usage) { if (llm_usage.input_tokens !== undefined) { usage = { prompt_tokens: (_e = llm_usage.input_tokens) !== null && _e !== void 0 ? _e : 0, completion_tokens: (_f = llm_usage.output_tokens) !== null && _f !== void 0 ? _f : 0, total_tokens: ((_g = llm_usage.input_tokens) !== null && _g !== void 0 ? _g : 0) + ((_h = llm_usage.output_tokens) !== null && _h !== void 0 ? _h : 0), }; } else if (llm_usage.prompt_tokens !== undefined) { usage = { prompt_tokens: (_j = llm_usage.prompt_tokens) !== null && _j !== void 0 ? _j : 0, completion_tokens: (_k = llm_usage.completion_tokens) !== null && _k !== void 0 ? _k : 0, total_tokens: ((_l = llm_usage.prompt_tokens) !== null && _l !== void 0 ? _l : 0) + ((_m = llm_usage.completion_tokens) !== null && _m !== void 0 ? _m : 0), }; } } if (usage) { return usage; } // Process individual generations if no top-level usage is found let prompt_tokens = 0; let output_tokens = 0; let total_tokens = 0; const generations = result.generations; if (generations) { for (const generation of generations) { for (const gen of generation) { const message = "message" in gen ? gen.message : undefined; const usage_data = message === null || message === void 0 ? void 0 : message.usage_metadata; if (usage_data) { if (usage_data.input_tokens !== undefined) { prompt_tokens += (_o = usage_data.input_tokens) !== null && _o !== void 0 ? _o : 0; output_tokens += (_p = usage_data.output_tokens) !== null && _p !== void 0 ? _p : 0; total_tokens += ((_q = usage_data.input_tokens) !== null && _q !== void 0 ? _q : 0) + ((_r = usage_data.output_tokens) !== null && _r !== void 0 ? _r : 0); continue; } else if (usage_data.prompt_tokens !== undefined) { prompt_tokens += (_s = usage_data.prompt_tokens) !== null && _s !== void 0 ? _s : 0; output_tokens += (_t = usage_data.completion_tokens) !== null && _t !== void 0 ? _t : 0; total_tokens += ((_u = usage_data.prompt_tokens) !== null && _u !== void 0 ? _u : 0) + ((_v = usage_data.completion_tokens) !== null && _v !== void 0 ? _v : 0); continue; } } const resp_metadata = message === null || message === void 0 ? void 0 : message.response_metadata; if (resp_metadata) { const metadata_usage = resp_metadata.usage; if (metadata_usage) { if (metadata_usage.input_tokens !== undefined) { prompt_tokens += (_w = metadata_usage.input_tokens) !== null && _w !== void 0 ? _w : 0; output_tokens += (_x = metadata_usage.output_tokens) !== null && _x !== void 0 ? _x : 0; total_tokens += ((_y = metadata_usage.input_tokens) !== null && _y !== void 0 ? _y : 0) + ((_z = metadata_usage.output_tokens) !== null && _z !== void 0 ? _z : 0); continue; } else if (metadata_usage.prompt_tokens !== undefined) { prompt_tokens += (_0 = metadata_usage.prompt_tokens) !== null && _0 !== void 0 ? _0 : 0; output_tokens += (_1 = metadata_usage.completion_tokens) !== null && _1 !== void 0 ? _1 : 0; total_tokens += ((_2 = metadata_usage.prompt_tokens) !== null && _2 !== void 0 ? _2 : 0) + ((_3 = metadata_usage.completion_tokens) !== null && _3 !== void 0 ? _3 : 0); continue; } } // Handle Amazon Bedrock case const bedrock_usage = resp_metadata["amazon-bedrock-invocationMetrics"]; if (bedrock_usage) { prompt_tokens += (_4 = bedrock_usage.inputTokenCount) !== null && _4 !== void 0 ? _4 : 0; output_tokens += (_5 = bedrock_usage.outputTokenCount) !== null && _5 !== void 0 ? _5 : 0; total_tokens += ((_6 = bedrock_usage.inputTokenCount) !== null && _6 !== void 0 ? _6 : 0) + ((_7 = bedrock_usage.outputTokenCount) !== null && _7 !== void 0 ? _7 : 0); } } } } } return { prompt_tokens, completion_tokens: output_tokens, total_tokens, }; } function parseLangchainLLMError(error) { if (error instanceof Error) { return { message: error.message, type: error.name, code: error.code, }; } else if (typeof error === "object" && error !== null) { const errorObj = error; return { message: String(errorObj["message"] || "Unknown error"), type: String(errorObj["type"] || errorObj["name"] || "Unknown"), code: String(errorObj["code"] || undefined), }; } else if (typeof error === "string") { return { message: error, type: "Unknown", }; } else { return { message: "An unknown error occurred", type: "Unknown", }; } } function maybeParseJSON(input = "") { try { return JSON.parse(input); } catch (e) { return input; } } function parseLangchainMessages(input, defaultRole = "user") { try { const delimiterToRole = { System: "system", Human: "user", User: "user", Assistant: "assistant", Model: "assistant", }; const messages = []; if (Array.isArray(input[0])) { input.forEach((messageList) => { messageList.forEach((message) => { if (typeof message === "string") { return; } const messageType = message.constructor.name; if (messageType === "SystemMessage") { messages.push({ role: "system", content: maybeParseJSON(message.content) }); } else if (messageType === "HumanMessage") { messages.push({ role: "user", content: maybeParseJSON(message.content) }); } else if (messageType === "AIMessage") { messages.push(Object.assign({ role: "assistant", content: maybeParseJSON(message.content) }, ("tool_calls" in message ? { tool_calls: message.tool_calls } : {}))); } else if (messageType === "ToolMessage") { messages.push({ role: "assistant", content: maybeParseJSON(message.content) }); } else { console.error(`Invalid message type: ${messageType}`, { message }); throw new Error(`Invalid message type: ${messageType}`); } }); }); } else { input.forEach((message) => { if (typeof message !== "string") { console.error(`Invalid message type: ${typeof message}`); throw new Error(`Invalid message type: ${typeof message}`); } const pattern = /(System:|Human:|User:|Assistant:|Model:)/; const splits = message.split(pattern).filter((s) => s.trim()); for (let i = 0; i < splits.length; i += 2) { if (i + 1 < splits.length) { const delimiter = splits[i].replace(":", "").trim(); const content = splits[i + 1].trim(); messages.push({ role: delimiterToRole[delimiter] || "user", content: maybeParseJSON(content), }); } else { if (splits[i].indexOf(":") === -1) { messages.push({ role: delimiterToRole[defaultRole] || "user", content: maybeParseJSON(splits[i]), }); } else { const delimiter = splits[i].replace(":", "").trim(); messages.push({ role: delimiterToRole[delimiter] || "user", content: "", }); } } } }); } return messages; } catch (e) { console.error(`Error parsing messages: ${e}`); throw new Error(`Error parsing messages: ${e}`); } }