Архитектура: централизовать selected-item carryover в continuity policy и transition glue

This commit is contained in:
2026-04-19 12:13:43 +03:00
parent 4f56aa9b2a
commit 851289b9a6
7 changed files with 179 additions and 38 deletions
@@ -536,6 +536,53 @@ export function applyReferencedEntityCarryover(
};
}
export function applySelectedItemCarryover(
previousFilters: Record<string, unknown> | null,
previousAnchorType: string | null,
previousAnchorValue: string | null,
rootScopedPivot: boolean,
shouldApplySelectedItemCarryover: boolean,
navigationFocusItemLabel: unknown,
continuityActiveItem: unknown,
selectedObjectLabelFromUser: unknown,
selectedObjectLabelFromAlternate: unknown,
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
): {
previousFilters: Record<string, unknown>;
previousAnchorType: string | null;
previousAnchorValue: string | null;
} {
const nextFilters =
previousFilters && typeof previousFilters === "object" ? { ...previousFilters } : {};
if (rootScopedPivot || !shouldApplySelectedItemCarryover || toNonEmptyString(nextFilters.item)) {
return {
previousFilters: nextFilters,
previousAnchorType,
previousAnchorValue
};
}
const selectedObjectLabel =
toNonEmptyString(navigationFocusItemLabel) ??
toNonEmptyString(continuityActiveItem) ??
toNonEmptyString(selectedObjectLabelFromUser) ??
toNonEmptyString(selectedObjectLabelFromAlternate);
if (!selectedObjectLabel) {
return {
previousFilters: nextFilters,
previousAnchorType,
previousAnchorValue
};
}
nextFilters.item = selectedObjectLabel;
return {
previousFilters: nextFilters,
previousAnchorType: "item",
previousAnchorValue: selectedObjectLabel
};
}
export function buildInventoryRootFrameFromAddressDebug(
debug: Record<string, unknown> | null,
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
@@ -3,6 +3,7 @@ import {
applyHistoricalPartyCarryoverFilters,
applyOrganizationCarryoverFilters,
applyReferencedEntityCarryover,
applySelectedItemCarryover,
applyTemporalCarryoverFilters,
buildRootScopedCarryoverFilters,
buildInventoryRootFrameFromAddressDebug,
@@ -874,10 +875,16 @@ export function createAssistantTransitionPolicy(deps) {
rootScopedPivot,
deps.toNonEmptyString
));
if (
!rootScopedPivot &&
!deps.toNonEmptyString(previousFilters.item) &&
(sourceIntentHint === "inventory_on_hand_as_of_date" ||
({
previousFilters,
previousAnchorType,
previousAnchorValue: previousAnchor
} = applySelectedItemCarryover(
previousFilters,
previousAnchorType,
previousAnchor,
rootScopedPivot,
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" ||
@@ -885,19 +892,13 @@ export function createAssistantTransitionPolicy(deps) {
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;
}
}
hasSelectedObjectInventorySignalAlternate,
navigationFocusObjectType === "item" ? navigationFocusObjectLabel : null,
continuitySnapshot.activeItem,
extractSelectedObjectLabel(userMessage),
deps.toNonEmptyString(alternateMessage) ? extractSelectedObjectLabel(String(alternateMessage ?? "")) : null,
deps.toNonEmptyString
));
if (explicitOrganizationClarificationSelection && !previousAnchor) {
previousAnchorType = "organization";
previousAnchor = explicitOrganizationClarificationSelection;