Уточнить all-time заработок при неполном денежном срезе
This commit is contained in:
parent
0eb583f7dc
commit
baa8aa31e7
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"schema_version": "domain_truth_harness_spec_v1",
|
||||||
|
"scenario_id": "hm_business_overview_cashflow_limits_20260525",
|
||||||
|
"domain": "assistant_stage1_business_overview",
|
||||||
|
"title": "Hm business overview cashflow limit honesty",
|
||||||
|
"description": "Focused live replay for the Hm business overview chain: all-time earnings wording must not present limited cashflow probes as confirmed all-time accounting profit.",
|
||||||
|
"bindings": {},
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"step_id": "s01_top_year",
|
||||||
|
"title": "Top revenue year",
|
||||||
|
"question": "\u043a\u0430\u043a\u043e\u0439 \u0443 \u041e\u041e\u041e \"\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u041f\u043b\u044e\u0441\" \u0441\u0430\u043c\u044b\u0439 \u0434\u043e\u0445\u043e\u0434\u043d\u044b\u0439 \u0433\u043e\u0434",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual",
|
||||||
|
"factual_with_explanation",
|
||||||
|
"partial_coverage"
|
||||||
|
],
|
||||||
|
"required_direct_answer_patterns_any": [
|
||||||
|
"2015",
|
||||||
|
"\u0432\u0445\u043e\u0434\u044f\u0449"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"\u041a\u043e\u0440\u043e\u0442\u043a\u043e:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"yearly_ranking"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step_id": "s02_earnings_2017",
|
||||||
|
"title": "2017 accounting earnings",
|
||||||
|
"question": "\u0430 \u0437\u0430 2017 \u043c\u044b \u0441\u043a\u043e\u043a \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438?",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual",
|
||||||
|
"factual_with_explanation"
|
||||||
|
],
|
||||||
|
"required_direct_answer_patterns_any": [
|
||||||
|
"\u0443\u0447\u0435\u0442\u043d\u0430\u044f \u043f\u0440\u0438\u0431\u044b\u043b\u044c",
|
||||||
|
"116 938,23"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"\u041a\u043e\u0440\u043e\u0442\u043a\u043e:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"accounting_result"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"step_id": "s03_all_time_earnings_limit",
|
||||||
|
"title": "All-time earnings must disclose limited cashflow coverage",
|
||||||
|
"question": "\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u0435\u043d\u0435\u0433 \u043c\u044b \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0437\u0430 \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u044f?",
|
||||||
|
"allowed_reply_types": [
|
||||||
|
"factual",
|
||||||
|
"factual_with_explanation"
|
||||||
|
],
|
||||||
|
"required_answer_patterns_all": [
|
||||||
|
"\u0442\u043e\u0447\u043d\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u043f\u0440\u0438\u0431\u044b\u043b\u044c",
|
||||||
|
"\u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e",
|
||||||
|
"\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d",
|
||||||
|
"\u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044e \u043f\u043e\u043b\u043d\u044b\u043c \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u043c \u043e\u0431\u043e\u0440\u043e\u0442\u043e\u043c"
|
||||||
|
],
|
||||||
|
"forbidden_answer_patterns": [
|
||||||
|
"\u041a\u043e\u0440\u043e\u0442\u043a\u043e:",
|
||||||
|
"capability_id",
|
||||||
|
"mcp_discovery"
|
||||||
|
],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": [
|
||||||
|
"business_overview",
|
||||||
|
"coverage_honesty",
|
||||||
|
"all_time_cashflow"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -905,10 +905,16 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
|
||||||
const signedNetDisplay = cashflowPolarityRequested && netDisplay && !String(netDisplay).trim().startsWith("-")
|
const signedNetDisplay = cashflowPolarityRequested && netDisplay && !String(netDisplay).trim().startsWith("-")
|
||||||
? `+${netDisplay}`
|
? `+${netDisplay}`
|
||||||
: netDisplay;
|
: netDisplay;
|
||||||
const polarityLead = cashflowPolarityRequested
|
const limitedEarningsAnswer = Boolean(earningsAmountRequested && !accountingFinancialResultForEarnings && limitLine);
|
||||||
|
const polarityLead = limitedEarningsAnswer
|
||||||
|
? "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u0442\u043e\u0447\u043d\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u043f\u0440\u0438\u0431\u044b\u043b\u044c \u0437\u0430 \u044d\u0442\u043e \u043e\u043a\u043d\u043e \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e; \u0432 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u043c \u0441\u0440\u0435\u0437\u0435 "
|
||||||
|
: cashflowPolarityRequested
|
||||||
? `\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c \u043f\u043b\u044e\u0441. `
|
? `\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c \u043f\u043b\u044e\u0441. `
|
||||||
: "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: ";
|
: "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: ";
|
||||||
lines.push(`${polarityLead}${organizationPrefix}${period} \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 ${incomingAmount ?? "0 \u0440\u0443\u0431."}; \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438/\u0441\u043f\u0438\u0441\u0430\u043b\u0438 ${outgoingAmount ?? "0 \u0440\u0443\u0431."}; \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u0435 \u043d\u0435\u0442\u0442\u043e ${signedNetDisplay}.`);
|
lines.push(`${polarityLead}${organizationPrefix}${period} \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 ${incomingAmount ?? "0 \u0440\u0443\u0431."}; \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438/\u0441\u043f\u0438\u0441\u0430\u043b\u0438 ${outgoingAmount ?? "0 \u0440\u0443\u0431."}; \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u0435 \u043d\u0435\u0442\u0442\u043e ${signedNetDisplay}.`);
|
||||||
|
if (limitLine) {
|
||||||
|
lines.push(limitLine);
|
||||||
|
}
|
||||||
lines.push(cashflowPolarityRequested
|
lines.push(cashflowPolarityRequested
|
||||||
? "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442."
|
? "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442."
|
||||||
: "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0447\u0438\u0441\u0442\u0430\u044f \u043f\u0440\u0438\u0431\u044b\u043b\u044c \u0438 \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.");
|
: "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0447\u0438\u0441\u0442\u0430\u044f \u043f\u0440\u0438\u0431\u044b\u043b\u044c \u0438 \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.");
|
||||||
|
|
|
||||||
|
|
@ -1096,12 +1096,18 @@ function buildCompactBusinessOverviewReply(
|
||||||
cashflowPolarityRequested && netDisplay && !String(netDisplay).trim().startsWith("-")
|
cashflowPolarityRequested && netDisplay && !String(netDisplay).trim().startsWith("-")
|
||||||
? `+${netDisplay}`
|
? `+${netDisplay}`
|
||||||
: netDisplay;
|
: netDisplay;
|
||||||
const polarityLead = cashflowPolarityRequested
|
const limitedEarningsAnswer = Boolean(earningsAmountRequested && !accountingFinancialResultForEarnings && limitLine);
|
||||||
|
const polarityLead = limitedEarningsAnswer
|
||||||
|
? "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u0442\u043e\u0447\u043d\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u043f\u0440\u0438\u0431\u044b\u043b\u044c \u0437\u0430 \u044d\u0442\u043e \u043e\u043a\u043d\u043e \u043d\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e; \u0432 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u043c \u0441\u0440\u0435\u0437\u0435 "
|
||||||
|
: cashflowPolarityRequested
|
||||||
? `\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c \u043f\u043b\u044e\u0441. `
|
? `\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u043f\u043e \u0434\u0435\u043d\u044c\u0433\u0430\u043c \u043f\u043b\u044e\u0441. `
|
||||||
: "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: ";
|
: "\u041a\u043e\u0440\u043e\u0442\u043a\u043e: ";
|
||||||
lines.push(
|
lines.push(
|
||||||
`${polarityLead}${organizationPrefix}${period} \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 ${incomingAmount ?? "0 \u0440\u0443\u0431."}; \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438/\u0441\u043f\u0438\u0441\u0430\u043b\u0438 ${outgoingAmount ?? "0 \u0440\u0443\u0431."}; \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u0435 \u043d\u0435\u0442\u0442\u043e ${signedNetDisplay}.`
|
`${polarityLead}${organizationPrefix}${period} \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 ${incomingAmount ?? "0 \u0440\u0443\u0431."}; \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438/\u0441\u043f\u0438\u0441\u0430\u043b\u0438 ${outgoingAmount ?? "0 \u0440\u0443\u0431."}; \u0434\u0435\u043d\u0435\u0436\u043d\u043e\u0435 \u043d\u0435\u0442\u0442\u043e ${signedNetDisplay}.`
|
||||||
);
|
);
|
||||||
|
if (limitLine) {
|
||||||
|
lines.push(limitLine);
|
||||||
|
}
|
||||||
lines.push(
|
lines.push(
|
||||||
cashflowPolarityRequested
|
cashflowPolarityRequested
|
||||||
? "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442."
|
? "\u042d\u0442\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u0440\u043e\u043a\u0430\u043c 1\u0421, \u043d\u0435 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u0438\u0439 \u0444\u0438\u043d\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442."
|
||||||
|
|
|
||||||
|
|
@ -850,6 +850,72 @@ describe("assistant MCP discovery response candidate", () => {
|
||||||
expect(candidate.reply_text).not.toContain("wide overview");
|
expect(candidate.reply_text).not.toContain("wide overview");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("marks all-time earnings wording as limited when cashflow probes hit row limits", () => {
|
||||||
|
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
|
||||||
|
entryPoint({
|
||||||
|
turn_input: {
|
||||||
|
adapter_status: "ready",
|
||||||
|
turn_meaning_ref: {
|
||||||
|
raw_message: "сколько вообще денег мы заработали за все время?",
|
||||||
|
asked_action_family: "broad_evaluation",
|
||||||
|
unsupported_but_understood_family: "broad_business_evaluation",
|
||||||
|
explicit_organization_scope: "ООО Альтернатива Плюс"
|
||||||
|
},
|
||||||
|
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: {
|
||||||
|
incoming_customer_revenue: {
|
||||||
|
total_amount_human_ru: "285 819 547,57 руб.",
|
||||||
|
coverage_limited_by_probe_limit: true
|
||||||
|
},
|
||||||
|
outgoing_supplier_payout: {
|
||||||
|
total_amount_human_ru: "137 963 720,37 руб.",
|
||||||
|
coverage_limited_by_probe_limit: true
|
||||||
|
},
|
||||||
|
net_amount_human_ru: "147 855 827,20 руб.",
|
||||||
|
net_direction: "net_incoming",
|
||||||
|
top_customers: [],
|
||||||
|
top_suppliers: [],
|
||||||
|
accounting_financial_result: null,
|
||||||
|
coverage_limited_by_probe_limit: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
answer_draft: {
|
||||||
|
answer_mode: "confirmed_with_bounded_inference",
|
||||||
|
headline: "wide overview should not leak",
|
||||||
|
confirmed_lines: [],
|
||||||
|
inference_lines: [],
|
||||||
|
unknown_lines: [],
|
||||||
|
limitation_lines: [],
|
||||||
|
next_step_line: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(candidate.reply_text).toContain("точную учетную прибыль");
|
||||||
|
expect(candidate.reply_text).toContain("не подтверждаю");
|
||||||
|
expect(candidate.reply_text).toContain("ограниченном денежном срезе");
|
||||||
|
expect(candidate.reply_text).toContain("285 819 547,57");
|
||||||
|
expect(candidate.reply_text).toContain("147 855 827,20");
|
||||||
|
expect(candidate.reply_text).toContain("не считаю полным бухгалтерским оборотом");
|
||||||
|
expect(candidate.reply_text).not.toContain("wide overview");
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps broad overview layers when direct-money reason is present", () => {
|
it("keeps broad overview layers when direct-money reason is present", () => {
|
||||||
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
|
const candidate = buildAssistantMcpDiscoveryResponseCandidate(
|
||||||
entryPoint({
|
entryPoint({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue