"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAssistantLivingModePolicy = createAssistantLivingModePolicy; function createAssistantLivingModePolicy(deps) { const { featureAssistantLivingChatRouterV1, compactWhitespace, repairAddressMojibake, toNonEmptyString, normalizeOrganizationScopeValue, hasReferentialPointer, hasSmallTalkSignal, hasAssistantCapabilityQuestionSignal, hasOperationalAdminActionRequestSignal, resolveProviderExecutionState } = 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)); const hasExplicitRecapPrompt = samples.some((sample) => /(?:что\s+мы\s+.*(?:обсуждали|выяснили)|что\s+уже\s+выяснили|напомни\s+что\s+мы|what\s+we\s+already\s+(?:discussed|figured\s+out))/iu.test(sample)); if (!hasMemoryCue || !(hasDiscussionCue || hasExplicitRecapPrompt)) { return false; } if (hasExplicitRecapPrompt) { return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) || shouldHandleAsAssistantCapabilityMetaQuery(sample)); } 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" }; } const providerExecution = resolveProviderExecutionState({ llmProvider: input?.llmProvider, useMock: input?.useMock }); if (providerExecution.living_mode_forced_deep) { return { mode: "deep_analysis", reason: providerExecution.living_mode_forced_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 }; }