"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runAssistantAddressLaneResponseRuntime = runAssistantAddressLaneResponseRuntime; const assistantAddressTurnFinalizeRuntimeAdapter_1 = require("./assistantAddressTurnFinalizeRuntimeAdapter"); const assistantCapabilityBindingResponseGuard_1 = require("./assistantCapabilityBindingResponseGuard"); const assistantCapabilityRuntimeBindingAdapter_1 = require("./assistantCapabilityRuntimeBindingAdapter"); const assistantMcpDiscoveryDebugAttachment_1 = require("./assistantMcpDiscoveryDebugAttachment"); const assistantMcpDiscoveryResponsePolicy_1 = require("./assistantMcpDiscoveryResponsePolicy"); const assistantRuntimeContractResolver_1 = require("./assistantRuntimeContractResolver"); const assistantStateTransitionRuntimeAdapter_1 = require("./assistantStateTransitionRuntimeAdapter"); const assistantTruthAnswerPolicyRuntimeAdapter_1 = require("./assistantTruthAnswerPolicyRuntimeAdapter"); function toRecordObject(value) { if (!value || typeof value !== "object") { return null; } return value; } function toNullableString(value) { if (typeof value !== "string") { return null; } const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : null; } function toNullableBoolean(value) { if (typeof value === "boolean") { return value; } return undefined; } function normalizeAddressReplyType(value) { return value === "factual" || value === "partial_coverage" ? value : "partial_coverage"; } function uniqueNormalizedStrings(values) { const result = []; const seen = new Set(); for (const value of values) { const text = String(value ?? "").trim(); if (!text) { continue; } const key = text.toLocaleLowerCase("ru-RU").replace(/ё/g, "е"); if (seen.has(key)) { continue; } seen.add(key); result.push(text); } return result; } function extractInventorySupplierOverlapCounterpartiesFromReply(replyText) { const values = []; const pattern = /\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442:\s*([^|\r\n]+)/giu; for (const match of replyText.matchAll(pattern)) { const value = toNullableString(match[1]?.replace(/[.;,\s]+$/u, "")); if (!value || /^(?:\u043d\u0435\s+\u0432\u044b\u0434\u0435\u043b\u0435\u043d|\u043d\/\u0434|unknown)$/iu.test(value)) { continue; } values.push(value); } return uniqueNormalizedStrings(values); } function formatInventorySupplierOverlapCounterpartyLead(counterparties, limit = 6) { const visible = counterparties.slice(0, limit); const remaining = counterparties.length - visible.length; const suffix = remaining > 0 ? `; и еще ${remaining}` : ""; return `${visible.join("; ")}${suffix}`; } function hasInventorySupplierOverlapDefensiveLead(firstLine) { const normalized = String(firstLine ?? "").toLocaleLowerCase("ru-RU").replace(/\u0451/gu, "\u0435"); const startsWithStockScope = /^\u043f\u043e\s+(?:\u0441\u043a\u043b\u0430\u0434\u0441\u043a\u043e\u043c\u0443\s+\u043e\u0441\u0442\u0430\u0442\u043a\u0443|\u043e\u043a\u043d\u0443)/u.test(normalized); const hasDefensiveAttribution = /\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d(?:\u044b\u0439\s+\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0430\u044f\s+\u0430\u0442\u0440\u0438\u0431\u0443\u0446\u0438\u044f).*?\u043d\u0435\s+\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d/u.test(normalized); return startsWithStockScope && hasDefensiveAttribution; } function firstNonEmptyReplyLine(text) { return String(text ?? "") .split(/\r?\n/u) .map((line) => line.trim()) .find((line) => line.length > 0) ?? ""; } function hasInventorySupplierOverlapCounterpartyLead(firstLine) { const normalized = String(firstLine ?? "").toLocaleLowerCase("ru-RU").replace(/\u0451/gu, "\u0435"); return (/^\u043f\u043e\s+\u0441\u043a\u043b\u0430\u0434\u0441\u043a\u043e\u043c\u0443\s+\u043e\u0441\u0442\u0430\u0442\u043a\u0443/u.test(normalized) && /\u043d\u0430\u0439\u0434\u0435\u043d/u.test(normalized) && /\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a/u.test(normalized) && /\u0437\u0430\u043a\u0443\u043f\u043e\u0447\u043d\u043e\u0433\u043e\s+\u0441\u043b\u0435\u0434\u0430/u.test(normalized)); } function preserveInventorySupplierOverlapCounterpartyLeadAfterSanitize(input) { const debug = toRecordObject(input.addressDebug); const detectedIntent = toNullableString(debug?.detected_intent); if (detectedIntent !== "inventory_supplier_stock_overlap_as_of_date") { return { text: input.sanitizedReply, applied: false }; } const rawLead = firstNonEmptyReplyLine(input.rawReply); if (!hasInventorySupplierOverlapCounterpartyLead(rawLead)) { return { text: input.sanitizedReply, applied: false }; } const sanitizedLead = firstNonEmptyReplyLine(input.sanitizedReply); if (hasInventorySupplierOverlapCounterpartyLead(sanitizedLead)) { return { text: input.sanitizedReply, applied: false }; } const sanitizedText = String(input.sanitizedReply ?? "").trim(); return { text: sanitizedText ? [rawLead, sanitizedText].join("\n\n") : rawLead, applied: true }; } function inspectInventorySupplierOverlapDefensiveLead(firstLine) { const normalized = String(firstLine ?? "").toLocaleLowerCase("ru-RU").replace(/\u0451/gu, "\u0435"); return { stockScopeMatch: /^\u043f\u043e\s+(?:\u0441\u043a\u043b\u0430\u0434\u0441\u043a\u043e\u043c\u0443\s+\u043e\u0441\u0442\u0430\u0442\u043a\u0443|\u043e\u043a\u043d\u0443)/u.test(normalized), defensiveMatch: /\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d(?:\u044b\u0439\s+\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0430\u044f\s+\u0430\u0442\u0440\u0438\u0431\u0443\u0446\u0438\u044f).*?\u043d\u0435\s+\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d/u.test(normalized) }; } function buildInventorySupplierOverlapSurfaceRepairAudit(input) { return { schema_version: "inventory_supplier_overlap_surface_repair_v1", applied: input.applied, detected_intent: input.detectedIntent, counterparties: input.counterparties ?? [], first_line_sample: input.firstLineSample ?? null, stock_scope_match: input.stockScopeMatch ?? null, defensive_match: input.defensiveMatch ?? null, reason_codes: input.reasonCodes }; } function repairInventorySupplierOverlapSurfaceReply(replyText, addressDebug) { const text = String(replyText ?? ""); const debug = toRecordObject(addressDebug); const detectedIntent = toNullableString(debug?.detected_intent); if (detectedIntent !== "inventory_supplier_stock_overlap_as_of_date") { return { text, audit: buildInventorySupplierOverlapSurfaceRepairAudit({ applied: false, detectedIntent, reasonCodes: ["inventory_supplier_overlap_surface_repair_intent_not_applicable"] }) }; } const lines = text.split(/\r?\n/u); const firstLine = lines[0]?.trim() ?? ""; const leadInspection = inspectInventorySupplierOverlapDefensiveLead(firstLine); if (!hasInventorySupplierOverlapDefensiveLead(firstLine)) { return { text, audit: buildInventorySupplierOverlapSurfaceRepairAudit({ applied: false, detectedIntent, firstLineSample: firstLine.slice(0, 220), stockScopeMatch: leadInspection.stockScopeMatch, defensiveMatch: leadInspection.defensiveMatch, reasonCodes: ["inventory_supplier_overlap_surface_repair_first_line_not_defensive"] }) }; } const counterparties = extractInventorySupplierOverlapCounterpartiesFromReply(text); if (counterparties.length === 0) { return { text, audit: buildInventorySupplierOverlapSurfaceRepairAudit({ applied: false, detectedIntent, counterparties, firstLineSample: firstLine.slice(0, 220), stockScopeMatch: leadInspection.stockScopeMatch, defensiveMatch: leadInspection.defensiveMatch, reasonCodes: ["inventory_supplier_overlap_surface_repair_no_counterparties"] }) }; } const repairedLead = counterparties.length === 1 ? `По складскому остатку найден поставщик закупочного следа: ${counterparties[0]}.` : `По складскому остатку найдено несколько поставщиков закупочного следа: ${formatInventorySupplierOverlapCounterpartyLead(counterparties)}.`; return { text: [repairedLead, firstLine, ...lines.slice(1)].join("\n"), audit: buildInventorySupplierOverlapSurfaceRepairAudit({ applied: true, detectedIntent, counterparties, firstLineSample: firstLine.slice(0, 220), stockScopeMatch: leadInspection.stockScopeMatch, defensiveMatch: leadInspection.defensiveMatch, reasonCodes: ["inventory_supplier_overlap_surface_repair_applied"] }) }; } function extractSingleWarehouseScopeFromReply(replyText) { const values = []; const normalized = String(replyText ?? ""); const byFieldPattern = /(?:^|\|)\s*склад\s*:\s*([^|\r\n]+)/giu; for (const match of normalized.matchAll(byFieldPattern)) { const value = toNullableString(match[1]?.replace(/[.;,\s]+$/u, "")); if (value) { values.push(value); } } const fieldUnique = uniqueNormalizedStrings(values); if (fieldUnique.length > 0) { return fieldUnique.length === 1 ? fieldUnique[0] : null; } const leadMatch = normalized.match(/(?:по|на)\s+склад[уе]?\s+([^.,;\r\n]+)/iu); const leadWarehouse = toNullableString(leadMatch?.[1]?.replace(/[.;,\s]+$/u, "")); if (leadWarehouse) { values.push(leadWarehouse); } const unique = uniqueNormalizedStrings(values); return unique.length === 1 ? unique[0] : null; } function sameBusinessLabel(left, right) { const normalizedLeft = toNullableString(left)?.toLocaleLowerCase("ru-RU").replace(/ё/g, "е"); const normalizedRight = toNullableString(right)?.toLocaleLowerCase("ru-RU").replace(/ё/g, "е"); return Boolean(normalizedLeft && normalizedRight && (normalizedLeft === normalizedRight || normalizedLeft.includes(normalizedRight) || normalizedRight.includes(normalizedLeft))); } function firstString(values) { for (const value of values) { const text = toNullableString(value); if (text) { return text; } } return null; } function legalOrganizationLabelFromClarification(value) { const text = toNullableString(value); if (!text) { return null; } const compact = text.replace(/\s+/gu, " ").replace(/[.!?]+$/u, "").trim(); if (compact.length > 120 || !/^(?:ООО|ПАО|АО|ИП)\s+\S/iu.test(compact)) { return null; } return compact; } function cleanComparisonScopeCompanyLine(line, organization) { let clean = String(line ?? "") .replace(/\bcompany-level\b/giu, "общий по компании") .replace(/\breusable bundle\b/giu, "сохраненный подтвержденный срез"); if (organization) { clean = clean.replace(/по компании\s+.+?(?=\s+(?:подтвержден|подтвержд[её]н|зафиксирован|показан|есть)\b|:|$)/iu, `по компании ${organization}`); } return clean.trim(); } function hasComparisonScopeProofCue(value) { const text = toNullableString(value)?.toLocaleLowerCase("ru-RU").replace(/\s+/gu, " ").trim(); if (!text) { return false; } return /(?:\bсравни\b|собери\s+коротк\p{L}*\s+итог|коротк\p{L}*\s+сравн|что\s+.*подтверд\p{L}*.*(?:компан|контрагент|свк)|что\s+.*отдельно\s+по\s+(?:группа\s+свк|выбранн\p{L}*\s+контрагент)|какие\s+выводы\s+можно\s+делать\s+и\s+какие\s+нельзя)/iu.test(text); } function buildComparisonScopeProofReply(input) { const legalOrganizationFromCurrentTurn = legalOrganizationLabelFromClarification(input.userMessage); const entryPoint = toRecordObject(input.debug.assistant_mcp_discovery_entry_point_v1); const turnInput = toRecordObject(entryPoint?.turn_input); const turnMeaning = toRecordObject(turnInput?.turn_meaning_ref); const isBusinessOverview = toNullableString(turnMeaning?.asked_domain_family) === "business_overview"; if (!isBusinessOverview) { return null; } if (!hasComparisonScopeProofCue(input.userMessage) && !legalOrganizationFromCurrentTurn) { return null; } const separateCandidates = Array.isArray(turnMeaning?.business_overview_separate_entity_candidates) ? turnMeaning.business_overview_separate_entity_candidates : []; const separateSubject = firstString([...separateCandidates, turnMeaning?.metadata_scope_hint]); if (!separateSubject) { return null; } const sessionRecord = toRecordObject(input.session); const addressNavigationState = toRecordObject(sessionRecord?.address_navigation_state); const sessionContext = toRecordObject(addressNavigationState?.session_context); const comparisonScope = toRecordObject(sessionContext?.comparison_scope); const comparisonCounterparty = toRecordObject(comparisonScope?.counterparty); const proofBundles = toRecordObject(comparisonScope?.proof_bundles); const valueBundle = toRecordObject(proofBundles?.counterparty_value_flow_bundle); const documentBundle = toRecordObject(proofBundles?.counterparty_document_bundle); if (!valueBundle || !sameBusinessLabel(separateSubject, valueBundle.counterparty ?? comparisonCounterparty?.label)) { return null; } const incoming = toRecordObject(valueBundle.incoming_customer_revenue); const outgoing = toRecordObject(valueBundle.outgoing_supplier_payout); const incomingAmount = toNullableString(incoming?.total_amount_human_ru); const outgoingAmount = toNullableString(outgoing?.total_amount_human_ru); const netAmount = toNullableString(valueBundle.net_amount_human_ru); if (!incomingAmount && !outgoingAmount && !netAmount) { return null; } const organization = legalOrganizationFromCurrentTurn ?? toNullableString(turnMeaning?.explicit_organization_scope) ?? toNullableString(toRecordObject(comparisonScope?.organization)?.label); const documentCount = Number(toRecordObject(documentBundle)?.document_count); const documentText = Number.isFinite(documentCount) && documentCount > 0 ? `, документы: ${documentCount}` : ""; const lines = String(input.baseReply ?? "") .split(/\r?\n/u) .map((line) => line.trim()) .filter(Boolean); const companyLine = cleanComparisonScopeCompanyLine(lines[0] ?? `Коротко: по компании ${organization ?? "выбранной организации"} подтвержден общий денежный срез.`, organization); const netDirection = valueBundle.net_direction === "net_outgoing" ? "нетто в минус" : "нетто в нашу сторону"; const counterparty = toNullableString(valueBundle.counterparty) ?? separateSubject; return { reply: [ `${companyLine}; отдельно по ${counterparty}: получили ${incomingAmount ?? "0 руб."}, заплатили ${outgoingAmount ?? "0 руб."}, ${netDirection} ${netAmount ?? "0 руб."}${documentText}.`, `Отдельно по контрагенту ${counterparty}: это ранее подтвержденный контрагентский срез, а не перенос общих сумм компании на контрагента.`, `Нельзя утверждать: чистую прибыль, полноценный финрезультат, юридические роли клиентов/поставщиков и выводы по ${counterparty} из общих сумм компании без отдельного контрагентского среза.` ].join("\n"), audit: { applied: true, source: "address_navigation_state.comparison_scope.proof_bundles", counterparty, organization: organization ?? null, document_count: Number.isFinite(documentCount) && documentCount > 0 ? documentCount : null } }; } function buildAppliedMcpDiscoveryRoutePatch(debug, applied) { if (!applied) { return {}; } const selectedChain = toNullableString(debug.mcp_discovery_selected_chain_id); if (selectedChain === "business_overview") { return { detected_intent: "business_overview", detected_intent_confidence: "high", selected_recipe: "business_overview", response_type: "LIMITED_WITH_REASON", mcp_discovery_effective_response_route: "business_overview" }; } return {}; } function normalizeAddressLaneDebug(value) { return (toRecordObject(value) ?? {}); } function normalizeCarryoverMeta(value) { const source = toRecordObject(value); if (!source) { return null; } const followupContext = toRecordObject(source.followupContext); const previousAddressIntent = toNullableString(source.previousAddressIntent) ?? toNullableString(followupContext?.previous_intent); const previousAddressAnchor = toNullableString(source.previousAddressAnchor) ?? toNullableString(followupContext?.previous_anchor); if (!previousAddressIntent && !previousAddressAnchor) { return null; } return { previousAddressIntent, previousAddressAnchor }; } function normalizeLlmPreDecomposeMeta(value) { const source = toRecordObject(value); if (!source) { return null; } const dialogContinuationContractRaw = toRecordObject(source.dialogContinuationContract); const addressRetryAuditRaw = toRecordObject(source.addressRetryAudit); const predecomposeContractRaw = toRecordObject(source.predecomposeContract); const predecomposePeriodRaw = toRecordObject(predecomposeContractRaw?.period); const semanticExtractionContractRaw = toRecordObject(source.semanticExtractionContract); const normalized = {}; const attempted = toNullableBoolean(source.attempted); if (attempted !== undefined) normalized.attempted = attempted; const applied = toNullableBoolean(source.applied); if (applied !== undefined) normalized.applied = applied; const provider = toNullableString(source.provider); if (provider) normalized.provider = provider; const traceId = toNullableString(source.traceId); if (traceId) normalized.traceId = traceId; const reason = toNullableString(source.reason); if (reason) normalized.reason = reason; const fallbackRuleHit = toNullableString(source.fallbackRuleHit); if (fallbackRuleHit) normalized.fallbackRuleHit = fallbackRuleHit; const sanitizedUserMessage = toNullableString(source.sanitizedUserMessage); if (sanitizedUserMessage) normalized.sanitizedUserMessage = sanitizedUserMessage; const toolGateDecision = toNullableString(source.toolGateDecision); if (toolGateDecision) normalized.toolGateDecision = toolGateDecision; const toolGateReason = toNullableString(source.toolGateReason); if (toolGateReason) normalized.toolGateReason = toolGateReason; if (dialogContinuationContractRaw) { const decision = toNullableString(dialogContinuationContractRaw.decision); const targetIntent = toNullableString(dialogContinuationContractRaw.target_intent); if (decision || targetIntent) { normalized.dialogContinuationContract = { decision, target_intent: targetIntent }; } } if (addressRetryAuditRaw) { const retryAttempted = toNullableBoolean(addressRetryAuditRaw.attempted); const retryReason = toNullableString(addressRetryAuditRaw.reason); const initialLimitedCategory = toNullableString(addressRetryAuditRaw.initial_limited_category); const retryResultCategory = toNullableString(addressRetryAuditRaw.retry_result_category); if (retryAttempted !== undefined || retryReason || initialLimitedCategory || retryResultCategory) { normalized.addressRetryAudit = { attempted: retryAttempted, reason: retryReason, initial_limited_category: initialLimitedCategory, retry_result_category: retryResultCategory }; } } if (predecomposeContractRaw) { const intent = toNullableString(predecomposeContractRaw.intent); const aggregationProfile = toNullableString(predecomposeContractRaw.aggregation_profile); const periodScope = toNullableString(predecomposePeriodRaw?.scope); if (intent || aggregationProfile || periodScope) { normalized.predecomposeContract = { intent, aggregation_profile: aggregationProfile, period: periodScope ? { scope: periodScope } : null }; } } if (semanticExtractionContractRaw) { const valid = toNullableBoolean(semanticExtractionContractRaw.valid); const quality = toNullableString(semanticExtractionContractRaw.quality); const applyCanonicalRecommended = toNullableBoolean(semanticExtractionContractRaw.apply_canonical_recommended); const reasonCodes = Array.isArray(semanticExtractionContractRaw.reason_codes) ? semanticExtractionContractRaw.reason_codes .map((item) => toNullableString(item)) .filter((item) => Boolean(item)) : []; if (valid !== undefined || quality || applyCanonicalRecommended !== undefined || reasonCodes.length > 0) { normalized.semanticExtractionContract = { valid: valid ?? null, quality, apply_canonical_recommended: applyCanonicalRecommended ?? null, reason_codes: reasonCodes }; } } const hasUsefulField = Object.values(normalized).some((item) => item !== undefined && item !== null); return hasUsefulField ? normalized : null; } function runAssistantAddressLaneResponseRuntime(input) { const finalizeAddressTurnSafe = input.finalizeAddressTurn ?? assistantAddressTurnFinalizeRuntimeAdapter_1.finalizeAssistantAddressTurn; const debug = input.buildAddressDebugPayload(input.addressLane.debug, input.llmPreDecomposeMeta); const surfaceRepair = repairInventorySupplierOverlapSurfaceReply(input.addressLane.reply_text, debug); const safeAddressReplyBase = input.sanitizeOutgoingAssistantText(surfaceRepair.text); const preservedAddressReply = preserveInventorySupplierOverlapCounterpartyLeadAfterSanitize({ rawReply: surfaceRepair.text, sanitizedReply: safeAddressReplyBase, addressDebug: debug }); const safeAddressReply = preservedAddressReply.text; if (surfaceRepair.audit) { debug.inventory_supplier_overlap_surface_repair_v1 = { ...surfaceRepair.audit, lead_preserved_after_sanitize: preservedAddressReply.applied }; } const followupOffer = input.buildAddressFollowupOffer(debug); if (followupOffer) { debug.address_followup_offer = followupOffer; } const laneOrganizationCandidates = Array.isArray(input.addressLane.debug?.organization_candidates) ? input.addressLane.debug.organization_candidates : []; const debugKnownOrganizations = input.mergeKnownOrganizations([ ...input.knownOrganizations, ...laneOrganizationCandidates ]); const debugFilters = debug?.extracted_filters && typeof debug.extracted_filters === "object" ? debug.extracted_filters : null; const debugActiveOrganization = input.toNonEmptyString(debugFilters?.organization) ?? input.toNonEmptyString(input.activeOrganization); const followupContextSource = input.carryoverMeta?.followupContext && typeof input.carryoverMeta.followupContext === "object" ? input.carryoverMeta.followupContext : null; if (debugKnownOrganizations.length > 0) { debug.assistant_known_organizations = debugKnownOrganizations; } if (debugActiveOrganization) { debug.assistant_active_organization = debugActiveOrganization; } const rootIntent = input.toNonEmptyString(followupContextSource?.root_intent); const currentFrameKind = input.toNonEmptyString(followupContextSource?.current_frame_kind); const rootFilters = followupContextSource?.root_filters && typeof followupContextSource.root_filters === "object" ? followupContextSource.root_filters : null; const detectedIntent = input.toNonEmptyString(debug.detected_intent); const rootFrameWarehouse = input.toNonEmptyString(rootFilters?.warehouse) ?? input.toNonEmptyString(debugFilters?.warehouse) ?? (detectedIntent === "inventory_on_hand_as_of_date" ? extractSingleWarehouseScopeFromReply(safeAddressReply) : null); const shouldPersistInventoryRootFrame = rootIntent || currentFrameKind || detectedIntent === "inventory_on_hand_as_of_date"; if (shouldPersistInventoryRootFrame) { const rootFiltersForDebug = { ...(rootFilters ?? {}), organization: input.toNonEmptyString(rootFilters?.organization) ?? input.toNonEmptyString(debugFilters?.organization), warehouse: rootFrameWarehouse, as_of_date: input.toNonEmptyString(rootFilters?.as_of_date) ?? input.toNonEmptyString(debugFilters?.as_of_date), period_from: input.toNonEmptyString(rootFilters?.period_from) ?? input.toNonEmptyString(debugFilters?.period_from), period_to: input.toNonEmptyString(rootFilters?.period_to) ?? input.toNonEmptyString(debugFilters?.period_to) }; for (const key of Object.keys(rootFiltersForDebug)) { if (!input.toNonEmptyString(rootFiltersForDebug[key])) { delete rootFiltersForDebug[key]; } } debug.address_root_frame_context = { root_intent: rootIntent ?? (detectedIntent === "inventory_on_hand_as_of_date" ? "inventory_on_hand_as_of_date" : null), root_filters: rootFiltersForDebug, root_anchor_type: input.toNonEmptyString(followupContextSource?.root_anchor_type) ?? undefined, root_anchor_value: input.toNonEmptyString(followupContextSource?.root_anchor_value) ?? undefined, current_frame_kind: currentFrameKind ?? (detectedIntent === "inventory_on_hand_as_of_date" ? "inventory_root" : null), organization: input.toNonEmptyString(rootFiltersForDebug.organization), warehouse: input.toNonEmptyString(rootFiltersForDebug.warehouse), as_of_date: input.toNonEmptyString(rootFiltersForDebug.as_of_date), period_from: input.toNonEmptyString(rootFiltersForDebug.period_from), period_to: input.toNonEmptyString(rootFiltersForDebug.period_to) }; } const debugWithRuntimeContracts = (0, assistantRuntimeContractResolver_1.attachAssistantRuntimeContractShadow)(debug, { userMessage: input.userMessage, addressRuntimeMeta: input.llmPreDecomposeMeta }); const debugWithTruthAnswerPolicy = (0, assistantTruthAnswerPolicyRuntimeAdapter_1.attachAssistantTruthAnswerPolicy)(debugWithRuntimeContracts, { addressRuntimeMeta: input.llmPreDecomposeMeta, replyType: normalizeAddressReplyType(input.addressLane.reply_type) }); const debugWithStateTransition = (0, assistantStateTransitionRuntimeAdapter_1.attachAssistantStateTransition)(debugWithTruthAnswerPolicy, { addressRuntimeMeta: input.llmPreDecomposeMeta, replyType: normalizeAddressReplyType(input.addressLane.reply_type) }); const debugWithCapabilityBinding = (0, assistantCapabilityRuntimeBindingAdapter_1.attachAssistantCapabilityRuntimeBinding)(debugWithStateTransition, { addressRuntimeMeta: input.llmPreDecomposeMeta, replyType: normalizeAddressReplyType(input.addressLane.reply_type) }); const debugWithMcpDiscovery = (0, assistantMcpDiscoveryDebugAttachment_1.attachAssistantMcpDiscoveryDebug)(debugWithCapabilityBinding, { addressRuntimeMeta: input.llmPreDecomposeMeta }); const guardedResponse = (0, assistantCapabilityBindingResponseGuard_1.applyAssistantCapabilityBindingResponseGuard)({ assistantReply: safeAddressReply, replyType: normalizeAddressReplyType(input.addressLane.reply_type), capabilityBinding: debugWithMcpDiscovery.assistant_capability_binding_v1 }); const debugWithResponseGuard = { ...debugWithMcpDiscovery, capability_binding_response_guard: guardedResponse.audit }; const mcpDiscoveryResponsePolicy = (0, assistantMcpDiscoveryResponsePolicy_1.applyAssistantMcpDiscoveryResponsePolicy)({ currentReply: guardedResponse.assistantReply, currentReplySource: "address_query_runtime_v1", currentReplyType: guardedResponse.replyType, addressRuntimeMeta: debugWithResponseGuard }); const finalAssistantReply = mcpDiscoveryResponsePolicy.applied ? mcpDiscoveryResponsePolicy.reply_text : guardedResponse.assistantReply; const comparisonScopeProofReply = buildComparisonScopeProofReply({ baseReply: finalAssistantReply, debug: debugWithResponseGuard, session: input.getSession(input.sessionId), userMessage: input.userMessage }); const finalAssistantReplyWithComparisonProof = comparisonScopeProofReply?.reply ?? finalAssistantReply; const finalReplyType = mcpDiscoveryResponsePolicy.applied ? "partial_coverage" : guardedResponse.replyType; const finalDebug = { ...debugWithResponseGuard, mcp_discovery_response_policy_v1: mcpDiscoveryResponsePolicy, mcp_discovery_response_candidate_v1: mcpDiscoveryResponsePolicy.candidate, mcp_discovery_response_applied: mcpDiscoveryResponsePolicy.applied, comparison_scope_response_augmentation_v1: comparisonScopeProofReply?.audit ?? null, ...buildAppliedMcpDiscoveryRoutePatch(debugWithResponseGuard, mcpDiscoveryResponsePolicy.applied), ...(0, assistantMcpDiscoveryResponsePolicy_1.buildAppliedMcpDiscoveryTruthPatch)(mcpDiscoveryResponsePolicy, debugWithResponseGuard) }; const finalization = finalizeAddressTurnSafe({ sessionId: input.sessionId, userMessage: input.userMessage, effectiveAddressUserMessage: input.effectiveAddressUserMessage, assistantReply: finalAssistantReplyWithComparisonProof, replyType: finalReplyType, addressLaneDebug: normalizeAddressLaneDebug(input.addressLane.debug), debug: finalDebug, carryoverMeta: normalizeCarryoverMeta(input.carryoverMeta), llmPreDecomposeMeta: normalizeLlmPreDecomposeMeta(input.llmPreDecomposeMeta), appendItem: input.appendItem, getSession: input.getSession, persistSession: input.persistSession, cloneConversation: input.cloneConversation, logEvent: input.logEvent, messageIdFactory: input.messageIdFactory }); return { response: finalization.response, debug: finalDebug }; }