ARCH: замкнуть metadata-scoped clarification recovery loops

This commit is contained in:
2026-04-23 13:42:14 +03:00
parent c96c9bab86
commit cddd6667fb
20 changed files with 993 additions and 43 deletions
@@ -12,6 +12,8 @@ exports.readAssistantMcpDiscoveryLoopProvidedAxes = readAssistantMcpDiscoveryLoo
exports.readAssistantMcpDiscoveryLoopAskedDomainFamily = readAssistantMcpDiscoveryLoopAskedDomainFamily;
exports.readAssistantMcpDiscoveryLoopAskedActionFamily = readAssistantMcpDiscoveryLoopAskedActionFamily;
exports.readAssistantMcpDiscoveryLoopUnsupportedFamily = readAssistantMcpDiscoveryLoopUnsupportedFamily;
exports.readAssistantMcpDiscoveryLoopMetadataScopeHint = readAssistantMcpDiscoveryLoopMetadataScopeHint;
exports.readAssistantMcpDiscoveryLoopSubjectResolutionOptional = readAssistantMcpDiscoveryLoopSubjectResolutionOptional;
exports.readAssistantMcpDiscoveryMetadataRouteFamily = readAssistantMcpDiscoveryMetadataRouteFamily;
exports.readAssistantMcpDiscoveryMetadataRouteFamilySelectionBasis = readAssistantMcpDiscoveryMetadataRouteFamilySelectionBasis;
exports.readAssistantMcpDiscoveryMetadataSelectedEntitySet = readAssistantMcpDiscoveryMetadataSelectedEntitySet;
@@ -194,6 +196,16 @@ function readAssistantMcpDiscoveryLoopAskedActionFamily(debug, toNonEmptyString
function readAssistantMcpDiscoveryLoopUnsupportedFamily(debug, toNonEmptyString = fallbackToNonEmptyString) {
return toNonEmptyString(readAssistantMcpDiscoveryLoopState(debug)?.unsupported_but_understood_family);
}
function readAssistantMcpDiscoveryLoopMetadataScopeHint(debug, toNonEmptyString = fallbackToNonEmptyString) {
return (toNonEmptyString(readAssistantMcpDiscoveryLoopState(debug)?.metadata_scope_hint) ??
toNonEmptyString(readAssistantMcpDiscoveryTurnMeaning(debug)?.metadata_scope_hint) ??
toNonEmptyString(readAssistantMcpDiscoveryDataNeedGraph(debug)?.metadata_scope_hint));
}
function readAssistantMcpDiscoveryLoopSubjectResolutionOptional(debug) {
return (readAssistantMcpDiscoveryLoopState(debug)?.subject_resolution_optional === true ||
readAssistantMcpDiscoveryTurnMeaning(debug)?.subject_resolution_optional === true ||
readAssistantMcpDiscoveryDataNeedGraph(debug)?.subject_resolution_optional === true);
}
function readAssistantMcpDiscoveryMetadataRouteFamily(debug, toNonEmptyString = fallbackToNonEmptyString) {
return toNonEmptyString(readAssistantMcpDiscoveryDerivedMetadataSurface(debug)?.downstream_route_family);
}
@@ -361,6 +373,12 @@ function readAddressDebugCounterparty(debug, toNonEmptyString = fallbackToNonEmp
if (String(debug?.anchor_type ?? "") === "counterparty") {
return toNonEmptyString(debug?.anchor_value_resolved) ?? toNonEmptyString(debug?.anchor_value_raw);
}
const discoveryPilotScope = readAssistantMcpDiscoveryPilotScope(debug, toNonEmptyString);
const suppressDiscoveryEntityCarryover = discoveryPilotScope === "metadata_inspection_v1" ||
readAssistantMcpDiscoveryLoopSubjectResolutionOptional(debug);
if (suppressDiscoveryEntityCarryover) {
return null;
}
const discoveryEntities = collectAssistantMcpDiscoveryEntityCandidates(debug, toNonEmptyString);
for (const entity of discoveryEntities) {
const text = toNonEmptyString(entity);
@@ -131,6 +131,10 @@ function allowsOpenScopeWithoutSubject(input) {
}
return Boolean(supportsOrganizationScopedOpenTotal(input.action) && (input.organizationScope || input.oneSidedOpenScopeTotalHint));
}
function allowsMetadataScopedOpenLaneWithoutSubject(input) {
return Boolean(input.subjectResolutionOptional &&
(input.family === "movement_evidence" || input.family === "document_evidence"));
}
function rankingNeedFromRawUtterance(value) {
const text = lower(value);
if (!text) {
@@ -206,13 +210,17 @@ function decompositionCandidatesFor(input) {
return result;
}
if (input.family === "movement_evidence") {
pushUnique(result, "resolve_entity_reference");
if (!input.metadataScopedOpenLaneWithoutSubject) {
pushUnique(result, "resolve_entity_reference");
}
pushUnique(result, "fetch_scoped_movements");
pushUnique(result, "probe_coverage");
return result;
}
if (input.family === "document_evidence") {
pushUnique(result, "resolve_entity_reference");
if (!input.metadataScopedOpenLaneWithoutSubject) {
pushUnique(result, "resolve_entity_reference");
}
pushUnique(result, "fetch_scoped_documents");
pushUnique(result, "probe_coverage");
return result;
@@ -252,6 +260,8 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
const seededRankingNeed = toNonEmptyString(turnMeaning?.seeded_ranking_need);
const explicitDateScope = toNonEmptyString(turnMeaning?.explicit_date_scope);
const explicitOrganizationScope = toNonEmptyString(turnMeaning?.explicit_organization_scope);
const metadataScopeHint = toNonEmptyString(turnMeaning?.metadata_scope_hint);
const subjectResolutionOptional = turnMeaning?.subject_resolution_optional === true;
const subjectCandidates = (turnMeaning?.explicit_entity_candidates ?? [])
.map((item) => toNonEmptyString(item))
.filter((item) => Boolean(item));
@@ -275,6 +285,11 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
rankingNeed,
oneSidedOpenScopeTotalHint
});
const metadataScopedOpenLaneWithoutSubject = subjectCandidates.length === 0 &&
allowsMetadataScopedOpenLaneWithoutSubject({
family: businessFactFamily,
subjectResolutionOptional
});
const clarificationGaps = [];
if (unsupported === "metadata_lane_choice_clarification" || action === "resolve_next_lane") {
pushUnique(clarificationGaps, "lane_family_choice");
@@ -285,7 +300,15 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
!explicitOrganizationScope) {
pushUnique(clarificationGaps, "organization");
}
else if (subjectCandidates.length === 0 && businessFactFamily !== "schema_surface" && !openScopeWithoutSubject) {
else if (subjectCandidates.length === 0 &&
metadataScopedOpenLaneWithoutSubject &&
!explicitOrganizationScope) {
pushUnique(clarificationGaps, "organization");
}
else if (subjectCandidates.length === 0 &&
businessFactFamily !== "schema_surface" &&
!openScopeWithoutSubject &&
!metadataScopedOpenLaneWithoutSubject) {
pushUnique(clarificationGaps, "subject");
}
const timeScopeNeed = timeScopeNeedFor({
@@ -302,7 +325,8 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
aggregationNeed,
comparisonNeed,
rankingNeed,
openScopeWithoutSubject
openScopeWithoutSubject,
metadataScopedOpenLaneWithoutSubject
});
const reasonCodes = [];
pushReason(reasonCodes, "data_need_graph_built");
@@ -324,6 +348,9 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
if (openScopeWithoutSubject && !rankingNeed && !comparisonNeed) {
pushReason(reasonCodes, "data_need_graph_open_scope_total_without_subject");
}
if (metadataScopedOpenLaneWithoutSubject) {
pushReason(reasonCodes, "data_need_graph_metadata_scoped_open_lane_without_subject");
}
if (allTimeScopeHint) {
pushReason(reasonCodes, "data_need_graph_all_time_scope_hint");
}
@@ -337,6 +364,8 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
schema_version: exports.ASSISTANT_MCP_DISCOVERY_DATA_NEED_GRAPH_SCHEMA_VERSION,
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: subjectCandidates,
metadata_scope_hint: metadataScopeHint,
subject_resolution_optional: subjectResolutionOptional || undefined,
business_fact_family: businessFactFamily,
action_family: toNonEmptyString(turnMeaning?.asked_action_family),
aggregation_need: aggregationNeed,
@@ -41,6 +41,10 @@ function hasEntity(meaning) {
function hasSubjectCandidates(graph) {
return (graph?.subject_candidates.length ?? 0) > 0;
}
function hasMetadataScopedOpenLane(graph, meaning) {
return Boolean(graph?.subject_resolution_optional === true ||
meaning?.subject_resolution_optional === true);
}
function hasReasonCode(graph, reasonCode) {
return (graph?.reason_codes ?? []).includes(reasonCode);
}
@@ -58,6 +62,11 @@ function addScopeAxes(axes, meaning) {
pushUnique(axes, "period");
}
}
function addMetadataScopeAxis(axes, meaning) {
if (toNonEmptyString(meaning?.metadata_scope_hint)) {
pushUnique(axes, "metadata_scope");
}
}
function addTimeScopeAxes(axes, dataNeedGraph) {
if (dataNeedGraph?.time_scope_need === "all_time_scope") {
pushUnique(axes, "all_time_scope");
@@ -273,7 +282,7 @@ function recipeFor(input) {
const graphAction = lower(dataNeedGraph?.action_family);
const graphAggregation = lower(dataNeedGraph?.aggregation_need);
const graphClarificationGaps = (dataNeedGraph?.clarification_gaps ?? []).map((item) => lower(item));
const organizationScope = toNonEmptyString(meaning?.explicit_organization_scope);
const metadataScopedOpenLane = hasMetadataScopedOpenLane(dataNeedGraph, meaning);
const openScopeTotalWithoutSubject = graphFactFamily === "value_flow" &&
!hasSubjectCandidates(dataNeedGraph) &&
hasReasonCode(dataNeedGraph, "data_need_graph_open_scope_total_without_subject");
@@ -281,6 +290,7 @@ function recipeFor(input) {
const axes = [];
const requestedAggregationAxis = aggregationAxis(meaning);
addScopeAxes(axes, meaning);
addMetadataScopeAxis(axes, meaning);
addTimeScopeAxes(axes, dataNeedGraph);
if (graphClarificationGaps.includes("lane_family_choice")) {
pushUnique(axes, "lane_family_choice");
@@ -494,6 +504,26 @@ function recipeFor(input) {
};
}
if (graphFactFamily === "movement_evidence") {
if (metadataScopedOpenLane) {
pushUnique(axes, "organization");
pushUnique(axes, "coverage_target");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
fallbackPrimitives: ["query_movements", "probe_coverage"],
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action
});
return {
semanticDataNeed: "movement evidence",
chainId: "movement_evidence",
chainSummary: "Keep the metadata-scoped movement lane, ask only for the remaining business scope, then fetch scoped movement rows and probe coverage without pretending there is a grounded counterparty.",
primitives: primitiveSelection.primitives,
axes,
reason: "planner_selected_metadata_scoped_movement_from_data_need_graph",
extraReasons: primitiveSelection.reasonCodes
};
}
pushUnique(axes, "coverage_target");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
@@ -513,6 +543,26 @@ function recipeFor(input) {
};
}
if (graphFactFamily === "document_evidence") {
if (metadataScopedOpenLane) {
pushUnique(axes, "organization");
pushUnique(axes, "coverage_target");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
fallbackPrimitives: ["query_documents", "probe_coverage"],
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action
});
return {
semanticDataNeed: "document evidence",
chainId: "document_evidence",
chainSummary: "Keep the metadata-scoped document lane, ask only for the remaining business scope, then fetch scoped document rows and probe coverage without pretending there is a grounded counterparty.",
primitives: primitiveSelection.primitives,
axes,
reason: "planner_selected_metadata_scoped_document_from_data_need_graph",
extraReasons: primitiveSelection.reasonCodes
};
}
pushUnique(axes, "coverage_target");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
@@ -98,6 +98,11 @@ function buildLoopState(planner, pilot, bridgeStatus) {
pending_axes: plannerClarificationGaps.length > 0 ? plannerClarificationGaps : flattenAxes(pilot, "missing_axis_options"),
provided_axes: flattenAxes(pilot, "provided_axes"),
explicit_entity_candidates: entityCandidatesFromPlanner(planner),
metadata_scope_hint: planner.discovery_plan.turn_meaning_ref?.metadata_scope_hint ??
planner.data_need_graph?.metadata_scope_hint ??
null,
subject_resolution_optional: planner.discovery_plan.turn_meaning_ref?.subject_resolution_optional === true ||
planner.data_need_graph?.subject_resolution_optional === true,
explicit_organization_scope: planner.discovery_plan.turn_meaning_ref?.explicit_organization_scope ?? null,
explicit_date_scope: planner.discovery_plan.turn_meaning_ref?.explicit_date_scope ?? null
};
@@ -321,6 +321,8 @@ function collectFollowupDiscoverySeed(followupContext) {
const loopAskedDomainFamily = toNonEmptyString(followupContext?.previous_discovery_loop_asked_domain_family);
const loopAskedActionFamily = toNonEmptyString(followupContext?.previous_discovery_loop_asked_action_family);
const loopUnsupportedFamily = toNonEmptyString(followupContext?.previous_discovery_loop_unsupported_family);
const loopMetadataScopeHint = toNonEmptyString(followupContext?.previous_discovery_loop_metadata_scope_hint);
const loopSubjectResolutionOptional = followupContext?.previous_discovery_loop_subject_resolution_optional === true;
const previousIntent = toNonEmptyString(followupContext?.target_intent) ?? toNonEmptyString(followupContext?.previous_intent);
const loopMapped = loopStatus === "awaiting_clarification"
? mapLoopClarificationSeedToFollowupMeaning({
@@ -343,13 +345,16 @@ function collectFollowupDiscoverySeed(followupContext) {
const discoveryEntities = collectEntityCandidates(followupContext?.previous_discovery_entity_candidates);
const entityResolutionStatus = toNonEmptyString(followupContext?.previous_discovery_entity_resolution_status);
const entityResolutionAmbiguityCandidates = collectEntityCandidates(followupContext?.previous_discovery_entity_ambiguity_candidates);
const ambiguityBlocksImplicitGrounding = pilotScope === "entity_resolution_search_v1" && entityResolutionStatus === "ambiguous";
const ambiguityBlocksImplicitGrounding = effectivePilotScope === "entity_resolution_search_v1" && entityResolutionStatus === "ambiguous";
const metadataPilotCarriesScopeOnly = effectivePilotScope === "metadata_inspection_v1" || loopSubjectResolutionOptional;
const metadataScopeHint = loopMetadataScopeHint ??
(loopSubjectResolutionOptional ? discoveryEntities[0] ?? null : null);
const counterparty = toNonEmptyString(previousFilters?.counterparty) ??
toNonEmptyString(rootFilters?.counterparty) ??
(toNonEmptyString(followupContext?.previous_anchor_type) === "counterparty"
? toNonEmptyString(followupContext?.previous_anchor_value)
: null) ??
(ambiguityBlocksImplicitGrounding ? null : discoveryEntities[0] ?? null);
(ambiguityBlocksImplicitGrounding || metadataPilotCarriesScopeOnly ? null : discoveryEntities[0] ?? null);
const organization = toNonEmptyString(previousFilters?.organization) ??
toNonEmptyString(rootFilters?.organization) ??
(toNonEmptyString(followupContext?.previous_anchor_type) === "organization"
@@ -367,12 +372,14 @@ function collectFollowupDiscoverySeed(followupContext) {
loopPendingAxes,
loopProvidedAxes,
counterparty,
discoveryEntity: ambiguityBlocksImplicitGrounding ? null : discoveryEntities[0] ?? null,
discoveryEntity: ambiguityBlocksImplicitGrounding || loopSubjectResolutionOptional ? null : discoveryEntities[0] ?? null,
entityResolutionStatus,
entityResolutionAmbiguityCandidates,
rankingNeed: toNonEmptyString(followupContext?.previous_discovery_ranking_need),
organization,
dateScope,
metadataScopeHint,
subjectResolutionOptional: loopSubjectResolutionOptional,
metadataRouteFamily: normalizeMetadataRouteFamily(followupContext?.previous_discovery_metadata_route_family),
metadataRouteFamilySelectionBasis: normalizeMetadataRouteFamilySelectionBasis(followupContext?.previous_discovery_metadata_route_family_selection_basis),
metadataSelectedEntitySet: toNonEmptyString(followupContext?.previous_discovery_metadata_selected_entity_set),
@@ -793,10 +800,15 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
!rawLifecycleSignal &&
!rawValueFlowSignal &&
hasMetadataObjectHint(rawText));
const metadataLaneCarryoverAvailable = Boolean(followupSeed.counterparty ||
followupSeed.discoveryEntity ||
followupSeed.metadataScopeHint ||
followupSeed.metadataSelectedEntitySet ||
followupSeed.metadataSelectedSurfaceObjects.length > 0);
const metadataGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataRouteFamily === "document_evidence" &&
!followupSeed.metadataAmbiguityDetected &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataDocumentHintSignal);
@@ -804,21 +816,21 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
followupSeed.metadataAmbiguityDetected &&
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
metadataEntitySetsSuggestDocumentLane(followupSeed.metadataAmbiguityEntitySets)) &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
metadataDocumentHintSignal);
const metadataGroundedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataRouteFamily === "movement_evidence" &&
!followupSeed.metadataAmbiguityDetected &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
metadataMovementHintSignal);
const metadataAmbiguityResolvedMovementFollowupApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
(followupSeed.metadataAmbiguityEntitySets.length === 0 ||
metadataEntitySetsSuggestMovementLane(followupSeed.metadataAmbiguityEntitySets)) &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
metadataMovementHintSignal);
const entityResolutionGroundedDocumentFollowupApplicable = Boolean(followupSeed.pilotScope === "entity_resolution_search_v1" &&
@@ -886,7 +898,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
(followupSeed.metadataRouteFamily === "document_evidence" ||
followupSeed.metadataRouteFamily === "movement_evidence") &&
!followupSeed.metadataAmbiguityDetected &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
@@ -905,7 +917,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
const metadataAmbiguityCollapsedDocumentLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
@@ -915,7 +927,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
const metadataAmbiguityCollapsedMovementLaneContinuationApplicable = Boolean(followupSeed.pilotScope === "metadata_inspection_v1" &&
followupSeed.metadataAmbiguityDetected &&
metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
@@ -926,7 +938,7 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
followupSeed.metadataAmbiguityDetected &&
!metadataAmbiguityCollapsesToDocumentLane(followupSeed.metadataAmbiguityEntitySets) &&
!metadataAmbiguityCollapsesToMovementLane(followupSeed.metadataAmbiguityEntitySets) &&
followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
@@ -935,6 +947,14 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
hasMetadataDownstreamContinuationSignal(rawText));
const metadataGroundedDocumentLaneApplicable = metadataGroundedDocumentFollowupApplicable ||
metadataAmbiguityResolvedDocumentFollowupApplicable ||
(followupSeed.subjectResolutionOptional &&
!followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
followupSeed.domain === "documents" &&
followupSeed.action === "list_documents") ||
entityResolutionGroundedDocumentFollowupApplicable ||
entityResolutionClarifiedDocumentFollowupApplicable ||
valueFlowGroundedDocumentFollowupApplicable ||
@@ -943,6 +963,14 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
metadataAmbiguityCollapsedDocumentLaneContinuationApplicable;
const metadataGroundedMovementLaneApplicable = metadataGroundedMovementFollowupApplicable ||
metadataAmbiguityResolvedMovementFollowupApplicable ||
(followupSeed.subjectResolutionOptional &&
!followupSeed.counterparty &&
metadataLaneCarryoverAvailable &&
!rawLifecycleSignal &&
!rawValueFlowSignal &&
!rawMetadataSignal &&
followupSeed.domain === "movements" &&
followupSeed.action === "list_movements") ||
entityResolutionGroundedMovementFollowupApplicable ||
entityResolutionClarifiedMovementFollowupApplicable ||
valueFlowGroundedMovementFollowupApplicable ||
@@ -1009,7 +1037,17 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
!metadataGroundedDocumentLaneApplicable &&
!metadataGroundedMovementLaneApplicable
});
const groundedFollowupEntity = followupSeed.counterparty ?? followupSeed.discoveryEntity;
const metadataLaneScopeHint = rawMetadataScopeHint ??
followupSeed.metadataScopeHint ??
followupSeed.discoveryEntity ??
followupSeed.metadataSelectedEntitySet ??
null;
const metadataScopedLaneWithoutSubject = Boolean((metadataGroundedMovementLaneApplicable || metadataGroundedDocumentLaneApplicable) &&
!followupSeed.counterparty &&
metadataLaneCarryoverAvailable);
const groundedFollowupEntity = metadataScopedLaneWithoutSubject
? null
: followupSeed.counterparty ?? followupSeed.discoveryEntity;
const entityCandidates = entityResolutionSignal ? [] : [];
if (entityResolutionSignal) {
pushNormalizedEntityResolutionCandidate(entityCandidates, entityResolutionClarificationCandidate);
@@ -1030,11 +1068,15 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
pushScopedEntityCandidate(entityCandidates, normalizedPredecomposeCounterparty, groundedFollowupEntity);
if (!groundedFollowupEntity) {
pushScopedEntityCandidate(entityCandidates, followupSeed.counterparty, null);
pushScopedEntityCandidate(entityCandidates, followupSeed.discoveryEntity, null);
if (!metadataScopedLaneWithoutSubject) {
pushScopedEntityCandidate(entityCandidates, followupSeed.discoveryEntity, null);
}
}
pushScopedEntityCandidate(entityCandidates, rawEntityCandidate, groundedFollowupEntity);
}
if ((rawMetadataSignal || metadataFollowupSeedApplicable) && !groundedFollowupEntity) {
if ((rawMetadataSignal || metadataFollowupSeedApplicable) &&
!groundedFollowupEntity &&
!metadataScopedLaneWithoutSubject) {
pushUnique(entityCandidates, followupSeed.discoveryEntity);
pushUnique(entityCandidates, rawMetadataScopeHint);
}
@@ -1126,8 +1168,10 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
metadata_ambiguity_entity_sets: metadataAmbiguityLaneClarificationApplicable && followupSeed.metadataAmbiguityEntitySets.length > 0
? followupSeed.metadataAmbiguityEntitySets
: undefined,
metadata_scope_hint: metadataLaneScopeHint,
explicit_organization_scope: explicitOrganizationScope,
explicit_date_scope: explicitDateScope,
subject_resolution_optional: metadataScopedLaneWithoutSubject || undefined,
unsupported_but_understood_family: unsupported ??
(lifecycleSignal
? "counterparty_lifecycle"
@@ -1181,12 +1225,18 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
if ((turnMeaning.metadata_ambiguity_entity_sets?.length ?? 0) > 0) {
cleanTurnMeaning.metadata_ambiguity_entity_sets = turnMeaning.metadata_ambiguity_entity_sets;
}
if (toNonEmptyString(turnMeaning.metadata_scope_hint)) {
cleanTurnMeaning.metadata_scope_hint = turnMeaning.metadata_scope_hint;
}
if (toNonEmptyString(turnMeaning.explicit_organization_scope)) {
cleanTurnMeaning.explicit_organization_scope = turnMeaning.explicit_organization_scope;
}
if (toNonEmptyString(turnMeaning.explicit_date_scope)) {
cleanTurnMeaning.explicit_date_scope = turnMeaning.explicit_date_scope;
}
if (turnMeaning.subject_resolution_optional) {
cleanTurnMeaning.subject_resolution_optional = true;
}
if (toNonEmptyString(turnMeaning.unsupported_but_understood_family)) {
cleanTurnMeaning.unsupported_but_understood_family = turnMeaning.unsupported_but_understood_family;
}
@@ -1299,6 +1349,9 @@ function buildAssistantMcpDiscoveryTurnInput(input) {
if (metadataAmbiguityResolvedMovementFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_metadata_ambiguity_resolved_to_movement_lane");
}
if (metadataScopedLaneWithoutSubject) {
pushReason(reasonCodes, "mcp_discovery_metadata_scoped_lane_without_subject");
}
if (entityResolutionGroundedDocumentFollowupApplicable) {
pushReason(reasonCodes, "mcp_discovery_entity_resolution_grounded_document_followup");
}
@@ -515,6 +515,8 @@ function createAssistantTransitionPolicy(deps) {
const sourceDiscoveryLoopAskedDomainFamily = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopAskedDomainFamily)(carryoverSourceDebug, deps.toNonEmptyString);
const sourceDiscoveryLoopAskedActionFamily = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopAskedActionFamily)(carryoverSourceDebug, deps.toNonEmptyString);
const sourceDiscoveryLoopUnsupportedFamily = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopUnsupportedFamily)(carryoverSourceDebug, deps.toNonEmptyString);
const sourceDiscoveryLoopMetadataScopeHint = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopMetadataScopeHint)(carryoverSourceDebug, deps.toNonEmptyString);
const sourceDiscoveryLoopSubjectResolutionOptional = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopSubjectResolutionOptional)(carryoverSourceDebug);
const sourceDiscoveryRankingNeed = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryRankingNeed)(carryoverSourceDebug, deps.toNonEmptyString);
const sourceDiscoveryEntityAmbiguityCandidates = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryEntityAmbiguityCandidates)(carryoverSourceDebug, deps.toNonEmptyString);
const llmExplicitIntent = deps.toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
@@ -760,6 +762,8 @@ function createAssistantTransitionPolicy(deps) {
previous_discovery_loop_asked_domain_family: sourceDiscoveryLoopAskedDomainFamily ?? undefined,
previous_discovery_loop_asked_action_family: sourceDiscoveryLoopAskedActionFamily ?? undefined,
previous_discovery_loop_unsupported_family: sourceDiscoveryLoopUnsupportedFamily ?? undefined,
previous_discovery_loop_metadata_scope_hint: sourceDiscoveryLoopMetadataScopeHint ?? undefined,
previous_discovery_loop_subject_resolution_optional: sourceDiscoveryLoopSubjectResolutionOptional || undefined,
previous_discovery_ranking_need: sourceDiscoveryRankingNeed ?? undefined,
previous_discovery_entity_ambiguity_candidates: sourceDiscoveryEntityAmbiguityCandidates.length > 0
? sourceDiscoveryEntityAmbiguityCandidates