Закрепить phase83 carryover и движения ассистента
This commit is contained in:
@@ -12,6 +12,7 @@ exports.readAssistantMcpDiscoveryLoopProvidedAxes = readAssistantMcpDiscoveryLoo
|
||||
exports.readAssistantMcpDiscoveryLoopAskedDomainFamily = readAssistantMcpDiscoveryLoopAskedDomainFamily;
|
||||
exports.readAssistantMcpDiscoveryLoopAskedActionFamily = readAssistantMcpDiscoveryLoopAskedActionFamily;
|
||||
exports.readAssistantMcpDiscoveryLoopUnsupportedFamily = readAssistantMcpDiscoveryLoopUnsupportedFamily;
|
||||
exports.readAssistantMcpDiscoveryLoopExplicitDateScope = readAssistantMcpDiscoveryLoopExplicitDateScope;
|
||||
exports.readAssistantMcpDiscoveryLoopMetadataScopeHint = readAssistantMcpDiscoveryLoopMetadataScopeHint;
|
||||
exports.readAssistantMcpDiscoveryLoopSubjectResolutionOptional = readAssistantMcpDiscoveryLoopSubjectResolutionOptional;
|
||||
exports.readAssistantMcpDiscoveryMetadataRouteFamily = readAssistantMcpDiscoveryMetadataRouteFamily;
|
||||
@@ -197,6 +198,11 @@ function readAssistantMcpDiscoveryLoopAskedActionFamily(debug, toNonEmptyString
|
||||
function readAssistantMcpDiscoveryLoopUnsupportedFamily(debug, toNonEmptyString = fallbackToNonEmptyString) {
|
||||
return toNonEmptyString(readAssistantMcpDiscoveryLoopState(debug)?.unsupported_but_understood_family);
|
||||
}
|
||||
function readAssistantMcpDiscoveryLoopExplicitDateScope(debug, toNonEmptyString = fallbackToNonEmptyString) {
|
||||
return (toNonEmptyString(readAssistantMcpDiscoveryLoopState(debug)?.explicit_date_scope) ??
|
||||
toNonEmptyString(readAssistantMcpDiscoveryTurnMeaning(debug)?.explicit_date_scope) ??
|
||||
toNonEmptyString(readAssistantMcpDiscoveryDataNeedGraph(debug)?.explicit_date_scope));
|
||||
}
|
||||
function readAssistantMcpDiscoveryLoopMetadataScopeHint(debug, toNonEmptyString = fallbackToNonEmptyString) {
|
||||
return (toNonEmptyString(readAssistantMcpDiscoveryLoopState(debug)?.metadata_scope_hint) ??
|
||||
toNonEmptyString(readAssistantMcpDiscoveryTurnMeaning(debug)?.metadata_scope_hint) ??
|
||||
|
||||
+152
-9
@@ -239,6 +239,26 @@ function isOpenScopeValueFlowRanking(entryPoint) {
|
||||
const subjectCandidates = Array.isArray(graph?.subject_candidates) ? graph.subject_candidates : [];
|
||||
return businessFactFamily === "value_flow" && subjectCandidates.length === 0 && Boolean(toNonEmptyString(graph?.ranking_need));
|
||||
}
|
||||
function readDiscoverySelectedChainId(entryPoint) {
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const pilot = toRecordObject(bridge?.pilot);
|
||||
const routeCandidate = toRecordObject(bridge?.route_candidate);
|
||||
return (toNonEmptyString(routeCandidate?.selected_chain_id) ??
|
||||
toNonEmptyString(bridge?.selected_chain_id) ??
|
||||
toNonEmptyString(pilot?.selected_chain_id));
|
||||
}
|
||||
function isValueFlowRankingDiscoveryTurn(entryPoint) {
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const routeCandidate = toRecordObject(bridge?.route_candidate);
|
||||
const selectedChainId = readDiscoverySelectedChainId(entryPoint);
|
||||
const graphReasonCodes = readStringArray(graph?.reason_codes);
|
||||
return Boolean(toNonEmptyString(graph?.business_fact_family) === "value_flow" &&
|
||||
(selectedChainId === "value_flow_ranking" ||
|
||||
toNonEmptyString(routeCandidate?.nearest_catalog_chain_template) === "value_flow_ranking" ||
|
||||
toNonEmptyString(graph?.ranking_need) === "top_desc" ||
|
||||
graphReasonCodes.includes("data_need_graph_ranking_top_desc")));
|
||||
}
|
||||
function readTruthAnswerShape(input) {
|
||||
const directShape = toRecordObject(input.addressRuntimeMeta?.answer_shape_contract);
|
||||
if (directShape) {
|
||||
@@ -296,6 +316,54 @@ function hasDiscoveryClarificationCandidatePriorityOverCurrentClarification(inpu
|
||||
capabilityId?.includes("inventory_")));
|
||||
return asksForMovements && staleInventoryItemClarification;
|
||||
}
|
||||
function hasGroundedMovementCandidatePriorityOverCurrentInventoryItemClarification(input, entryPoint, candidate) {
|
||||
if (!hasCurrentClarificationRequiredAddressReply(input)) {
|
||||
return false;
|
||||
}
|
||||
if (candidate.candidate_status !== "ready_for_guarded_use") {
|
||||
return false;
|
||||
}
|
||||
if (!candidate.eligible_for_future_hot_runtime || !toNonEmptyString(candidate.reply_text)) {
|
||||
return false;
|
||||
}
|
||||
if (candidate.reply_text && hasInternalMechanics(candidate.reply_text)) {
|
||||
return false;
|
||||
}
|
||||
if (!isDiscoveryReadyAddressCandidate(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
const turnMeaning = readDiscoveryTurnMeaning(entryPoint);
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const pilot = toRecordObject(bridge?.pilot);
|
||||
const handoff = toRecordObject(bridge?.execution_handoff);
|
||||
const selectedChainId = readDiscoverySelectedChainId(entryPoint);
|
||||
const discoveryFamily = toNonEmptyString(graph?.business_fact_family);
|
||||
const askedDomain = toNonEmptyString(turnMeaning?.asked_domain_family);
|
||||
const askedAction = toNonEmptyString(turnMeaning?.asked_action_family) ?? toNonEmptyString(graph?.action_family);
|
||||
const asksForMovements = Boolean(selectedChainId === "movement_evidence" ||
|
||||
discoveryFamily === "movement_evidence" ||
|
||||
askedDomain === "movements" ||
|
||||
askedAction === "list_movements");
|
||||
const truthAnswerShape = readTruthAnswerShape(input);
|
||||
const detectedIntent = toNonEmptyString(input.addressRuntimeMeta?.detected_intent);
|
||||
const selectedRecipe = toNonEmptyString(input.addressRuntimeMeta?.selected_recipe);
|
||||
const capabilityId = toNonEmptyString(input.addressRuntimeMeta?.capability_id) ??
|
||||
toNonEmptyString(input.addressRuntimeMeta?.capability_contract_id) ??
|
||||
toNonEmptyString(truthAnswerShape?.capability_contract_id);
|
||||
const missingFilters = [
|
||||
...readStringArray(input.addressRuntimeMeta?.missing_required_filters),
|
||||
...readStringArray(input.addressRuntimeMeta?.missing_anchors),
|
||||
...readStringArray(toRecordObject(input.addressRuntimeMeta?.capability_binding_contract)?.missing_anchors)
|
||||
];
|
||||
const staleInventoryItemClarification = Boolean(missingFilters.includes("item") &&
|
||||
(detectedIntent?.startsWith("inventory_") ||
|
||||
selectedRecipe?.includes("inventory_") ||
|
||||
capabilityId?.includes("inventory_")));
|
||||
const mcpExecutionPerformed = handoff?.mcp_execution_performed === true || pilot?.mcp_execution_performed === true;
|
||||
const boundedMovementAnswerAllowed = bridge?.user_facing_response_allowed === true && bridge?.business_fact_answer_allowed === true;
|
||||
return asksForMovements && staleInventoryItemClarification && mcpExecutionPerformed && boundedMovementAnswerAllowed;
|
||||
}
|
||||
function hasGroundedValueFlowCandidatePriorityOverCurrentClarification(input, entryPoint, candidate) {
|
||||
if (!hasCurrentClarificationRequiredAddressReply(input)) {
|
||||
return false;
|
||||
@@ -313,10 +381,7 @@ function hasGroundedValueFlowCandidatePriorityOverCurrentClarification(input, en
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const pilot = toRecordObject(bridge?.pilot);
|
||||
const handoff = toRecordObject(bridge?.execution_handoff);
|
||||
const routeCandidate = toRecordObject(bridge?.route_candidate);
|
||||
const selectedChainId = toNonEmptyString(routeCandidate?.selected_chain_id) ??
|
||||
toNonEmptyString(bridge?.selected_chain_id) ??
|
||||
toNonEmptyString(pilot?.selected_chain_id);
|
||||
const selectedChainId = readDiscoverySelectedChainId(entryPoint);
|
||||
const pilotScope = toNonEmptyString(pilot?.pilot_scope);
|
||||
const actionFamily = toNonEmptyString(graph?.action_family);
|
||||
const comparisonNeed = toNonEmptyString(graph?.comparison_need);
|
||||
@@ -329,6 +394,70 @@ function hasGroundedValueFlowCandidatePriorityOverCurrentClarification(input, en
|
||||
(handoff?.can_use_guarded_response === true || toNonEmptyString(bridge?.bridge_status) === "answer_draft_ready");
|
||||
return valueFlowComparison && mcpExecutionPerformed && guardedBusinessAnswerAllowed;
|
||||
}
|
||||
function hasCounterpartyRankingQuestionSignal(entryPoint) {
|
||||
const graph = readDiscoveryDataNeedGraph(entryPoint);
|
||||
const turnMeaning = readDiscoveryTurnMeaning(entryPoint);
|
||||
const rawMessage = toNonEmptyString(turnMeaning?.raw_message) ?? "";
|
||||
const effectiveMessage = toNonEmptyString(turnMeaning?.effective_message) ?? "";
|
||||
const askedDomain = toNonEmptyString(turnMeaning?.asked_domain_family);
|
||||
const askedAction = toNonEmptyString(turnMeaning?.asked_action_family);
|
||||
const text = `${rawMessage}\n${effectiveMessage}`.toLowerCase();
|
||||
return Boolean(isValueFlowRankingDiscoveryTurn(entryPoint) &&
|
||||
(askedDomain === "counterparty_value" || askedDomain === "counterparty") &&
|
||||
(askedAction === "turnover" || askedAction === "counterparty_value_or_turnover") &&
|
||||
(/\bкто\b/u.test(text) ||
|
||||
text.includes("контрагент") ||
|
||||
text.includes("клиент") ||
|
||||
text.includes("покупател") ||
|
||||
text.includes("заказчик") ||
|
||||
text.includes("принес") ||
|
||||
text.includes("принёс") ||
|
||||
text.includes("больше всего") ||
|
||||
toNonEmptyString(graph?.ranking_need) === "top_desc"));
|
||||
}
|
||||
function hasWrongPeriodRankingCurrentReply(input) {
|
||||
const currentReply = String(input.currentReply ?? "").toLowerCase();
|
||||
return (currentReply.includes("самый доходный год") ||
|
||||
currentReply.includes("топ-1 лет") ||
|
||||
currentReply.includes("топ-5 лет") ||
|
||||
currentReply.includes("топ-10 лет") ||
|
||||
/топ-\d+\s+лет/u.test(currentReply) ||
|
||||
currentReply.includes("лет по сумме поступлений") ||
|
||||
currentReply.includes("год по подтвержденным поступлениям"));
|
||||
}
|
||||
function hasConfirmedValueFlowRankingEvidence(entryPoint) {
|
||||
const bridge = toRecordObject(entryPoint?.bridge);
|
||||
const pilot = toRecordObject(bridge?.pilot);
|
||||
const handoff = toRecordObject(bridge?.execution_handoff);
|
||||
const evidence = toRecordObject(pilot?.evidence);
|
||||
const confirmedFacts = readStringArray(evidence?.confirmed_facts);
|
||||
const mcpExecutionPerformed = handoff?.mcp_execution_performed === true || pilot?.mcp_execution_performed === true;
|
||||
const businessAnswerAllowed = bridge?.user_facing_response_allowed === true && bridge?.business_fact_answer_allowed === true;
|
||||
const confirmedRankingEvidence = Boolean(toNonEmptyString(evidence?.evidence_status) === "confirmed" ||
|
||||
toNonEmptyString(evidence?.answer_permission) === "confirmed_answer" ||
|
||||
confirmedFacts.some((fact) => /ranked by counterparty|рейтинг.*контрагент/iu.test(fact)));
|
||||
return mcpExecutionPerformed && businessAnswerAllowed && confirmedRankingEvidence;
|
||||
}
|
||||
function hasGroundedValueFlowRankingCandidatePriorityOverCurrentExactReply(input, entryPoint, candidate) {
|
||||
if (candidate.candidate_status !== "ready_for_guarded_use") {
|
||||
return false;
|
||||
}
|
||||
if (!candidate.eligible_for_future_hot_runtime || !toNonEmptyString(candidate.reply_text)) {
|
||||
return false;
|
||||
}
|
||||
if (candidate.reply_text && hasInternalMechanics(candidate.reply_text)) {
|
||||
return false;
|
||||
}
|
||||
if (!isDiscoveryReadyAddressCandidate(input, entryPoint)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasEffectivelyFactualAddressReply(input)) {
|
||||
return false;
|
||||
}
|
||||
return Boolean(hasCounterpartyRankingQuestionSignal(entryPoint) &&
|
||||
hasWrongPeriodRankingCurrentReply(input) &&
|
||||
hasConfirmedValueFlowRankingEvidence(entryPoint));
|
||||
}
|
||||
function hasEffectivelyFactualAddressReply(input) {
|
||||
if (toNonEmptyString(input.currentReplyType) === "factual") {
|
||||
return true;
|
||||
@@ -804,9 +933,17 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
const currentClarificationRequiredAddressReply = hasCurrentClarificationRequiredAddressReply(input);
|
||||
const discoveryClarificationCandidatePriority = hasDiscoveryClarificationCandidatePriorityOverCurrentClarification(input, entryPoint, candidate);
|
||||
const groundedValueFlowCandidatePriority = hasGroundedValueFlowCandidatePriorityOverCurrentClarification(input, entryPoint, candidate);
|
||||
const groundedMovementCandidatePriority = hasGroundedMovementCandidatePriorityOverCurrentInventoryItemClarification(input, entryPoint, candidate);
|
||||
const groundedValueFlowRankingCandidatePriority = hasGroundedValueFlowRankingCandidatePriorityOverCurrentExactReply(input, entryPoint, candidate);
|
||||
const currentClarificationProtectsCurrentReply = currentClarificationRequiredAddressReply &&
|
||||
!discoveryClarificationCandidatePriority &&
|
||||
!groundedValueFlowCandidatePriority;
|
||||
!groundedValueFlowCandidatePriority &&
|
||||
!groundedMovementCandidatePriority &&
|
||||
!groundedValueFlowRankingCandidatePriority;
|
||||
const alignedFactualAddressReplyProtectsCurrent = alignedFactualAddressReply && !groundedValueFlowRankingCandidatePriority;
|
||||
const matchedFactualAddressContinuationTargetProtectsCurrent = matchedFactualAddressContinuationTarget && !groundedValueFlowRankingCandidatePriority;
|
||||
const fullConfirmedFactualAddressReplyProtectsCurrent = fullConfirmedFactualAddressReply && !groundedValueFlowRankingCandidatePriority;
|
||||
const exactMatchedFactualAddressReplyProtectsCurrent = exactMatchedFactualAddressReply && !groundedValueFlowRankingCandidatePriority;
|
||||
const exactBankOperationsProtectsCurrent = exactBankOperationsAddressReply &&
|
||||
!semanticConflictWithDiscoveryTurnMeaning &&
|
||||
!valueFlowActionConflictWithDiscoveryTurnMeaning;
|
||||
@@ -849,6 +986,12 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
if (groundedValueFlowCandidatePriority) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_grounded_value_flow_candidate_priority_over_current_clarification");
|
||||
}
|
||||
if (groundedMovementCandidatePriority) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_grounded_movement_candidate_priority_over_inventory_item_clarification");
|
||||
}
|
||||
if (groundedValueFlowRankingCandidatePriority) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_grounded_value_flow_ranking_candidate_priority_over_current_exact_reply");
|
||||
}
|
||||
if (openScopeValueFlowDiscoveryPriority) {
|
||||
pushReason(reasonCodes, "mcp_discovery_response_policy_open_scope_value_flow_candidate_priority");
|
||||
}
|
||||
@@ -911,11 +1054,11 @@ function applyAssistantMcpDiscoveryResponsePolicy(input) {
|
||||
}
|
||||
const canApply = Boolean(entryPoint) &&
|
||||
(unsupportedBoundary || discoveryReadyChatCandidate || discoveryReadyDeepCandidate || discoveryReadyAddressCandidate) &&
|
||||
!alignedFactualAddressReply &&
|
||||
!matchedFactualAddressContinuationTarget &&
|
||||
!alignedFactualAddressReplyProtectsCurrent &&
|
||||
!matchedFactualAddressContinuationTargetProtectsCurrent &&
|
||||
!matchedFactualSuggestedIntentPivotTarget &&
|
||||
!fullConfirmedFactualAddressReply &&
|
||||
!exactMatchedFactualAddressReply &&
|
||||
!fullConfirmedFactualAddressReplyProtectsCurrent &&
|
||||
!exactMatchedFactualAddressReplyProtectsCurrent &&
|
||||
!runtimeAdjustedExactReply &&
|
||||
!runtimeMatchedExactReply &&
|
||||
!staleMetadataDiscoveryFallbackAgainstExactAddressReply &&
|
||||
|
||||
+2
-1
@@ -541,6 +541,7 @@ 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 loopExplicitDateScope = toNonEmptyString(followupContext?.previous_discovery_loop_explicit_date_scope);
|
||||
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);
|
||||
@@ -592,7 +593,7 @@ function collectFollowupDiscoverySeed(followupContext) {
|
||||
const loopProvidedAllTimeScope = loopProvidedAxes.includes("all_time_scope");
|
||||
const dateScope = loopProvidedAllTimeScope
|
||||
? "all_time_scope"
|
||||
: collectDateScopeFromFilters(previousFilters) ?? collectDateScopeFromFilters(rootFilters);
|
||||
: loopExplicitDateScope ?? collectDateScopeFromFilters(previousFilters) ?? collectDateScopeFromFilters(rootFilters);
|
||||
return {
|
||||
pilotScope: effectivePilotScope,
|
||||
domain: mapped.domain,
|
||||
|
||||
@@ -1011,6 +1011,7 @@ 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 sourceDiscoveryLoopExplicitDateScope = (0, assistantContinuityPolicy_1.readAssistantMcpDiscoveryLoopExplicitDateScope)(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);
|
||||
@@ -1346,6 +1347,7 @@ 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_explicit_date_scope: sourceDiscoveryLoopExplicitDateScope ?? undefined,
|
||||
previous_discovery_loop_metadata_scope_hint: sourceDiscoveryLoopMetadataScopeHint ?? undefined,
|
||||
previous_discovery_loop_subject_resolution_optional: sourceDiscoveryLoopSubjectResolutionOptional || undefined,
|
||||
previous_discovery_ranking_need: sourceDiscoveryRankingNeed ?? undefined,
|
||||
|
||||
Reference in New Issue
Block a user