Усилить бизнес-ответы 1С ассистента после прогона 105

This commit is contained in:
2026-05-21 10:22:51 +03:00
parent bbc257fd6c
commit 151f2a26de
12 changed files with 378 additions and 288 deletions
@@ -2092,9 +2092,11 @@ describe("address compose stage utf8 headers", () => {
);
expect(reply.responseType).toBe("FACTUAL_SUMMARY");
expect(reply.text).toContain("Покрытие VAT-источников в 1С");
expect(reply.text).toContain("Найдено VAT-объектов: 5");
expect(reply.text).toContain("РегистрНакопления.НДСПродажи");
expect(reply.text).toContain("предварительная оценка по бухгалтерским оборотам НДС");
expect(reply.text).toContain("НДС начисленный");
expect(reply.text).not.toContain("Покрытие VAT-источников в 1С");
expect(reply.text).not.toContain("VAT-объектов");
expect(reply.text).not.toContain("РегистрНакопления.НДСПродажи");
});
it("builds confirmed VAT tax-period reply from sales and purchase book markers", () => {
@@ -2194,7 +2196,7 @@ describe("address compose stage utf8 headers", () => {
expect(reply.text).not.toContain("**1**)");
});
it("keeps VAT probe timestamps intact when numeric emphasis is enabled", () => {
it("keeps VAT probe diagnostics out of the user-facing estimate when numeric emphasis is enabled", () => {
const reply = composeFactualReply(
"vat_payable_forecast",
[
@@ -2229,11 +2231,12 @@ describe("address compose stage utf8 headers", () => {
}
);
expect(reply.text).toContain("последнее движение: 2019-12-31T23:59:59Z");
expect(reply.text).toContain("предварительная оценка по бухгалтерским оборотам НДС");
expect(reply.text).not.toContain("последнее движение: 2019-12-31T23:59:59Z");
expect(reply.text).not.toContain("2019****-12**-31T23:**59**:59Z");
});
it("adds MCP VAT source probe block for confirmed VAT as-of response", () => {
it("hides MCP VAT source probe diagnostics for confirmed VAT as-of response", () => {
const reply = composeFactualReply(
"vat_payable_confirmed_as_of_date",
[
@@ -2275,10 +2278,10 @@ describe("address compose stage utf8 headers", () => {
);
expect(reply.responseType).toBe("FACTUAL_LIST");
expect(reply.text).toContain("Блок 2.1. Проверка VAT-источников в 1С");
expect(reply.text).toContain("VAT-объектов в метаданных 1С: 3");
expect(reply.text).toContain("Источников с движениями до даты среза: 1");
expect(reply.text).toContain("РегистрНакопления.НДСНачисленный");
expect(reply.text).toContain("Что учтено:");
expect(reply.text).toContain("Подтвержденные позиции:");
expect(reply.text).not.toContain("VAT-объектов");
expect(reply.text).not.toContain("РегистрНакопления.НДСНачисленный");
});
it("adds VAT probe error note for confirmed VAT as-of response", () => {
@@ -2308,7 +2311,8 @@ describe("address compose stage utf8 headers", () => {
);
expect(reply.responseType).toBe("FACTUAL_LIST");
expect(reply.text).toContain("Дополнительная проверка VAT-источников завершилась ошибкой");
expect(reply.text).toContain("Подтвержденные позиции:");
expect(reply.text).not.toContain("Дополнительная проверка VAT-источников завершилась ошибкой");
});
});
@@ -5727,6 +5731,47 @@ it("routes old purchase residue questions to aging-by-purchase-date", () => {
expect(reply.semantics?.balance_confirmed).toBe(true);
});
it("sorts inventory-on-hand positions by amount before rendering the top list", () => {
const reply = composeFactualReply(
"inventory_on_hand_as_of_date",
[
{
period: "2020-03-31T23:59:59Z",
registrator: "Остатки на дату",
account_dt: "41.01",
account_kt: "",
amount: 148261.67,
analytics: ["Модуль прямоугольный", "Основной склад", "ООО Ромашка"],
item: "Модуль прямоугольный",
warehouse: "Основной склад",
organization: "ООО Ромашка",
quantity: 22
},
{
period: "2020-03-31T23:59:59Z",
registrator: "Остатки на дату",
account_dt: "41.01",
account_kt: "",
amount: 498472.5,
analytics: ["Конструкция трансформер рабочей станции", "Основной склад", "ООО Ромашка"],
item: "Конструкция трансформер рабочей станции",
warehouse: "Основной склад",
organization: "ООО Ромашка",
quantity: 3
}
],
{
asOfDate: "2020-03-31",
useRubCurrency: true
}
);
expect(reply.responseType).toBe("FACTUAL_LIST");
expect(reply.text.indexOf("Конструкция трансформер рабочей станции")).toBeLessThan(
reply.text.indexOf("Модуль прямоугольный")
);
});
it("keeps supplier-overlap reply business-first without exact contour leakage", () => {
const reply = composeFactualReply(
"inventory_supplier_stock_overlap_as_of_date",
@@ -1750,6 +1750,51 @@ describe("assistant MCP discovery pilot executor", () => {
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(2);
});
it("prefers clean counterparty candidates for bidirectional net value-flow probes", async () => {
const planner = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "net_value_flow",
explicit_entity_candidates: ["деньгам с группа свк", "Группа СВК"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "counterparty_bidirectional_value_flow_or_netting"
}
});
const deps = buildSequentialDeps([
{
rows: [{ Period: "2020-06-30T00:00:00", Amount: 12093465, Counterparty: "Группа СВК" }]
},
{
rows: []
}
]);
const result = await executeAssistantMcpDiscoveryPilot(planner, deps);
expect(result.derived_bidirectional_value_flow).toMatchObject({
counterparty: "Группа СВК",
period_scope: "2020",
net_amount: 12093465,
net_direction: "net_incoming",
incoming_customer_revenue: {
rows_matched: 1,
total_amount: 12093465
},
outgoing_supplier_payout: {
rows_matched: 0,
total_amount: 0
}
});
expect(result.reason_codes).toContain("pilot_derived_bidirectional_value_flow_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(2);
const serializedCalls = deps.executeAddressMcpQuery.mock.calls
.map((call) => JSON.stringify(call[0]))
.join("\n");
expect(serializedCalls).toContain("%Группа%");
expect(serializedCalls).toContain("%СВК%");
expect(serializedCalls).not.toContain("деньгам с группа свк");
});
it("preserves explicit date ranges when building bidirectional value-flow probes", async () => {
const planner = planAssistantMcpDiscovery({
turnMeaning: {