АРЧ - Усилить root-frame возврат, memory recap и colloquial provenance follow-up

This commit is contained in:
2026-04-15 20:34:21 +03:00
parent f911f9893b
commit 8056bdfaf2
16 changed files with 2032 additions and 21 deletions
@@ -91,6 +91,12 @@ function hasSameDateHint(text: string): boolean {
);
}
function hasSamePeriodHint(text: string): boolean {
return /(?:на\s+тот\s+же\s+период|за\s+тот\s+же\s+период|тот\s+же\s+период(?:\s+рассмотрения)?|на\s+этот\s+же\s+период|за\s+этот\s+же\s+период|аналогичн\w+\s+текущ\w+\s+период\w+|same\s+period|same\s+range|same\s+window)/iu.test(
String(text ?? "")
);
}
function hasExplicitPeriodLiteral(text: string): boolean {
return /(?:^|[^\d*×xх])((?:19|20)\d{2}(?:[./-](?:0?[1-9]|1[0-2]))?)(?=$|[^\d*×xх])/iu.test(String(text ?? ""));
}
@@ -487,10 +493,19 @@ function shouldRestoreInventoryRootFrame(
const previousIntent = followupContext.previous_intent;
const comingFromInventoryDrilldown =
currentFrameKind === "inventory_drilldown" || isInventoryDrilldownFrameIntent(previousIntent);
if (!comingFromInventoryDrilldown) {
const normalized = String(userMessage ?? "");
const hasInventoryRootRestatementCue =
/(?:склад|остат(?:ок|ки)|позици(?:я|и|ю)|товар(?:ы|ов)?|номенклатур)/iu.test(normalized) &&
/(?:покажи|показать|выведи|раскрой|еще\s+раз|ещ[её]\s+раз|снова|опять|верни|вернись|повтори|тот\s+же|этот\s+же|same|again)/iu.test(
normalized
);
const canReenterInventoryRoot =
comingFromInventoryDrilldown ||
(currentFrameKind === "inventory_root" && hasSamePeriodHint(normalized)) ||
(currentFrameKind === "generic" && hasInventoryRootRestatementCue && hasSamePeriodHint(normalized));
if (!canReenterInventoryRoot) {
return false;
}
const normalized = String(userMessage ?? "");
if (
hasSelectedObjectInventorySignal(normalized) ||
hasInventorySupplierFollowupCue(normalized) ||
@@ -508,6 +523,7 @@ function shouldRestoreInventoryRootFrame(
const hasTemporalPatch =
hasExplicitPeriodWindow(extractedFilters) ||
Boolean(toNonEmptyString(extractedFilters.as_of_date)) ||
hasSamePeriodHint(normalized) ||
hasExplicitPeriodLiteral(normalized) ||
Boolean(resolveRelativeMonthPeriodFromInventoryRoot(normalized, followupContext));
return hasTemporalPatch;
@@ -651,6 +667,7 @@ function mergeFollowupFilters(
const relativeMonthFromInventoryRoot = resolveRelativeMonthPeriodFromInventoryRoot(userMessage, followupContext);
const allTimeRequested = hasAllTimeHint(userMessage);
const sameDateRequested = hasSameDateHint(userMessage);
const samePeriodRequested = hasSamePeriodHint(userMessage);
if (!toNonEmptyString(merged.organization) && previousOrganization) {
merged.organization = previousOrganization;
reasons.push("organization_from_followup_context");
@@ -821,6 +838,24 @@ function mergeFollowupFilters(
reasons.push("as_of_date_from_followup_context");
}
}
if (
samePeriodRequested &&
(intent === "inventory_on_hand_as_of_date" || intent === "inventory_supplier_stock_overlap_as_of_date")
) {
if (previousPeriodFrom && merged.period_from !== previousPeriodFrom) {
merged.period_from = previousPeriodFrom;
reasons.push("period_from_from_followup_context");
}
if (previousPeriodTo && merged.period_to !== previousPeriodTo) {
merged.period_to = previousPeriodTo;
reasons.push("period_to_from_followup_context");
}
const inheritedAsOfDate = previousAsOfDate ?? previousPeriodTo ?? previousPeriodFrom;
if (inheritedAsOfDate && merged.as_of_date !== inheritedAsOfDate) {
merged.as_of_date = inheritedAsOfDate;
reasons.push("as_of_date_from_followup_context");
}
}
if (
!sameDateRequested &&
(intent === "inventory_aging_by_purchase_date" || isInventoryLifecycleHistoryIntent(intent)) &&