"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION = void 0; exports.executeAssistantMcpDiscoveryPilot = executeAssistantMcpDiscoveryPilot; const addressMcpClient_1 = require("./addressMcpClient"); const assistantMcpDiscoveryRuntimeAdapter_1 = require("./assistantMcpDiscoveryRuntimeAdapter"); const assistantMcpDiscoveryPolicy_1 = require("./assistantMcpDiscoveryPolicy"); const addressRecipeCatalog_1 = require("./addressRecipeCatalog"); exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION = "assistant_mcp_discovery_pilot_executor_v1"; const DEFAULT_DEPS = { executeAddressMcpQuery: addressMcpClient_1.executeAddressMcpQuery, executeAddressMcpMetadata: addressMcpClient_1.executeAddressMcpMetadata }; function toNonEmptyString(value) { if (value === null || value === undefined) { return null; } const text = String(value).trim(); return text.length > 0 ? text : null; } function normalizeReasonCode(value) { const normalized = value .trim() .replace(/[^\p{L}\p{N}_.:-]+/gu, "_") .replace(/^_+|_+$/g, "") .toLowerCase(); return normalized.length > 0 ? normalized.slice(0, 120) : null; } function pushReason(target, value) { const normalized = normalizeReasonCode(value); if (normalized && !target.includes(normalized)) { target.push(normalized); } } function pushUnique(target, value) { const text = value.trim(); if (text && !target.includes(text)) { target.push(text); } } function aggregationAxisForPlanner(planner) { const axis = toNonEmptyString(planner.discovery_plan.turn_meaning_ref?.asked_aggregation_axis)?.toLowerCase(); return axis === "month" ? "month" : null; } function firstEntityCandidate(planner) { const candidates = planner.discovery_plan.turn_meaning_ref?.explicit_entity_candidates ?? []; for (const candidate of candidates) { const text = toNonEmptyString(candidate); if (text) { return text; } } return null; } function dateScopeToFilters(dateScope) { if (!dateScope) { return {}; } const yearMatch = dateScope.match(/^(\d{4})$/); if (yearMatch) { return { period_from: `${yearMatch[1]}-01-01`, period_to: `${yearMatch[1]}-12-31` }; } const dateMatch = dateScope.match(/^(\d{4})-(\d{2})-(\d{2})/); if (dateMatch) { const date = `${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}`; return { period_from: date, period_to: date }; } return {}; } function buildLifecycleFilters(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const counterparty = firstEntityCandidate(planner); const organization = toNonEmptyString(meaning?.explicit_organization_scope); const dateScope = toNonEmptyString(meaning?.explicit_date_scope); return { ...dateScopeToFilters(dateScope), ...(counterparty ? { counterparty } : {}), ...(organization ? { organization } : {}), limit: planner.discovery_plan.execution_budget.max_rows_per_probe, sort: "period_asc" }; } function buildValueFlowFilters(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const counterparty = firstEntityCandidate(planner); const organization = toNonEmptyString(meaning?.explicit_organization_scope); const dateScope = toNonEmptyString(meaning?.explicit_date_scope); return { ...dateScopeToFilters(dateScope), ...(counterparty ? { counterparty } : {}), ...(organization ? { organization } : {}), limit: planner.discovery_plan.execution_budget.max_rows_per_probe, sort: "period_asc" }; } function isLifecyclePilotEligible(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const domain = String(meaning?.asked_domain_family ?? "").toLowerCase(); const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const combined = `${domain} ${action}`; return (planner.proposed_primitives.includes("query_documents") && (combined.includes("lifecycle") || combined.includes("activity") || combined.includes("duration") || combined.includes("age"))); } function isDocumentEvidencePilotEligible(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const domain = String(meaning?.asked_domain_family ?? "").toLowerCase(); const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const combined = `${domain} ${action} ${unsupported}`; return (planner.proposed_primitives.includes("query_documents") && (combined.includes("document") || combined.includes("list_documents"))); } function isMovementEvidencePilotEligible(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const domain = String(meaning?.asked_domain_family ?? "").toLowerCase(); const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const semanticNeed = String(planner.semantic_data_need ?? "").toLowerCase(); const combined = `${domain} ${action} ${unsupported} ${semanticNeed}`; return (planner.proposed_primitives.includes("query_movements") && (combined.includes("movement") || combined.includes("movements") || combined.includes("bank_operations") || combined.includes("movement_evidence") || combined.includes("list_movements"))); } function isValueFlowPilotEligible(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const domain = String(meaning?.asked_domain_family ?? "").toLowerCase(); const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const combined = `${domain} ${action} ${unsupported}`; return (planner.proposed_primitives.includes("query_movements") && (combined.includes("turnover") || combined.includes("revenue") || combined.includes("payment") || combined.includes("payout") || combined.includes("value"))); } function isMetadataPilotEligible(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const domain = String(meaning?.asked_domain_family ?? "").toLowerCase(); const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const semanticNeed = String(planner.semantic_data_need ?? "").toLowerCase(); const combined = `${domain} ${action} ${unsupported} ${semanticNeed}`; return (planner.proposed_primitives.includes("inspect_1c_metadata") && (combined.includes("metadata") || combined.includes("schema") || combined.includes("catalog") || combined.includes("inspect_documents") || combined.includes("inspect_registers") || combined.includes("inspect_fields"))); } function metadataScopeForPlanner(planner) { const entityCandidate = firstEntityCandidate(planner); if (entityCandidate) { return entityCandidate; } const meaning = planner.discovery_plan.turn_meaning_ref; const combined = `${meaning?.asked_domain_family ?? ""} ${meaning?.asked_action_family ?? ""} ${meaning?.unsupported_but_understood_family ?? ""}` .toLowerCase() .trim(); if (combined.includes("vat")) { return "НДС"; } if (combined.includes("inventory")) { return "склад"; } if (combined.includes("counterparty")) { return "контрагент"; } return null; } function metadataTypesForPlanner(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const action = String(meaning?.asked_action_family ?? "").toLowerCase(); if (action === "inspect_registers") { return ["РегистрНакопления", "РегистрСведений"]; } if (action === "inspect_documents") { return ["Документ"]; } if (action === "inspect_catalog") { return ["Справочник"]; } return ["Документ", "РегистрНакопления", "РегистрСведений", "Справочник"]; } function valueFlowPilotProfile(planner) { const meaning = planner.discovery_plan.turn_meaning_ref; const action = String(meaning?.asked_action_family ?? "").toLowerCase(); const unsupported = String(meaning?.unsupported_but_understood_family ?? "").toLowerCase(); const combined = `${action} ${unsupported}`; if (combined.includes("net_value_flow") || combined.includes("bidirectional") || combined.includes("netting") || combined.includes("net")) { return { scope: "counterparty_bidirectional_value_flow_query_movements_v1", recipe_intent: null, direction: "bidirectional_net_value_flow" }; } if (combined.includes("payout") || combined.includes("outflow") || combined.includes("supplier") || combined.includes("paid")) { return { scope: "counterparty_supplier_payout_query_movements_v1", recipe_intent: "supplier_payouts_profile", direction: "outgoing_supplier_payout" }; } return { scope: "counterparty_value_flow_query_movements_v1", recipe_intent: "customer_revenue_and_payments", direction: "incoming_customer_revenue" }; } function skippedProbeResult(step, limitation) { return { primitive_id: step.primitive_id, status: "skipped", rows_received: 0, rows_matched: 0, limitation }; } function queryResultToProbeResult(primitiveId, result) { return { primitive_id: primitiveId, status: result.error ? "error" : "ok", rows_received: result.fetched_rows, rows_matched: result.matched_rows, limitation: result.error }; } function metadataResultToProbeResult(primitiveId, result) { return { primitive_id: primitiveId, status: result.error ? "error" : "ok", rows_received: result.fetched_rows, rows_matched: result.error ? 0 : result.rows.length, limitation: result.error }; } function toCoverageAwareQueryResult(result, options = {}) { if (!result) { return null; } return { ...result, coverage_limited_by_probe_limit: options.coverageLimitedByProbeLimit ?? false, coverage_recovered_by_period_chunking: options.coverageRecoveredByPeriodChunking ?? false, period_chunking_granularity: options.periodChunkingGranularity ?? null, period_chunk_count: options.periodChunkCount ?? 0 }; } function monthWindowsForYear(year) { const result = []; for (let month = 0; month < 12; month += 1) { const start = new Date(Date.UTC(Number(year), month, 1)); const end = new Date(Date.UTC(Number(year), month + 1, 0)); result.push({ period_from: `${start.getUTCFullYear()}-${String(start.getUTCMonth() + 1).padStart(2, "0")}-${String(start.getUTCDate()).padStart(2, "0")}`, period_to: `${end.getUTCFullYear()}-${String(end.getUTCMonth() + 1).padStart(2, "0")}-${String(end.getUTCDate()).padStart(2, "0")}` }); } return result; } function periodWindowsForDateScope(dateScope) { const yearMatch = dateScope?.match(/^(\d{4})$/); if (yearMatch) { return monthWindowsForYear(yearMatch[1]); } return []; } function mergeCoverageAwareQueryResults(results, options) { const rawRows = results.flatMap((item) => item.raw_rows); const rows = results.flatMap((item) => item.rows); const errors = results.map((item) => toNonEmptyString(item.error)).filter((item) => Boolean(item)); return { fetched_rows: results.reduce((sum, item) => sum + item.fetched_rows, 0), matched_rows: results.reduce((sum, item) => sum + item.matched_rows, 0), raw_rows: rawRows, rows, error: errors[0] ?? null, coverage_limited_by_probe_limit: options.coverageLimitedByProbeLimit, coverage_recovered_by_period_chunking: options.coverageRecoveredByPeriodChunking, period_chunking_granularity: options.periodChunkingGranularity, period_chunk_count: options.periodChunkCount }; } async function executeCoverageAwareValueFlowQuery(input) { const queryLimitations = []; const probeResults = []; let executedProbeCount = 0; const broadRecipePlan = input.recipePlanBuilder(input.baseFilters); const broadResult = await input.deps.executeAddressMcpQuery({ query: broadRecipePlan.query, limit: broadRecipePlan.limit, account_scope: broadRecipePlan.account_scope }); executedProbeCount += 1; probeResults.push(queryResultToProbeResult(input.primitiveId, broadResult)); const broadCoverageLimited = !broadResult.error && broadResult.matched_rows >= input.maxRowsPerProbe; if (broadResult.error) { pushUnique(queryLimitations, broadResult.error); return { result: toCoverageAwareQueryResult(broadResult, { coverageLimitedByProbeLimit: false }), probe_results: probeResults, query_limitations: queryLimitations, executed_probe_count: executedProbeCount }; } const periodWindows = periodWindowsForDateScope(input.dateScope); if (!broadCoverageLimited || periodWindows.length === 0) { return { result: toCoverageAwareQueryResult(broadResult, { coverageLimitedByProbeLimit: broadCoverageLimited }), probe_results: probeResults, query_limitations: queryLimitations, executed_probe_count: executedProbeCount }; } const requiredChunkProbeCount = periodWindows.length; if (executedProbeCount + requiredChunkProbeCount > input.maxProbeCount) { pushUnique(queryLimitations, "Requested period hit the MCP row limit, but the approved monthly recovery probe budget is smaller than the required subperiod count"); return { result: toCoverageAwareQueryResult(broadResult, { coverageLimitedByProbeLimit: true }), probe_results: probeResults, query_limitations: queryLimitations, executed_probe_count: executedProbeCount }; } const chunkResults = []; let anyChunkLimited = false; let anyChunkError = false; for (const window of periodWindows) { const chunkFilters = { ...input.baseFilters, period_from: window.period_from, period_to: window.period_to }; const chunkPlan = input.recipePlanBuilder(chunkFilters); const chunkResult = await input.deps.executeAddressMcpQuery({ query: chunkPlan.query, limit: chunkPlan.limit, account_scope: chunkPlan.account_scope }); executedProbeCount += 1; probeResults.push(queryResultToProbeResult(input.primitiveId, chunkResult)); if (chunkResult.error) { anyChunkError = true; pushUnique(queryLimitations, chunkResult.error); continue; } if (chunkResult.matched_rows >= input.maxRowsPerProbe) { anyChunkLimited = true; } chunkResults.push(chunkResult); } if (chunkResults.length === 0 && anyChunkError) { return { result: toCoverageAwareQueryResult(broadResult, { coverageLimitedByProbeLimit: true }), probe_results: probeResults, query_limitations: queryLimitations, executed_probe_count: executedProbeCount }; } return { result: mergeCoverageAwareQueryResults(chunkResults, { coverageLimitedByProbeLimit: anyChunkLimited || anyChunkError, coverageRecoveredByPeriodChunking: true, periodChunkingGranularity: "month", periodChunkCount: periodWindows.length }), probe_results: probeResults, query_limitations: queryLimitations, executed_probe_count: executedProbeCount }; } function summarizeLifecycleRows(result) { if (result.error) { return null; } if (result.fetched_rows <= 0) { return "0 MCP document rows fetched"; } return `${result.fetched_rows} MCP document rows fetched, ${result.matched_rows} matched lifecycle scope`; } function summarizeDocumentRows(result) { if (result.error) { return null; } if (result.fetched_rows <= 0) { return "0 MCP document rows fetched"; } return `${result.fetched_rows} MCP document rows fetched, ${result.matched_rows} matched document scope`; } function summarizeMovementRows(result) { if (result.error) { return null; } if (result.fetched_rows <= 0) { return "0 MCP movement rows fetched"; } return `${result.fetched_rows} MCP movement rows fetched, ${result.matched_rows} matched movement scope`; } function summarizeValueFlowRows(result) { if (result.error) { return null; } if (result.fetched_rows <= 0) { return "0 MCP value-flow rows fetched"; } if (result.coverage_recovered_by_period_chunking && result.period_chunking_granularity === "month") { return `${result.period_chunk_count} monthly MCP value-flow probes fetched ${result.fetched_rows} rows total, ${result.matched_rows} matched value-flow scope after the broad probe hit the row limit`; } return `${result.fetched_rows} MCP value-flow rows fetched, ${result.matched_rows} matched value-flow scope`; } function summarizeMetadataRows(result) { if (result.error) { return null; } if (result.fetched_rows <= 0) { return "0 MCP metadata rows fetched"; } return `${result.fetched_rows} MCP metadata rows fetched`; } function metadataRowText(row, keys) { for (const key of keys) { const text = toNonEmptyString(row[key]); if (text) { return text; } } return null; } function metadataObjectName(row) { return metadataRowText(row, [ "ПолноеИмя", "full_name", "FullName", "Имя", "name", "Name", "presentation", "Представление", "synonym", "Synonym" ]); } function metadataEntitySet(row) { return metadataRowText(row, [ "ТипМетаданных", "type", "Type", "meta_type", "MetaType", "ВидМетаданных", "kind" ]); } function metadataChildNames(value) { if (!Array.isArray(value)) { return []; } const result = []; for (const item of value) { if (!item || typeof item !== "object" || Array.isArray(item)) { continue; } const record = item; const fieldName = metadataRowText(record, ["Имя", "name", "Name", "full_name", "FullName"]); if (fieldName) { pushUnique(result, fieldName); } } return result; } function metadataAvailableFields(rows) { const result = []; for (const row of rows) { for (const field of metadataChildNames(row["Реквизиты"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["attributes"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["Attributes"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["Измерения"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["dimensions"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["Ресурсы"])) { pushUnique(result, field); } for (const field of metadataChildNames(row["resources"])) { pushUnique(result, field); } } return result; } function normalizeMetadataEntitySetToken(value) { return String(value ?? "") .toLowerCase() .replace(/[\s_.-]+/g, ""); } function metadataMatchesRequestedType(entitySet, requestedMetaType) { const entityToken = normalizeMetadataEntitySetToken(entitySet); const requestedToken = normalizeMetadataEntitySetToken(requestedMetaType); return entityToken.includes(requestedToken) || requestedToken.includes(entityToken); } function metadataRouteFamilyForEntitySet(entitySet) { const token = normalizeMetadataEntitySetToken(entitySet); if (token.includes("документ") || token.includes("document")) { return "document_evidence"; } if (token.includes("регистрнакопления") || token.includes("регистсведений") || token.includes("регистрсведений") || token.includes("accumulationregister") || token.includes("informationregister")) { return "movement_evidence"; } if (token.includes("справочник") || token.includes("catalog") || token.includes("directory")) { return "catalog_drilldown"; } return null; } function metadataNextPrimitiveForRouteFamily(routeFamily) { if (routeFamily === "document_evidence") { return "query_documents"; } if (routeFamily === "movement_evidence") { return "query_movements"; } if (routeFamily === "catalog_drilldown") { return "drilldown_related_objects"; } return null; } function selectMetadataEntityGrounding(availableEntitySets, requestedMetaTypes) { const requestedMatches = availableEntitySets.filter((entitySet) => requestedMetaTypes.some((requestedMetaType) => metadataMatchesRequestedType(entitySet, requestedMetaType))); if (requestedMatches.length === 1) { return { selectedEntitySet: requestedMatches[0] ?? null, ambiguityDetected: false, ambiguityEntitySets: [] }; } if (requestedMatches.length > 1) { return { selectedEntitySet: null, ambiguityDetected: true, ambiguityEntitySets: requestedMatches }; } if (availableEntitySets.length === 1) { return { selectedEntitySet: availableEntitySets[0] ?? null, ambiguityDetected: false, ambiguityEntitySets: [] }; } return { selectedEntitySet: null, ambiguityDetected: availableEntitySets.length > 1, ambiguityEntitySets: availableEntitySets }; } function metadataObjectsForEntitySet(entitySet, matchedObjects) { if (!entitySet) { return []; } return matchedObjects.filter((item) => item.startsWith(`${entitySet}.`) || item.includes(entitySet)); } function deriveMetadataSurface(result, metadataScope, requestedMetaTypes) { if (!result || result.error || result.rows.length <= 0) { return null; } const matchedObjects = []; const availableEntitySets = []; for (const row of result.rows) { const objectName = metadataObjectName(row); if (objectName) { pushUnique(matchedObjects, objectName); } const entitySet = metadataEntitySet(row); if (entitySet) { pushUnique(availableEntitySets, entitySet); } } const grounding = selectMetadataEntityGrounding(availableEntitySets, requestedMetaTypes); const downstreamRouteFamily = grounding.selectedEntitySet ? metadataRouteFamilyForEntitySet(grounding.selectedEntitySet) : null; const knownLimitations = []; if (grounding.ambiguityDetected && grounding.ambiguityEntitySets.length > 0) { knownLimitations.push(`Exact downstream metadata surface remains ambiguous across: ${grounding.ambiguityEntitySets.join(", ")}`); } return { metadata_scope: metadataScope, requested_meta_types: requestedMetaTypes, matched_rows: result.rows.length, available_entity_sets: availableEntitySets, matched_objects: matchedObjects, selected_entity_set: grounding.selectedEntitySet, selected_surface_objects: metadataObjectsForEntitySet(grounding.selectedEntitySet, matchedObjects), downstream_route_family: downstreamRouteFamily, recommended_next_primitive: metadataNextPrimitiveForRouteFamily(downstreamRouteFamily), ambiguity_detected: grounding.ambiguityDetected, ambiguity_entity_sets: grounding.ambiguityEntitySets, available_fields: metadataAvailableFields(result.rows), known_limitations: knownLimitations, inference_basis: "confirmed_1c_metadata_surface_rows" }; } function buildMetadataConfirmedFacts(surface) { if (!surface) { return []; } const facts = []; const scopeSuffix = surface.metadata_scope ? ` for ${surface.metadata_scope}` : ""; facts.push(`Confirmed 1C metadata surface${scopeSuffix}: ${surface.matched_rows} rows and ${surface.matched_objects.length} matching objects`); if (surface.available_entity_sets.length > 0) { facts.push(`Available metadata object sets: ${surface.available_entity_sets.join(", ")}`); } if (surface.selected_entity_set) { facts.push(`Selected metadata entity set: ${surface.selected_entity_set}`); } if (surface.selected_surface_objects.length > 0) { facts.push(`Selected metadata objects: ${surface.selected_surface_objects.slice(0, 8).join(", ")}`); } if (surface.available_fields.length > 0) { facts.push(`Available metadata fields/sections: ${surface.available_fields.slice(0, 12).join(", ")}`); } return facts; } function buildMetadataInferredFacts(surface) { if (!surface || !surface.selected_entity_set || !surface.downstream_route_family || !surface.recommended_next_primitive) { return []; } return [ `A likely next checked lane may be inferred as ${surface.downstream_route_family} from the confirmed metadata surface` ]; } function buildMetadataUnknownFacts(surface, metadataScope) { if (surface) { if (surface.ambiguity_detected && surface.ambiguity_entity_sets.length > 0) { return [...surface.known_limitations]; } if (surface.available_fields.length > 0) { return []; } return ["Detailed metadata fields were not returned by this MCP metadata probe"]; } if (metadataScope) { return [`No matching 1C metadata objects were confirmed for scope "${metadataScope}"`]; } return ["No matching 1C metadata objects were confirmed by this MCP metadata probe"]; } function rowDateValue(row) { const candidates = [ row["Период"], row["Period"], row["period"], row["Дата"], row["Date"], row["date"] ]; for (const candidate of candidates) { const text = toNonEmptyString(candidate); const match = text?.match(/(\d{4})-(\d{2})-(\d{2})/); if (match) { return `${match[1]}-${match[2]}-${match[3]}`; } } return null; } function rowAmountValue(row) { const candidates = [ row["Сумма"], row["РЎСѓРјРјР°"], row["СуммаДокумента"], row["СуммаДокумента"], row["Amount"], row["amount"], row["Total"], row["total"] ]; for (const candidate of candidates) { if (typeof candidate === "number" && Number.isFinite(candidate)) { return candidate; } const text = toNonEmptyString(candidate); if (!text) { continue; } const normalized = text .replace(/\s+/g, "") .replace(/\u00a0/g, "") .replace(",", ".") .replace(/[^\d.-]/g, ""); const parsed = Number(normalized); if (Number.isFinite(parsed)) { return parsed; } } return null; } function monthBucketFromIsoDate(isoDate) { const match = isoDate?.match(/^(\d{4})-(\d{2})-\d{2}$/); return match ? `${match[1]}-${match[2]}` : null; } function netDirectionFromAmount(amount) { if (amount > 0) { return "net_incoming"; } if (amount < 0) { return "net_outgoing"; } return "balanced"; } function monthDiff(firstIsoDate, latestIsoDate) { const first = new Date(`${firstIsoDate}T00:00:00.000Z`); const latest = new Date(`${latestIsoDate}T00:00:00.000Z`); if (Number.isNaN(first.getTime()) || Number.isNaN(latest.getTime()) || latest < first) { return 0; } let months = (latest.getUTCFullYear() - first.getUTCFullYear()) * 12; months += latest.getUTCMonth() - first.getUTCMonth(); if (latest.getUTCDate() < first.getUTCDate()) { months -= 1; } return Math.max(0, months); } function formatDurationHumanRu(totalMonths) { const years = Math.floor(totalMonths / 12); const months = totalMonths % 12; const parts = []; if (years > 0) { parts.push(`${years} ${years === 1 ? "год" : years >= 2 && years <= 4 ? "года" : "лет"}`); } if (months > 0) { parts.push(`${months} ${months === 1 ? "месяц" : months >= 2 && months <= 4 ? "месяца" : "месяцев"}`); } return parts.length > 0 ? parts.join(" ") : "меньше месяца"; } function deriveActivityPeriod(result) { if (!result || result.error || result.matched_rows <= 0) { return null; } const dates = result.rows .map((row) => rowDateValue(row)) .filter((value) => Boolean(value)) .sort(); if (dates.length === 0) { return null; } const first = dates[0]; const latest = dates[dates.length - 1]; const totalMonths = monthDiff(first, latest); return { first_activity_date: first, latest_activity_date: latest, matched_rows: result.matched_rows, duration_total_months: totalMonths, duration_years: Math.floor(totalMonths / 12), duration_months_remainder: totalMonths % 12, duration_human_ru: formatDurationHumanRu(totalMonths), inference_basis: "first_and_latest_confirmed_1c_activity_rows" }; } function formatAmountHumanRu(amount) { const formatted = new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 2, minimumFractionDigits: Number.isInteger(amount) ? 0 : 2 }) .format(amount) .replace(/\u00a0/g, " "); return `${formatted} руб.`; } function deriveValueFlowMonthBreakdown(result, aggregationAxis) { if (!result || result.error || aggregationAxis !== "month") { return []; } const buckets = new Map(); for (const row of result.rows) { const isoDate = rowDateValue(row); const monthBucket = monthBucketFromIsoDate(isoDate); const amount = rowAmountValue(row); if (!monthBucket || amount === null) { continue; } const current = buckets.get(monthBucket) ?? { rows_with_amount: 0, total_amount: 0 }; current.rows_with_amount += 1; current.total_amount += amount; buckets.set(monthBucket, current); } return Array.from(buckets.entries()) .sort(([left], [right]) => left.localeCompare(right)) .map(([monthBucket, bucket]) => ({ month_bucket: monthBucket, rows_with_amount: bucket.rows_with_amount, total_amount: bucket.total_amount, total_amount_human_ru: formatAmountHumanRu(bucket.total_amount) })); } function deriveBidirectionalValueFlowMonthBreakdown(input) { if (input.aggregationAxis !== "month") { return []; } const incomingBuckets = deriveValueFlowMonthBreakdown(input.incomingResult, "month"); const outgoingBuckets = deriveValueFlowMonthBreakdown(input.outgoingResult, "month"); const allMonthBuckets = new Set(); for (const bucket of incomingBuckets) { allMonthBuckets.add(bucket.month_bucket); } for (const bucket of outgoingBuckets) { allMonthBuckets.add(bucket.month_bucket); } const incomingByMonth = new Map(incomingBuckets.map((bucket) => [bucket.month_bucket, bucket])); const outgoingByMonth = new Map(outgoingBuckets.map((bucket) => [bucket.month_bucket, bucket])); return Array.from(allMonthBuckets) .sort((left, right) => left.localeCompare(right)) .map((monthBucket) => { const incoming = incomingByMonth.get(monthBucket); const outgoing = outgoingByMonth.get(monthBucket); const incomingAmount = incoming?.total_amount ?? 0; const outgoingAmount = outgoing?.total_amount ?? 0; const netAmount = incomingAmount - outgoingAmount; return { month_bucket: monthBucket, incoming_total_amount: incomingAmount, incoming_total_amount_human_ru: formatAmountHumanRu(incomingAmount), incoming_rows_with_amount: incoming?.rows_with_amount ?? 0, outgoing_total_amount: outgoingAmount, outgoing_total_amount_human_ru: formatAmountHumanRu(outgoingAmount), outgoing_rows_with_amount: outgoing?.rows_with_amount ?? 0, net_amount: netAmount, net_amount_human_ru: formatAmountHumanRu(Math.abs(netAmount)), net_direction: netDirectionFromAmount(netAmount) }; }); } function deriveValueFlow(result, counterparty, periodScope, direction, aggregationAxis) { if (!result || result.error || result.matched_rows <= 0) { return null; } let totalAmount = 0; let rowsWithAmount = 0; for (const row of result.rows) { const amount = rowAmountValue(row); if (amount !== null) { totalAmount += amount; rowsWithAmount += 1; } } if (rowsWithAmount <= 0) { return null; } const dates = result.rows .map((row) => rowDateValue(row)) .filter((value) => Boolean(value)) .sort(); return { value_flow_direction: direction, counterparty, period_scope: periodScope, aggregation_axis: aggregationAxis, rows_matched: result.matched_rows, rows_with_amount: rowsWithAmount, total_amount: totalAmount, total_amount_human_ru: formatAmountHumanRu(totalAmount), first_movement_date: dates[0] ?? null, latest_movement_date: dates[dates.length - 1] ?? null, coverage_limited_by_probe_limit: result.coverage_limited_by_probe_limit, coverage_recovered_by_period_chunking: result.coverage_recovered_by_period_chunking, period_chunking_granularity: result.period_chunking_granularity, monthly_breakdown: deriveValueFlowMonthBreakdown(result, aggregationAxis), inference_basis: "sum_of_confirmed_1c_value_flow_rows" }; } function deriveValueFlowSideSummary(result) { if (!result || result.error || result.matched_rows <= 0) { return { rows_matched: 0, rows_with_amount: 0, total_amount: 0, total_amount_human_ru: formatAmountHumanRu(0), first_movement_date: null, latest_movement_date: null, coverage_limited_by_probe_limit: false, coverage_recovered_by_period_chunking: false, period_chunking_granularity: null }; } let totalAmount = 0; let rowsWithAmount = 0; for (const row of result.rows) { const amount = rowAmountValue(row); if (amount !== null) { totalAmount += amount; rowsWithAmount += 1; } } const dates = result.rows .map((row) => rowDateValue(row)) .filter((value) => Boolean(value)) .sort(); return { rows_matched: result.matched_rows, rows_with_amount: rowsWithAmount, total_amount: totalAmount, total_amount_human_ru: formatAmountHumanRu(totalAmount), first_movement_date: dates[0] ?? null, latest_movement_date: dates[dates.length - 1] ?? null, coverage_limited_by_probe_limit: result.coverage_limited_by_probe_limit, coverage_recovered_by_period_chunking: result.coverage_recovered_by_period_chunking, period_chunking_granularity: result.period_chunking_granularity }; } function deriveBidirectionalValueFlow(input) { const incoming = deriveValueFlowSideSummary(input.incomingResult); const outgoing = deriveValueFlowSideSummary(input.outgoingResult); if (incoming.rows_with_amount <= 0 && outgoing.rows_with_amount <= 0) { return null; } const netAmount = incoming.total_amount - outgoing.total_amount; return { counterparty: input.counterparty, period_scope: input.periodScope, aggregation_axis: input.aggregationAxis, incoming_customer_revenue: incoming, outgoing_supplier_payout: outgoing, net_amount: netAmount, net_amount_human_ru: formatAmountHumanRu(Math.abs(netAmount)), net_direction: netDirectionFromAmount(netAmount), coverage_limited_by_probe_limit: incoming.coverage_limited_by_probe_limit || outgoing.coverage_limited_by_probe_limit, coverage_recovered_by_period_chunking: incoming.coverage_recovered_by_period_chunking || outgoing.coverage_recovered_by_period_chunking, period_chunking_granularity: incoming.period_chunking_granularity ?? outgoing.period_chunking_granularity ?? null, monthly_breakdown: deriveBidirectionalValueFlowMonthBreakdown({ incomingResult: input.incomingResult, outgoingResult: input.outgoingResult, aggregationAxis: input.aggregationAxis }), inference_basis: "incoming_minus_outgoing_confirmed_1c_value_flow_rows" }; } function summarizeBidirectionalValueFlowRows(input) { const incoming = input.incomingResult; const outgoing = input.outgoingResult; if (!incoming && !outgoing) { return null; } const incomingSummary = incoming?.error ? "incoming value-flow query failed" : incoming?.coverage_recovered_by_period_chunking && incoming.period_chunking_granularity === "month" ? `${incoming.period_chunk_count} monthly incoming value-flow probes fetched ${incoming.fetched_rows} rows total, ${incoming.matched_rows} matched` : `${incoming?.fetched_rows ?? 0} incoming value-flow rows fetched, ${incoming?.matched_rows ?? 0} matched`; const outgoingSummary = outgoing?.error ? "outgoing supplier-payout query failed" : outgoing?.coverage_recovered_by_period_chunking && outgoing.period_chunking_granularity === "month" ? `${outgoing.period_chunk_count} monthly outgoing supplier-payout probes fetched ${outgoing.fetched_rows} rows total, ${outgoing.matched_rows} matched` : `${outgoing?.fetched_rows ?? 0} outgoing supplier-payout rows fetched, ${outgoing?.matched_rows ?? 0} matched`; return `${incomingSummary}; ${outgoingSummary}`; } function buildLifecycleConfirmedFacts(result, counterparty) { if (result.error || result.matched_rows <= 0) { return []; } return [ counterparty ? `1C activity rows were found for counterparty ${counterparty}` : "1C activity rows were found for the requested counterparty scope" ]; } function buildDocumentConfirmedFacts(result, counterparty) { if (result.error || result.matched_rows <= 0) { return []; } return [ counterparty ? `1C document rows were found for counterparty ${counterparty}` : "1C document rows were found for the requested scope" ]; } function buildMovementConfirmedFacts(result, counterparty) { if (result.error || result.matched_rows <= 0) { return []; } return [ counterparty ? `1C movement rows were found for counterparty ${counterparty}` : "1C movement rows were found for the requested scope" ]; } function buildValueFlowConfirmedFacts(result, counterparty, direction) { if (result.error || result.matched_rows <= 0) { return []; } if (direction === "outgoing_supplier_payout") { return [ counterparty ? `1C supplier-payout rows were found for counterparty ${counterparty}` : "1C supplier-payout rows were found for the requested counterparty scope" ]; } return [ counterparty ? `1C value-flow rows were found for counterparty ${counterparty}` : "1C value-flow rows were found for the requested counterparty scope" ]; } function buildBidirectionalValueFlowConfirmedFacts(derived) { if (!derived) { return []; } const hasIncoming = derived.incoming_customer_revenue.rows_matched > 0; const hasOutgoing = derived.outgoing_supplier_payout.rows_matched > 0; if (derived.counterparty) { return [ `1C bidirectional value-flow rows were checked for counterparty ${derived.counterparty}: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` ]; } return [ `1C bidirectional value-flow rows were checked for the requested counterparty scope: incoming=${hasIncoming ? "found" : "not_found"}, outgoing=${hasOutgoing ? "found" : "not_found"}` ]; } function buildLifecycleInferredFacts(result) { if (result.error || result.fetched_rows <= 0) { return []; } return ["Business activity duration may be inferred from first and latest confirmed 1C activity rows"]; } function buildDocumentInferredFacts(result) { if (result.error || result.fetched_rows <= 0) { return []; } return ["Counterparty document evidence is limited to confirmed 1C document rows in the checked scope"]; } function buildMovementInferredFacts(result) { if (result.error || result.fetched_rows <= 0) { return []; } return ["Counterparty movement evidence is limited to confirmed 1C movement rows in the checked scope"]; } function buildValueFlowInferredFacts(derived) { if (!derived) { return []; } const facts = []; if (derived.value_flow_direction === "outgoing_supplier_payout") { facts.push("Counterparty supplier-payout total was calculated from confirmed 1C outgoing payment rows"); } else { facts.push("Counterparty value-flow total was calculated from confirmed 1C movement rows"); } if (derived.coverage_recovered_by_period_chunking && derived.period_chunking_granularity === "month") { facts.push("Requested period coverage was recovered through monthly 1C value-flow probes after the broad probe hit the row limit"); } if (derived.aggregation_axis === "month" && derived.monthly_breakdown.length > 0) { facts.push("Counterparty monthly value-flow breakdown was grouped by month over confirmed 1C movement rows"); } return facts; } function buildBidirectionalValueFlowInferredFacts(derived) { if (!derived) { return []; } const facts = ["Counterparty net value-flow was calculated as incoming confirmed 1C rows minus outgoing confirmed 1C rows"]; if (derived.coverage_recovered_by_period_chunking && derived.period_chunking_granularity === "month") { facts.push("Requested period coverage for bidirectional value-flow was recovered through monthly 1C side probes after a broad probe hit the row limit"); } if (derived.aggregation_axis === "month" && derived.monthly_breakdown.length > 0) { facts.push("Counterparty monthly net value-flow breakdown was grouped by month over confirmed incoming and outgoing 1C rows"); } return facts; } function buildLifecycleUnknownFacts() { return ["Legal registration date is not proven by this MCP discovery pilot"]; } function buildDocumentUnknownFacts(periodScope) { return [ periodScope ? "Full document history outside the checked period is not proven by this MCP discovery pilot" : "Full document history is not proven without an explicit checked period" ]; } function buildMovementUnknownFacts(periodScope) { return [ periodScope ? "Full movement history outside the checked period is not proven by this MCP discovery pilot" : "Full movement history is not proven without an explicit checked period" ]; } function buildValueFlowUnknownFacts(periodScope, direction, derived) { const unknownFacts = []; if (derived?.coverage_limited_by_probe_limit) { unknownFacts.push("Complete requested-period coverage is not proven because the MCP discovery probe row limit was reached"); } if (direction === "outgoing_supplier_payout") { unknownFacts.push(periodScope ? "Full supplier-payout amount outside the checked period is not proven by this MCP discovery pilot" : "Full all-time supplier-payout amount is not proven without an explicit checked period"); return unknownFacts; } unknownFacts.push(periodScope ? "Full turnover outside the checked period is not proven by this MCP discovery pilot" : "Full all-time turnover is not proven without an explicit checked period"); return unknownFacts; } function buildBidirectionalValueFlowUnknownFacts(periodScope, derived) { const unknownFacts = []; if (derived?.coverage_limited_by_probe_limit) { unknownFacts.push("Complete requested-period coverage for bidirectional value-flow is not proven because at least one MCP discovery probe row limit was reached"); } unknownFacts.push(periodScope ? "Full bidirectional value-flow outside the checked period is not proven by this MCP discovery pilot" : "Full all-time bidirectional value-flow is not proven without an explicit checked period"); return unknownFacts; } function buildEmptyEvidence(planner, dryRun, probeResults, reason) { return (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, unknownFacts: [reason], queryLimitations: [reason], recommendedNextProbe: dryRun.user_facing_fallback }); } function pilotScopeForPlanner(planner) { if (isMetadataPilotEligible(planner)) { return "metadata_inspection_v1"; } if (isMovementEvidencePilotEligible(planner)) { return "counterparty_movement_evidence_query_movements_v1"; } if (isValueFlowPilotEligible(planner)) { return valueFlowPilotProfile(planner).scope; } if (isDocumentEvidencePilotEligible(planner)) { return "counterparty_document_evidence_query_documents_v1"; } return "counterparty_lifecycle_query_documents_v1"; } async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) { const runtimeDeps = { ...DEFAULT_DEPS, ...deps }; const dryRun = (0, assistantMcpDiscoveryRuntimeAdapter_1.buildAssistantMcpDiscoveryRuntimeDryRun)(planner); const reasonCodes = [...dryRun.reason_codes]; const executedPrimitives = []; const skippedPrimitives = []; const probeResults = []; const queryLimitations = []; const pilotScope = pilotScopeForPlanner(planner); if (dryRun.adapter_status === "blocked") { pushReason(reasonCodes, "pilot_blocked_before_mcp_execution"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "MCP discovery pilot was blocked before execution"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "blocked", pilot_scope: pilotScope, dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot was blocked before execution"], reason_codes: reasonCodes }; } if (dryRun.adapter_status !== "dry_run_ready") { pushReason(reasonCodes, "pilot_needs_clarification_before_mcp_execution"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "MCP discovery pilot needs more scope before execution"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "skipped_needs_clarification", pilot_scope: pilotScope, dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot needs more scope before execution"], reason_codes: reasonCodes }; } const metadataPilotEligible = isMetadataPilotEligible(planner); const documentPilotEligible = isDocumentEvidencePilotEligible(planner); const movementPilotEligible = isMovementEvidencePilotEligible(planner); const lifecyclePilotEligible = isLifecyclePilotEligible(planner); const valueFlowPilotEligible = isValueFlowPilotEligible(planner); if (!metadataPilotEligible && !documentPilotEligible && !movementPilotEligible && !lifecyclePilotEligible && !valueFlowPilotEligible) { pushReason(reasonCodes, "pilot_scope_unsupported_for_live_execution"); for (const step of dryRun.execution_steps) { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_scope_unsupported_for_live_execution")); } const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "MCP discovery pilot scope is not implemented yet"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: pilotScope, dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["MCP discovery pilot scope is not implemented yet"], reason_codes: reasonCodes }; } const counterparty = firstEntityCandidate(planner); const dateScope = toNonEmptyString(planner.discovery_plan.turn_meaning_ref?.explicit_date_scope); const aggregationAxis = aggregationAxisForPlanner(planner); if (metadataPilotEligible) { let metadataResult = null; const metadataScope = metadataScopeForPlanner(planner); const requestedMetaTypes = metadataTypesForPlanner(planner); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "inspect_1c_metadata") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_metadata_uses_only_inspect_1c_metadata")); continue; } metadataResult = await runtimeDeps.executeAddressMcpMetadata({ meta_type: requestedMetaTypes, name_mask: metadataScope ?? undefined, limit: planner.discovery_plan.execution_budget.max_rows_per_probe }); pushUnique(executedPrimitives, step.primitive_id); probeResults.push(metadataResultToProbeResult(step.primitive_id, metadataResult)); if (metadataResult.error) { pushUnique(queryLimitations, metadataResult.error); pushReason(reasonCodes, "pilot_inspect_1c_metadata_mcp_error"); } else { pushReason(reasonCodes, "pilot_inspect_1c_metadata_mcp_executed"); } } const sourceRowsSummary = metadataResult ? summarizeMetadataRows(metadataResult) : null; const derivedMetadataSurface = deriveMetadataSurface(metadataResult, metadataScope, requestedMetaTypes); if (derivedMetadataSurface) { pushReason(reasonCodes, "pilot_derived_metadata_surface_from_confirmed_rows"); } const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: buildMetadataConfirmedFacts(derivedMetadataSurface), inferredFacts: buildMetadataInferredFacts(derivedMetadataSurface), unknownFacts: buildMetadataUnknownFacts(derivedMetadataSurface, metadataScope), sourceRowsSummary, queryLimitations, recommendedNextProbe: "inspect_1c_metadata" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: "metadata_inspection_v1", dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: derivedMetadataSurface, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; } if (documentPilotEligible) { let queryResult = null; const filters = buildLifecycleFilters(planner); const selection = (0, addressRecipeCatalog_1.selectAddressRecipe)("list_documents_by_counterparty", filters); if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_document_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Document-evidence recipe is not available"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: "counterparty_document_evidence_query_documents_v1", dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["Document-evidence recipe is not available"], reason_codes: reasonCodes }; } const recipePlan = (0, addressRecipeCatalog_1.buildAddressRecipePlan)(selection.selected_recipe, filters); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "query_documents") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_only_executes_query_documents")); continue; } queryResult = await runtimeDeps.executeAddressMcpQuery({ query: recipePlan.query, limit: recipePlan.limit, account_scope: recipePlan.account_scope }); executedPrimitives.push(step.primitive_id); probeResults.push(queryResultToProbeResult(step.primitive_id, queryResult)); if (queryResult.error) { pushUnique(queryLimitations, queryResult.error); pushReason(reasonCodes, "pilot_query_documents_mcp_error"); } else { pushReason(reasonCodes, "pilot_query_documents_mcp_executed"); } } const sourceRowsSummary = queryResult ? summarizeDocumentRows(queryResult) : null; const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: queryResult ? buildDocumentConfirmedFacts(queryResult, counterparty) : [], inferredFacts: queryResult ? buildDocumentInferredFacts(queryResult) : [], unknownFacts: buildDocumentUnknownFacts(dateScope), sourceRowsSummary, queryLimitations, recommendedNextProbe: "explain_evidence_basis" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: "counterparty_document_evidence_query_documents_v1", dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; } if (movementPilotEligible) { let queryResult = null; const filters = buildValueFlowFilters(planner); const selection = (0, addressRecipeCatalog_1.selectAddressRecipe)("bank_operations_by_counterparty", filters); if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_movement_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Movement-evidence recipe is not available"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: "counterparty_movement_evidence_query_movements_v1", dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["Movement-evidence recipe is not available"], reason_codes: reasonCodes }; } const recipePlan = (0, addressRecipeCatalog_1.buildAddressRecipePlan)(selection.selected_recipe, filters); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "query_movements") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_only_executes_query_movements")); continue; } queryResult = await runtimeDeps.executeAddressMcpQuery({ query: recipePlan.query, limit: recipePlan.limit, account_scope: recipePlan.account_scope }); executedPrimitives.push(step.primitive_id); probeResults.push(queryResultToProbeResult(step.primitive_id, queryResult)); if (queryResult.error) { pushUnique(queryLimitations, queryResult.error); pushReason(reasonCodes, "pilot_query_movements_mcp_error"); } else { pushReason(reasonCodes, "pilot_query_movements_mcp_executed"); } } const sourceRowsSummary = queryResult ? summarizeMovementRows(queryResult) : null; const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: queryResult ? buildMovementConfirmedFacts(queryResult, counterparty) : [], inferredFacts: queryResult ? buildMovementInferredFacts(queryResult) : [], unknownFacts: buildMovementUnknownFacts(dateScope), sourceRowsSummary, queryLimitations, recommendedNextProbe: "explain_evidence_basis" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: "counterparty_movement_evidence_query_movements_v1", dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; } if (valueFlowPilotEligible) { let queryResult = null; const filters = buildValueFlowFilters(planner); const valueFlowProfile = valueFlowPilotProfile(planner); if (valueFlowProfile.direction === "bidirectional_net_value_flow") { let incomingResult = null; let outgoingResult = null; const incomingSelection = (0, addressRecipeCatalog_1.selectAddressRecipe)("customer_revenue_and_payments", filters); const outgoingSelection = (0, addressRecipeCatalog_1.selectAddressRecipe)("supplier_payouts_profile", filters); if (!incomingSelection.selected_recipe || !outgoingSelection.selected_recipe) { pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Bidirectional value-flow recipes are not available"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: valueFlowProfile.scope, dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["Bidirectional value-flow recipes are not available"], reason_codes: reasonCodes }; } pushReason(reasonCodes, "pilot_bidirectional_value_flow_recipes_selected"); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "query_movements") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_bidirectional_value_flow_uses_two_query_movements_and_derives_net")); continue; } const incomingExecution = await executeCoverageAwareValueFlowQuery({ primitiveId: step.primitive_id, recipePlanBuilder: (scopedFilters) => (0, addressRecipeCatalog_1.buildAddressRecipePlan)(incomingSelection.selected_recipe, scopedFilters), baseFilters: filters, dateScope, maxProbeCount: planner.discovery_plan.execution_budget.max_probe_count, maxRowsPerProbe: planner.discovery_plan.execution_budget.max_rows_per_probe, deps: runtimeDeps }); const outgoingExecution = await executeCoverageAwareValueFlowQuery({ primitiveId: step.primitive_id, recipePlanBuilder: (scopedFilters) => (0, addressRecipeCatalog_1.buildAddressRecipePlan)(outgoingSelection.selected_recipe, scopedFilters), baseFilters: filters, dateScope, maxProbeCount: planner.discovery_plan.execution_budget.max_probe_count, maxRowsPerProbe: planner.discovery_plan.execution_budget.max_rows_per_probe, deps: runtimeDeps }); incomingResult = incomingExecution.result; outgoingResult = outgoingExecution.result; pushUnique(executedPrimitives, step.primitive_id); probeResults.push(...incomingExecution.probe_results, ...outgoingExecution.probe_results); for (const limitation of [...incomingExecution.query_limitations, ...outgoingExecution.query_limitations]) { pushUnique(queryLimitations, limitation); } if (incomingResult?.error) { pushReason(reasonCodes, "pilot_bidirectional_incoming_query_movements_mcp_error"); } if (outgoingResult?.error) { pushReason(reasonCodes, "pilot_bidirectional_outgoing_query_movements_mcp_error"); } if (incomingResult?.coverage_recovered_by_period_chunking) { pushReason(reasonCodes, "pilot_bidirectional_incoming_monthly_period_chunking_recovered_coverage"); } if (outgoingResult?.coverage_recovered_by_period_chunking) { pushReason(reasonCodes, "pilot_bidirectional_outgoing_monthly_period_chunking_recovered_coverage"); } if (!incomingResult?.error || !outgoingResult?.error) { pushReason(reasonCodes, "pilot_bidirectional_query_movements_mcp_executed"); } } const sourceRowsSummary = summarizeBidirectionalValueFlowRows({ incomingResult, outgoingResult }); const derivedBidirectionalValueFlow = deriveBidirectionalValueFlow({ incomingResult, outgoingResult, counterparty, periodScope: dateScope, aggregationAxis }); if (derivedBidirectionalValueFlow) { pushReason(reasonCodes, "pilot_derived_bidirectional_value_flow_from_confirmed_rows"); if (aggregationAxis === "month" && derivedBidirectionalValueFlow.monthly_breakdown.length > 0) { pushReason(reasonCodes, "pilot_derived_bidirectional_monthly_breakdown_from_confirmed_rows"); } } const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: buildBidirectionalValueFlowConfirmedFacts(derivedBidirectionalValueFlow), inferredFacts: buildBidirectionalValueFlowInferredFacts(derivedBidirectionalValueFlow), unknownFacts: buildBidirectionalValueFlowUnknownFacts(dateScope, derivedBidirectionalValueFlow), sourceRowsSummary, queryLimitations, recommendedNextProbe: "explain_evidence_basis" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: valueFlowProfile.scope, dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: derivedBidirectionalValueFlow, query_limitations: queryLimitations, reason_codes: reasonCodes }; } const recipeIntent = valueFlowProfile.recipe_intent; const selection = recipeIntent ? (0, addressRecipeCatalog_1.selectAddressRecipe)(recipeIntent, filters) : { selected_recipe: null }; if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_value_flow_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Value-flow recipe is not available"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: valueFlowProfile.scope, dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["Value-flow recipe is not available"], reason_codes: reasonCodes }; } pushReason(reasonCodes, valueFlowProfile.direction === "outgoing_supplier_payout" ? "pilot_supplier_payout_recipe_selected" : "pilot_customer_revenue_recipe_selected"); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "query_movements") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_value_flow_uses_query_movements_and_derives_aggregate")); continue; } const execution = await executeCoverageAwareValueFlowQuery({ primitiveId: step.primitive_id, recipePlanBuilder: (scopedFilters) => (0, addressRecipeCatalog_1.buildAddressRecipePlan)(selection.selected_recipe, scopedFilters), baseFilters: filters, dateScope, maxProbeCount: planner.discovery_plan.execution_budget.max_probe_count, maxRowsPerProbe: planner.discovery_plan.execution_budget.max_rows_per_probe, deps: runtimeDeps }); queryResult = execution.result; pushUnique(executedPrimitives, step.primitive_id); probeResults.push(...execution.probe_results); for (const limitation of execution.query_limitations) { pushUnique(queryLimitations, limitation); } if (queryResult?.error) { pushReason(reasonCodes, "pilot_query_movements_mcp_error"); } else { pushReason(reasonCodes, "pilot_query_movements_mcp_executed"); } if (queryResult?.coverage_recovered_by_period_chunking) { pushReason(reasonCodes, "pilot_monthly_period_chunking_recovered_coverage"); } } const sourceRowsSummary = queryResult ? summarizeValueFlowRows(queryResult) : null; const derivedValueFlow = deriveValueFlow(queryResult, counterparty, dateScope, valueFlowProfile.direction, aggregationAxis); if (derivedValueFlow) { pushReason(reasonCodes, "pilot_derived_value_flow_from_confirmed_rows"); if (aggregationAxis === "month" && derivedValueFlow.monthly_breakdown.length > 0) { pushReason(reasonCodes, "pilot_derived_value_flow_monthly_breakdown_from_confirmed_rows"); } } const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: queryResult ? buildValueFlowConfirmedFacts(queryResult, counterparty, valueFlowProfile.direction) : [], inferredFacts: buildValueFlowInferredFacts(derivedValueFlow), unknownFacts: buildValueFlowUnknownFacts(dateScope, valueFlowProfile.direction, derivedValueFlow), sourceRowsSummary, queryLimitations, recommendedNextProbe: "explain_evidence_basis" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: valueFlowProfile.scope, dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: derivedValueFlow, derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; } let queryResult = null; const filters = buildLifecycleFilters(planner); const selection = (0, addressRecipeCatalog_1.selectAddressRecipe)("counterparty_activity_lifecycle", filters); if (!selection.selected_recipe) { pushReason(reasonCodes, "pilot_lifecycle_recipe_not_available"); const evidence = buildEmptyEvidence(planner, dryRun, probeResults, "Lifecycle recipe is not available"); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "unsupported", pilot_scope: "counterparty_lifecycle_query_documents_v1", dry_run: dryRun, mcp_execution_performed: false, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: null, derived_metadata_surface: null, derived_activity_period: null, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: ["Lifecycle recipe is not available"], reason_codes: reasonCodes }; } const recipePlan = (0, addressRecipeCatalog_1.buildAddressRecipePlan)(selection.selected_recipe, filters); for (const step of dryRun.execution_steps) { if (step.primitive_id !== "query_documents") { skippedPrimitives.push(step.primitive_id); probeResults.push(skippedProbeResult(step, "pilot_only_executes_query_documents")); continue; } queryResult = await runtimeDeps.executeAddressMcpQuery({ query: recipePlan.query, limit: recipePlan.limit, account_scope: recipePlan.account_scope }); executedPrimitives.push(step.primitive_id); probeResults.push(queryResultToProbeResult(step.primitive_id, queryResult)); if (queryResult.error) { pushUnique(queryLimitations, queryResult.error); pushReason(reasonCodes, "pilot_query_documents_mcp_error"); } else { pushReason(reasonCodes, "pilot_query_documents_mcp_executed"); } } const sourceRowsSummary = queryResult ? summarizeLifecycleRows(queryResult) : null; const derivedActivityPeriod = deriveActivityPeriod(queryResult); if (derivedActivityPeriod) { pushReason(reasonCodes, "pilot_derived_activity_period_from_confirmed_rows"); } const evidence = (0, assistantMcpDiscoveryPolicy_1.resolveAssistantMcpDiscoveryEvidence)({ plan: planner.discovery_plan, probeResults, confirmedFacts: queryResult ? buildLifecycleConfirmedFacts(queryResult, counterparty) : [], inferredFacts: queryResult ? buildLifecycleInferredFacts(queryResult) : [], unknownFacts: buildLifecycleUnknownFacts(), sourceRowsSummary, queryLimitations, recommendedNextProbe: "explain_evidence_basis" }); return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PILOT_EXECUTOR_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPilotExecutor", pilot_status: "executed", pilot_scope: "counterparty_lifecycle_query_documents_v1", dry_run: dryRun, mcp_execution_performed: executedPrimitives.length > 0, executed_primitives: executedPrimitives, skipped_primitives: skippedPrimitives, probe_results: probeResults, evidence, source_rows_summary: sourceRowsSummary, derived_metadata_surface: null, derived_activity_period: derivedActivityPeriod, derived_value_flow: null, derived_bidirectional_value_flow: null, query_limitations: queryLimitations, reason_codes: reasonCodes }; }