// @ts-nocheck export function createAssistantTransitionPolicy(deps) { function parseDmyDateToIso(value) { const match = String(value ?? "").trim().match(/^(\d{2})\.(\d{2})\.(\d{4})$/); if (!match) { return null; } return `${match[3]}-${match[2]}-${match[1]}`; } function computeMonthWindowFromIso(isoDate) { const match = String(isoDate ?? "").match(/^(\d{4})-(\d{2})-(\d{2})$/); if (!match) { return null; } const year = Number(match[1]); const month = Number(match[2]); if (!Number.isFinite(year) || !Number.isFinite(month) || month < 1 || month > 12) { return null; } const lastDay = new Date(Date.UTC(year, month, 0)).getUTCDate(); const mm = String(month).padStart(2, "0"); const dd = String(lastDay).padStart(2, "0"); return { purchase_date: isoDate, period_from: `${year}-${mm}-01`, period_to: `${year}-${mm}-${dd}`, as_of_date: `${year}-${mm}-${dd}` }; } function extractEarliestDmyDateFromEntityRefs(entityRefs) { const dates = []; for (const entityRef of Array.isArray(entityRefs) ? entityRefs : []) { const value = deps.toNonEmptyString(entityRef?.value); if (!value) { continue; } const matches = String(value).match(/\b(\d{2}\.\d{2}\.\d{4})\b/g); if (!matches) { continue; } for (const token of matches) { const isoDate = parseDmyDateToIso(token); if (isoDate) { dates.push(isoDate); } } } if (dates.length === 0) { return null; } return dates.sort()[0] ?? null; } function extractPurchaseDateBridgeWindow(previousAddressItem, addressNavigationState) { const replyText = deps.toNonEmptyString(previousAddressItem?.text); if (replyText) { const repairedText = deps.repairAddressMojibake(replyText); const explicitFirstDateMatch = repairedText.match(/первая\s+найденная\s+дата\s+закупки:\s*(\d{2}\.\d{2}\.\d{4})/iu); const explicitFirstDateIso = explicitFirstDateMatch ? parseDmyDateToIso(explicitFirstDateMatch[1]) : null; if (explicitFirstDateIso) { return computeMonthWindowFromIso(explicitFirstDateIso); } } const sessionContext = addressNavigationState && typeof addressNavigationState === "object" && addressNavigationState.session_context && typeof addressNavigationState.session_context === "object" ? addressNavigationState.session_context : null; const focusObject = sessionContext && typeof sessionContext.active_focus_object === "object" ? sessionContext.active_focus_object : null; const preferredResultSetId = deps.toNonEmptyString(focusObject?.provenance_result_set_id) ?? deps.toNonEmptyString(sessionContext?.active_result_set_id); const resultSets = Array.isArray(addressNavigationState?.result_sets) ? addressNavigationState.result_sets : []; const preferredResultSet = (preferredResultSetId ? resultSets.find((item) => deps.toNonEmptyString(item?.result_set_id) === preferredResultSetId) ?? null : null) ?? resultSets.find((item) => deps.toNonEmptyString(item?.intent) === "inventory_purchase_provenance_for_item") ?? null; const earliestIsoDate = extractEarliestDmyDateFromEntityRefs(preferredResultSet?.entity_refs); return earliestIsoDate ? computeMonthWindowFromIso(earliestIsoDate) : null; } function hasInventoryPurchaseDateVatBridgeSignal(userMessage, alternateMessage, sourceIntentHint, hasInventoryItemFocusHint) { if ( sourceIntentHint !== "inventory_purchase_provenance_for_item" && !hasInventoryItemFocusHint && !deps.isInventorySelectedObjectIntent(sourceIntentHint) ) { return false; } const samples = [userMessage, alternateMessage] .map((item) => deps.compactWhitespace(deps.repairAddressMojibake(String(item ?? "")).toLowerCase())) .filter((item) => item.length > 0); if (samples.length === 0) { return false; } return samples.some( (sample) => /(?:ндс|vat)/iu.test(sample) && /(?:на\s+дат[ауеы]\s+покупк|на\s+дат[ауеы]\s+закупк|по\s+дат[еу]\s+покупк|по\s+дат[еу]\s+закупк|дата\s+покупк|дата\s+закупк|purchase\s+date)/iu.test( sample ) ); } function hasInventoryRootRestatementLikeSignal(userMessage, sourceIntentHint, hasInventoryRootFrame) { if (!hasInventoryRootFrame) { return false; } const normalized = deps .compactWhitespace(deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase()) .replace(/ё/g, "е"); if (!normalized) { return false; } if (deps.countTokens(normalized) > 10) { return false; } const hasInventoryLexeme = /(?:остат|склад|товар|номенклатур|позиц)/iu.test(normalized); const hasRestatementCue = /(?:еще\s+раз|снова|повтори|повтори\s+еще\s+раз|верни|покажи)/iu.test(normalized) && /(?:на\s+ту\s+же\s+дат[ауеы]|на\s+эту\s+же\s+дат[ауеы]|на\s+эту\s+дат[ауеы]|эту\s+дат[ауеы]|та\s+же\s+дата|тот\s+же\s+период|этот\s+же\s+период)/iu.test( normalized ); const hasBareSnapshotSameDateCue = hasInventoryLexeme && /(?:РЅР°\s+ту\s+Р¶Рµ\s+дат[ауеы]|РЅР°\s+эту\s+Р¶Рµ\s+дат[ауеы]|РЅР°\s+эту\s+дат[ауеы]|эту\s+дат[ауеы]|та\s+Р¶Рµ\s+дата|тот\s+Р¶Рµ\s+период|этот\s+Р¶Рµ\s+период)/iu.test( normalized ); const bareSnapshotSameDatePhrases = [ "\u043d\u0430 \u0442\u0443 \u0436\u0435 \u0434\u0430\u0442", "\u043d\u0430 \u044d\u0442\u0443 \u0436\u0435 \u0434\u0430\u0442", "\u043d\u0430 \u044d\u0442\u0443 \u0434\u0430\u0442", "\u044d\u0442\u0443 \u0434\u0430\u0442", "\u0442\u0430 \u0436\u0435 \u0434\u0430\u0442\u0430", "\u0442\u043e\u0442 \u0436\u0435 \u043f\u0435\u0440\u0438\u043e\u0434", "\u044d\u0442\u043e\u0442 \u0436\u0435 \u043f\u0435\u0440\u0438\u043e\u0434" ]; const hasBareSnapshotSameDatePhraseCue = hasInventoryLexeme && bareSnapshotSameDatePhrases.some((phrase) => normalized.includes(phrase)); return ( hasInventoryLexeme && (hasRestatementCue || hasBareSnapshotSameDateCue || hasBareSnapshotSameDatePhraseCue) && !deps.hasForeignAccountingPivotOverInventoryMessage(normalized) ); } function hasExplicitInventorySameDatePivotSignal(userMessage) { const normalized = deps .compactWhitespace(deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase()) .replace(/ё/g, "е"); if (!normalized) { return false; } const hasInventoryLexeme = /(?:остат|склад|товар|номенклатур|позиц)/iu.test(normalized); if (!hasInventoryLexeme) { return false; } const sameDatePhrases = [ "на ту же дат", "на эту же дат", "на эту дат", "эту дат", "та же дата", "тот же период", "этот же период" ]; return sameDatePhrases.some((phrase) => normalized.includes(phrase)); } function shouldKeepPreviousIntentForShortCounterpartyRetarget(userMessage, sourceIntent) { const normalized = deps.compactWhitespace( deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase() ); if (!normalized || deps.countTokens(normalized) > 4) { return false; } if (sourceIntent !== "list_documents_by_counterparty" && sourceIntent !== "list_documents_by_contract") { return false; } if ( /(?:банк|выписк|плат[её]Р¶|оплат|списан|поступлен|bank|payment|wire|statement)/iu.test( normalized ) ) { return false; } return /^(?:Р°|Рё|РЅСѓ)?\s*РїРѕ\s+[a-zР°-СЏС‘0-9._-]{2,}(?:\s+[a-zР°-СЏС‘0-9._-]{2,})?$/iu.test(normalized); } function shouldKeepPreviousIntentForShortCounterpartyRetargetV2(userMessage, sourceIntent) { const normalized = deps.compactWhitespace( deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase() ); if (!normalized || deps.countTokens(normalized) > 4) { return false; } if (sourceIntent !== "list_documents_by_counterparty" && sourceIntent !== "list_documents_by_contract") { return false; } if (/(?:bank|payment|wire|statement)/iu.test(normalized)) { return false; } return /^(?:а|и|ну)?\s*(?:покажи\s+)?по\s+[a-zа-яё0-9._-]{2,}(?:\s+[a-zа-яё0-9._-]{2,})?$/iu.test(normalized); } function inferStandaloneAddressTopicFamily(userMessage) { const normalized = deps.compactWhitespace( deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase() ); if (!normalized) { return null; } if (/(?:ндс|vat)/iu.test(normalized)) { return "vat"; } if (/(?:остат|склад|товар|номенклатур|позици)/iu.test(normalized)) { return "inventory"; } return null; } function resolveDisplayedEntityRetargetIntent(userMessage, entityType) { const normalized = deps.compactWhitespace( deps.repairAddressMojibake(String(userMessage ?? "")).toLowerCase() ); if (!normalized) { return null; } if (entityType === "counterparty") { if (/(?:договор|контракт)/iu.test(normalized)) { return "list_contracts_by_counterparty"; } if (/(?:банк|выписк|плат[её]ж|оплат|statement|payment|wire)/iu.test(normalized)) { return "bank_operations_by_counterparty"; } if (/(?:документ|накладн|счет|сч[её]т|акт|реализац|поступл)/iu.test(normalized)) { return "list_documents_by_counterparty"; } if (/(?:сколько\s+денег|сколько\s+принес|выручк|сумм[аы]?|оплатил|продаж)/iu.test(normalized)) { return "customer_revenue_and_payments"; } return null; } if (entityType === "contract") { if (/(?:банк|выписк|плат[её]ж|оплат|statement|payment|wire)/iu.test(normalized)) { return "bank_operations_by_contract"; } if (/(?:документ|накладн|счет|сч[её]т|акт|реализац|поступл)/iu.test(normalized)) { return "list_documents_by_contract"; } } return null; } function resolveAddressFollowupCarryoverContext( userMessage, items, alternateMessage = null, llmPreDecomposeMeta = null, addressNavigationState = null ) { const previousAddressItem = deps.findLastAddressAssistantItem(items); const previousAddressDebug = previousAddressItem?.debug ?? null; const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items); const organizationClarificationCandidates = Array.isArray(lastOrganizationClarificationDebug?.organization_candidates) ? deps.mergeKnownOrganizations(lastOrganizationClarificationDebug.organization_candidates) : []; const organizationClarificationSelection = deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ?? (deps.toNonEmptyString(alternateMessage) ? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates) : null); const hasOrganizationClarificationContinuation = Boolean( lastOrganizationClarificationDebug && organizationClarificationSelection ); const followupOffer = previousAddressDebug ? deps.buildAddressFollowupOffer(previousAddressDebug) : null; const hasImplicitContinuationSignal = Boolean(previousAddressDebug) && Boolean(followupOffer?.enabled) && (deps.isImplicitAddressContinuationByLlm(userMessage, llmPreDecomposeMeta) || (deps.toNonEmptyString(alternateMessage) ? deps.isImplicitAddressContinuationByLlm(alternateMessage, llmPreDecomposeMeta) : false)); const sourceIntentHint = deps.toNonEmptyString(previousAddressDebug?.detected_intent); const navigationFocusObjectHint = addressNavigationState && typeof addressNavigationState === "object" && addressNavigationState.session_context && typeof addressNavigationState.session_context === "object" && addressNavigationState.session_context.active_focus_object && typeof addressNavigationState.session_context.active_focus_object === "object" ? addressNavigationState.session_context.active_focus_object : null; const hasNavigationInventoryItemFocusHint = Boolean( deps.toNonEmptyString(navigationFocusObjectHint?.label) && deps.toNonEmptyString(navigationFocusObjectHint?.object_type) === "item" && (sourceIntentHint === "inventory_on_hand_as_of_date" || sourceIntentHint === "inventory_supplier_stock_overlap_as_of_date" || deps.isInventorySelectedObjectIntent(sourceIntentHint)) ); const inventoryPurchaseDateVatBridge = hasInventoryPurchaseDateVatBridgeSignal( userMessage, alternateMessage, sourceIntentHint, hasNavigationInventoryItemFocusHint ); let inventoryShortFollowupPrimary = (deps.isInventorySelectedObjectIntent(sourceIntentHint) || hasNavigationInventoryItemFocusHint) && deps.hasShortInventoryObjectFollowupSignal(userMessage); let inventoryShortFollowupAlternate = (deps.isInventorySelectedObjectIntent(sourceIntentHint) || hasNavigationInventoryItemFocusHint) && deps.toNonEmptyString(alternateMessage) ? deps.hasShortInventoryObjectFollowupSignal(String(alternateMessage ?? "")) : false; const debtRoleSwapPrimary = sourceIntentHint ? deps.resolveDebtRoleSwapFollowupIntent(userMessage, sourceIntentHint) : null; const debtRoleSwapAlternate = sourceIntentHint && deps.toNonEmptyString(alternateMessage) ? deps.resolveDebtRoleSwapFollowupIntent(String(alternateMessage ?? ""), sourceIntentHint) : null; const debtRoleSwapIntent = debtRoleSwapPrimary ?? debtRoleSwapAlternate ?? null; let hasPrimaryFollowupSignal = deps.hasAddressFollowupContextSignal(userMessage) || Boolean(debtRoleSwapPrimary) || inventoryShortFollowupPrimary || inventoryPurchaseDateVatBridge; let hasAlternateFollowupSignal = deps.toNonEmptyString(alternateMessage) ? deps.hasAddressFollowupContextSignal(alternateMessage) || Boolean(debtRoleSwapAlternate) || inventoryShortFollowupAlternate || inventoryPurchaseDateVatBridge : false; const hasPrimaryIndexReferenceSignal = deps.extractDisplayedEntityIndexMention(userMessage) !== null; const hasAlternateIndexReferenceSignal = deps.toNonEmptyString(alternateMessage) ? deps.extractDisplayedEntityIndexMention(String(alternateMessage ?? "")) !== null : false; const hasIndexReferenceSignal = hasPrimaryIndexReferenceSignal || hasAlternateIndexReferenceSignal; const recentInventoryRootFrame = deps.findRecentInventoryRootFrame(items); const hasInventoryRootTemporalFollowupPrimary = deps.hasInventoryRootTemporalFollowupSignal( userMessage, sourceIntentHint, Boolean(recentInventoryRootFrame) ); const hasInventoryRootTemporalFollowupAlternate = deps.toNonEmptyString(alternateMessage) ? deps.hasInventoryRootTemporalFollowupSignal( String(alternateMessage ?? ""), sourceIntentHint, Boolean(recentInventoryRootFrame) ) : false; const hasInventoryRootRestatementPrimary = hasInventoryRootRestatementLikeSignal( userMessage, sourceIntentHint, Boolean(recentInventoryRootFrame) ); const hasInventoryRootRestatementAlternate = deps.toNonEmptyString(alternateMessage) ? hasInventoryRootRestatementLikeSignal( String(alternateMessage ?? ""), sourceIntentHint, Boolean(recentInventoryRootFrame) ) : false; const hasExplicitInventorySameDatePivotPrimary = hasExplicitInventorySameDatePivotSignal(userMessage); const hasExplicitInventorySameDatePivotAlternate = deps.toNonEmptyString(alternateMessage) ? hasExplicitInventorySameDatePivotSignal(String(alternateMessage ?? "")) : false; let hasStrongFollowupReference = hasPrimaryIndexReferenceSignal || hasAlternateIndexReferenceSignal || hasOrganizationClarificationContinuation || hasImplicitContinuationSignal || inventoryShortFollowupPrimary || inventoryShortFollowupAlternate || hasInventoryRootTemporalFollowupPrimary || hasInventoryRootTemporalFollowupAlternate || hasInventoryRootRestatementPrimary || hasInventoryRootRestatementAlternate || inventoryPurchaseDateVatBridge || Boolean(debtRoleSwapIntent) || deps.hasFollowupMarker(userMessage) || deps.hasReferentialPointer(userMessage) || (deps.toNonEmptyString(alternateMessage) ? deps.hasFollowupMarker(String(alternateMessage ?? "")) || deps.hasReferentialPointer(String(alternateMessage ?? "")) : false); const hasStandaloneAddressTopic = deps.hasStandaloneAddressTopicSignal(userMessage) || (deps.toNonEmptyString(alternateMessage) ? deps.hasStandaloneAddressTopicSignal(alternateMessage) : false); if ( hasStandaloneAddressTopic && !hasPrimaryFollowupSignal && !hasAlternateFollowupSignal && !hasInventoryRootTemporalFollowupPrimary && !hasInventoryRootTemporalFollowupAlternate && !hasInventoryRootRestatementPrimary && !hasInventoryRootRestatementAlternate && !hasImplicitContinuationSignal && !hasOrganizationClarificationContinuation && !hasIndexReferenceSignal ) { return null; } if ( !hasPrimaryFollowupSignal && !hasAlternateFollowupSignal && !hasInventoryRootTemporalFollowupPrimary && !hasInventoryRootTemporalFollowupAlternate && !hasInventoryRootRestatementPrimary && !hasInventoryRootRestatementAlternate && !hasImplicitContinuationSignal && !hasOrganizationClarificationContinuation && !hasIndexReferenceSignal ) { return null; } if (!previousAddressDebug) { return null; } const sourceIntent = deps.toNonEmptyString(previousAddressDebug.detected_intent); const llmExplicitIntent = deps.toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent); const resolvedPrimaryIntent = deps.resolveAddressIntent(deps.repairAddressMojibake(String(userMessage ?? ""))).intent; const resolvedAlternateIntent = deps.toNonEmptyString(alternateMessage) ? deps.resolveAddressIntent(deps.repairAddressMojibake(String(alternateMessage ?? ""))).intent : null; const explicitIntent = llmExplicitIntent && llmExplicitIntent !== "unknown" ? llmExplicitIntent : resolvedPrimaryIntent && resolvedPrimaryIntent !== "unknown" ? resolvedPrimaryIntent : resolvedAlternateIntent && resolvedAlternateIntent !== "unknown" ? resolvedAlternateIntent : null; const sourceIntentFamily = deps.resolveAddressIntentFamily(sourceIntent); const explicitIntentFamily = deps.resolveAddressIntentFamily(explicitIntent) ?? inferStandaloneAddressTopicFamily(userMessage) ?? (deps.toNonEmptyString(alternateMessage) ? inferStandaloneAddressTopicFamily(String(alternateMessage ?? "")) : null); const foreignAccountingPivotOverInventory = deps.hasForeignAccountingPivotOverInventoryMessage( userMessage, alternateMessage ); const familyMismatchStandaloneTopic = Boolean( hasStandaloneAddressTopic && sourceIntentFamily && explicitIntentFamily && sourceIntentFamily !== explicitIntentFamily && !hasOrganizationClarificationContinuation && !hasImplicitContinuationSignal && !hasIndexReferenceSignal && !hasInventoryRootTemporalFollowupPrimary && !hasInventoryRootTemporalFollowupAlternate && !hasInventoryRootRestatementPrimary && !hasInventoryRootRestatementAlternate && !inventoryShortFollowupPrimary && !inventoryShortFollowupAlternate && !foreignAccountingPivotOverInventory && !deps.hasFollowupMarker(userMessage) && !deps.hasReferentialPointer(userMessage) && (!deps.toNonEmptyString(alternateMessage) ? true : !deps.hasFollowupMarker(String(alternateMessage ?? "")) && !deps.hasReferentialPointer(String(alternateMessage ?? ""))) ); if (familyMismatchStandaloneTopic) { return null; } if ( sourceIntentFamily && explicitIntentFamily && sourceIntentFamily !== explicitIntentFamily && !hasStrongFollowupReference && !foreignAccountingPivotOverInventory ) { return null; } let previousIntent = sourceIntent; let followupSelectionMode = "carry_previous_intent"; if (debtRoleSwapIntent) { previousIntent = debtRoleSwapIntent; } if (hasImplicitContinuationSignal) { const suggestedIntent = Array.isArray(followupOffer?.suggested_intents) ? deps.toNonEmptyString(followupOffer.suggested_intents[0]) : null; const keepPreviousIntent = shouldKeepPreviousIntentForShortCounterpartyRetargetV2(userMessage, sourceIntent); if (suggestedIntent && !keepPreviousIntent) { previousIntent = suggestedIntent; followupSelectionMode = "switch_to_suggested_intent"; } } let previousAnchorType = deps.toNonEmptyString(previousAddressDebug.anchor_type); let previousAnchor = deps.toNonEmptyString(previousAddressDebug.anchor_value_resolved) ?? deps.toNonEmptyString(previousAddressDebug.anchor_value_raw) ?? deps.readAddressFilterString(previousAddressDebug, "item") ?? deps.readAddressFilterString(previousAddressDebug, "counterparty") ?? deps.readAddressFilterString(previousAddressDebug, "account") ?? deps.readAddressFilterString(previousAddressDebug, "contract"); const navigationSessionContext = addressNavigationState && typeof addressNavigationState === "object" ? addressNavigationState.session_context && typeof addressNavigationState.session_context === "object" ? addressNavigationState.session_context : null : null; const navigationDateScope = navigationSessionContext && typeof navigationSessionContext.date_scope === "object" ? navigationSessionContext.date_scope : null; const navigationOrganization = deps.normalizeOrganizationScopeValue(navigationSessionContext?.organization_scope); const navigationFocusObject = navigationSessionContext && typeof navigationSessionContext.active_focus_object === "object" ? navigationSessionContext.active_focus_object : null; const navigationFocusObjectType = deps.toNonEmptyString(navigationFocusObject?.object_type); const navigationFocusObjectLabel = deps.toNonEmptyString(navigationFocusObject?.label); const hasInventoryItemFocusCarryover = navigationFocusObjectType === "item" && navigationFocusObjectLabel && (sourceIntentHint === "inventory_on_hand_as_of_date" || sourceIntentHint === "inventory_supplier_stock_overlap_as_of_date" || deps.isInventorySelectedObjectIntent(sourceIntentHint)); if (!inventoryShortFollowupPrimary && hasInventoryItemFocusCarryover) { inventoryShortFollowupPrimary = deps.hasShortInventoryObjectFollowupSignal(userMessage); } if (!inventoryShortFollowupAlternate && hasInventoryItemFocusCarryover && deps.toNonEmptyString(alternateMessage)) { inventoryShortFollowupAlternate = deps.hasShortInventoryObjectFollowupSignal(String(alternateMessage ?? "")); } hasPrimaryFollowupSignal = deps.hasAddressFollowupContextSignal(userMessage) || Boolean(debtRoleSwapPrimary) || inventoryShortFollowupPrimary || inventoryPurchaseDateVatBridge || hasInventoryRootTemporalFollowupPrimary; hasAlternateFollowupSignal = deps.toNonEmptyString(alternateMessage) ? deps.hasAddressFollowupContextSignal(alternateMessage) || Boolean(debtRoleSwapAlternate) || inventoryShortFollowupAlternate || inventoryPurchaseDateVatBridge || hasInventoryRootTemporalFollowupAlternate : false; hasStrongFollowupReference = hasPrimaryIndexReferenceSignal || hasAlternateIndexReferenceSignal || hasOrganizationClarificationContinuation || hasImplicitContinuationSignal || inventoryShortFollowupPrimary || inventoryShortFollowupAlternate || hasInventoryRootTemporalFollowupPrimary || hasInventoryRootTemporalFollowupAlternate || inventoryPurchaseDateVatBridge || Boolean(debtRoleSwapIntent) || deps.hasFollowupMarker(userMessage) || deps.hasReferentialPointer(userMessage) || (deps.toNonEmptyString(alternateMessage) ? deps.hasFollowupMarker(String(alternateMessage ?? "")) || deps.hasReferentialPointer(String(alternateMessage ?? "")) : false); const hasSelectedObjectInventorySignalPrimary = /(?:РїРѕ\s+выбранному\s+объекту|РїРѕ\s+этой\s+позиции|РїРѕ\s+этому\s+товару|selected\s+object)/iu.test( String(userMessage ?? "") ); const hasSelectedObjectInventorySignalAlternate = deps.toNonEmptyString(alternateMessage) ? /(?:РїРѕ\s+выбранному\s+объекту|РїРѕ\s+этой\s+позиции|РїРѕ\s+этому\s+товару|selected\s+object)/iu.test( String(alternateMessage ?? "") ) : false; let inventoryRootFrame = deps.findRecentInventoryRootFrame(items); if (inventoryRootFrame && navigationOrganization && !deps.toNonEmptyString(inventoryRootFrame.filters?.organization)) { inventoryRootFrame = { ...inventoryRootFrame, filters: { ...(inventoryRootFrame.filters ?? {}), organization: navigationOrganization } }; } if (inventoryRootFrame && navigationDateScope) { inventoryRootFrame = { ...inventoryRootFrame, filters: { ...(inventoryRootFrame.filters ?? {}), as_of_date: deps.toNonEmptyString(inventoryRootFrame.filters?.as_of_date) ?? deps.toNonEmptyString(navigationDateScope.as_of_date) ?? undefined, period_from: deps.toNonEmptyString(inventoryRootFrame.filters?.period_from) ?? deps.toNonEmptyString(navigationDateScope.period_from) ?? undefined, period_to: deps.toNonEmptyString(inventoryRootFrame.filters?.period_to) ?? deps.toNonEmptyString(navigationDateScope.period_to) ?? undefined } }; } let currentFrameKind = inventoryRootFrame ? deps.isInventoryDrilldownFrameIntent(sourceIntent) ? "inventory_drilldown" : deps.isInventoryRootFrameIntent(sourceIntent) ? "inventory_root" : "generic" : null; let resolvedCounterpartyFromDisplay = false; let displayedEntityTargetIntent = null; const previousFiltersRaw = previousAddressDebug.extracted_filters; let previousFilters = previousFiltersRaw && typeof previousFiltersRaw === "object" ? { ...previousFiltersRaw } : {}; const shouldBackfillHistoricalPartyAnchors = sourceIntentHint === "list_contracts_by_counterparty" || sourceIntentHint === "list_documents_by_counterparty" || sourceIntentHint === "bank_operations_by_counterparty" || sourceIntentHint === "list_documents_by_contract" || sourceIntentHint === "bank_operations_by_contract" || sourceIntentHint === "open_items_by_counterparty_or_contract"; if (shouldBackfillHistoricalPartyAnchors && !deps.toNonEmptyString(previousFilters.contract)) { const historicalContract = deps.findRecentAddressFilterValue(items, "contract"); if (historicalContract) { previousFilters.contract = historicalContract; } } if (shouldBackfillHistoricalPartyAnchors && !deps.toNonEmptyString(previousFilters.counterparty)) { const historicalCounterparty = deps.findRecentAddressFilterValue(items, "counterparty"); if (historicalCounterparty) { previousFilters.counterparty = historicalCounterparty; } } if (!deps.toNonEmptyString(previousFilters.organization)) { const historicalOrganization = deps.findRecentAddressFilterValue(items, "organization"); if (historicalOrganization) { previousFilters.organization = historicalOrganization; } } if (!deps.toNonEmptyString(previousFilters.organization) && navigationOrganization) { previousFilters.organization = navigationOrganization; } if (!deps.toNonEmptyString(previousFilters.organization) && organizationClarificationSelection) { previousFilters.organization = organizationClarificationSelection; } if (inventoryPurchaseDateVatBridge) { const purchaseBridgeWindow = extractPurchaseDateBridgeWindow(previousAddressItem, addressNavigationState); if (purchaseBridgeWindow) { previousFilters.period_from = purchaseBridgeWindow.period_from; previousFilters.period_to = purchaseBridgeWindow.period_to; } } const shouldBackfillPreviousDateScopeFromNavigation = sourceIntentHint === "inventory_on_hand_as_of_date" || sourceIntentHint === "inventory_supplier_stock_overlap_as_of_date" || sourceIntentHint === "inventory_purchase_provenance_for_item" || sourceIntentHint === "inventory_purchase_documents_for_item" || sourceIntentHint === "inventory_sale_trace_for_item" || sourceIntentHint === "inventory_profitability_for_item" || sourceIntentHint === "inventory_purchase_to_sale_chain" || sourceIntentHint === "inventory_aging_by_purchase_date" || sourceIntentHint === "account_balance_snapshot" || sourceIntentHint === "documents_forming_balance"; if ( shouldBackfillPreviousDateScopeFromNavigation && !deps.toNonEmptyString(previousFilters.as_of_date) && deps.toNonEmptyString(navigationDateScope?.as_of_date) ) { previousFilters.as_of_date = deps.toNonEmptyString(navigationDateScope?.as_of_date); } if ( shouldBackfillPreviousDateScopeFromNavigation && !deps.toNonEmptyString(previousFilters.period_from) && deps.toNonEmptyString(navigationDateScope?.period_from) ) { previousFilters.period_from = deps.toNonEmptyString(navigationDateScope?.period_from); } if ( shouldBackfillPreviousDateScopeFromNavigation && !deps.toNonEmptyString(previousFilters.period_to) && deps.toNonEmptyString(navigationDateScope?.period_to) ) { previousFilters.period_to = deps.toNonEmptyString(navigationDateScope?.period_to); } const rootContextOnlyPivot = Boolean( (deps.isInventorySelectedObjectIntent(sourceIntentHint) || currentFrameKind === "inventory_drilldown") && deps.hasForeignAccountingPivotOverInventoryMessage(userMessage, alternateMessage) && !inventoryPurchaseDateVatBridge ); const inventoryRootTemporalPivot = Boolean( inventoryRootFrame && (deps.isInventorySelectedObjectIntent(sourceIntentHint) || deps.isInventoryRootFrameIntent(sourceIntentHint) || currentFrameKind === "inventory_drilldown" || currentFrameKind === "inventory_root") && (hasInventoryRootTemporalFollowupPrimary || hasInventoryRootTemporalFollowupAlternate) && !deps.hasForeignAccountingPivotOverInventoryMessage(userMessage, alternateMessage) ); const inventoryRootRestatementPivot = Boolean( inventoryRootFrame && (deps.isInventorySelectedObjectIntent(sourceIntentHint) || deps.isInventoryRootFrameIntent(sourceIntentHint) || currentFrameKind === "inventory_drilldown" || currentFrameKind === "inventory_root" || currentFrameKind === "generic") && (hasInventoryRootRestatementPrimary || hasInventoryRootRestatementAlternate) && !deps.hasForeignAccountingPivotOverInventoryMessage(userMessage, alternateMessage) ); const explicitInventorySameDatePivot = Boolean( !inventoryRootFrame && (hasExplicitInventorySameDatePivotPrimary || hasExplicitInventorySameDatePivotAlternate) && !deps.hasForeignAccountingPivotOverInventoryMessage(userMessage, alternateMessage) ); const rootScopedPivot = rootContextOnlyPivot || inventoryRootTemporalPivot || inventoryRootRestatementPivot; if (rootScopedPivot) { previousIntent = null; previousAnchorType = null; previousAnchor = null; previousFilters = deps.buildRootScopedCarryoverFilters(previousFilters, inventoryRootFrame); currentFrameKind = inventoryRootFrame ? "inventory_root" : currentFrameKind; followupSelectionMode = "carry_root_context"; } const displayedEntityType = deps.inferDisplayedEntityTypeFromIntent(sourceIntent); const displayedEntities = deps.extractDisplayedAddressEntityCandidates( deps.toNonEmptyString(previousAddressItem?.text) ?? "", displayedEntityType ); const resolvedEntityFromFollowup = deps.resolveDisplayedAddressEntityMention(userMessage, displayedEntities) ?? (deps.toNonEmptyString(alternateMessage) ? deps.resolveDisplayedAddressEntityMention(String(alternateMessage ?? ""), displayedEntities) : null); if (resolvedEntityFromFollowup && !rootScopedPivot) { displayedEntityTargetIntent = resolveDisplayedEntityRetargetIntent( userMessage, resolvedEntityFromFollowup.entityType ); if (resolvedEntityFromFollowup.entityType === "counterparty") { previousFilters.counterparty = resolvedEntityFromFollowup.value; previousAnchorType = "counterparty"; previousAnchor = resolvedEntityFromFollowup.value; resolvedCounterpartyFromDisplay = true; } else if (resolvedEntityFromFollowup.entityType === "contract") { previousFilters.contract = resolvedEntityFromFollowup.value; previousAnchorType = "contract"; previousAnchor = resolvedEntityFromFollowup.value; } else if (resolvedEntityFromFollowup.entityType === "item") { previousFilters.item = resolvedEntityFromFollowup.value; previousAnchorType = "item"; previousAnchor = resolvedEntityFromFollowup.value; } if (followupSelectionMode !== "switch_to_suggested_intent") { followupSelectionMode = "carry_referenced_entity"; } } if ( !rootScopedPivot && !deps.toNonEmptyString(previousFilters.item) && navigationFocusObjectType === "item" && navigationFocusObjectLabel && (sourceIntentHint === "inventory_on_hand_as_of_date" || sourceIntentHint === "inventory_purchase_provenance_for_item" || sourceIntentHint === "inventory_purchase_documents_for_item" || sourceIntentHint === "inventory_sale_trace_for_item" || sourceIntentHint === "inventory_profitability_for_item" || sourceIntentHint === "inventory_purchase_to_sale_chain" || sourceIntentHint === "inventory_aging_by_purchase_date" || hasSelectedObjectInventorySignalPrimary || hasSelectedObjectInventorySignalAlternate) ) { previousFilters.item = navigationFocusObjectLabel; if (!previousAnchor) { previousAnchorType = "item"; previousAnchor = navigationFocusObjectLabel; } } if (organizationClarificationSelection && !previousAnchor) { previousAnchorType = "organization"; previousAnchor = organizationClarificationSelection; } if ( inventoryRootFrame && organizationClarificationSelection && !deps.toNonEmptyString(inventoryRootFrame.filters?.organization) ) { inventoryRootFrame = { ...inventoryRootFrame, filters: { ...(inventoryRootFrame.filters ?? {}), organization: organizationClarificationSelection } }; } if (!previousIntent && !previousAnchor && Object.keys(previousFilters).length === 0) { return null; } const shouldAttachInventoryRootFrame = Boolean( inventoryRootFrame && (rootScopedPivot || deps.isInventoryRootFrameIntent(sourceIntentHint) || deps.isInventorySelectedObjectIntent(sourceIntentHint) || hasNavigationInventoryItemFocusHint || inventoryShortFollowupPrimary || inventoryShortFollowupAlternate || hasInventoryRootTemporalFollowupPrimary || hasInventoryRootTemporalFollowupAlternate || hasInventoryRootRestatementPrimary || hasInventoryRootRestatementAlternate || hasSelectedObjectInventorySignalPrimary || hasSelectedObjectInventorySignalAlternate) ); const carryoverTargetIntent = inventoryPurchaseDateVatBridge ? "vat_liability_confirmed_for_tax_period" : followupSelectionMode === "carry_root_context" ? inventoryRootFrame?.intent ?? displayedEntityTargetIntent ?? explicitIntent ?? previousIntent ?? undefined : explicitInventorySameDatePivot ? "inventory_on_hand_as_of_date" : displayedEntityTargetIntent ?? explicitIntent ?? previousIntent ?? undefined; return { followupContext: { previous_intent: previousIntent ?? undefined, target_intent: carryoverTargetIntent, previous_filters: previousFilters, previous_anchor_type: previousAnchorType ?? undefined, previous_anchor_value: previousAnchor, resolved_counterparty_from_display: resolvedCounterpartyFromDisplay || undefined, root_context_only: rootScopedPivot || undefined, root_intent: shouldAttachInventoryRootFrame ? inventoryRootFrame?.intent ?? undefined : undefined, root_filters: shouldAttachInventoryRootFrame ? inventoryRootFrame?.filters ?? undefined : undefined, root_anchor_type: shouldAttachInventoryRootFrame ? inventoryRootFrame?.anchorType ?? undefined : undefined, root_anchor_value: shouldAttachInventoryRootFrame ? inventoryRootFrame?.anchorValue ?? undefined : undefined, current_frame_kind: shouldAttachInventoryRootFrame ? currentFrameKind ?? undefined : undefined }, previousAddressIntent: previousIntent, previousAddressAnchor: previousAnchor, previousSourceIntent: sourceIntent, followupSelectionMode, hasImplicitContinuationSignal }; } function buildAddressDialogContinuationContractV2( userMessage, effectiveMessage, carryoverMeta, llmPreDecomposeMeta ) { const sourceMessage = String(userMessage ?? ""); const canonicalMessage = String(effectiveMessage ?? sourceMessage); const hasFollowupContext = Boolean(carryoverMeta?.followupContext); const previousIntent = deps.toNonEmptyString(carryoverMeta?.previousSourceIntent) ?? null; const selectionMode = deps.toNonEmptyString(carryoverMeta?.followupSelectionMode) ?? null; const rootContextOnly = selectionMode === "carry_root_context"; const carryoverTargetIntent = deps.toNonEmptyString(carryoverMeta?.followupContext?.target_intent) ?? null; const explicitIntentRaw = deps.toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent); const explicitIntent = explicitIntentRaw === "unknown" ? null : explicitIntentRaw; const rootIntent = deps.toNonEmptyString(carryoverMeta?.followupContext?.root_intent) ?? null; const targetIntent = selectionMode === "switch_to_suggested_intent" ? deps.toNonEmptyString(carryoverMeta?.previousAddressIntent) ?? null : rootContextOnly ? carryoverTargetIntent ?? rootIntent ?? explicitIntent ?? null : carryoverTargetIntent ?? explicitIntent ?? deps.toNonEmptyString(carryoverMeta?.previousAddressIntent) ?? null; const hasImplicitContinuationSignal = Boolean(carryoverMeta?.hasImplicitContinuationSignal); const rewrittenByPredecompose = deps.compactWhitespace(sourceMessage.toLowerCase()) !== deps.compactWhitespace(canonicalMessage.toLowerCase()); const hasExplicitIntent = Boolean(explicitIntent); const decision = !hasFollowupContext ? "new_topic" : selectionMode === "switch_to_suggested_intent" ? "switch_to_suggested" : "continue_previous"; const reasons = []; if (hasFollowupContext) { reasons.push("followup_context_detected"); } if (hasImplicitContinuationSignal) { reasons.push("implicit_continuation_by_llm"); } if (rewrittenByPredecompose) { reasons.push("effective_message_rewritten_by_predecompose"); } if (hasExplicitIntent) { reasons.push("llm_contract_intent_available"); } if (selectionMode === "carry_referenced_entity" && explicitIntent && previousIntent && explicitIntent !== previousIntent) { reasons.push("operation_intent_from_current_message"); } if (rootContextOnly) { reasons.push("root_context_only_carryover"); } return { schema_version: "address_dialog_continuation_contract_v2", source_message: sourceMessage, effective_message: canonicalMessage, decision, decision_reasons: reasons, followup_context_applied: hasFollowupContext, previous_intent: previousIntent, target_intent: targetIntent, intent_selection_mode: selectionMode, anchor_type: carryoverMeta?.followupContext?.previous_anchor_type ?? null, anchor_value: carryoverMeta?.followupContext?.previous_anchor_value ?? null, implicit_continuation_signal: hasImplicitContinuationSignal }; } return { resolveAddressFollowupCarryoverContext, buildAddressDialogContinuationContractV2 }; }