Planner Autonomy: выбрать comparison chain для явного bidirectional graph

This commit is contained in:
2026-05-01 14:20:24 +03:00
parent 1c1383b8b5
commit ea96df9ca1
5 changed files with 27 additions and 17 deletions
@@ -496,16 +496,19 @@ function recipeFor(input) {
});
}
if (graphFactFamily === "value_flow") {
if (dataNeedGraph?.comparison_need === "incoming_vs_outgoing" && !hasSubjectCandidates(dataNeedGraph)) {
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: template.fallback_primitives,
fallbackPrimitives,
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action,
@@ -703,16 +703,19 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe {
}
if (graphFactFamily === "value_flow") {
if (dataNeedGraph?.comparison_need === "incoming_vs_outgoing" && !hasSubjectCandidates(dataNeedGraph)) {
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 = getAssistantMcpCatalogChainTemplate("value_flow_comparison");
const fallbackPrimitives = hasSubjectCandidates(dataNeedGraph)
? (["resolve_entity_reference", ...template.fallback_primitives] as AssistantMcpDiscoveryPrimitive[])
: template.fallback_primitives;
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
fallbackPrimitives: template.fallback_primitives,
fallbackPrimitives,
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action,
@@ -520,7 +520,7 @@ describe("assistant MCP discovery planner", () => {
expect(result.reason_codes).not.toContain("planner_selected_movement_from_confirmed_metadata_surface_ref");
});
it("can select value-flow chain from data need graph even when turn meaning family is still under-specified", () => {
it("can select bidirectional value-flow comparison from data need graph even when turn meaning family is still under-specified", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
@@ -552,23 +552,18 @@ describe("assistant MCP discovery planner", () => {
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_movements",
"aggregate_by_axis",
"probe_coverage"
]);
expect(result.selected_chain_id).toBe("value_flow_comparison");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual([
"counterparty",
"period",
"aggregate_axis",
"amount",
"coverage_target",
"calendar_month"
]);
expect(result.reason_codes).toContain("planner_selected_monthly_value_flow_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow");
expect(result.reason_codes).toContain("planner_selected_bidirectional_value_flow_comparison_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow_comparison");
expect(result.catalog_chain_template_matches[0]).toBe("value_flow_comparison");
});
it("does not collapse a ranking-shaped value graph into entity-resolution just because no subject is preselected", () => {