Open-World: добавить профиль документов в бизнес-обзор

This commit is contained in:
2026-05-05 13:09:42 +03:00
parent e803942472
commit 466b3b66e5
9 changed files with 479 additions and 26 deletions
@@ -233,6 +233,14 @@ describe("assistant MCP discovery answer adapter", () => {
{ Период: "2020-01-15T00:00:00", Регистратор: "Поступление 1" },
{ Период: "2020-12-15T00:00:00", Регистратор: "Поступление 2" }
]
},
{
rows: [
{ Period: "2020-01-01T00:00:00", Registrator: "DOC_TYPE_DOCS", AccountDt: "Списание с расчетного счета", Amount: 12 },
{ Period: "2020-01-01T00:00:00", Registrator: "DOC_TYPE_DOCS", AccountDt: "Поступление на расчетный счет", Amount: 8 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_DT_OPS", AccountDt: "60", Amount: 9 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_KT_OPS", AccountDt: "62", Amount: 6 }
]
}
])
);
@@ -245,6 +253,9 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.confirmed_lines.join("\n")).toContain("Самый крупный подтвержденный клиент");
expect(draft.confirmed_lines.join("\n")).toContain("Самый крупный подтвержденный поставщик");
expect(draft.confirmed_lines.join("\n")).toContain("Годовая раскладка операционного денежного потока");
expect(draft.confirmed_lines.join("\n")).toContain("Профиль операционной активности");
expect(draft.confirmed_lines.join("\n")).toContain("ведущий тип документов Списание с расчетного счета");
expect(draft.confirmed_lines.join("\n")).toContain("ведущий раздел учета 60");
expect(draft.inference_lines.join("\n")).toContain("Аналитический вывод по оборотам");
expect(draft.inference_lines.join("\n")).toContain("Концентрация входящего потока");
expect(draft.inference_lines.join("\n")).toContain("Концентрация исходящего потока");
@@ -258,9 +269,11 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.must_not_claim).toContain("Do not present business overview cash-flow spread as profit or margin.");
expect(draft.must_not_claim).toContain("Do not present business overview yearly operating-flow breakdown as profit, financial result, or a complete annual P&L.");
expect(draft.must_not_claim).toContain("Do not present business overview supplier concentration as vendor-risk audit, procurement quality, or full expense structure.");
expect(draft.must_not_claim).toContain("Do not present business overview document/account-section activity profile as process quality, accounting correctness, or completeness of all 1C activity.");
expect(draft.reason_codes).toContain("answer_contains_business_overview");
expect(draft.reason_codes).toContain("answer_contains_business_overview_supplier_concentration");
expect(draft.reason_codes).toContain("answer_contains_business_overview_yearly_operating_breakdown");
expect(draft.reason_codes).toContain("answer_contains_business_overview_document_activity_profile");
expect(draft.reason_codes).toContain("answer_contains_business_overview_analyst_synthesis");
});
@@ -156,8 +156,10 @@ describe("assistant MCP discovery pilot executor", () => {
},
{
rows: [
{ Period: "2020-03-01T00:00:00", Amount: 200000, Item: "Товар А", Counterparty: "Клиент А", СчетКт: "41.01" },
{ Period: "2020-02-01T00:00:00", Amount: 120000, Item: "Товар А", Counterparty: "Поставщик А", СчетДт: "41.01" }
{ Period: "2020-01-01T00:00:00", Registrator: "DOC_TYPE_DOCS", AccountDt: "Списание с расчетного счета", Amount: 12 },
{ Period: "2020-01-01T00:00:00", Registrator: "DOC_TYPE_DOCS", AccountDt: "Поступление на расчетный счет", Amount: 8 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_DT_OPS", AccountDt: "60", Amount: 9 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_KT_OPS", AccountDt: "62", Amount: 6 }
]
}
]);
@@ -210,9 +212,25 @@ describe("assistant MCP discovery pilot executor", () => {
}
]);
expect(result.derived_business_overview?.activity_period?.duration_total_months).toBe(11);
expect(result.derived_business_overview?.document_activity_profile).toMatchObject({
rows_matched: 4,
total_document_type_count: 20,
total_account_section_operations: 15
});
expect(result.derived_business_overview?.document_activity_profile?.top_document_types[0]).toMatchObject({
document_type: "Списание с расчетного счета",
count: 12,
share_pct: 60
});
expect(result.derived_business_overview?.document_activity_profile?.top_account_sections[0]).toMatchObject({
account_section: "60",
operation_count: 9,
share_pct: 60
});
expect(result.evidence.confirmed_facts.join("\n")).toContain("В 1С подтверждены входящие поступления");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Самый крупный подтвержденный поставщик");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Годовая раскладка операционного денежного потока");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Профиль операционной активности");
expect(result.evidence.inferred_facts.join("\n")).toContain("procurement concentration proxy");
expect(result.evidence.inferred_facts.join("\n")).toContain("Самый сильный год по подтвержденным входящим поступлениям: 2021");
expect(result.evidence.unknown_facts).toContain(
@@ -221,7 +239,8 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_top_suppliers_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_yearly_operating_breakdown_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(3);
expect(result.reason_codes).toContain("pilot_derived_business_overview_document_activity_profile_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(4);
});
it("adds a checked VAT/tax family to business overview only when an explicit period is available", async () => {
@@ -324,7 +343,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_tax_position_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_business_overview_trading_margin_query_mcp_executed");
expect(result.reason_codes).toContain("pilot_derived_business_overview_trading_margin_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(10);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
const taxCall = deps.executeAddressMcpQuery.mock.calls[2]?.[0];
const tradingMarginCall = deps.executeAddressMcpQuery.mock.calls[9]?.[0];
expect(String(taxCall?.query ?? "")).toContain("НДСЗаписиКнигиПродаж");
@@ -524,7 +543,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_open_settlement_quality_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_debt_age_signal_from_contract_dates");
expect(result.reason_codes).toContain("pilot_derived_business_overview_debt_staleness_risk_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(10);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
const receivablesCall = deps.executeAddressMcpQuery.mock.calls[3]?.[0];
const payablesCall = deps.executeAddressMcpQuery.mock.calls[4]?.[0];
const openContractsCall = deps.executeAddressMcpQuery.mock.calls[5]?.[0];
@@ -651,7 +670,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_position_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_turnover_proxy_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_staleness_risk_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(10);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
const inventoryCall = deps.executeAddressMcpQuery.mock.calls[6]?.[0];
expect(inventoryCall?.account_scope).toContain("41.01");
});