АДРЕСНЫЙ РЕЖИМ - M2.3e: стабилизация address runtime парсинг периодов, LLM pre-decompose fallback и приоритет intent для банковских операций

This commit is contained in:
2026-04-01 19:35:25 +03:00
parent 4d59672576
commit 18e0f1364d
16 changed files with 1467 additions and 562 deletions
@@ -50,6 +50,11 @@ describe("address intent resolver expansion (M2.3a)", () => {
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves documents forming balance for russian participle phrasing", () => {
const result = resolveAddressIntent("Показать документы, формирующие остаток по счету 60.01 на дату 2020-07-31");
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves documents by company phrase as counterparty intent", () => {
const result = resolveAddressIntent("Какие документы доступны по компании СВК за 2021 год?");
expect(result.intent).toBe("list_documents_by_counterparty");
@@ -60,6 +65,11 @@ describe("address intent resolver expansion (M2.3a)", () => {
expect(result.intent).toBe("bank_operations_by_counterparty");
});
it("keeps bank_operations_by_counterparty even when account hints are present", () => {
const result = resolveAddressIntent("Показать банковские операции (счета 51, 62) для контрагента СВК за 2020 год");
expect(result.intent).toBe("bank_operations_by_counterparty");
});
it("resolves documents by client phrase", () => {
const result = resolveAddressIntent("Выведи документы по клиенту Бета за 2020-07");
expect(result.intent).toBe("list_documents_by_counterparty");
@@ -137,6 +147,36 @@ describe("address filter extraction for balance drilldown", () => {
expect(result.warnings).toContain("period_derived_from_month_phrase");
});
it("derives month period for balance snapshot from 'на май 2020'", () => {
const result = extractAddressFilters("Какой остаток по счету 60 на май 2020", "account_balance_snapshot");
expect(result.extracted_filters.account).toBe("60");
expect(result.extracted_filters.period_from).toBe("2020-05-01");
expect(result.extracted_filters.period_to).toBe("2020-05-31");
expect(result.extracted_filters.as_of_date).toBe("2020-05-31");
expect(result.warnings).toContain("period_derived_from_month_phrase");
expect(result.warnings).toContain("as_of_date_derived_from_period_to");
});
it("derives month period for balance snapshot from 'на 2020.05'", () => {
const result = extractAddressFilters("Какой остаток по счету 60 на 2020.05", "account_balance_snapshot");
expect(result.extracted_filters.account).toBe("60");
expect(result.extracted_filters.period_from).toBe("2020-05-01");
expect(result.extracted_filters.period_to).toBe("2020-05-31");
expect(result.extracted_filters.as_of_date).toBe("2020-05-31");
expect(result.warnings).toContain("period_derived_from_month_phrase");
expect(result.warnings).toContain("as_of_date_derived_from_period_to");
});
it("derives month period for balance snapshot from 'на 2020 май'", () => {
const result = extractAddressFilters("Какой остаток по счету 60 на 2020 май", "account_balance_snapshot");
expect(result.extracted_filters.account).toBe("60");
expect(result.extracted_filters.period_from).toBe("2020-05-01");
expect(result.extracted_filters.period_to).toBe("2020-05-31");
expect(result.extracted_filters.as_of_date).toBe("2020-05-31");
expect(result.warnings).toContain("period_derived_from_month_phrase");
expect(result.warnings).toContain("as_of_date_derived_from_period_to");
});
it("treats 'за весь период' as all-time hint and does not force 90-day default", () => {
const result = extractAddressFilters(
"Покажи банковские операции по клиенту Бета за весь период",
@@ -379,4 +419,30 @@ describe("address recipe catalog counterparty filtering", () => {
expect(plan.limit).toBe(200);
});
it("injects account condition into movements query for account snapshot", () => {
const filters = extractAddressFilters(
"Какой остаток по счету 60 на дату 2020-07-31",
"account_balance_snapshot"
).extracted_filters;
const selected = selectAddressRecipe("account_balance_snapshot", filters);
expect(selected.selected_recipe).toBeTruthy();
const plan = buildAddressRecipePlan(selected.selected_recipe!, filters);
expect(plan.query).toContain("Движения.СчетДт.Код");
expect(plan.query).toContain("ПОДОБНО \"60%\"");
});
it("injects subaccount condition variants into movements query for documents_forming_balance", () => {
const filters = extractAddressFilters(
"Какие документы формируют остаток по счету 60.01 на дату 2020-07-31",
"documents_forming_balance"
).extracted_filters;
const selected = selectAddressRecipe("documents_forming_balance", filters);
expect(selected.selected_recipe).toBeTruthy();
const plan = buildAddressRecipePlan(selected.selected_recipe!, filters);
expect(plan.query).toContain("ПОДОБНО \"60.01%\"");
expect(plan.query).toContain("ПОДОБНО \"60.1%\"");
});
});