/** * llmindex.io — worker unit tests (cost gate, judge protocol invariants) * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * License: Proprietary — © Simon-Pierre Boucher, all rights reserved */ import { describe, expect, it } from 'vitest'; import { DEGRADED_FAILURE_RATE, EST_TOKENS, estimateBatchCostUsd } from './eval-runner'; import { JudgeConfigError, eligibleJudges, loadJudgeConfig, parseVerdict, } from './judges/config'; describe('cost guardrails', () => { it('estimates batch cost from pricing and k samples', () => { const cost = estimateBatchCostUsd(200, 1, { promptPerM: 3, completionPerM: 15 }); expect(cost).toBeCloseTo( (200 * (EST_TOKENS.prompt * 3 + EST_TOKENS.completion * 15)) / 1_000_000, 8, ); const withK = estimateBatchCostUsd(200, 5, { promptPerM: 3, completionPerM: 15 }); expect(withK).toBeCloseTo(cost * 5, 8); }); it('degraded threshold matches §6 (2%)', () => { expect(DEGRADED_FAILURE_RATE).toBe(0.02); }); }); describe('judge config', () => { it('requires ≥2 judges across ≥2 providers', () => { expect(() => loadJudgeConfig({ JUDGE_MODELS: 'a/x' } as NodeJS.ProcessEnv)).toThrow( JudgeConfigError, ); expect(() => loadJudgeConfig({ JUDGE_MODELS: 'a/x,a/y' } as NodeJS.ProcessEnv)).toThrow( JudgeConfigError, ); const ok = loadJudgeConfig({ JUDGE_MODELS: 'a/x, b/y' } as NodeJS.ProcessEnv); expect(ok.slugs).toEqual(['a/x', 'b/y']); }); it('a model never judges its own duels', () => { const config = { slugs: ['a/x', 'b/y', 'c/z'] }; expect(eligibleJudges(config, 'a/x', 'q/r')).toEqual(['b/y', 'c/z']); expect(eligibleJudges(config, 'a/x', 'b/y')).toEqual(['c/z']); }); it('parses verdicts robustly', () => { expect(parseVerdict('VERDICT: 1')).toBe('1'); expect(parseVerdict('after thought…\nverdict: tie')).toBe('tie'); expect(parseVerdict('no verdict here')).toBeNull(); }); });