ARCH: добить all-time и period-first clarification loops
This commit is contained in:
@@ -71,6 +71,17 @@ describe("assistant MCP catalog index", () => {
|
||||
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",
|
||||
@@ -150,6 +161,25 @@ describe("assistant MCP catalog index", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
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("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");
|
||||
|
||||
@@ -182,6 +182,29 @@ describe("assistant MCP discovery data need graph", () => {
|
||||
expect(result.reason_codes).toContain("data_need_graph_open_scope_total_needs_organization");
|
||||
});
|
||||
|
||||
it("treats colloquial open incoming total wording with filler words as an open-scope ask rather than a missing subject", () => {
|
||||
const result = buildAssistantMcpDiscoveryDataNeedGraph({
|
||||
semanticDataNeed: "counterparty value-flow evidence",
|
||||
rawUtterance: "сколько вообще входящих денег было?",
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "turnover"
|
||||
}
|
||||
});
|
||||
|
||||
expect(result.business_fact_family).toBe("value_flow");
|
||||
expect(result.subject_candidates).toEqual([]);
|
||||
expect(result.clarification_gaps).toEqual(["organization", "period"]);
|
||||
expect(result.proof_expectation).toBe("clarification_required");
|
||||
expect(result.decomposition_candidates).toEqual([
|
||||
"collect_scoped_movements",
|
||||
"aggregate_checked_amounts",
|
||||
"probe_coverage"
|
||||
]);
|
||||
expect(result.reason_codes).toContain("data_need_graph_open_scope_total_without_subject");
|
||||
expect(result.reason_codes).toContain("data_need_graph_open_scope_total_needs_organization");
|
||||
});
|
||||
|
||||
it("treats all-time open-scope totals as an open-ended period rather than a missing period", () => {
|
||||
const result = buildAssistantMcpDiscoveryDataNeedGraph({
|
||||
semanticDataNeed: "counterparty value-flow evidence",
|
||||
|
||||
@@ -779,4 +779,48 @@ describe("assistant MCP discovery planner", () => {
|
||||
expect(result.reason_codes).toContain("planner_selected_open_scope_value_flow_total_from_data_need_graph");
|
||||
expect(result.selected_chain_id).not.toBe("entity_resolution");
|
||||
});
|
||||
|
||||
it("treats all-time organization-scoped open totals as execution-ready without reintroducing a fake period gap", () => {
|
||||
const result = planAssistantMcpDiscovery({
|
||||
dataNeedGraph: {
|
||||
schema_version: "assistant_data_need_graph_v1",
|
||||
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
|
||||
subject_candidates: [],
|
||||
business_fact_family: "value_flow",
|
||||
action_family: "turnover",
|
||||
aggregation_need: null,
|
||||
time_scope_need: "all_time_scope",
|
||||
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",
|
||||
"data_need_graph_all_time_scope_hint"
|
||||
]
|
||||
},
|
||||
turnMeaning: {
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "turnover",
|
||||
explicit_organization_scope: "ООО Альтернатива Плюс"
|
||||
}
|
||||
});
|
||||
|
||||
expect(result.planner_status).toBe("ready_for_execution");
|
||||
expect(result.semantic_data_need).toBe("organization-scoped value-flow evidence");
|
||||
expect(result.selected_chain_id).toBe("value_flow");
|
||||
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
|
||||
expect(result.required_axes).toEqual([
|
||||
"organization",
|
||||
"all_time_scope",
|
||||
"aggregate_axis",
|
||||
"amount",
|
||||
"coverage_target"
|
||||
]);
|
||||
expect(result.catalog_review.review_status).toBe("catalog_compatible");
|
||||
expect(result.reason_codes).toContain("planner_selected_open_scope_value_flow_total_from_data_need_graph");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1500,6 +1500,27 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_open_scope_total_needs_organization");
|
||||
});
|
||||
|
||||
it("treats colloquial open incoming total wording with filler words as an open-scope ask that needs organization and period", () => {
|
||||
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||
userMessage: "сколько вообще входящих денег было?"
|
||||
});
|
||||
|
||||
expect(result.adapter_status).toBe("ready");
|
||||
expect(result.should_run_discovery).toBe(true);
|
||||
expect(result.semantic_data_need).toBe("counterparty value-flow evidence");
|
||||
expect(result.turn_meaning_ref).toMatchObject({
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "turnover",
|
||||
unsupported_but_understood_family: "counterparty_value_or_turnover",
|
||||
stale_replay_forbidden: true
|
||||
});
|
||||
expect(result.turn_meaning_ref?.explicit_entity_candidates).toBeUndefined();
|
||||
expect(result.data_need_graph?.subject_candidates).toEqual([]);
|
||||
expect(result.data_need_graph?.clarification_gaps).toEqual(["organization", "period"]);
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_open_scope_total_without_subject");
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_open_scope_total_needs_organization");
|
||||
});
|
||||
|
||||
it("resumes an open-scope incoming total from follow-up context when the user clarifies only the organization", () => {
|
||||
const orgName = "ООО Альтернатива Плюс";
|
||||
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||
@@ -1564,6 +1585,46 @@ describe("assistant MCP discovery turn input adapter", () => {
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_all_time_scope_hint");
|
||||
});
|
||||
|
||||
it("resumes an open-scope total clarification loop from saved state when the user resolves the pending period with all-time wording", () => {
|
||||
const orgName = "ООО Альтернатива Плюс";
|
||||
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||
userMessage: "за все время",
|
||||
assistantTurnMeaning: {
|
||||
explicit_intent_candidate: "customer_revenue_and_payments"
|
||||
},
|
||||
followupContext: {
|
||||
previous_discovery_loop_status: "awaiting_clarification",
|
||||
previous_discovery_loop_selected_chain_id: "value_flow",
|
||||
previous_discovery_loop_pending_axes: ["period"],
|
||||
previous_discovery_loop_provided_axes: ["organization", "aggregate_axis", "amount", "coverage_target"],
|
||||
previous_discovery_loop_asked_domain_family: "counterparty_value",
|
||||
previous_discovery_loop_asked_action_family: "turnover",
|
||||
previous_discovery_loop_unsupported_family: "counterparty_value_or_turnover",
|
||||
previous_filters: {
|
||||
organization: orgName
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(result.adapter_status).toBe("ready");
|
||||
expect(result.should_run_discovery).toBe(true);
|
||||
expect(result.reason_codes).toContain("mcp_discovery_all_time_scope_signal_detected");
|
||||
expect(result.reason_codes).toContain("mcp_discovery_period_clarification_followup_from_followup_context");
|
||||
expect(result.reason_codes).not.toContain("mcp_discovery_not_applicable_for_supported_exact_turn");
|
||||
expect(result.turn_meaning_ref).toMatchObject({
|
||||
asked_domain_family: "counterparty_value",
|
||||
asked_action_family: "turnover",
|
||||
explicit_organization_scope: orgName,
|
||||
unsupported_but_understood_family: "counterparty_value_or_turnover",
|
||||
stale_replay_forbidden: true
|
||||
});
|
||||
expect(result.turn_meaning_ref?.explicit_date_scope).toBeUndefined();
|
||||
expect(result.data_need_graph?.clarification_gaps).toEqual([]);
|
||||
expect(result.data_need_graph?.time_scope_need).toBe("all_time_scope");
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_open_scope_total_without_subject");
|
||||
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_all_time_scope_hint");
|
||||
});
|
||||
|
||||
it("resumes an open-scope ranking from follow-up context when the user clarifies only the organization", () => {
|
||||
const orgName = "ООО Альтернатива Плюс";
|
||||
const result = buildAssistantMcpDiscoveryTurnInput({
|
||||
|
||||
Reference in New Issue
Block a user