mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 13:33:11 +00:00
chore: add pre-built dist folder for npx usage
This commit is contained in:
committed by
Romuald Członkowski
parent
a70d96a373
commit
5057481e70
177
dist/telemetry/mutation-tracker.js
vendored
Normal file
177
dist/telemetry/mutation-tracker.js
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mutationTracker = exports.MutationTracker = void 0;
|
||||
const intent_classifier_js_1 = require("./intent-classifier.js");
|
||||
const mutation_validator_js_1 = require("./mutation-validator.js");
|
||||
const intent_sanitizer_js_1 = require("./intent-sanitizer.js");
|
||||
const workflow_sanitizer_js_1 = require("./workflow-sanitizer.js");
|
||||
const logger_js_1 = require("../utils/logger.js");
|
||||
class MutationTracker {
|
||||
constructor() {
|
||||
this.recentMutations = [];
|
||||
this.RECENT_MUTATIONS_LIMIT = 100;
|
||||
}
|
||||
async processMutation(data, userId) {
|
||||
try {
|
||||
if (!this.validateMutationData(data)) {
|
||||
logger_js_1.logger.debug('Mutation data validation failed');
|
||||
return null;
|
||||
}
|
||||
const workflowBefore = workflow_sanitizer_js_1.WorkflowSanitizer.sanitizeWorkflowRaw(data.workflowBefore);
|
||||
const workflowAfter = workflow_sanitizer_js_1.WorkflowSanitizer.sanitizeWorkflowRaw(data.workflowAfter);
|
||||
const sanitizedIntent = intent_sanitizer_js_1.intentSanitizer.sanitize(data.userIntent);
|
||||
if (mutation_validator_js_1.mutationValidator.shouldExclude(data)) {
|
||||
logger_js_1.logger.debug('Mutation excluded from tracking based on quality criteria');
|
||||
return null;
|
||||
}
|
||||
if (mutation_validator_js_1.mutationValidator.isDuplicate(workflowBefore, workflowAfter, data.operations, this.recentMutations)) {
|
||||
logger_js_1.logger.debug('Duplicate mutation detected, skipping tracking');
|
||||
return null;
|
||||
}
|
||||
const hashBefore = mutation_validator_js_1.mutationValidator.hashWorkflow(workflowBefore);
|
||||
const hashAfter = mutation_validator_js_1.mutationValidator.hashWorkflow(workflowAfter);
|
||||
const structureHashBefore = workflow_sanitizer_js_1.WorkflowSanitizer.generateWorkflowHash(workflowBefore);
|
||||
const structureHashAfter = workflow_sanitizer_js_1.WorkflowSanitizer.generateWorkflowHash(workflowAfter);
|
||||
const intentClassification = intent_classifier_js_1.intentClassifier.classify(data.operations, sanitizedIntent);
|
||||
const changeMetrics = this.calculateChangeMetrics(data.operations);
|
||||
const validationMetrics = this.calculateValidationMetrics(data.validationBefore, data.validationAfter);
|
||||
const record = {
|
||||
userId,
|
||||
sessionId: data.sessionId,
|
||||
workflowBefore,
|
||||
workflowAfter,
|
||||
workflowHashBefore: hashBefore,
|
||||
workflowHashAfter: hashAfter,
|
||||
workflowStructureHashBefore: structureHashBefore,
|
||||
workflowStructureHashAfter: structureHashAfter,
|
||||
userIntent: sanitizedIntent,
|
||||
intentClassification,
|
||||
toolName: data.toolName,
|
||||
operations: data.operations,
|
||||
operationCount: data.operations.length,
|
||||
operationTypes: this.extractOperationTypes(data.operations),
|
||||
validationBefore: data.validationBefore,
|
||||
validationAfter: data.validationAfter,
|
||||
...validationMetrics,
|
||||
...changeMetrics,
|
||||
mutationSuccess: data.mutationSuccess,
|
||||
mutationError: data.mutationError,
|
||||
durationMs: data.durationMs,
|
||||
};
|
||||
this.addToRecentMutations(hashBefore, hashAfter, data.operations);
|
||||
return record;
|
||||
}
|
||||
catch (error) {
|
||||
logger_js_1.logger.error('Error processing mutation:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
validateMutationData(data) {
|
||||
const validationResult = mutation_validator_js_1.mutationValidator.validate(data);
|
||||
if (!validationResult.valid) {
|
||||
logger_js_1.logger.warn('Mutation data validation failed:', validationResult.errors);
|
||||
return false;
|
||||
}
|
||||
if (validationResult.warnings.length > 0) {
|
||||
logger_js_1.logger.debug('Mutation data validation warnings:', validationResult.warnings);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
calculateChangeMetrics(operations) {
|
||||
const metrics = {
|
||||
nodesAdded: 0,
|
||||
nodesRemoved: 0,
|
||||
nodesModified: 0,
|
||||
connectionsAdded: 0,
|
||||
connectionsRemoved: 0,
|
||||
propertiesChanged: 0,
|
||||
};
|
||||
for (const op of operations) {
|
||||
switch (op.type) {
|
||||
case 'addNode':
|
||||
metrics.nodesAdded++;
|
||||
break;
|
||||
case 'removeNode':
|
||||
metrics.nodesRemoved++;
|
||||
break;
|
||||
case 'updateNode':
|
||||
metrics.nodesModified++;
|
||||
if ('updates' in op && op.updates) {
|
||||
metrics.propertiesChanged += Object.keys(op.updates).length;
|
||||
}
|
||||
break;
|
||||
case 'addConnection':
|
||||
metrics.connectionsAdded++;
|
||||
break;
|
||||
case 'removeConnection':
|
||||
metrics.connectionsRemoved++;
|
||||
break;
|
||||
case 'rewireConnection':
|
||||
metrics.connectionsRemoved++;
|
||||
metrics.connectionsAdded++;
|
||||
break;
|
||||
case 'replaceConnections':
|
||||
if ('connections' in op && op.connections) {
|
||||
metrics.connectionsRemoved++;
|
||||
metrics.connectionsAdded++;
|
||||
}
|
||||
break;
|
||||
case 'updateSettings':
|
||||
if ('settings' in op && op.settings) {
|
||||
metrics.propertiesChanged += Object.keys(op.settings).length;
|
||||
}
|
||||
break;
|
||||
case 'moveNode':
|
||||
case 'enableNode':
|
||||
case 'disableNode':
|
||||
case 'updateName':
|
||||
case 'addTag':
|
||||
case 'removeTag':
|
||||
case 'activateWorkflow':
|
||||
case 'deactivateWorkflow':
|
||||
case 'cleanStaleConnections':
|
||||
metrics.propertiesChanged++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
calculateValidationMetrics(validationBefore, validationAfter) {
|
||||
if (!validationBefore || !validationAfter) {
|
||||
return {
|
||||
validationImproved: null,
|
||||
errorsResolved: 0,
|
||||
errorsIntroduced: 0,
|
||||
};
|
||||
}
|
||||
const errorsBefore = validationBefore.errors?.length || 0;
|
||||
const errorsAfter = validationAfter.errors?.length || 0;
|
||||
const errorsResolved = Math.max(0, errorsBefore - errorsAfter);
|
||||
const errorsIntroduced = Math.max(0, errorsAfter - errorsBefore);
|
||||
const validationImproved = errorsBefore > errorsAfter;
|
||||
return {
|
||||
validationImproved,
|
||||
errorsResolved,
|
||||
errorsIntroduced,
|
||||
};
|
||||
}
|
||||
extractOperationTypes(operations) {
|
||||
const types = new Set(operations.map((op) => op.type));
|
||||
return Array.from(types);
|
||||
}
|
||||
addToRecentMutations(hashBefore, hashAfter, operations) {
|
||||
this.recentMutations.push({ hashBefore, hashAfter, operations });
|
||||
if (this.recentMutations.length > this.RECENT_MUTATIONS_LIMIT) {
|
||||
this.recentMutations.shift();
|
||||
}
|
||||
}
|
||||
clearRecentMutations() {
|
||||
this.recentMutations = [];
|
||||
}
|
||||
getRecentMutationsCount() {
|
||||
return this.recentMutations.length;
|
||||
}
|
||||
}
|
||||
exports.MutationTracker = MutationTracker;
|
||||
exports.mutationTracker = new MutationTracker();
|
||||
//# sourceMappingURL=mutation-tracker.js.map
|
||||
Reference in New Issue
Block a user