ARCH: усилить metadata ambiguity choice sets в lane arbitration
This commit is contained in:
parent
d9454fcdef
commit
c328c52c9b
|
|
@ -228,9 +228,22 @@ function collectFollowupDiscoverySeed(followupContext) {
|
||||||
dateScope,
|
dateScope,
|
||||||
metadataRouteFamily: toNonEmptyString(followupContext?.previous_discovery_metadata_route_family),
|
metadataRouteFamily: toNonEmptyString(followupContext?.previous_discovery_metadata_route_family),
|
||||||
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
|
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
|
||||||
metadataAmbiguityDetected: followupContext?.previous_discovery_metadata_ambiguity_detected === true
|
metadataAmbiguityDetected: followupContext?.previous_discovery_metadata_ambiguity_detected === true,
|
||||||
|
metadataAmbiguityEntitySets: collectEntityCandidates(followupContext?.previous_discovery_metadata_ambiguity_entity_sets)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function metadataEntitySetsSuggestDocumentLane(values) {
|
||||||
|
return values.some((value) => /(?:документ|document|invoice|waybill|накладн|счет[- ]?фактур|акт)/iu.test(value));
|
||||||
|
}
|
||||||
|
function metadataEntitySetsSuggestMovementLane(values) {
|
||||||
|
return values.some((value) => /(?:регистр|register|movement|движени|операц|проводк|bank)/iu.test(value));
|
||||||
|
}
|
||||||
|
function metadataAmbiguityCollapsesToDocumentLane(values) {
|
||||||
|
return values.length > 0 && metadataEntitySetsSuggestDocumentLane(values) && !metadataEntitySetsSuggestMovementLane(values);
|
||||||
|
}
|
||||||
|
function metadataAmbiguityCollapsesToMovementLane(values) {
|
||||||
|
return values.length > 0 && metadataEntitySetsSuggestMovementLane(values) && !metadataEntitySetsSuggestDocumentLane(values);
|
||||||
|
}
|
||||||
function hasLifecycleSignal(text) {
|
function hasLifecycleSignal(text) {
|
||||||
return /(?:сколько\s+лет|как\s+давно|давно\s+ли|возраст|перв(?:ая|ый)\s+актив|когда\s+начал|когда\s+появ|lifecycle|activity\s+duration|business\s+age|how\s+long)/iu.test(text);
|
return /(?:сколько\s+лет|как\s+давно|давно\s+ли|возраст|перв(?:ая|ый)\s+актив|когда\s+начал|когда\s+появ|lifecycle|activity\s+duration|business\s+age|how\s+long)/iu.test(text);
|
||||||
}
|
}
|
||||||
|
|
@ -257,10 +270,10 @@ function hasMetadataObjectHint(text) {
|
||||||
return /(?:\u0440\u0435\u0433\u0438\u0441\u0442\u0440(?:\u044b)?|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a(?:\u0438)?|\u043f\u043e\u043b(?:\u0435|\u044f)|registers?|documents?|catalogs?|fields?)/iu.test(text);
|
return /(?:\u0440\u0435\u0433\u0438\u0441\u0442\u0440(?:\u044b)?|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a(?:\u0438)?|\u043f\u043e\u043b(?:\u0435|\u044f)|registers?|documents?|catalogs?|fields?)/iu.test(text);
|
||||||
}
|
}
|
||||||
function hasDocumentEvidenceFollowupSignal(text) {
|
function hasDocumentEvidenceFollowupSignal(text) {
|
||||||
return /(?:\u043f\u043e\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u0430\u043c|\u044b)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0438\u0449\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|document(?:s)?\s+(?:then|next)?|(?:then|next)\s+documents?|go\s+to\s+documents?)/iu.test(text);
|
return /(?:\u043f\u043e\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u0430\u043c|\u044b)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u0438\u0449\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442(?:\u044b)?|(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043a\u0430\u043a\u0438\u0435|\u0441\u043f\u0438\u0441\u043e\u043a|\u0434\u0430\u0439|\u0438\u0449\u0438)\s+(?:\u0441\u0447(?:[еe]т|\u0435\u0442)[-\u2011 ]?\u0444\u0430\u043a\u0442\u0443\u0440(?:\u044b|\u0430)?|\u043d\u0430\u043a\u043b\u0430\u0434\u043d(?:\u044b\u0435|\u0430\u044f)?|\u0430\u043a\u0442(?:\u044b)?|\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446(?:\u0438\u0438|\u0438\u044e)|invoice(?:s)?|bill(?:s)?|waybill(?:s)?)|document(?:s)?\s+(?:then|next)?|(?:then|next)\s+documents?|go\s+to\s+documents?)/iu.test(text);
|
||||||
}
|
}
|
||||||
function hasMovementEvidenceFollowupSignal(text) {
|
function hasMovementEvidenceFollowupSignal(text) {
|
||||||
return /(?:\u043f\u043e\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f\u043c|\u0438\u044f)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0438\u0449\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a(?:\u0438\u0435|\u0438\u0439)\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|movement(?:s)?\s+(?:then|next)?|(?:then|next)\s+movements?|go\s+to\s+movements?)/iu.test(text);
|
return /(?:\u043f\u043e\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f\u043c|\u0438\u044f)?|\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0438\u0449\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|\u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a(?:\u0438\u0435|\u0438\u0439)\s+\u0434\u0432\u0438\u0436\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043a\u0430\u043a\u0438\u0435|\u0441\u043f\u0438\u0441\u043e\u043a|\u0434\u0430\u0439|\u0438\u0449\u0438)\s+(?:\u043f\u043b\u0430\u0442[еe]\u0436(?:\u0438|\u0438)?|\u043e\u043f\u0435\u0440\u0430\u0446(?:\u0438\u0438|\u0438\u044e)|\u043f\u0440\u043e\u0432\u043e\u0434\u043a(?:\u0438|\u0430)|\u0441\u043f\u0438\u0441\u0430\u043d(?:\u0438\u044f|\u0438\u0435)|\u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d(?:\u0438\u044f|\u0438\u0435)|payment(?:s)?|transaction(?:s)?|operation(?:s)?|posting(?:s)?|bank\s+operation(?:s)?)|movement(?:s)?\s+(?:then|next)?|(?:then|next)\s+movements?|go\s+to\s+movements?)/iu.test(text);
|
||||||
}
|
}
|
||||||
function hasMetadataDownstreamContinuationSignal(text) {
|
function hasMetadataDownstreamContinuationSignal(text) {
|
||||||
return /(?:\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0434(?:\u0435|\u0451)\u043c\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u043e\u0448\u043b(?:\u0438|\u0451\u043c)\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0439|\u0438\u0449\u0438\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0449\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0441\u0442\u0440\u043e\u043a\u0438|\u0433\u043b\u0443\u0431\u0436\u0435|\u0447\u0442\u043e\s+\u0434\u0430\u043b\u044c\u0448\u0435|continue|go\s+ahead|go\s+deeper|look\s+deeper|drill\s+down|show\s+(?:data|rows))/iu.test(text);
|
return /(?:\u0434\u0430\u0432\u0430\u0439\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0434(?:\u0435|\u0451)\u043c\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u043e\u0448\u043b(?:\u0438|\u0451\u043c)\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0439|\u0438\u0449\u0438\s+\u0434\u0430\u043b\u044c\u0448\u0435|\u0438\u0449\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0434\u0430\u043d\u043d\u044b\u0435|\u043f\u043e\u043a\u0430\u0436\u0438\s+\u0441\u0442\u0440\u043e\u043a\u0438|\u0433\u043b\u0443\u0431\u0436\u0435|\u0447\u0442\u043e\s+\u0434\u0430\u043b\u044c\u0448\u0435|continue|go\s+ahead|go\s+deeper|look\s+deeper|drill\s+down|show\s+(?:data|rows))/iu.test(text);
|
||||||
|
|
@ -351,6 +364,8 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
const monthlyAggregationSignal = hasMonthlyAggregationSignal(rawText);
|
const monthlyAggregationSignal = hasMonthlyAggregationSignal(rawText);
|
||||||
const explicitDateScopeLiteralDetected = hasExplicitDateScopeLiteral(rawText);
|
const explicitDateScopeLiteralDetected = hasExplicitDateScopeLiteral(rawText);
|
||||||
const rawDateScope = collectDateScopeFromRawText(rawText);
|
const rawDateScope = collectDateScopeFromRawText(rawText);
|
||||||
|
const metadataDocumentHintSignal = hasDocumentEvidenceFollowupSignal(rawText);
|
||||||
|
const metadataMovementHintSignal = hasMovementEvidenceFollowupSignal(rawText);
|
||||||
const rawDomain = toNonEmptyString(assistantTurnMeaning?.asked_domain_family);
|
const rawDomain = toNonEmptyString(assistantTurnMeaning?.asked_domain_family);
|
||||||
const rawAction = toNonEmptyString(assistantTurnMeaning?.asked_action_family);
|
const rawAction = toNonEmptyString(assistantTurnMeaning?.asked_action_family);
|
||||||
const rawAggregationAxis = toNonEmptyString(assistantTurnMeaning?.asked_aggregation_axis);
|
const rawAggregationAxis = toNonEmptyString(assistantTurnMeaning?.asked_aggregation_axis);
|
||||||
|
|
@ -373,26 +388,28 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
!rawValueFlowSignal &&
|
||||||
hasDocumentEvidenceFollowupSignal(rawText));
|
metadataDocumentHintSignal);
|
||||||
const metadataAmbiguityResolvedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
const metadataAmbiguityResolvedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
followupSeed.metadataAmbiguityDetected &&
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
|
||||||
|
metadataEntitySetsSuggestDocumentLane(followupSeed.metadataAmbiguityEntitySets)) &&
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
!rawValueFlowSignal &&
|
||||||
hasDocumentEvidenceFollowupSignal(rawText));
|
metadataDocumentHintSignal);
|
||||||
const metadataGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
const metadataGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
followupSeed.metadataRouteFamily === "movement_evidence" &&
|
followupSeed.metadataRouteFamily === "movement_evidence" &&
|
||||||
!followupSeed.metadataAmbiguityDetected &&
|
!followupSeed.metadataAmbiguityDetected &&
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
metadataMovementHintSignal);
|
||||||
hasMovementEvidenceFollowupSignal(rawText));
|
|
||||||
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
followupSeed.metadataAmbiguityDetected &&
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
|
||||||
|
metadataEntitySetsSuggestMovementLane(followupSeed.metadataAmbiguityEntitySets)) &&
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
metadataMovementHintSignal);
|
||||||
hasMovementEvidenceFollowupSignal(rawText));
|
|
||||||
const metadataGroundedLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
const metadataGroundedLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
(followupSeed.metadataRouteFamily === "document_evidence" ||
|
(followupSeed.metadataRouteFamily === "document_evidence" ||
|
||||||
followupSeed.metadataRouteFamily === "movement_evidence") &&
|
followupSeed.metadataRouteFamily === "movement_evidence") &&
|
||||||
|
|
@ -401,15 +418,37 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
!rawValueFlowSignal &&
|
||||||
!rawMetadataSignal &&
|
!rawMetadataSignal &&
|
||||||
!hasDocumentEvidenceFollowupSignal(rawText) &&
|
!metadataDocumentHintSignal &&
|
||||||
!hasMovementEvidenceFollowupSignal(rawText) &&
|
!metadataMovementHintSignal &&
|
||||||
|
hasMetadataDownstreamContinuationSignal(rawText));
|
||||||
|
const metadataAmbiguityCollapsedDocumentLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
followupSeed.counterparty &&
|
||||||
|
!rawLifecycleSignal &&
|
||||||
|
!rawValueFlowSignal &&
|
||||||
|
!rawMetadataSignal &&
|
||||||
|
!metadataDocumentHintSignal &&
|
||||||
|
!metadataMovementHintSignal &&
|
||||||
|
hasMetadataDownstreamContinuationSignal(rawText));
|
||||||
|
const metadataAmbiguityCollapsedMovementLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
followupSeed.counterparty &&
|
||||||
|
!rawLifecycleSignal &&
|
||||||
|
!rawValueFlowSignal &&
|
||||||
|
!rawMetadataSignal &&
|
||||||
|
!metadataDocumentHintSignal &&
|
||||||
|
!metadataMovementHintSignal &&
|
||||||
hasMetadataDownstreamContinuationSignal(rawText));
|
hasMetadataDownstreamContinuationSignal(rawText));
|
||||||
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
|
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
|
||||||
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence");
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence") ||
|
||||||
|
metadataAmbiguityCollapsedDocumentLaneContinuationApplicable;
|
||||||
const metadataGroundedMovementLaneApplicable = metadataGroundedMovementFollowupApplicable ||
|
const metadataGroundedMovementLaneApplicable = metadataGroundedMovementFollowupApplicable ||
|
||||||
metadataAmbiguityResolvedMovementFollowupApplicable ||
|
metadataAmbiguityResolvedMovementFollowupApplicable ||
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence");
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence") ||
|
||||||
|
metadataAmbiguityCollapsedMovementLaneContinuationApplicable;
|
||||||
const effectiveMetadataFollowupSeedApplicable = metadataFollowupSeedApplicable &&
|
const effectiveMetadataFollowupSeedApplicable = metadataFollowupSeedApplicable &&
|
||||||
!metadataGroundedDocumentLaneApplicable &&
|
!metadataGroundedDocumentLaneApplicable &&
|
||||||
!metadataGroundedMovementLaneApplicable;
|
!metadataGroundedMovementLaneApplicable;
|
||||||
|
|
@ -437,7 +476,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
const lifecycleSignal = rawLifecycleSignal || seededDomain === "counterparty_lifecycle";
|
const lifecycleSignal = rawLifecycleSignal || seededDomain === "counterparty_lifecycle";
|
||||||
const bidirectionalValueFlowSignal = !lifecycleSignal &&
|
const bidirectionalValueFlowSignal = !lifecycleSignal &&
|
||||||
(rawBidirectionalValueFlowSignal || seededAction === "net_value_flow");
|
(rawBidirectionalValueFlowSignal || seededAction === "net_value_flow");
|
||||||
const valueFlowSignal = !lifecycleSignal && (rawValueFlowSignal || seededDomain === "counterparty_value");
|
const valueFlowSignal = !lifecycleSignal &&
|
||||||
|
!metadataGroundedMovementLaneApplicable &&
|
||||||
|
(rawValueFlowSignal || seededDomain === "counterparty_value");
|
||||||
const payoutSignal = valueFlowSignal &&
|
const payoutSignal = valueFlowSignal &&
|
||||||
!bidirectionalValueFlowSignal &&
|
!bidirectionalValueFlowSignal &&
|
||||||
(rawPayoutSignal || seededAction === "payout");
|
(rawPayoutSignal || seededAction === "payout");
|
||||||
|
|
@ -616,6 +657,12 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
|
||||||
if (metadataGroundedLaneContinuationApplicable) {
|
if (metadataGroundedLaneContinuationApplicable) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_lane_continuation");
|
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_lane_continuation");
|
||||||
}
|
}
|
||||||
|
if (metadataAmbiguityCollapsedDocumentLaneContinuationApplicable) {
|
||||||
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_document_lane");
|
||||||
|
}
|
||||||
|
if (metadataAmbiguityCollapsedMovementLaneContinuationApplicable) {
|
||||||
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
|
||||||
|
}
|
||||||
if (unsupported) {
|
if (unsupported) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,17 @@ export function readAssistantMcpDiscoveryMetadataAmbiguityDetected(
|
||||||
return readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_detected === true;
|
return readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_detected === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function readAssistantMcpDiscoveryMetadataAmbiguityEntitySets(
|
||||||
|
debug: Record<string, unknown> | null,
|
||||||
|
toNonEmptyString: (value: unknown) => string | null = fallbackToNonEmptyString
|
||||||
|
): string[] {
|
||||||
|
const values = readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.ambiguity_entity_sets;
|
||||||
|
if (!Array.isArray(values)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return values.map((item) => toNonEmptyString(item)).filter((item): item is string => Boolean(item));
|
||||||
|
}
|
||||||
|
|
||||||
function mapAssistantMcpDiscoveryPilotScopeToAddressIntent(
|
function mapAssistantMcpDiscoveryPilotScopeToAddressIntent(
|
||||||
pilotScope: string | null,
|
pilotScope: string | null,
|
||||||
actionFamily: string | null
|
actionFamily: string | null
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,7 @@ function collectFollowupDiscoverySeed(followupContext: Record<string, unknown> |
|
||||||
metadataRouteFamily: string | null;
|
metadataRouteFamily: string | null;
|
||||||
metadataSelectedEntitySet: string | null;
|
metadataSelectedEntitySet: string | null;
|
||||||
metadataAmbiguityDetected: boolean;
|
metadataAmbiguityDetected: boolean;
|
||||||
|
metadataAmbiguityEntitySets: string[];
|
||||||
} {
|
} {
|
||||||
const previousFilters = toRecordObject(followupContext?.previous_filters);
|
const previousFilters = toRecordObject(followupContext?.previous_filters);
|
||||||
const rootFilters = toRecordObject(followupContext?.root_filters);
|
const rootFilters = toRecordObject(followupContext?.root_filters);
|
||||||
|
|
@ -302,10 +303,29 @@ function collectFollowupDiscoverySeed(followupContext: Record<string, unknown> |
|
||||||
dateScope,
|
dateScope,
|
||||||
metadataRouteFamily: toNonEmptyString(followupContext?.previous_discovery_metadata_route_family),
|
metadataRouteFamily: toNonEmptyString(followupContext?.previous_discovery_metadata_route_family),
|
||||||
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
|
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
|
||||||
metadataAmbiguityDetected: followupContext?.previous_discovery_metadata_ambiguity_detected === true
|
metadataAmbiguityDetected: followupContext?.previous_discovery_metadata_ambiguity_detected === true,
|
||||||
|
metadataAmbiguityEntitySets: collectEntityCandidates(followupContext?.previous_discovery_metadata_ambiguity_entity_sets)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function metadataEntitySetsSuggestDocumentLane(values: string[]): boolean {
|
||||||
|
return values.some((value) => /(?:документ|document|invoice|waybill|накладн|счет[- ]?фактур|акт)/iu.test(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function metadataEntitySetsSuggestMovementLane(values: string[]): boolean {
|
||||||
|
return values.some((value) =>
|
||||||
|
/(?:регистр|register|movement|движени|операц|проводк|bank)/iu.test(value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function metadataAmbiguityCollapsesToDocumentLane(values: string[]): boolean {
|
||||||
|
return values.length > 0 && metadataEntitySetsSuggestDocumentLane(values) && !metadataEntitySetsSuggestMovementLane(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
function metadataAmbiguityCollapsesToMovementLane(values: string[]): boolean {
|
||||||
|
return values.length > 0 && metadataEntitySetsSuggestMovementLane(values) && !metadataEntitySetsSuggestDocumentLane(values);
|
||||||
|
}
|
||||||
|
|
||||||
function hasLifecycleSignal(text: string): boolean {
|
function hasLifecycleSignal(text: string): boolean {
|
||||||
return /(?:сколько\s+лет|как\s+давно|давно\s+ли|возраст|перв(?:ая|ый)\s+актив|когда\s+начал|когда\s+появ|lifecycle|activity\s+duration|business\s+age|how\s+long)/iu.test(
|
return /(?:сколько\s+лет|как\s+давно|давно\s+ли|возраст|перв(?:ая|ый)\s+актив|когда\s+начал|когда\s+появ|lifecycle|activity\s+duration|business\s+age|how\s+long)/iu.test(
|
||||||
text
|
text
|
||||||
|
|
@ -520,6 +540,8 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
const metadataAmbiguityResolvedDocumentFollowupApplicable = Boolean(
|
const metadataAmbiguityResolvedDocumentFollowupApplicable = Boolean(
|
||||||
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
followupSeed.metadataAmbiguityDetected &&
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
|
||||||
|
metadataEntitySetsSuggestDocumentLane(followupSeed.metadataAmbiguityEntitySets)) &&
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
!rawValueFlowSignal &&
|
!rawValueFlowSignal &&
|
||||||
|
|
@ -536,6 +558,8 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(
|
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(
|
||||||
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
followupSeed.metadataAmbiguityDetected &&
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
|
||||||
|
metadataEntitySetsSuggestMovementLane(followupSeed.metadataAmbiguityEntitySets)) &&
|
||||||
followupSeed.counterparty &&
|
followupSeed.counterparty &&
|
||||||
!rawLifecycleSignal &&
|
!rawLifecycleSignal &&
|
||||||
metadataMovementHintSignal
|
metadataMovementHintSignal
|
||||||
|
|
@ -553,14 +577,40 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
!metadataMovementHintSignal &&
|
!metadataMovementHintSignal &&
|
||||||
hasMetadataDownstreamContinuationSignal(rawText)
|
hasMetadataDownstreamContinuationSignal(rawText)
|
||||||
);
|
);
|
||||||
|
const metadataAmbiguityCollapsedDocumentLaneContinuationApplicable = Boolean(
|
||||||
|
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
followupSeed.counterparty &&
|
||||||
|
!rawLifecycleSignal &&
|
||||||
|
!rawValueFlowSignal &&
|
||||||
|
!rawMetadataSignal &&
|
||||||
|
!metadataDocumentHintSignal &&
|
||||||
|
!metadataMovementHintSignal &&
|
||||||
|
hasMetadataDownstreamContinuationSignal(rawText)
|
||||||
|
);
|
||||||
|
const metadataAmbiguityCollapsedMovementLaneContinuationApplicable = Boolean(
|
||||||
|
followupSeed.pilotScope === "metadata_inspection_v1" &&
|
||||||
|
followupSeed.metadataAmbiguityDetected &&
|
||||||
|
metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
|
||||||
|
followupSeed.counterparty &&
|
||||||
|
!rawLifecycleSignal &&
|
||||||
|
!rawValueFlowSignal &&
|
||||||
|
!rawMetadataSignal &&
|
||||||
|
!metadataDocumentHintSignal &&
|
||||||
|
!metadataMovementHintSignal &&
|
||||||
|
hasMetadataDownstreamContinuationSignal(rawText)
|
||||||
|
);
|
||||||
const metadataGroundedDocumentLaneApplicable =
|
const metadataGroundedDocumentLaneApplicable =
|
||||||
metadataGroundedDocumentFollowupApplicable ||
|
metadataGroundedDocumentFollowupApplicable ||
|
||||||
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
metadataAmbiguityResolvedDocumentFollowupApplicable ||
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence");
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "document_evidence") ||
|
||||||
|
metadataAmbiguityCollapsedDocumentLaneContinuationApplicable;
|
||||||
const metadataGroundedMovementLaneApplicable =
|
const metadataGroundedMovementLaneApplicable =
|
||||||
metadataGroundedMovementFollowupApplicable ||
|
metadataGroundedMovementFollowupApplicable ||
|
||||||
metadataAmbiguityResolvedMovementFollowupApplicable ||
|
metadataAmbiguityResolvedMovementFollowupApplicable ||
|
||||||
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence");
|
(metadataGroundedLaneContinuationApplicable && followupSeed.metadataRouteFamily === "movement_evidence") ||
|
||||||
|
metadataAmbiguityCollapsedMovementLaneContinuationApplicable;
|
||||||
const effectiveMetadataFollowupSeedApplicable =
|
const effectiveMetadataFollowupSeedApplicable =
|
||||||
metadataFollowupSeedApplicable &&
|
metadataFollowupSeedApplicable &&
|
||||||
!metadataGroundedDocumentLaneApplicable &&
|
!metadataGroundedDocumentLaneApplicable &&
|
||||||
|
|
@ -784,6 +834,12 @@ export function buildAssistantMcpDiscoveryTurnInput(
|
||||||
if (metadataGroundedLaneContinuationApplicable) {
|
if (metadataGroundedLaneContinuationApplicable) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_lane_continuation");
|
pushReason(reasonCodes, "mcp_discovery_metadata_grounded_lane_continuation");
|
||||||
}
|
}
|
||||||
|
if (metadataAmbiguityCollapsedDocumentLaneContinuationApplicable) {
|
||||||
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_document_lane");
|
||||||
|
}
|
||||||
|
if (metadataAmbiguityCollapsedMovementLaneContinuationApplicable) {
|
||||||
|
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
|
||||||
|
}
|
||||||
if (unsupported) {
|
if (unsupported) {
|
||||||
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
pushReason(reasonCodes, "mcp_discovery_unsupported_but_understood_turn");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import {
|
||||||
readAddressDebugFilters,
|
readAddressDebugFilters,
|
||||||
readAddressDebugItem,
|
readAddressDebugItem,
|
||||||
readAssistantMcpDiscoveryMetadataAmbiguityDetected,
|
readAssistantMcpDiscoveryMetadataAmbiguityDetected,
|
||||||
|
readAssistantMcpDiscoveryMetadataAmbiguityEntitySets,
|
||||||
readAssistantMcpDiscoveryMetadataRouteFamily,
|
readAssistantMcpDiscoveryMetadataRouteFamily,
|
||||||
readAssistantMcpDiscoveryMetadataSelectedEntitySet,
|
readAssistantMcpDiscoveryMetadataSelectedEntitySet,
|
||||||
readAddressDebugTemporalScope,
|
readAddressDebugTemporalScope,
|
||||||
|
|
@ -621,6 +622,10 @@ export function createAssistantTransitionPolicy(deps) {
|
||||||
const sourceDiscoveryMetadataAmbiguityDetected = readAssistantMcpDiscoveryMetadataAmbiguityDetected(
|
const sourceDiscoveryMetadataAmbiguityDetected = readAssistantMcpDiscoveryMetadataAmbiguityDetected(
|
||||||
carryoverSourceDebug
|
carryoverSourceDebug
|
||||||
);
|
);
|
||||||
|
const sourceDiscoveryMetadataAmbiguityEntitySets = readAssistantMcpDiscoveryMetadataAmbiguityEntitySets(
|
||||||
|
carryoverSourceDebug,
|
||||||
|
deps.toNonEmptyString
|
||||||
|
);
|
||||||
const llmExplicitIntent = deps.toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
|
const llmExplicitIntent = deps.toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
|
||||||
const llmSelectedObjectScopeDetected =
|
const llmSelectedObjectScopeDetected =
|
||||||
llmPreDecomposeMeta?.predecomposeContract?.semantics?.selected_object_scope_detected === true;
|
llmPreDecomposeMeta?.predecomposeContract?.semantics?.selected_object_scope_detected === true;
|
||||||
|
|
@ -956,6 +961,8 @@ export function createAssistantTransitionPolicy(deps) {
|
||||||
previous_discovery_metadata_route_family: sourceDiscoveryMetadataRouteFamily ?? undefined,
|
previous_discovery_metadata_route_family: sourceDiscoveryMetadataRouteFamily ?? undefined,
|
||||||
previous_discovery_metadata_selected_entity_set: sourceDiscoveryMetadataSelectedEntitySet ?? undefined,
|
previous_discovery_metadata_selected_entity_set: sourceDiscoveryMetadataSelectedEntitySet ?? undefined,
|
||||||
previous_discovery_metadata_ambiguity_detected: sourceDiscoveryMetadataAmbiguityDetected || undefined,
|
previous_discovery_metadata_ambiguity_detected: sourceDiscoveryMetadataAmbiguityDetected || undefined,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets:
|
||||||
|
sourceDiscoveryMetadataAmbiguityEntitySets.length > 0 ? sourceDiscoveryMetadataAmbiguityEntitySets : undefined,
|
||||||
resolved_counterparty_from_display: resolvedCounterpartyFromDisplay || undefined,
|
resolved_counterparty_from_display: resolvedCounterpartyFromDisplay || undefined,
|
||||||
root_context_only: rootScopedPivot || undefined,
|
root_context_only: rootScopedPivot || undefined,
|
||||||
root_intent: shouldAttachInventoryRootFrame ? inventoryRootFrame?.intent ?? undefined : undefined,
|
root_intent: shouldAttachInventoryRootFrame ? inventoryRootFrame?.intent ?? undefined : undefined,
|
||||||
|
|
|
||||||
|
|
@ -367,6 +367,7 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
followupContext: {
|
followupContext: {
|
||||||
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
previous_discovery_metadata_ambiguity_detected: true,
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
previous_filters: {
|
previous_filters: {
|
||||||
counterparty: "SVK",
|
counterparty: "SVK",
|
||||||
period_from: "2020-01-01",
|
period_from: "2020-01-01",
|
||||||
|
|
@ -398,6 +399,7 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
followupContext: {
|
followupContext: {
|
||||||
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
previous_discovery_metadata_ambiguity_detected: true,
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
previous_filters: {
|
previous_filters: {
|
||||||
counterparty: "SVK",
|
counterparty: "SVK",
|
||||||
period_from: "2020-01-01",
|
period_from: "2020-01-01",
|
||||||
|
|
@ -429,6 +431,7 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
followupContext: {
|
followupContext: {
|
||||||
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
previous_discovery_metadata_ambiguity_detected: true,
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
previous_filters: {
|
previous_filters: {
|
||||||
counterparty: "SVK",
|
counterparty: "SVK",
|
||||||
period_from: "2020-01-01",
|
period_from: "2020-01-01",
|
||||||
|
|
@ -459,6 +462,7 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
followupContext: {
|
followupContext: {
|
||||||
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
previous_discovery_metadata_ambiguity_detected: true,
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ", "РегистрНакопления"],
|
||||||
previous_filters: {
|
previous_filters: {
|
||||||
counterparty: "SVK",
|
counterparty: "SVK",
|
||||||
period_from: "2020-01-01",
|
period_from: "2020-01-01",
|
||||||
|
|
@ -484,6 +488,88 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||||
expect(result.reason_codes).not.toContain("mcp_discovery_value_flow_signal_detected");
|
expect(result.reason_codes).not.toContain("mcp_discovery_value_flow_signal_detected");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not resolve metadata ambiguity into movement lane when confirmed ambiguity sets contain documents only", () => {
|
||||||
|
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||||
|
userMessage: "по движениям",
|
||||||
|
followupContext: {
|
||||||
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ"],
|
||||||
|
previous_filters: {
|
||||||
|
counterparty: "SVK",
|
||||||
|
period_from: "2020-01-01",
|
||||||
|
period_to: "2020-12-31"
|
||||||
|
},
|
||||||
|
previous_anchor_type: "counterparty",
|
||||||
|
previous_anchor_value: "SVK"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.reason_codes).not.toContain("mcp_discovery_metadata_ambiguity_resolved_to_movement_lane");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("continues from ambiguous metadata into document lane when ambiguity choice set collapses to documents on a generic downstream follow-up", () => {
|
||||||
|
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||||
|
userMessage: "continue with data",
|
||||||
|
followupContext: {
|
||||||
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["Документ", "invoice"],
|
||||||
|
previous_filters: {
|
||||||
|
counterparty: "SVK",
|
||||||
|
period_from: "2020-01-01",
|
||||||
|
period_to: "2020-12-31"
|
||||||
|
},
|
||||||
|
previous_anchor_type: "counterparty",
|
||||||
|
previous_anchor_value: "SVK"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.adapter_status).toBe("ready");
|
||||||
|
expect(result.should_run_discovery).toBe(true);
|
||||||
|
expect(result.semantic_data_need).toBe("document evidence");
|
||||||
|
expect(result.turn_meaning_ref).toMatchObject({
|
||||||
|
asked_domain_family: "documents",
|
||||||
|
asked_action_family: "list_documents",
|
||||||
|
explicit_entity_candidates: ["SVK"],
|
||||||
|
explicit_date_scope: "2020",
|
||||||
|
unsupported_but_understood_family: "document_evidence",
|
||||||
|
stale_replay_forbidden: true
|
||||||
|
});
|
||||||
|
expect(result.reason_codes).toContain("mcp_discovery_metadata_ambiguity_collapsed_to_document_lane");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("continues from ambiguous metadata into movement lane when ambiguity choice set collapses to movements on a generic downstream follow-up", () => {
|
||||||
|
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||||
|
userMessage: "continue with data",
|
||||||
|
followupContext: {
|
||||||
|
previous_discovery_pilot_scope: "metadata_inspection_v1",
|
||||||
|
previous_discovery_metadata_ambiguity_detected: true,
|
||||||
|
previous_discovery_metadata_ambiguity_entity_sets: ["РегистрНакопления", "movement"],
|
||||||
|
previous_filters: {
|
||||||
|
counterparty: "SVK",
|
||||||
|
period_from: "2020-01-01",
|
||||||
|
period_to: "2020-12-31"
|
||||||
|
},
|
||||||
|
previous_anchor_type: "counterparty",
|
||||||
|
previous_anchor_value: "SVK"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.adapter_status).toBe("ready");
|
||||||
|
expect(result.should_run_discovery).toBe(true);
|
||||||
|
expect(result.semantic_data_need).toBe("movement evidence");
|
||||||
|
expect(result.turn_meaning_ref).toMatchObject({
|
||||||
|
asked_domain_family: "movements",
|
||||||
|
asked_action_family: "list_movements",
|
||||||
|
explicit_entity_candidates: ["SVK"],
|
||||||
|
explicit_date_scope: "2020",
|
||||||
|
unsupported_but_understood_family: "movement_evidence",
|
||||||
|
stale_replay_forbidden: true
|
||||||
|
});
|
||||||
|
expect(result.reason_codes).toContain("mcp_discovery_metadata_ambiguity_collapsed_to_movement_lane");
|
||||||
|
});
|
||||||
|
|
||||||
it("switches the checked year on a short payout follow-up while keeping prior discovery counterparty", () => {
|
it("switches the checked year on a short payout follow-up while keeping prior discovery counterparty", () => {
|
||||||
const result = buildAssistantMcpDiscoveryTurnInput({
|
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||||
userMessage: "а теперь за 2021?",
|
userMessage: "а теперь за 2021?",
|
||||||
|
|
|
||||||
|
|
@ -1169,6 +1169,64 @@ describe("assistantTransitionPolicy", () => {
|
||||||
expect(carryover?.followupContext?.previous_discovery_metadata_selected_entity_set).toBe("Документ");
|
expect(carryover?.followupContext?.previous_discovery_metadata_selected_entity_set).toBe("Документ");
|
||||||
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_detected).toBeUndefined();
|
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_detected).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
it("carries metadata ambiguity entity sets into follow-up context for downstream lane arbitration", () => {
|
||||||
|
const policy = buildPolicy({
|
||||||
|
findLastAddressAssistantItem: () => ({
|
||||||
|
text: "metadata ambiguity",
|
||||||
|
debug: {
|
||||||
|
execution_lane: "living_chat",
|
||||||
|
mcp_discovery_response_applied: true,
|
||||||
|
assistant_mcp_discovery_entry_point_v1: {
|
||||||
|
schema_version: "assistant_mcp_discovery_runtime_entry_point_v1",
|
||||||
|
entry_status: "bridge_executed",
|
||||||
|
turn_input: {
|
||||||
|
turn_meaning_ref: {
|
||||||
|
asked_domain_family: "metadata",
|
||||||
|
asked_action_family: "inspect_documents",
|
||||||
|
explicit_entity_candidates: ["SVK"],
|
||||||
|
explicit_date_scope: "2020"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bridge: {
|
||||||
|
bridge_status: "answer_draft_ready",
|
||||||
|
business_fact_answer_allowed: true,
|
||||||
|
pilot: {
|
||||||
|
pilot_scope: "metadata_inspection_v1",
|
||||||
|
derived_metadata_surface: {
|
||||||
|
selected_entity_set: null,
|
||||||
|
downstream_route_family: null,
|
||||||
|
ambiguity_detected: true,
|
||||||
|
ambiguity_entity_sets: ["Документ", "РегистрНакопления"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
answer_draft: {
|
||||||
|
answer_mode: "confirmed_with_bounded_inference"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
hasAddressFollowupContextSignal: () => true,
|
||||||
|
hasReferentialPointer: () => false,
|
||||||
|
resolveAddressIntent: () => ({ intent: "unknown" }),
|
||||||
|
resolveAddressIntentFamily: () => null,
|
||||||
|
resolveAssistantTurnMeaning: () => null
|
||||||
|
});
|
||||||
|
|
||||||
|
const carryover = policy.resolveAddressFollowupCarryoverContext(
|
||||||
|
"по документам",
|
||||||
|
[{ kind: "assistant", text: "metadata ambiguity" }],
|
||||||
|
"по документам",
|
||||||
|
{ predecomposeContract: { intent: "unknown" } },
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_detected).toBe(true);
|
||||||
|
expect(carryover?.followupContext?.previous_discovery_metadata_ambiguity_entity_sets).toEqual([
|
||||||
|
"Документ",
|
||||||
|
"РегистрНакопления"
|
||||||
|
]);
|
||||||
|
});
|
||||||
it("switches to VAT tax-period intent while preserving carried period filters", () => {
|
it("switches to VAT tax-period intent while preserving carried period filters", () => {
|
||||||
const policy = buildPolicy({
|
const policy = buildPolicy({
|
||||||
findLastAddressAssistantItem: () => ({
|
findLastAddressAssistantItem: () => ({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue