"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = void 0; exports.planAssistantMcpDiscovery = planAssistantMcpDiscovery; const assistantMcpDiscoveryPolicy_1 = require("./assistantMcpDiscoveryPolicy"); const assistantMcpCatalogIndex_1 = require("./assistantMcpCatalogIndex"); exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION = "assistant_mcp_discovery_planner_v1"; function toNonEmptyString(value) { if (value === null || value === undefined) { return null; } const text = String(value).trim(); return text.length > 0 ? text : null; } function lower(value) { return String(value ?? "").trim().toLowerCase(); } 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 pushAllUnique(target, values) { for (const value of values) { pushUnique(target, value); } } const LIFECYCLE_BOUNDED_INFERENCE_REASON_CODES = [ "planner_lifecycle_bounded_activity_window_template", "planner_lifecycle_legal_fact_boundary_required" ]; function recipeFromCatalogChainTemplate(input) { const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)(input.chainId); const axes = [...input.axes]; pushAllUnique(axes, template.base_required_axes); return { semanticDataNeed: input.semanticDataNeed ?? template.semantic_data_need, chainId: template.chain_id, chainSummary: input.chainSummary ?? template.chain_summary, primitives: input.primitives ?? template.fallback_primitives, axes, reason: input.reason, extraReasons: [ `planner_instantiated_catalog_chain_template_${template.chain_id}`, ...(input.extraReasons ?? []) ] }; } function hasEntity(meaning) { return (meaning?.explicit_entity_candidates?.length ?? 0) > 0; } function hasSubjectCandidates(graph) { return (graph?.subject_candidates.length ?? 0) > 0; } function hasMetadataScopedOpenLane(graph, meaning) { return Boolean(graph?.subject_resolution_optional === true || meaning?.subject_resolution_optional === true); } function hasReasonCode(graph, reasonCode) { return (graph?.reason_codes ?? []).includes(reasonCode); } function aggregationAxis(meaning) { return toNonEmptyString(meaning?.asked_aggregation_axis)?.toLowerCase() ?? null; } function addScopeAxes(axes, meaning) { if (hasEntity(meaning)) { pushUnique(axes, "counterparty"); } if (toNonEmptyString(meaning?.explicit_organization_scope)) { pushUnique(axes, "organization"); } if (toNonEmptyString(meaning?.explicit_date_scope)) { pushUnique(axes, "period"); } } function addMetadataScopeAxis(axes, meaning) { if (toNonEmptyString(meaning?.metadata_scope_hint)) { pushUnique(axes, "metadata_scope"); } } function addTimeScopeAxes(axes, dataNeedGraph) { if (dataNeedGraph?.time_scope_need === "all_time_scope") { pushUnique(axes, "all_time_scope"); } } function includesAny(text, tokens) { return tokens.some((token) => text.includes(token)); } function isYearDateScope(meaning) { return /^\d{4}$/.test(toNonEmptyString(meaning?.explicit_date_scope) ?? ""); } function mergeCatalogPrimitivesWithFallback(catalogPrimitives, fallbackPrimitives) { const result = []; for (const primitive of fallbackPrimitives) { if (catalogPrimitives.includes(primitive) && !result.includes(primitive)) { result.push(primitive); } } for (const primitive of catalogPrimitives) { if (!result.includes(primitive)) { result.push(primitive); } } for (const primitive of fallbackPrimitives) { if (!result.includes(primitive)) { result.push(primitive); } } return result; } function normalizeMetadataSurfaceToken(value) { return String(value ?? "").trim().toLowerCase().replace(/[\s_.-]+/g, ""); } function metadataSurfaceValueSuggestsDocument(value) { const token = normalizeMetadataSurfaceToken(value); return token.includes("document") || token.includes("invoice") || token.includes("waybill") || token.includes("act"); } function metadataSurfaceValueSuggestsMovement(value) { const token = normalizeMetadataSurfaceToken(value); return token.includes("register") || token.includes("movement") || token.includes("operation") || token.includes("bank"); } function metadataSurfaceValueSuggestsCatalog(value) { const token = normalizeMetadataSurfaceToken(value); return token.includes("catalog") || token.includes("directory"); } function routeFamilyFromMetadataSurfaceRef(surface) { if (!surface || surface.ambiguity_detected) { return null; } if (surface.downstream_route_family) { return surface.downstream_route_family; } const values = [surface.selected_entity_set ?? "", ...surface.selected_surface_objects]; const documentHit = values.some(metadataSurfaceValueSuggestsDocument); const movementHit = values.some(metadataSurfaceValueSuggestsMovement); const catalogHit = values.some(metadataSurfaceValueSuggestsCatalog); const hitCount = [documentHit, movementHit, catalogHit].filter(Boolean).length; if (hitCount !== 1) { return null; } if (documentHit) { return "document_evidence"; } if (movementHit) { return "movement_evidence"; } return "catalog_drilldown"; } function inferredRouteFamilyFromMetadataSurfaceRef(surface) { return Boolean(surface && !surface.downstream_route_family && routeFamilyFromMetadataSurfaceRef(surface)); } function preferredPrimitiveForRouteFamily(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 preferredPrimitiveFromMetadataSurface(surface) { if (surface?.ambiguity_detected) { return null; } const recommendedPrimitive = surface?.recommended_next_primitive ?? null; if (recommendedPrimitive) { return recommendedPrimitive; } return preferredPrimitiveForRouteFamily(routeFamilyFromMetadataSurfaceRef(surface)); } function preferredPrimitiveFromExplicitDataNeedGraph(graph) { const factFamily = lower(graph?.business_fact_family); const actionFamily = lower(graph?.action_family); if (factFamily === "document_evidence" || actionFamily === "list_documents") { return "query_documents"; } if (factFamily === "movement_evidence" || actionFamily === "list_movements") { return "query_movements"; } return null; } function hasCarriedMetadataSurfaceScoringEvidence(surface) { return Boolean(surface && (toNonEmptyString(surface.selected_entity_set) || surface.selected_surface_objects.length > 0 || surface.ambiguity_entity_sets.length > 0)); } function filterCatalogPrimitivesByMetadataSurface(input) { const surfacePreferredPrimitive = preferredPrimitiveFromMetadataSurface(input.metadataSurface); const dataNeedPreferredPrimitive = preferredPrimitiveFromExplicitDataNeedGraph(input.dataNeedGraph); const preferredPrimitive = surfacePreferredPrimitive ?? dataNeedPreferredPrimitive; const hasSurfaceScoringEvidence = hasCarriedMetadataSurfaceScoringEvidence(input.metadataSurface); const reasonCodes = []; if (!preferredPrimitive || !input.fallbackPrimitives.includes(preferredPrimitive)) { return { primitives: input.catalogPrimitives, reasonCodes }; } const laneSensitivePrimitives = new Set([ "query_documents", "query_movements", "drilldown_related_objects" ]); const filteredPrimitives = input.catalogPrimitives.filter((primitive) => !laneSensitivePrimitives.has(primitive) || primitive === preferredPrimitive); if (filteredPrimitives.length !== input.catalogPrimitives.length) { reasonCodes.push(surfacePreferredPrimitive ? "planner_filtered_catalog_primitives_by_confirmed_metadata_surface" : "planner_filtered_catalog_primitives_by_explicit_data_need_lane"); } if ((filteredPrimitives.includes(preferredPrimitive) || input.fallbackPrimitives.includes(preferredPrimitive)) && hasSurfaceScoringEvidence) { reasonCodes.push(surfacePreferredPrimitive ? "planner_surface_aware_next_lane_from_confirmed_metadata_objects" : "planner_metadata_surface_scored_with_explicit_lane_family"); } return { primitives: filteredPrimitives, reasonCodes }; } function selectPrimitivesFromGraphAndCatalog(input) { const reasonCodes = []; const decompositionCandidates = input.dataNeedGraph?.decomposition_candidates ?? []; const decompositionPrimitives = decompositionCandidates.length > 0 ? (0, assistantMcpCatalogIndex_1.searchAssistantMcpCatalogPrimitivesByDecompositionCandidates)({ decomposition_candidates: decompositionCandidates, allow_aggregate_by_axis: input.allowAggregateByAxis }) : []; if (decompositionPrimitives.length > 0) { reasonCodes.push("planner_selected_catalog_primitives_from_decomposition_candidates"); } const metadataSurfacePrimitives = input.metadataSurface ? (0, assistantMcpCatalogIndex_1.searchAssistantMcpCatalogPrimitivesByMetadataSurface)({ downstream_route_family: input.metadataSurface.downstream_route_family, selected_entity_set: input.metadataSurface.selected_entity_set, selected_surface_objects: input.metadataSurface.selected_surface_objects, recommended_next_primitive: input.metadataSurface.recommended_next_primitive, required_axes: input.requiredAxes, allow_aggregate_by_axis: input.allowAggregateByAxis }) : []; if (metadataSurfacePrimitives.length > 0) { reasonCodes.push("planner_selected_catalog_primitives_from_metadata_surface_search"); } const factAxisPrimitives = input.dataNeedGraph ? (0, assistantMcpCatalogIndex_1.searchAssistantMcpCatalogPrimitivesByFactAxis)({ business_fact_family: input.dataNeedGraph.business_fact_family, action_family: input.actionFamily ?? input.dataNeedGraph.action_family, required_axes: input.requiredAxes, comparison_need: input.dataNeedGraph.comparison_need, ranking_need: input.dataNeedGraph.ranking_need, aggregation_need: input.dataNeedGraph.aggregation_need, has_subject_candidates: hasSubjectCandidates(input.dataNeedGraph), allow_aggregate_by_axis: input.allowAggregateByAxis }) : []; if (factAxisPrimitives.length > 0) { reasonCodes.push("planner_selected_catalog_primitives_from_fact_axis_search"); } const chainTemplateMatches = input.dataNeedGraph ? (0, assistantMcpCatalogIndex_1.searchAssistantMcpCatalogChainTemplatesByFactAxis)({ business_fact_family: input.dataNeedGraph.business_fact_family, action_family: input.actionFamily ?? input.dataNeedGraph.action_family, required_axes: input.requiredAxes, comparison_need: input.dataNeedGraph.comparison_need, ranking_need: input.dataNeedGraph.ranking_need, aggregation_need: input.dataNeedGraph.aggregation_need }) : []; if (chainTemplateMatches.length > 0) { reasonCodes.push("planner_scored_catalog_chain_templates_from_fact_axis"); reasonCodes.push(`planner_catalog_chain_template_search_top_${chainTemplateMatches[0]}`); } const combinedCatalogPrimitives = []; for (const primitive of decompositionPrimitives) { if (!combinedCatalogPrimitives.includes(primitive)) { combinedCatalogPrimitives.push(primitive); } } for (const primitive of metadataSurfacePrimitives) { if (!combinedCatalogPrimitives.includes(primitive)) { combinedCatalogPrimitives.push(primitive); } } for (const primitive of factAxisPrimitives) { if (!combinedCatalogPrimitives.includes(primitive)) { combinedCatalogPrimitives.push(primitive); } } const filteredCatalogPrimitives = filterCatalogPrimitivesByMetadataSurface({ catalogPrimitives: combinedCatalogPrimitives, fallbackPrimitives: input.fallbackPrimitives, dataNeedGraph: input.dataNeedGraph, metadataSurface: input.metadataSurface }); reasonCodes.push(...filteredCatalogPrimitives.reasonCodes); if (filteredCatalogPrimitives.primitives.length <= 0) { return { primitives: input.fallbackPrimitives, reasonCodes: ["planner_fell_back_to_recipe_primitives_after_empty_catalog_search"] }; } const mergedPrimitives = mergeCatalogPrimitivesWithFallback(filteredCatalogPrimitives.primitives, input.fallbackPrimitives); if (input.fallbackPrimitives.some((primitive) => !filteredCatalogPrimitives.primitives.includes(primitive))) { reasonCodes.push("planner_completed_catalog_searched_chain_with_recipe_primitives"); } return { primitives: mergedPrimitives, reasonCodes }; } function budgetOverrideFor(input, recipe) { const meaning = input.turnMeaning ?? null; const requestedAggregationAxis = aggregationAxis(meaning); const isValueFlowRecipe = recipe.semanticDataNeed === "counterparty value-flow evidence" && recipe.primitives.includes("query_movements"); if (!isValueFlowRecipe) { return {}; } if (requestedAggregationAxis === "month" || isYearDateScope(meaning)) { return { maxProbeCount: 30 }; } return {}; } function catalogChainTemplateMatchesForContract(input, recipe) { const dataNeedGraph = input.dataNeedGraph ?? null; if (!dataNeedGraph) { return []; } return (0, assistantMcpCatalogIndex_1.searchAssistantMcpCatalogChainTemplatesByFactAxis)({ business_fact_family: dataNeedGraph.business_fact_family, action_family: toNonEmptyString(input.turnMeaning?.asked_action_family) ?? dataNeedGraph.action_family, required_axes: recipe.axes, comparison_need: dataNeedGraph.comparison_need, ranking_need: dataNeedGraph.ranking_need, aggregation_need: dataNeedGraph.aggregation_need }); } function routeFamilyFromThinMetadataSurfaceInput(input) { const surface = input.metadataSurface ?? null; const surfaceRouteFamily = routeFamilyFromMetadataSurfaceRef(surface); if (!surface || surface.ambiguity_detected || !surfaceRouteFamily) { return null; } const meaning = input.turnMeaning ?? null; const dataNeedGraph = input.dataNeedGraph ?? null; const graphFactFamily = lower(dataNeedGraph?.business_fact_family); const domain = lower(meaning?.asked_domain_family); const action = lower(meaning?.asked_action_family); const unsupported = lower(meaning?.unsupported_but_understood_family); const semanticNeed = lower(input.semanticDataNeed); const combined = `${domain} ${action} ${unsupported} ${semanticNeed}`.trim(); const explicitlyOtherFamily = includesAny(combined, ["value_flow", "turnover", "revenue", "payment", "payout", "net", "lifecycle", "activity", "duration", "metadata lane clarification"]); if (explicitlyOtherFamily) { return null; } if (graphFactFamily === "document_evidence" || includesAny(combined, ["document", "documents", "list_documents"])) { return surfaceRouteFamily === "document_evidence" ? "document_evidence" : null; } if (graphFactFamily === "movement_evidence" || includesAny(combined, ["movement", "movements", "list_movements", "bank_operations"])) { return surfaceRouteFamily === "movement_evidence" ? "movement_evidence" : null; } if (graphFactFamily === "schema_surface" || includesAny(combined, ["catalog", "directory", "inspect_catalog"])) { return surfaceRouteFamily === "catalog_drilldown" ? "catalog_drilldown" : null; } if (!graphFactFamily && !domain && !action) { return surfaceRouteFamily; } return null; } function recipeFor(input) { const meaning = input.turnMeaning ?? null; const dataNeedGraph = input.dataNeedGraph ?? null; const domain = lower(meaning?.asked_domain_family); const action = lower(meaning?.asked_action_family); const unsupported = lower(meaning?.unsupported_but_understood_family); const graphFactFamily = lower(dataNeedGraph?.business_fact_family); const graphAction = lower(dataNeedGraph?.action_family); const graphAggregation = lower(dataNeedGraph?.aggregation_need); const graphClarificationGaps = (dataNeedGraph?.clarification_gaps ?? []).map((item) => lower(item)); const metadataScopedOpenLane = hasMetadataScopedOpenLane(dataNeedGraph, meaning); const openScopeTotalWithoutSubject = graphFactFamily === "value_flow" && !hasSubjectCandidates(dataNeedGraph) && hasReasonCode(dataNeedGraph, "data_need_graph_open_scope_total_without_subject"); const combined = `${domain} ${action} ${unsupported}`.trim(); const axes = []; const requestedAggregationAxis = aggregationAxis(meaning); addScopeAxes(axes, meaning); addMetadataScopeAxis(axes, meaning); addTimeScopeAxes(axes, dataNeedGraph); if (graphClarificationGaps.includes("lane_family_choice")) { pushUnique(axes, "lane_family_choice"); return { semanticDataNeed: "metadata lane clarification", chainId: "metadata_lane_clarification", chainSummary: "Preserve the ambiguous metadata surface and ask the user to choose the next data lane before running MCP probes.", primitives: [], axes, reason: "planner_selected_metadata_lane_clarification_from_data_need_graph" }; } const thinSurfaceRouteFamily = routeFamilyFromThinMetadataSurfaceInput(input); if (thinSurfaceRouteFamily === "document_evidence") { pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("document_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "document_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_document_from_confirmed_metadata_surface_ref", chainSummary: "Ground the next checked document lane from the confirmed metadata surface, then fetch scoped document rows and probe coverage before answering.", extraReasons: [ ...primitiveSelection.reasonCodes, ...(inferredRouteFamilyFromMetadataSurfaceRef(input.metadataSurface) ? ["planner_inferred_next_lane_from_unambiguous_metadata_surface"] : []) ] }); } if (thinSurfaceRouteFamily === "movement_evidence") { pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("movement_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "movement_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_movement_from_confirmed_metadata_surface_ref", chainSummary: "Ground the next checked movement lane from the confirmed metadata surface, then fetch scoped movement rows and probe coverage before answering.", extraReasons: [ ...primitiveSelection.reasonCodes, ...(inferredRouteFamilyFromMetadataSurfaceRef(input.metadataSurface) ? ["planner_inferred_next_lane_from_unambiguous_metadata_surface"] : []) ] }); } if (thinSurfaceRouteFamily === "catalog_drilldown") { pushUnique(axes, "metadata_scope"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("catalog_drilldown"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "catalog_drilldown", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_catalog_drilldown_from_confirmed_metadata_surface_ref", chainSummary: "Drill deeper into the confirmed catalog-oriented metadata surface, inspect related metadata objects, and keep the next safe lane grounded in checked schema evidence.", extraReasons: [ ...primitiveSelection.reasonCodes, ...(inferredRouteFamilyFromMetadataSurfaceRef(input.metadataSurface) ? ["planner_inferred_next_lane_from_unambiguous_metadata_surface"] : []) ] }); } if (graphFactFamily === "value_flow") { if (dataNeedGraph?.comparison_need === "incoming_vs_outgoing") { pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); if (requestedAggregationAxis === "month" || graphAggregation === "by_month") { pushUnique(axes, "calendar_month"); } const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("value_flow_comparison"); const fallbackPrimitives = hasSubjectCandidates(dataNeedGraph) ? ["resolve_entity_reference", ...template.fallback_primitives] : template.fallback_primitives; const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action, allowAggregateByAxis: false }); return recipeFromCatalogChainTemplate({ chainId: "value_flow_comparison", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_bidirectional_value_flow_comparison_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (dataNeedGraph?.ranking_need && !hasSubjectCandidates(dataNeedGraph)) { pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("value_flow_ranking"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action, allowAggregateByAxis: true }); return recipeFromCatalogChainTemplate({ chainId: "value_flow_ranking", axes, primitives: primitiveSelection.primitives, reason: dataNeedGraph.ranking_need === "bottom_asc" ? "planner_selected_bottom_ranked_value_flow_from_data_need_graph" : "planner_selected_top_ranked_value_flow_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (openScopeTotalWithoutSubject) { pushUnique(axes, "organization"); pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); if (requestedAggregationAxis === "month" || graphAggregation === "by_month") { pushUnique(axes, "calendar_month"); } const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: ["query_movements", "aggregate_by_axis", "probe_coverage"], requiredAxes: axes, actionFamily: action, allowAggregateByAxis: true }); return recipeFromCatalogChainTemplate({ chainId: "value_flow", axes, primitives: primitiveSelection.primitives, semanticDataNeed: "organization-scoped value-flow evidence", chainSummary: "Query scoped movements for the checked period and organization without a preselected counterparty, aggregate checked amounts, then probe coverage before answering a bounded total.", reason: requestedAggregationAxis === "month" || graphAggregation === "by_month" ? "planner_selected_monthly_open_scope_value_flow_total_from_data_need_graph" : "planner_selected_open_scope_value_flow_total_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); if (requestedAggregationAxis === "month" || graphAggregation === "by_month") { pushUnique(axes, "calendar_month"); } const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("value_flow"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action, allowAggregateByAxis: true }); return recipeFromCatalogChainTemplate({ chainId: "value_flow", axes, primitives: primitiveSelection.primitives, reason: requestedAggregationAxis === "month" || graphAggregation === "by_month" ? "planner_selected_monthly_value_flow_from_data_need_graph" : "planner_selected_value_flow_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "activity_lifecycle") { pushUnique(axes, "document_date"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("lifecycle"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "lifecycle", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_lifecycle_from_data_need_graph", extraReasons: [...primitiveSelection.reasonCodes, ...LIFECYCLE_BOUNDED_INFERENCE_REASON_CODES] }); } if (graphFactFamily === "inventory_stock_snapshot") { pushUnique(axes, "as_of_date"); pushUnique(axes, "organization"); pushUnique(axes, "warehouse"); pushUnique(axes, "aggregate_axis"); pushUnique(axes, "quantity"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("inventory_stock_snapshot"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action || graphAction, allowAggregateByAxis: true }); return recipeFromCatalogChainTemplate({ chainId: "inventory_stock_snapshot", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_inventory_stock_snapshot_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "inventory_supplier_overlap") { pushUnique(axes, "supplier"); pushUnique(axes, "item"); pushUnique(axes, "warehouse"); pushUnique(axes, "as_of_date"); pushUnique(axes, "aggregate_axis"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("inventory_supplier_overlap"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action || graphAction, allowAggregateByAxis: true }); return recipeFromCatalogChainTemplate({ chainId: "inventory_supplier_overlap", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_inventory_supplier_overlap_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "inventory_purchase_provenance") { pushUnique(axes, "item"); pushUnique(axes, "document"); pushUnique(axes, "supplier"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("inventory_purchase_provenance"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action || graphAction }); return recipeFromCatalogChainTemplate({ chainId: "inventory_purchase_provenance", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_inventory_purchase_provenance_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "inventory_sale_trace") { pushUnique(axes, "item"); pushUnique(axes, "document"); pushUnique(axes, "buyer"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("inventory_sale_trace"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action || graphAction }); return recipeFromCatalogChainTemplate({ chainId: "inventory_sale_trace", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_inventory_sale_trace_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "schema_surface") { pushUnique(axes, "metadata_scope"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("metadata_inspection"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "metadata_inspection", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_metadata_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "movement_evidence") { if (metadataScopedOpenLane) { pushUnique(axes, "organization"); pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("movement_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: ["query_movements", "probe_coverage"], requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "movement_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_metadata_scoped_movement_from_data_need_graph", chainSummary: "Keep the metadata-scoped movement lane, ask only for the remaining business scope, then fetch scoped movement rows and probe coverage without pretending there is a grounded counterparty.", semanticDataNeed: template.semantic_data_need, extraReasons: primitiveSelection.reasonCodes }); } pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("movement_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "movement_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_movement_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "document_evidence") { if (metadataScopedOpenLane) { pushUnique(axes, "organization"); pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("document_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: ["query_documents", "probe_coverage"], requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "document_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_metadata_scoped_document_from_data_need_graph", chainSummary: "Keep the metadata-scoped document lane, ask only for the remaining business scope, then fetch scoped document rows and probe coverage without pretending there is a grounded counterparty.", semanticDataNeed: template.semantic_data_need, extraReasons: primitiveSelection.reasonCodes }); } pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("document_evidence"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "document_evidence", axes, primitives: primitiveSelection.primitives, reason: "planner_selected_document_from_data_need_graph", extraReasons: primitiveSelection.reasonCodes }); } if (graphFactFamily === "entity_grounding" || (!graphFactFamily && (dataNeedGraph?.subject_candidates.length ?? 0) > 0)) { pushUnique(axes, "business_entity"); pushUnique(axes, "coverage_target"); const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("entity_resolution"); const primitiveSelection = selectPrimitivesFromGraphAndCatalog({ dataNeedGraph, fallbackPrimitives: template.fallback_primitives, requiredAxes: axes, metadataSurface: input.metadataSurface, actionFamily: action }); return recipeFromCatalogChainTemplate({ chainId: "entity_resolution", axes, primitives: primitiveSelection.primitives, reason: graphAction === "search_business_entity" ? "planner_selected_entity_resolution_from_data_need_graph" : "planner_selected_entity_resolution_recipe", extraReasons: primitiveSelection.reasonCodes }); } if (includesAny(combined, ["metadata_lane_choice_clarification", "resolve_next_lane"])) { pushUnique(axes, "lane_family_choice"); return { semanticDataNeed: "metadata lane clarification", chainId: "metadata_lane_clarification", chainSummary: "Preserve the ambiguous metadata surface and ask the user to choose the next data lane before running MCP probes.", primitives: [], axes, reason: "planner_selected_metadata_lane_clarification_recipe" }; } if (includesAny(combined, ["inventory_sale_trace", "sale_trace", "sale trace", "purchase_to_sale", "purchase-to-sale", "buyer"])) { pushUnique(axes, "item"); pushUnique(axes, "document"); pushUnique(axes, "buyer"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); return recipeFromCatalogChainTemplate({ chainId: "inventory_sale_trace", axes, reason: "planner_selected_inventory_sale_trace_recipe" }); } if (includesAny(combined, ["inventory_supplier_overlap", "supplier overlap", "supplier stock", "stock by supplier"])) { pushUnique(axes, "supplier"); pushUnique(axes, "item"); pushUnique(axes, "warehouse"); pushUnique(axes, "as_of_date"); pushUnique(axes, "aggregate_axis"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); return recipeFromCatalogChainTemplate({ chainId: "inventory_supplier_overlap", axes, reason: "planner_selected_inventory_supplier_overlap_recipe" }); } if (includesAny(combined, ["inventory_purchase_provenance", "purchase_provenance", "purchase provenance", "supplier provenance"])) { pushUnique(axes, "item"); pushUnique(axes, "document"); pushUnique(axes, "supplier"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); return recipeFromCatalogChainTemplate({ chainId: "inventory_purchase_provenance", axes, reason: "planner_selected_inventory_purchase_provenance_recipe" }); } if (includesAny(combined, ["inventory", "stock", "warehouse"])) { pushUnique(axes, "as_of_date"); pushUnique(axes, "organization"); pushUnique(axes, "warehouse"); pushUnique(axes, "aggregate_axis"); pushUnique(axes, "quantity"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); return recipeFromCatalogChainTemplate({ chainId: "inventory_stock_snapshot", axes, reason: "planner_selected_inventory_stock_snapshot_recipe" }); } if (includesAny(combined, ["turnover", "revenue", "payment", "payout", "value", "net", "netting", "balance", "cashflow"])) { pushUnique(axes, "aggregate_axis"); pushUnique(axes, "amount"); pushUnique(axes, "coverage_target"); if (requestedAggregationAxis === "month") { pushUnique(axes, "calendar_month"); } return recipeFromCatalogChainTemplate({ chainId: "value_flow", axes, reason: requestedAggregationAxis === "month" ? "planner_selected_monthly_value_flow_recipe" : "planner_selected_value_flow_recipe" }); } if (includesAny(combined, ["lifecycle", "activity", "duration", "age"])) { pushUnique(axes, "document_date"); pushUnique(axes, "coverage_target"); pushUnique(axes, "evidence_basis"); return recipeFromCatalogChainTemplate({ chainId: "lifecycle", axes, reason: "planner_selected_lifecycle_recipe", extraReasons: LIFECYCLE_BOUNDED_INFERENCE_REASON_CODES }); } if (includesAny(combined, ["metadata", "schema", "catalog"])) { pushUnique(axes, "metadata_scope"); return recipeFromCatalogChainTemplate({ chainId: "metadata_inspection", axes, reason: "planner_selected_metadata_recipe" }); } if (includesAny(combined, ["movement", "movements", "bank_operations", "movement_evidence", "list_movements"])) { pushUnique(axes, "coverage_target"); return recipeFromCatalogChainTemplate({ chainId: "movement_evidence", axes, reason: "planner_selected_movement_recipe" }); } if (includesAny(combined, ["document", "documents"])) { pushUnique(axes, "coverage_target"); return recipeFromCatalogChainTemplate({ chainId: "document_evidence", axes, reason: "planner_selected_document_recipe" }); } if (hasEntity(meaning)) { pushUnique(axes, "business_entity"); pushUnique(axes, "coverage_target"); return recipeFromCatalogChainTemplate({ chainId: "entity_resolution", axes, reason: "planner_selected_entity_resolution_recipe" }); } return recipeFromCatalogChainTemplate({ chainId: "metadata_inspection", semanticDataNeed: "unclassified 1C discovery need", chainSummary: "Start with metadata inspection instead of guessing a deeper fact route when the business need is still under-specified.", axes, reason: "planner_selected_clarification_recipe" }); } function statusFrom(plan, review) { if (plan.plan_status === "blocked" || review.review_status === "catalog_blocked") { return "blocked"; } if (plan.plan_status !== "allowed" || review.review_status !== "catalog_compatible") { return "needs_clarification"; } return "ready_for_execution"; } function planAssistantMcpDiscovery(input) { const recipe = recipeFor(input); const budgetOverride = budgetOverrideFor(input, recipe); const semanticDataNeed = toNonEmptyString(input.semanticDataNeed) ?? recipe.semanticDataNeed; const dataNeedGraph = input.dataNeedGraph ?? null; const metadataSurface = input.metadataSurface ?? null; const catalogChainTemplateMatches = catalogChainTemplateMatchesForContract(input, recipe); const reasonCodes = []; pushReason(reasonCodes, recipe.reason); for (const reason of recipe.extraReasons ?? []) { pushReason(reasonCodes, reason); } if (dataNeedGraph) { pushReason(reasonCodes, "planner_consumed_data_need_graph_v1"); } if (metadataSurface) { pushReason(reasonCodes, "planner_consumed_metadata_surface_ref_v1"); } if (budgetOverride.maxProbeCount) { pushReason(reasonCodes, "planner_enabled_chunked_coverage_probe_budget"); } const plan = (0, assistantMcpDiscoveryPolicy_1.buildAssistantMcpDiscoveryPlan)({ semanticDataNeed, turnMeaning: input.turnMeaning, proposedPrimitives: recipe.primitives, requiredAxes: recipe.axes, clarificationGaps: dataNeedGraph?.clarification_gaps ?? [], maxProbeCount: budgetOverride.maxProbeCount }); const review = (0, assistantMcpCatalogIndex_1.reviewAssistantMcpDiscoveryPlanAgainstCatalog)(plan); const organizationClarificationRequired = (dataNeedGraph?.clarification_gaps ?? []).includes("organization") && !toNonEmptyString(input.turnMeaning?.explicit_organization_scope); const adjustedReview = organizationClarificationRequired && recipe.primitives.includes("query_movements") ? { ...review, review_status: "needs_more_axes", missing_axes_by_primitive: { ...review.missing_axes_by_primitive, query_movements: review.missing_axes_by_primitive.query_movements?.length ? review.missing_axes_by_primitive.query_movements : [["organization"]] }, reason_codes: review.reason_codes.includes("catalog_requires_organization_scope_from_data_need_graph") ? review.reason_codes : [...review.reason_codes, "catalog_requires_organization_scope_from_data_need_graph"] } : review; const plannerStatus = organizationClarificationRequired ? "needs_clarification" : statusFrom(plan, adjustedReview); if (organizationClarificationRequired) { pushReason(reasonCodes, "planner_requires_organization_scope_from_data_need_graph"); } if (plannerStatus === "ready_for_execution") { pushReason(reasonCodes, "planner_ready_for_guarded_mcp_execution"); } else if (plannerStatus === "blocked") { pushReason(reasonCodes, "planner_blocked_by_policy_or_catalog"); } else { pushReason(reasonCodes, "planner_needs_more_user_or_scope_context"); } return { schema_version: exports.ASSISTANT_MCP_DISCOVERY_PLANNER_SCHEMA_VERSION, policy_owner: "assistantMcpDiscoveryPlanner", planner_status: plannerStatus, semantic_data_need: semanticDataNeed, data_need_graph: dataNeedGraph, metadata_surface_ref: metadataSurface, selected_chain_id: recipe.chainId, selected_chain_summary: recipe.chainSummary, catalog_chain_template_matches: catalogChainTemplateMatches, proposed_primitives: recipe.primitives, required_axes: recipe.axes, discovery_plan: plan, catalog_review: adjustedReview, reason_codes: reasonCodes }; }