ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - fix(router): keep llm-first non-domain indexing and prevent followup force into address lane

This commit is contained in:
2026-04-12 17:29:35 +03:00
parent 143cf6efe1
commit a717ea6b26
5 changed files with 358 additions and 44 deletions
@@ -3750,6 +3750,28 @@ export function resolveAssistantOrchestrationDecision(input) {
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);
const effectiveAddressFollowupSignal = explicitAddressFollowupSignal && !dangerOrCoercionSignal;
const deterministicNonDomainGuard = Boolean(!dataScopeMetaQuery &&
!capabilityMetaQuery &&
!dataRetrievalSignal &&
!effectiveAddressFollowupSignal &&
modeDetection.mode === "unsupported" &&
intentResolution.intent === "unknown");
const nonDomainQueryIndexed = Boolean(!llmFirstAddressCandidate &&
deterministicNonDomainGuard &&
(llmFirstUnsupportedCandidate || llmContractMode === null));
const hardMetaMode = dataScopeMetaQuery
? "data_scope"
: capabilityMetaQuery && !dataRetrievalSignal
@@ -3811,8 +3833,35 @@ export function resolveAssistantOrchestrationDecision(input) {
}
};
}
if (nonDomainQueryIndexed) {
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: modeDetection.mode,
address_mode_confidence: modeDetection.confidence,
address_intent: intentResolution.intent,
address_intent_confidence: intentResolution.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 baseToolGate = resolveAddressToolGateDecision(effectiveAddressUserMessage, followupContext, llmPreDecomposeMeta, rawUserMessage);
const llmContractMode = toNonEmptyString(llmPreDecomposeMeta?.predecomposeContract?.mode);
const preserveAddressLaneSignal = Boolean((llmPreDecomposeMeta?.llmCanonicalCandidateDetected &&
llmPreDecomposeMeta?.applied &&
llmContractMode === "address_query") ||
@@ -4118,11 +4167,11 @@ function hasOperationalAdminActionRequestSignal(text) {
return /(?:удаляй?\s+баз|удали\s+баз|снеси\s+баз|delete\s+database|drop\s+database)/i.test(normalized);
}
function hasDangerOrCoercionSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase()).replace(/ё/g, "е");
if (!lower) {
const normalized = compactWhitespace(String(text ?? "").toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
return /(?:убьют|убьют|убью|убить|убиют|угрож|опасн|омон|полици|насили|заставля|принужда|шантаж)/i.test(lower);
return /(?:убью|убить|убьют|убиют|угрож|опасн|омон|полици|насили|заставля|принужда|шантаж|выпил(?:юсь|иться|ился|илась|иться)|суицид|самоубий|покончу\s+с\s+собой|не\s+хочу\s+жить|хочу\s+умереть|сдохнуть|вскрыть\s+вены|повешусь|повеситься|спрыгну|kill\s+myself|end\s+my\s+life|suicid|self[\s-]?harm)/iu.test(normalized);
}
function hasDestructiveDataActionSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase()).replace(/ё/g, "е");
@@ -4240,6 +4289,9 @@ function hasLivingChatSignal(text) {
if (!lower) {
return false;
}
if (/^(?:а\s+)?(?:тут|здесь|там|сюда|туда)[\s!?.,:;\-]*$/iu.test(lower)) {
return true;
}
if (/^(ага|угу|ок|окей|ясно|понял|поняла|принято|спасибо|благодарю|супер|класс|норм|го|давай|погнали|привет|хай|йо|yo|че\s+там|ч[её]\s+как|че\s+как|hello|hi|thanks?)$/i.test(lower)) {
return true;
}