#!/usr/bin/env node /** * Accuracy runner — прогоняет 20 промптов через classifier (без LLM, regex only) * и выдаёт отчёт «правильно/неправильно» по каждому пункту. * * Использовать перед регистрацией router-prehook в settings.json. */ import { readFileSync } from 'fs'; import { classifyByRegex } from './router-classifier-regex-fallback.mjs'; import { loadRegistry } from './registry-load.mjs'; function main() { const promptsFile = process.argv[2] || 'tools/router-test-prompts.json'; const data = JSON.parse(readFileSync(promptsFile, 'utf-8')); const registry = loadRegistry({ useCache: false }); let correctType = 0, correctNode = 0, correctMicro = 0, total = data.prompts.length; const failures = []; for (const p of data.prompts) { const r = classifyByRegex(p.text, registry); const typeOk = r.taskType === p.expectedType; const nodeOk = r.recommendedNode === p.expectedNode; const microOk = r.micro === p.expectedMicro; if (typeOk) correctType++; if (nodeOk) correctNode++; if (microOk) correctMicro++; if (!typeOk || !nodeOk || !microOk) { failures.push({ prompt: p.text, expected: { type: p.expectedType, node: p.expectedNode, micro: p.expectedMicro }, actual: { type: r.taskType, node: r.recommendedNode, micro: r.micro }, deltas: { type: !typeOk, node: !nodeOk, micro: !microOk }, }); } } console.log('=== Accuracy Report ==='); console.log(`Type accuracy: ${correctType}/${total} = ${(correctType / total * 100).toFixed(1)}%`); console.log(`Node accuracy: ${correctNode}/${total} = ${(correctNode / total * 100).toFixed(1)}%`); console.log(`Micro accuracy: ${correctMicro}/${total} = ${(correctMicro / total * 100).toFixed(1)}%`); console.log(''); console.log(`Failures (${failures.length}):`); for (const f of failures) { console.log(` «${f.prompt}»`); console.log(` expected: type=${f.expected.type}, node=${f.expected.node}, micro=${f.expected.micro}`); console.log(` actual: type=${f.actual.type}, node=${f.actual.node}, micro=${f.actual.micro}`); } const passOverall = (correctType + correctNode + correctMicro) / (total * 3); process.exit(passOverall >= 0.75 ? 0 : 1); } main();