Сделать денежные итоги amount-first в 1С
This commit is contained in:
parent
b2fe0460b3
commit
847a32ba4c
|
|
@ -3,7 +3,7 @@
|
||||||
"scenario_id": "agent_autonomy_business_quality_20260523",
|
"scenario_id": "agent_autonomy_business_quality_20260523",
|
||||||
"domain": "autonomy_business_quality",
|
"domain": "autonomy_business_quality",
|
||||||
"title": "AGENT | Autonomy business quality pack",
|
"title": "AGENT | Autonomy business quality pack",
|
||||||
"description": "Expanded targeted AGENT replay for the current autonomy milestone: value-flow hot handoff must survive realistic business questions, while final answers must read like a useful 1C analyst instead of runtime/debug prose.",
|
"description": "Expanded targeted AGENT replay for the autonomy milestone: value-flow, business overview, debts, VAT, profit/cashflow distinction, nomenclature margin boundary, and final answer quality must survive realistic business questions.",
|
||||||
"bindings": {},
|
"bindings": {},
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
|
|
@ -101,6 +101,19 @@
|
||||||
"criticality": "critical",
|
"criticality": "critical",
|
||||||
"semantic_tags": ["followup_context", "profit_vs_cashflow"]
|
"semantic_tags": ["followup_context", "profit_vs_cashflow"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"step_id": "step_06b_direct_clean_profit",
|
||||||
|
"title": "Direct clean profit question starts with accounting result, not with denial",
|
||||||
|
"question": "Какая чистая прибыль по ООО Альтернатива Плюс за 2020?",
|
||||||
|
"allowed_reply_types": ["partial_coverage", "factual_with_explanation", "factual"],
|
||||||
|
"expected_catalog_alignment_status": "selected_matches_top",
|
||||||
|
"expected_catalog_chain_top_match": "business_overview",
|
||||||
|
"expected_catalog_selected_matches_top": true,
|
||||||
|
"required_answer_patterns_all": ["2020", "7\\s*136\\s*815|7,?136,?815|7136815", "убыт|минус", "90|91|99"],
|
||||||
|
"forbidden_answer_patterns": ["Коротко: нет", "денежное операционное нетто не стоит считать чистой прибылью", "Учтено строк", "Первая найденная дата", "runtime_", "planner_", "query_movements", "primitive"],
|
||||||
|
"criticality": "critical",
|
||||||
|
"semantic_tags": ["direct_profit", "profit_vs_cashflow", "business_answer_quality"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"step_id": "step_07_sberbank_financial_flow",
|
"step_id": "step_07_sberbank_financial_flow",
|
||||||
"title": "Sberbank role is financial flow, not ordinary customer/supplier",
|
"title": "Sberbank role is financial flow, not ordinary customer/supplier",
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ function uniqueStrings(values) {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
function trimTrailingSentenceDot(value) {
|
||||||
|
return value.trim().replace(/[.]+$/u, "");
|
||||||
|
}
|
||||||
function formatNamedChoiceList(values) {
|
function formatNamedChoiceList(values) {
|
||||||
return uniqueStrings(values)
|
return uniqueStrings(values)
|
||||||
.slice(0, 6)
|
.slice(0, 6)
|
||||||
|
|
@ -837,10 +840,7 @@ function headlineFor(mode, pilot) {
|
||||||
return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду.";
|
return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду.";
|
||||||
}
|
}
|
||||||
if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") {
|
if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") {
|
||||||
if (pilot.derived_value_flow.value_flow_direction === "outgoing_supplier_payout") {
|
return derivedValueFlowHeadlineLine(pilot) ?? "По данным 1С найдены денежные строки; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
||||||
return "По данным 1С найдены строки исходящих платежей/списаний; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
|
||||||
}
|
|
||||||
return "По данным 1С найдены строки входящих денежных поступлений; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
|
||||||
}
|
}
|
||||||
const zeroValueFlowHeadline = valueFlowZeroResultHeadline(pilot);
|
const zeroValueFlowHeadline = valueFlowZeroResultHeadline(pilot);
|
||||||
if (mode === "checked_sources_only" && zeroValueFlowHeadline) {
|
if (mode === "checked_sources_only" && zeroValueFlowHeadline) {
|
||||||
|
|
@ -1203,6 +1203,20 @@ function derivedRankedValueFlowConfirmedLine(pilot) {
|
||||||
: "";
|
: "";
|
||||||
return `${directionLead} ${leader.axis_value}${organization}${period}: ${leader.total_amount_human_ru} по ${leader.rows_with_amount} строкам с суммой.${roleCaveat}${trail}${limitCaveat}`;
|
return `${directionLead} ${leader.axis_value}${organization}${period}: ${leader.total_amount_human_ru} по ${leader.rows_with_amount} строкам с суммой.${roleCaveat}${trail}${limitCaveat}`;
|
||||||
}
|
}
|
||||||
|
function derivedValueFlowHeadlineLine(pilot) {
|
||||||
|
const flow = pilot.derived_value_flow;
|
||||||
|
if (!flow) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const organizationScope = explicitOrganizationScope(pilot);
|
||||||
|
const organization = organizationScope ? ` по организации ${organizationScope}` : "";
|
||||||
|
const counterparty = flow.counterparty ? ` по контрагенту ${flow.counterparty}` : "";
|
||||||
|
const period = flow.period_scope ? ` за период ${flow.period_scope}` : " в проверенном окне";
|
||||||
|
const totalLabel = flow.value_flow_direction === "outgoing_supplier_payout"
|
||||||
|
? "Исходящие платежи/списания"
|
||||||
|
: "Входящие денежные поступления";
|
||||||
|
return `${totalLabel}${counterparty || organization}${period}: ${trimTrailingSentenceDot(flow.total_amount_human_ru)}.`;
|
||||||
|
}
|
||||||
function derivedValueFlowConfirmedLine(pilot) {
|
function derivedValueFlowConfirmedLine(pilot) {
|
||||||
const flow = pilot.derived_value_flow;
|
const flow = pilot.derived_value_flow;
|
||||||
if (!flow) {
|
if (!flow) {
|
||||||
|
|
@ -1221,7 +1235,7 @@ function derivedValueFlowConfirmedLine(pilot) {
|
||||||
const limitCaveat = flow.coverage_limited_by_probe_limit
|
const limitCaveat = flow.coverage_limited_by_probe_limit
|
||||||
? " Проверка уперлась в лимит строк, поэтому полный период может быть покрыт не полностью."
|
? " Проверка уперлась в лимит строк, поэтому полный период может быть покрыт не полностью."
|
||||||
: "";
|
: "";
|
||||||
return `${totalLabel}${counterparty || organization}${period}: ${flow.total_amount_human_ru}.${limitCaveat} ${caveat}`;
|
return `${totalLabel}${counterparty || organization}${period}: ${trimTrailingSentenceDot(flow.total_amount_human_ru)}.${limitCaveat} ${caveat}`;
|
||||||
}
|
}
|
||||||
function derivedValueFlowMonthlyLines(pilot) {
|
function derivedValueFlowMonthlyLines(pilot) {
|
||||||
const flow = pilot.derived_value_flow;
|
const flow = pilot.derived_value_flow;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ function uniqueStrings(values: string[]): string[] {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function trimTrailingSentenceDot(value: string): string {
|
||||||
|
return value.trim().replace(/[.]+$/u, "");
|
||||||
|
}
|
||||||
|
|
||||||
function formatNamedChoiceList(values: string[]): string {
|
function formatNamedChoiceList(values: string[]): string {
|
||||||
return uniqueStrings(values)
|
return uniqueStrings(values)
|
||||||
.slice(0, 6)
|
.slice(0, 6)
|
||||||
|
|
@ -990,10 +994,7 @@ function headlineFor(mode: AssistantMcpDiscoveryAnswerMode, pilot: AssistantMcpD
|
||||||
return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду.";
|
return "По данным 1С найдены строки входящих и исходящих денежных движений; нетто можно называть только как расчет по найденным строкам и проверенному периоду.";
|
||||||
}
|
}
|
||||||
if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") {
|
if (pilot.derived_value_flow && mode === "confirmed_with_bounded_inference") {
|
||||||
if (pilot.derived_value_flow.value_flow_direction === "outgoing_supplier_payout") {
|
return derivedValueFlowHeadlineLine(pilot) ?? "По данным 1С найдены денежные строки; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
||||||
return "По данным 1С найдены строки исходящих платежей/списаний; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
|
||||||
}
|
|
||||||
return "По данным 1С найдены строки входящих денежных поступлений; сумму можно называть только в рамках проверенного периода и найденных строк.";
|
|
||||||
}
|
}
|
||||||
const zeroValueFlowHeadline = valueFlowZeroResultHeadline(pilot);
|
const zeroValueFlowHeadline = valueFlowZeroResultHeadline(pilot);
|
||||||
if (mode === "checked_sources_only" && zeroValueFlowHeadline) {
|
if (mode === "checked_sources_only" && zeroValueFlowHeadline) {
|
||||||
|
|
@ -1383,6 +1384,22 @@ function derivedRankedValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotEx
|
||||||
return `${directionLead} ${leader.axis_value}${organization}${period}: ${leader.total_amount_human_ru} по ${leader.rows_with_amount} строкам с суммой.${roleCaveat}${trail}${limitCaveat}`;
|
return `${directionLead} ${leader.axis_value}${organization}${period}: ${leader.total_amount_human_ru} по ${leader.rows_with_amount} строкам с суммой.${roleCaveat}${trail}${limitCaveat}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function derivedValueFlowHeadlineLine(pilot: AssistantMcpDiscoveryPilotExecutionContract): string | null {
|
||||||
|
const flow = pilot.derived_value_flow;
|
||||||
|
if (!flow) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const organizationScope = explicitOrganizationScope(pilot);
|
||||||
|
const organization = organizationScope ? ` по организации ${organizationScope}` : "";
|
||||||
|
const counterparty = flow.counterparty ? ` по контрагенту ${flow.counterparty}` : "";
|
||||||
|
const period = flow.period_scope ? ` за период ${flow.period_scope}` : " в проверенном окне";
|
||||||
|
const totalLabel =
|
||||||
|
flow.value_flow_direction === "outgoing_supplier_payout"
|
||||||
|
? "Исходящие платежи/списания"
|
||||||
|
: "Входящие денежные поступления";
|
||||||
|
return `${totalLabel}${counterparty || organization}${period}: ${trimTrailingSentenceDot(flow.total_amount_human_ru)}.`;
|
||||||
|
}
|
||||||
|
|
||||||
function derivedValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotExecutionContract): string | null {
|
function derivedValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotExecutionContract): string | null {
|
||||||
const flow = pilot.derived_value_flow;
|
const flow = pilot.derived_value_flow;
|
||||||
if (!flow) {
|
if (!flow) {
|
||||||
|
|
@ -1403,7 +1420,7 @@ function derivedValueFlowConfirmedLine(pilot: AssistantMcpDiscoveryPilotExecutio
|
||||||
const limitCaveat = flow.coverage_limited_by_probe_limit
|
const limitCaveat = flow.coverage_limited_by_probe_limit
|
||||||
? " Проверка уперлась в лимит строк, поэтому полный период может быть покрыт не полностью."
|
? " Проверка уперлась в лимит строк, поэтому полный период может быть покрыт не полностью."
|
||||||
: "";
|
: "";
|
||||||
return `${totalLabel}${counterparty || organization}${period}: ${flow.total_amount_human_ru}.${limitCaveat} ${caveat}`;
|
return `${totalLabel}${counterparty || organization}${period}: ${trimTrailingSentenceDot(flow.total_amount_human_ru)}.${limitCaveat} ${caveat}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function derivedValueFlowMonthlyLines(pilot: AssistantMcpDiscoveryPilotExecutionContract): string[] {
|
function derivedValueFlowMonthlyLines(pilot: AssistantMcpDiscoveryPilotExecutionContract): string[] {
|
||||||
|
|
|
||||||
|
|
@ -1401,11 +1401,10 @@ describe("assistant MCP discovery answer adapter", () => {
|
||||||
const confirmedText = draft.confirmed_lines.join("\n");
|
const confirmedText = draft.confirmed_lines.join("\n");
|
||||||
|
|
||||||
expect(draft.answer_mode).toBe("confirmed_with_bounded_inference");
|
expect(draft.answer_mode).toBe("confirmed_with_bounded_inference");
|
||||||
expect(draft.headline).toContain("входящих денежных поступлений");
|
expect(draft.headline).toContain("Входящие денежные поступления");
|
||||||
|
expect(draft.headline).toContain("3 750,50 руб");
|
||||||
expect(confirmedText).toContain("3 750,50 руб.");
|
expect(confirmedText).toContain("3 750,50 руб.");
|
||||||
expect(confirmedText).toContain("входящих денежных поступлений");
|
expect(confirmedText).toContain("входящие денежные поступления");
|
||||||
expect(confirmedText).toContain("2020-01-15");
|
|
||||||
expect(confirmedText).toContain("2020-02-20");
|
|
||||||
expect(draft.unknown_lines).toContain("Full turnover outside the checked period is not proven by this MCP discovery pilot");
|
expect(draft.unknown_lines).toContain("Full turnover outside the checked period is not proven by this MCP discovery pilot");
|
||||||
expect(draft.must_not_claim).toContain("Do not claim full all-time turnover unless the checked period and coverage prove it.");
|
expect(draft.must_not_claim).toContain("Do not claim full all-time turnover unless the checked period and coverage prove it.");
|
||||||
expect(draft.limitation_lines.join("\n")).not.toContain("pilot_");
|
expect(draft.limitation_lines.join("\n")).not.toContain("pilot_");
|
||||||
|
|
@ -1433,8 +1432,9 @@ describe("assistant MCP discovery answer adapter", () => {
|
||||||
const confirmedText = draft.confirmed_lines.join("\n");
|
const confirmedText = draft.confirmed_lines.join("\n");
|
||||||
|
|
||||||
expect(draft.answer_mode).toBe("confirmed_with_bounded_inference");
|
expect(draft.answer_mode).toBe("confirmed_with_bounded_inference");
|
||||||
expect(draft.headline).toContain("исходящих платежей");
|
expect(draft.headline).toContain("Исходящие платежи");
|
||||||
expect(confirmedText).toContain("исходящих платежей/списаний");
|
expect(draft.headline).toContain("5 000,25 руб");
|
||||||
|
expect(confirmedText).toContain("исходящие платежи/списания");
|
||||||
expect(confirmedText).toContain("5 000,25 руб.");
|
expect(confirmedText).toContain("5 000,25 руб.");
|
||||||
expect(draft.inference_lines.join("\n")).toContain("supplier-payout total");
|
expect(draft.inference_lines.join("\n")).toContain("supplier-payout total");
|
||||||
expect(draft.unknown_lines).toContain("Full supplier-payout amount outside the checked period is not proven by this MCP discovery pilot");
|
expect(draft.unknown_lines).toContain("Full supplier-payout amount outside the checked period is not proven by this MCP discovery pilot");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue