Planner Autonomy: поднять inventory routes в MCP catalog

This commit is contained in:
2026-05-01 13:08:21 +03:00
parent 6bfbd5cb20
commit 9243642400
15 changed files with 1162 additions and 61 deletions
@@ -44,8 +44,28 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "resolve_entity_reference",
purpose: "Resolve a user-visible entity name to a concrete 1C reference candidate.",
decomposition_hints: ["resolve_entity_reference"],
supported_fact_families: ["entity_grounding", "value_flow", "document_evidence", "movement_evidence", "activity_lifecycle"],
supported_action_families: ["search_business_entity", "turnover", "payout", "net_value_flow", "list_documents", "list_movements", "activity_duration"],
supported_fact_families: [
"entity_grounding",
"value_flow",
"document_evidence",
"movement_evidence",
"activity_lifecycle",
"inventory_purchase_provenance",
"inventory_sale_trace",
"inventory_supplier_overlap"
],
supported_action_families: [
"search_business_entity",
"turnover",
"payout",
"net_value_flow",
"list_documents",
"list_movements",
"activity_duration",
"purchase_provenance",
"sale_trace",
"supplier_overlap"
],
planning_tags: ["subject_resolution"],
required_axes_any_of: [["business_entity"], ["counterparty"], ["organization"], ["contract"], ["item"]],
optional_axes: ["period", "inn", "document"],
@@ -63,18 +83,21 @@ const PRIMITIVE_CONTRACTS = [
"collect_outgoing_movements",
"fetch_scoped_movements"
],
supported_fact_families: ["value_flow", "movement_evidence"],
supported_action_families: ["turnover", "payout", "net_value_flow", "list_movements"],
supported_fact_families: ["value_flow", "movement_evidence", "inventory_stock_snapshot", "inventory_supplier_overlap"],
supported_action_families: ["turnover", "payout", "net_value_flow", "list_movements", "stock_snapshot", "supplier_overlap"],
planning_tags: ["movement", "comparison", "ranking", "aggregation", "monthly_aggregation"],
required_axes_any_of: [
["period", "account"],
["period", "counterparty"],
["period", "organization"],
["as_of_date", "organization"],
["as_of_date", "warehouse"],
["as_of_date", "item"],
["all_time_scope", "counterparty"],
["all_time_scope", "organization"]
],
optional_axes: ["contract", "document", "amount", "item", "warehouse"],
output_fact_kinds: ["movement_rows", "turnover", "balance_delta"],
optional_axes: ["contract", "document", "amount", "item", "warehouse", "quantity", "supplier"],
output_fact_kinds: ["movement_rows", "turnover", "balance_delta", "stock_rows", "stock_quantity"],
evidence_floor: "rows_matched",
safe_for_model_planning: true,
runtime_must_execute: true
@@ -83,19 +106,27 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "query_documents",
purpose: "Fetch documents related to a scoped entity, period, contract, or movement explanation.",
decomposition_hints: ["fetch_scoped_documents", "fetch_supporting_documents"],
supported_fact_families: ["document_evidence", "activity_lifecycle"],
supported_action_families: ["list_documents", "activity_duration"],
supported_fact_families: [
"document_evidence",
"activity_lifecycle",
"inventory_purchase_provenance",
"inventory_sale_trace",
"inventory_supplier_overlap"
],
supported_action_families: ["list_documents", "activity_duration", "purchase_provenance", "sale_trace", "supplier_overlap"],
planning_tags: ["document"],
required_axes_any_of: [
["document"],
["item"],
["supplier"],
["counterparty"],
["contract"],
["period", "organization"],
["all_time_scope", "counterparty"],
["all_time_scope", "organization"]
],
optional_axes: ["account", "amount", "item", "warehouse"],
output_fact_kinds: ["document_rows", "document_dates", "document_amounts"],
optional_axes: ["account", "amount", "item", "warehouse", "as_of_date", "supplier", "buyer"],
output_fact_kinds: ["document_rows", "document_dates", "document_amounts", "purchase_documents", "sale_documents"],
evidence_floor: "rows_matched",
safe_for_model_planning: true,
runtime_must_execute: true
@@ -104,18 +135,19 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "aggregate_by_axis",
purpose: "Aggregate already-scoped 1C evidence by a business axis such as counterparty, contract, or period.",
decomposition_hints: ["aggregate_checked_amounts", "aggregate_ranked_axis_values", "aggregate_by_month"],
supported_fact_families: ["value_flow"],
supported_action_families: ["turnover", "payout", "net_value_flow"],
supported_fact_families: ["value_flow", "inventory_stock_snapshot", "inventory_supplier_overlap"],
supported_action_families: ["turnover", "payout", "net_value_flow", "stock_snapshot", "supplier_overlap"],
planning_tags: ["aggregation", "ranking", "monthly_aggregation"],
required_axes_any_of: [
["aggregate_axis", "period"],
["aggregate_axis", "as_of_date"],
["aggregate_axis", "counterparty"],
["aggregate_axis", "account"],
["aggregate_axis", "counterparty", "all_time_scope"],
["aggregate_axis", "organization", "all_time_scope"]
],
optional_axes: ["organization", "contract", "document", "amount"],
output_fact_kinds: ["aggregate_totals", "ranked_axis_values"],
optional_axes: ["organization", "contract", "document", "amount", "quantity", "item", "warehouse", "supplier"],
output_fact_kinds: ["aggregate_totals", "ranked_axis_values", "stock_totals", "item_totals"],
evidence_floor: "rows_matched",
safe_for_model_planning: true,
runtime_must_execute: true
@@ -124,12 +156,12 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "drilldown_related_objects",
purpose: "Drill from a known entity or document into related contracts, documents, movements, or payments.",
decomposition_hints: ["drilldown_related_objects"],
supported_fact_families: [],
supported_action_families: [],
planning_tags: ["drilldown"],
required_axes_any_of: [["business_entity"], ["document"], ["contract"], ["counterparty"]],
optional_axes: ["period", "account", "amount"],
output_fact_kinds: ["related_objects", "relationship_edges"],
supported_fact_families: ["inventory_purchase_provenance", "inventory_sale_trace", "inventory_supplier_overlap"],
supported_action_families: ["purchase_provenance", "sale_trace", "supplier_overlap", "purchase_to_sale_chain"],
planning_tags: ["drilldown", "inventory"],
required_axes_any_of: [["business_entity"], ["document"], ["contract"], ["counterparty"], ["item"], ["supplier"]],
optional_axes: ["period", "account", "amount", "warehouse", "as_of_date", "buyer"],
output_fact_kinds: ["related_objects", "relationship_edges", "supplier_item_edges", "buyer_item_edges"],
evidence_floor: "rows_received",
safe_for_model_planning: true,
runtime_must_execute: true
@@ -144,7 +176,11 @@ const PRIMITIVE_CONTRACTS = [
"value_flow",
"document_evidence",
"movement_evidence",
"activity_lifecycle"
"activity_lifecycle",
"inventory_stock_snapshot",
"inventory_purchase_provenance",
"inventory_sale_trace",
"inventory_supplier_overlap"
],
supported_action_families: [
"inspect_catalog",
@@ -158,11 +194,16 @@ const PRIMITIVE_CONTRACTS = [
"net_value_flow",
"list_documents",
"list_movements",
"activity_duration"
"activity_duration",
"stock_snapshot",
"purchase_provenance",
"sale_trace",
"supplier_overlap",
"purchase_to_sale_chain"
],
planning_tags: ["coverage"],
required_axes_any_of: [["coverage_target"], ["domain_family"], ["primitive_id"]],
optional_axes: ["period", "organization", "counterparty", "document", "account"],
optional_axes: ["period", "organization", "counterparty", "document", "account", "item", "warehouse", "as_of_date"],
output_fact_kinds: ["coverage_status", "known_gaps"],
evidence_floor: "source_summary",
safe_for_model_planning: true,
@@ -172,11 +213,24 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "explain_evidence_basis",
purpose: "Produce a machine-readable explanation of which checked MCP evidence supports, limits, or fails the answer.",
decomposition_hints: ["explain_evidence_basis"],
supported_fact_families: ["activity_lifecycle"],
supported_action_families: ["activity_duration"],
planning_tags: ["explanation"],
supported_fact_families: [
"activity_lifecycle",
"inventory_stock_snapshot",
"inventory_purchase_provenance",
"inventory_sale_trace",
"inventory_supplier_overlap"
],
supported_action_families: [
"activity_duration",
"stock_snapshot",
"purchase_provenance",
"sale_trace",
"supplier_overlap",
"purchase_to_sale_chain"
],
planning_tags: ["explanation", "inventory"],
required_axes_any_of: [["evidence_basis"], ["primitive_id"], ["source_rows_summary"]],
optional_axes: ["coverage_target", "domain_family"],
optional_axes: ["coverage_target", "domain_family", "item", "warehouse", "as_of_date", "supplier", "buyer"],
output_fact_kinds: ["confirmed_facts", "inferred_facts", "unknown_facts"],
evidence_floor: "source_summary",
safe_for_model_planning: true,
@@ -245,6 +299,73 @@ const CHAIN_TEMPLATES = [
safe_for_model_planning: true,
requires_evidence_gate: true
},
{
chain_id: "inventory_stock_snapshot",
semantic_data_need: "inventory stock snapshot evidence",
chain_summary: "Fetch checked inventory movement or balance rows for the requested as-of date, aggregate item quantities, then probe coverage and explain stock-snapshot limits before answering.",
fallback_primitives: ["query_movements", "aggregate_by_axis", "probe_coverage", "explain_evidence_basis"],
base_required_axes: ["as_of_date", "organization", "warehouse", "aggregate_axis", "quantity", "coverage_target", "evidence_basis"],
supported_fact_families: ["inventory_stock_snapshot"],
supported_action_families: ["stock_snapshot"],
planning_tags: ["inventory", "movement", "aggregation", "coverage", "explanation"],
safe_for_model_planning: true,
requires_evidence_gate: true
},
{
chain_id: "inventory_supplier_overlap",
semantic_data_need: "inventory supplier overlap evidence",
chain_summary: "Ground the supplier or item anchor, fetch checked stock and supporting purchase evidence for the requested slice, aggregate item overlap, then state supplier-link limits explicitly.",
fallback_primitives: [
"resolve_entity_reference",
"query_movements",
"query_documents",
"aggregate_by_axis",
"probe_coverage",
"explain_evidence_basis"
],
base_required_axes: ["supplier", "item", "warehouse", "as_of_date", "aggregate_axis", "coverage_target", "evidence_basis"],
supported_fact_families: ["inventory_supplier_overlap"],
supported_action_families: ["supplier_overlap"],
planning_tags: ["inventory", "subject_resolution", "movement", "document", "aggregation", "coverage", "explanation"],
safe_for_model_planning: true,
requires_evidence_gate: true
},
{
chain_id: "inventory_purchase_provenance",
semantic_data_need: "inventory purchase provenance evidence",
chain_summary: "Ground the selected item, fetch checked purchase documents, drill into related supplier evidence, then probe coverage before stating purchase provenance.",
fallback_primitives: [
"resolve_entity_reference",
"query_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
],
base_required_axes: ["item", "document", "supplier", "coverage_target", "evidence_basis"],
supported_fact_families: ["inventory_purchase_provenance"],
supported_action_families: ["purchase_provenance"],
planning_tags: ["inventory", "document", "drilldown", "subject_resolution", "coverage", "explanation"],
safe_for_model_planning: true,
requires_evidence_gate: true
},
{
chain_id: "inventory_sale_trace",
semantic_data_need: "inventory sale trace evidence",
chain_summary: "Ground the selected item, fetch checked sale documents, drill into related buyer evidence, then probe coverage before stating the sale or purchase-to-sale trace.",
fallback_primitives: [
"resolve_entity_reference",
"query_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
],
base_required_axes: ["item", "document", "buyer", "coverage_target", "evidence_basis"],
supported_fact_families: ["inventory_sale_trace"],
supported_action_families: ["sale_trace", "purchase_to_sale_chain"],
planning_tags: ["inventory", "document", "drilldown", "subject_resolution", "coverage", "explanation"],
safe_for_model_planning: true,
requires_evidence_gate: true
},
{
chain_id: "value_flow",
semantic_data_need: "counterparty value-flow evidence",
@@ -355,6 +476,23 @@ function tagSetFromFactAxisInput(input) {
if (input.business_fact_family === "value_flow") {
tags.add("movement");
}
if (input.business_fact_family?.startsWith("inventory_")) {
tags.add("inventory");
}
if (input.business_fact_family === "inventory_stock_snapshot") {
tags.add("movement");
tags.add("aggregation");
}
if (input.business_fact_family === "inventory_supplier_overlap") {
tags.add("movement");
tags.add("document");
tags.add("aggregation");
}
if (input.business_fact_family === "inventory_purchase_provenance" ||
input.business_fact_family === "inventory_sale_trace") {
tags.add("document");
tags.add("drilldown");
}
if (input.comparison_need) {
tags.add("comparison");
}
@@ -528,6 +666,9 @@ function searchAssistantMcpCatalogPrimitivesByFactAxis(input) {
if (contract.primitive_id === "explain_evidence_basis" && !desiredTags.has("explanation")) {
continue;
}
if (contract.primitive_id === "drilldown_related_objects" && !desiredTags.has("drilldown")) {
continue;
}
if (!factMatch && !actionMatch && tagMatches.length <= 0) {
continue;
}
@@ -44,6 +44,32 @@ function businessFactFamilyFor(input) {
if (combined.includes("entity discovery") || combined.includes("entity_resolution")) {
return "entity_grounding";
}
if (combined.includes("inventory") ||
combined.includes("stock") ||
combined.includes("warehouse") ||
combined.includes("item provenance") ||
combined.includes("purchase provenance")) {
if (combined.includes("sale_trace") ||
combined.includes("sale trace") ||
combined.includes("buyer") ||
combined.includes("purchase_to_sale") ||
combined.includes("purchase-to-sale")) {
return "inventory_sale_trace";
}
if (combined.includes("supplier_overlap") ||
combined.includes("supplier overlap") ||
combined.includes("supplier stock") ||
combined.includes("stock by supplier")) {
return "inventory_supplier_overlap";
}
if (combined.includes("purchase_provenance") ||
combined.includes("purchase provenance") ||
combined.includes("purchase document") ||
combined.includes("supplier provenance")) {
return "inventory_purchase_provenance";
}
return "inventory_stock_snapshot";
}
if (combined.includes("lifecycle") || combined.includes("activity")) {
return "activity_lifecycle";
}
@@ -87,6 +113,12 @@ function timeScopeNeedFor(input) {
if (input.family === "activity_lifecycle") {
return "open_activity_window";
}
if (input.family === "inventory_stock_snapshot" || input.family === "inventory_supplier_overlap") {
return input.explicitDateScope ? "explicit_period" : "as_of_date_required";
}
if (input.family === "inventory_purchase_provenance" || input.family === "inventory_sale_trace") {
return input.explicitDateScope ? "explicit_period" : null;
}
return null;
}
function comparisonNeedFor(action) {
@@ -230,6 +262,30 @@ function decompositionCandidatesFor(input) {
pushUnique(result, "fetch_supporting_documents");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
return result;
}
if (input.family === "inventory_stock_snapshot") {
pushUnique(result, "fetch_scoped_movements");
pushUnique(result, "aggregate_checked_amounts");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
return result;
}
if (input.family === "inventory_supplier_overlap") {
pushUnique(result, "resolve_entity_reference");
pushUnique(result, "fetch_scoped_movements");
pushUnique(result, "fetch_scoped_documents");
pushUnique(result, "aggregate_checked_amounts");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
return result;
}
if (input.family === "inventory_purchase_provenance" || input.family === "inventory_sale_trace") {
pushUnique(result, "resolve_entity_reference");
pushUnique(result, "fetch_scoped_documents");
pushUnique(result, "drilldown_related_objects");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
}
return result;
}
@@ -247,6 +303,15 @@ function forbiddenOverclaimFlagsFor(family) {
if (family === "value_flow" || family === "movement_evidence" || family === "document_evidence") {
pushUnique(result, "no_unchecked_fact_totals");
}
if (family === "inventory_stock_snapshot") {
pushUnique(result, "no_unchecked_stock_snapshot");
}
if (family === "inventory_purchase_provenance" || family === "inventory_supplier_overlap") {
pushUnique(result, "no_unproven_supplier_attribution");
}
if (family === "inventory_sale_trace") {
pushUnique(result, "no_unproven_buyer_or_sale_trace");
}
return result;
}
function buildAssistantMcpDiscoveryDataNeedGraph(input) {
@@ -290,6 +355,8 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
family: businessFactFamily,
subjectResolutionOptional
});
const inventoryStockSnapshotWithoutSubject = subjectCandidates.length === 0 &&
businessFactFamily === "inventory_stock_snapshot";
const clarificationGaps = [];
if (unsupported === "metadata_lane_choice_clarification" || action === "resolve_next_lane") {
pushUnique(clarificationGaps, "lane_family_choice");
@@ -308,7 +375,8 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
else if (subjectCandidates.length === 0 &&
businessFactFamily !== "schema_surface" &&
!openScopeWithoutSubject &&
!metadataScopedOpenLaneWithoutSubject) {
!metadataScopedOpenLaneWithoutSubject &&
!inventoryStockSnapshotWithoutSubject) {
pushUnique(clarificationGaps, "subject");
}
const timeScopeNeed = timeScopeNeedFor({
@@ -319,6 +387,9 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
if (timeScopeNeed === "period_required" && !explicitDateScope) {
pushUnique(clarificationGaps, "period");
}
if (timeScopeNeed === "as_of_date_required" && !explicitDateScope) {
pushUnique(clarificationGaps, "as_of_date");
}
const decompositionCandidates = decompositionCandidatesFor({
family: businessFactFamily,
action,
@@ -1812,6 +1812,11 @@ function pilotScopeForPlanner(planner) {
case "metadata_lane_clarification":
case "metadata_inspection":
return "metadata_inspection_v1";
case "inventory_stock_snapshot":
case "inventory_supplier_overlap":
case "inventory_purchase_provenance":
case "inventory_sale_trace":
return "inventory_route_template_v1";
case "movement_evidence":
return "counterparty_movement_evidence_query_movements_v1";
case "value_flow_comparison":
@@ -1827,6 +1832,12 @@ function pilotScopeForPlanner(planner) {
}
}
function isLivePilotChainSupported(chainId) {
if (chainId === "inventory_stock_snapshot" ||
chainId === "inventory_supplier_overlap" ||
chainId === "inventory_purchase_provenance" ||
chainId === "inventory_sale_trace") {
return false;
}
return true;
}
async function executeAssistantMcpDiscoveryPilot(planner, deps = DEFAULT_DEPS) {
@@ -530,6 +530,100 @@ function recipeFor(input) {
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");
@@ -658,6 +752,58 @@ function recipeFor(input) {
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");
@@ -787,6 +787,18 @@ function semanticNeedFor(input) {
if (/(?:document|documents|list_documents)/iu.test(combined)) {
return "document evidence";
}
if (/(?:inventory|stock|warehouse|purchase_provenance|purchase provenance|supplier provenance|supplier_overlap|supplier overlap|sale_trace|sale trace|purchase_to_sale|purchase-to-sale)/iu.test(combined)) {
if (/(?:sale_trace|sale trace|purchase_to_sale|purchase-to-sale|buyer)/iu.test(combined)) {
return "inventory sale trace evidence";
}
if (/(?:supplier_overlap|supplier overlap|supplier stock|stock by supplier)/iu.test(combined)) {
return "inventory supplier overlap evidence";
}
if (/(?:purchase_provenance|purchase provenance|supplier provenance|purchase document)/iu.test(combined)) {
return "inventory purchase provenance evidence";
}
return "inventory stock snapshot evidence";
}
return null;
}
function shouldRunDiscovery(input) {