Сжать бизнес-ответы по доходности и заработанным суммам

This commit is contained in:
2026-05-09 10:30:46 +03:00
parent a15cbb3fcb
commit 7c77db2c8d
15 changed files with 987 additions and 13 deletions
@@ -637,7 +637,10 @@ describe("assistant living chat runtime adapter", () => {
sessionItems: [
{
role: "assistant",
text: "По товару Рабочая станция универсального специалиста покупатель определен: Комитет государственных услуг г. Москвы.\nДокументы выбытия:\n1. Реализация товаров и услуг | товар: Рабочая станция универсального специалиста | контрагент: Комитет государственных услуг г. Москвы",
trace_id: "address-sale-trace",
debug: {
trace_id: "address-sale-trace",
execution_lane: "address_query",
answer_grounding_check: {
status: "grounded"
@@ -658,6 +661,8 @@ describe("assistant living chat runtime adapter", () => {
expect(output.handled).toBe(true);
expect(output.chatText).toContain("Рабочая станция универсального специалиста");
expect(output.chatText).toContain("Комитет государственных услуг г. Москвы");
expect(output.chatText).not.toContain("Покупатель в доступных данных отдельно не выделен");
expect(output.debug?.living_chat_response_source).toBe("deterministic_answer_inspection_contract");
expect(executeLlmChat).not.toHaveBeenCalled();
});
@@ -264,7 +264,12 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.answer_mode).toBe("confirmed_with_bounded_inference");
expect(draft.headline).toContain("бизнес-обзор");
expect(draft.headline).toContain("входящие поступления");
expect(draft.headline).toContain("расчетное операционное нетто");
expect(draft.headline).toContain("самый сильный год");
expect(draft.confirmed_lines.join("\n")).toContain("Входящие поступления");
expect(draft.confirmed_lines.join("\n")).toContain("Самый сильный год");
expect(draft.confirmed_lines.join("\n")).toContain("2021");
expect(draft.confirmed_lines.join("\n")).toContain("Самый крупный подтвержденный клиент");
expect(draft.confirmed_lines.join("\n")).toContain("Самый крупный подтвержденный поставщик");
expect(draft.confirmed_lines.join("\n")).toContain("Годовая раскладка операционного денежного потока");
@@ -44,6 +44,149 @@ describe("assistant MCP discovery response candidate", () => {
expect(candidate.reply_text).not.toContain("primitive");
});
it("uses a compact direct answer for business-overview top year questions", () => {
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
entryPoint({
turn_input: {
adapter_status: "ready",
data_need_graph: {
business_fact_family: "business_overview",
ranking_need: "top_desc",
reason_codes: [
"data_need_graph_family_business_overview",
"data_need_graph_ranking_top_desc",
"data_need_graph_business_overview_direct_money_answer"
]
}
},
bridge: {
bridge_status: "answer_draft_ready",
user_facing_response_allowed: true,
business_fact_answer_allowed: true,
requires_user_clarification: false,
pilot: {
pilot_scope: "business_overview_route_template_v1",
derived_business_overview: {
period_scope: null,
incoming_customer_revenue: {
total_amount_human_ru: "157 192 981,43 руб.",
coverage_limited_by_probe_limit: true
},
outgoing_supplier_payout: {
total_amount_human_ru: "35 439 044,74 руб.",
coverage_limited_by_probe_limit: true
},
net_amount_human_ru: "121 753 936,69 руб.",
net_direction: "net_incoming",
top_customers: [],
yearly_breakdown: [
{
year_bucket: "2014",
incoming_total_amount: 11239150.41,
incoming_total_amount_human_ru: "11 239 150,41 руб.",
incoming_rows_with_amount: 4,
net_amount: -634486.17,
net_amount_human_ru: "634 486,17 руб.",
net_direction: "net_outgoing"
},
{
year_bucket: "2015",
incoming_total_amount: 136723459.73,
incoming_total_amount_human_ru: "136 723 459,73 руб.",
incoming_rows_with_amount: 54,
net_amount: 113158051.57,
net_amount_human_ru: "113 158 051,57 руб.",
net_direction: "net_incoming"
}
]
}
},
answer_draft: {
answer_mode: "confirmed_with_bounded_inference",
headline: "Ограниченный бизнес-обзор с большим полотном.",
confirmed_lines: ["Профиль операционной активности: лишняя широкая строка."],
inference_lines: ["Сводный LLM-аудит: лишняя широкая строка."],
unknown_lines: ["Прибыль и маржа не подтверждены."],
limitation_lines: [],
next_step_line: null
}
}
})
);
expect(candidate.reply_text).toContain("самый доходный год");
expect(candidate.reply_text).toContain("2015");
expect(candidate.reply_text).toContain("136 723 459,73 руб.");
expect(candidate.reply_text).toContain("не как чистую бухгалтерскую прибыль");
expect(candidate.reply_text).toContain("лимит выборки MCP");
expect(candidate.reply_text).not.toContain("Что подтверждено:");
expect(candidate.reply_text).not.toContain("Профиль операционной активности");
});
it("uses a compact direct answer for business-overview earned-money totals", () => {
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
entryPoint({
turn_input: {
adapter_status: "ready",
data_need_graph: {
business_fact_family: "business_overview",
ranking_need: null,
reason_codes: [
"data_need_graph_family_business_overview",
"data_need_graph_business_overview_direct_money_answer"
]
}
},
bridge: {
bridge_status: "answer_draft_ready",
user_facing_response_allowed: true,
business_fact_answer_allowed: true,
requires_user_clarification: false,
pilot: {
pilot_scope: "business_overview_route_template_v1",
derived_business_overview: {
period_scope: "2017",
incoming_customer_revenue: {
total_amount_human_ru: "16 932 063,96 руб.",
coverage_limited_by_probe_limit: false
},
outgoing_supplier_payout: {
total_amount_human_ru: "4 458 027,05 руб.",
coverage_limited_by_probe_limit: true
},
net_amount_human_ru: "12 474 036,91 руб.",
net_direction: "net_incoming",
top_customers: [
{
axis_value: "ГКУ УКРиС",
total_amount_human_ru: "11 536 836,23 руб."
}
],
yearly_breakdown: []
}
},
answer_draft: {
answer_mode: "confirmed_with_bounded_inference",
headline: "Ограниченный бизнес-обзор с большим полотном.",
confirmed_lines: ["Складской срез на дату: лишняя широкая строка."],
inference_lines: ["Риски и контуры внимания: лишняя широкая строка."],
unknown_lines: [],
limitation_lines: [],
next_step_line: null
}
}
})
);
expect(candidate.reply_text).toContain("за 2017");
expect(candidate.reply_text).toContain("получили 16 932 063,96 руб.");
expect(candidate.reply_text).toContain("исходящие платежи/списания 4 458 027,05 руб.");
expect(candidate.reply_text).toContain("12 474 036,91 руб.");
expect(candidate.reply_text).toContain("денежный operating-flow proxy");
expect(candidate.reply_text).not.toContain("Что можно сказать только как вывод:");
expect(candidate.reply_text).not.toContain("Складской срез");
});
it("localizes value-flow evidence without leaking pilot mechanics", () => {
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
entryPoint({
@@ -1989,6 +1989,65 @@ describe("assistant MCP discovery turn input adapter", () => {
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_all_time_scope_hint");
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_business_overview_direct_money_answer");
});
it.skip("marks organization-level top-year wording as a direct business-overview money answer", () => {
const orgName = "ООО Альтернатива Плюс";
const result = buildAssistantMcpDiscoveryTurnInput({
userMessage: "какой у нас самый доходный год",
followupContext: {
previous_discovery_pilot_scope: "business_overview_route_template_v1",
previous_filters: {
organization: orgName
}
}
});
expect(result.adapter_status).toBe("ready");
expect(result.should_run_discovery).toBe(true);
expect(result.data_need_graph?.business_fact_family).toBe("business_overview");
expect(result.data_need_graph?.ranking_need).toBe("top_desc");
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_business_overview_direct_money_answer");
});
it("marks UTF-8 organization-level top-year wording as a direct business-overview money answer", () => {
const orgName = "\u041e\u041e\u041e \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u041f\u043b\u044e\u0441";
const result = buildAssistantMcpDiscoveryTurnInput({
userMessage:
"\u043a\u0430\u043a\u043e\u0439 \u0443 \u043d\u0430\u0441 \u0441\u0430\u043c\u044b\u0439 \u0434\u043e\u0445\u043e\u0434\u043d\u044b\u0439 \u0433\u043e\u0434",
followupContext: {
previous_discovery_pilot_scope: "business_overview_route_template_v1",
previous_filters: {
organization: orgName
}
}
});
expect(result.adapter_status).toBe("ready");
expect(result.should_run_discovery).toBe(true);
expect(result.data_need_graph?.business_fact_family).toBe("business_overview");
expect(result.data_need_graph?.ranking_need).toBe("top_desc");
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_business_overview_direct_money_answer");
});
it("marks explicit-period earned-money wording as a direct business-overview money answer", () => {
const orgName = "ООО Альтернатива Плюс";
const result = buildAssistantMcpDiscoveryTurnInput({
userMessage: "а за 2017 мы скок заработали?",
followupContext: {
previous_discovery_pilot_scope: "business_overview_route_template_v1",
previous_filters: {
organization: orgName
}
}
});
expect(result.adapter_status).toBe("ready");
expect(result.should_run_discovery).toBe(true);
expect(result.data_need_graph?.business_fact_family).toBe("business_overview");
expect(result.turn_meaning_ref?.explicit_date_scope).toBe("2017");
expect(result.data_need_graph?.reason_codes).toContain("data_need_graph_business_overview_direct_money_answer");
});
it("routes organization-level profit and margin wording to business overview instead of exact value recipes", () => {
@@ -348,6 +348,26 @@ describe("assistantMemoryRecapPolicy", () => {
const reply = buildSelectedObjectAnswerInspectionReply({
addressDebug: context.lastAnswerInspectionAddressDebug,
sessionItems: [
{
role: "assistant",
text: "По товару Рабочая станция покупатель определен: Комитет государственных услуг г. Москвы.\nДокументы выбытия:\n1. Реализация товаров и услуг | товар: Рабочая станция | контрагент: Комитет государственных услуг г. Москвы",
trace_id: "address-sale-trace",
debug: {
trace_id: "address-sale-trace",
execution_lane: "address_query",
answer_grounding_check: {
status: "grounded"
},
detected_intent: "inventory_sale_trace_for_item",
extracted_filters: {
item: "Рабочая станция",
organization: "ООО Альтернатива Плюс",
as_of_date: "2016-03-31"
}
}
}
],
toNonEmptyString: (value: unknown) => {
const text = String(value ?? "").trim();
return text.length > 0 ? text : null;
@@ -357,7 +377,8 @@ describe("assistantMemoryRecapPolicy", () => {
expect(context.contextualAnswerInspectionFollowup).toBe(true);
expect(reply).toContain("не контрагент");
expect(reply).toContain("Рабочая станция");
expect(reply).toContain("Покупатель");
expect(reply).toContain("Комитет государственных услуг г. Москвы");
expect(reply).not.toContain("Покупатель в доступных данных отдельно не выделен");
});
it("builds deterministic recap summary from grounded MCP discovery counterparty context", () => {