819 lines
49 KiB
JavaScript
819 lines
49 KiB
JavaScript
"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
|
||
};
|
||
}
|