АРЧ АП11 - Вынести политику оркестрационной маршрутизации из assistantService в отдельный модуль
This commit is contained in:
@@ -0,0 +1,616 @@
|
||||
// @ts-nocheck
|
||||
const ADDRESS_INTENTS_KEEP_ADDRESS_LANE = new Set([
|
||||
"period_coverage_profile",
|
||||
"document_type_and_account_section_profile",
|
||||
"counterparty_population_and_roles",
|
||||
"counterparty_activity_lifecycle",
|
||||
"customer_revenue_and_payments",
|
||||
"supplier_payouts_profile",
|
||||
"open_contracts_confirmed_as_of_date",
|
||||
"list_open_contracts",
|
||||
"open_items_by_counterparty_or_contract",
|
||||
"list_payables_counterparties",
|
||||
"list_receivables_counterparties",
|
||||
"inventory_on_hand_as_of_date",
|
||||
"payables_confirmed_as_of_date",
|
||||
"receivables_confirmed_as_of_date",
|
||||
"list_documents_by_contract",
|
||||
"bank_operations_by_contract",
|
||||
"list_documents_by_counterparty",
|
||||
"bank_operations_by_counterparty",
|
||||
"list_contracts_by_counterparty",
|
||||
"inventory_purchase_provenance_for_item",
|
||||
"inventory_purchase_documents_for_item",
|
||||
"inventory_supplier_stock_overlap_as_of_date",
|
||||
"inventory_sale_trace_for_item",
|
||||
"inventory_profitability_for_item",
|
||||
"inventory_purchase_to_sale_chain",
|
||||
"inventory_aging_by_purchase_date",
|
||||
"contract_usage_overview",
|
||||
"contract_usage_and_value",
|
||||
"vat_payable_forecast",
|
||||
"vat_liability_confirmed_for_tax_period",
|
||||
"vat_payable_confirmed_as_of_date"
|
||||
]);
|
||||
const ADDRESS_INTENTS_ALLOW_STRICT_DEEP_INVESTIGATION_BYPASS = new Set([
|
||||
"inventory_purchase_provenance_for_item",
|
||||
"inventory_purchase_documents_for_item",
|
||||
"inventory_sale_trace_for_item",
|
||||
"inventory_profitability_for_item",
|
||||
"inventory_purchase_to_sale_chain"
|
||||
]);
|
||||
function shouldBypassStrictDeepInvestigationCueForAddressIntent(intent) {
|
||||
return Boolean(intent && ADDRESS_INTENTS_ALLOW_STRICT_DEEP_INVESTIGATION_BYPASS.has(intent));
|
||||
}
|
||||
export function createAssistantRoutePolicy(deps) {
|
||||
const {
|
||||
repairAddressMojibake,
|
||||
findLastGroundedAddressAnswerDebug,
|
||||
findLastOrganizationClarificationAddressDebug,
|
||||
mergeKnownOrganizations,
|
||||
normalizeOrganizationScopeValue,
|
||||
resolveOrganizationSelectionFromMessage,
|
||||
hasAssistantDataScopeMetaQuestionSignal,
|
||||
shouldHandleAsAssistantCapabilityMetaQuery,
|
||||
hasDataRetrievalRequestSignal,
|
||||
hasAggregateBusinessAnalyticsSignal,
|
||||
hasStandaloneAddressTopicSignal,
|
||||
hasOpenContractsAddressSignal,
|
||||
detectAddressQuestionMode,
|
||||
resolveAddressIntent,
|
||||
toNonEmptyString,
|
||||
hasStrictDeepInvestigationCue,
|
||||
hasStrongDataIntentSignal,
|
||||
hasAccountingSignal,
|
||||
hasDangerOrCoercionSignal,
|
||||
hasAddressFollowupContextSignal,
|
||||
hasShortDebtMirrorFollowupSignal,
|
||||
isInventorySelectedObjectIntent,
|
||||
hasShortInventoryObjectFollowupSignal,
|
||||
hasHistoricalCapabilityFollowupSignal,
|
||||
isGroundedInventoryContextDebug,
|
||||
hasConversationMemoryRecallFollowupSignal,
|
||||
findLastAddressAssistantItem,
|
||||
hasMetaAnswerFollowupSignal,
|
||||
resolveAddressToolGateDecision,
|
||||
hasSameDateAccountFollowupSignalForPredecompose,
|
||||
hasLooseAllTimeAddressLookupSignal,
|
||||
hasDeepAnalysisPreferenceSignal,
|
||||
hasDirectDeepAnalysisSignal,
|
||||
compactWhitespace,
|
||||
hasDeepSessionContinuationSignal,
|
||||
resolveLivingAssistantModeDecision
|
||||
} = deps;
|
||||
function resolveAssistantOrchestrationDecision(input) {
|
||||
const rawUserMessage = String(input?.rawUserMessage ?? input?.userMessage ?? "");
|
||||
const effectiveAddressUserMessage = String(input?.effectiveAddressUserMessage ?? rawUserMessage);
|
||||
const repairedRawUserMessage = repairAddressMojibake(rawUserMessage);
|
||||
const repairedEffectiveAddressUserMessage = repairAddressMojibake(effectiveAddressUserMessage);
|
||||
const followupContext = input?.followupContext ?? null;
|
||||
const llmPreDecomposeMeta = input?.llmPreDecomposeMeta ?? null;
|
||||
const useMock = Boolean(input?.useMock);
|
||||
const sessionItems = Array.isArray(input?.sessionItems) ? input.sessionItems : null;
|
||||
const sessionOrganizationScope = input?.sessionOrganizationScope && typeof input.sessionOrganizationScope === "object"
|
||||
? input.sessionOrganizationScope
|
||||
: null;
|
||||
const lastGroundedAddressDebug = findLastGroundedAddressAnswerDebug(sessionItems);
|
||||
const lastOrganizationClarificationDebug = findLastOrganizationClarificationAddressDebug(sessionItems);
|
||||
const organizationClarificationCandidates = Array.isArray(lastOrganizationClarificationDebug?.organization_candidates)
|
||||
? mergeKnownOrganizations([
|
||||
...lastOrganizationClarificationDebug.organization_candidates,
|
||||
...((Array.isArray(sessionOrganizationScope?.knownOrganizations)
|
||||
? sessionOrganizationScope.knownOrganizations
|
||||
: []))
|
||||
])
|
||||
: [];
|
||||
const organizationClarificationSelectionFromScope = normalizeOrganizationScopeValue(sessionOrganizationScope?.selectedOrganization);
|
||||
const organizationClarificationSelection = resolveOrganizationSelectionFromMessage(rawUserMessage, organizationClarificationCandidates) ??
|
||||
resolveOrganizationSelectionFromMessage(repairedRawUserMessage, organizationClarificationCandidates) ??
|
||||
resolveOrganizationSelectionFromMessage(effectiveAddressUserMessage, organizationClarificationCandidates) ??
|
||||
resolveOrganizationSelectionFromMessage(repairedEffectiveAddressUserMessage, organizationClarificationCandidates) ??
|
||||
(organizationClarificationSelectionFromScope &&
|
||||
organizationClarificationCandidates.some((candidate) => normalizeOrganizationScopeValue(candidate) === organizationClarificationSelectionFromScope)
|
||||
? organizationClarificationSelectionFromScope
|
||||
: null);
|
||||
const dataScopeMetaQuery = hasAssistantDataScopeMetaQuestionSignal(rawUserMessage) ||
|
||||
hasAssistantDataScopeMetaQuestionSignal(repairedRawUserMessage) ||
|
||||
hasAssistantDataScopeMetaQuestionSignal(effectiveAddressUserMessage) ||
|
||||
hasAssistantDataScopeMetaQuestionSignal(repairedEffectiveAddressUserMessage);
|
||||
const capabilityMetaQuery = shouldHandleAsAssistantCapabilityMetaQuery(rawUserMessage) ||
|
||||
shouldHandleAsAssistantCapabilityMetaQuery(repairedRawUserMessage) ||
|
||||
shouldHandleAsAssistantCapabilityMetaQuery(effectiveAddressUserMessage) ||
|
||||
shouldHandleAsAssistantCapabilityMetaQuery(repairedEffectiveAddressUserMessage);
|
||||
const dataRetrievalSignal = hasDataRetrievalRequestSignal(rawUserMessage) ||
|
||||
hasDataRetrievalRequestSignal(repairedRawUserMessage) ||
|
||||
hasDataRetrievalRequestSignal(effectiveAddressUserMessage) ||
|
||||
hasDataRetrievalRequestSignal(repairedEffectiveAddressUserMessage);
|
||||
const aggregateBusinessAnalyticsSignal = hasAggregateBusinessAnalyticsSignal(rawUserMessage) ||
|
||||
hasAggregateBusinessAnalyticsSignal(repairedRawUserMessage) ||
|
||||
hasAggregateBusinessAnalyticsSignal(effectiveAddressUserMessage) ||
|
||||
hasAggregateBusinessAnalyticsSignal(repairedEffectiveAddressUserMessage);
|
||||
const standaloneAddressTopicSignal = hasStandaloneAddressTopicSignal(rawUserMessage) ||
|
||||
hasStandaloneAddressTopicSignal(repairedRawUserMessage) ||
|
||||
hasStandaloneAddressTopicSignal(effectiveAddressUserMessage) ||
|
||||
hasStandaloneAddressTopicSignal(repairedEffectiveAddressUserMessage);
|
||||
const openContractsAddressSignal = hasOpenContractsAddressSignal(rawUserMessage) ||
|
||||
hasOpenContractsAddressSignal(repairedRawUserMessage) ||
|
||||
hasOpenContractsAddressSignal(effectiveAddressUserMessage) ||
|
||||
hasOpenContractsAddressSignal(repairedEffectiveAddressUserMessage);
|
||||
const modeSample = repairedEffectiveAddressUserMessage || effectiveAddressUserMessage;
|
||||
const modeDetection = detectAddressQuestionMode(modeSample);
|
||||
const modeDetectionRaw = detectAddressQuestionMode(repairedRawUserMessage || rawUserMessage);
|
||||
const resolvedModeDetection = modeDetection.mode === "address_query" ? modeDetection : modeDetectionRaw;
|
||||
const intentResolution = resolveAddressIntent(modeSample);
|
||||
const intentResolutionRaw = resolveAddressIntent(repairedRawUserMessage || rawUserMessage);
|
||||
const resolvedIntentResolution = intentResolution.intent !== "unknown" ? intentResolution : intentResolutionRaw;
|
||||
const llmContractIntent = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.intent);
|
||||
const llmPreDecomposeReason = toNonEmptyString(llmPreDecomposeMeta?.reason);
|
||||
const llmRuntimeUnavailableDetected = Boolean(llmPreDecomposeReason &&
|
||||
/(?:openai\s+api\s+key\s+is\s+missing|api\s+key\s+is\s+missing|missing\s+api\s+key|authentication)/iu.test(llmPreDecomposeReason));
|
||||
const semanticExtractionContract = llmPreDecomposeMeta?.semanticExtractionContract &&
|
||||
typeof llmPreDecomposeMeta.semanticExtractionContract === "object"
|
||||
? llmPreDecomposeMeta.semanticExtractionContract
|
||||
: null;
|
||||
const semanticContractValid = semanticExtractionContract?.valid !== false;
|
||||
const semanticApplyCanonicalRecommended = semanticExtractionContract?.apply_canonical_recommended !== false;
|
||||
const semanticReasonCodes = Array.isArray(semanticExtractionContract?.reason_codes)
|
||||
? semanticExtractionContract.reason_codes
|
||||
: [];
|
||||
const strictDeepInvestigationCueDetected = hasStrictDeepInvestigationCue(rawUserMessage) ||
|
||||
hasStrictDeepInvestigationCue(repairedRawUserMessage) ||
|
||||
hasStrictDeepInvestigationCue(effectiveAddressUserMessage) ||
|
||||
hasStrictDeepInvestigationCue(repairedEffectiveAddressUserMessage);
|
||||
const strictDeepInvestigationBypassAllowed = shouldBypassStrictDeepInvestigationCueForAddressIntent(resolvedIntentResolution.intent) ||
|
||||
shouldBypassStrictDeepInvestigationCueForAddressIntent(llmContractIntent);
|
||||
const keepAddressLaneByIntent = semanticApplyCanonicalRecommended &&
|
||||
Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) ||
|
||||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
|
||||
openContractsAddressSignal) &&
|
||||
(!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed);
|
||||
const strongDataSignal = hasStrongDataIntentSignal(rawUserMessage) ||
|
||||
hasStrongDataIntentSignal(repairedRawUserMessage) ||
|
||||
hasStrongDataIntentSignal(effectiveAddressUserMessage) ||
|
||||
hasStrongDataIntentSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasAccountingSignal(rawUserMessage) ||
|
||||
hasAccountingSignal(repairedRawUserMessage) ||
|
||||
hasAccountingSignal(effectiveAddressUserMessage) ||
|
||||
hasAccountingSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasDataRetrievalRequestSignal(rawUserMessage) ||
|
||||
hasDataRetrievalRequestSignal(repairedRawUserMessage);
|
||||
const llmContractMode = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.mode);
|
||||
const llmFirstAddressCandidate = Boolean(llmContractMode === "address_query" && llmContractIntent && llmContractIntent !== "unknown");
|
||||
const llmFirstUnsupportedCandidate = Boolean(llmContractMode === "unsupported" &&
|
||||
(!llmContractIntent || llmContractIntent === "unknown"));
|
||||
const dangerOrCoercionSignal = hasDangerOrCoercionSignal(rawUserMessage) ||
|
||||
hasDangerOrCoercionSignal(repairedRawUserMessage) ||
|
||||
hasDangerOrCoercionSignal(effectiveAddressUserMessage) ||
|
||||
hasDangerOrCoercionSignal(repairedEffectiveAddressUserMessage);
|
||||
const explicitAddressFollowupSignal = hasAddressFollowupContextSignal(rawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedRawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(effectiveAddressUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(rawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage);
|
||||
const protectedInventoryShortFollowup = Boolean(followupContext &&
|
||||
isInventorySelectedObjectIntent(toNonEmptyString(followupContext.previous_intent)) &&
|
||||
(hasShortInventoryObjectFollowupSignal(rawUserMessage) ||
|
||||
hasShortInventoryObjectFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortInventoryObjectFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasShortInventoryObjectFollowupSignal(repairedEffectiveAddressUserMessage)));
|
||||
const organizationClarificationContinuationDetected = Boolean(followupContext &&
|
||||
lastOrganizationClarificationDebug &&
|
||||
organizationClarificationSelection &&
|
||||
!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
!dataRetrievalSignal);
|
||||
const effectiveAddressFollowupSignal = explicitAddressFollowupSignal && !dangerOrCoercionSignal;
|
||||
const deterministicNonDomainGuard = Boolean(!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
!dataRetrievalSignal &&
|
||||
!effectiveAddressFollowupSignal &&
|
||||
resolvedModeDetection.mode === "unsupported" &&
|
||||
resolvedIntentResolution.intent === "unknown");
|
||||
const nonDomainQueryIndexed = Boolean(!llmFirstAddressCandidate &&
|
||||
deterministicNonDomainGuard &&
|
||||
(llmFirstUnsupportedCandidate || llmContractMode === null) &&
|
||||
!protectedInventoryShortFollowup &&
|
||||
!organizationClarificationContinuationDetected);
|
||||
const contextualHistoricalCapabilityFollowupDetected = Boolean(capabilityMetaQuery &&
|
||||
!dataScopeMetaQuery &&
|
||||
!dataRetrievalSignal &&
|
||||
(hasHistoricalCapabilityFollowupSignal(rawUserMessage) ||
|
||||
hasHistoricalCapabilityFollowupSignal(repairedRawUserMessage) ||
|
||||
hasHistoricalCapabilityFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasHistoricalCapabilityFollowupSignal(repairedEffectiveAddressUserMessage)) &&
|
||||
isGroundedInventoryContextDebug(lastGroundedAddressDebug));
|
||||
const contextualMemoryRecapFollowupDetected = Boolean(!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
!dataRetrievalSignal &&
|
||||
!strongDataSignal &&
|
||||
!aggregateBusinessAnalyticsSignal &&
|
||||
(hasConversationMemoryRecallFollowupSignal(rawUserMessage) ||
|
||||
hasConversationMemoryRecallFollowupSignal(repairedRawUserMessage) ||
|
||||
hasConversationMemoryRecallFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasConversationMemoryRecallFollowupSignal(repairedEffectiveAddressUserMessage)) &&
|
||||
(lastGroundedAddressDebug ||
|
||||
findLastAddressAssistantItem(sessionItems)?.debug));
|
||||
const hardMetaMode = dataScopeMetaQuery
|
||||
? "data_scope"
|
||||
: capabilityMetaQuery && !dataRetrievalSignal
|
||||
? "capability"
|
||||
: null;
|
||||
if (hardMetaMode === "data_scope") {
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "assistant_data_scope_query_detected",
|
||||
livingMode: "chat",
|
||||
livingReason: "assistant_data_scope_query_detected",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "data_scope",
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "assistant_data_scope_query_detected",
|
||||
living_mode: "chat",
|
||||
living_reason: "assistant_data_scope_query_detected"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if (hardMetaMode === "capability") {
|
||||
if (contextualHistoricalCapabilityFollowupDetected) {
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "inventory_history_capability_followup_detected",
|
||||
livingMode: "chat",
|
||||
livingReason: "inventory_history_capability_followup_detected",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "capability",
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug),
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "inventory_history_capability_followup_detected",
|
||||
living_mode: "chat",
|
||||
living_reason: "inventory_history_capability_followup_detected"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "assistant_capability_query_detected",
|
||||
livingMode: "chat",
|
||||
livingReason: "assistant_capability_query_detected",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "capability",
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "assistant_capability_query_detected",
|
||||
living_mode: "chat",
|
||||
living_reason: "assistant_capability_query_detected"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if (nonDomainQueryIndexed) {
|
||||
if (contextualMemoryRecapFollowupDetected) {
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "memory_recap_followup_detected",
|
||||
livingMode: "chat",
|
||||
livingReason: "memory_recap_followup_detected",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "non_domain",
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug),
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "memory_recap_followup_detected",
|
||||
living_mode: "chat",
|
||||
living_reason: "memory_recap_followup_detected"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
runAddressLane: false,
|
||||
toolGateDecision: "skip_address_lane",
|
||||
toolGateReason: "non_domain_query_indexed",
|
||||
livingMode: "chat",
|
||||
livingReason: "non_domain_query_indexed",
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: "non_domain",
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
unsupported_address_intent_fallback_to_deep: false,
|
||||
final_decision: {
|
||||
run_address_lane: false,
|
||||
tool_gate_decision: "skip_address_lane",
|
||||
tool_gate_reason: "non_domain_query_indexed",
|
||||
living_mode: "chat",
|
||||
living_reason: "non_domain_query_indexed"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const metaAnswerFollowupSignal = hasMetaAnswerFollowupSignal(rawUserMessage) ||
|
||||
hasMetaAnswerFollowupSignal(repairedRawUserMessage) ||
|
||||
hasMetaAnswerFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasMetaAnswerFollowupSignal(repairedEffectiveAddressUserMessage);
|
||||
const baseToolGate = resolveAddressToolGateDecision(effectiveAddressUserMessage, followupContext, llmPreDecomposeMeta, rawUserMessage);
|
||||
const preserveAddressLaneSignal = Boolean((llmPreDecomposeMeta?.llmCanonicalCandidateDetected &&
|
||||
llmPreDecomposeMeta?.applied &&
|
||||
llmContractMode === "address_query") ||
|
||||
hasSameDateAccountFollowupSignalForPredecompose(rawUserMessage) ||
|
||||
hasSameDateAccountFollowupSignalForPredecompose(effectiveAddressUserMessage) ||
|
||||
hasSameDateAccountFollowupSignalForPredecompose(repairedRawUserMessage) ||
|
||||
hasSameDateAccountFollowupSignalForPredecompose(repairedEffectiveAddressUserMessage) ||
|
||||
hasLooseAllTimeAddressLookupSignal(rawUserMessage) ||
|
||||
hasLooseAllTimeAddressLookupSignal(effectiveAddressUserMessage) ||
|
||||
hasLooseAllTimeAddressLookupSignal(repairedRawUserMessage) ||
|
||||
hasLooseAllTimeAddressLookupSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasAddressFollowupContextSignal(rawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(effectiveAddressUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedRawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(rawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage));
|
||||
const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) &&
|
||||
Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) ||
|
||||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
|
||||
openContractsAddressSignal);
|
||||
const semanticGuardHints = semanticExtractionContract?.guard_hints &&
|
||||
typeof semanticExtractionContract.guard_hints === "object"
|
||||
? semanticExtractionContract.guard_hints
|
||||
: null;
|
||||
const semanticExtraction = semanticExtractionContract?.extraction &&
|
||||
typeof semanticExtractionContract.extraction === "object"
|
||||
? semanticExtractionContract.extraction
|
||||
: null;
|
||||
const semanticDeepInvestigationHintDetected = semanticGuardHints?.deep_investigation_signal_detected === true;
|
||||
const semanticAggregateShapeDetected = semanticExtraction?.query_shape === "AGGREGATE_LOOKUP" ||
|
||||
semanticExtraction?.aggregation_profile === "management_profile";
|
||||
const rootContextOnlyFollowup = Boolean(followupContext && followupContext.root_context_only === true);
|
||||
const followupSemanticOverrideToDeepAllowed = Boolean(followupContext &&
|
||||
!supportedAddressIntentDetected &&
|
||||
(rootContextOnlyFollowup ||
|
||||
llmContractMode === "unsupported" ||
|
||||
semanticAggregateShapeDetected ||
|
||||
semanticDeepInvestigationHintDetected ||
|
||||
!semanticApplyCanonicalRecommended));
|
||||
const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") ||
|
||||
llmContractMode === "unsupported" ||
|
||||
(rootContextOnlyFollowup &&
|
||||
resolvedIntentResolution.intent === "unknown" &&
|
||||
(!llmContractIntent || llmContractIntent === "unknown"));
|
||||
const unsupportedAddressIntentFallbackToDeep = Boolean(baseToolGate?.runAddressLane &&
|
||||
!llmRuntimeUnavailableDetected &&
|
||||
unsupportedIntentOrMode &&
|
||||
strongDataSignal &&
|
||||
(rootContextOnlyFollowup ||
|
||||
llmContractMode === "deep_analysis" ||
|
||||
!dataRetrievalSignal ||
|
||||
strictDeepInvestigationCueDetected ||
|
||||
semanticDeepInvestigationHintDetected ||
|
||||
aggregateBusinessAnalyticsSignal) &&
|
||||
!preserveAddressLaneSignal &&
|
||||
!keepAddressLaneByIntent &&
|
||||
!supportedAddressIntentDetected &&
|
||||
(!followupContext || followupSemanticOverrideToDeepAllowed));
|
||||
const deepAnalysisPreferenceDetected = Boolean(hasDeepAnalysisPreferenceSignal(rawUserMessage) ||
|
||||
hasDeepAnalysisPreferenceSignal(repairedRawUserMessage) ||
|
||||
hasDeepAnalysisPreferenceSignal(effectiveAddressUserMessage) ||
|
||||
hasDeepAnalysisPreferenceSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasDirectDeepAnalysisSignal(rawUserMessage) ||
|
||||
hasDirectDeepAnalysisSignal(repairedRawUserMessage) ||
|
||||
hasDirectDeepAnalysisSignal(effectiveAddressUserMessage) ||
|
||||
hasDirectDeepAnalysisSignal(repairedEffectiveAddressUserMessage));
|
||||
const vatExplainFollowupSignal = Boolean(followupContext &&
|
||||
toNonEmptyString(followupContext.previous_intent) === "vat_payable_forecast" &&
|
||||
/(?:\u043f\u043e\u0447\u0435\u043c\u0443|why).*(?:\u043f\u0440\u043e\u0433\u043d\u043e\u0437|forecast).*(?:\u0443\u043f\u043b\u0430\u0442|payable|\b0\b)/iu.test(compactWhitespace(`${repairedRawUserMessage} ${repairedEffectiveAddressUserMessage}`)));
|
||||
const vatEvaluativeFollowupSignal = Boolean(followupContext &&
|
||||
toNonEmptyString(followupContext.previous_intent) === "vat_payable_forecast" &&
|
||||
/(?:^|\s)(?:это\s+)?много\s+или\s+мало(?:\?|$)|(?:^|\s)(?:это\s+)?нормально(?:\?|$)|(?:^|\s)(?:это\s+)?плохо(?:\?|$)|(?:^|\s)(?:это\s+)?хорошо(?:\?|$)/iu.test(compactWhitespace(`${repairedRawUserMessage} ${repairedEffectiveAddressUserMessage}`)));
|
||||
const deepAnalysisSignalFallbackToDeep = Boolean(baseToolGate?.runAddressLane &&
|
||||
!llmRuntimeUnavailableDetected &&
|
||||
(deepAnalysisPreferenceDetected || semanticDeepInvestigationHintDetected) &&
|
||||
!keepAddressLaneByIntent &&
|
||||
!supportedAddressIntentDetected &&
|
||||
!vatExplainFollowupSignal &&
|
||||
(!followupContext || !dataRetrievalSignal || followupSemanticOverrideToDeepAllowed));
|
||||
const aggregateAnalyticsFallbackToDeep = Boolean(baseToolGate?.runAddressLane &&
|
||||
!llmRuntimeUnavailableDetected &&
|
||||
aggregateBusinessAnalyticsSignal &&
|
||||
!keepAddressLaneByIntent &&
|
||||
!supportedAddressIntentDetected &&
|
||||
(!followupContext ||
|
||||
llmContractMode === "unsupported" ||
|
||||
semanticAggregateShapeDetected ||
|
||||
!semanticApplyCanonicalRecommended ||
|
||||
standaloneAddressTopicSignal));
|
||||
const deepSessionContinuationFallbackToDeep = Boolean(!followupContext &&
|
||||
baseToolGate?.runAddressLane &&
|
||||
!llmRuntimeUnavailableDetected &&
|
||||
hasDeepSessionContinuationSignal({
|
||||
rawUserMessage,
|
||||
repairedRawUserMessage,
|
||||
effectiveAddressUserMessage,
|
||||
repairedEffectiveAddressUserMessage,
|
||||
sessionItems
|
||||
}));
|
||||
const hasPriorAddressAnswerContext = Boolean(lastGroundedAddressDebug || toNonEmptyString(followupContext?.previous_intent));
|
||||
const metaFollowupOverGroundedAnswer = Boolean(followupContext &&
|
||||
hasPriorAddressAnswerContext &&
|
||||
(metaAnswerFollowupSignal || vatEvaluativeFollowupSignal) &&
|
||||
!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
!aggregateBusinessAnalyticsSignal &&
|
||||
!dataRetrievalSignal &&
|
||||
!strongDataSignal &&
|
||||
resolvedModeDetection.mode !== "address_query" &&
|
||||
resolvedIntentResolution.intent === "unknown" &&
|
||||
(!llmContractIntent || llmContractIntent === "unknown") &&
|
||||
llmContractMode !== "address_query");
|
||||
let runAddressLane = Boolean(baseToolGate?.runAddressLane);
|
||||
let toolGateDecision = String(baseToolGate?.decision ?? "skip_address_lane");
|
||||
let toolGateReason = String(baseToolGate?.reason ?? "no_address_signal_after_l0");
|
||||
if (unsupportedAddressIntentFallbackToDeep) {
|
||||
runAddressLane = false;
|
||||
toolGateDecision = "skip_address_lane";
|
||||
toolGateReason = "address_signal_unsupported_intent_fallback_to_deep";
|
||||
}
|
||||
if (deepAnalysisSignalFallbackToDeep && !unsupportedAddressIntentFallbackToDeep) {
|
||||
runAddressLane = false;
|
||||
toolGateDecision = "skip_address_lane";
|
||||
toolGateReason = "deep_analysis_signal_fallback_to_deep";
|
||||
}
|
||||
if (aggregateAnalyticsFallbackToDeep &&
|
||||
!unsupportedAddressIntentFallbackToDeep &&
|
||||
!deepAnalysisSignalFallbackToDeep) {
|
||||
runAddressLane = false;
|
||||
toolGateDecision = "skip_address_lane";
|
||||
toolGateReason = "aggregate_analytics_signal_fallback_to_deep";
|
||||
}
|
||||
if (deepSessionContinuationFallbackToDeep) {
|
||||
runAddressLane = false;
|
||||
toolGateDecision = "skip_address_lane";
|
||||
toolGateReason = "deep_session_continuation_fallback_to_deep";
|
||||
}
|
||||
if (metaFollowupOverGroundedAnswer) {
|
||||
runAddressLane = false;
|
||||
toolGateDecision = "skip_address_lane";
|
||||
toolGateReason = "meta_followup_over_grounded_answer";
|
||||
}
|
||||
let livingDecision = resolveLivingAssistantModeDecision({
|
||||
userMessage: rawUserMessage,
|
||||
addressLaneTriggered: runAddressLane,
|
||||
useMock,
|
||||
predecomposeMode: llmPreDecomposeMeta?.predecomposeContract?.mode ?? null,
|
||||
predecomposeModeConfidence: llmPreDecomposeMeta?.predecomposeContract?.mode_confidence ?? null
|
||||
});
|
||||
if (unsupportedAddressIntentFallbackToDeep) {
|
||||
livingDecision = {
|
||||
mode: "deep_analysis",
|
||||
reason: "unsupported_address_intent_fallback_to_deep"
|
||||
};
|
||||
}
|
||||
if (deepAnalysisSignalFallbackToDeep && !unsupportedAddressIntentFallbackToDeep) {
|
||||
livingDecision = {
|
||||
mode: "deep_analysis",
|
||||
reason: "deep_analysis_signal_fallback_to_deep"
|
||||
};
|
||||
}
|
||||
if (aggregateAnalyticsFallbackToDeep &&
|
||||
!unsupportedAddressIntentFallbackToDeep &&
|
||||
!deepAnalysisSignalFallbackToDeep) {
|
||||
livingDecision = {
|
||||
mode: "deep_analysis",
|
||||
reason: "aggregate_analytics_signal_fallback_to_deep"
|
||||
};
|
||||
}
|
||||
if (deepSessionContinuationFallbackToDeep) {
|
||||
livingDecision = {
|
||||
mode: "deep_analysis",
|
||||
reason: "deep_session_continuation_fallback_to_deep"
|
||||
};
|
||||
}
|
||||
if (metaFollowupOverGroundedAnswer) {
|
||||
livingDecision = {
|
||||
mode: "chat",
|
||||
reason: "meta_followup_over_grounded_answer"
|
||||
};
|
||||
}
|
||||
return {
|
||||
runAddressLane,
|
||||
toolGateDecision,
|
||||
toolGateReason,
|
||||
livingMode: livingDecision.mode,
|
||||
livingReason: livingDecision.reason,
|
||||
orchestrationContract: {
|
||||
schema_version: "assistant_orchestration_contract_v1",
|
||||
hard_meta_mode: null,
|
||||
address_mode: resolvedModeDetection.mode,
|
||||
address_mode_confidence: resolvedModeDetection.confidence,
|
||||
address_intent: resolvedIntentResolution.intent,
|
||||
address_intent_confidence: resolvedIntentResolution.confidence,
|
||||
strong_data_signal_detected: strongDataSignal,
|
||||
data_retrieval_signal_detected: dataRetrievalSignal,
|
||||
semantic_contract_valid: semanticContractValid,
|
||||
semantic_apply_canonical_recommended: semanticApplyCanonicalRecommended,
|
||||
semantic_reason_codes: semanticReasonCodes,
|
||||
semantic_route_arbitration: {
|
||||
supported_address_intent_detected: supportedAddressIntentDetected,
|
||||
strict_deep_investigation_bypass_allowed: strictDeepInvestigationBypassAllowed,
|
||||
semantic_deep_investigation_hint_detected: semanticDeepInvestigationHintDetected,
|
||||
semantic_aggregate_shape_detected: semanticAggregateShapeDetected,
|
||||
followup_semantic_override_to_deep_allowed: followupSemanticOverrideToDeepAllowed
|
||||
},
|
||||
followup_context_detected: Boolean(followupContext),
|
||||
unsupported_address_intent_fallback_to_deep: unsupportedAddressIntentFallbackToDeep,
|
||||
deep_analysis_signal_fallback_to_deep: deepAnalysisSignalFallbackToDeep,
|
||||
aggregate_analytics_signal_fallback_to_deep: aggregateAnalyticsFallbackToDeep,
|
||||
deep_session_continuation_fallback_to_deep: deepSessionContinuationFallbackToDeep,
|
||||
final_decision: {
|
||||
run_address_lane: runAddressLane,
|
||||
tool_gate_decision: toolGateDecision,
|
||||
tool_gate_reason: toolGateReason,
|
||||
living_mode: livingDecision.mode,
|
||||
living_reason: livingDecision.reason
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
resolveAssistantOrchestrationDecision
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user