n8n-nodes-databricks-api
Version:
Databricks node for n8n
140 lines • 6.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.N8nLlmTracing = void 0;
const base_1 = require("@langchain/core/callbacks/base");
const base_2 = require("@langchain/core/language_models/base");
const tiktoken_1 = require("@langchain/core/utils/tiktoken");
const lodash_1 = require("lodash");
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../../utils/helpers");
const TIKTOKEN_ESTIMATE_MODEL = 'gpt-4o';
class N8nLlmTracing extends base_1.BaseCallbackHandler {
constructor(executionFunctions, options) {
super();
this.executionFunctions = executionFunctions;
this.name = 'N8nLlmTracing';
this.awaitHandlers = true;
this.connectionType = n8n_workflow_1.NodeConnectionTypes.AiLanguageModel;
this.promptTokensEstimate = 0;
this.completionTokensEstimate = 0;
this.runsMap = {};
this.options = {
tokensUsageParser: (llmOutput) => {
var _a, _b, _c, _d;
const completionTokens = (_b = (_a = llmOutput === null || llmOutput === void 0 ? void 0 : llmOutput.tokenUsage) === null || _a === void 0 ? void 0 : _a.completionTokens) !== null && _b !== void 0 ? _b : 0;
const promptTokens = (_d = (_c = llmOutput === null || llmOutput === void 0 ? void 0 : llmOutput.tokenUsage) === null || _c === void 0 ? void 0 : _c.promptTokens) !== null && _d !== void 0 ? _d : 0;
return {
completionTokens,
promptTokens,
totalTokens: completionTokens + promptTokens,
};
},
errorDescriptionMapper: (error) => error.description,
};
this.options = { ...this.options, ...options };
}
async estimateTokensFromGeneration(generations) {
const messages = generations.flatMap((gen) => gen.map((g) => g.text));
return await this.estimateTokensFromStringList(messages);
}
async estimateTokensFromStringList(list) {
const embeddingModel = (0, base_2.getModelNameForTiktoken)(TIKTOKEN_ESTIMATE_MODEL);
const encoder = await (0, tiktoken_1.encodingForModel)(embeddingModel);
const encodedListLength = await Promise.all(list.map(async (text) => encoder.encode(text).length));
return encodedListLength.reduce((acc, curr) => acc + curr, 0);
}
async handleLLMEnd(output, runId) {
var _a;
const runDetails = (_a = this.runsMap[runId]) !== null && _a !== void 0 ? _a : { index: Object.keys(this.runsMap).length };
output.generations = output.generations.map((gen) => gen.map((g) => (0, lodash_1.pick)(g, ['text', 'generationInfo'])));
const tokenUsageEstimate = {
completionTokens: 0,
promptTokens: 0,
totalTokens: 0,
};
const tokenUsage = this.options.tokensUsageParser(output.llmOutput);
if (output.generations.length > 0) {
tokenUsageEstimate.completionTokens = await this.estimateTokensFromGeneration(output.generations);
tokenUsageEstimate.promptTokens = this.promptTokensEstimate;
tokenUsageEstimate.totalTokens =
tokenUsageEstimate.completionTokens + this.promptTokensEstimate;
}
const response = {
response: { generations: output.generations },
};
if (tokenUsage.completionTokens > 0) {
response.tokenUsage = tokenUsage;
}
else {
response.tokenUsageEstimate = tokenUsageEstimate;
}
const parsedMessages = typeof runDetails.messages === 'string'
? runDetails.messages
: runDetails.messages.map((message) => {
if (typeof message === 'string')
return message;
if (typeof (message === null || message === void 0 ? void 0 : message.toJSON) === 'function')
return message.toJSON();
return message;
});
this.executionFunctions.addOutputData(this.connectionType, runDetails.index, [
[{ json: { ...response } }],
]);
(0, helpers_1.logAiEvent)(this.executionFunctions, 'ai-llm-generated-output', {
messages: parsedMessages,
options: runDetails.options,
response,
});
}
async handleLLMStart(llm, prompts, runId) {
const estimatedTokens = await this.estimateTokensFromStringList(prompts);
const options = llm.type === 'constructor' ? llm.kwargs : llm;
const { index } = this.executionFunctions.addInputData(this.connectionType, [
[
{
json: {
messages: prompts,
estimatedTokens,
options,
},
},
],
]);
this.runsMap[runId] = {
index,
options,
messages: prompts,
};
this.promptTokensEstimate = estimatedTokens;
}
async handleLLMError(error, runId, parentRunId) {
var _a;
const runDetails = (_a = this.runsMap[runId]) !== null && _a !== void 0 ? _a : { index: Object.keys(this.runsMap).length };
if (typeof error === 'object' && (error === null || error === void 0 ? void 0 : error.hasOwnProperty('headers'))) {
const errorWithHeaders = error;
Object.keys(errorWithHeaders.headers).forEach((key) => {
if (!key.startsWith('x-')) {
delete errorWithHeaders.headers[key];
}
});
}
if (error instanceof n8n_workflow_1.NodeError) {
if (this.options.errorDescriptionMapper) {
error.description = this.options.errorDescriptionMapper(error);
}
this.executionFunctions.addOutputData(this.connectionType, runDetails.index, error);
}
else {
this.executionFunctions.addOutputData(this.connectionType, runDetails.index, new n8n_workflow_1.NodeOperationError(this.executionFunctions.getNode(), error, {
functionality: 'configuration-node',
}));
}
(0, helpers_1.logAiEvent)(this.executionFunctions, 'ai-llm-errored', {
error: Object.keys(error).length === 0 ? error.toString() : error,
runId,
parentRunId,
});
}
}
exports.N8nLlmTracing = N8nLlmTracing;
//# sourceMappingURL=N8nLlmTracing.js.map