diff --git a/docs/orchestration/agent_autonomy_business_quality_20260523.json b/docs/orchestration/agent_autonomy_business_quality_20260523.json index 901bdb2..c2d8185 100644 --- a/docs/orchestration/agent_autonomy_business_quality_20260523.json +++ b/docs/orchestration/agent_autonomy_business_quality_20260523.json @@ -41,9 +41,8 @@ "expected_catalog_alignment_status": "selected_matches_top", "expected_catalog_chain_top_match": "value_flow", "expected_catalog_selected_matches_top": true, - "required_answer_patterns_all": ["2020", "исходящ|списан|заплат", "руб"], - "required_answer_patterns_any": ["43[\\s.]*763[\\s.]*351", "не полностью покрыт|лимит|нужно дозапрос"], - "forbidden_answer_patterns": ["Учтено строк", "Первая найденная дата", "последняя:", "runtime_", "planner_", "query_movements", "primitive", "уточните контрагента", "по какому контрагенту"], + "required_answer_patterns_all": ["2020", "43[\\s.]*763[\\s.]*351", "исходящ|списан|заплат", "руб"], + "forbidden_answer_patterns": ["33[\\s.]*664[\\s.]*802", "Учтено строк", "Первая найденная дата", "последняя:", "runtime_", "planner_", "query_movements", "primitive", "уточните контрагента", "по какому контрагенту"], "criticality": "critical", "semantic_tags": ["autonomy_core", "value_flow", "outgoing_total", "business_answer_quality", "limit_honesty"] }, diff --git a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js index 38a35b2..6ac7f3e 100644 --- a/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js +++ b/llm_normalizer/backend/dist/services/assistantMcpDiscoveryPlanner.js @@ -400,7 +400,10 @@ function budgetOverrideFor(input, recipe) { const meaning = input.turnMeaning ?? null; const requestedAggregationAxis = aggregationAxis(meaning); const isValueFlowRecipe = recipe.primitives.includes("query_movements") && - (recipe.semanticDataNeed === "counterparty value-flow evidence" || + (recipe.chainId === "value_flow" || + recipe.chainId === "value_flow_comparison" || + recipe.chainId === "value_flow_ranking" || + recipe.semanticDataNeed === "counterparty value-flow evidence" || recipe.semanticDataNeed === "bidirectional value-flow comparison evidence" || recipe.semanticDataNeed === "ranked value-flow evidence"); const isBusinessOverviewRecipe = recipe.primitives.includes("query_movements") && diff --git a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts index 9903752..56556ba 100644 --- a/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts +++ b/llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts @@ -632,7 +632,10 @@ function budgetOverrideFor(input: AssistantMcpDiscoveryPlannerInput, recipe: Pla const requestedAggregationAxis = aggregationAxis(meaning); const isValueFlowRecipe = recipe.primitives.includes("query_movements") && - (recipe.semanticDataNeed === "counterparty value-flow evidence" || + (recipe.chainId === "value_flow" || + recipe.chainId === "value_flow_comparison" || + recipe.chainId === "value_flow_ranking" || + recipe.semanticDataNeed === "counterparty value-flow evidence" || recipe.semanticDataNeed === "bidirectional value-flow comparison evidence" || recipe.semanticDataNeed === "ranked value-flow evidence"); const isBusinessOverviewRecipe = diff --git a/llm_normalizer/backend/tests/assistantMcpDiscoveryPlanner.test.ts b/llm_normalizer/backend/tests/assistantMcpDiscoveryPlanner.test.ts index f6acb6e..36fbca6 100644 --- a/llm_normalizer/backend/tests/assistantMcpDiscoveryPlanner.test.ts +++ b/llm_normalizer/backend/tests/assistantMcpDiscoveryPlanner.test.ts @@ -95,6 +95,38 @@ describe("assistant MCP discovery planner", () => { expect(result.reason_codes).toContain("planner_selected_chain_matches_catalog_top"); }); + it("gives organization-scoped yearly value-flow enough budget for monthly recovery", () => { + const result = planAssistantMcpDiscovery({ + dataNeedGraph: { + schema_version: "assistant_data_need_graph_v1", + policy_owner: "assistantMcpDiscoveryDataNeedGraph", + subject_candidates: [], + business_fact_family: "value_flow", + action_family: "payout", + aggregation_need: null, + time_scope_need: "explicit_period", + comparison_need: null, + ranking_need: null, + proof_expectation: "coverage_checked_fact", + clarification_gaps: [], + decomposition_candidates: ["collect_scoped_movements", "aggregate_checked_amounts", "probe_coverage"], + forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"], + reason_codes: ["data_need_graph_built", "data_need_graph_open_scope_total_without_subject"] + }, + turnMeaning: { + asked_domain_family: "counterparty_value", + asked_action_family: "payout", + explicit_organization_scope: "ООО Альтернатива Плюс", + explicit_date_scope: "2020" + } + }); + + expect(result.selected_chain_id).toBe("value_flow"); + expect(result.semantic_data_need).toBe("organization-scoped value-flow evidence"); + expect(result.discovery_plan.execution_budget.max_probe_count).toBe(30); + expect(result.reason_codes).toContain("planner_enabled_chunked_coverage_probe_budget"); + }); + it("treats an explicit date as a provided as-of-date evidence axis", () => { const result = planAssistantMcpDiscovery({ dataNeedGraph: {