import { describe, expect, it } from "vitest"; import { resolveCounterpartyAddressIntent } from "../src/services/addressCounterpartyIntentSignals"; import { resolveAddressIntent } from "../src/services/addressIntentResolver"; const utf8Deps = { hasAny: (text: string, hints: readonly string[]) => hints.some((hint) => text.includes(hint)), openItemsHints: ["хвост", "долг", "open items"], openContractsHints: ["договор", "контракт", "open contracts"], documentsByCounterpartyHints: ["документы по", "documents by counterparty"], bankOperationsByCounterpartyHints: ["банк", "выписка", "bank operations by counterparty"], documentsByContractHints: ["документы по договору", "documents by contract"], hasCounterpartyDebtLongevitySignal: () => false, hasInventoryAgingSignal: () => false, hasInventoryProvenanceSignalV2: () => false, hasInventoryPurchaseDocumentsSignalV2: () => false, hasInventorySaleTraceSignalV2: () => false, hasAccountNumberAnchor: (text: string) => /(?:60|62|76)/.test(text), hasCompactAccountCodeToken: () => false, hasPeriodCoverageProfileSignal: () => false, hasPartyAnchorMention: () => false, hasContractAnchorSignal: (text: string) => text.includes("договор"), hasAccountBalanceSignal: () => false, hasDocumentTypeAndAccountSectionProfileSignal: () => false, hasCounterpartyPopulationAndRolesSignal: () => false, hasCounterpartyActivityLifecycleSignal: () => false, hasContractUsageOverviewSignal: () => false, hasOpenContractsListSignal: () => false, hasCustomerRevenueAndPaymentsSignal: () => false, hasSupplierPayoutsProfileSignal: () => false, hasContractUsageAndValueSignal: () => false, hasContractListByCounterpartySignal: () => false, hasBankOperationSignal: (text: string) => text.includes("банк"), hasDocumentSignal: (text: string) => text.includes("док"), hasLooseByAnchorMention: () => false, hasHeuristicCounterpartyAnchor: () => false, hasCounterpartyShipmentItemFlowSignal: (text: string) => text.includes("отгружал"), hasImplicitCounterpartyAnchorAroundDocs: () => false, hasGenericAddressLookupSignal: (text: string) => text.includes("покажи") }; describe("address counterparty utf8 regression", () => { it("classifies direct documents-by-counterparty wording with a loose human anchor", () => { const result = resolveCounterpartyAddressIntent("покажи все документы по чепурнову", utf8Deps); expect(result?.intent).toBe("list_documents_by_counterparty"); expect(result?.reasons).toContain("documents_by_counterparty_signal_detected"); }); it("keeps the main resolver in the supported contour for direct documents-by-counterparty wording", () => { const result = resolveAddressIntent("покажи все документы по чепурнову"); expect(result.intent).toBe("list_documents_by_counterparty"); }); it("classifies direct company activity-age wording with a colloquial organization anchor", () => { const result = resolveCounterpartyAddressIntent( "а по Альтернативе Плюс сколько лет активности в базе 1С?", utf8Deps ); expect(result?.intent).toBe("counterparty_activity_lifecycle"); expect(result?.reasons).toContain("counterparty_activity_lifecycle_signal_detected"); }); it("keeps the main resolver in the supported contour for direct company activity-age wording", () => { const result = resolveAddressIntent("а по Альтернативе Плюс сколько лет активности в базе 1С?"); expect(result.intent).toBe("counterparty_activity_lifecycle"); }); });