АРЧ АП11 - Оркестрация: дожать агентный прогон по выбору компании и возрасту активности в 1С

This commit is contained in:
2026-04-17 16:40:08 +03:00
parent 7be037e225
commit cd0b78d1de
31 changed files with 1909 additions and 1187 deletions
@@ -54,6 +54,8 @@ export function createAssistantRoutePolicy(deps) {
resolveHardMetaMode,
isMetaFollowupOverGroundedAnswer,
hasDataRetrievalRequestSignal,
hasOrganizationFactLookupSignal,
hasOrganizationFactFollowupSignal,
hasAggregateBusinessAnalyticsSignal,
hasStandaloneAddressTopicSignal,
hasOpenContractsAddressSignal,
@@ -81,6 +83,18 @@ export function createAssistantRoutePolicy(deps) {
resolveLivingAssistantModeDecision,
resolveProviderExecutionState
} = deps;
function hasInventoryRootRestatementFollowupSignal(text) {
const normalized = compactWhitespace(repairAddressMojibake(String(text ?? "")).toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (!/(?:остатк(?:и|ов|ами|ах)?|на\s+складе|склад(?:е|у|ом)?)/iu.test(normalized)) {
return false;
}
const hasRequestCue = /(?:покажи|показать|выведи|список|какие|что\s+по|че\s+по|чё\s+по|тогда\s+покажи)/iu.test(normalized);
const hasTemporalCue = /(?:на\s+эту\s+же\s+дат[ауеы]|на\s+тот\s+же\s+период|за\s+этот\s+же\s+период|за\s+этот\s+период|март|апрел|ма[йя]|июн|июл|август|сентябр|октябр|ноябр|декабр|\b(?:19|20)\d{2}\b)/iu.test(normalized);
return hasRequestCue && hasTemporalCue;
}
function resolveAssistantOrchestrationDecision(input) {
const rawUserMessage = String(input?.rawUserMessage ?? input?.userMessage ?? "");
const effectiveAddressUserMessage = String(input?.effectiveAddressUserMessage ?? rawUserMessage);
@@ -246,6 +260,24 @@ export function createAssistantRoutePolicy(deps) {
});
const contextualHistoricalCapabilityFollowupDetected = memorySignals.contextualHistoricalCapabilityFollowupDetected;
const contextualMemoryRecapFollowupDetected = memorySignals.contextualMemoryRecapFollowupDetected;
const organizationFactLookupDetected = hasOrganizationFactLookupSignal(rawUserMessage) ||
hasOrganizationFactLookupSignal(repairedRawUserMessage) ||
hasOrganizationFactLookupSignal(effectiveAddressUserMessage) ||
hasOrganizationFactLookupSignal(repairedEffectiveAddressUserMessage);
const previousIntent = toNonEmptyString(followupContext?.previous_intent);
const rootContextOnlyFollowup = Boolean(followupContext && followupContext.root_context_only === true);
const inventoryRootRestatementFollowupDetected = Boolean(followupContext &&
(previousIntent === "inventory_on_hand_as_of_date" ||
previousIntent === "inventory_supplier_stock_overlap_as_of_date" ||
rootContextOnlyFollowup) &&
(hasInventoryRootRestatementFollowupSignal(rawUserMessage) ||
hasInventoryRootRestatementFollowupSignal(repairedRawUserMessage) ||
hasInventoryRootRestatementFollowupSignal(effectiveAddressUserMessage) ||
hasInventoryRootRestatementFollowupSignal(repairedEffectiveAddressUserMessage)));
const organizationFactBoundaryFollowupDetected = hasOrganizationFactFollowupSignal(rawUserMessage, sessionItems ?? []) ||
hasOrganizationFactFollowupSignal(repairedRawUserMessage, sessionItems ?? []) ||
hasOrganizationFactFollowupSignal(effectiveAddressUserMessage, sessionItems ?? []) ||
hasOrganizationFactFollowupSignal(repairedEffectiveAddressUserMessage, sessionItems ?? []);
const hardMetaMode = resolveHardMetaMode({
dataScopeMetaQuery,
capabilityMetaQuery,
@@ -367,6 +399,35 @@ export function createAssistantRoutePolicy(deps) {
}
};
}
if (organizationFactLookupDetected || organizationFactBoundaryFollowupDetected) {
return {
runAddressLane: false,
toolGateDecision: "skip_address_lane",
toolGateReason: "organization_fact_lookup_signal_detected",
livingMode: "chat",
livingReason: "organization_fact_lookup_signal_detected",
orchestrationContract: {
schema_version: "assistant_orchestration_contract_v1",
hard_meta_mode: null,
provider_execution: providerExecution,
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 || organizationFactBoundaryFollowupDetected),
unsupported_address_intent_fallback_to_deep: false,
final_decision: {
run_address_lane: false,
tool_gate_decision: "skip_address_lane",
tool_gate_reason: "organization_fact_lookup_signal_detected",
living_mode: "chat",
living_reason: "organization_fact_lookup_signal_detected"
}
}
};
}
if (nonDomainQueryIndexed) {
return {
runAddressLane: false,
@@ -416,7 +477,8 @@ export function createAssistantRoutePolicy(deps) {
hasShortDebtMirrorFollowupSignal(rawUserMessage) ||
hasShortDebtMirrorFollowupSignal(effectiveAddressUserMessage) ||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage));
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage) ||
inventoryRootRestatementFollowupDetected);
const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) &&
Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) ||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
@@ -432,7 +494,6 @@ export function createAssistantRoutePolicy(deps) {
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 ||