import { afterEach, describe, expect, it, vi } from "vitest"; const { executeAddressMcpQueryMock } = vi.hoisted(() => ({ executeAddressMcpQueryMock: vi.fn() })); vi.mock("../src/services/addressMcpClient", async () => { const actual = await vi.importActual( "../src/services/addressMcpClient" ); return { ...actual, executeAddressMcpQuery: executeAddressMcpQueryMock }; it("clears company-name counterparty noise when a bare organization selection resumes inventory", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 1, matched_rows: 1, raw_rows: [ { Period: "2026-04-19T23:59:59Z", Registrator: "Остатки товаров на складах", AccountDt: "41.01", AccountKt: "00.00", Amount: 148261.67, Quantity: 22, SubcontoDt1: "Модуль прямоугольый 1400*110*750", Warehouse: "Основной склад", Organization: 'ООО "Альтернатива Плюс"' } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("АЛЬТЕРНАТИВА", { activeOrganization: 'ООО "Альтернатива Плюс"', knownOrganizations: ['ООО "Альтернатива Плюс"', "ООО Лайсвуд"], followupContext: { previous_intent: "inventory_on_hand_as_of_date", target_intent: "inventory_on_hand_as_of_date", previous_filters: { organization: 'ООО "Альтернатива Плюс"', as_of_date: "2026-04-19" }, previous_anchor_type: "organization", previous_anchor_value: 'ООО "Альтернатива Плюс"' } }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.debug.detected_intent).toBe("inventory_on_hand_as_of_date"); expect(result?.debug.extracted_filters?.organization).toBe('ООО "Альтернатива Плюс"'); expect(result?.debug.extracted_filters?.counterparty).toBeUndefined(); expect(result?.debug.reasons).toContain("counterparty_cleared_from_referential_organization_scope"); expect(String(result?.reply_text ?? "")).toContain("Модуль прямоугольый 1400*110*750"); }); }); import { AddressQueryService } from "../src/services/addressQueryService"; afterEach(() => { executeAddressMcpQueryMock.mockReset(); vi.restoreAllMocks(); }); describe("implicit organization stock scope", () => { it("uses llm semantic hints to ground informal organization wording without turning it into warehouse anchor", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 1, matched_rows: 1, raw_rows: [ { Period: "2026-04-15T23:59:59Z", Registrator: "Остатки товаров на складах", AccountDt: "41.01", AccountKt: "00.00", Amount: 148261.67, Quantity: 22, SubcontoDt1: "Модуль прямоугольый 1400*110*750", Warehouse: "Основной склад", Organization: 'ООО "Альтернатива Плюс"' } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("что на складе конторы альтернатива", { llmSemanticHints: { scope_target_kind: "organization", scope_target_text: "Альтернатива", date_scope_kind: "implicit_current", self_scope_detected: false, selected_object_scope_detected: false } }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.response_type).toBe("FACTUAL_LIST"); expect(result?.debug.detected_intent).toBe("inventory_on_hand_as_of_date"); expect(result?.debug.selected_recipe).toBe("address_inventory_on_hand_as_of_date_v1"); expect(result?.debug.mcp_call_status).toBe("matched_non_empty"); expect(result?.debug.extracted_filters?.organization).toBe("Альтернатива"); expect(result?.debug.extracted_filters?.warehouse).toBeUndefined(); expect(result?.debug.semantic_frame?.scope_kind).toBe("explicit_anchor"); expect(result?.debug.semantic_frame?.anchor_kind).toBe("organization"); expect(result?.debug.semantic_frame?.anchor_value).toBe("Альтернатива"); expect(result?.debug.as_of_date_basis).toBe("implicit_current_snapshot"); expect(String(result?.reply_text ?? "")).toContain("Модуль прямоугольый 1400*110*750"); }); it("re-grounds warehouse-like informal company wording to live organization candidate set", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 1, matched_rows: 1, raw_rows: [ { Period: "2026-04-15T23:59:59Z", Registrator: "Остатки товаров на складах", AccountDt: "41.01", AccountKt: "00.00", Amount: 833.33, Quantity: 1, SubcontoDt1: "Четки Пост (84*117)", Warehouse: "Основной склад", Organization: "ООО КОТ ССЫТ ВО ДВОРЕ" } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("что на складе конторы ссыт кот", { activeOrganization: "ООО КОТ ССЫТ ВО ДВОРЕ", knownOrganizations: ["ООО КОТ ССЫТ ВО ДВОРЕ", "ООО Альтернатива Плюс"] }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.debug.extracted_filters?.organization).toBe("ООО КОТ ССЫТ ВО ДВОРЕ"); expect(result?.debug.extracted_filters?.warehouse).toBeUndefined(); expect(result?.debug.anchor_type).toBe("organization"); expect(result?.debug.reasons).toContain("warehouse_anchor_regrounded_to_organization_scope"); expect(result?.debug.reasons).toContain("organization_scope_live_grounding_recovered_rows"); expect(String(result?.reply_text ?? "")).toContain("Четки Пост (84*117)"); }); it("handles slang stock-state wording as current inventory snapshot for grounded organization scope", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 1, matched_rows: 1, raw_rows: [ { Period: "2026-04-15T23:59:59Z", Registrator: "Остатки товаров на складах", AccountDt: "41.01", AccountKt: "00.00", Amount: 34490, Quantity: 1, SubcontoDt1: "Диван трехместный", Warehouse: "Основной склад", Organization: "ООО Альтернатива Плюс" } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("чекни плиз чо там на складе альтернативы происходит", { activeOrganization: "ООО Альтернатива Плюс", knownOrganizations: ["ООО Альтернатива Плюс", "ООО Лайсвуд"] }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.debug.detected_intent).toBe("inventory_on_hand_as_of_date"); expect(result?.debug.selected_recipe).toBe("address_inventory_on_hand_as_of_date_v1"); expect(result?.debug.extracted_filters?.organization).toBe("ООО Альтернатива Плюс"); expect(result?.debug.extracted_filters?.warehouse).toBeUndefined(); expect(result?.debug.as_of_date_basis).toBe("implicit_current_snapshot"); expect(String(result?.reply_text ?? "")).toContain("Диван трехместный"); }); it("handles short colloquial stock query as current inventory snapshot for grounded organization scope", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 1, matched_rows: 1, raw_rows: [ { Period: "2026-04-15T23:59:59Z", Registrator: "Остатки товаров на складах", AccountDt: "41.01", AccountKt: "00.00", Amount: 6490, Quantity: 1, SubcontoDt1: "Пуф арий", Warehouse: "Основной склад", Organization: "ООО Альтернатива Плюс" } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("че на складах альтернативы", { activeOrganization: "ООО Альтернатива Плюс", knownOrganizations: ["ООО Альтернатива Плюс", "ООО Лайсвуд"] }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.debug.detected_intent).toBe("inventory_on_hand_as_of_date"); expect(result?.debug.selected_recipe).toBe("address_inventory_on_hand_as_of_date_v1"); expect(result?.debug.extracted_filters?.organization).toBe("ООО Альтернатива Плюс"); expect(result?.debug.extracted_filters?.warehouse).toBeUndefined(); expect(result?.debug.anchor_type).toBe("organization"); expect(result?.debug.as_of_date_basis).toBe("implicit_current_snapshot"); expect(String(result?.reply_text ?? "")).toContain("Пуф арий"); }); });