"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runAssistantLivingChatRuntime = runAssistantLivingChatRuntime; const assistantMemoryRecapPolicy_1 = require("./assistantMemoryRecapPolicy"); const assistantContinuityPolicy_1 = require("./assistantContinuityPolicy"); const assistantMcpDiscoveryDebugAttachment_1 = require("./assistantMcpDiscoveryDebugAttachment"); const assistantMcpDiscoveryResponsePolicy_1 = require("./assistantMcpDiscoveryResponsePolicy"); function hasPriorAssistantTurn(items) { if (!Array.isArray(items)) { return false; } return items.some((item) => item && typeof item === "object" && item.role === "assistant"); } function shouldProbeBareOrganizationScopeCandidate(input) { if (input.selectedOrganization || input.activeOrganization || input.dataScopeMetaQuery || input.capabilityMetaQuery || input.destructiveSignal || input.dangerSignal || input.operationalSignal) { return false; } const raw = String(input.userMessage ?? "").trim(); if (!raw || raw.length > 80 || /[?!]/u.test(raw) || /\d/u.test(raw) || !/\p{L}/u.test(raw)) { return false; } const tokenCount = raw.split(/\s+/u).filter(Boolean).length; if (tokenCount < 1 || tokenCount > 5) { return false; } const normalized = raw .toLowerCase() .replace(/\u0451/gu, "\u0435") .replace(/\s+/gu, " ") .trim(); if (/^(?:\u043f\u0440\u0438\u0432\u0435\u0442|\u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439|\u0437\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435|\u0434\u0430|\u043d\u0435\u0442|\u043e\u043a|\u043e\u043a\u0435\u0439|\u0441\u043f\u0430\u0441\u0438\u0431\u043e|\u043f\u043e\u043a\u0430|\u0433\u043e|\u0434\u0430\u043b\u044c\u0448\u0435|\u043f\u043e\u043d\u044f\u043b|\u043f\u043e\u043d\u044f\u043b\u0430)(?:\s|$)/iu.test(normalized)) { return false; } return !/(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u043f\u043e\u043a\u0430\u0436\u0438|\u0434\u0430\u0439|\u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0438|\u0447\u0442\u043e|\u043a\u0430\u043a|\u0433\u0434\u0435|\u043a\u043e\u0433\u0434\u0430|\u043f\u043e\u0447\u0435\u043c\u0443|\u0437\u0430\u0447\u0435\u043c|\u043c\u043e\u0436\u0435\u0448\u044c|\u0443\u043c\u0435\u0435\u0448\u044c|\u043d\u0430\u0434\u043e|\u043d\u0443\u0436\u043d\u043e|\u0445\u043e\u0447\u0443|\u043e\u0441\u0442\u0430\u0442\u043a|\u043d\u0434\u0441|\u0434\u043e\u043b\u0433|\u0434\u0435\u0431\u0438\u0442\u043e\u0440|\u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0440|\u0441\u043a\u043b\u0430\u0434|\u0442\u043e\u0432\u0430\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442|\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\u043a|\u043f\u0440\u0438\u0431\u044b\u043b)/iu.test(normalized); } function buildDeterministicSmalltalkLeadReply() { return "\u041f\u0440\u0438\u0432\u0435\u0442! \u0412\u0441\u0451 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e."; } function hasConversationExecutiveSummarySignal(value) { const normalized = String(value ?? "") .toLowerCase() .replace(/\u0451/gu, "\u0435") .replace(/\s+/g, " ") .trim(); return /(?:executive\s+summary|финальн\w*\s+собери|итогов\w*\s+(?:резюм|summary|вывод)|по\s+всему\s+диалогу|где\s+ответы\s+были\s+подтвержден|где\s+proxy|где\s+прокси|не\s+хватил\w*\s+доказательств|ручн\w*\s+(?:смотр|провер|контрол))/iu.test(normalized); } function asRecord(value) { return value && typeof value === "object" && !Array.isArray(value) ? value : null; } function firstMeaningEntityLabel(assistantTurnMeaning) { const candidates = Array.isArray(assistantTurnMeaning?.explicit_entity_candidates) ? assistantTurnMeaning?.explicit_entity_candidates : []; for (const candidate of candidates) { const record = asRecord(candidate); const value = typeof record?.value === "string" ? record.value.trim() : ""; if (value.length > 0) { return value; } } return null; } function buildUnsupportedCurrentTurnMeaningBoundaryReply(input) { const family = typeof input.assistantTurnMeaning?.unsupported_but_understood_family === "string" ? input.assistantTurnMeaning.unsupported_but_understood_family : null; const entityLabel = firstMeaningEntityLabel(input.assistantTurnMeaning); if (family === "counterparty_value_or_turnover") { const entityPart = entityLabel ? ` \u043f\u043e \u00ab${entityLabel}\u00bb` : ""; return [ `\u042f \u043f\u043e\u043d\u044f\u043b \u0432\u043e\u043f\u0440\u043e\u0441: \u043d\u0443\u0436\u0435\u043d \u043e\u0431\u043e\u0440\u043e\u0442${entityPart}.`, "\u0422\u043e\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u0447\u0451\u0442\u0430 \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0448\u043b\u044b\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0438\u043b\u0438 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u0430.", "\u041c\u043e\u0433\u0443 \u043f\u043e\u043a\u0430 \u043d\u0430\u0434\u0451\u0436\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b, \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u044b \u0438\u043b\u0438 \u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u0443." ].join(" "); } return "\u042f \u043f\u043e\u043d\u044f\u043b \u0441\u043c\u044b\u0441\u043b \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u0430, \u043d\u043e \u0442\u043e\u0447\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d. \u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435."; } async function runAssistantLivingChatRuntime(input) { const userMessage = String(input.userMessage ?? ""); const organizationAuthority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({ sessionItems: input.sessionItems, sessionKnownOrganizations: Array.isArray(input.sessionScope.knownOrganizations) ? input.sessionScope.knownOrganizations : [], sessionSelectedOrganization: input.sessionScope.selectedOrganization, sessionActiveOrganization: input.sessionScope.activeOrganization, toNonEmptyString: input.toNonEmptyString, normalizeOrganizationScopeValue: input.toNonEmptyString, mergeKnownOrganizations: input.mergeKnownOrganizations }); const continuitySnapshot = organizationAuthority.continuitySnapshot; const dataScopeMetaQuery = input.hasAssistantDataScopeMetaQuestionSignal(userMessage); const capabilityMetaQuery = input.shouldHandleAsAssistantCapabilityMetaQuery(userMessage); const destructiveSignal = input.hasDestructiveDataActionSignal(userMessage); const dangerSignal = input.hasDangerOrCoercionSignal(userMessage); const operationalSignal = input.hasOperationalAdminActionRequestSignal(userMessage); let dataScopeProbe = null; let chatText = ""; let livingChatSource = "llm_chat"; let livingChatScriptGuardApplied = false; let livingChatScriptGuardReason = null; let livingChatGroundingGuardApplied = false; let livingChatGroundingGuardReason = null; let livingChatProactiveScopeOfferApplied = false; let livingChatBareScopeProbeAttempted = false; let livingChatBareScopeProbeMatchedOrganization = null; const continuityActiveOrganization = organizationAuthority.continuityActiveOrganization; let knownOrganizations = [...organizationAuthority.knownOrganizations]; let selectedOrganization = organizationAuthority.selectedOrganization; let activeOrganization = organizationAuthority.activeOrganization; const addressRuntimeMeta = (input.addressRuntimeMeta && typeof input.addressRuntimeMeta === "object" ? input.addressRuntimeMeta : {}); const orchestrationContract = asRecord(addressRuntimeMeta.orchestrationContract); const assistantTurnMeaning = asRecord(orchestrationContract?.assistant_turn_meaning); const unsupportedCurrentTurnMeaningBoundary = Boolean(input.modeDecision?.reason === "unsupported_current_turn_meaning_boundary" || orchestrationContract?.unsupported_current_turn_meaning_boundary === true); const memoryRecapContext = (0, assistantMemoryRecapPolicy_1.resolveAssistantLivingChatMemoryContext)({ modeDecisionReason: input.modeDecision?.reason ?? null, sessionItems: input.sessionItems }); const contextualInventoryHistoryCapabilityFollowup = memoryRecapContext.contextualInventoryHistoryCapabilityFollowup; const contextualMemoryRecapFollowup = memoryRecapContext.contextualMemoryRecapFollowup; const contextualAnswerInspectionFollowup = memoryRecapContext.contextualAnswerInspectionFollowup; const lastGroundedInventoryAddressDebug = memoryRecapContext.lastGroundedInventoryAddressDebug; const lastMemoryAddressDebug = memoryRecapContext.lastMemoryAddressDebug; const lastAnswerInspectionAddressDebug = memoryRecapContext.lastAnswerInspectionAddressDebug; if (shouldProbeBareOrganizationScopeCandidate({ userMessage, selectedOrganization, activeOrganization, dataScopeMetaQuery, capabilityMetaQuery, destructiveSignal, dangerSignal, operationalSignal })) { dataScopeProbe = await input.resolveDataScopeProbe(); livingChatBareScopeProbeAttempted = true; knownOrganizations = input.mergeKnownOrganizations([ ...knownOrganizations, ...(Array.isArray(dataScopeProbe?.organizations) ? dataScopeProbe.organizations : []) ]); const probedOrganization = input.resolveOrganizationSelectionFromMessage(userMessage, knownOrganizations); if (probedOrganization) { selectedOrganization = probedOrganization; activeOrganization = probedOrganization; livingChatBareScopeProbeMatchedOrganization = probedOrganization; } } if (capabilityMetaQuery && (destructiveSignal || dangerSignal)) { chatText = input.buildAssistantSafetyRefusalReply(); livingChatSource = "deterministic_safety_refusal"; } else if (dataScopeMetaQuery) { dataScopeProbe = await input.resolveDataScopeProbe(); chatText = input.buildAssistantDataScopeContractReply(dataScopeProbe); knownOrganizations = input.mergeKnownOrganizations([ ...knownOrganizations, ...(Array.isArray(dataScopeProbe?.organizations) ? dataScopeProbe.organizations : []) ]); if (!activeOrganization && knownOrganizations.length === 1) { activeOrganization = knownOrganizations[0]; } livingChatSource = dataScopeProbe?.status === "resolved" ? "deterministic_data_scope_contract_live" : "deterministic_data_scope_contract"; } else if (unsupportedCurrentTurnMeaningBoundary) { const unsupportedFamily = typeof assistantTurnMeaning?.unsupported_but_understood_family === "string" ? assistantTurnMeaning.unsupported_but_understood_family : null; if (unsupportedFamily === "broad_business_evaluation") { const scopedOrganization = selectedOrganization ?? activeOrganization ?? continuityActiveOrganization ?? null; chatText = (0, assistantMemoryRecapPolicy_1.buildBroadBusinessEvaluationReply)({ organization: scopedOrganization, addressDebug: continuitySnapshot.lastGroundedAddressDebug, sessionItems: input.sessionItems, toNonEmptyString: input.toNonEmptyString }); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_broad_business_evaluation_contract"; } else { chatText = buildUnsupportedCurrentTurnMeaningBoundaryReply({ assistantTurnMeaning }); livingChatSource = "deterministic_unsupported_current_turn_boundary"; } } else if ((selectedOrganization || activeOrganization) && input.hasOrganizationFactLookupSignal(userMessage)) { const scopedOrganization = selectedOrganization ?? activeOrganization ?? null; chatText = input.buildAssistantOrganizationFactBoundaryReply(scopedOrganization); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_organization_fact_boundary"; } else if ((selectedOrganization || activeOrganization) && input.hasOrganizationFactFollowupSignal(userMessage, input.sessionItems)) { const scopedOrganization = selectedOrganization ?? activeOrganization ?? null; chatText = input.buildAssistantOrganizationFactBoundaryReply(scopedOrganization); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_organization_fact_boundary_followup"; } else if (!capabilityMetaQuery && input.shouldEmitOrganizationSelectionReply(userMessage, selectedOrganization ?? activeOrganization)) { const scopedOrganization = selectedOrganization ?? activeOrganization ?? null; chatText = input.buildAssistantDataScopeSelectionReply(scopedOrganization); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_data_scope_selection_contract"; } else if (capabilityMetaQuery && operationalSignal && !input.hasAssistantCapabilityQuestionSignal(userMessage)) { chatText = input.buildAssistantOperationalBoundaryReply(); livingChatSource = "deterministic_operational_boundary"; } else if (contextualInventoryHistoryCapabilityFollowup) { const scopedOrganization = selectedOrganization ?? activeOrganization ?? null; chatText = (0, assistantMemoryRecapPolicy_1.buildInventoryHistoryCapabilityFollowupReply)({ organization: scopedOrganization, addressDebug: lastGroundedInventoryAddressDebug, toNonEmptyString: input.toNonEmptyString }); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_inventory_history_capability_contract"; } else if (contextualMemoryRecapFollowup) { const scopedOrganization = selectedOrganization ?? activeOrganization ?? continuityActiveOrganization ?? null; const executiveSummaryFollowup = hasConversationExecutiveSummarySignal(userMessage); chatText = executiveSummaryFollowup ? (0, assistantMemoryRecapPolicy_1.buildConversationExecutiveSummaryReply)({ organization: scopedOrganization, addressDebug: lastMemoryAddressDebug, sessionItems: input.sessionItems, toNonEmptyString: input.toNonEmptyString }) : (0, assistantMemoryRecapPolicy_1.buildAddressMemoryRecapReply)({ organization: scopedOrganization, addressDebug: lastMemoryAddressDebug, sessionItems: input.sessionItems, userMessage, toNonEmptyString: input.toNonEmptyString }); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = executiveSummaryFollowup ? "deterministic_conversation_executive_summary_contract" : "deterministic_memory_recap_contract"; } else if (contextualAnswerInspectionFollowup) { chatText = (0, assistantMemoryRecapPolicy_1.buildSelectedObjectAnswerInspectionReply)({ addressDebug: lastAnswerInspectionAddressDebug, sessionItems: input.sessionItems, toNonEmptyString: input.toNonEmptyString }); livingChatSource = "deterministic_answer_inspection_contract"; } else if (capabilityMetaQuery) { chatText = input.buildAssistantCapabilityContractReply(userMessage); livingChatSource = "deterministic_capability_contract"; } else { chatText = await input.executeLlmChat(); const scriptGuard = input.applyScriptGuard(chatText, userMessage); chatText = scriptGuard.text; if (scriptGuard.applied) { livingChatScriptGuardApplied = true; livingChatScriptGuardReason = scriptGuard.reason; livingChatSource = "llm_chat_script_guard"; } const groundingGuard = input.applyGroundingGuard({ userMessage, chatText, organization: activeOrganization ?? selectedOrganization ?? null }); chatText = groundingGuard.text; if (groundingGuard.applied) { livingChatGroundingGuardApplied = true; livingChatGroundingGuardReason = groundingGuard.reason; livingChatSource = "llm_chat_grounding_guard"; } const shouldOfferProactiveOrganizationScope = !selectedOrganization && !activeOrganization && !continuitySnapshot.hasGroundedAddressContext && !hasPriorAssistantTurn(input.sessionItems) && input.modeDecision?.mode === "chat" && input.hasLivingChatSignal(userMessage); if (shouldOfferProactiveOrganizationScope) { const proactiveScopeProbe = await input.resolveDataScopeProbe(); const mergedKnownOrganizations = input.mergeKnownOrganizations([ ...knownOrganizations, ...(Array.isArray(proactiveScopeProbe?.organizations) ? proactiveScopeProbe.organizations : []) ]); knownOrganizations = mergedKnownOrganizations; if (!activeOrganization && mergedKnownOrganizations.length === 1) { activeOrganization = mergedKnownOrganizations[0]; } const proactiveOffer = input.buildAssistantProactiveOrganizationOfferReply(proactiveScopeProbe); if (proactiveOffer) { chatText = [buildDeterministicSmalltalkLeadReply(), proactiveOffer] .filter((part) => String(part ?? "").trim().length > 0) .join(" "); livingChatProactiveScopeOfferApplied = true; livingChatSource = "deterministic_smalltalk_with_proactive_scope_offer"; if (!dataScopeProbe) { dataScopeProbe = proactiveScopeProbe; } } } } if (!chatText) { return { handled: false, chatText: "", debug: null }; } const mcpDiscoveryResponsePolicy = (0, assistantMcpDiscoveryResponsePolicy_1.applyAssistantMcpDiscoveryResponsePolicy)({ currentReply: chatText, currentReplySource: livingChatSource, livingChatSource, modeDecisionReason: input.modeDecision?.reason ?? null, addressRuntimeMeta }); if (mcpDiscoveryResponsePolicy.applied) { chatText = mcpDiscoveryResponsePolicy.reply_text; livingChatSource = mcpDiscoveryResponsePolicy.reply_source; } const predecomposeContract = addressRuntimeMeta.predecomposeContract && typeof addressRuntimeMeta.predecomposeContract === "object" ? addressRuntimeMeta.predecomposeContract : null; const semanticExtractionContract = addressRuntimeMeta.semanticExtractionContract && typeof addressRuntimeMeta.semanticExtractionContract === "object" ? addressRuntimeMeta.semanticExtractionContract : null; const debug = { trace_id: input.traceIdFactory(), prompt_version: "living_chat_router_v1", schema_version: "living_chat_router_v1", fallback_type: "none", detected_mode: "chat", detected_mode_confidence: "high", execution_lane: "living_chat", living_router_mode: input.modeDecision?.mode ?? "chat", living_router_reason: input.modeDecision?.reason ?? "living_chat_signal_detected", living_chat_response_source: livingChatSource, mcp_discovery_response_policy_v1: mcpDiscoveryResponsePolicy, mcp_discovery_response_candidate_v1: mcpDiscoveryResponsePolicy.candidate, mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied, living_chat_script_guard_applied: livingChatScriptGuardApplied, living_chat_script_guard_reason: livingChatScriptGuardReason, living_chat_grounding_guard_applied: livingChatGroundingGuardApplied, living_chat_grounding_guard_reason: livingChatGroundingGuardReason, living_chat_proactive_scope_offer_applied: livingChatProactiveScopeOfferApplied, living_chat_bare_scope_probe_attempted: livingChatBareScopeProbeAttempted, living_chat_bare_scope_probe_matched_organization: livingChatBareScopeProbeMatchedOrganization, living_chat_data_scope_probe_status: dataScopeProbe?.status ?? null, living_chat_data_scope_probe_channel: dataScopeProbe?.channel ?? null, living_chat_data_scope_probe_org_count: Array.isArray(dataScopeProbe?.organizations) ? dataScopeProbe.organizations.length : 0, living_chat_data_scope_probe_organizations: Array.isArray(dataScopeProbe?.organizations) ? input.mergeKnownOrganizations(dataScopeProbe.organizations) : [], living_chat_data_scope_probe_error: dataScopeProbe?.error ?? null, living_chat_continuity_grounded_context_detected: continuitySnapshot.hasGroundedAddressContext, living_chat_continuity_active_organization: continuityActiveOrganization, living_chat_selected_organization: selectedOrganization ?? null, assistant_known_organizations: knownOrganizations, assistant_active_organization: activeOrganization ?? null, address_llm_predecompose_attempted: Boolean(addressRuntimeMeta.attempted), address_llm_predecompose_applied: Boolean(addressRuntimeMeta.applied), address_llm_predecompose_reason: addressRuntimeMeta.reason ?? null, address_llm_predecompose_contract: predecomposeContract, address_semantic_extraction_contract: semanticExtractionContract, orchestration_contract_v1: addressRuntimeMeta.orchestrationContract ?? null, tool_gate_decision: addressRuntimeMeta.toolGateDecision ?? null, tool_gate_reason: addressRuntimeMeta.toolGateReason ?? null, normalized: null, normalizer_output: null }; return { handled: true, chatText, debug: (0, assistantMcpDiscoveryDebugAttachment_1.attachAssistantMcpDiscoveryDebug)(debug, { addressRuntimeMeta }) }; }