first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
+97
@@ -0,0 +1,97 @@
|
||||
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import type { SimpleWorkflow } from '@/types/workflow';
|
||||
|
||||
import { evaluateWorkflowPairwise, type PairwiseEvaluationInput } from './judge-chain';
|
||||
import * as baseEvaluator from '../llm-judge/evaluators/base';
|
||||
|
||||
// Mock the base evaluator module
|
||||
jest.mock('../llm-judge/evaluators/base', () => ({
|
||||
createEvaluatorChain: jest.fn(),
|
||||
invokeEvaluatorChain: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('evaluateWorkflowPairwise', () => {
|
||||
const mockLlm = mock<BaseChatModel>();
|
||||
|
||||
const mockWorkflow: SimpleWorkflow = {
|
||||
nodes: [],
|
||||
connections: {},
|
||||
name: 'Test Workflow',
|
||||
};
|
||||
|
||||
const input: PairwiseEvaluationInput = {
|
||||
evalCriteria: {
|
||||
dos: 'Do this',
|
||||
donts: "Don't do that",
|
||||
},
|
||||
workflowJSON: mockWorkflow,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return structured result from invokeEvaluatorChain', async () => {
|
||||
const mockResult = {
|
||||
violations: [],
|
||||
passes: [
|
||||
{ rule: 'Do this', justification: 'Done' },
|
||||
{ rule: "Don't do that", justification: 'Not done' },
|
||||
],
|
||||
};
|
||||
|
||||
jest.mocked(baseEvaluator.invokeEvaluatorChain).mockResolvedValue(mockResult);
|
||||
|
||||
const result = await evaluateWorkflowPairwise(mockLlm, input);
|
||||
|
||||
expect(result).toEqual({
|
||||
...mockResult,
|
||||
primaryPass: true,
|
||||
diagnosticScore: 1,
|
||||
});
|
||||
expect(baseEvaluator.createEvaluatorChain).toHaveBeenCalledWith(
|
||||
mockLlm,
|
||||
expect.anything(), // schema
|
||||
expect.stringContaining('expert n8n workflow auditor'), // system prompt
|
||||
expect.stringContaining('<task_context>'), // human template
|
||||
);
|
||||
expect(baseEvaluator.invokeEvaluatorChain).toHaveBeenCalledWith(
|
||||
undefined, // The chain (undefined because createEvaluatorChain mock returns undefined)
|
||||
expect.objectContaining({
|
||||
userPrompt: expect.stringContaining('<do>'),
|
||||
generatedWorkflow: input.workflowJSON,
|
||||
}),
|
||||
undefined, // config parameter (not passed in this test)
|
||||
);
|
||||
});
|
||||
|
||||
it('should calculate diagnosticScore correctly with violations', async () => {
|
||||
const mockResult = {
|
||||
violations: [{ rule: "Don't do that", justification: 'Did it' }],
|
||||
passes: [{ rule: 'Do this', justification: 'Done' }],
|
||||
};
|
||||
|
||||
jest.mocked(baseEvaluator.invokeEvaluatorChain).mockResolvedValue(mockResult);
|
||||
|
||||
const result = await evaluateWorkflowPairwise(mockLlm, input);
|
||||
|
||||
expect(result.primaryPass).toBe(false);
|
||||
expect(result.diagnosticScore).toBe(0.5);
|
||||
});
|
||||
|
||||
it('should return diagnosticScore 0 when no rules evaluated', async () => {
|
||||
const mockResult = {
|
||||
violations: [],
|
||||
passes: [],
|
||||
};
|
||||
|
||||
jest.mocked(baseEvaluator.invokeEvaluatorChain).mockResolvedValue(mockResult);
|
||||
|
||||
const result = await evaluateWorkflowPairwise(mockLlm, input);
|
||||
|
||||
expect(result.primaryPass).toBe(true);
|
||||
expect(result.diagnosticScore).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user