ARCH: замкнуть metadata-scoped clarification recovery loops
This commit is contained in:
@@ -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);
|
||||
|
||||
+33
-4
@@ -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
|
||||
};
|
||||
|
||||
+67
-14
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user