"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runAssistantLivingChatRuntime = runAssistantLivingChatRuntime; const assistantMemoryRecapPolicy_1 = require("./assistantMemoryRecapPolicy"); function formatIsoDateForReply(value) { const source = String(value ?? "").trim(); const match = source.match(/^(\d{4})-(\d{2})-(\d{2})$/); if (!match) { return null; } return `${match[3]}.${match[2]}.${match[1]}`; } function findLastGroundedInventoryAddressDebug(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" || !item.debug || typeof item.debug !== "object") { continue; } const debug = item.debug; const answerGroundingCheck = debug.answer_grounding_check && typeof debug.answer_grounding_check === "object" ? debug.answer_grounding_check : null; const groundingStatus = String(answerGroundingCheck?.status ?? ""); const detectedIntent = String(debug.detected_intent ?? ""); const capabilityId = String(debug.capability_id ?? ""); const rootFrameContext = debug.address_root_frame_context && typeof debug.address_root_frame_context === "object" ? debug.address_root_frame_context : null; const rootIntent = String(rootFrameContext?.root_intent ?? ""); const isInventoryContext = detectedIntent === "inventory_on_hand_as_of_date" || capabilityId === "confirmed_inventory_on_hand_as_of_date" || rootIntent === "inventory_on_hand_as_of_date"; if (groundingStatus === "grounded" && isInventoryContext) { return debug; } } return null; } function findLastAddressDebugWithItem(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" || !item.debug || typeof item.debug !== "object") { continue; } const debug = item.debug; if (String(debug.execution_lane ?? "") !== "address_query") { continue; } const extractedFilters = debug.extracted_filters && typeof debug.extracted_filters === "object" ? debug.extracted_filters : null; const itemLabel = String(extractedFilters?.item ?? "").trim() || (String(debug.anchor_type ?? "") === "item" ? String(debug.anchor_value_resolved ?? debug.anchor_value_raw ?? "").trim() : ""); if (itemLabel) { return debug; } } return null; } function findLastAddressDebug(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" || !item.debug || typeof item.debug !== "object") { continue; } if (String(item.debug.execution_lane ?? "") === "address_query") { return item.debug; } } return null; } function buildInventoryHistoryCapabilityFollowupReply(input) { const rootFrameContext = input.addressDebug?.address_root_frame_context && typeof input.addressDebug.address_root_frame_context === "object" ? input.addressDebug.address_root_frame_context : null; const extractedFilters = input.addressDebug?.extracted_filters && typeof input.addressDebug.extracted_filters === "object" ? input.addressDebug.extracted_filters : null; const organization = input.organization ?? input.toNonEmptyString(rootFrameContext?.organization) ?? input.toNonEmptyString(extractedFilters?.organization); const lastAsOfDate = formatIsoDateForReply(rootFrameContext?.as_of_date) ?? formatIsoDateForReply(extractedFilters?.as_of_date); const organizationPart = organization ? ` по компании «${organization}»` : ""; const referenceLine = lastAsOfDate ? `Да, могу. Сейчас мы уже смотрели складской срез${organizationPart} на ${lastAsOfDate}.` : `Да, могу показать исторические данные${organizationPart} в этом же складском контуре.`; return [ referenceLine, `Могу показать исторические остатки${organizationPart} за нужный месяц, дату или год.`, "Например:", "- `на март 2020`", "- `на июнь 2016`", "- `за 2017 год`", "- `сравни июнь 2016 с текущим срезом`", "Если хочешь, сразу покажу нужный исторический период." ].join("\n"); } function buildAddressMemoryRecapReply(input) { const extractedFilters = input.addressDebug?.extracted_filters && typeof input.addressDebug.extracted_filters === "object" ? input.addressDebug.extracted_filters : null; const rootFrameContext = input.addressDebug?.address_root_frame_context && typeof input.addressDebug.address_root_frame_context === "object" ? input.addressDebug.address_root_frame_context : null; const item = input.toNonEmptyString(extractedFilters?.item) ?? (String(input.addressDebug?.anchor_type ?? "") === "item" ? input.toNonEmptyString(input.addressDebug?.anchor_value_resolved) ?? input.toNonEmptyString(input.addressDebug?.anchor_value_raw) : null); const organization = input.organization ?? input.toNonEmptyString(extractedFilters?.organization) ?? input.toNonEmptyString(rootFrameContext?.organization); const scopedDate = formatIsoDateForReply(extractedFilters?.as_of_date) ?? formatIsoDateForReply(rootFrameContext?.as_of_date) ?? formatIsoDateForReply(extractedFilters?.period_to); if (item) { const datePart = scopedDate ? ` в срезе на ${scopedDate}` : ""; const organizationPart = organization ? ` по компании «${organization}»` : ""; return [ `Да, помню. Мы обсуждали позицию «${item}»${organizationPart}${datePart}.`, "Могу продолжить по ней без переписывания сущности: кто поставил, когда купили, по каким документам или кому продали." ].join(" "); } if (organization || scopedDate) { const organizationPart = organization ? ` по компании «${organization}»` : ""; const datePart = scopedDate ? ` на ${scopedDate}` : ""; return [ `Да, помню. Мы уже смотрели адресный контур${organizationPart}${datePart}.`, "Могу кратко напомнить контекст или сразу продолжить следующий шаг по этому же сценарию." ].join(" "); } return "Да, помню предыдущий адресный контур. Могу кратко напомнить, что мы уже подтвердили, или сразу продолжить следующий шаг."; } async function runAssistantLivingChatRuntime(input) { const userMessage = String(input.userMessage ?? ""); 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 knownOrganizations = input.mergeKnownOrganizations(input.sessionScope.knownOrganizations ?? []); let selectedOrganization = input.toNonEmptyString(input.sessionScope.selectedOrganization); let activeOrganization = input.toNonEmptyString(input.sessionScope.activeOrganization); const memoryRecapContext = (0, assistantMemoryRecapPolicy_1.resolveAssistantLivingChatMemoryContext)({ modeDecisionReason: input.modeDecision?.reason ?? null, sessionItems: input.sessionItems }); const contextualInventoryHistoryCapabilityFollowup = memoryRecapContext.contextualInventoryHistoryCapabilityFollowup; const contextualMemoryRecapFollowup = memoryRecapContext.contextualMemoryRecapFollowup; const lastGroundedInventoryAddressDebug = memoryRecapContext.lastGroundedInventoryAddressDebug; const lastMemoryAddressDebug = memoryRecapContext.lastMemoryAddressDebug; 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 ((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 ?? null; chatText = (0, assistantMemoryRecapPolicy_1.buildAddressMemoryRecapReply)({ organization: scopedOrganization, addressDebug: lastMemoryAddressDebug, sessionItems: input.sessionItems, toNonEmptyString: input.toNonEmptyString }); activeOrganization = scopedOrganization ?? activeOrganization; livingChatSource = "deterministic_memory_recap_contract"; } else if (capabilityMetaQuery) { chatText = input.buildAssistantCapabilityContractReply(); 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"; } } if (!chatText) { return { handled: false, chatText: "", debug: null }; } const addressRuntimeMeta = (input.addressRuntimeMeta && typeof input.addressRuntimeMeta === "object" ? input.addressRuntimeMeta : {}); 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, 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_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_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 }; }