Уточнить честность широкого бизнес-обзора ассистента

This commit is contained in:
2026-05-26 00:05:28 +03:00
parent baa8aa31e7
commit 92473c894f
4 changed files with 118 additions and 20 deletions
@@ -959,11 +959,7 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
: "Это учетный финрезультат по найденным строкам закрытия периода в 1С, а не внешний аудит и не юридически подтвержденная отчетность.");
return joinBusinessReplyLines(lines);
}
const headline = toNonEmptyString(draft.headline);
const cleanHeadline = headline?.replace(/^Коротко:\s*/iu, "").trim();
lines.push(cleanHeadline
? `Коротко: ${localizeLine(cleanHeadline)}`
: "Коротко: нельзя точно подтвердить чистую прибыль и маржу по текущему срезу 1С; есть только ограниченный операционный денежный/товарный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат.");
lines.push("Коротко: чистую прибыль и маржу не подтверждаю по текущему срезу 1С; видны только ограниченные денежные обороты и расчетное нетто/операционный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат.");
const boundaryLines = userFacingLines([
...toStringList(draft.confirmed_lines),
...toStringList(draft.inference_lines),
@@ -1113,8 +1109,8 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
(actionFamily === "broad_evaluation" || unsupportedFamily === "broad_business_evaluation")) {
const subject = organizationScope ?? "компания";
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
lines.push(`Коротко: по доступным данным ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж.`);
lines.push("Что видно:");
lines.push(`Коротко: по ограниченному проверенному 1С-срезу ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж; это не аудиторское заключение и не подтвержденная чистая прибыль.`);
lines.push("Что видно в ограниченном денежном срезе:");
if (incomingAmount) {
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
}
@@ -1146,7 +1142,9 @@ function buildCompactBusinessOverviewReply(entryPoint, draft) {
if (debtLine) {
lines.push(`- ${localizeLine(debtLine)}`);
}
lines.push("Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль.");
if (!limitLine) {
lines.push("Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль.");
}
const missingOverviewFamilies = [];
if (!taxLine) {
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
@@ -1167,12 +1167,8 @@ function buildCompactBusinessOverviewReply(
);
return joinBusinessReplyLines(lines);
}
const headline = toNonEmptyString(draft.headline);
const cleanHeadline = headline?.replace(/^Коротко:\s*/iu, "").trim();
lines.push(
cleanHeadline
? `Коротко: ${localizeLine(cleanHeadline)}`
: "Коротко: нельзя точно подтвердить чистую прибыль и маржу по текущему срезу 1С; есть только ограниченный операционный денежный/товарный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат."
"Коротко: чистую прибыль и маржу не подтверждаю по текущему срезу 1С; видны только ограниченные денежные обороты и расчетное нетто/операционный сигнал, а не полный отчет о прибыли и не бухгалтерский финансовый результат."
);
const boundaryLines = userFacingLines([
...toStringList(draft.confirmed_lines),
@@ -1366,9 +1362,9 @@ function buildCompactBusinessOverviewReply(
const subject = organizationScope ?? "компания";
const periodWithoutPrefix = period.replace(/^за\s+/iu, "");
lines.push(
`Коротко: по доступным данным ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж.`
`Коротко: по ограниченному проверенному 1С-срезу ${subject} выглядит как бизнес с крупными контрактными денежными потоками и заметной зависимостью от нескольких крупных контрагентов, а не как равномерный поток мелких продаж; это не аудиторское заключение и не подтвержденная чистая прибыль.`
);
lines.push("Что видно:");
lines.push("Что видно в ограниченном денежном срезе:");
if (incomingAmount) {
lines.push(`- входящие деньги за ${periodWithoutPrefix}: ${incomingAmount};`);
}
@@ -1404,9 +1400,11 @@ function buildCompactBusinessOverviewReply(
if (debtLine) {
lines.push(`- ${localizeLine(debtLine)}`);
}
lines.push(
"Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль."
);
if (!limitLine) {
lines.push(
"Ограничение: это оценка по денежным потокам и найденным срезам 1С, не аудиторское заключение и не подтвержденная чистая прибыль."
);
}
const missingOverviewFamilies: string[] = [];
if (!taxLine) {
missingOverviewFamilies.push("НДС/налоговая позиция без отдельного точного расчета");
@@ -202,7 +202,8 @@ describe("assistant MCP discovery response candidate", () => {
})
);
expect(candidate.reply_text).toContain("нельзя точно подтвердить чистую прибыль");
expect(candidate.reply_text).toContain("чистую прибыль и маржу не подтверждаю");
expect(candidate.reply_text).toContain("расчетное нетто");
expect(candidate.reply_text).toContain("полный отчет о прибылях и убытках");
expect(candidate.reply_text).toContain("себестоимости");
expect(candidate.reply_text).not.toContain("47 628 853");
@@ -1003,7 +1004,7 @@ describe("assistant MCP discovery response candidate", () => {
})
);
expect(candidate.reply_text).toContain("Что видно:");
expect(candidate.reply_text).toContain("Что видно в ограниченном денежном срезе:");
expect(candidate.reply_text).toContain("НДС:");
expect(candidate.reply_text).toContain("Долги:");
expect(candidate.reply_text).toContain("Склад:");
@@ -1425,6 +1426,11 @@ describe("assistant MCP discovery response candidate", () => {
})
);
const firstLine = candidate.reply_text?.split("\n")[0] ?? "";
expect(firstLine).toContain("по ограниченному проверенному 1С-срезу");
expect(firstLine).toContain("не аудиторское заключение");
expect(firstLine).toContain("не подтвержденная чистая прибыль");
expect(candidate.reply_text).toContain("Что видно в ограниченном денежном срезе");
expect(candidate.reply_text).toContain("Что не подтверждено в этом срезе");
expect(candidate.reply_text).toContain("НДС");
expect(candidate.reply_text).toContain("долги");