@maximai/maxim-js
Version:
Maxim AI JS SDK. Visit https://getmaxim.ai for more info.
420 lines • 19.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MaximLangchainTracer = void 0;
const base_1 = require("@langchain/core/callbacks/base");
const messages_1 = require("@langchain/core/messages");
const util_1 = require("util");
const uuid_1 = require("uuid");
const containers_1 = require("../../models/containers");
const utils_1 = require("./utils");
class MaximLangchainTracer extends base_1.BaseCallbackHandler {
constructor(logger, input) {
super(input);
this.logger = logger;
this.name = "MaximLangchainTracer";
this.containerManager = new containers_1.ContainerManager();
}
safeStringify(value) {
try {
return JSON.stringify(value);
}
catch (error) {
return (0, util_1.inspect)(value, {
depth: 3,
maxArrayLength: 100,
maxStringLength: 1000,
breakLength: Infinity,
compact: true,
});
}
}
getMetadataClassFromRecord(metadata) {
if (metadata && "maxim" in metadata) {
return new containers_1.Metadata(metadata["maxim"]);
}
return null;
}
getContainer(runId, parentRunId, metadata, tags) {
var _a, _b;
let container;
if (parentRunId) {
container = this.containerManager.getContainer(parentRunId);
}
else {
container = this.containerManager.getContainer(runId);
if (!container) {
const traceId = (0, uuid_1.v4)();
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const traceName = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.traceName) !== null && _a !== void 0 ? _a : "Trace";
const sessionId = (_b = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.sessionId) !== null && _b !== void 0 ? _b : undefined;
const traceTags = (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.traceTags, tags);
if (metadata) {
Object.entries(metadata).forEach(([key, value]) => {
if (key !== "maxim") {
traceTags[key.trim()] = typeof value === "string" ? value.trim() : this.safeStringify(value);
}
});
}
container = new containers_1.TraceContainer(this.containerManager, this.logger, traceId, traceName, undefined, false);
if (container instanceof containers_1.TraceContainer) {
container.create(traceTags, sessionId);
}
else {
container.create(traceTags);
}
}
}
return container;
}
handleChainStart(_chain, inputs, runId, parentRunId, tags, metadata, _runType, runName) {
var _a, _b;
try {
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const container = this.getContainer(runId, parentRunId, metadata, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for chain");
return;
}
if (!container.isCreated()) {
container.create();
}
const name = (_b = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.chainName) !== null && _a !== void 0 ? _a : runName) !== null && _b !== void 0 ? _b : "default-chain";
const chainTags = (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.chainTags, tags);
chainTags["run_id"] = runId;
if (parentRunId) {
chainTags["parent_run_id"] = parentRunId;
}
if (metadata) {
Object.entries(metadata).forEach(([key, value]) => {
if (key !== "maxim") {
chainTags[key.trim()] = typeof value === "string" ? value.trim() : this.safeStringify(value);
}
});
}
const spanConfig = {
id: runId,
name: name,
tags: chainTags,
};
const span = container.addSpan(spanConfig);
span.addMetadata({ inputs });
new containers_1.SpanContainer(this.containerManager, this.logger, runId, name, parentRunId, container.type === "trace" ? container.id : undefined, true);
}
catch (e) {
console.error("[MaximSDK] Error while processing chain_start", e);
}
}
handleChainEnd(outputs, runId, _parentRunId, tags, _kwargs) {
try {
const container = this.getContainer(runId, undefined, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for chain");
return;
}
container.addTags((0, utils_1.parseLangchainTags)(undefined, tags));
container.addMetadata({ outputs });
container.end();
}
catch (e) {
console.error("[MaximSDK] Failed to parse chain-end:", e);
}
}
handleChainError(err, runId, _parentRunId, tags) {
try {
const container = this.getContainer(runId, undefined, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for chain");
return;
}
container.addTags((0, utils_1.parseLangchainTags)(undefined, tags));
container.addMetadata({ error: err.message });
container.end();
}
catch (e) {
console.error("[MaximSDK] Failed to parse chain-error:", e);
}
}
async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, name) {
var _a, _b;
try {
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const container = this.getContainer(runId, parentRunId, metadata, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for LLM");
return;
}
if (!container.isCreated()) {
container.create();
}
const parsedMessages = (0, utils_1.parseLangchainMessages)(prompts);
const traceContainer = container.getTraceContainer();
if (traceContainer && traceContainer instanceof containers_1.TraceContainer) {
let lastUserInput = "";
const lastUserMessage = parsedMessages.findLast((m) => m.role === "user");
if (lastUserMessage) {
if (typeof lastUserMessage.content === "string") {
lastUserInput = lastUserMessage.content;
}
else if (Array.isArray(lastUserMessage.content)) {
const textParts = lastUserMessage.content
.filter((item) => item.type === "text")
.map((item) => item.text || "")
.join(" ");
if (textParts) {
lastUserInput = textParts;
}
}
}
if (lastUserInput) {
traceContainer.setInput(lastUserInput);
}
}
const generationName = (_b = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.generationName) !== null && _a !== void 0 ? _a : name) !== null && _b !== void 0 ? _b : "default-generation";
const [model, modelParameters] = (0, utils_1.parseLangchainModelAndParameters)(metadata, extraParams);
const generationConfig = {
id: runId,
name: generationName,
provider: (0, utils_1.determineProvider)(llm.id, metadata),
model,
messages: parsedMessages,
modelParameters,
tags: (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.generationTags, tags),
};
container.addGeneration(generationConfig);
if (!container.parentId) {
this.containerManager.setContainer(runId, container);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing LLM start", e);
}
}
handleLLMEnd(output, runId, parentRunId, tags) {
try {
const container = this.getContainer(runId, parentRunId, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for generation");
return;
}
const result = (0, utils_1.convertLLMResultToCompletionResult)(output);
(0, utils_1.addParsedTagsToLogger)(tags, (key, value) => this.logger.generationAddTag(runId, key, value));
this.logger.generationResult(runId, result);
if (!container.parentId) {
this.containerManager.removeRunIdMapping(runId);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing LLM end", e);
}
}
handleLLMError(err, runId, parentRunId, tags) {
try {
const container = this.getContainer(runId, parentRunId, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for generation");
return;
}
(0, utils_1.addParsedTagsToLogger)(tags, (key, value) => this.logger.generationAddTag(runId, key, value));
const generationError = (0, utils_1.parseLangchainErrorToMaximError)(err);
this.logger.generationError(runId, generationError);
if (!container.parentId) {
this.containerManager.removeRunIdMapping(runId);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing LLM error", e);
}
}
async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
var _a, _b;
try {
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const container = this.getContainer(runId, parentRunId, metadata, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for chat model");
return;
}
if (!container.isCreated()) {
container.create();
}
const parsedMessages = (0, utils_1.parseLangchainMessages)(messages);
const traceContainer = container.getTraceContainer();
if (traceContainer && traceContainer instanceof containers_1.TraceContainer) {
let lastUserInput = "";
const lastUserMessage = parsedMessages.findLast((m) => m.role === "user");
if (lastUserMessage) {
if (typeof lastUserMessage.content === "string") {
lastUserInput = lastUserMessage.content;
}
else if (Array.isArray(lastUserMessage.content)) {
const textParts = lastUserMessage.content
.filter((item) => item.type === "text")
.map((item) => item.text || "")
.join(" ");
if (textParts) {
lastUserInput = textParts;
}
}
}
if (lastUserInput) {
traceContainer.setInput(lastUserInput);
}
}
const generationName = (_b = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.generationName) !== null && _a !== void 0 ? _a : runName) !== null && _b !== void 0 ? _b : "default-generation";
const [model, modelParameters] = (0, utils_1.parseLangchainModelAndParameters)(metadata, extraParams);
const generationConfig = {
id: runId,
name: generationName,
provider: (0, utils_1.determineProvider)(llm.id, metadata),
model,
messages: parsedMessages,
modelParameters,
tags: (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.generationTags, tags),
};
container.addGeneration(generationConfig);
if (!container.parentId) {
this.containerManager.setContainer(runId, container);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing chat model start", e);
}
}
handleRetrieverStart(_retriever, query, runId, parentRunId, tags, metadata, name) {
var _a, _b;
try {
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const container = this.getContainer(runId, parentRunId, metadata, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for retrieval");
return;
}
if (!container.isCreated()) {
container.create();
}
const retrievalId = runId;
const retrievalName = (_b = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.retrievalName) !== null && _a !== void 0 ? _a : name) !== null && _b !== void 0 ? _b : "default-retrieval";
const retrievalConfig = {
id: retrievalId,
name: retrievalName,
tags: (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.retrievalTags, tags),
};
const retrieval = container.addRetrieval(retrievalConfig);
retrieval.input(query);
if (!container.parentId) {
this.containerManager.setContainer(runId, container);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing retriever start", e);
}
}
handleRetrieverEnd(documents, runId, parentRunId, tags) {
try {
const container = this.getContainer(runId, parentRunId, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for retrieval");
return;
}
(0, utils_1.addParsedTagsToLogger)(tags, (key, value) => this.logger.retrievalAddTag(runId, key, value));
this.logger.retrievalOutput(runId, this.safeStringify(documents));
if (!container.parentId) {
this.containerManager.removeRunIdMapping(runId);
}
}
catch (e) {
console.error("[MaximSDK] Error while processing retriever end", e);
}
}
handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName) {
var _a, _b, _c;
try {
const maximMetadata = this.getMetadataClassFromRecord(metadata);
const container = this.getContainer(runId, parentRunId, metadata, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for tool");
return;
}
if (!container.isCreated()) {
container.create();
}
const name = (_c = (_b = (_a = maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.toolCallName) !== null && _a !== void 0 ? _a : runName) !== null && _b !== void 0 ? _b : tool.name) !== null && _c !== void 0 ? _c : "default-tool";
const description = "description" in tool ? tool.description : "";
const toolCallConfig = {
id: runId,
name,
description,
args: input,
tags: (0, utils_1.parseLangchainTags)(maximMetadata === null || maximMetadata === void 0 ? void 0 : maximMetadata.toolCallTags, tags),
};
container.addToolCall(toolCallConfig);
if (!container.parentId) {
this.containerManager.setContainer(runId, container);
}
}
catch (e) {
console.error("[MaximSDK] Failed to parse tool-start:", e);
}
}
handleToolEnd(output, runId, parentRunId, tags) {
try {
const container = this.getContainer(runId, parentRunId, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for tool");
return;
}
(0, utils_1.addParsedTagsToLogger)(tags, (key, value) => this.logger.toolCallAddTag(runId, key, value));
try {
(0, messages_1.isToolMessage)(output);
if (output.status) {
if (output.status === "success") {
this.logger.toolCallResult(runId, typeof output.content === "string" ? output.content : this.safeStringify(output.content));
}
else if (output.status === "error") {
this.logger.toolCallError(runId, {
message: typeof output.content === "string" ? output.content : this.safeStringify(output.content),
});
}
}
else {
this.logger.toolCallResult(runId, typeof output.content === "string" ? output.content : this.safeStringify(output.content));
}
}
catch (err) {
this.logger.toolCallResult(runId, typeof output === "function" ||
typeof output === "object" ||
typeof output === "symbol" ||
typeof output === "undefined" ||
output === null
? this.safeStringify(output)
: String(output));
}
if (!container.parentId) {
this.containerManager.removeRunIdMapping(runId);
}
}
catch (e) {
console.error("[MaximSDK] Failed to parse tool-end:", e);
}
}
handleToolError(error, runId, parentRunId, tags) {
try {
const container = this.getContainer(runId, parentRunId, undefined, tags);
if (!container) {
console.error("[MaximSDK] Couldn't find a container for tool");
return;
}
(0, utils_1.addParsedTagsToLogger)(tags, (key, value) => this.logger.toolCallAddTag(runId, key, value));
const toolCallError = (0, utils_1.parseLangchainErrorToMaximError)(error);
this.logger.toolCallError(runId, toolCallError);
if (!container.parentId) {
this.containerManager.removeRunIdMapping(runId);
}
}
catch (e) {
console.error("[MaximSDK] Failed to parse tool-end:", e);
}
}
}
exports.MaximLangchainTracer = MaximLangchainTracer;
//# sourceMappingURL=tracer.js.map