From d7d6be18ff0f2d9413e0d7e78efaaca1111cc5f0 Mon Sep 17 00:00:00 2001 From: dctouch Date: Fri, 24 Apr 2026 00:14:50 +0300 Subject: [PATCH] =?UTF-8?q?Post-F:=20=D0=B7=D0=B0=D1=89=D0=B8=D1=82=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20VAT=20follow-up=20=D0=BE=D1=82=20stale=20period?= =?UTF-8?q?=20carryover?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/address_runtime/decomposeStage.js | 11 +++++++++-- .../services/address_runtime/decomposeStage.ts | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/llm_normalizer/backend/dist/services/address_runtime/decomposeStage.js b/llm_normalizer/backend/dist/services/address_runtime/decomposeStage.js index 6a02e81..5c4a345 100644 --- a/llm_normalizer/backend/dist/services/address_runtime/decomposeStage.js +++ b/llm_normalizer/backend/dist/services/address_runtime/decomposeStage.js @@ -15,6 +15,7 @@ const addressQueryShapeClassifier_1 = require("../addressQueryShapeClassifier"); const addressIntentResolver_1 = require("../addressIntentResolver"); const addressFilterExtractor_1 = require("../addressFilterExtractor"); const inventoryLifecycleCueHelpers_1 = require("../inventoryLifecycleCueHelpers"); +const addressTextRepair_1 = require("../addressTextRepair"); const assistantOrganizationMatcher_1 = require("../assistantOrganizationMatcher"); const semanticHintOverlay_1 = require("./semanticHintOverlay"); function hasExplicitPeriodWindow(filters) { @@ -28,6 +29,11 @@ function toNonEmptyString(value) { const normalized = String(value).trim(); return normalized.length > 0 ? normalized : null; } +function textWithRepairedVariant(text) { + const source = String(text ?? ""); + const repaired = (0, addressTextRepair_1.repairAddressMojibakeText)(source); + return repaired && repaired !== source ? `${source} ${repaired}` : source; +} function hasAllTimeHint(text) { const normalized = String(text ?? ""); return /(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+весь\s+срок|за\s+всю\s+истори(?:ю|и)|за\s+любой\s+период|за\s+любой\s+срок|for\s+all\s+time|all\s+time|for\s+entire\s+period|entire\s+period|for\s+any\s+period|any\s+period|for\s+full\s+history|full\s+history)/iu.test(normalized); @@ -45,13 +51,13 @@ function hasExplicitPeriodLiteral(text) { return /(?:^|[^\d*×xх])((?:19|20)\d{2}(?:[./-](?:0?[1-9]|1[0-2]))?)(?=$|[^\d*×xх])/iu.test(String(text ?? "")); } function hasExplicitCurrentDateHint(text) { - return /(?:на\s+текущ(?:ую|ая|ий|ее|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодняшн(?:юю|ий|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодня|сегодня|на\s+текущ(?:ий|ую)\s+момент|today|as\s+of\s+today|current\s+date|as\s+of\s+current\s+date)/iu.test(String(text ?? "")); + return /(?:на\s+текущ(?:ую|ая|ий|ее|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодняшн(?:юю|ий|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодня|сегодня|на\s+текущ(?:ий|ую)\s+момент|today|as\s+of\s+today|current\s+date|as\s+of\s+current\s+date)/iu.test(textWithRepairedVariant(String(text ?? ""))); } function hasOpenItemsHint(text) { return /(?:open\s+items|unclosed\s+items|хвост|висят|незакрыт|не\s+закрыт|открыт|долг|задолж|позиц)/iu.test(String(text ?? "")); } function hasVatCue(text) { - return /(?:^|[\s,.;:!?()\-])(?:ндс|vat)(?=$|[\s,.;:!?()\-])/iu.test(String(text ?? "")); + return /(?:^|[\s,.;:!?()\-])(?:ндс[а-яё]*|vat)(?=$|[\s,.;:!?()\-])/iu.test(textWithRepairedVariant(String(text ?? ""))); } function hasVatForecastCue(text) { return /(?:прогноз|forecast|прикин|оцен|план)/iu.test(String(text ?? "")); @@ -1059,6 +1065,7 @@ function mergeFollowupFilters(current, intent, userMessage, followupContext) { previousHasPeriod && hasFollowupSignal && !hasExplicitPeriodInMessage && + !hasExplicitCurrentDateInMessage && !inventoryLifecycleHistoryIntent && !vatRelativeMonthFollowup && !shouldSuppressGenericPeriodCarryover) { diff --git a/llm_normalizer/backend/src/services/address_runtime/decomposeStage.ts b/llm_normalizer/backend/src/services/address_runtime/decomposeStage.ts index 198a1fc..f3085f0 100644 --- a/llm_normalizer/backend/src/services/address_runtime/decomposeStage.ts +++ b/llm_normalizer/backend/src/services/address_runtime/decomposeStage.ts @@ -1,4 +1,4 @@ -import type { +import type { AddressFilterSet, AddressIntent, AddressIntentResolution, @@ -21,6 +21,7 @@ import { hasInventorySaleCue, hasInventorySupplierCue } from "../inventoryLifecycleCueHelpers"; +import { repairAddressMojibakeText } from "../addressTextRepair"; import { normalizeOrganizationScopeSearchText, organizationsLikelySameEntity } from "../assistantOrganizationMatcher"; import { applyAddressLlmSemanticHintsToExtraction } from "./semanticHintOverlay"; import type { AddressLlmSemanticHints } from "../../types/addressQuery"; @@ -88,6 +89,12 @@ function toNonEmptyString(value: unknown): string | null { return normalized.length > 0 ? normalized : null; } +function textWithRepairedVariant(text: string): string { + const source = String(text ?? ""); + const repaired = repairAddressMojibakeText(source); + return repaired && repaired !== source ? `${source} ${repaired}` : source; +} + function hasAllTimeHint(text: string): boolean { const normalized = String(text ?? ""); return /(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+весь\s+срок|за\s+всю\s+истори(?:ю|и)|за\s+любой\s+период|за\s+любой\s+срок|for\s+all\s+time|all\s+time|for\s+entire\s+period|entire\s+period|for\s+any\s+period|any\s+period|for\s+full\s+history|full\s+history)/iu.test( @@ -117,7 +124,7 @@ function hasExplicitPeriodLiteral(text: string): boolean { function hasExplicitCurrentDateHint(text: string): boolean { return /(?:на\s+текущ(?:ую|ая|ий|ее|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодняшн(?:юю|ий|ей|ем|его)\s+дат(?:у|а|е|ой|ою)|на\s+сегодня|сегодня|на\s+текущ(?:ий|ую)\s+момент|today|as\s+of\s+today|current\s+date|as\s+of\s+current\s+date)/iu.test( - String(text ?? "") + textWithRepairedVariant(String(text ?? "")) ); } @@ -126,7 +133,9 @@ function hasOpenItemsHint(text: string): boolean { } function hasVatCue(text: string): boolean { - return /(?:^|[\s,.;:!?()\-])(?:ндс|vat)(?=$|[\s,.;:!?()\-])/iu.test(String(text ?? "")); + return /(?:^|[\s,.;:!?()\-])(?:ндс[а-яё]*|vat)(?=$|[\s,.;:!?()\-])/iu.test( + textWithRepairedVariant(String(text ?? "")) + ); } function hasVatForecastCue(text: string): boolean { @@ -1327,6 +1336,7 @@ function mergeFollowupFilters( previousHasPeriod && hasFollowupSignal && !hasExplicitPeriodInMessage && + !hasExplicitCurrentDateInMessage && !inventoryLifecycleHistoryIntent && !vatRelativeMonthFollowup && !shouldSuppressGenericPeriodCarryover