"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAssistantTransitionPolicy = createAssistantTransitionPolicy; // @ts-nocheck const assistantContinuityPolicy_1 = require("./assistantContinuityPolicy"); function createAssistantTransitionPolicy(deps) { function normalizeFollowupText(value) { return deps.compactWhitespace(deps.repairAddressMojibake(String(value ?? "")).toLowerCase()).replace(/ё/g, "е"); } function hasSelectedObjectInventoryScopeSignal(text) { const normalized = normalizeFollowupText(text); if (!normalized) { return false; } return /(?:по\s+выбранному\s+объекту|по\s+выбранной\s+позиции|по\s+этой\s+позиции|по\s+этому\s+товару|selected\s+object)/iu.test(normalized); } function extractSelectedObjectLabel(text) { const repaired = deps.repairAddressMojibake(String(text ?? "")); const quotedMatch = repaired.match(/(?:по\s+выбранному\s+объекту|по\s+выбранной\s+позиции)\s*[:,-]?\s*[«"]([^"»]+?)["»]/iu); if (quotedMatch?.[1]) { return deps.toNonEmptyString(quotedMatch[1]); } return null; } function inferSelectedObjectInventoryFollowupIntent(userMessage, alternateMessage = null) { const samples = [userMessage, alternateMessage].map((item) => normalizeFollowupText(item)).filter(Boolean); if (samples.length === 0) { return null; } if (samples.some((sample) => /(?:где\s+(?:мы\s+)?взял|откуда\s+(?:мы\s+)?взял|у\s+кого\s+купил|кто\s+постав|поставщик|источник\s+поступл|от\s+кого\s+поступ)/iu.test(sample))) { return "inventory_purchase_provenance_for_item"; } if (samples.some((sample) => /(?:документ|накладн|счет|сч[её]т|акт|поступл|покажи\s+док|все\s+документ|все\s+операц)/iu.test(sample))) { return "inventory_purchase_documents_for_item"; } if (samples.some((sample) => /(?:кому\s+продал|кому\s+ушл|куда\s+продал|кто\s+купил|реализац|отгруз|продаж)/iu.test(sample))) { return "inventory_sale_trace_for_item"; } if (samples.some((sample) => /(?:рентабел|маржин|прибыл|наценк|выгод)/iu.test(sample))) { return "inventory_profitability_for_item"; } if (samples.some((sample) => /(?:цепочк|от\s+закупк.*до\s+продаж|от\s+покупк.*до\s+продаж)/iu.test(sample))) { return "inventory_purchase_to_sale_chain"; } return null; } 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 isUsableFollowupSourceDebug(debug) { if (!debug || typeof debug !== "object") { return false; } const executionLane = deps.toNonEmptyString(debug.execution_lane); const detectedIntent = deps.toNonEmptyString(debug.detected_intent); const selectedRecipe = deps.toNonEmptyString(debug.selected_recipe); const answerGroundingCheck = debug.answer_grounding_check && typeof debug.answer_grounding_check === "object" ? debug.answer_grounding_check : null; const groundingStatus = deps.toNonEmptyString(answerGroundingCheck?.status); if (groundingStatus === "grounded") { return true; } if (selectedRecipe) { return true; } return executionLane === "address_query" && Boolean(detectedIntent && detectedIntent !== "unknown"); } function findRecentUsableAddressAssistantItem(items) { for (let index = Array.isArray(items) ? items.length - 1 : -1; index >= 0; index -= 1) { const item = items[index]; if (!item || item.role !== "assistant" || !item.debug || typeof item.debug !== "object") { continue; } if (isUsableFollowupSourceDebug(item.debug)) { return item; } } return null; } function findRecentInventoryPurchaseProvenanceItem(items, itemHint = null) { const normalizedItemHint = deps.toNonEmptyString(itemHint); for (let index = Array.isArray(items) ? items.length - 1 : -1; index >= 0; index -= 1) { const item = items[index]; const debug = item?.debug; if (!item || item.role !== "assistant" || !debug || typeof debug !== "object") { continue; } if (deps.toNonEmptyString(debug.detected_intent) !== "inventory_purchase_provenance_for_item") { continue; } if (!normalizedItemHint) { return item; } const candidateItem = (0, assistantContinuityPolicy_1.readAddressDebugItem)(debug, deps.toNonEmptyString); if (candidateItem && candidateItem === normalizedItemHint) { return item; } } return 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 rawCapabilityMetaQuery = deps.shouldHandleAsAssistantCapabilityMetaQuery(userMessage) || (deps.toNonEmptyString(alternateMessage) ? deps.shouldHandleAsAssistantCapabilityMetaQuery(String(alternateMessage ?? "")) : false); const rawDataRetrievalSignal = deps.hasDataRetrievalRequestSignal(userMessage) || (deps.toNonEmptyString(alternateMessage) ? deps.hasDataRetrievalRequestSignal(String(alternateMessage ?? "")) : false); if (rawCapabilityMetaQuery && !rawDataRetrievalSignal) { return null; } const latestAddressItem = deps.findLastAddressAssistantItem(items); const previousAddressItem = (latestAddressItem && isUsableFollowupSourceDebug(latestAddressItem?.debug) ? latestAddressItem : findRecentUsableAddressAssistantItem(items)) ?? latestAddressItem; const previousAddressDebug = previousAddressItem?.debug ?? null; const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items); const organizationAuthority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({ sessionItems: items, lastOrganizationClarificationDebug, toNonEmptyString: deps.toNonEmptyString, normalizeOrganizationScopeValue: deps.normalizeOrganizationScopeValue, mergeKnownOrganizations: deps.mergeKnownOrganizations }); const continuitySnapshot = organizationAuthority.continuitySnapshot; const continuityTemporalScope = (0, assistantContinuityPolicy_1.readAddressDebugTemporalScope)(continuitySnapshot.lastGroundedAddressDebug, deps.toNonEmptyString); const organizationClarificationCandidates = Array.isArray(organizationAuthority.organizationClarificationCandidates) ? organizationAuthority.organizationClarificationCandidates : []; const explicitOrganizationClarificationSelection = deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ?? (deps.toNonEmptyString(alternateMessage) ? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates) : null); const organizationClarificationSelection = explicitOrganizationClarificationSelection ?? deps.normalizeOrganizationScopeValue(organizationAuthority.organizationClarificationSelectionFromScope); 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 llmSelectedObjectScopeDetected = llmPreDecomposeMeta?.predecomposeContract?.semantics?.selected_object_scope_detected === true; 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"; } } const previousAnchorContext = (0, assistantContinuityPolicy_1.resolveAddressDebugAnchorContext)(previousAddressDebug, deps.toNonEmptyString); let previousAnchorType = previousAnchorContext.anchorType; let previousAnchor = previousAnchorContext.anchorValue; 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 = llmSelectedObjectScopeDetected || hasSelectedObjectInventoryScopeSignal(userMessage); const hasSelectedObjectInventorySignalAlternate = deps.toNonEmptyString(alternateMessage) ? hasSelectedObjectInventoryScopeSignal(String(alternateMessage ?? "")) : false; const selectedObjectRetargetIntent = hasSelectedObjectInventorySignalPrimary || hasSelectedObjectInventorySignalAlternate ? inferSelectedObjectInventoryFollowupIntent(userMessage, alternateMessage) : null; const inventoryRootFrameCandidate = deps.findRecentInventoryRootFrame(items) ?? continuitySnapshot.inventoryRootFrame ?? (0, assistantContinuityPolicy_1.buildInventoryRootFrameFromAddressDebug)(continuitySnapshot.lastGroundedAddressDebug, deps.toNonEmptyString); let { inventoryRootFrame, currentFrameKind } = (0, assistantContinuityPolicy_1.hydrateInventoryRootFrameState)(inventoryRootFrameCandidate, sourceIntent, navigationOrganization, navigationDateScope, deps.toNonEmptyString, deps.isInventoryDrilldownFrameIntent, deps.isInventoryRootFrameIntent); let resolvedCounterpartyFromDisplay = false; let displayedEntityTargetIntent = null; let previousFilters = (0, assistantContinuityPolicy_1.resolveAddressDebugCarryoverFilters)(previousAddressDebug, deps.toNonEmptyString); 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"; previousFilters = (0, assistantContinuityPolicy_1.applyHistoricalPartyCarryoverFilters)(previousFilters, shouldBackfillHistoricalPartyAnchors, deps.findRecentAddressFilterValue(items, "contract"), deps.findRecentAddressFilterValue(items, "counterparty"), deps.toNonEmptyString); const historicalOrganization = deps.findRecentAddressFilterValue(items, "organization"); const authorityActiveOrganization = deps.normalizeOrganizationScopeValue(organizationAuthority.activeOrganization) ?? deps.normalizeOrganizationScopeValue(organizationAuthority.continuityActiveOrganization); previousFilters = (0, assistantContinuityPolicy_1.applyOrganizationCarryoverFilters)(previousFilters, historicalOrganization, authorityActiveOrganization, continuitySnapshot.activeOrganization, navigationOrganization, organizationClarificationSelection, deps.toNonEmptyString); if (inventoryPurchaseDateVatBridge) { const purchaseBridgeItem = previousAddressItem && deps.toNonEmptyString(previousAddressDebug?.detected_intent) === "inventory_purchase_provenance_for_item" ? previousAddressItem : findRecentInventoryPurchaseProvenanceItem(items, deps.toNonEmptyString(navigationFocusObjectLabel) ?? (0, assistantContinuityPolicy_1.readAddressDebugItem)(previousAddressDebug, deps.toNonEmptyString) ?? deps.toNonEmptyString(previousFilters.item)) ?? previousAddressItem; const purchaseBridgeWindow = extractPurchaseDateBridgeWindow(purchaseBridgeItem, addressNavigationState); if (purchaseBridgeWindow) { previousFilters.period_from = purchaseBridgeWindow.period_from; previousFilters.period_to = purchaseBridgeWindow.period_to; } } previousFilters = (0, assistantContinuityPolicy_1.applyTemporalCarryoverFilters)(previousFilters, navigationDateScope, continuityTemporalScope, sourceIntentHint, deps.toNonEmptyString); 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 = (0, assistantContinuityPolicy_1.buildRootScopedCarryoverFilters)(previousFilters, inventoryRootFrame, deps.toNonEmptyString); 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); } ({ previousFilters, previousAnchorType, previousAnchorValue: previousAnchor, followupSelectionMode, resolvedCounterpartyFromDisplay } = (0, assistantContinuityPolicy_1.applyReferencedEntityCarryover)(previousFilters, previousAnchorType, previousAnchor, followupSelectionMode, resolvedEntityFromFollowup, rootScopedPivot, deps.toNonEmptyString)); if (!rootScopedPivot && !deps.toNonEmptyString(previousFilters.item) && (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)) { const selectedObjectLabel = (navigationFocusObjectType === "item" ? navigationFocusObjectLabel : null) ?? continuitySnapshot.activeItem ?? extractSelectedObjectLabel(userMessage) ?? (deps.toNonEmptyString(alternateMessage) ? extractSelectedObjectLabel(String(alternateMessage ?? "")) : null); if (selectedObjectLabel) { previousFilters.item = selectedObjectLabel; previousAnchorType = "item"; previousAnchor = selectedObjectLabel; } } if (explicitOrganizationClarificationSelection && !previousAnchor) { previousAnchorType = "organization"; previousAnchor = explicitOrganizationClarificationSelection; } 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" : selectedObjectRetargetIntent && (explicitIntent === null || explicitIntent === "inventory_on_hand_as_of_date" || explicitIntent === sourceIntent) ? selectedObjectRetargetIntent : 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 }; }