mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(core): Fix metric default value handling and add AI model connection validation for setMetric operation in Evaluation (#18088)
This commit is contained in:
@@ -9,7 +9,11 @@ import { readFileSync } from 'fs';
|
|||||||
import type { Mock } from 'jest-mock';
|
import type { Mock } from 'jest-mock';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
import type { ErrorReporter } from 'n8n-core';
|
import type { ErrorReporter } from 'n8n-core';
|
||||||
import { EVALUATION_NODE_TYPE, EVALUATION_TRIGGER_NODE_TYPE } from 'n8n-workflow';
|
import {
|
||||||
|
EVALUATION_NODE_TYPE,
|
||||||
|
EVALUATION_TRIGGER_NODE_TYPE,
|
||||||
|
NodeConnectionTypes,
|
||||||
|
} from 'n8n-workflow';
|
||||||
import type { IWorkflowBase, IRun, ExecutionError } from 'n8n-workflow';
|
import type { IWorkflowBase, IRun, ExecutionError } from 'n8n-workflow';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
@@ -1225,46 +1229,45 @@ describe('TestRunnerService', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail for version >= 4.7 with missing metric parameter', () => {
|
it('should pass for version >= 4.7 with missing metric parameter (uses default correctness) when model connected', () => {
|
||||||
const workflow = mock<IWorkflowBase>({
|
const workflow = mock<IWorkflowBase>({
|
||||||
nodes: [
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'model1',
|
||||||
|
name: 'OpenAI Model',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'node1',
|
id: 'node1',
|
||||||
name: 'Set Metrics',
|
name: 'Set Metrics',
|
||||||
type: EVALUATION_NODE_TYPE,
|
type: EVALUATION_NODE_TYPE,
|
||||||
typeVersion: 4.7,
|
typeVersion: 4.7,
|
||||||
position: [0, 0],
|
position: [100, 0],
|
||||||
parameters: {
|
parameters: {
|
||||||
operation: 'setMetrics',
|
operation: 'setMetrics',
|
||||||
metrics: {
|
// metric parameter is undefined, which means it uses the default value 'correctness'
|
||||||
assignments: [
|
// This should pass since correctness is valid and has model connected
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
name: 'accuracy',
|
|
||||||
value: 0.95,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
connections: {},
|
connections: {
|
||||||
|
'OpenAI Model': {
|
||||||
|
[NodeConnectionTypes.AiLanguageModel]: [
|
||||||
|
[{ node: 'Set Metrics', type: 'ai_languageModel', index: 0 }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Missing metric parameter - this should fail for versions >= 4.7
|
// Missing metric parameter - this should pass for versions >= 4.7 since it defaults to 'correctness' and has model
|
||||||
workflow.nodes[0].parameters.metric = undefined;
|
workflow.nodes[1].parameters.metric = undefined;
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
}).toThrow(TestRunError);
|
}).not.toThrow();
|
||||||
|
|
||||||
try {
|
|
||||||
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
|
||||||
} catch (error) {
|
|
||||||
expect(error).toBeInstanceOf(TestRunError);
|
|
||||||
expect(error.code).toBe('SET_METRICS_NODE_NOT_CONFIGURED');
|
|
||||||
expect(error.extra).toEqual({ node_name: 'Set Metrics' });
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass for version >= 4.7 with valid customMetrics configuration', () => {
|
it('should pass for version >= 4.7 with valid customMetrics configuration', () => {
|
||||||
@@ -1299,7 +1302,7 @@ describe('TestRunnerService', () => {
|
|||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass for version >= 4.7 with non-customMetrics metric (no metrics validation needed)', () => {
|
it('should pass for version >= 4.7 with non-AI metric (no model connection needed)', () => {
|
||||||
const workflow = mock<IWorkflowBase>({
|
const workflow = mock<IWorkflowBase>({
|
||||||
nodes: [
|
nodes: [
|
||||||
{
|
{
|
||||||
@@ -1310,8 +1313,8 @@ describe('TestRunnerService', () => {
|
|||||||
position: [0, 0],
|
position: [0, 0],
|
||||||
parameters: {
|
parameters: {
|
||||||
operation: 'setMetrics',
|
operation: 'setMetrics',
|
||||||
metric: 'correctness',
|
metric: 'stringSimilarity',
|
||||||
// No metrics parameter needed for non-customMetrics
|
// Non-AI metrics don't need model connection
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -1360,12 +1363,20 @@ describe('TestRunnerService', () => {
|
|||||||
it('should handle mixed versions correctly', () => {
|
it('should handle mixed versions correctly', () => {
|
||||||
const workflow = mock<IWorkflowBase>({
|
const workflow = mock<IWorkflowBase>({
|
||||||
nodes: [
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'model1',
|
||||||
|
name: 'OpenAI Model',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'node1',
|
id: 'node1',
|
||||||
name: 'Set Metrics Old',
|
name: 'Set Metrics Old',
|
||||||
type: EVALUATION_NODE_TYPE,
|
type: EVALUATION_NODE_TYPE,
|
||||||
typeVersion: 4.6,
|
typeVersion: 4.6,
|
||||||
position: [0, 0],
|
position: [100, 0],
|
||||||
parameters: {
|
parameters: {
|
||||||
operation: 'setMetrics',
|
operation: 'setMetrics',
|
||||||
// No metric parameter for old version
|
// No metric parameter for old version
|
||||||
@@ -1385,21 +1396,227 @@ describe('TestRunnerService', () => {
|
|||||||
name: 'Set Metrics New',
|
name: 'Set Metrics New',
|
||||||
type: EVALUATION_NODE_TYPE,
|
type: EVALUATION_NODE_TYPE,
|
||||||
typeVersion: 4.7,
|
typeVersion: 4.7,
|
||||||
position: [100, 0],
|
position: [200, 0],
|
||||||
parameters: {
|
parameters: {
|
||||||
operation: 'setMetrics',
|
operation: 'setMetrics',
|
||||||
metric: 'correctness',
|
metric: 'correctness',
|
||||||
// No metrics parameter needed for non-customMetrics
|
// Correctness needs model connection for version 4.7+
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
connections: {},
|
connections: {
|
||||||
|
'OpenAI Model': {
|
||||||
|
[NodeConnectionTypes.AiLanguageModel]: [
|
||||||
|
[{ node: 'Set Metrics New', type: 'ai_languageModel', index: 0 }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(() => {
|
expect(() => {
|
||||||
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Model connection validation', () => {
|
||||||
|
it('should pass when correctness metric has model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'model1',
|
||||||
|
name: 'OpenAI Model',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [100, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'correctness',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {
|
||||||
|
'OpenAI Model': {
|
||||||
|
[NodeConnectionTypes.AiLanguageModel]: [
|
||||||
|
[{ node: 'Set Metrics', type: 'ai_languageModel', index: 0 }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail when correctness metric has no model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'correctness',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).toThrow(TestRunError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass when helpfulness metric has model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'model1',
|
||||||
|
name: 'OpenAI Model',
|
||||||
|
type: '@n8n/n8n-nodes-langchain.lmChatOpenAi',
|
||||||
|
typeVersion: 1,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [100, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'helpfulness',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {
|
||||||
|
'OpenAI Model': {
|
||||||
|
[NodeConnectionTypes.AiLanguageModel]: [
|
||||||
|
[{ node: 'Set Metrics', type: 'ai_languageModel', index: 0 }],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail when helpfulness metric has no model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'helpfulness',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).toThrow(TestRunError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail when default correctness metric (undefined) has no model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: undefined, // explicitly set to undefined to test default behavior
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).toThrow(TestRunError);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass when non-AI metrics (customMetrics) have no model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'customMetrics',
|
||||||
|
metrics: {
|
||||||
|
assignments: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'accuracy',
|
||||||
|
value: 0.95,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass when stringSimilarity metric has no model connected', () => {
|
||||||
|
const workflow = mock<IWorkflowBase>({
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
id: 'metrics1',
|
||||||
|
name: 'Set Metrics',
|
||||||
|
type: EVALUATION_NODE_TYPE,
|
||||||
|
typeVersion: 4.7,
|
||||||
|
position: [0, 0],
|
||||||
|
parameters: {
|
||||||
|
operation: 'setMetrics',
|
||||||
|
metric: 'stringSimilarity',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
connections: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
(testRunnerService as any).validateSetMetricsNodes(workflow);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
EVALUATION_TRIGGER_NODE_TYPE,
|
EVALUATION_TRIGGER_NODE_TYPE,
|
||||||
ExecutionCancelledError,
|
ExecutionCancelledError,
|
||||||
NodeConnectionTypes,
|
NodeConnectionTypes,
|
||||||
|
metricRequiresModelConnection,
|
||||||
|
DEFAULT_EVALUATION_METRIC,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import type {
|
import type {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
@@ -102,6 +104,16 @@ export class TestRunnerService {
|
|||||||
* Checks if the Evaluation Set Metrics nodes are present in the workflow
|
* Checks if the Evaluation Set Metrics nodes are present in the workflow
|
||||||
* and are configured correctly.
|
* and are configured correctly.
|
||||||
*/
|
*/
|
||||||
|
private hasModelNodeConnected(workflow: IWorkflowBase, targetNodeName: string): boolean {
|
||||||
|
// Check if there's a node connected to the target node via ai_languageModel connection type
|
||||||
|
return Object.keys(workflow.connections).some((sourceNodeName) => {
|
||||||
|
const connections = workflow.connections[sourceNodeName];
|
||||||
|
return connections?.[NodeConnectionTypes.AiLanguageModel]?.[0]?.some(
|
||||||
|
(connection) => connection.node === targetNodeName,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private validateSetMetricsNodes(workflow: IWorkflowBase) {
|
private validateSetMetricsNodes(workflow: IWorkflowBase) {
|
||||||
const metricsNodes = TestRunnerService.getEvaluationMetricsNodes(workflow);
|
const metricsNodes = TestRunnerService.getEvaluationMetricsNodes(workflow);
|
||||||
if (metricsNodes.length === 0) {
|
if (metricsNodes.length === 0) {
|
||||||
@@ -113,11 +125,6 @@ export class TestRunnerService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For versions 4.7+, check if metric parameter is missing
|
|
||||||
if (node.typeVersion >= 4.7 && !node.parameters.metric) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check customMetrics configuration if:
|
// Check customMetrics configuration if:
|
||||||
// - Version 4.7+ and metric is 'customMetrics'
|
// - Version 4.7+ and metric is 'customMetrics'
|
||||||
// - Version < 4.7 (customMetrics is default)
|
// - Version < 4.7 (customMetrics is default)
|
||||||
@@ -134,6 +141,17 @@ export class TestRunnerService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For version 4.7+, check if AI-based metrics require model connection
|
||||||
|
if (node.typeVersion >= 4.7) {
|
||||||
|
const metric = (node.parameters.metric ?? DEFAULT_EVALUATION_METRIC) as string;
|
||||||
|
if (
|
||||||
|
metricRequiresModelConnection(metric) && // See packages/workflow/src/evaluation-helpers.ts
|
||||||
|
!this.hasModelNodeConnected(workflow, node.name)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { INodeProperties } from 'n8n-workflow';
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
import { DEFAULT_EVALUATION_METRIC } from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CORRECTNESS_PROMPT,
|
CORRECTNESS_PROMPT,
|
||||||
@@ -386,7 +387,7 @@ export const setMetricsProperties: INodeProperties[] = [
|
|||||||
description: 'Define your own metric(s)',
|
description: 'Define your own metric(s)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: 'correctness',
|
default: DEFAULT_EVALUATION_METRIC,
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
operation: ['setMetrics'],
|
operation: ['setMetrics'],
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
setOutputs,
|
setOutputs,
|
||||||
setInputs,
|
setInputs,
|
||||||
} from '../utils/evaluationUtils';
|
} from '../utils/evaluationUtils';
|
||||||
|
import { metricRequiresModelConnection } from 'n8n-workflow'; // See packages/workflow/src/evaluation-helpers.ts
|
||||||
|
|
||||||
export class Evaluation implements INodeType {
|
export class Evaluation implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
@@ -37,7 +38,8 @@ export class Evaluation implements INodeType {
|
|||||||
name: 'Evaluation',
|
name: 'Evaluation',
|
||||||
color: '#c3c9d5',
|
color: '#c3c9d5',
|
||||||
},
|
},
|
||||||
inputs: `={{(${getInputConnectionTypes})($parameter)}}`,
|
// Pass function explicitly since expression context doesn't allow imports in getInputConnectionTypes
|
||||||
|
inputs: `={{(${getInputConnectionTypes})($parameter, ${metricRequiresModelConnection})}}`,
|
||||||
outputs: `={{(${getOutputConnectionTypes})($parameter)}}`,
|
outputs: `={{(${getOutputConnectionTypes})($parameter)}}`,
|
||||||
codex: {
|
codex: {
|
||||||
alias: ['Test', 'Metrics', 'Evals', 'Set Output', 'Set Metrics'],
|
alias: ['Test', 'Metrics', 'Evals', 'Set Output', 'Set Metrics'],
|
||||||
|
|||||||
@@ -240,10 +240,13 @@ export function getOutputConnectionTypes(parameters: INodeParameters) {
|
|||||||
return [{ type: 'main' }];
|
return [{ type: 'main' }];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInputConnectionTypes(parameters: INodeParameters) {
|
export function getInputConnectionTypes(
|
||||||
|
parameters: INodeParameters,
|
||||||
|
metricRequiresModelConnectionFn: (metric: string) => boolean,
|
||||||
|
) {
|
||||||
if (
|
if (
|
||||||
parameters.operation === 'setMetrics' &&
|
parameters.operation === 'setMetrics' &&
|
||||||
['correctness', 'helpfulness'].includes(parameters.metric as string)
|
metricRequiresModelConnectionFn(parameters.metric as string)
|
||||||
) {
|
) {
|
||||||
return [
|
return [
|
||||||
{ type: 'main' },
|
{ type: 'main' },
|
||||||
|
|||||||
25
packages/workflow/src/evaluation-helpers.ts
Normal file
25
packages/workflow/src/evaluation-helpers.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Evaluation-related utility functions
|
||||||
|
*
|
||||||
|
* This file contains utilities that need to be shared between different packages
|
||||||
|
* to avoid circular dependencies. For example, the evaluation test-runner (in CLI package)
|
||||||
|
* and the Evaluation node (in nodes-base package) both need to know which metrics
|
||||||
|
* require AI model connections, but they can't import from each other directly.
|
||||||
|
*
|
||||||
|
* By placing shared utilities here in the workflow package (which both packages depend on),
|
||||||
|
* we avoid circular dependency issues.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default metric type used in evaluations
|
||||||
|
*/
|
||||||
|
export const DEFAULT_EVALUATION_METRIC = 'correctness';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a given evaluation metric requires an AI model connection
|
||||||
|
* @param metric The metric name to check
|
||||||
|
* @returns true if the metric requires an AI model connection
|
||||||
|
*/
|
||||||
|
export function metricRequiresModelConnection(metric: string): boolean {
|
||||||
|
return ['correctness', 'helpfulness'].includes(metric);
|
||||||
|
}
|
||||||
@@ -67,6 +67,7 @@ export { ExpressionExtensions } from './extensions';
|
|||||||
export * as ExpressionParser from './extensions/expression-parser';
|
export * as ExpressionParser from './extensions/expression-parser';
|
||||||
export { NativeMethods } from './native-methods';
|
export { NativeMethods } from './native-methods';
|
||||||
export * from './node-parameters/filter-parameter';
|
export * from './node-parameters/filter-parameter';
|
||||||
|
export * from './evaluation-helpers';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
DocMetadata,
|
DocMetadata,
|
||||||
|
|||||||
Reference in New Issue
Block a user