АРЧ АП11 - Вынести политику оркестрационной маршрутизации из assistantService в отдельный модуль

This commit is contained in:
dctouch 2026-04-16 09:47:26 +03:00
parent 606654641b
commit f1333c457e
8 changed files with 2283 additions and 1688 deletions

View File

@ -0,0 +1,333 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAssistantLivingModePolicy = createAssistantLivingModePolicy;
function createAssistantLivingModePolicy(deps) {
const { featureAssistantLivingChatRouterV1, compactWhitespace, repairAddressMojibake, toNonEmptyString, normalizeOrganizationScopeValue, hasReferentialPointer, hasSmallTalkSignal, hasAssistantCapabilityQuestionSignal, hasOperationalAdminActionRequestSignal } = deps;
function hasStrongDataIntentSignal(text) {
const lower = String(text ?? "").toLowerCase();
return /(база|док|документ|проводк|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|оборот|баланс|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|mcp|bank|counterparty|contract|document|ledger|posting|account|organization|company|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм)/i.test(lower);
}
function hasDataRetrievalRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
if (!lower) {
return false;
}
const hasBroadInterrogative = /(?:\u0433\u0434\u0435|\u0432\s+\u043a\u0430\u043a\u0438\u0445|\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c|\u043f\u043e\s+\u043a\u043e\u043c\u0443|\u043a\u0430\u043a\u0438\u0435|\u043a\u0430\u043a\u043e\u0439|\u043a\u0442\u043e|\u0441\u043a\u043e\u043b\u044c\u043a\u043e|where|which|who|how\s+many)/iu.test(lower);
const hasBroadBusinessObject = /(?:\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0433\u043e\u0434|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b|advance|prepay|shipment|receivab|payab|counterparty|contract|document|account|balance|turnover|warehouse|inventory|stock|item)/iu.test(lower);
if (hasBroadInterrogative && hasBroadBusinessObject) {
return true;
}
const hasRussianRetrievalAction = /(?:^|\s)(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c|\u043d\u0430\u0439\u0434\u0438|\u0432\u044b\u0432\u0435\u0434\u0438|\u0434\u0430\u0439|\u0440\u0430\u0441\u043a\u0440\u043e\u0439|\u0441\u043f\u0438\u0441\u043e\u043a|\u043f\u0440\u043e\u0432\u0435\u0440\u044c|\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c)(?:$|[\s,.!?;:])/iu.test(lower);
const hasRussianRetrievalObject = /(?:\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0441\u0442\u0430\u0442|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043e\u043f\u0435\u0440\u0430\u0446|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043a\u043b\u0438\u0435\u043d\u0442|\u0433\u043e\u0434|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b)/iu.test(lower);
if (hasRussianRetrievalAction && hasRussianRetrievalObject) {
return true;
}
const hasExplicitRetrievalAction = /(?:\bпокажи\b|\bпоказать\b|\bвыведи\b|\bнайди\b|\bсписок\b|\bдай\b|\bраскрой\b|\bshow\b|\blist\b|\bfind\b|\bcount\b)/i.test(lower);
const hasInterrogativeRetrievalAction = /(?:\bсколько\b|\bкакой\b|\bкакая\b|\bкакое\b|\bкакую\b|\bкакие\b|\bкто\b|\bгде\b|\bпо\s+каким\b|\bпо\s+кому\b|\bу\s+кого\b|\bwhich\b|\bwho\b|\bwhere\b)/i.test(lower);
if (!hasExplicitRetrievalAction && !hasInterrogativeRetrievalAction) {
return false;
}
const hasRetrievalObject = /(1с|база|док|документ|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|bank|counterparty|contract|document|account|balance|ledger|posting|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм|возраст|дата\s+регистрац|регистрац|основан)/i.test(lower);
if (!hasRetrievalObject) {
return false;
}
if (hasExplicitRetrievalAction) {
return true;
}
const hasMetaCapabilityShape = /(?:мож(?:ем|ешь|ете|но)|уме(?:ешь|ете)|доступ|подключ|чья|как\s+называ(?:ет|ется)|работ(?:ать|аем|аешь|аете)|в\s+тебе|у\s+тебя)/i.test(lower);
return !hasMetaCapabilityShape;
}
function hasOrganizationFactLookupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasFactCue = /(?:возраст|сколько\s+лет|дата\s+регистрац|когда\s+(?:зарегистр|создан|основан)|год\s+регистрац|год\s+основан|с\s+какого\s+года|when\s+was\s+(?:it\s+)?(?:registered|founded|created))/i.test(normalized);
if (!hasFactCue) {
return false;
}
return /(?:организац|компан|контор|фирм|ооо|ао|зао|ип|альтернатив|лайсвуд|райм|organization|company)/i.test(normalized);
}
function findLastAssistantLivingChatDebug(items) {
if (!Array.isArray(items)) {
return null;
}
for (let index = items.length - 1; index >= 0; index -= 1) {
const item = items[index];
if (!item || item.role !== "assistant") {
continue;
}
if (item.debug && typeof item.debug === "object") {
return item.debug;
}
}
return null;
}
function hasMetaAnswerFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasReflectionCue = samples.some((sample) => sample.includes("дума") ||
sample.includes("скаж") ||
sample.includes("мнение") ||
sample.includes("как тебе") ||
sample.includes("норм") ||
sample.includes("стран") ||
sample.includes("логич") ||
sample.includes("смуща") ||
sample.includes("выгляд"));
const hasTopicPointerCue = samples.some((sample) => sample.includes("на эту тему") ||
sample.includes("по этому поводу") ||
sample.includes("об этом") ||
(sample.includes("это") && hasReferentialPointer(sample)));
const hasEvaluationCue = samples.some((sample) => /\b(?:много|мало|нормально|хорошо|плохо|критично|перебор|слабо)\b/iu.test(sample));
if (!((hasReflectionCue || hasEvaluationCue) &&
(hasTopicPointerCue || (hasEvaluationCue && samples.some((sample) => /^(?:это|ну это)\b/iu.test(sample)))))) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
}
function hasConversationMemoryRecallFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample));
const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample));
if (!hasMemoryCue || !hasDiscussionCue) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
}
function hasHistoricalCapabilityFollowupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasHistoryCue = /(?:историческ|история|архив|прошл(?:ый|ые|ую|ых)?|раньше|ретро|старые\s+данные)/iu.test(normalized);
if (!hasHistoryCue) {
return false;
}
return /(?:мож(?:ешь|ете|но)|уме(?:ешь|ете)|показ|вывед|дай|раскрой)/iu.test(normalized);
}
function hasOrganizationFactFollowupSignal(userMessage, items) {
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized)) {
return false;
}
const hasFollowupCue = /(?:^|\s)(?:давай|го|погнали|ок(?:ей)?|хорошо|принято|подтверждаю|запрашивай|запроси|проверь|продолжай|ну\s+давай|да\s+давай)(?=$|[\s,.!?;:])/iu.test(normalized);
if (!hasFollowupCue) {
return false;
}
const lastDebug = findLastAssistantLivingChatDebug(items);
const lastSource = toNonEmptyString(lastDebug?.living_chat_response_source);
const lastGuardReason = toNonEmptyString(lastDebug?.living_chat_grounding_guard_reason);
const inOrganizationFactBoundary = lastSource === "deterministic_organization_fact_boundary" ||
lastSource === "deterministic_organization_fact_boundary_followup" ||
lastGuardReason === "organization_fact_without_live_source_blocked";
return inOrganizationFactBoundary;
}
function shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization) {
const selected = normalizeOrganizationScopeValue(selectedOrganization);
if (!selected) {
return false;
}
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized) || hasDataRetrievalRequestSignal(normalized) || hasStrongDataIntentSignal(normalized)) {
return false;
}
const hasAnalyticalCue = /(?:какой|какая|какие|когда|сколько|кто|почему|зачем|возраст|дата|регистрац|ндс|налог|контракт|договор|документ|операц|оборот|сумм|остат|сальдо|founded|registered|created)/i.test(normalized);
if (hasAnalyticalCue) {
return false;
}
const hasSelectionCue = /(?:давай|го|погнали|ок(?:ей)?|хорошо|отлично|берем|выберем|выбираем|переключ(?:им|аем|ай)|фиксир|работаем|обсудим|тогда)\b/i.test(normalized);
if (hasSelectionCue) {
return true;
}
const hasAffectiveReactionCue = /(?:^|[\s,.;:!?()\-])(?:ну|мда|ох|ах|офигеть|офигенно|ахуеть|охуеть|пиздец|пизда|нихуя|хуево|хуёво|ебать|ебан|бля|блять|fuck|shit|damn)(?=$|[\s,.;:!?()\-])/iu.test(normalized) ||
normalized.includes("\u0430\u0445\u0443") ||
normalized.includes("\u043e\u0445\u0443") ||
normalized.includes("\u043f\u0438\u0437\u0434") ||
normalized.includes("\u0431\u043b\u044f");
if (hasAffectiveReactionCue) {
return false;
}
return normalized.length <= 36 && !/[?]/.test(String(userMessage ?? ""));
}
function hasAssistantDataScopeMetaQuestionSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const lower = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
const normalized = lower.replace(/\b1\s*[cс]\b/giu, "1с");
if (!normalized) {
return false;
}
const hasDirectSlangScopeLead = /(?:по\s+каким\s+(?:контор(?:ам|ы|а)?|кантор(?:ам|ы|а)?|компан(?:иям|ии|ию|ия)|организац(?:иям|ии|ию|ия))\s+мож(?:ем|но)\s+(?:общат|работ)|база\s+какой\s+(?:контор|компан|организац|фирм)|какая\s+база\s+(?:подключ|подруб|актив))/iu.test(normalized);
if (hasDirectSlangScopeLead) {
return true;
}
const hasSlangScopeQuestion = /(?:\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440(?:\u0430\u043c|\u044b|\u0430)?|\u043a\u043e\u043c\u043f\u0430\u043d(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u0444\u0438\u0440\u043c(?:\u0430\u043c|\u0435|\u0443|\u0430)).*(?:\u043c\u043e\u0436(?:\u0435\u043c|\u043d\u043e)|\u0440\u0430\u0431\u043e\u0442|\u043e\u0431\u0449\u0430\u0442|\u043f\u043e\u0434\u0440\u0443\u0431|\u043f\u043e\u0434\u043a\u043b\u044e\u0447)|(?:\u0431\u0430\u0437\u0430\s+\u043a\u0430\u043a\u043e\u0439\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0444\u0438\u0440\u043c))|(?:\u043a\u0430\u043a\u0430\u044f\s+\u0431\u0430\u0437\u0430\s+(?:\u043f\u043e\u0434\u043a\u043b\u044e\u0447|\u0430\u043a\u0442\u0438\u0432)))/iu.test(normalized);
if (hasSlangScopeQuestion) {
return true;
}
const hasBaseOrTenantObject = /(?:баз(?:а|е|у|ы)?|тенант|tenant|контур)/i.test(normalized);
const hasCompanyObject = /(?:компан(?:ия|ии|ию|ией)|компин(?:ия|ии|ию|ией)?|компини(?:я|и|ю|ей)?|компани[яеию]|организац(?:ия|ии|ию|ией)|контор(?:а|ы|у|ой)?|фирм(?:а|ы|у|ой)?)/i.test(normalized);
const hasConnectionCue = /(?:подключен(?:а|о|ы)?|подруб|воткнут|активн(?:ый|ая)\s+канал|mcp-?канал|канал)/i.test(normalized);
const hasNamingCue = /(?:как\s+называ(?:ет|ется)|что\s+за\s+(?:контор|компан|организац|фирм))/i.test(normalized);
const hasWorkabilityCue = /(?:мож(?:ем|ешь|ете|но)\s+работ|работ(?:ать|аем|аешь|аете))/i.test(normalized);
const hasScopeObject = hasBaseOrTenantObject || hasCompanyObject || hasConnectionCue;
if (!hasScopeObject) {
return false;
}
const hasMetaPerspective = /(?:ты|тебе|твой|у\s+тебя|в\s+тебе|мы|нам|наш(?:а|е|и|у|ей)?|сейчас|щас)/i.test(normalized);
const hasScopedInterrogativePair = /(?:^|\s)(?:по\s+какой|с\s+какой|какая|какой|какие)\s+(?:баз|компан|компин|компини|компани|организац|контор|фирм|тенант|контур)/i.test(normalized);
const hasScopeQuestion = /(?:чья|чье|чьи|доступн|подключен|подруб|воткнут|какая\s+баз|какой\s+баз)/i.test(normalized) ||
hasNamingCue ||
hasWorkabilityCue ||
hasScopedInterrogativePair;
const hasInterrogativeScopeLead = /(?:^|\s)(?:по\s+какой|с\s+какой|чья|чье|чьи|which|who|what)/i.test(normalized);
const isQuestionLike = /[?]/.test(String(text ?? "")) || hasInterrogativeScopeLead || hasScopedInterrogativePair;
const hasExplicitScopeContext = hasBaseOrTenantObject || hasConnectionCue || hasWorkabilityCue || hasNamingCue;
const hasRetrievalSignal = hasDataRetrievalRequestSignal(normalized);
const hasContractAnalyticsCue = /(?:договор|контракт|contract).*(?:топ|сам(?:ый|ая|ое|ые)|крупн|жирн|оборот|бюджет|сумм|стоим|value|turnover|all\s+time|всю\s+истори|за\s+вс[её]\s+время)/iu.test(normalized);
if (hasContractAnalyticsCue) {
return false;
}
if (hasRetrievalSignal && !hasExplicitScopeContext) {
return false;
}
const hasEligibleScopeObject = hasBaseOrTenantObject || (hasCompanyObject && (hasConnectionCue || hasWorkabilityCue || hasNamingCue || hasMetaPerspective));
return hasEligibleScopeObject && hasScopeQuestion && (hasMetaPerspective || isQuestionLike || hasExplicitScopeContext);
}
function shouldHandleAsAssistantCapabilityMetaQuery(text) {
const raw = String(text ?? "");
const repaired = repairAddressMojibake(raw);
const hasScopeMetaSignal = hasAssistantDataScopeMetaQuestionSignal(raw) || hasAssistantDataScopeMetaQuestionSignal(repaired);
if (hasScopeMetaSignal) {
return true;
}
const hasCapabilitySignal = hasAssistantCapabilityQuestionSignal(raw) ||
hasAssistantCapabilityQuestionSignal(repaired) ||
hasOperationalAdminActionRequestSignal(raw) ||
hasOperationalAdminActionRequestSignal(repaired);
const hasRetrievalSignal = hasDataRetrievalRequestSignal(raw) || hasDataRetrievalRequestSignal(repaired);
return hasCapabilitySignal && !hasRetrievalSignal;
}
function hasLivingChatSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
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;
}
if (/(как дела|как ты|что нового|расскажи о себе|чем можешь помочь|давай поговорим|поговорим|обсудим|посоветуй|что думаешь)/i.test(lower)) {
return true;
}
return hasSmallTalkSignal(lower);
}
function resolveLivingAssistantModeDecision(input) {
const userMessage = String(input?.userMessage ?? "");
if (input?.addressLaneTriggered) {
return {
mode: "address_data",
reason: "address_lane_triggered"
};
}
if (!featureAssistantLivingChatRouterV1) {
return {
mode: "deep_analysis",
reason: "living_chat_router_disabled"
};
}
if (Boolean(input?.useMock)) {
return {
mode: "deep_analysis",
reason: "mock_mode_keeps_deep_pipeline"
};
}
if (hasAssistantDataScopeMetaQuestionSignal(userMessage)) {
return {
mode: "chat",
reason: "assistant_data_scope_query_detected"
};
}
if (shouldHandleAsAssistantCapabilityMetaQuery(userMessage)) {
return {
mode: "chat",
reason: "assistant_capability_query_detected"
};
}
if (hasOrganizationFactLookupSignal(userMessage) || hasOrganizationFactFollowupSignal(userMessage)) {
return {
mode: "chat",
reason: "organization_fact_lookup_signal_detected"
};
}
if (hasStrongDataIntentSignal(userMessage)) {
return {
mode: "deep_analysis",
reason: "strong_data_signal_detected"
};
}
if (hasLivingChatSignal(userMessage)) {
return {
mode: "chat",
reason: "living_chat_signal_detected"
};
}
const predecomposeMode = toNonEmptyString(input?.predecomposeMode);
const predecomposeConfidence = toNonEmptyString(input?.predecomposeModeConfidence);
if (predecomposeMode === "unsupported" && (predecomposeConfidence === "low" || predecomposeConfidence === "medium")) {
return {
mode: "deep_analysis",
reason: "predecompose_unsupported_mode_fallback_to_deep"
};
}
return {
mode: "deep_analysis",
reason: "default_deep_pipeline"
};
}
return {
hasStrongDataIntentSignal,
hasDataRetrievalRequestSignal,
hasOrganizationFactLookupSignal,
hasMetaAnswerFollowupSignal,
hasConversationMemoryRecallFollowupSignal,
hasHistoricalCapabilityFollowupSignal,
hasOrganizationFactFollowupSignal,
shouldEmitOrganizationSelectionReply,
hasAssistantDataScopeMetaQuestionSignal,
shouldHandleAsAssistantCapabilityMetaQuery,
hasLivingChatSignal,
resolveLivingAssistantModeDecision
};
}

View File

@ -0,0 +1,582 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAssistantRoutePolicy = createAssistantRoutePolicy;
// @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));
}
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
};
}

View File

@ -67,6 +67,8 @@ const assistantAddressAttemptRuntimeAdapter_1 = __importStar(require("./assistan
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
const assistantDeepTurnAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAttemptRuntimeAdapter"));
const assistantBoundaryPolicy_1 = __importStar(require("./assistantBoundaryPolicy"));
const assistantLivingModePolicy_1 = __importStar(require("./assistantLivingModePolicy"));
const assistantRoutePolicy_1 = __importStar(require("./assistantRoutePolicy"));
const assistantOrganizationScopeRuntimeAdapter_1 = __importStar(require("./assistantOrganizationScopeRuntimeAdapter"));
const assistantTurnAttemptRuntimeAdapter_1 = __importStar(require("./assistantTurnAttemptRuntimeAdapter"));
const assistantTurnRuntimeDepsAdapter_1 = __importStar(require("./assistantTurnRuntimeDepsAdapter"));
@ -4252,623 +4254,17 @@ function hasOpenContractsAddressSignal(text) {
const hasTemporalCue = hasPeriodLiteral(normalized) || /\b\d{4}[-/.]\d{2}[-/.]\d{2}\b/.test(normalized);
return hasRequestCue || hasTemporalCue;
}
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));
}
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 = (0, addressQueryClassifier_1.detectAddressQuestionMode)(modeSample);
const modeDetectionRaw = (0, addressQueryClassifier_1.detectAddressQuestionMode)(repairedRawUserMessage || rawUserMessage);
const resolvedModeDetection = modeDetection.mode === "address_query" ? modeDetection : modeDetectionRaw;
const intentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(modeSample);
const intentResolutionRaw = (0, addressIntentResolver_1.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 assistantRoutePolicy.resolveAssistantOrchestrationDecision(input);
}
function hasStrongDataIntentSignal(text) {
const lower = String(text ?? "").toLowerCase();
return /(база|док|документ|проводк|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|оборот|баланс|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|mcp|bank|counterparty|contract|document|ledger|posting|account|organization|company|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм)/i.test(lower);
return assistantLivingModePolicy.hasStrongDataIntentSignal(text);
}
function hasDataRetrievalRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
if (!lower) {
return false;
}
const hasBroadInterrogative = /(?:\u0433\u0434\u0435|\u0432\s+\u043a\u0430\u043a\u0438\u0445|\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c|\u043f\u043e\s+\u043a\u043e\u043c\u0443|\u043a\u0430\u043a\u0438\u0435|\u043a\u0430\u043a\u043e\u0439|\u043a\u0442\u043e|\u0441\u043a\u043e\u043b\u044c\u043a\u043e|where|which|who|how\s+many)/iu.test(lower);
const hasBroadBusinessObject = /(?:\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0433\u043e\u0434|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b|advance|prepay|shipment|receivab|payab|counterparty|contract|document|account|balance|turnover|warehouse|inventory|stock|item)/iu.test(lower);
if (hasBroadInterrogative && hasBroadBusinessObject) {
return true;
}
const hasRussianRetrievalAction = /(?:^|\s)(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c|\u043d\u0430\u0439\u0434\u0438|\u0432\u044b\u0432\u0435\u0434\u0438|\u0434\u0430\u0439|\u0440\u0430\u0441\u043a\u0440\u043e\u0439|\u0441\u043f\u0438\u0441\u043e\u043a|\u043f\u0440\u043e\u0432\u0435\u0440\u044c|\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c)(?:$|[\s,.!?;:])/iu.test(lower);
const hasRussianRetrievalObject = /(?:\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0441\u0442\u0430\u0442|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043e\u043f\u0435\u0440\u0430\u0446|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043a\u043b\u0438\u0435\u043d\u0442|\u0433\u043e\u0434|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b)/iu.test(lower);
if (hasRussianRetrievalAction && hasRussianRetrievalObject) {
return true;
}
const hasExplicitRetrievalAction = /(?:\bпокажи\b|\bпоказать\b|\bвыведи\b|\bнайди\b|\bсписок\b|\bдай\b|\bраскрой\b|\bshow\b|\blist\b|\bfind\b|\bcount\b)/i.test(lower);
const hasInterrogativeRetrievalAction = /(?:\bсколько\b|\bкакой\b|\bкакая\b|\bкакое\b|\bкакую\b|\bкакие\b|\bкто\b|\bгде\b|\bпо\s+каким\b|\bпо\s+кому\b|\bу\s+кого\b|\bwhich\b|\bwho\b|\bwhere\b)/i.test(lower);
if (!hasExplicitRetrievalAction && !hasInterrogativeRetrievalAction) {
return false;
}
const hasRetrievalObject = /(1с|база|док|документ|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|bank|counterparty|contract|document|account|balance|ledger|posting|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм|возраст|дата\s+регистрац|регистрац|основан)/i.test(lower);
if (!hasRetrievalObject) {
return false;
}
if (hasExplicitRetrievalAction) {
return true;
}
const hasMetaCapabilityShape = /(?:мож(?:ем|ешь|ете|но)|уме(?:ешь|ете)|доступ|подключ|чья|как\s+называ(?:ет|ется)|работ(?:ать|аем|аешь|аете)|в\s+тебе|у\s+тебя)/i.test(lower);
return !hasMetaCapabilityShape;
return assistantLivingModePolicy.hasDataRetrievalRequestSignal(text);
}
function hasOrganizationFactLookupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasFactCue = /(?:возраст|сколько\s+лет|дата\s+регистрац|когда\s+(?:зарегистр|создан|основан)|год\s+регистрац|год\s+основан|с\s+какого\s+года|when\s+was\s+(?:it\s+)?(?:registered|founded|created))/i.test(normalized);
if (!hasFactCue) {
return false;
}
return /(?:организац|компан|контор|фирм|ооо|ао|зао|ип|альтернатив|лайсвуд|райм|organization|company)/i.test(normalized);
return assistantLivingModePolicy.hasOrganizationFactLookupSignal(text);
}
function findLastAssistantLivingChatDebug(items) {
if (!Array.isArray(items)) {
@ -4929,67 +4325,13 @@ function findLastOrganizationClarificationAddressDebug(items) {
return null;
}
function hasMetaAnswerFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasReflectionCue = samples.some((sample) => sample.includes("дума") ||
sample.includes("скаж") ||
sample.includes("мнение") ||
sample.includes("как тебе") ||
sample.includes("норм") ||
sample.includes("стран") ||
sample.includes("логич") ||
sample.includes("смуща") ||
sample.includes("выгляд"));
const hasTopicPointerCue = samples.some((sample) => sample.includes("на эту тему") ||
sample.includes("по этому поводу") ||
sample.includes("об этом") ||
(sample.includes("это") && hasReferentialPointer(sample)));
const hasEvaluationCue = samples.some((sample) => /\b(?:много|мало|нормально|хорошо|плохо|критично|перебор|слабо)\b/iu.test(sample));
if (!((hasReflectionCue || hasEvaluationCue) &&
(hasTopicPointerCue || (hasEvaluationCue && samples.some((sample) => /^(?:это|ну это)\b/iu.test(sample)))))) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
return assistantLivingModePolicy.hasMetaAnswerFollowupSignal(userMessage);
}
function hasConversationMemoryRecallFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample));
const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample));
if (!hasMemoryCue || !hasDiscussionCue) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
return assistantLivingModePolicy.hasConversationMemoryRecallFollowupSignal(userMessage);
}
function hasHistoricalCapabilityFollowupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasHistoryCue = /(?:историческ|история|архив|прошл(?:ый|ые|ую|ых)?|раньше|ретро|старые\s+данные)/iu.test(normalized);
if (!hasHistoryCue) {
return false;
}
return /(?:мож(?:ешь|ете|но)|уме(?:ешь|ете)|показ|вывед|дай|раскрой)/iu.test(normalized);
return assistantLivingModePolicy.hasHistoricalCapabilityFollowupSignal(text);
}
function isGroundedInventoryContextDebug(debug) {
if (!debug || typeof debug !== "object") {
@ -5006,56 +4348,10 @@ function isGroundedInventoryContextDebug(debug) {
rootIntent === "inventory_on_hand_as_of_date";
}
function hasOrganizationFactFollowupSignal(userMessage, items) {
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized)) {
return false;
}
const hasFollowupCue = /(?:^|\s)(?:давай|го|погнали|ок(?:ей)?|хорошо|принято|подтверждаю|запрашивай|запроси|проверь|продолжай|ну\s+давай|да\s+давай)(?=$|[\s,.!?;:])/iu.test(normalized);
if (!hasFollowupCue) {
return false;
}
const lastDebug = findLastAssistantLivingChatDebug(items);
const lastSource = toNonEmptyString(lastDebug?.living_chat_response_source);
const lastGuardReason = toNonEmptyString(lastDebug?.living_chat_grounding_guard_reason);
const inOrganizationFactBoundary = lastSource === "deterministic_organization_fact_boundary" ||
lastSource === "deterministic_organization_fact_boundary_followup" ||
lastGuardReason === "organization_fact_without_live_source_blocked";
return inOrganizationFactBoundary;
return assistantLivingModePolicy.hasOrganizationFactFollowupSignal(userMessage, items);
}
function shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization) {
const selected = normalizeOrganizationScopeValue(selectedOrganization);
if (!selected) {
return false;
}
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized) || hasDataRetrievalRequestSignal(normalized) || hasStrongDataIntentSignal(normalized)) {
return false;
}
const hasAnalyticalCue = /(?:какой|какая|какие|когда|сколько|кто|почему|зачем|возраст|дата|регистрац|ндс|налог|контракт|договор|документ|операц|оборот|сумм|остат|сальдо|founded|registered|created)/i.test(normalized);
if (hasAnalyticalCue) {
return false;
}
const hasSelectionCue = /(?:давай|го|погнали|ок(?:ей)?|хорошо|отлично|берем|выберем|выбираем|переключ(?:им|аем|ай)|фиксир|работаем|обсудим|тогда)\b/i.test(normalized);
if (hasSelectionCue) {
return true;
}
const hasAffectiveReactionCue = /(?:^|[\s,.;:!?()\-])(?:ну|мда|ох|ах|офигеть|офигенно|ахуеть|охуеть|пиздец|пизда|нихуя|хуево|хуёво|ебать|ебан|бля|блять|fuck|shit|damn)(?=$|[\s,.;:!?()\-])/iu.test(normalized) ||
normalized.includes("\u0430\u0445\u0443") ||
normalized.includes("\u043e\u0445\u0443") ||
normalized.includes("\u043f\u0438\u0437\u0434") ||
normalized.includes("\u0431\u043b\u044f");
if (hasAffectiveReactionCue) {
return false;
}
return normalized.length <= 36 && !/[?]/.test(String(userMessage ?? ""));
return assistantLivingModePolicy.shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization);
}
function hasOperationalAdminActionRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase()).replace(/ё/g, "е");
@ -5131,78 +4427,13 @@ function hasAssistantCapabilityQuestionSignal(text) {
return false;
}
function hasAssistantDataScopeMetaQuestionSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const lower = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
const normalized = lower.replace(/\b1\s*[cс]\b/giu, "1с");
if (!normalized) {
return false;
}
const hasDirectSlangScopeLead = /(?:по\s+каким\s+(?:контор(?:ам|ы|а)?|кантор(?:ам|ы|а)?|компан(?:иям|ии|ию|ия)|организац(?:иям|ии|ию|ия))\s+мож(?:ем|но)\s+(?:общат|работ)|база\s+какой\s+(?:контор|компан|организац|фирм)|какая\s+база\s+(?:подключ|подруб|актив))/iu.test(normalized);
if (hasDirectSlangScopeLead) {
return true;
}
const hasSlangScopeQuestion = /(?:\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440(?:\u0430\u043c|\u044b|\u0430)?|\u043a\u043e\u043c\u043f\u0430\u043d(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u0444\u0438\u0440\u043c(?:\u0430\u043c|\u0435|\u0443|\u0430)).*(?:\u043c\u043e\u0436(?:\u0435\u043c|\u043d\u043e)|\u0440\u0430\u0431\u043e\u0442|\u043e\u0431\u0449\u0430\u0442|\u043f\u043e\u0434\u0440\u0443\u0431|\u043f\u043e\u0434\u043a\u043b\u044e\u0447)|(?:\u0431\u0430\u0437\u0430\s+\u043a\u0430\u043a\u043e\u0439\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0444\u0438\u0440\u043c))|(?:\u043a\u0430\u043a\u0430\u044f\s+\u0431\u0430\u0437\u0430\s+(?:\u043f\u043e\u0434\u043a\u043b\u044e\u0447|\u0430\u043a\u0442\u0438\u0432)))/iu.test(normalized);
if (hasSlangScopeQuestion) {
return true;
}
const hasBaseOrTenantObject = /(?:баз(?:а|е|у|ы)?|тенант|tenant|контур)/i.test(normalized);
const hasCompanyObject = /(?:компан(?:ия|ии|ию|ией)|компин(?:ия|ии|ию|ией)?|компини(?:я|и|ю|ей)?|компани[яеию]|организац(?:ия|ии|ию|ией)|контор(?:а|ы|у|ой)?|фирм(?:а|ы|у|ой)?)/i.test(normalized);
const hasConnectionCue = /(?:подключен(?:а|о|ы)?|подруб|воткнут|активн(?:ый|ая)\s+канал|mcp-?канал|канал)/i.test(normalized);
const hasNamingCue = /(?:как\s+называ(?:ет|ется)|что\s+за\s+(?:контор|компан|организац|фирм))/i.test(normalized);
const hasWorkabilityCue = /(?:мож(?:ем|ешь|ете|но)\s+работ|работ(?:ать|аем|аешь|аете))/i.test(normalized);
const hasScopeObject = hasBaseOrTenantObject || hasCompanyObject || hasConnectionCue;
if (!hasScopeObject) {
return false;
}
const hasMetaPerspective = /(?:ты|тебе|твой|у\s+тебя|в\s+тебе|мы|нам|наш(?:а|е|и|у|ей)?|сейчас|щас)/i.test(normalized);
const hasScopedInterrogativePair = /(?:^|\s)(?:по\s+какой|с\s+какой|какая|какой|какие)\s+(?:баз|компан|компин|компини|компани|организац|контор|фирм|тенант|контур)/i.test(normalized);
const hasScopeQuestion = /(?:чья|чье|чьи|доступн|подключен|подруб|воткнут|какая\s+баз|какой\s+баз)/i.test(normalized) ||
hasNamingCue ||
hasWorkabilityCue ||
hasScopedInterrogativePair;
const hasInterrogativeScopeLead = /(?:^|\s)(?:по\s+какой|с\s+какой|чья|чье|чьи|which|who|what)/i.test(normalized);
const isQuestionLike = /[?]/.test(String(text ?? "")) || hasInterrogativeScopeLead || hasScopedInterrogativePair;
const hasExplicitScopeContext = hasBaseOrTenantObject || hasConnectionCue || hasWorkabilityCue || hasNamingCue;
const hasRetrievalSignal = hasDataRetrievalRequestSignal(normalized);
const hasContractAnalyticsCue = /(?:договор|контракт|contract).*(?:топ|сам(?:ый|ая|ое|ые)|крупн|жирн|оборот|бюджет|сумм|стоим|value|turnover|all\s+time|всю\s+истори|за\s+вс[её]\s+время)/iu.test(normalized);
if (hasContractAnalyticsCue) {
return false;
}
if (hasRetrievalSignal && !hasExplicitScopeContext) {
return false;
}
const hasEligibleScopeObject = hasBaseOrTenantObject || (hasCompanyObject && (hasConnectionCue || hasWorkabilityCue || hasNamingCue || hasMetaPerspective));
return hasEligibleScopeObject && hasScopeQuestion && (hasMetaPerspective || isQuestionLike || hasExplicitScopeContext);
return assistantLivingModePolicy.hasAssistantDataScopeMetaQuestionSignal(text);
}
function shouldHandleAsAssistantCapabilityMetaQuery(text) {
const raw = String(text ?? "");
const repaired = repairAddressMojibake(raw);
const hasScopeMetaSignal = hasAssistantDataScopeMetaQuestionSignal(raw) || hasAssistantDataScopeMetaQuestionSignal(repaired);
if (hasScopeMetaSignal) {
return true;
}
const hasCapabilitySignal = hasAssistantCapabilityQuestionSignal(raw) ||
hasAssistantCapabilityQuestionSignal(repaired) ||
hasOperationalAdminActionRequestSignal(raw) ||
hasOperationalAdminActionRequestSignal(repaired);
const hasRetrievalSignal = hasDataRetrievalRequestSignal(raw) || hasDataRetrievalRequestSignal(repaired);
return hasCapabilitySignal && !hasRetrievalSignal;
return assistantLivingModePolicy.shouldHandleAsAssistantCapabilityMetaQuery(text);
}
function hasLivingChatSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
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;
}
if (/(как дела|как ты|что нового|расскажи о себе|чем можешь помочь|давай поговорим|поговорим|обсудим|посоветуй|что думаешь)/i.test(lower)) {
return true;
}
return hasSmallTalkSignal(lower);
return assistantLivingModePolicy.hasLivingChatSignal(text);
}
function buildAssistantCapabilityContractReply() {
return (0, capabilitiesRegistry_1.buildCapabilityContractReplyFromRegistry)();
@ -5306,6 +4537,55 @@ function normalizeOrganizationScopeValue(value) {
.trim();
return unwrapped ? unwrapped : null;
}
const assistantLivingModePolicy = (0, assistantLivingModePolicy_1.createAssistantLivingModePolicy)({
featureAssistantLivingChatRouterV1: config_1.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1,
compactWhitespace,
repairAddressMojibake,
toNonEmptyString,
normalizeOrganizationScopeValue,
hasReferentialPointer,
hasSmallTalkSignal,
hasAssistantCapabilityQuestionSignal,
hasOperationalAdminActionRequestSignal
});
const assistantRoutePolicy = (0, assistantRoutePolicy_1.createAssistantRoutePolicy)({
repairAddressMojibake,
findLastGroundedAddressAnswerDebug,
findLastOrganizationClarificationAddressDebug,
mergeKnownOrganizations,
normalizeOrganizationScopeValue,
resolveOrganizationSelectionFromMessage,
hasAssistantDataScopeMetaQuestionSignal: assistantLivingModePolicy.hasAssistantDataScopeMetaQuestionSignal,
shouldHandleAsAssistantCapabilityMetaQuery: assistantLivingModePolicy.shouldHandleAsAssistantCapabilityMetaQuery,
hasDataRetrievalRequestSignal: assistantLivingModePolicy.hasDataRetrievalRequestSignal,
hasAggregateBusinessAnalyticsSignal,
hasStandaloneAddressTopicSignal,
hasOpenContractsAddressSignal,
detectAddressQuestionMode: addressQueryClassifier_1.detectAddressQuestionMode,
resolveAddressIntent: addressIntentResolver_1.resolveAddressIntent,
toNonEmptyString,
hasStrictDeepInvestigationCue,
hasStrongDataIntentSignal: assistantLivingModePolicy.hasStrongDataIntentSignal,
hasAccountingSignal,
hasDangerOrCoercionSignal,
hasAddressFollowupContextSignal,
hasShortDebtMirrorFollowupSignal,
isInventorySelectedObjectIntent,
hasShortInventoryObjectFollowupSignal,
hasHistoricalCapabilityFollowupSignal: assistantLivingModePolicy.hasHistoricalCapabilityFollowupSignal,
isGroundedInventoryContextDebug,
hasConversationMemoryRecallFollowupSignal: assistantLivingModePolicy.hasConversationMemoryRecallFollowupSignal,
findLastAddressAssistantItem,
hasMetaAnswerFollowupSignal: assistantLivingModePolicy.hasMetaAnswerFollowupSignal,
resolveAddressToolGateDecision,
hasSameDateAccountFollowupSignalForPredecompose,
hasLooseAllTimeAddressLookupSignal,
hasDeepAnalysisPreferenceSignal,
hasDirectDeepAnalysisSignal,
compactWhitespace,
hasDeepSessionContinuationSignal,
resolveLivingAssistantModeDecision: assistantLivingModePolicy.resolveLivingAssistantModeDecision
});
function normalizeOrganizationScopeSearchText(value) {
const source = normalizeScopeKey(value);
return source
@ -6105,67 +5385,7 @@ function applyLivingChatGroundingGuard(input) {
};
}
function resolveLivingAssistantModeDecision(input) {
const userMessage = String(input?.userMessage ?? "");
if (input?.addressLaneTriggered) {
return {
mode: "address_data",
reason: "address_lane_triggered"
};
}
if (!config_1.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1) {
return {
mode: "deep_analysis",
reason: "living_chat_router_disabled"
};
}
if (Boolean(input?.useMock)) {
return {
mode: "deep_analysis",
reason: "mock_mode_keeps_deep_pipeline"
};
}
if (hasAssistantDataScopeMetaQuestionSignal(userMessage)) {
return {
mode: "chat",
reason: "assistant_data_scope_query_detected"
};
}
if (shouldHandleAsAssistantCapabilityMetaQuery(userMessage)) {
return {
mode: "chat",
reason: "assistant_capability_query_detected"
};
}
if (hasOrganizationFactLookupSignal(userMessage) || hasOrganizationFactFollowupSignal(userMessage)) {
return {
mode: "chat",
reason: "organization_fact_lookup_signal_detected"
};
}
if (hasStrongDataIntentSignal(userMessage)) {
return {
mode: "deep_analysis",
reason: "strong_data_signal_detected"
};
}
if (hasLivingChatSignal(userMessage)) {
return {
mode: "chat",
reason: "living_chat_signal_detected"
};
}
const predecomposeMode = toNonEmptyString(input?.predecomposeMode);
const predecomposeConfidence = toNonEmptyString(input?.predecomposeModeConfidence);
if (predecomposeMode === "unsupported" && (predecomposeConfidence === "low" || predecomposeConfidence === "medium")) {
return {
mode: "deep_analysis",
reason: "predecompose_unsupported_mode_fallback_to_deep"
};
}
return {
mode: "deep_analysis",
reason: "default_deep_pipeline"
};
return assistantLivingModePolicy.resolveLivingAssistantModeDecision(input);
}
class AssistantService {
normalizerService;

View File

@ -0,0 +1,395 @@
// @ts-nocheck
export interface ResolveLivingAssistantModeDecisionInput {
userMessage?: unknown;
addressLaneTriggered?: boolean;
useMock?: boolean;
predecomposeMode?: unknown;
predecomposeModeConfidence?: unknown;
}
export interface AssistantLivingModePolicyDeps {
featureAssistantLivingChatRouterV1: boolean;
compactWhitespace: (text: string) => string;
repairAddressMojibake: (text: string) => string;
toNonEmptyString: (value: unknown) => string | null;
normalizeOrganizationScopeValue: (value: unknown) => string | null;
hasReferentialPointer: (text: string) => boolean;
hasSmallTalkSignal: (text: string) => boolean;
hasAssistantCapabilityQuestionSignal: (text: string) => boolean;
hasOperationalAdminActionRequestSignal: (text: string) => boolean;
}
export interface AssistantLivingModeDecision {
mode: "address_data" | "deep_analysis" | "chat";
reason: string;
}
export interface AssistantLivingModePolicy {
hasStrongDataIntentSignal: (text: unknown) => boolean;
hasDataRetrievalRequestSignal: (text: unknown) => boolean;
hasOrganizationFactLookupSignal: (text: unknown) => boolean;
hasMetaAnswerFollowupSignal: (text: unknown) => boolean;
hasConversationMemoryRecallFollowupSignal: (text: unknown) => boolean;
hasHistoricalCapabilityFollowupSignal: (text: unknown) => boolean;
hasOrganizationFactFollowupSignal: (userMessage: unknown, items: unknown[]) => boolean;
shouldEmitOrganizationSelectionReply: (userMessage: unknown, selectedOrganization: unknown) => boolean;
hasAssistantDataScopeMetaQuestionSignal: (text: unknown) => boolean;
shouldHandleAsAssistantCapabilityMetaQuery: (text: unknown) => boolean;
hasLivingChatSignal: (text: unknown) => boolean;
resolveLivingAssistantModeDecision: (input: ResolveLivingAssistantModeDecisionInput) => AssistantLivingModeDecision;
}
export function createAssistantLivingModePolicy(deps: AssistantLivingModePolicyDeps): AssistantLivingModePolicy {
const {
featureAssistantLivingChatRouterV1,
compactWhitespace,
repairAddressMojibake,
toNonEmptyString,
normalizeOrganizationScopeValue,
hasReferentialPointer,
hasSmallTalkSignal,
hasAssistantCapabilityQuestionSignal,
hasOperationalAdminActionRequestSignal
} = deps;
function hasStrongDataIntentSignal(text) {
const lower = String(text ?? "").toLowerCase();
return /(база|док|документ|проводк|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|оборот|баланс|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|mcp|bank|counterparty|contract|document|ledger|posting|account|organization|company|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм)/i.test(lower);
}
function hasDataRetrievalRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
if (!lower) {
return false;
}
const hasBroadInterrogative = /(?:\u0433\u0434\u0435|\u0432\s+\u043a\u0430\u043a\u0438\u0445|\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c|\u043f\u043e\s+\u043a\u043e\u043c\u0443|\u043a\u0430\u043a\u0438\u0435|\u043a\u0430\u043a\u043e\u0439|\u043a\u0442\u043e|\u0441\u043a\u043e\u043b\u044c\u043a\u043e|where|which|who|how\s+many)/iu.test(lower);
const hasBroadBusinessObject = /(?:\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0433\u043e\u0434|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b|advance|prepay|shipment|receivab|payab|counterparty|contract|document|account|balance|turnover|warehouse|inventory|stock|item)/iu.test(lower);
if (hasBroadInterrogative && hasBroadBusinessObject) {
return true;
}
const hasRussianRetrievalAction = /(?:^|\s)(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c|\u043d\u0430\u0439\u0434\u0438|\u0432\u044b\u0432\u0435\u0434\u0438|\u0434\u0430\u0439|\u0440\u0430\u0441\u043a\u0440\u043e\u0439|\u0441\u043f\u0438\u0441\u043e\u043a|\u043f\u0440\u043e\u0432\u0435\u0440\u044c|\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c)(?:$|[\s,.!?;:])/iu.test(lower);
const hasRussianRetrievalObject = /(?:\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0441\u0442\u0430\u0442|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043e\u043f\u0435\u0440\u0430\u0446|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043a\u043b\u0438\u0435\u043d\u0442|\u0433\u043e\u0434|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b)/iu.test(lower);
if (hasRussianRetrievalAction && hasRussianRetrievalObject) {
return true;
}
const hasExplicitRetrievalAction = /(?:\bпокажи\b|\bпоказать\b|\bвыведи\b|\bнайди\b|\bсписок\b|\bдай\b|\bраскрой\b|\bshow\b|\blist\b|\bfind\b|\bcount\b)/i.test(lower);
const hasInterrogativeRetrievalAction = /(?:\bсколько\b|\bкакой\b|\bкакая\b|\bкакое\b|\bкакую\b|\bкакие\b|\bкто\b|\bгде\b|\bпо\s+каким\b|\bпо\s+кому\b|\bу\s+кого\b|\bwhich\b|\bwho\b|\bwhere\b)/i.test(lower);
if (!hasExplicitRetrievalAction && !hasInterrogativeRetrievalAction) {
return false;
}
const hasRetrievalObject = /(1с|база|док|документ|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|bank|counterparty|contract|document|account|balance|ledger|posting|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм|возраст|дата\s+регистрац|регистрац|основан)/i.test(lower);
if (!hasRetrievalObject) {
return false;
}
if (hasExplicitRetrievalAction) {
return true;
}
const hasMetaCapabilityShape = /(?:мож(?:ем|ешь|ете|но)|уме(?:ешь|ете)|доступ|подключ|чья|как\s+называ(?:ет|ется)|работ(?:ать|аем|аешь|аете)|в\s+тебе|у\s+тебя)/i.test(lower);
return !hasMetaCapabilityShape;
}
function hasOrganizationFactLookupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasFactCue = /(?:возраст|сколько\s+лет|дата\s+регистрац|когда\s+(?:зарегистр|создан|основан)|год\s+регистрац|год\s+основан|с\s+какого\s+года|when\s+was\s+(?:it\s+)?(?:registered|founded|created))/i.test(normalized);
if (!hasFactCue) {
return false;
}
return /(?:организац|компан|контор|фирм|ооо|ао|зао|ип|альтернатив|лайсвуд|райм|organization|company)/i.test(normalized);
}
function findLastAssistantLivingChatDebug(items) {
if (!Array.isArray(items)) {
return null;
}
for (let index = items.length - 1; index >= 0; index -= 1) {
const item = items[index];
if (!item || item.role !== "assistant") {
continue;
}
if (item.debug && typeof item.debug === "object") {
return item.debug;
}
}
return null;
}
function hasMetaAnswerFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasReflectionCue = samples.some((sample) => sample.includes("дума") ||
sample.includes("скаж") ||
sample.includes("мнение") ||
sample.includes("как тебе") ||
sample.includes("норм") ||
sample.includes("стран") ||
sample.includes("логич") ||
sample.includes("смуща") ||
sample.includes("выгляд"));
const hasTopicPointerCue = samples.some((sample) => sample.includes("на эту тему") ||
sample.includes("по этому поводу") ||
sample.includes("об этом") ||
(sample.includes("это") && hasReferentialPointer(sample)));
const hasEvaluationCue = samples.some((sample) => /\b(?:много|мало|нормально|хорошо|плохо|критично|перебор|слабо)\b/iu.test(sample));
if (!((hasReflectionCue || hasEvaluationCue) &&
(hasTopicPointerCue || (hasEvaluationCue && samples.some((sample) => /^(?:это|ну это)\b/iu.test(sample)))))) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
}
function hasConversationMemoryRecallFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample));
const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample));
if (!hasMemoryCue || !hasDiscussionCue) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
}
function hasHistoricalCapabilityFollowupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasHistoryCue = /(?:историческ|история|архив|прошл(?:ый|ые|ую|ых)?|раньше|ретро|старые\s+данные)/iu.test(normalized);
if (!hasHistoryCue) {
return false;
}
return /(?:мож(?:ешь|ете|но)|уме(?:ешь|ете)|показ|вывед|дай|раскрой)/iu.test(normalized);
}
function hasOrganizationFactFollowupSignal(userMessage, items) {
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized)) {
return false;
}
const hasFollowupCue = /(?:^|\s)(?:давай|го|погнали|ок(?:ей)?|хорошо|принято|подтверждаю|запрашивай|запроси|проверь|продолжай|ну\s+давай|да\s+давай)(?=$|[\s,.!?;:])/iu.test(normalized);
if (!hasFollowupCue) {
return false;
}
const lastDebug = findLastAssistantLivingChatDebug(items);
const lastSource = toNonEmptyString(lastDebug?.living_chat_response_source);
const lastGuardReason = toNonEmptyString(lastDebug?.living_chat_grounding_guard_reason);
const inOrganizationFactBoundary = lastSource === "deterministic_organization_fact_boundary" ||
lastSource === "deterministic_organization_fact_boundary_followup" ||
lastGuardReason === "organization_fact_without_live_source_blocked";
return inOrganizationFactBoundary;
}
function shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization) {
const selected = normalizeOrganizationScopeValue(selectedOrganization);
if (!selected) {
return false;
}
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized) || hasDataRetrievalRequestSignal(normalized) || hasStrongDataIntentSignal(normalized)) {
return false;
}
const hasAnalyticalCue = /(?:какой|какая|какие|когда|сколько|кто|почему|зачем|возраст|дата|регистрац|ндс|налог|контракт|договор|документ|операц|оборот|сумм|остат|сальдо|founded|registered|created)/i.test(normalized);
if (hasAnalyticalCue) {
return false;
}
const hasSelectionCue = /(?:давай|го|погнали|ок(?:ей)?|хорошо|отлично|берем|выберем|выбираем|переключ(?:им|аем|ай)|фиксир|работаем|обсудим|тогда)\b/i.test(normalized);
if (hasSelectionCue) {
return true;
}
const hasAffectiveReactionCue = /(?:^|[\s,.;:!?()\-])(?:РЅСѓ|РјРґР°|РѕС|Р°С|РѕСРёРіРµССЊ|РѕСигенно|Р°ССѓРµССЊ|РѕССѓРµССЊ|РїРёР·РґРµС|РїРёР·РґР°|РЅРёССѓСЏ|Суево|ССѓСРІРѕ|ебаССЊ|ебан|бля|бляССЊ|fuck|shit|damn)(?=$|[\s,.;:!?()\-])/iu.test(normalized) ||
normalized.includes("\u0430\u0445\u0443") ||
normalized.includes("\u043e\u0445\u0443") ||
normalized.includes("\u043f\u0438\u0437\u0434") ||
normalized.includes("\u0431\u043b\u044f");
if (hasAffectiveReactionCue) {
return false;
}
return normalized.length <= 36 && !/[?]/.test(String(userMessage ?? ""));
}
function hasAssistantDataScopeMetaQuestionSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const lower = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
const normalized = lower.replace(/\b1\s*[cс]\b/giu, "1с");
if (!normalized) {
return false;
}
const hasDirectSlangScopeLead = /(?:по\s+каким\s+(?:контор(?:ам|ы|а)?|кантор(?:ам|ы|а)?|компан(?:иям|ии|ию|ия)|организац(?:иям|ии|ию|ия))\s+мож(?:ем|но)\s+(?:общат|работ)|база\s+какой\s+(?:контор|компан|организац|фирм)|какая\s+база\s+(?:подключ|подруб|актив))/iu.test(normalized);
if (hasDirectSlangScopeLead) {
return true;
}
const hasSlangScopeQuestion = /(?:\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440(?:\u0430\u043c|\u044b|\u0430)?|\u043a\u043e\u043c\u043f\u0430\u043d(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u0444\u0438\u0440\u043c(?:\u0430\u043c|\u0435|\u0443|\u0430)).*(?:\u043c\u043e\u0436(?:\u0435\u043c|\u043d\u043e)|\u0440\u0430\u0431\u043e\u0442|\u043e\u0431\u0449\u0430\u0442|\u043f\u043e\u0434\u0440\u0443\u0431|\u043f\u043e\u0434\u043a\u043b\u044e\u0447)|(?:\u0431\u0430\u0437\u0430\s+\u043a\u0430\u043a\u043e\u0439\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0444\u0438\u0440\u043c))|(?:\u043a\u0430\u043a\u0430\u044f\s+\u0431\u0430\u0437\u0430\s+(?:\u043f\u043e\u0434\u043a\u043b\u044e\u0447|\u0430\u043a\u0442\u0438\u0432)))/iu.test(normalized);
if (hasSlangScopeQuestion) {
return true;
}
const hasBaseOrTenantObject = /(?:баз(?:а|е|у|ы)?|тенант|tenant|контур)/i.test(normalized);
const hasCompanyObject = /(?:компан(?:ия|ии|ию|ией)|компин(?:ия|ии|ию|ией)?|компини(?:я|и|ю|ей)?|компани[яеию]|организац(?:ия|ии|ию|ией)|контор(?:а|ы|у|ой)?|фирм(?:а|ы|у|ой)?)/i.test(normalized);
const hasConnectionCue = /(?:подключен(?:а|о|ы)?|подруб|воткнут|активн(?:ый|ая)\s+канал|mcp-?канал|канал)/i.test(normalized);
const hasNamingCue = /(?:как\s+называ(?:ет|ется)|что\s+за\s+(?:контор|компан|организац|фирм))/i.test(normalized);
const hasWorkabilityCue = /(?:мож(?:ем|ешь|ете|но)\s+работ|работ(?:ать|аем|аешь|аете))/i.test(normalized);
const hasScopeObject = hasBaseOrTenantObject || hasCompanyObject || hasConnectionCue;
if (!hasScopeObject) {
return false;
}
const hasMetaPerspective = /(?:ты|тебе|твой|у\s+тебя|в\s+тебе|мы|нам|наш(?:а|е|и|у|ей)?|сейчас|щас)/i.test(normalized);
const hasScopedInterrogativePair = /(?:^|\s)(?:по\s+какой|с\s+какой|какая|какой|какие)\s+(?:баз|компан|компин|компини|компани|организац|контор|фирм|тенант|контур)/i.test(normalized);
const hasScopeQuestion = /(?:чья|чье|чьи|доступн|подключен|подруб|воткнут|какая\s+баз|какой\s+баз)/i.test(normalized) ||
hasNamingCue ||
hasWorkabilityCue ||
hasScopedInterrogativePair;
const hasInterrogativeScopeLead = /(?:^|\s)(?:по\s+какой|с\s+какой|чья|чье|чьи|which|who|what)/i.test(normalized);
const isQuestionLike = /[?]/.test(String(text ?? "")) || hasInterrogativeScopeLead || hasScopedInterrogativePair;
const hasExplicitScopeContext = hasBaseOrTenantObject || hasConnectionCue || hasWorkabilityCue || hasNamingCue;
const hasRetrievalSignal = hasDataRetrievalRequestSignal(normalized);
const hasContractAnalyticsCue = /(?:договор|контракт|contract).*(?:топ|сам(?:ый|ая|ое|ые)|крупн|жирн|оборот|бюджет|сумм|стоим|value|turnover|all\s+time|всю\s+истори|за\s+вс[её]\s+время)/iu.test(normalized);
if (hasContractAnalyticsCue) {
return false;
}
if (hasRetrievalSignal && !hasExplicitScopeContext) {
return false;
}
const hasEligibleScopeObject = hasBaseOrTenantObject || (hasCompanyObject && (hasConnectionCue || hasWorkabilityCue || hasNamingCue || hasMetaPerspective));
return hasEligibleScopeObject && hasScopeQuestion && (hasMetaPerspective || isQuestionLike || hasExplicitScopeContext);
}
function shouldHandleAsAssistantCapabilityMetaQuery(text) {
const raw = String(text ?? "");
const repaired = repairAddressMojibake(raw);
const hasScopeMetaSignal = hasAssistantDataScopeMetaQuestionSignal(raw) || hasAssistantDataScopeMetaQuestionSignal(repaired);
if (hasScopeMetaSignal) {
return true;
}
const hasCapabilitySignal = hasAssistantCapabilityQuestionSignal(raw) ||
hasAssistantCapabilityQuestionSignal(repaired) ||
hasOperationalAdminActionRequestSignal(raw) ||
hasOperationalAdminActionRequestSignal(repaired);
const hasRetrievalSignal = hasDataRetrievalRequestSignal(raw) || hasDataRetrievalRequestSignal(repaired);
return hasCapabilitySignal && !hasRetrievalSignal;
}
function hasLivingChatSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
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;
}
if (/(как дела|как ты|что нового|расскажи о себе|чем можешь помочь|давай поговорим|поговорим|обсудим|посоветуй|что думаешь)/i.test(lower)) {
return true;
}
return hasSmallTalkSignal(lower);
}
function resolveLivingAssistantModeDecision(input) {
const userMessage = String(input?.userMessage ?? "");
if (input?.addressLaneTriggered) {
return {
mode: "address_data",
reason: "address_lane_triggered"
};
}
if (!featureAssistantLivingChatRouterV1) {
return {
mode: "deep_analysis",
reason: "living_chat_router_disabled"
};
}
if (Boolean(input?.useMock)) {
return {
mode: "deep_analysis",
reason: "mock_mode_keeps_deep_pipeline"
};
}
if (hasAssistantDataScopeMetaQuestionSignal(userMessage)) {
return {
mode: "chat",
reason: "assistant_data_scope_query_detected"
};
}
if (shouldHandleAsAssistantCapabilityMetaQuery(userMessage)) {
return {
mode: "chat",
reason: "assistant_capability_query_detected"
};
}
if (hasOrganizationFactLookupSignal(userMessage) || hasOrganizationFactFollowupSignal(userMessage)) {
return {
mode: "chat",
reason: "organization_fact_lookup_signal_detected"
};
}
if (hasStrongDataIntentSignal(userMessage)) {
return {
mode: "deep_analysis",
reason: "strong_data_signal_detected"
};
}
if (hasLivingChatSignal(userMessage)) {
return {
mode: "chat",
reason: "living_chat_signal_detected"
};
}
const predecomposeMode = toNonEmptyString(input?.predecomposeMode);
const predecomposeConfidence = toNonEmptyString(input?.predecomposeModeConfidence);
if (predecomposeMode === "unsupported" && (predecomposeConfidence === "low" || predecomposeConfidence === "medium")) {
return {
mode: "deep_analysis",
reason: "predecompose_unsupported_mode_fallback_to_deep"
};
}
return {
mode: "deep_analysis",
reason: "default_deep_pipeline"
};
}
return {
hasStrongDataIntentSignal,
hasDataRetrievalRequestSignal,
hasOrganizationFactLookupSignal,
hasMetaAnswerFollowupSignal,
hasConversationMemoryRecallFollowupSignal,
hasHistoricalCapabilityFollowupSignal,
hasOrganizationFactFollowupSignal,
shouldEmitOrganizationSelectionReply,
hasAssistantDataScopeMetaQuestionSignal,
shouldHandleAsAssistantCapabilityMetaQuery,
hasLivingChatSignal,
resolveLivingAssistantModeDecision
};
}

View File

@ -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
};
}

View File

@ -21,6 +21,8 @@ import * as assistantAddressAttemptRuntimeAdapter_1 from "./assistantAddressAtte
import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding";
import * as assistantDeepTurnAttemptRuntimeAdapter_1 from "./assistantDeepTurnAttemptRuntimeAdapter";
import * as assistantBoundaryPolicy_1 from "./assistantBoundaryPolicy";
import * as assistantLivingModePolicy_1 from "./assistantLivingModePolicy";
import * as assistantRoutePolicy_1 from "./assistantRoutePolicy";
import * as assistantOrganizationScopeRuntimeAdapter_1 from "./assistantOrganizationScopeRuntimeAdapter";
import * as assistantOrganizationMatcher_1 from "./assistantOrganizationMatcher";
import * as assistantTurnAttemptRuntimeAdapter_1 from "./assistantTurnAttemptRuntimeAdapter";
@ -4211,623 +4213,18 @@ function hasOpenContractsAddressSignal(text) {
const hasTemporalCue = hasPeriodLiteral(normalized) || /\b\d{4}[-/.]\d{2}[-/.]\d{2}\b/.test(normalized);
return hasRequestCue || hasTemporalCue;
}
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 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 = (0, addressQueryClassifier_1.detectAddressQuestionMode)(modeSample);
const modeDetectionRaw = (0, addressQueryClassifier_1.detectAddressQuestionMode)(repairedRawUserMessage || rawUserMessage);
const resolvedModeDetection = modeDetection.mode === "address_query" ? modeDetection : modeDetectionRaw;
const intentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(modeSample);
const intentResolutionRaw = (0, addressIntentResolver_1.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 assistantRoutePolicy.resolveAssistantOrchestrationDecision(input);
}
function hasStrongDataIntentSignal(text) {
const lower = String(text ?? "").toLowerCase();
return /(база|док|документ|проводк|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|оборот|баланс|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|mcp|bank|counterparty|contract|document|ledger|posting|account|organization|company|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм)/i.test(lower);
return assistantLivingModePolicy.hasStrongDataIntentSignal(text);
}
function hasDataRetrievalRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
if (!lower) {
return false;
}
const hasBroadInterrogative = /(?:\u0433\u0434\u0435|\u0432\s+\u043a\u0430\u043a\u0438\u0445|\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c|\u043f\u043e\s+\u043a\u043e\u043c\u0443|\u043a\u0430\u043a\u0438\u0435|\u043a\u0430\u043a\u043e\u0439|\u043a\u0442\u043e|\u0441\u043a\u043e\u043b\u044c\u043a\u043e|where|which|who|how\s+many)/iu.test(lower);
const hasBroadBusinessObject = /(?:\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0433\u043e\u0434|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b|advance|prepay|shipment|receivab|payab|counterparty|contract|document|account|balance|turnover|warehouse|inventory|stock|item)/iu.test(lower);
if (hasBroadInterrogative && hasBroadBusinessObject) {
return true;
}
const hasRussianRetrievalAction = /(?:^|\s)(?:\u043f\u043e\u043a\u0430\u0436\u0438|\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c|\u043d\u0430\u0439\u0434\u0438|\u0432\u044b\u0432\u0435\u0434\u0438|\u0434\u0430\u0439|\u0440\u0430\u0441\u043a\u0440\u043e\u0439|\u0441\u043f\u0438\u0441\u043e\u043a|\u043f\u0440\u043e\u0432\u0435\u0440\u044c|\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c)(?:$|[\s,.!?;:])/iu.test(lower);
const hasRussianRetrievalObject = /(?:\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0441\u0447(?:\u0435|\u0451)\u0442|\u043e\u0441\u0442\u0430\u0442|\u0441\u0430\u043b\u044c\u0434\u043e|\u043e\u0431\u043e\u0440\u043e\u0442|\u043f\u043b\u0430\u0442(?:\u0435|\u0451)\u0436|\u043e\u043f\u0435\u0440\u0430\u0446|\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043a\u043b\u0438\u0435\u043d\u0442|\u0433\u043e\u0434|\u043f\u0435\u0440\u0438\u043e\u0434|\u043c\u0435\u0441\u044f\u0446|\u0430\u0432\u0430\u043d\u0441|\u043f\u0440\u0435\u0434\u043e\u043f\u043b\u0430\u0442|\u043e\u0442\u0433\u0440\u0443\u0437|\u0437\u0430\u0434\u043e\u043b\u0436|\u0434\u043e\u043b\u0433|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442|\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b)/iu.test(lower);
if (hasRussianRetrievalAction && hasRussianRetrievalObject) {
return true;
}
const hasExplicitRetrievalAction = /(?:\bпокажи\b|\bпоказать\b|\bвыведи\b|\bнайди\b|\bсписок\b|\bдай\b|\bраскрой\b|\bshow\b|\blist\b|\bfind\b|\bcount\b)/i.test(lower);
const hasInterrogativeRetrievalAction = /(?:\bсколько\b|\bкакой\b|\bкакая\b|\bкакое\b|\bкакую\b|\bкакие\b|\bкто\b|\bгде\b|\bпо\s+каким\b|\bпо\s+кому\b|\bу\s+кого\b|\bwhich\b|\bwho\b|\bwhere\b)/i.test(lower);
if (!hasExplicitRetrievalAction && !hasInterrogativeRetrievalAction) {
return false;
}
const hasRetrievalObject = /(1с|база|док|документ|контрагент|договор|контракт|счет|сч[её]т|остат|сальдо|хвост|платеж|плат[её]ж|операц|поставщик|клиент|заказчик|дебитор|кредитор|период|месяц|год|инн|аванс|предоплат|отгруз|задолж|долг|склад|товар|номенклат|материал|bank|counterparty|contract|document|account|balance|ledger|posting|advance|prepay|shipment|receivab|payab|warehouse|inventory|stock|item|организац|компан|контор|фирм|возраст|дата\s+регистрац|регистрац|основан)/i.test(lower);
if (!hasRetrievalObject) {
return false;
}
if (hasExplicitRetrievalAction) {
return true;
}
const hasMetaCapabilityShape = /(?:мож(?:ем|ешь|ете|но)|уме(?:ешь|ете)|доступ|подключ|чья|как\s+называ(?:ет|ется)|работ(?:ать|аем|аешь|аете)|в\s+тебе|у\s+тебя)/i.test(lower);
return !hasMetaCapabilityShape;
return assistantLivingModePolicy.hasDataRetrievalRequestSignal(text);
}
function hasOrganizationFactLookupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasFactCue = /(?:возраст|сколько\s+лет|дата\s+регистрац|когда\s+(?:зарегистр|создан|основан)|год\s+регистрац|год\s+основан|с\s+какого\s+года|when\s+was\s+(?:it\s+)?(?:registered|founded|created))/i.test(normalized);
if (!hasFactCue) {
return false;
}
return /(?:организац|компан|контор|фирм|ооо|ао|зао|ип|альтернатив|лайсвуд|райм|organization|company)/i.test(normalized);
return assistantLivingModePolicy.hasOrganizationFactLookupSignal(text);
}
function findLastAssistantLivingChatDebug(items) {
if (!Array.isArray(items)) {
@ -4888,67 +4285,13 @@ function findLastOrganizationClarificationAddressDebug(items) {
return null;
}
function hasMetaAnswerFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasReflectionCue = samples.some((sample) => sample.includes("дума") ||
sample.includes("скаж") ||
sample.includes("мнение") ||
sample.includes("как тебе") ||
sample.includes("норм") ||
sample.includes("стран") ||
sample.includes("логич") ||
sample.includes("смуща") ||
sample.includes("выгляд"));
const hasTopicPointerCue = samples.some((sample) => sample.includes("на эту тему") ||
sample.includes("по этому поводу") ||
sample.includes("об этом") ||
(sample.includes("это") && hasReferentialPointer(sample)));
const hasEvaluationCue = samples.some((sample) => /\b(?:много|мало|нормально|хорошо|плохо|критично|перебор|слабо)\b/iu.test(sample));
if (!((hasReflectionCue || hasEvaluationCue) &&
(hasTopicPointerCue || (hasEvaluationCue && samples.some((sample) => /^(?:это|ну это)\b/iu.test(sample)))))) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
return assistantLivingModePolicy.hasMetaAnswerFollowupSignal(userMessage);
}
function hasConversationMemoryRecallFollowupSignal(userMessage) {
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
const samples = [rawText, repairedText]
.filter((item) => item.length > 0)
.map((item) => item.replace(/ё/g, "е"));
if (samples.length === 0) {
return false;
}
const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample));
const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample));
if (!hasMemoryCue || !hasDiscussionCue) {
return false;
}
return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) ||
shouldHandleAsAssistantCapabilityMetaQuery(sample) ||
hasDataRetrievalRequestSignal(sample) ||
hasStrongDataIntentSignal(sample));
return assistantLivingModePolicy.hasConversationMemoryRecallFollowupSignal(userMessage);
}
function hasHistoricalCapabilityFollowupSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
const hasHistoryCue = /(?:историческ|история|архив|прошл(?:ый|ые|ую|ых)?|раньше|ретро|старые\s+данные)/iu.test(normalized);
if (!hasHistoryCue) {
return false;
}
return /(?:мож(?:ешь|ете|но)|уме(?:ешь|ете)|показ|вывед|дай|раскрой)/iu.test(normalized);
return assistantLivingModePolicy.hasHistoricalCapabilityFollowupSignal(text);
}
function isGroundedInventoryContextDebug(debug) {
if (!debug || typeof debug !== "object") {
@ -4965,56 +4308,10 @@ function isGroundedInventoryContextDebug(debug) {
rootIntent === "inventory_on_hand_as_of_date";
}
function hasOrganizationFactFollowupSignal(userMessage, items) {
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized)) {
return false;
}
const hasFollowupCue = /(?:^|\s)(?:давай|го|погнали|ок(?:ей)?|хорошо|принято|подтверждаю|запрашивай|запроси|проверь|продолжай|ну\s+давай|да\s+давай)(?=$|[\s,.!?;:])/iu.test(normalized);
if (!hasFollowupCue) {
return false;
}
const lastDebug = findLastAssistantLivingChatDebug(items);
const lastSource = toNonEmptyString(lastDebug?.living_chat_response_source);
const lastGuardReason = toNonEmptyString(lastDebug?.living_chat_grounding_guard_reason);
const inOrganizationFactBoundary = lastSource === "deterministic_organization_fact_boundary" ||
lastSource === "deterministic_organization_fact_boundary_followup" ||
lastGuardReason === "organization_fact_without_live_source_blocked";
return inOrganizationFactBoundary;
return assistantLivingModePolicy.hasOrganizationFactFollowupSignal(userMessage, items);
}
function shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization) {
const selected = normalizeOrganizationScopeValue(selectedOrganization);
if (!selected) {
return false;
}
const repaired = repairAddressMojibake(String(userMessage ?? ""));
const normalized = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
if (!normalized) {
return false;
}
if (hasOrganizationFactLookupSignal(normalized) || hasDataRetrievalRequestSignal(normalized) || hasStrongDataIntentSignal(normalized)) {
return false;
}
const hasAnalyticalCue = /(?:какой|какая|какие|когда|сколько|кто|почему|зачем|возраст|дата|регистрац|ндс|налог|контракт|договор|документ|операц|оборот|сумм|остат|сальдо|founded|registered|created)/i.test(normalized);
if (hasAnalyticalCue) {
return false;
}
const hasSelectionCue = /(?:давай|го|погнали|ок(?:ей)?|хорошо|отлично|берем|выберем|выбираем|переключ(?:им|аем|ай)|фиксир|работаем|обсудим|тогда)\b/i.test(normalized);
if (hasSelectionCue) {
return true;
}
const hasAffectiveReactionCue = /(?:^|[\s,.;:!?()\-])(?:РЅСѓ|РјРґР°|РѕС|Р°С|РѕСРёРіРµССЊ|РѕСигенно|Р°ССѓРµССЊ|РѕССѓРµССЊ|РїРёР·РґРµС|РїРёР·РґР°|РЅРёССѓСЏ|Суево|ССѓСРІРѕ|ебаССЊ|ебан|бля|бляССЊ|fuck|shit|damn)(?=$|[\s,.;:!?()\-])/iu.test(normalized) ||
normalized.includes("\u0430\u0445\u0443") ||
normalized.includes("\u043e\u0445\u0443") ||
normalized.includes("\u043f\u0438\u0437\u0434") ||
normalized.includes("\u0431\u043b\u044f");
if (hasAffectiveReactionCue) {
return false;
}
return normalized.length <= 36 && !/[?]/.test(String(userMessage ?? ""));
return assistantLivingModePolicy.shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization);
}
function hasOperationalAdminActionRequestSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase()).replace(/ё/g, "е");
@ -5090,78 +4387,13 @@ function hasAssistantCapabilityQuestionSignal(text) {
return false;
}
function hasAssistantDataScopeMetaQuestionSignal(text) {
const repaired = repairAddressMojibake(String(text ?? ""));
const lower = compactWhitespace(repaired.toLowerCase()).replace(/ё/g, "е");
const normalized = lower.replace(/\b1\s*[cс]\b/giu, "1с");
if (!normalized) {
return false;
}
const hasDirectSlangScopeLead = /(?:по\s+каким\s+(?:контор(?:ам|ы|а)?|кантор(?:ам|ы|а)?|компан(?:иям|ии|ию|ия)|организац(?:иям|ии|ию|ия))\s+мож(?:ем|но)\s+(?:общат|работ)|база\s+какой\s+(?:контор|компан|организац|фирм)|какая\s+база\s+(?:подключ|подруб|актив))/iu.test(normalized);
if (hasDirectSlangScopeLead) {
return true;
}
const hasSlangScopeQuestion = /(?:\u043f\u043e\s+\u043a\u0430\u043a\u0438\u043c\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440(?:\u0430\u043c|\u044b|\u0430)?|\u043a\u043e\u043c\u043f\u0430\u043d(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446(?:\u0438\u044f\u043c|\u0438\u0438|\u0438\u044e|\u0438\u044f)|\u0444\u0438\u0440\u043c(?:\u0430\u043c|\u0435|\u0443|\u0430)).*(?:\u043c\u043e\u0436(?:\u0435\u043c|\u043d\u043e)|\u0440\u0430\u0431\u043e\u0442|\u043e\u0431\u0449\u0430\u0442|\u043f\u043e\u0434\u0440\u0443\u0431|\u043f\u043e\u0434\u043a\u043b\u044e\u0447)|(?:\u0431\u0430\u0437\u0430\s+\u043a\u0430\u043a\u043e\u0439\s+(?:\u043a\u043e\u043d\u0442\u043e\u0440|\u043a\u043e\u043c\u043f\u0430\u043d|\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446|\u0444\u0438\u0440\u043c))|(?:\u043a\u0430\u043a\u0430\u044f\s+\u0431\u0430\u0437\u0430\s+(?:\u043f\u043e\u0434\u043a\u043b\u044e\u0447|\u0430\u043a\u0442\u0438\u0432)))/iu.test(normalized);
if (hasSlangScopeQuestion) {
return true;
}
const hasBaseOrTenantObject = /(?:баз(?:а|е|у|ы)?|тенант|tenant|контур)/i.test(normalized);
const hasCompanyObject = /(?:компан(?:ия|ии|ию|ией)|компин(?:ия|ии|ию|ией)?|компини(?:я|и|ю|ей)?|компани[яеию]|организац(?:ия|ии|ию|ией)|контор(?:а|ы|у|ой)?|фирм(?:а|ы|у|ой)?)/i.test(normalized);
const hasConnectionCue = /(?:подключен(?:а|о|ы)?|подруб|воткнут|активн(?:ый|ая)\s+канал|mcp-?канал|канал)/i.test(normalized);
const hasNamingCue = /(?:как\s+называ(?:ет|ется)|что\s+за\s+(?:контор|компан|организац|фирм))/i.test(normalized);
const hasWorkabilityCue = /(?:мож(?:ем|ешь|ете|но)\s+работ|работ(?:ать|аем|аешь|аете))/i.test(normalized);
const hasScopeObject = hasBaseOrTenantObject || hasCompanyObject || hasConnectionCue;
if (!hasScopeObject) {
return false;
}
const hasMetaPerspective = /(?:ты|тебе|твой|у\s+тебя|в\s+тебе|мы|нам|наш(?:а|е|и|у|ей)?|сейчас|щас)/i.test(normalized);
const hasScopedInterrogativePair = /(?:^|\s)(?:по\s+какой|с\s+какой|какая|какой|какие)\s+(?:баз|компан|компин|компини|компани|организац|контор|фирм|тенант|контур)/i.test(normalized);
const hasScopeQuestion = /(?:чья|чье|чьи|доступн|подключен|подруб|воткнут|какая\s+баз|какой\s+баз)/i.test(normalized) ||
hasNamingCue ||
hasWorkabilityCue ||
hasScopedInterrogativePair;
const hasInterrogativeScopeLead = /(?:^|\s)(?:по\s+какой|с\s+какой|чья|чье|чьи|which|who|what)/i.test(normalized);
const isQuestionLike = /[?]/.test(String(text ?? "")) || hasInterrogativeScopeLead || hasScopedInterrogativePair;
const hasExplicitScopeContext = hasBaseOrTenantObject || hasConnectionCue || hasWorkabilityCue || hasNamingCue;
const hasRetrievalSignal = hasDataRetrievalRequestSignal(normalized);
const hasContractAnalyticsCue = /(?:договор|контракт|contract).*(?:топ|сам(?:ый|ая|ое|ые)|крупн|жирн|оборот|бюджет|сумм|стоим|value|turnover|all\s+time|всю\s+истори|за\s+вс[её]\s+время)/iu.test(normalized);
if (hasContractAnalyticsCue) {
return false;
}
if (hasRetrievalSignal && !hasExplicitScopeContext) {
return false;
}
const hasEligibleScopeObject = hasBaseOrTenantObject || (hasCompanyObject && (hasConnectionCue || hasWorkabilityCue || hasNamingCue || hasMetaPerspective));
return hasEligibleScopeObject && hasScopeQuestion && (hasMetaPerspective || isQuestionLike || hasExplicitScopeContext);
return assistantLivingModePolicy.hasAssistantDataScopeMetaQuestionSignal(text);
}
function shouldHandleAsAssistantCapabilityMetaQuery(text) {
const raw = String(text ?? "");
const repaired = repairAddressMojibake(raw);
const hasScopeMetaSignal = hasAssistantDataScopeMetaQuestionSignal(raw) || hasAssistantDataScopeMetaQuestionSignal(repaired);
if (hasScopeMetaSignal) {
return true;
}
const hasCapabilitySignal = hasAssistantCapabilityQuestionSignal(raw) ||
hasAssistantCapabilityQuestionSignal(repaired) ||
hasOperationalAdminActionRequestSignal(raw) ||
hasOperationalAdminActionRequestSignal(repaired);
const hasRetrievalSignal = hasDataRetrievalRequestSignal(raw) || hasDataRetrievalRequestSignal(repaired);
return hasCapabilitySignal && !hasRetrievalSignal;
return assistantLivingModePolicy.shouldHandleAsAssistantCapabilityMetaQuery(text);
}
function hasLivingChatSignal(text) {
const lower = compactWhitespace(String(text ?? "").toLowerCase());
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;
}
if (/(как дела|как ты|что нового|расскажи о себе|чем можешь помочь|давай поговорим|поговорим|обсудим|посоветуй|что думаешь)/i.test(lower)) {
return true;
}
return hasSmallTalkSignal(lower);
return assistantLivingModePolicy.hasLivingChatSignal(text);
}
function buildAssistantCapabilityContractReply() {
return (0, capabilitiesRegistry_1.buildCapabilityContractReplyFromRegistry)();
@ -5265,6 +4497,55 @@ function normalizeOrganizationScopeValue(value) {
.trim();
return unwrapped ? unwrapped : null;
}
const assistantLivingModePolicy = (0, assistantLivingModePolicy_1.createAssistantLivingModePolicy)({
featureAssistantLivingChatRouterV1: config_1.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1,
compactWhitespace,
repairAddressMojibake,
toNonEmptyString,
normalizeOrganizationScopeValue,
hasReferentialPointer,
hasSmallTalkSignal,
hasAssistantCapabilityQuestionSignal,
hasOperationalAdminActionRequestSignal
});
const assistantRoutePolicy = (0, assistantRoutePolicy_1.createAssistantRoutePolicy)({
repairAddressMojibake,
findLastGroundedAddressAnswerDebug,
findLastOrganizationClarificationAddressDebug,
mergeKnownOrganizations,
normalizeOrganizationScopeValue,
resolveOrganizationSelectionFromMessage,
hasAssistantDataScopeMetaQuestionSignal: assistantLivingModePolicy.hasAssistantDataScopeMetaQuestionSignal,
shouldHandleAsAssistantCapabilityMetaQuery: assistantLivingModePolicy.shouldHandleAsAssistantCapabilityMetaQuery,
hasDataRetrievalRequestSignal: assistantLivingModePolicy.hasDataRetrievalRequestSignal,
hasAggregateBusinessAnalyticsSignal,
hasStandaloneAddressTopicSignal,
hasOpenContractsAddressSignal,
detectAddressQuestionMode: addressQueryClassifier_1.detectAddressQuestionMode,
resolveAddressIntent: addressIntentResolver_1.resolveAddressIntent,
toNonEmptyString,
hasStrictDeepInvestigationCue,
hasStrongDataIntentSignal: assistantLivingModePolicy.hasStrongDataIntentSignal,
hasAccountingSignal,
hasDangerOrCoercionSignal,
hasAddressFollowupContextSignal,
hasShortDebtMirrorFollowupSignal,
isInventorySelectedObjectIntent,
hasShortInventoryObjectFollowupSignal,
hasHistoricalCapabilityFollowupSignal: assistantLivingModePolicy.hasHistoricalCapabilityFollowupSignal,
isGroundedInventoryContextDebug,
hasConversationMemoryRecallFollowupSignal: assistantLivingModePolicy.hasConversationMemoryRecallFollowupSignal,
findLastAddressAssistantItem,
hasMetaAnswerFollowupSignal: assistantLivingModePolicy.hasMetaAnswerFollowupSignal,
resolveAddressToolGateDecision,
hasSameDateAccountFollowupSignalForPredecompose,
hasLooseAllTimeAddressLookupSignal,
hasDeepAnalysisPreferenceSignal,
hasDirectDeepAnalysisSignal,
compactWhitespace,
hasDeepSessionContinuationSignal,
resolveLivingAssistantModeDecision: assistantLivingModePolicy.resolveLivingAssistantModeDecision
});
function normalizeOrganizationScopeSearchText(value) {
const source = normalizeScopeKey(value);
return source
@ -6063,67 +5344,7 @@ function applyLivingChatGroundingGuard(input) {
};
}
export function resolveLivingAssistantModeDecision(input) {
const userMessage = String(input?.userMessage ?? "");
if (input?.addressLaneTriggered) {
return {
mode: "address_data",
reason: "address_lane_triggered"
};
}
if (!config_1.FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1) {
return {
mode: "deep_analysis",
reason: "living_chat_router_disabled"
};
}
if (Boolean(input?.useMock)) {
return {
mode: "deep_analysis",
reason: "mock_mode_keeps_deep_pipeline"
};
}
if (hasAssistantDataScopeMetaQuestionSignal(userMessage)) {
return {
mode: "chat",
reason: "assistant_data_scope_query_detected"
};
}
if (shouldHandleAsAssistantCapabilityMetaQuery(userMessage)) {
return {
mode: "chat",
reason: "assistant_capability_query_detected"
};
}
if (hasOrganizationFactLookupSignal(userMessage) || hasOrganizationFactFollowupSignal(userMessage)) {
return {
mode: "chat",
reason: "organization_fact_lookup_signal_detected"
};
}
if (hasStrongDataIntentSignal(userMessage)) {
return {
mode: "deep_analysis",
reason: "strong_data_signal_detected"
};
}
if (hasLivingChatSignal(userMessage)) {
return {
mode: "chat",
reason: "living_chat_signal_detected"
};
}
const predecomposeMode = toNonEmptyString(input?.predecomposeMode);
const predecomposeConfidence = toNonEmptyString(input?.predecomposeModeConfidence);
if (predecomposeMode === "unsupported" && (predecomposeConfidence === "low" || predecomposeConfidence === "medium")) {
return {
mode: "deep_analysis",
reason: "predecompose_unsupported_mode_fallback_to_deep"
};
}
return {
mode: "deep_analysis",
reason: "default_deep_pipeline"
};
return assistantLivingModePolicy.resolveLivingAssistantModeDecision(input);
}
export class AssistantService {
normalizerService;

View File

@ -0,0 +1,81 @@
import { describe, expect, it } from "vitest";
import { createAssistantLivingModePolicy } from "../src/services/assistantLivingModePolicy";
function buildPolicy() {
return createAssistantLivingModePolicy({
featureAssistantLivingChatRouterV1: true,
compactWhitespace: (text: string) => text.replace(/\s+/g, " ").trim(),
repairAddressMojibake: (text: string) => text,
toNonEmptyString: (value: unknown) => {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
},
normalizeOrganizationScopeValue: (value: unknown) => {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim().replace(/^"+|"+$/g, "").replace(/^'+|'+$/g, "");
return text.length > 0 ? text : null;
},
hasReferentialPointer: (text: string) =>
/(по этому|по тому|это же|этой|этим|этому|этого|этот|эту|этом|это|эти|этих|из этого|из них|из этих|из тех|в этом|тот же|same thing|that one|po etomu|po tomu)/i.test(
text.toLowerCase()
),
hasSmallTalkSignal: (text: string) => /(привет|как дела|спасибо|благодарю|thanks|thank you|hello|hi)\b/i.test(text.toLowerCase()),
hasAssistantCapabilityQuestionSignal: (text: string) =>
/(?:кто ты|что ты можешь|какие фичи|полный список возможностей|чем ты можешь помочь|что ты умеешь)/i.test(text),
hasOperationalAdminActionRequestSignal: (text: string) =>
/(?:настро|установ|подключ|обнов|почин|исправ|удал|снеси|delete\s+database|drop\s+database)/i.test(text)
});
}
describe("assistantLivingModePolicy", () => {
it("routes data-scope question to chat mode", () => {
const policy = buildPolicy();
const decision = policy.resolveLivingAssistantModeDecision({
userMessage: "по какой компании мы можем работать?",
addressLaneTriggered: false,
useMock: false,
predecomposeMode: "unsupported",
predecomposeModeConfidence: "low"
});
expect(decision.mode).toBe("chat");
expect(decision.reason).toBe("assistant_data_scope_query_detected");
});
it("keeps explicit accounting question in deep mode", () => {
const policy = buildPolicy();
const decision = policy.resolveLivingAssistantModeDecision({
userMessage: "покажи документы по сверке за 2020",
addressLaneTriggered: false,
useMock: false,
predecomposeMode: "unsupported",
predecomposeModeConfidence: "low"
});
expect(decision.mode).toBe("deep_analysis");
expect(decision.reason).toBe("strong_data_signal_detected");
});
it("detects organization fact follow-up after prior boundary reply", () => {
const policy = buildPolicy();
const detected = policy.hasOrganizationFactFollowupSignal("давай", [
{
role: "assistant",
debug: {
living_chat_response_source: "deterministic_organization_fact_boundary",
living_chat_grounding_guard_reason: null
}
}
]);
expect(detected).toBe(true);
});
});

View File

@ -0,0 +1,147 @@
import { describe, expect, it } from "vitest";
import { createAssistantRoutePolicy } from "../src/services/assistantRoutePolicy";
function toNonEmptyString(value: unknown): string | null {
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function normalizeOrganizationScopeValue(value: unknown): string | null {
const text = toNonEmptyString(value);
if (!text) {
return null;
}
return text.replace(/^"+|"+$/g, "").replace(/^'+|'+$/g, "");
}
function buildPolicy(overrides: Record<string, unknown> = {}) {
return createAssistantRoutePolicy({
repairAddressMojibake: (text: string) => text,
findLastGroundedAddressAnswerDebug: () => null,
findLastOrganizationClarificationAddressDebug: () => null,
mergeKnownOrganizations: (values: unknown[]) =>
Array.from(
new Set(
(Array.isArray(values) ? values : [])
.map((item) => normalizeOrganizationScopeValue(item))
.filter((item): item is string => Boolean(item))
)
),
normalizeOrganizationScopeValue,
resolveOrganizationSelectionFromMessage: () => null,
hasAssistantDataScopeMetaQuestionSignal: (text: string) => /по какой компании|какая база|по каким конторам/i.test(text),
shouldHandleAsAssistantCapabilityMetaQuery: (text: string) => /что ты можешь|что ты умеешь/i.test(text),
hasDataRetrievalRequestSignal: () => false,
hasAggregateBusinessAnalyticsSignal: () => false,
hasStandaloneAddressTopicSignal: () => false,
hasOpenContractsAddressSignal: () => false,
detectAddressQuestionMode: () => ({ mode: "unsupported", confidence: "low" }),
resolveAddressIntent: () => ({ intent: "unknown", confidence: "low" }),
toNonEmptyString,
hasStrictDeepInvestigationCue: () => false,
hasStrongDataIntentSignal: () => false,
hasAccountingSignal: () => false,
hasDangerOrCoercionSignal: () => false,
hasAddressFollowupContextSignal: () => false,
hasShortDebtMirrorFollowupSignal: () => false,
isInventorySelectedObjectIntent: (intent: unknown) => /inventory/i.test(String(intent ?? "")),
hasShortInventoryObjectFollowupSignal: () => false,
hasHistoricalCapabilityFollowupSignal: () => false,
isGroundedInventoryContextDebug: (debug: unknown) => Boolean(debug),
hasConversationMemoryRecallFollowupSignal: () => false,
findLastAddressAssistantItem: () => null,
hasMetaAnswerFollowupSignal: () => false,
resolveAddressToolGateDecision: () => ({
runAddressLane: false,
decision: "skip_address_lane",
reason: "no_address_signal_after_l0"
}),
hasSameDateAccountFollowupSignalForPredecompose: () => false,
hasLooseAllTimeAddressLookupSignal: () => false,
hasDeepAnalysisPreferenceSignal: () => false,
hasDirectDeepAnalysisSignal: () => false,
compactWhitespace: (text: string) => String(text ?? "").replace(/\s+/g, " ").trim(),
hasDeepSessionContinuationSignal: () => false,
resolveLivingAssistantModeDecision: (input: { addressLaneTriggered?: boolean }) =>
input.addressLaneTriggered
? { mode: "address_data", reason: "address_lane_triggered" }
: { mode: "chat", reason: "living_chat_signal_detected" },
...overrides
});
}
describe("assistantRoutePolicy", () => {
it("routes data-scope meta question to chat contract", () => {
const policy = buildPolicy();
const decision = policy.resolveAssistantOrchestrationDecision({
rawUserMessage: "по какой компании мы можем работать?",
effectiveAddressUserMessage: "по какой компании мы можем работать?",
followupContext: null,
llmPreDecomposeMeta: null,
useMock: false
});
expect(decision.runAddressLane).toBe(false);
expect(decision.toolGateReason).toBe("assistant_data_scope_query_detected");
expect(decision.livingMode).toBe("chat");
expect(decision.orchestrationContract?.hard_meta_mode).toBe("data_scope");
});
it("keeps supported address intent in address lane", () => {
const policy = buildPolicy({
detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }),
resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date", confidence: "high" }),
resolveAddressToolGateDecision: () => ({
runAddressLane: true,
decision: "run_address_lane",
reason: "address_mode_classifier_detected"
})
});
const decision = policy.resolveAssistantOrchestrationDecision({
rawUserMessage: "какие товары сейчас лежат на складе",
effectiveAddressUserMessage: "какие товары сейчас лежат на складе",
followupContext: null,
llmPreDecomposeMeta: null,
useMock: false
});
expect(decision.runAddressLane).toBe(true);
expect(decision.toolGateReason).toBe("address_mode_classifier_detected");
expect(decision.livingMode).toBe("address_data");
expect(decision.orchestrationContract?.semantic_route_arbitration?.supported_address_intent_detected).toBe(true);
});
it("routes memory recap follow-up over grounded answer to chat", () => {
const policy = buildPolicy({
hasConversationMemoryRecallFollowupSignal: () => true,
findLastGroundedAddressAnswerDebug: () => ({ execution_lane: "address_query" })
});
const decision = policy.resolveAssistantOrchestrationDecision({
rawUserMessage: "а ты помнишь что мы обсуждали?",
effectiveAddressUserMessage: "а ты помнишь что мы обсуждали?",
followupContext: null,
llmPreDecomposeMeta: {
applied: false,
reason: "normalized_fragment_rejected_semantic_guard",
predecomposeContract: {
mode: "unsupported",
mode_confidence: "low",
intent: "unknown",
intent_confidence: "low"
}
},
useMock: false
});
expect(decision.runAddressLane).toBe(false);
expect(decision.toolGateReason).toBe("memory_recap_followup_detected");
expect(decision.livingMode).toBe("chat");
expect(decision.livingReason).toBe("memory_recap_followup_detected");
});
});