fix(n8n Evaluation Trigger Node): Fix tweaks (#15473)

This commit is contained in:
Dana
2025-05-19 11:33:07 +02:00
committed by GitHub
parent 5c3840583d
commit 3985387204
7 changed files with 51 additions and 14 deletions

View File

@@ -139,6 +139,32 @@ function getAiNodesBySubcategory(nodes: INodeTypeDescription[], subcategory: str
.sort((a, b) => a.properties.displayName.localeCompare(b.properties.displayName)); .sort((a, b) => a.properties.displayName.localeCompare(b.properties.displayName));
} }
function getEvaluationNode(
nodeTypesStore: ReturnType<typeof useNodeTypesStore>,
isEvaluationVariantEnabled: boolean,
) {
const evaluationNodeStore = nodeTypesStore.getNodeType('n8n-nodes-base.evaluation');
if (!isEvaluationVariantEnabled || !evaluationNodeStore) {
return [];
}
const evaluationNode = getNodeView(evaluationNodeStore);
return [
{
...evaluationNode,
properties: {
...evaluationNode.properties,
defaults: {
name: 'Evaluation',
color: '#c3c9d5',
},
},
},
];
}
export function AIView(_nodes: SimplifiedNodeType[]): NodeView { export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
const i18n = useI18n(); const i18n = useI18n();
const nodeTypesStore = useNodeTypesStore(); const nodeTypesStore = useNodeTypesStore();
@@ -150,9 +176,7 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
EVALUATION_TRIGGER.variant, EVALUATION_TRIGGER.variant,
); );
const evaluationNodeStore = nodeTypesStore.getNodeType('n8n-nodes-base.evaluation'); const evaluationNode = getEvaluationNode(nodeTypesStore, isEvaluationVariantEnabled);
const evaluationNode =
isEvaluationVariantEnabled && evaluationNodeStore ? [getNodeView(evaluationNodeStore)] : [];
const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS); const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS);
const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS); const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS);
@@ -358,9 +382,13 @@ export function TriggerView() {
properties: { properties: {
group: [], group: [],
name: EVALUATION_TRIGGER_NODE_TYPE, name: EVALUATION_TRIGGER_NODE_TYPE,
displayName: 'Evaluation Trigger', displayName: 'When running evaluation',
description: 'Run a dataset through your workflow to test performance', description: 'Run a dataset through your workflow to test performance',
icon: 'fa:check-double', icon: 'fa:check-double',
defaults: {
name: 'Evaluation',
color: '#c3c9d5',
},
}, },
} }
: null; : null;

View File

@@ -1299,7 +1299,7 @@
"nodeCreator.triggerHelperPanel.whatHappensNext": "What happens next?", "nodeCreator.triggerHelperPanel.whatHappensNext": "What happens next?",
"nodeCreator.triggerHelperPanel.selectATrigger": "What triggers this workflow?", "nodeCreator.triggerHelperPanel.selectATrigger": "What triggers this workflow?",
"nodeCreator.triggerHelperPanel.selectATriggerDescription": "A trigger is a step that starts your workflow", "nodeCreator.triggerHelperPanel.selectATriggerDescription": "A trigger is a step that starts your workflow",
"nodeCreator.triggerHelperPanel.workflowTriggerDisplayName": "When Executed by Another Workflow", "nodeCreator.triggerHelperPanel.workflowTriggerDisplayName": "When executed by another workflow",
"nodeCreator.triggerHelperPanel.workflowTriggerDescription": "Runs the flow when called by the Execute Workflow node from a different workflow", "nodeCreator.triggerHelperPanel.workflowTriggerDescription": "Runs the flow when called by the Execute Workflow node from a different workflow",
"nodeCreator.aiPanel.aiNodes": "AI Nodes", "nodeCreator.aiPanel.aiNodes": "AI Nodes",
"nodeCreator.aiPanel.aiOtherNodes": "Other AI Nodes", "nodeCreator.aiPanel.aiOtherNodes": "Other AI Nodes",

View File

@@ -11,6 +11,7 @@ export const setOutputProperties: INodeProperties[] = [
}, },
{ {
...document, ...document,
displayName: 'Document Containing Dataset',
displayOptions: { displayOptions: {
show: { show: {
operation: ['setOutputs'], operation: ['setOutputs'],
@@ -19,6 +20,7 @@ export const setOutputProperties: INodeProperties[] = [
}, },
{ {
...sheet, ...sheet,
displayName: 'Sheet Containing Dataset',
displayOptions: { displayOptions: {
show: { show: {
operation: ['setOutputs'], operation: ['setOutputs'],

View File

@@ -32,6 +32,9 @@ export class Evaluation implements INodeType {
}, },
inputs: [NodeConnectionTypes.Main], inputs: [NodeConnectionTypes.Main],
outputs: `={{(${setOutputs})($parameter)}}`, outputs: `={{(${setOutputs})($parameter)}}`,
codex: {
alias: ['Test', 'Metrics', 'Evals', 'Set Output', 'Set Metrics'],
},
credentials: [ credentials: [
{ {
name: 'googleApi', name: 'googleApi',

View File

@@ -54,9 +54,10 @@ export class EvaluationTrigger implements INodeType {
authentication, authentication,
{ {
...document, ...document,
displayName: 'Document Containing Dataset',
hint: 'Example dataset format <a href="https://docs.google.com/spreadsheets/d/1vD_IdeFUg7sHsK9okL6Doy1rGOkWTnPJV3Dro4FBUsY/edit?gid=0#gid=0">here</a>', hint: 'Example dataset format <a href="https://docs.google.com/spreadsheets/d/1vD_IdeFUg7sHsK9okL6Doy1rGOkWTnPJV3Dro4FBUsY/edit?gid=0#gid=0">here</a>',
}, },
sheet, { ...sheet, displayName: 'Sheet Containing Dataset' },
{ {
displayName: 'Limit Rows', displayName: 'Limit Rows',
name: 'limitRows', name: 'limitRows',
@@ -76,6 +77,9 @@ export class EvaluationTrigger implements INodeType {
}, },
readFilter, readFilter,
], ],
codex: {
alias: ['Test', 'Metrics', 'Evals', 'Set Output', 'Set Metrics'],
},
credentials: [ credentials: [
{ {
name: 'googleApi', name: 'googleApi',

View File

@@ -127,7 +127,7 @@ describe('Test Evaluation', () => {
const result = await new Evaluation().execute.call(mockExecuteFunctions); const result = await new Evaluation().execute.call(mockExecuteFunctions);
expect(result).toEqual([]); expect(result).toEqual([[{ json: {} }]]);
expect(GoogleSheet.prototype.updateRows).not.toBeCalled(); expect(GoogleSheet.prototype.updateRows).not.toBeCalled();

View File

@@ -25,7 +25,7 @@ export async function setOutput(this: IExecuteFunctions): Promise<INodeExecution
message: "No outputs were set since the execution didn't start from an evaluation trigger", message: "No outputs were set since the execution didn't start from an evaluation trigger",
location: 'outputPane', location: 'outputPane',
}); });
return []; return [this.getInputData()];
} }
const outputFields = this.getNodeParameter('outputs.values', 0, []) as Array<{ const outputFields = this.getNodeParameter('outputs.values', 0, []) as Array<{
@@ -107,12 +107,6 @@ export async function setMetrics(this: IExecuteFunctions): Promise<INodeExecutio
const assignmentValue = const assignmentValue =
typeof assignment.value === 'number' ? assignment.value : Number(assignment.value); typeof assignment.value === 'number' ? assignment.value : Number(assignment.value);
if (!assignment.name || isNaN(assignmentValue)) {
throw new NodeOperationError(this.getNode(), 'Metric name missing', {
description: 'Make sure each metric you define has a name',
});
}
if (isNaN(assignmentValue)) { if (isNaN(assignmentValue)) {
throw new NodeOperationError( throw new NodeOperationError(
this.getNode(), this.getNode(),
@@ -123,6 +117,12 @@ export async function setMetrics(this: IExecuteFunctions): Promise<INodeExecutio
); );
} }
if (!assignment.name || isNaN(assignmentValue)) {
throw new NodeOperationError(this.getNode(), 'Metric name missing', {
description: 'Make sure each metric you define has a name',
});
}
const { name, value } = validateEntry( const { name, value } = validateEntry(
assignment.name, assignment.name,
assignment.type as FieldType, assignment.type as FieldType,