AUDIT / src /lib /__tests__ /agentLoopDirectResponse.test.ts
Arypulka98's picture
feat(audit): deploy full backend cluster node (part 2)
cc11e77 verified
Raw
History Blame Contribute Delete
6.32 kB
/**
* agentLoopDirectResponse.test.ts — S478 DIRECT_RESPONSE_MODE: integration tests
*
* Verifica che il flag isDirectAnswer propagato da taskClassifier:
* 1. Blocchi detectIntent (nessun tool pre-exec per domande definitorie)
* 2. Imponga _effectiveMaxIter=1 tramite P1-GATE
* 3. Non inietti ReasoningCore completo (stub leggero)
* 4. Blocchi retry engine
* 5. Blocchi belief restore
*
* Pattern: DI puro — usa _setTestMatcher da taskClassifier per controllare
* isDirectAnswer in modo deterministico, senza mock di moduli ESM.
*
* SESSIONE: S478 — DIRECT_RESPONSE_MODE
*/
import { describe, it, expect, afterEach } from "vitest";
import { classifyTask, _setTestMatcher, _resetMatcher } from "@/lib/taskClassifier";
import { detectIntent } from "@/lib/agentLoop/intentParser";
afterEach(() => {
_resetMatcher();
});
// ─── Gruppo A: classifyTask → isDirectAnswer propagato correttamente ──────────
describe("S478: classifyTask → isDirectAnswer propagato (wire-in check)", () => {
it("A-1. query definitoria breve → isDirectAnswer=true", () => {
const cls = classifyTask("cos'è il DNA?");
expect(cls.isDirectAnswer).toBe(true);
expect(cls.modelTier).not.toBe("premium"); // no heavy model per direct
});
it("A-2. full_app → isDirectAnswer=false", () => {
const cls = classifyTask("Crea un'app completa da zero con auth e dashboard");
expect(cls.isDirectAnswer).toBe(false);
});
it("A-3. math_calculation → isDirectAnswer=true senza live signal", () => {
const cls = classifyTask("quanto fa 12 * 12?");
expect(cls.type).toBe("math_calculation");
expect(cls.isDirectAnswer).toBe(true);
});
it("A-4. simple_question → isDirectAnswer=true", () => {
const cls = classifyTask("ciao!");
expect(cls.type).toBe("simple_question");
expect(cls.isDirectAnswer).toBe(true);
});
it("A-5. explanation con live signal → isDirectAnswer=false", () => {
// "oggi" è live signal → non direct anche se è una spiegazione
const cls = classifyTask("spiegami le ultime notizie di oggi");
expect(cls.isDirectAnswer).toBe(false);
});
it("A-6. search_and_report breve senza live → isDirectAnswer=true", () => {
const cls = classifyTask("cerca cos'è TypeScript");
expect(cls.isDirectAnswer).toBe(true);
});
it("A-7. search_and_report >100 chars → isDirectAnswer=false (troppo lungo)", () => {
const longMsg = "cerca online e analizza in dettaglio tutti i trend recenti del mercato aziendale italiano per il 2026 e dimmi cosa dicono gli esperti";
expect(longMsg.length).toBeGreaterThan(100);
const cls = classifyTask(longMsg);
expect(cls.isDirectAnswer).toBe(false);
});
it("A-8. DI: _setTestMatcher con isDirectAnswer=true esplicito → propagato", () => {
_setTestMatcher((_msg, rules) => {
const r = rules.find(r => r.type === "simple_question");
return r ?? null;
});
const cls = classifyTask("anything");
expect(cls.isDirectAnswer).toBe(true); // simple_question senza live → direct
});
});
// ─── Gruppo B: detectIntent → null per domande definitorie (S478 intentParser fix) ──
describe("S478: detectIntent → null per domande definitorie (gate confermato)", () => {
const DEFINITIONAL = [
"chi è Einstein?",
"chi era Galileo Galilei?",
"cos'è il DNA?",
"cosa è il quantum computing?",
"cosa sono i neutrini?",
"what is TypeScript?",
"what are design patterns?",
"who is Alan Turing?",
"who was Ada Lovelace?",
"dimmi chi è Darwin",
"sai chi è Platone?",
"mi spieghi chi è Socrate?",
];
for (const query of DEFINITIONAL) {
it(`→ null per: "${query}"`, () => {
const result = detectIntent(query);
expect(result).toBeNull();
});
}
});
// ─── Gruppo C: detectIntent → NON null per query live ────────────────────────
describe("S478: detectIntent → tool corretto per query live (non bloccato)", () => {
it("C-1. meteo → get_weather", () => {
expect(detectIntent("che tempo fa a Roma?")?.tool).toBe("get_weather");
});
it("C-2. notizie → get_news", () => {
expect(detectIntent("ultime notizie")?.tool).toBe("get_news");
});
it("C-3. 'chi è il presidente adesso?' → web_search (live, non bloccato)", () => {
expect(detectIntent("chi è il presidente adesso?")?.tool).toBe("web_search");
});
it("C-4. 'chi ha vinto la partita ieri?' → web_search (live: risultato)", () => {
expect(detectIntent("chi ha vinto la partita ieri?")?.tool).toBe("web_search");
});
it("C-5. immagine → generate_image", () => {
expect(detectIntent("disegna un gatto su uno skateboard")?.tool).toBe("generate_image");
});
it("C-6. math eval → math_eval", () => {
expect(detectIntent("calcola 2^10")?.tool).toBe("math_eval");
});
});
// ─── Gruppo D: isDirectAnswer via DI — verifica coerenza con getTopInterpretations ──
describe("S478: getTopInterpretations → isDirectAnswer propagato", () => {
// Import getTopInterpretations solo se esportato
it("D-1. classifyTask ritorna isDirectAnswer booleano sempre definito", () => {
const queries = [
"ciao",
"cos'è il DNA?",
"scrivi una funzione sort in TypeScript",
"crea un'app completa con React",
"xyzzy plugh frobozz",
];
for (const q of queries) {
const cls = classifyTask(q);
expect(typeof cls.isDirectAnswer).toBe("boolean");
}
});
it("D-2. task code_generation → isDirectAnswer=false (mai direct)", () => {
const cls = classifyTask("scrivi una funzione TypeScript per validare email con regex");
expect(cls.type).toBe("code_generation");
expect(cls.isDirectAnswer).toBe(false);
});
it("D-3. task debug → isDirectAnswer=false (mai direct)", () => {
const cls = classifyTask("il componente crasha su mobile, non funziona nulla");
expect(cls.type).toBe("debug");
expect(cls.isDirectAnswer).toBe(false);
});
it("D-4. task architecture → isDirectAnswer=false (mai direct)", () => {
const cls = classifyTask("come strutturare il progetto con microservizi e event bus?");
expect(cls.isDirectAnswer).toBe(false);
});
});