Spaces:
Sleeping
Sleeping
| // agentSSEInferer.test.ts — Regressione per sseActionInferer.ts | |
| // Protegge i 6 bug corretti in inferActionType e la copertura label italiane. | |
| // Runner: vitest run (configurato in package.json) | |
| import { describe, it, expect } from "vitest"; | |
| import { inferActionType, inferActionLabel, inferActionDetail } from "../sseActionInferer"; | |
| import type { SSEEvent } from "../agentSSETypes"; | |
| function ev(tool?: string, extra: Record<string, unknown> = {}): SSEEvent { | |
| return { event: "step_start", taskId: "test", ...(tool ? { tool } : {}), ...extra } as SSEEvent; | |
| } | |
| // ─── inferActionType ────────────────────────────────────────────────────────── | |
| describe("inferActionType — bug fix regressions", () => { | |
| // FIX-1/2: browser_* era catturato da n.includes("open") → file_open | |
| // browser_navigate/act/screenshot non avevano match → tool_call | |
| it("browser_open → search_web (era file_open)", () => { | |
| expect(inferActionType("browser_open", ev("browser_open"))).toBe("search_web"); | |
| }); | |
| it("browser_navigate → search_web (era tool_call)", () => { | |
| expect(inferActionType("browser_navigate", ev("browser_navigate"))).toBe("search_web"); | |
| }); | |
| it("browser_act → search_web (era tool_call)", () => { | |
| expect(inferActionType("browser_act", ev("browser_act"))).toBe("search_web"); | |
| }); | |
| it("browser_screenshot → search_web (era tool_call)", () => { | |
| expect(inferActionType("browser_screenshot", ev("browser_screenshot"))).toBe("search_web"); | |
| }); | |
| it("browser_close → search_web", () => { | |
| expect(inferActionType("browser_close", ev("browser_close"))).toBe("search_web"); | |
| }); | |
| // FIX-3: git_list_files catturato da n.includes("file") → file_open | |
| it("git_list_files → api_call (era file_open)", () => { | |
| expect(inferActionType("git_list_files", ev("git_list_files"))).toBe("api_call"); | |
| }); | |
| it("git_push → api_call (era tool_call)", () => { | |
| expect(inferActionType("git_push", ev("git_push"))).toBe("api_call"); | |
| }); | |
| it("git_sync_vfs → api_call (era tool_call)", () => { | |
| expect(inferActionType("git_sync_vfs", ev("git_sync_vfs"))).toBe("api_call"); | |
| }); | |
| it("diff_commits → api_call (era tool_call)", () => { | |
| expect(inferActionType("diff_commits", ev("diff_commits"))).toBe("api_call"); | |
| }); | |
| // FIX-4: deploy → tool_call | |
| it("deploy_trigger → api_call (era tool_call)", () => { | |
| expect(inferActionType("deploy_trigger", ev("deploy_trigger"))).toBe("api_call"); | |
| }); | |
| it("check_deploy → api_call (era tool_call)", () => { | |
| expect(inferActionType("check_deploy", ev("check_deploy"))).toBe("api_call"); | |
| }); | |
| // FIX-5: generate_* → tool_call | |
| it("generate_image → file_write (era tool_call)", () => { | |
| expect(inferActionType("generate_image", ev("generate_image"))).toBe("file_write"); | |
| }); | |
| it("generate_readme → file_write (era tool_call)", () => { | |
| expect(inferActionType("generate_readme", ev("generate_readme"))).toBe("file_write"); | |
| }); | |
| it("create_chart → file_write (era tool_call)", () => { | |
| expect(inferActionType("create_chart", ev("create_chart"))).toBe("file_write"); | |
| }); | |
| // FIX-6: analyze_image → plan (n.includes("analyz")) | |
| it("analyze_image → file_read (era plan)", () => { | |
| expect(inferActionType("analyze_image", ev("analyze_image"))).toBe("file_read"); | |
| }); | |
| // send_email | |
| it("send_email → api_call (era tool_call)", () => { | |
| expect(inferActionType("send_email", ev("send_email"))).toBe("api_call"); | |
| }); | |
| }); | |
| describe("inferActionType — pattern generici invariati", () => { | |
| it("web_search → search_web", () => expect(inferActionType("web_search", ev("web_search"))).toBe("search_web")); | |
| it("write_file → file_write", () => expect(inferActionType("write_file", ev("write_file"))).toBe("file_write")); | |
| it("read_file → file_read", () => expect(inferActionType("read_file", ev("read_file"))).toBe("file_read")); | |
| it("delete_file → file_delete", () => expect(inferActionType("delete_file", ev("delete_file"))).toBe("file_delete")); | |
| it("run_python → code_run", () => expect(inferActionType("run_python", ev("run_python"))).toBe("code_run")); | |
| it("execute_shell → code_run", () => expect(inferActionType("execute_shell", ev("execute_shell"))).toBe("code_run")); | |
| it("run_tests → code_run", () => expect(inferActionType("run_tests", ev("run_tests"))).toBe("code_run")); | |
| it("planning → plan", () => expect(inferActionType("planning", ev("planning"))).toBe("plan")); | |
| it("goal_verifier → plan", () => expect(inferActionType("goal_verifier", ev("goal_verifier"))).toBe("plan")); | |
| it("execution_validator_fix → plan", () => expect(inferActionType("execution_validator_fix", ev("execution_validator_fix"))).toBe("plan")); | |
| it("validate_project → plan", () => expect(inferActionType("validate_project", ev("validate_project"))).toBe("plan")); | |
| it("__thinking__ → thinking", () => expect(inferActionType("__thinking__", ev("__thinking__"))).toBe("thinking")); | |
| it("remember → memory", () => expect(inferActionType("remember", ev("remember"))).toBe("memory")); | |
| it("calculate → tool_call", () => expect(inferActionType("calculate", ev("calculate"))).toBe("tool_call")); | |
| it("unknown_tool → tool_call", () => expect(inferActionType("unknown_tool", ev())).toBe("tool_call")); | |
| }); | |
| // ─── inferActionLabel ───────────────────────────────────────────────────────── | |
| describe("inferActionLabel — etichette italiane", () => { | |
| const EXPECTED: Array<[string, string]> = [ | |
| ["web_search", "Ricerca web"], | |
| ["run_python", "Script Python"], | |
| ["git_push", "Pubblica su Git"], | |
| ["send_email", "Email"], | |
| ["browser_navigate", "Naviga"], | |
| ["generate_image", "Genera immagine"], | |
| ["analyze_image", "Analisi immagine"], | |
| ["deploy_trigger", "Avvio deploy"], | |
| ["tool_governor_skip", "Cache hit"], | |
| ["__plan__", "Pianificazione"], | |
| ["__thinking__", "Analisi"], | |
| ["execution_validator_fix", "Fix automatico"], | |
| ["translate", "Traduzione"], | |
| ["text_to_speech", "Audio"], | |
| ["zip_project", "Comprimi progetto"], | |
| ]; | |
| EXPECTED.forEach(([tool, label]) => { | |
| it(`${tool} → "${label}"`, () => { | |
| expect(inferActionLabel(tool, ev(tool))).toBe(label); | |
| }); | |
| }); | |
| it("preferisce path sul label del tool", () => { | |
| expect(inferActionLabel("write_file", ev("write_file", { path: "/src/App.tsx" }))).toBe("App.tsx"); | |
| }); | |
| it("preferisce url/query sul label del tool", () => { | |
| expect(inferActionLabel("web_search", ev("web_search", { query: "react hooks" }))).toBe("react hooks"); | |
| }); | |
| it("humanizza tool sconosciuto (raw → Title case)", () => { | |
| expect(inferActionLabel("my_custom_tool", ev())).toBe("My custom tool"); | |
| }); | |
| it("rimuove underscore iniziali dai tool interni", () => { | |
| expect(inferActionLabel("__plan__", ev("__plan__"))).toBe("Pianificazione"); | |
| }); | |
| }); | |
| // ─── inferActionDetail ──────────────────────────────────────────────────────── | |
| describe("inferActionDetail", () => { | |
| it("ritorna path quando presente", () => expect(inferActionDetail(ev("write_file", { path: "/src/App.tsx" }))).toBe("/src/App.tsx")); | |
| it("ritorna url quando path assente", () => expect(inferActionDetail(ev("web_search", { url: "https://example.com" }))).toBe("https://example.com")); | |
| it("preferisce path su url", () => expect(inferActionDetail(ev("write_file", { path: "/a.ts", url: "https://x.com" }))).toBe("/a.ts")); | |
| it("ritorna undefined senza path/url", () => expect(inferActionDetail(ev("planning"))).toBeUndefined()); | |
| it("supporta campo file come path", () => expect(inferActionDetail(ev("read_file", { file: "/src/index.ts" }))).toBe("/src/index.ts")); | |
| }); | |