Spaces:
Sleeping
Sleeping
| /** | |
| * 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); | |
| }); | |
| }); | |