mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(n8n Evaluation Trigger Node): Add telemetry events (#15465)
This commit is contained in:
@@ -729,6 +729,7 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
sharing_role: userRole,
|
sharing_role: userRole,
|
||||||
credential_type: null,
|
credential_type: null,
|
||||||
is_managed: false,
|
is_managed: false,
|
||||||
|
eval_rows_left: null,
|
||||||
...TelemetryHelpers.resolveAIMetrics(workflow.nodes, this.nodeTypes),
|
...TelemetryHelpers.resolveAIMetrics(workflow.nodes, this.nodeTypes),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -739,6 +740,15 @@ export class TelemetryEventRelay extends EventRelay {
|
|||||||
manualExecEventProperties.node_graph_string = JSON.stringify(nodeGraphResult.nodeGraph);
|
manualExecEventProperties.node_graph_string = JSON.stringify(nodeGraphResult.nodeGraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeGraphResult?.evaluationTriggerNodeNames?.forEach((name: string) => {
|
||||||
|
const rowsLeft =
|
||||||
|
runData.data.resultData.runData[name]?.[0]?.data?.main?.[0]?.[0]?.json?._rowsLeft;
|
||||||
|
|
||||||
|
if (typeof rowsLeft === 'number') {
|
||||||
|
manualExecEventProperties.eval_rows_left = rowsLeft;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (runData.data.startData?.destinationNode) {
|
if (runData.data.startData?.destinationNode) {
|
||||||
const credentialsData = TelemetryHelpers.extractLastExecutedNodeCredentialData(runData);
|
const credentialsData = TelemetryHelpers.extractLastExecutedNodeCredentialData(runData);
|
||||||
if (credentialsData) {
|
if (credentialsData) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export const HTTP_REQUEST_NODE_TYPE = 'n8n-nodes-base.httpRequest';
|
|||||||
export const WEBHOOK_NODE_TYPE = 'n8n-nodes-base.webhook';
|
export const WEBHOOK_NODE_TYPE = 'n8n-nodes-base.webhook';
|
||||||
export const MANUAL_TRIGGER_NODE_TYPE = 'n8n-nodes-base.manualTrigger';
|
export const MANUAL_TRIGGER_NODE_TYPE = 'n8n-nodes-base.manualTrigger';
|
||||||
export const EVALUATION_TRIGGER_NODE_TYPE = 'n8n-nodes-base.evaluationTrigger';
|
export const EVALUATION_TRIGGER_NODE_TYPE = 'n8n-nodes-base.evaluationTrigger';
|
||||||
|
export const EVALUATION_NODE_TYPE = 'n8n-nodes-base.evaluation';
|
||||||
export const ERROR_TRIGGER_NODE_TYPE = 'n8n-nodes-base.errorTrigger';
|
export const ERROR_TRIGGER_NODE_TYPE = 'n8n-nodes-base.errorTrigger';
|
||||||
export const START_NODE_TYPE = 'n8n-nodes-base.start';
|
export const START_NODE_TYPE = 'n8n-nodes-base.start';
|
||||||
export const EXECUTE_WORKFLOW_NODE_TYPE = 'n8n-nodes-base.executeWorkflow';
|
export const EXECUTE_WORKFLOW_NODE_TYPE = 'n8n-nodes-base.executeWorkflow';
|
||||||
|
|||||||
@@ -2587,6 +2587,7 @@ export interface INodeGraphItem {
|
|||||||
workflow_id?: string; //@n8n/n8n-nodes-langchain.toolWorkflow and n8n-nodes-base.executeWorkflow
|
workflow_id?: string; //@n8n/n8n-nodes-langchain.toolWorkflow and n8n-nodes-base.executeWorkflow
|
||||||
runs?: number;
|
runs?: number;
|
||||||
items_total?: number;
|
items_total?: number;
|
||||||
|
metric_names?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodeNameIndex {
|
export interface INodeNameIndex {
|
||||||
@@ -2597,6 +2598,7 @@ export interface INodesGraphResult {
|
|||||||
nodeGraph: INodesGraph;
|
nodeGraph: INodesGraph;
|
||||||
nameIndices: INodeNameIndex;
|
nameIndices: INodeNameIndex;
|
||||||
webhookNodeNames: string[];
|
webhookNodeNames: string[];
|
||||||
|
evaluationTriggerNodeNames: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FeatureFlags {
|
export interface FeatureFlags {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import {
|
|||||||
AI_TRANSFORM_NODE_TYPE,
|
AI_TRANSFORM_NODE_TYPE,
|
||||||
CHAIN_LLM_LANGCHAIN_NODE_TYPE,
|
CHAIN_LLM_LANGCHAIN_NODE_TYPE,
|
||||||
CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE,
|
CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE,
|
||||||
|
EVALUATION_NODE_TYPE,
|
||||||
|
EVALUATION_TRIGGER_NODE_TYPE,
|
||||||
EXECUTE_WORKFLOW_NODE_TYPE,
|
EXECUTE_WORKFLOW_NODE_TYPE,
|
||||||
FREE_AI_CREDITS_ERROR_TYPE,
|
FREE_AI_CREDITS_ERROR_TYPE,
|
||||||
FREE_AI_CREDITS_USED_ALL_CREDITS_ERROR_CODE,
|
FREE_AI_CREDITS_USED_ALL_CREDITS_ERROR_CODE,
|
||||||
@@ -178,11 +180,12 @@ export function generateNodesGraph(
|
|||||||
};
|
};
|
||||||
const nameIndices: INodeNameIndex = {};
|
const nameIndices: INodeNameIndex = {};
|
||||||
const webhookNodeNames: string[] = [];
|
const webhookNodeNames: string[] = [];
|
||||||
|
const evaluationTriggerNodeNames: string[] = [];
|
||||||
|
|
||||||
const notes = (workflow.nodes ?? []).filter((node) => node.type === STICKY_NODE_TYPE);
|
const nodes = (workflow.nodes ?? []).filter((node) => node.type === STICKY_NODE_TYPE);
|
||||||
const otherNodes = (workflow.nodes ?? []).filter((node) => node.type !== STICKY_NODE_TYPE);
|
const otherNodes = (workflow.nodes ?? []).filter((node) => node.type !== STICKY_NODE_TYPE);
|
||||||
|
|
||||||
notes.forEach((stickyNote: INode, index: number) => {
|
nodes.forEach((stickyNote: INode, index: number) => {
|
||||||
const stickyType = nodeTypes.getByNameAndVersion(STICKY_NODE_TYPE, stickyNote.typeVersion);
|
const stickyType = nodeTypes.getByNameAndVersion(STICKY_NODE_TYPE, stickyNote.typeVersion);
|
||||||
if (!stickyType) {
|
if (!stickyType) {
|
||||||
return;
|
return;
|
||||||
@@ -367,6 +370,18 @@ export function generateNodesGraph(
|
|||||||
if (node.parameters?.workflowId) {
|
if (node.parameters?.workflowId) {
|
||||||
nodeItem.workflow_id = node.parameters?.workflowId as string;
|
nodeItem.workflow_id = node.parameters?.workflowId as string;
|
||||||
}
|
}
|
||||||
|
} else if (node.type === EVALUATION_TRIGGER_NODE_TYPE) {
|
||||||
|
evaluationTriggerNodeNames.push(node.name);
|
||||||
|
} else if (
|
||||||
|
node.type === EVALUATION_NODE_TYPE &&
|
||||||
|
options?.isCloudDeployment &&
|
||||||
|
node.parameters?.operation === 'setMetrics'
|
||||||
|
) {
|
||||||
|
const metrics = node.parameters?.metrics as IDataObject;
|
||||||
|
|
||||||
|
nodeItem.metric_names = (metrics.assignments as Array<{ name: string }> | undefined)?.map(
|
||||||
|
(metric: { name: string }) => metric.name,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
const nodeType = nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
||||||
@@ -484,7 +499,7 @@ export function generateNodesGraph(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return { nodeGraph, nameIndices, webhookNodeNames };
|
return { nodeGraph, nameIndices, webhookNodeNames, evaluationTriggerNodeNames };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractLastExecutedNodeCredentialData(
|
export function extractLastExecutedNodeCredentialData(
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -175,6 +176,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: {},
|
nameIndices: {},
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -190,6 +192,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: {},
|
nameIndices: {},
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,6 +259,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -333,6 +337,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
nameIndices: { 'When clicking "Execute Workflow"': '0', 'Google Sheets': '1' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -388,6 +393,7 @@ describe('generateNodesGraph', () => {
|
|||||||
versionId: '70b92d94-0e9a-4b41-9976-a654df420af5',
|
versionId: '70b92d94-0e9a-4b41-9976-a654df420af5',
|
||||||
};
|
};
|
||||||
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
nodeGraph: {
|
nodeGraph: {
|
||||||
node_types: ['n8n-nodes-base.manualTrigger', 'test.googleSheets'],
|
node_types: ['n8n-nodes-base.manualTrigger', 'test.googleSheets'],
|
||||||
node_connections: [{ start: '0', end: '1' }],
|
node_connections: [{ start: '0', end: '1' }],
|
||||||
@@ -451,6 +457,7 @@ describe('generateNodesGraph', () => {
|
|||||||
notes: {},
|
notes: {},
|
||||||
},
|
},
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -474,6 +481,7 @@ describe('generateNodesGraph', () => {
|
|||||||
pinData: {},
|
pinData: {},
|
||||||
};
|
};
|
||||||
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
nodeGraph: {
|
nodeGraph: {
|
||||||
node_types: ['n8n-nodes-base.webhook'],
|
node_types: ['n8n-nodes-base.webhook'],
|
||||||
node_connections: [],
|
node_connections: [],
|
||||||
@@ -520,6 +528,7 @@ describe('generateNodesGraph', () => {
|
|||||||
pinData: {},
|
pinData: {},
|
||||||
};
|
};
|
||||||
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
nodeGraph: {
|
nodeGraph: {
|
||||||
node_types: ['n8n-nodes-base.httpRequest'],
|
node_types: ['n8n-nodes-base.httpRequest'],
|
||||||
node_connections: [],
|
node_connections: [],
|
||||||
@@ -574,6 +583,7 @@ describe('generateNodesGraph', () => {
|
|||||||
pinData: {},
|
pinData: {},
|
||||||
};
|
};
|
||||||
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
expect(generateNodesGraph(workflow, nodeTypes)).toEqual({
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
nodeGraph: {
|
nodeGraph: {
|
||||||
node_types: ['n8n-nodes-base.httpRequest'],
|
node_types: ['n8n-nodes-base.httpRequest'],
|
||||||
node_connections: [],
|
node_connections: [],
|
||||||
@@ -635,6 +645,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'Merge Node V3': '0' },
|
nameIndices: { 'Merge Node V3': '0' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -673,6 +684,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'Merge Node V3': '0' },
|
nameIndices: { 'Merge Node V3': '0' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -713,6 +725,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'Merge Node V3': '0' },
|
nameIndices: { 'Merge Node V3': '0' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])('should return graph with merge v3 node', ({ workflow, expected, isCloudDeployment }) => {
|
])('should return graph with merge v3 node', ({ workflow, expected, isCloudDeployment }) => {
|
||||||
@@ -755,6 +768,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'HTTP Request V1': '0' },
|
nameIndices: { 'HTTP Request V1': '0' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -795,6 +809,7 @@ describe('generateNodesGraph', () => {
|
|||||||
},
|
},
|
||||||
nameIndices: { 'HTTP Request v4 with defaults': '0' },
|
nameIndices: { 'HTTP Request v4 with defaults': '0' },
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -900,6 +915,7 @@ describe('generateNodesGraph', () => {
|
|||||||
Model: '2',
|
Model: '2',
|
||||||
},
|
},
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1012,6 +1028,7 @@ describe('generateNodesGraph', () => {
|
|||||||
notes: {},
|
notes: {},
|
||||||
},
|
},
|
||||||
webhookNodeNames: [],
|
webhookNodeNames: [],
|
||||||
|
evaluationTriggerNodeNames: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user