Planner Autonomy: ранжировать catalog chain templates
This commit is contained in:
parent
ccfa9283e9
commit
4dcffef7d6
|
|
@ -110,6 +110,14 @@ The next local scoring step broadened metadata-surface autonomy without adding a
|
||||||
- inferred catalog surfaces instantiate `catalog_drilldown`;
|
- inferred catalog surfaces instantiate `catalog_drilldown`;
|
||||||
- mixed or ambiguous surfaces still do not guess and continue through clarification / explicit data-need scoring.
|
- mixed or ambiguous surfaces still do not guess and continue through clarification / explicit data-need scoring.
|
||||||
|
|
||||||
|
The following consolidation step added catalog-level chain-template scoring:
|
||||||
|
|
||||||
|
- `assistantMcpCatalogIndex` can now score reviewed `chain_templates` directly from fact family, action family, required axes, comparison, ranking, and aggregation needs;
|
||||||
|
- comparison-shaped value-flow ranks `value_flow_comparison` above the generic value-flow template;
|
||||||
|
- ranking-shaped value-flow ranks `value_flow_ranking` above the generic value-flow template;
|
||||||
|
- document/movement/inventory/lifecycle templates can now be inspected as catalog search results, not only as local planner branch constants;
|
||||||
|
- `assistantMcpDiscoveryPlanner` now records the top catalog chain-template match in reason codes while preserving existing guarded execution behavior.
|
||||||
|
|
||||||
## Why This Matters
|
## Why This Matters
|
||||||
|
|
||||||
This reduces the pressure to add one hard route per user wording.
|
This reduces the pressure to add one hard route per user wording.
|
||||||
|
|
@ -183,6 +191,13 @@ Latest validation after unambiguous metadata-surface lane inference:
|
||||||
- live inventory full-pack attempt: `inventory_stock_exact_bridge_live_20260501_after_runtime_bridge`, status `partial`
|
- live inventory full-pack attempt: `inventory_stock_exact_bridge_live_20260501_after_runtime_bridge`, status `partial`
|
||||||
- live attempt interpretation: route/intent/recipe/capability selection matched, but MCP execution failed with `MCP fetch failed: This operation was aborted`; direct proxy `get_metadata` also timed out while `/health` reported `active_sessions_count=0` and pending commands, so this is an infrastructure/polling-session blocker rather than accepted semantic evidence.
|
- live attempt interpretation: route/intent/recipe/capability selection matched, but MCP execution failed with `MCP fetch failed: This operation was aborted`; direct proxy `get_metadata` also timed out while `/health` reported `active_sessions_count=0` and pending commands, so this is an infrastructure/polling-session blocker rather than accepted semantic evidence.
|
||||||
|
|
||||||
|
Latest validation after catalog chain-template scoring:
|
||||||
|
|
||||||
|
- targeted catalog/planner tests: passed, `54 passed`
|
||||||
|
- full MCP-discovery suite: passed, `282 passed`, `9 skipped`
|
||||||
|
- `npm.cmd run build`: passed
|
||||||
|
- graphify rebuild: `5938 nodes`, `12903 edges`, `139 communities`
|
||||||
|
|
||||||
## Next Step
|
## Next Step
|
||||||
|
|
||||||
The next safe step is to re-run live replay once the 1C side is actively polling the proxy, then continue into broader reviewed scoring.
|
The next safe step is to re-run live replay once the 1C side is actively polling the proxy, then continue into broader reviewed scoring.
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ It now documents a turnaround that is already operational in code, already mater
|
||||||
- runtime bridge and answer adapter now keep unsupported inventory route templates behind an explicit user-facing boundary instead of letting template planning look like confirmed stock/supplier/purchase/sale evidence;
|
- runtime bridge and answer adapter now keep unsupported inventory route templates behind an explicit user-facing boundary instead of letting template planning look like confirmed stock/supplier/purchase/sale evidence;
|
||||||
- inventory catalog templates now bridge through existing exact inventory recipes (`41.01` scoped stock, supplier overlap, purchase provenance, and sale trace) inside the bounded MCP discovery pilot, while missing selected-item anchors still clarify instead of guessing;
|
- inventory catalog templates now bridge through existing exact inventory recipes (`41.01` scoped stock, supplier overlap, purchase provenance, and sale trace) inside the bounded MCP discovery pilot, while missing selected-item anchors still clarify instead of guessing;
|
||||||
- unambiguous metadata surfaces can now infer the next reviewed lane from `Document.*`, `Register.*`, or `Catalog.*` objects even before upstream labels `downstream_route_family`, while mixed surfaces still do not guess;
|
- unambiguous metadata surfaces can now infer the next reviewed lane from `Document.*`, `Register.*`, or `Catalog.*` objects even before upstream labels `downstream_route_family`, while mixed surfaces still do not guess;
|
||||||
|
- catalog index now scores reviewed chain templates directly from fact/action/axis/comparison/ranking needs, and planner exposes the top catalog chain match in reason codes;
|
||||||
- live map sync: [20 - planner_autonomy_consolidation_2026-05-01.md](./20%20-%20planner_autonomy_consolidation_2026-05-01.md)
|
- live map sync: [20 - planner_autonomy_consolidation_2026-05-01.md](./20%20-%20planner_autonomy_consolidation_2026-05-01.md)
|
||||||
|
|
||||||
Current honest status:
|
Current honest status:
|
||||||
|
|
@ -91,8 +92,8 @@ Current honest status:
|
||||||
- open-world bounded-autonomy readiness: `~85%`
|
- open-world bounded-autonomy readiness: `~85%`
|
||||||
- Post-F semantic integrity module progress: `~99%` operationally closed, with remaining risk now treated as next-slice discovery rather than an open blocker inside the closed slice
|
- Post-F semantic integrity module progress: `~99%` operationally closed, with remaining risk now treated as next-slice discovery rather than an open blocker inside the closed slice
|
||||||
- active inventory-stock breadth slice progress: `100%` for the declared scenario pack, not for arbitrary inventory questions
|
- active inventory-stock breadth slice progress: `100%` for the declared scenario pack, not for arbitrary inventory questions
|
||||||
- Planner Autonomy Consolidation progress: `~78%` for the declared module, with catalog-fabric, value-flow arbitration, lifecycle bounded inference, broad-evaluation bridge, inventory catalog templates, inventory runtime-boundary honesty, exact inventory recipe bridging, and unambiguous metadata-surface lane inference validated locally, but live replay for the new bridge is currently blocked by missing active 1C polling and broader unfamiliar 1C asks still need replay-backed growth
|
- Planner Autonomy Consolidation progress: `~80%` for the declared module, with catalog-fabric, value-flow arbitration, lifecycle bounded inference, broad-evaluation bridge, inventory catalog templates, inventory runtime-boundary honesty, exact inventory recipe bridging, unambiguous metadata-surface lane inference, and catalog chain-template scoring validated locally, but live replay for the new bridge is currently blocked by missing active 1C polling and broader unfamiliar 1C asks still need replay-backed growth
|
||||||
- graph snapshot after latest rebuild: `5937 nodes`, `12899 edges`, `138 communities`
|
- graph snapshot after latest rebuild: `5938 nodes`, `12903 edges`, `139 communities`
|
||||||
- current breakpoint:
|
- current breakpoint:
|
||||||
- the validated hot paths are no longer structurally broken;
|
- the validated hot paths are no longer structurally broken;
|
||||||
- flagship continuity collapse is no longer the primary risk;
|
- flagship continuity collapse is no longer the primary risk;
|
||||||
|
|
@ -137,6 +138,7 @@ Latest live proof now includes:
|
||||||
- inventory exact-runtime bridge accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `70/70` with `1` skipped; full MCP-discovery slice passed `279/279` with `9` skipped; build passed; graphify rebuilt to `5930 nodes`, `12884 edges`, `135 communities`
|
- inventory exact-runtime bridge accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `70/70` with `1` skipped; full MCP-discovery slice passed `279/279` with `9` skipped; build passed; graphify rebuilt to `5930 nodes`, `12884 edges`, `135 communities`
|
||||||
- unambiguous metadata-surface lane inference accepted locally: planner slice passed `36/36`; full MCP-discovery slice passed `281/281` with `9` skipped; build passed; graphify rebuilt to `5937 nodes`, `12899 edges`, `138 communities`
|
- unambiguous metadata-surface lane inference accepted locally: planner slice passed `36/36`; full MCP-discovery slice passed `281/281` with `9` skipped; build passed; graphify rebuilt to `5937 nodes`, `12899 edges`, `138 communities`
|
||||||
- live inventory exact-bridge rerun `inventory_stock_exact_bridge_live_20260501_after_runtime_bridge` is recorded as infrastructure-blocked, not accepted: route/intent/recipe/capability matched, but MCP calls aborted and direct `get_metadata` timed out while proxy health showed `active_sessions_count=0` with pending commands
|
- live inventory exact-bridge rerun `inventory_stock_exact_bridge_live_20260501_after_runtime_bridge` is recorded as infrastructure-blocked, not accepted: route/intent/recipe/capability matched, but MCP calls aborted and direct `get_metadata` timed out while proxy health showed `active_sessions_count=0` with pending commands
|
||||||
|
- catalog chain-template scoring accepted locally: catalog/planner slice passed `54/54`; full MCP-discovery slice passed `282/282` with `9` skipped; build passed; graphify rebuilt to `5938 nodes`, `12903 edges`, `139 communities`
|
||||||
|
|
||||||
Current architectural reading:
|
Current architectural reading:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.ASSISTANT_MCP_CATALOG_PLAN_REVIEW_SCHEMA_VERSION = exports.ASSISTANT_MCP_CATALOG_INDEX_SCHEMA_VERSION = void 0;
|
exports.ASSISTANT_MCP_CATALOG_PLAN_REVIEW_SCHEMA_VERSION = exports.ASSISTANT_MCP_CATALOG_INDEX_SCHEMA_VERSION = void 0;
|
||||||
exports.searchAssistantMcpCatalogPrimitivesByDecompositionCandidates = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates;
|
exports.searchAssistantMcpCatalogPrimitivesByDecompositionCandidates = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates;
|
||||||
exports.searchAssistantMcpCatalogPrimitivesByFactAxis = searchAssistantMcpCatalogPrimitivesByFactAxis;
|
exports.searchAssistantMcpCatalogPrimitivesByFactAxis = searchAssistantMcpCatalogPrimitivesByFactAxis;
|
||||||
|
exports.searchAssistantMcpCatalogChainTemplatesByFactAxis = searchAssistantMcpCatalogChainTemplatesByFactAxis;
|
||||||
exports.searchAssistantMcpCatalogPrimitivesByMetadataSurface = searchAssistantMcpCatalogPrimitivesByMetadataSurface;
|
exports.searchAssistantMcpCatalogPrimitivesByMetadataSurface = searchAssistantMcpCatalogPrimitivesByMetadataSurface;
|
||||||
exports.buildAssistantMcpCatalogIndex = buildAssistantMcpCatalogIndex;
|
exports.buildAssistantMcpCatalogIndex = buildAssistantMcpCatalogIndex;
|
||||||
exports.getAssistantMcpCatalogPrimitive = getAssistantMcpCatalogPrimitive;
|
exports.getAssistantMcpCatalogPrimitive = getAssistantMcpCatalogPrimitive;
|
||||||
|
|
@ -700,6 +701,53 @@ function searchAssistantMcpCatalogPrimitivesByFactAxis(input) {
|
||||||
.sort((left, right) => right.score - left.score)
|
.sort((left, right) => right.score - left.score)
|
||||||
.map((item) => item.primitive);
|
.map((item) => item.primitive);
|
||||||
}
|
}
|
||||||
|
function searchAssistantMcpCatalogChainTemplatesByFactAxis(input) {
|
||||||
|
const requiredAxisSet = toStringSet(input.required_axes ?? []);
|
||||||
|
const desiredTags = tagSetFromFactAxisInput({
|
||||||
|
business_fact_family: input.business_fact_family,
|
||||||
|
action_family: input.action_family,
|
||||||
|
required_axes: input.required_axes,
|
||||||
|
comparison_need: input.comparison_need,
|
||||||
|
ranking_need: input.ranking_need,
|
||||||
|
aggregation_need: input.aggregation_need
|
||||||
|
});
|
||||||
|
const scored = [];
|
||||||
|
for (const template of CHAIN_TEMPLATES) {
|
||||||
|
const factMatch = matchesPlanningToken(input.business_fact_family, template.supported_fact_families);
|
||||||
|
const actionMatch = matchesPlanningToken(input.action_family, template.supported_action_families);
|
||||||
|
const tagMatches = template.planning_tags.filter((tag) => desiredTags.has(normalizePlanningToken(tag)));
|
||||||
|
const axisOverlap = template.base_required_axes.filter((axis) => requiredAxisSet.has(axis)).length;
|
||||||
|
let score = 0;
|
||||||
|
if (factMatch) {
|
||||||
|
score += 8;
|
||||||
|
}
|
||||||
|
if (actionMatch) {
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
score += tagMatches.length * 2;
|
||||||
|
score += axisOverlap;
|
||||||
|
if (input.comparison_need && template.planning_tags.some((tag) => normalizePlanningToken(tag) === "comparison")) {
|
||||||
|
score += 6;
|
||||||
|
}
|
||||||
|
if (input.ranking_need && template.planning_tags.some((tag) => normalizePlanningToken(tag) === "ranking")) {
|
||||||
|
score += 6;
|
||||||
|
}
|
||||||
|
if (input.aggregation_need === "by_month" &&
|
||||||
|
template.planning_tags.some((tag) => normalizePlanningToken(tag) === "monthly_aggregation")) {
|
||||||
|
score += 4;
|
||||||
|
}
|
||||||
|
if (score <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scored.push({
|
||||||
|
chainId: template.chain_id,
|
||||||
|
score
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return scored
|
||||||
|
.sort((left, right) => right.score - left.score)
|
||||||
|
.map((item) => item.chainId);
|
||||||
|
}
|
||||||
function searchAssistantMcpCatalogPrimitivesByMetadataSurface(input) {
|
function searchAssistantMcpCatalogPrimitivesByMetadataSurface(input) {
|
||||||
const allowAggregateByAxis = input.allow_aggregate_by_axis !== false;
|
const allowAggregateByAxis = input.allow_aggregate_by_axis !== false;
|
||||||
const requiredAxisSet = toStringSet(input.required_axes ?? []);
|
const requiredAxisSet = toStringSet(input.required_axes ?? []);
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,20 @@ function selectPrimitivesFromGraphAndCatalog(input) {
|
||||||
if (factAxisPrimitives.length > 0) {
|
if (factAxisPrimitives.length > 0) {
|
||||||
reasonCodes.push("planner_selected_catalog_primitives_from_fact_axis_search");
|
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 = [];
|
const combinedCatalogPrimitives = [];
|
||||||
for (const primitive of decompositionPrimitives) {
|
for (const primitive of decompositionPrimitives) {
|
||||||
if (!combinedCatalogPrimitives.includes(primitive)) {
|
if (!combinedCatalogPrimitives.includes(primitive)) {
|
||||||
|
|
|
||||||
|
|
@ -622,6 +622,15 @@ export interface AssistantMcpCatalogFactAxisSearchInput {
|
||||||
allow_aggregate_by_axis?: boolean;
|
allow_aggregate_by_axis?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AssistantMcpCatalogChainTemplateSearchInput {
|
||||||
|
business_fact_family?: string | null;
|
||||||
|
action_family?: string | null;
|
||||||
|
required_axes?: string[];
|
||||||
|
comparison_need?: string | null;
|
||||||
|
ranking_need?: string | null;
|
||||||
|
aggregation_need?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AssistantMcpCatalogPrimitiveSearchInput {
|
export interface AssistantMcpCatalogPrimitiveSearchInput {
|
||||||
decomposition_candidates: string[];
|
decomposition_candidates: string[];
|
||||||
allow_aggregate_by_axis?: boolean;
|
allow_aggregate_by_axis?: boolean;
|
||||||
|
|
@ -847,6 +856,62 @@ export function searchAssistantMcpCatalogPrimitivesByFactAxis(
|
||||||
.map((item) => item.primitive);
|
.map((item) => item.primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function searchAssistantMcpCatalogChainTemplatesByFactAxis(
|
||||||
|
input: AssistantMcpCatalogChainTemplateSearchInput
|
||||||
|
): AssistantMcpCatalogChainTemplateId[] {
|
||||||
|
const requiredAxisSet = toStringSet(input.required_axes ?? []);
|
||||||
|
const desiredTags = tagSetFromFactAxisInput({
|
||||||
|
business_fact_family: input.business_fact_family,
|
||||||
|
action_family: input.action_family,
|
||||||
|
required_axes: input.required_axes,
|
||||||
|
comparison_need: input.comparison_need,
|
||||||
|
ranking_need: input.ranking_need,
|
||||||
|
aggregation_need: input.aggregation_need
|
||||||
|
});
|
||||||
|
const scored: Array<{ chainId: AssistantMcpCatalogChainTemplateId; score: number }> = [];
|
||||||
|
|
||||||
|
for (const template of CHAIN_TEMPLATES) {
|
||||||
|
const factMatch = matchesPlanningToken(input.business_fact_family, template.supported_fact_families);
|
||||||
|
const actionMatch = matchesPlanningToken(input.action_family, template.supported_action_families);
|
||||||
|
const tagMatches = template.planning_tags.filter((tag) => desiredTags.has(normalizePlanningToken(tag)));
|
||||||
|
const axisOverlap = template.base_required_axes.filter((axis) => requiredAxisSet.has(axis)).length;
|
||||||
|
|
||||||
|
let score = 0;
|
||||||
|
if (factMatch) {
|
||||||
|
score += 8;
|
||||||
|
}
|
||||||
|
if (actionMatch) {
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
score += tagMatches.length * 2;
|
||||||
|
score += axisOverlap;
|
||||||
|
if (input.comparison_need && template.planning_tags.some((tag) => normalizePlanningToken(tag) === "comparison")) {
|
||||||
|
score += 6;
|
||||||
|
}
|
||||||
|
if (input.ranking_need && template.planning_tags.some((tag) => normalizePlanningToken(tag) === "ranking")) {
|
||||||
|
score += 6;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
input.aggregation_need === "by_month" &&
|
||||||
|
template.planning_tags.some((tag) => normalizePlanningToken(tag) === "monthly_aggregation")
|
||||||
|
) {
|
||||||
|
score += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (score <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scored.push({
|
||||||
|
chainId: template.chain_id,
|
||||||
|
score
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return scored
|
||||||
|
.sort((left, right) => right.score - left.score)
|
||||||
|
.map((item) => item.chainId);
|
||||||
|
}
|
||||||
|
|
||||||
export function searchAssistantMcpCatalogPrimitivesByMetadataSurface(
|
export function searchAssistantMcpCatalogPrimitivesByMetadataSurface(
|
||||||
input: AssistantMcpCatalogMetadataSurfaceSearchInput
|
input: AssistantMcpCatalogMetadataSurfaceSearchInput
|
||||||
): AssistantMcpDiscoveryPrimitive[] {
|
): AssistantMcpDiscoveryPrimitive[] {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import {
|
||||||
} from "./assistantMcpDiscoveryPolicy";
|
} from "./assistantMcpDiscoveryPolicy";
|
||||||
import {
|
import {
|
||||||
getAssistantMcpCatalogChainTemplate,
|
getAssistantMcpCatalogChainTemplate,
|
||||||
|
searchAssistantMcpCatalogChainTemplatesByFactAxis,
|
||||||
searchAssistantMcpCatalogPrimitivesByDecompositionCandidates,
|
searchAssistantMcpCatalogPrimitivesByDecompositionCandidates,
|
||||||
searchAssistantMcpCatalogPrimitivesByFactAxis,
|
searchAssistantMcpCatalogPrimitivesByFactAxis,
|
||||||
searchAssistantMcpCatalogPrimitivesByMetadataSurface,
|
searchAssistantMcpCatalogPrimitivesByMetadataSurface,
|
||||||
|
|
@ -457,6 +458,21 @@ function selectPrimitivesFromGraphAndCatalog(input: {
|
||||||
reasonCodes.push("planner_selected_catalog_primitives_from_fact_axis_search");
|
reasonCodes.push("planner_selected_catalog_primitives_from_fact_axis_search");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const chainTemplateMatches = input.dataNeedGraph
|
||||||
|
? 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: AssistantMcpDiscoveryPrimitive[] = [];
|
const combinedCatalogPrimitives: AssistantMcpDiscoveryPrimitive[] = [];
|
||||||
for (const primitive of decompositionPrimitives) {
|
for (const primitive of decompositionPrimitives) {
|
||||||
if (!combinedCatalogPrimitives.includes(primitive)) {
|
if (!combinedCatalogPrimitives.includes(primitive)) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import {
|
||||||
getAssistantMcpCatalogChainTemplate,
|
getAssistantMcpCatalogChainTemplate,
|
||||||
getAssistantMcpCatalogPrimitive,
|
getAssistantMcpCatalogPrimitive,
|
||||||
reviewAssistantMcpDiscoveryPlanAgainstCatalog,
|
reviewAssistantMcpDiscoveryPlanAgainstCatalog,
|
||||||
|
searchAssistantMcpCatalogChainTemplatesByFactAxis,
|
||||||
searchAssistantMcpCatalogPrimitivesByDecompositionCandidates,
|
searchAssistantMcpCatalogPrimitivesByDecompositionCandidates,
|
||||||
searchAssistantMcpCatalogPrimitivesByFactAxis,
|
searchAssistantMcpCatalogPrimitivesByFactAxis,
|
||||||
searchAssistantMcpCatalogPrimitivesByMetadataSurface
|
searchAssistantMcpCatalogPrimitivesByMetadataSurface
|
||||||
|
|
@ -151,6 +152,30 @@ describe("assistant MCP catalog index", () => {
|
||||||
expect(primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
|
expect(primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("can score reviewed chain templates directly from fact family and required axes", () => {
|
||||||
|
const documentTemplates = searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||||
|
business_fact_family: "document_evidence",
|
||||||
|
action_family: "list_documents",
|
||||||
|
required_axes: ["counterparty", "period", "coverage_target"]
|
||||||
|
});
|
||||||
|
const comparisonTemplates = searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||||
|
business_fact_family: "value_flow",
|
||||||
|
action_family: "net_value_flow",
|
||||||
|
comparison_need: "incoming_vs_outgoing",
|
||||||
|
required_axes: ["organization", "period", "amount", "coverage_target"]
|
||||||
|
});
|
||||||
|
const rankingTemplates = searchAssistantMcpCatalogChainTemplatesByFactAxis({
|
||||||
|
business_fact_family: "value_flow",
|
||||||
|
action_family: "turnover",
|
||||||
|
ranking_need: "top_desc",
|
||||||
|
required_axes: ["organization", "period", "aggregate_axis", "amount", "coverage_target"]
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(documentTemplates[0]).toBe("document_evidence");
|
||||||
|
expect(comparisonTemplates[0]).toBe("value_flow_comparison");
|
||||||
|
expect(rankingTemplates[0]).toBe("value_flow_ranking");
|
||||||
|
});
|
||||||
|
|
||||||
it("can search reviewed primitives for inventory stock snapshot chains", () => {
|
it("can search reviewed primitives for inventory stock snapshot chains", () => {
|
||||||
const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({
|
const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({
|
||||||
business_fact_family: "inventory_stock_snapshot",
|
business_fact_family: "inventory_stock_snapshot",
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ describe("assistant MCP discovery planner", () => {
|
||||||
expect(result.reason_codes).toContain("planner_enabled_chunked_coverage_probe_budget");
|
expect(result.reason_codes).toContain("planner_enabled_chunked_coverage_probe_budget");
|
||||||
expect(result.reason_codes).toContain("planner_consumed_data_need_graph_v1");
|
expect(result.reason_codes).toContain("planner_consumed_data_need_graph_v1");
|
||||||
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_decomposition_candidates");
|
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_decomposition_candidates");
|
||||||
|
expect(result.reason_codes).toContain("planner_scored_catalog_chain_templates_from_fact_axis");
|
||||||
|
expect(result.reason_codes).toContain("planner_catalog_chain_template_search_top_value_flow");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps a value-flow plan in clarification state when period axis is missing", () => {
|
it("keeps a value-flow plan in clarification state when period axis is missing", () => {
|
||||||
|
|
@ -145,6 +147,7 @@ describe("assistant MCP discovery planner", () => {
|
||||||
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
|
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
|
||||||
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_fact_axis_search");
|
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_fact_axis_search");
|
||||||
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_document_evidence");
|
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_document_evidence");
|
||||||
|
expect(result.reason_codes).toContain("planner_catalog_chain_template_search_top_document_evidence");
|
||||||
expect(result.reason_codes).not.toContain("planner_fell_back_to_recipe_primitives_after_empty_catalog_search");
|
expect(result.reason_codes).not.toContain("planner_fell_back_to_recipe_primitives_after_empty_catalog_search");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue