import { describe, expect, it, vi } from "vitest"; import { heuristicReceptionRoute, isReceptionConfigured, parseReceptionResponse, receptionEnabled, resolveReceptionChecker, runReceptionPlan, shouldSkipReception, } from "./reception.js"; describe("reception env", () => { it("defaults off", () => { expect(receptionEnabled({})).toBe(false); expect(isReceptionConfigured({})).toBe(false); expect(receptionEnabled({ RAKAZO_RECEPTION_ENABLED: "1" })).toBe(true); }); it("requires model and url when enabled", () => { expect( resolveReceptionChecker({ RAKAZO_RECEPTION_ENABLED: "1", RAKAZO_RECEPTION_MODEL: "qwen2.5-coder-3b", RAKAZO_RECEPTION_MODELS_URL: "http://127.0.0.1:1239/v1", }), ).toEqual({ model: "qwen2.5-coder-3b", baseUrl: "http://127.0.0.1:1239/v1", }); expect( resolveReceptionChecker({ RAKAZO_RECEPTION_ENABLED: "1", RAKAZO_RECEPTION_MODEL: "qwen2.5-coder-3b", }), ).toBeNull(); }); }); describe("shouldSkipReception", () => { it("skips attachments and empty text", () => { expect(shouldSkipReception({ hasAttachments: true, text: "Hey" })).toBe(true); expect(shouldSkipReception({ hasAttachments: false, text: " " })).toBe(true); expect(shouldSkipReception({ hasAttachments: false, text: "Hey" })).toBe(false); }); }); describe("heuristicReceptionRoute", () => { it("routes obvious greetings to chat", () => { expect(heuristicReceptionRoute("Hey")).toBe("chat"); expect(heuristicReceptionRoute("Hallo!")).toBe("chat"); }); it("routes clear work orders to work", () => { expect( heuristicReceptionRoute("Split executor.ts into modules and open a PR"), ).toBe("work"); expect(heuristicReceptionRoute("Refactor the login flow and add tests")).toBe("work"); }); it("returns null for ambiguous messages", () => { expect(heuristicReceptionRoute("Can you help with something?")).toBeNull(); }); }); describe("parseReceptionResponse", () => { it("parses chat, clarify, and work routes", () => { expect(parseReceptionResponse('{"route":"chat","reply":"Hello!"}')).toEqual({ route: "chat", reply: "Hello!", }); expect(parseReceptionResponse('{"route":"clarify","reply":"What should I change?"}')).toEqual({ route: "clarify", reply: "What should I change?", }); expect(parseReceptionResponse('{"route":"work"}')).toEqual({ route: "work" }); }); it("returns null for invalid payloads", () => { expect(parseReceptionResponse("not json")).toBeNull(); expect(parseReceptionResponse('{"route":"chat"}')).toBeNull(); }); }); describe("runReceptionPlan", () => { it("escalates clear work without calling the runtime", async () => { const runtime = { run: vi.fn() }; const plan = await runReceptionPlan( { runtime: runtime as never, checker: { model: "fast", baseUrl: "http://127.0.0.1:1239/v1" }, }, { botId: "bot-1", botName: "Coder", spaceId: "space-1", userId: "user-1", threadId: "thread-1", text: "Split executor.ts into modules and open a PR", hasAttachments: false, history: [], }, ); expect(plan).toEqual({ route: "work" }); expect(runtime.run).not.toHaveBeenCalled(); }); it("returns null when disabled inputs skip reception", async () => { const runtime = { run: vi.fn() }; await expect( runReceptionPlan( { runtime: runtime as never, checker: { model: "fast", baseUrl: "http://127.0.0.1:1239/v1" }, }, { botId: "bot-1", botName: "Coder", spaceId: "space-1", userId: "user-1", threadId: "thread-1", text: "Hey", hasAttachments: true, history: [], }, ), ).resolves.toBeNull(); expect(runtime.run).not.toHaveBeenCalled(); }); it("uses runtime for ambiguous messages", async () => { async function* run() { yield { type: "done", text: '{"route":"chat","reply":"Sure — hi!"}' } as const; } const runtime = { run: vi.fn(() => run()) }; const plan = await runReceptionPlan( { runtime: runtime as never, checker: { model: "fast", baseUrl: "http://127.0.0.1:1239/v1" }, }, { botId: "bot-1", botName: "Coder", spaceId: "space-1", userId: "user-1", threadId: "thread-1", text: "Can you help with something?", hasAttachments: false, history: [], }, ); expect(plan).toEqual({ route: "chat", reply: "Sure — hi!" }); expect(runtime.run).toHaveBeenCalledOnce(); }); });