281 lines
12 KiB
TypeScript
281 lines
12 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import { ASSISTANT_MCP_DISCOVERY_PRIMITIVES, buildAssistantMcpDiscoveryPlan } from "../src/services/assistantMcpDiscoveryPolicy";
|
||
import {
|
||
buildAssistantMcpCatalogIndex,
|
||
getAssistantMcpCatalogChainTemplate,
|
||
getAssistantMcpCatalogPrimitive,
|
||
reviewAssistantMcpDiscoveryPlanAgainstCatalog,
|
||
searchAssistantMcpCatalogPrimitivesByDecompositionCandidates,
|
||
searchAssistantMcpCatalogPrimitivesByFactAxis,
|
||
searchAssistantMcpCatalogPrimitivesByMetadataSurface
|
||
} from "../src/services/assistantMcpCatalogIndex";
|
||
|
||
describe("assistant MCP catalog index", () => {
|
||
it("declares a catalog contract for every reviewed discovery primitive", () => {
|
||
const index = buildAssistantMcpCatalogIndex();
|
||
const primitiveIds = index.primitives.map((entry) => entry.primitive_id);
|
||
|
||
expect(index.reason_codes).toContain("catalog_covers_all_discovery_primitives");
|
||
expect(index.reason_codes).toContain("catalog_chain_templates_reference_reviewed_primitives");
|
||
expect(primitiveIds).toEqual([...ASSISTANT_MCP_DISCOVERY_PRIMITIVES]);
|
||
for (const entry of index.primitives) {
|
||
expect(entry.safe_for_model_planning).toBe(true);
|
||
expect(entry.runtime_must_execute).toBe(true);
|
||
expect(entry.decomposition_hints.length).toBeGreaterThan(0);
|
||
expect(Array.isArray(entry.supported_fact_families)).toBe(true);
|
||
expect(Array.isArray(entry.supported_action_families)).toBe(true);
|
||
expect(Array.isArray(entry.planning_tags)).toBe(true);
|
||
expect(entry.required_axes_any_of.length).toBeGreaterThan(0);
|
||
expect(entry.output_fact_kinds.length).toBeGreaterThan(0);
|
||
}
|
||
expect(index.chain_templates.map((entry) => entry.chain_id)).toEqual([
|
||
"metadata_inspection",
|
||
"catalog_drilldown",
|
||
"entity_resolution",
|
||
"document_evidence",
|
||
"movement_evidence",
|
||
"value_flow",
|
||
"value_flow_comparison",
|
||
"value_flow_ranking",
|
||
"lifecycle"
|
||
]);
|
||
for (const template of index.chain_templates) {
|
||
expect(template.safe_for_model_planning).toBe(true);
|
||
expect(template.requires_evidence_gate).toBe(true);
|
||
expect(template.semantic_data_need.length).toBeGreaterThan(0);
|
||
expect(template.chain_summary.length).toBeGreaterThan(0);
|
||
expect(template.fallback_primitives.length).toBeGreaterThan(0);
|
||
for (const primitive of template.fallback_primitives) {
|
||
expect(primitiveIds).toContain(primitive);
|
||
}
|
||
}
|
||
});
|
||
|
||
it("exposes reusable chain templates for planner route-fabric selection", () => {
|
||
const documentTemplate = getAssistantMcpCatalogChainTemplate("document_evidence");
|
||
const movementTemplate = getAssistantMcpCatalogChainTemplate("movement_evidence");
|
||
const valueFlowTemplate = getAssistantMcpCatalogChainTemplate("value_flow");
|
||
const valueFlowComparisonTemplate = getAssistantMcpCatalogChainTemplate("value_flow_comparison");
|
||
const valueFlowRankingTemplate = getAssistantMcpCatalogChainTemplate("value_flow_ranking");
|
||
|
||
expect(documentTemplate.fallback_primitives).toEqual([
|
||
"resolve_entity_reference",
|
||
"query_documents",
|
||
"probe_coverage"
|
||
]);
|
||
expect(movementTemplate.fallback_primitives).toEqual([
|
||
"resolve_entity_reference",
|
||
"query_movements",
|
||
"probe_coverage"
|
||
]);
|
||
expect(valueFlowTemplate.base_required_axes).toEqual(["aggregate_axis", "amount", "coverage_target"]);
|
||
expect(valueFlowComparisonTemplate.fallback_primitives).toEqual(["query_movements", "probe_coverage"]);
|
||
expect(valueFlowRankingTemplate.fallback_primitives).toEqual([
|
||
"query_movements",
|
||
"aggregate_by_axis",
|
||
"probe_coverage"
|
||
]);
|
||
});
|
||
|
||
it("can search reviewed primitives from data-need decomposition candidates", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates({
|
||
decomposition_candidates: [
|
||
"resolve_entity_reference",
|
||
"collect_scoped_movements",
|
||
"aggregate_checked_amounts",
|
||
"probe_coverage"
|
||
]
|
||
});
|
||
|
||
expect(primitives).toEqual([
|
||
"resolve_entity_reference",
|
||
"query_movements",
|
||
"aggregate_by_axis",
|
||
"probe_coverage"
|
||
]);
|
||
});
|
||
|
||
it("can suppress aggregate_by_axis for decomposition shapes that derive comparison without an aggregate primitive", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates({
|
||
decomposition_candidates: [
|
||
"collect_incoming_movements",
|
||
"collect_outgoing_movements",
|
||
"aggregate_by_month",
|
||
"probe_coverage"
|
||
],
|
||
allow_aggregate_by_axis: false
|
||
});
|
||
|
||
expect(primitives).toEqual(["query_movements", "probe_coverage"]);
|
||
});
|
||
|
||
it("can search reviewed primitives directly from fact family and required axes", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({
|
||
business_fact_family: "document_evidence",
|
||
action_family: "list_documents",
|
||
has_subject_candidates: true,
|
||
required_axes: ["counterparty", "period", "coverage_target"]
|
||
});
|
||
|
||
expect(primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
|
||
});
|
||
|
||
it("treats all-time organization-scoped value-flow as catalog-compatible without inventing a fake period axis", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({
|
||
business_fact_family: "value_flow",
|
||
action_family: "turnover",
|
||
has_subject_candidates: false,
|
||
required_axes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target"]
|
||
});
|
||
|
||
expect(primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
|
||
});
|
||
|
||
it("can search reviewed primitives directly from a confirmed document metadata surface", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({
|
||
downstream_route_family: "document_evidence",
|
||
selected_entity_set: "Document",
|
||
selected_surface_objects: ["Document.InvoiceIssued"],
|
||
recommended_next_primitive: "query_documents",
|
||
required_axes: ["counterparty", "period", "coverage_target"]
|
||
});
|
||
|
||
expect(primitives).toEqual(["query_documents", "resolve_entity_reference", "probe_coverage"]);
|
||
});
|
||
|
||
it("can search reviewed primitives directly from a confirmed movement metadata surface", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({
|
||
downstream_route_family: "movement_evidence",
|
||
selected_entity_set: "AccumulationRegister",
|
||
selected_surface_objects: ["Register.BankOperations"],
|
||
recommended_next_primitive: "query_movements",
|
||
required_axes: ["counterparty", "period", "coverage_target"]
|
||
});
|
||
|
||
expect(primitives).toEqual(["query_movements", "resolve_entity_reference", "probe_coverage"]);
|
||
});
|
||
|
||
it("can search reviewed primitives directly from a confirmed catalog metadata surface without inventing an unsupported drilldown primitive", () => {
|
||
const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({
|
||
downstream_route_family: "catalog_drilldown",
|
||
selected_entity_set: "Catalog",
|
||
selected_surface_objects: ["Catalog.Counterparties"],
|
||
recommended_next_primitive: "drilldown_related_objects",
|
||
required_axes: ["metadata_scope"]
|
||
});
|
||
|
||
expect(primitives).toEqual(["inspect_1c_metadata"]);
|
||
});
|
||
|
||
it("marks a counterparty turnover discovery plan as catalog-compatible when required axes exist", () => {
|
||
const plan = buildAssistantMcpDiscoveryPlan({
|
||
semanticDataNeed: "counterparty turnover evidence",
|
||
turnMeaning: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "turnover",
|
||
explicit_entity_candidates: ["SVK"]
|
||
},
|
||
proposedPrimitives: ["resolve_entity_reference", "query_movements", "aggregate_by_axis"],
|
||
requiredAxes: ["counterparty", "period", "aggregate_axis", "amount"]
|
||
});
|
||
|
||
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
|
||
|
||
expect(review.review_status).toBe("catalog_compatible");
|
||
expect(review.reason_codes).toContain("catalog_plan_compatible");
|
||
expect(review.missing_axes_by_primitive).toEqual({});
|
||
expect(review.evidence_floors.query_movements).toBe("rows_matched");
|
||
});
|
||
|
||
it("asks for more axes before document discovery can run safely", () => {
|
||
const plan = buildAssistantMcpDiscoveryPlan({
|
||
semanticDataNeed: "document evidence",
|
||
turnMeaning: {
|
||
asked_domain_family: "counterparty_documents",
|
||
asked_action_family: "list_documents"
|
||
},
|
||
proposedPrimitives: ["query_documents"],
|
||
requiredAxes: ["amount"]
|
||
});
|
||
|
||
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
|
||
|
||
expect(review.review_status).toBe("needs_more_axes");
|
||
expect(review.reason_codes).toContain("catalog_required_axes_missing_for_primitive");
|
||
expect(review.missing_axes_by_primitive.query_documents).toEqual([
|
||
["document"],
|
||
["counterparty"],
|
||
["contract"],
|
||
["period", "organization"],
|
||
["all_time_scope", "counterparty"],
|
||
["all_time_scope", "organization"]
|
||
]);
|
||
});
|
||
|
||
it("marks an all-time organization-scoped value-flow plan as catalog-compatible without requiring an explicit period", () => {
|
||
const plan = buildAssistantMcpDiscoveryPlan({
|
||
semanticDataNeed: "organization-scoped value-flow evidence",
|
||
turnMeaning: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "turnover",
|
||
explicit_organization_scope: "ООО Альтернатива Плюс"
|
||
},
|
||
proposedPrimitives: ["query_movements", "aggregate_by_axis", "probe_coverage"],
|
||
requiredAxes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target"]
|
||
});
|
||
|
||
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
|
||
|
||
expect(review.review_status).toBe("catalog_compatible");
|
||
expect(review.reason_codes).toContain("catalog_plan_compatible");
|
||
expect(review.missing_axes_by_primitive).toEqual({});
|
||
});
|
||
|
||
it("marks an all-time organization-scoped document plan as catalog-compatible without requiring an explicit period", () => {
|
||
const plan = buildAssistantMcpDiscoveryPlan({
|
||
semanticDataNeed: "document evidence",
|
||
turnMeaning: {
|
||
asked_domain_family: "documents",
|
||
asked_action_family: "list_documents",
|
||
explicit_organization_scope: "ООО Альтернатива Плюс",
|
||
metadata_scope_hint: "НДС",
|
||
subject_resolution_optional: true
|
||
},
|
||
proposedPrimitives: ["query_documents", "probe_coverage"],
|
||
requiredAxes: ["organization", "all_time_scope", "metadata_scope", "coverage_target"]
|
||
});
|
||
|
||
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
|
||
|
||
expect(review.review_status).toBe("catalog_compatible");
|
||
expect(review.reason_codes).toContain("catalog_plan_compatible");
|
||
expect(review.missing_axes_by_primitive).toEqual({});
|
||
});
|
||
|
||
it("preserves source-summary evidence floors for metadata and coverage primitives", () => {
|
||
expect(getAssistantMcpCatalogPrimitive("inspect_1c_metadata").evidence_floor).toBe("source_summary");
|
||
expect(getAssistantMcpCatalogPrimitive("probe_coverage").evidence_floor).toBe("source_summary");
|
||
expect(getAssistantMcpCatalogPrimitive("resolve_entity_reference").evidence_floor).toBe("rows_matched");
|
||
});
|
||
|
||
it("turns a non-allowed discovery plan into a catalog-level blocked review", () => {
|
||
const plan = buildAssistantMcpDiscoveryPlan({
|
||
semanticDataNeed: "raw model sql",
|
||
turnMeaning: {
|
||
asked_domain_family: "counterparty_value",
|
||
asked_action_family: "turnover",
|
||
explicit_entity_candidates: ["SVK"]
|
||
},
|
||
proposedPrimitives: ["raw_sql"],
|
||
requiredAxes: ["counterparty"]
|
||
});
|
||
|
||
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
|
||
|
||
expect(plan.plan_status).toBe("blocked");
|
||
expect(review.review_status).toBe("catalog_blocked");
|
||
expect(review.reason_codes).toContain("catalog_review_received_non_allowed_plan");
|
||
expect(review.reason_codes).toContain("catalog_plan_blocked");
|
||
});
|
||
});
|