Planner Autonomy: закрепить alignment guard для catalog chains
This commit is contained in:
@@ -63,6 +63,147 @@ describe("assistant MCP discovery planner", () => {
|
||||
expect(result.reason_codes).toContain("planner_catalog_chain_template_search_top_value_flow");
|
||||
});
|
||||
|
||||
it("keeps representative graph-selected chains aligned with top catalog template matches", () => {
|
||||
const graph = (
|
||||
businessFactFamily: string,
|
||||
actionFamily: string,
|
||||
extra: {
|
||||
subject_candidates?: string[];
|
||||
comparison_need?: string | null;
|
||||
ranking_need?: string | null;
|
||||
} = {}
|
||||
) => ({
|
||||
schema_version: "assistant_data_need_graph_v1" as const,
|
||||
policy_owner: "assistantMcpDiscoveryDataNeedGraph" as const,
|
||||
subject_candidates: extra.subject_candidates ?? ["SVK"],
|
||||
business_fact_family: businessFactFamily,
|
||||
action_family: actionFamily,
|
||||
aggregation_need: null,
|
||||
time_scope_need: "explicit_period",
|
||||
comparison_need: extra.comparison_need ?? null,
|
||||
ranking_need: extra.ranking_need ?? null,
|
||||
proof_expectation: "coverage_checked_fact",
|
||||
clarification_gaps: [],
|
||||
decomposition_candidates: [],
|
||||
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
|
||||
reason_codes: ["data_need_graph_built"]
|
||||
});
|
||||
const cases = [
|
||||
{
|
||||
name: "value_flow",
|
||||
expected: "value_flow",
|
||||
input: {
|
||||
dataNeedGraph: graph("value_flow", "turnover"),
|
||||
turnMeaning: {
|
||||
asked_action_family: "turnover",
|
||||
explicit_entity_candidates: ["SVK"],
|
||||
explicit_date_scope: "2020"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "value_flow_comparison",
|
||||
expected: "value_flow_comparison",
|
||||
input: {
|
||||
dataNeedGraph: graph("value_flow", "net_value_flow", { comparison_need: "incoming_vs_outgoing" }),
|
||||
turnMeaning: {
|
||||
asked_action_family: "net_value_flow",
|
||||
explicit_entity_candidates: ["SVK"],
|
||||
explicit_date_scope: "2020"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "value_flow_ranking",
|
||||
expected: "value_flow_ranking",
|
||||
input: {
|
||||
dataNeedGraph: graph("value_flow", "turnover", { subject_candidates: [], ranking_need: "top_desc" }),
|
||||
turnMeaning: {
|
||||
asked_action_family: "turnover",
|
||||
explicit_date_scope: "2020",
|
||||
explicit_organization_scope: "Org"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "document_evidence",
|
||||
expected: "document_evidence",
|
||||
input: {
|
||||
dataNeedGraph: graph("document_evidence", "list_documents"),
|
||||
turnMeaning: {
|
||||
asked_action_family: "list_documents",
|
||||
explicit_entity_candidates: ["SVK"],
|
||||
explicit_date_scope: "2020"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "movement_evidence",
|
||||
expected: "movement_evidence",
|
||||
input: {
|
||||
dataNeedGraph: graph("movement_evidence", "list_movements"),
|
||||
turnMeaning: {
|
||||
asked_action_family: "list_movements",
|
||||
explicit_entity_candidates: ["SVK"],
|
||||
explicit_date_scope: "2020"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "schema_surface",
|
||||
expected: "metadata_inspection",
|
||||
input: {
|
||||
dataNeedGraph: graph("schema_surface", "inspect_catalog", { subject_candidates: [] }),
|
||||
turnMeaning: {
|
||||
asked_action_family: "inspect_catalog"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "entity_resolution",
|
||||
expected: "entity_resolution",
|
||||
input: {
|
||||
dataNeedGraph: graph("entity_grounding", "search_business_entity"),
|
||||
turnMeaning: {
|
||||
asked_action_family: "search_business_entity",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "lifecycle",
|
||||
expected: "lifecycle",
|
||||
input: {
|
||||
dataNeedGraph: graph("activity_lifecycle", "activity_duration"),
|
||||
turnMeaning: {
|
||||
asked_action_family: "activity_duration",
|
||||
explicit_entity_candidates: ["SVK"]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "inventory_stock_snapshot",
|
||||
expected: "inventory_stock_snapshot",
|
||||
input: {
|
||||
dataNeedGraph: graph("inventory_stock_snapshot", "stock_snapshot", { subject_candidates: [] }),
|
||||
turnMeaning: {
|
||||
asked_action_family: "stock_snapshot",
|
||||
explicit_date_scope: "2020",
|
||||
explicit_organization_scope: "Org"
|
||||
}
|
||||
}
|
||||
}
|
||||
] as const;
|
||||
|
||||
for (const item of cases) {
|
||||
const result = planAssistantMcpDiscovery(item.input);
|
||||
expect(result.selected_chain_id, item.name).toBe(item.expected);
|
||||
expect(result.catalog_chain_template_alignment.top_chain_template_match, item.name).toBe(item.expected);
|
||||
expect(result.catalog_chain_template_alignment.selected_chain_template_rank, item.name).toBe(1);
|
||||
expect(result.catalog_chain_template_alignment.selected_chain_matches_top, item.name).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps a value-flow plan in clarification state when period axis is missing", () => {
|
||||
const result = planAssistantMcpDiscovery({
|
||||
turnMeaning: {
|
||||
|
||||
Reference in New Issue
Block a user