Дочистить user-facing ответы 1С ассистента
This commit is contained in:
parent
1a94e72381
commit
f5d86d4bc1
|
|
@ -3493,44 +3493,27 @@ function composeFactualReplyBody(intent, rows, options = {}) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const lines = [
|
const lines = [
|
||||||
`Коротко: подтвержденная дебиторская задолженность на ${formatDateRu(receivablesAsOfDate)} — ${formatMoneyRub(totalOutstandingAmount)}.`,
|
`Коротко: на ${formatDateRu(receivablesAsOfDate)} нам должны ${formatMoneyRub(totalOutstandingAmount)}.`
|
||||||
"Это подтвержденный срез дебиторской задолженности, а не эвристический shortlist."
|
|
||||||
];
|
];
|
||||||
|
if (periodScopeLine || carryoverLine) {
|
||||||
lines.push("");
|
lines.push("");
|
||||||
lines.push("Что учтено");
|
lines.push("Граница ответа:");
|
||||||
lines.push(`- Дата среза: ${formatDateRu(receivablesAsOfDate)}.`);
|
|
||||||
if (periodScopeLine) {
|
if (periodScopeLine) {
|
||||||
lines.push(periodScopeLine);
|
lines.push(periodScopeLine);
|
||||||
}
|
}
|
||||||
lines.push("- Контур: дебиторская задолженность по счетам 62/76.");
|
|
||||||
if (carryoverLine) {
|
if (carryoverLine) {
|
||||||
lines.push(carryoverLine);
|
lines.push(carryoverLine);
|
||||||
}
|
}
|
||||||
lines.push("");
|
|
||||||
lines.push("Сводка");
|
|
||||||
lines.push(`- Строк в выборке: ${formatNumberWithDots(rows.length)}.`);
|
|
||||||
lines.push(`- Контрагентов с подтвержденным остатком к получению: ${formatNumberWithDots(confirmedBalances.length)}.`);
|
|
||||||
appendDebtMirrorDisclosure(lines, balanceSnapshot, "receivables");
|
|
||||||
lines.push("");
|
|
||||||
lines.push("Категории дебиторской задолженности");
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("supplier_or_contractor")}: ${formatNumberWithDots(categoryCounts.supplier_or_contractor)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("bank_or_credit")}: ${formatNumberWithDots(categoryCounts.bank_or_credit)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("tax_or_state")}: ${formatNumberWithDots(categoryCounts.tax_or_state)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("other")}: ${formatNumberWithDots(categoryCounts.other)}.`);
|
|
||||||
lines.push("");
|
|
||||||
lines.push("Подтвержденные позиции к получению");
|
|
||||||
if (confirmedBalances.length > 0) {
|
|
||||||
lines.push(...confirmedBalances.slice(0, 10).flatMap((item, index) => [
|
|
||||||
`${index + 1}. ${item.name} | категория: ${receivablesCategoryLabel(item.category)} | остаток к получению: ${formatMoneyRub(item.outstandingAmount)} | операций: ${formatNumberWithDots(item.operations)}${item.categoryReasons.length > 0 ? ` | основание: ${item.categoryReasons.join(", ")}` : ""}${formatPayablesEvidenceSuffix(item)}`,
|
|
||||||
""
|
|
||||||
]));
|
|
||||||
if (lines[lines.length - 1] === "") {
|
|
||||||
lines.pop();
|
|
||||||
}
|
}
|
||||||
|
lines.push("");
|
||||||
|
lines.push("К получению:");
|
||||||
|
if (confirmedBalances.length > 0) {
|
||||||
|
lines.push(...confirmedBalances.slice(0, 10).map((item, index) => `${index + 1}. ${item.name} — ${formatMoneyRub(item.outstandingAmount)} (${formatNumberWithDots(item.operations)} опер.).`));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lines.push("- Подтвержденной открытой дебиторской задолженности на дату среза не найдено.");
|
lines.push("- Подтвержденной открытой дебиторской задолженности на дату среза не найдено.");
|
||||||
}
|
}
|
||||||
|
appendDebtMirrorDisclosure(lines, balanceSnapshot, "receivables");
|
||||||
return {
|
return {
|
||||||
responseType: confirmedBalances.length > 0 ? "FACTUAL_LIST" : "FACTUAL_SUMMARY",
|
responseType: confirmedBalances.length > 0 ? "FACTUAL_LIST" : "FACTUAL_SUMMARY",
|
||||||
text: joinLines(lines),
|
text: joinLines(lines),
|
||||||
|
|
|
||||||
|
|
@ -403,9 +403,9 @@ function businessOverviewCoverageLimitLine(overview) {
|
||||||
if (outgoing?.coverage_limited_by_probe_limit === true) {
|
if (outgoing?.coverage_limited_by_probe_limit === true) {
|
||||||
limited.push("исходящие");
|
limited.push("исходящие");
|
||||||
}
|
}
|
||||||
const continuation = "Если нужен полный сквозной ответ, безопасный следующий шаг — выбрать конкретный год или квартал для дозапроса: тогда широкий срез можно собрать частями без выдачи непроверенного итога.";
|
const continuation = "Для полного сквозного итога лучше разбить проверку по годам или кварталам.";
|
||||||
return limited.length > 0
|
return limited.length > 0
|
||||||
? `Важно: по направлению ${limited.join(" и ")} проверка достигла лимита строк; это расширенный проверенный срез найденных строк, но не гарантия полного бухгалтерского оборота без отдельной полной выгрузки. ${continuation}`
|
? `Ограничение: широкий денежный срез по направлению ${limited.join(" и ")} не считаю полным бухгалтерским оборотом без отдельной полной выгрузки. ${continuation}`
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
function joinBusinessReplyLines(lines) {
|
function joinBusinessReplyLines(lines) {
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,8 @@ function loadCapabilitiesRegistry() {
|
||||||
}
|
}
|
||||||
function buildCapabilityContractReplyFromRegistry() {
|
function buildCapabilityContractReplyFromRegistry() {
|
||||||
return [
|
return [
|
||||||
"Могу быстро смотреть управленческие вещи по данным 1С в режиме чтения:",
|
"Могу быстро смотреть управленческие вещи по данным 1С в режиме чтения.",
|
||||||
|
"",
|
||||||
"- кто должен денег и кому должны;",
|
"- кто должен денег и кому должны;",
|
||||||
"- какой год или месяц был самым денежным;",
|
"- какой год или месяц был самым денежным;",
|
||||||
"- какие контрагенты дают основной поток;",
|
"- какие контрагенты дают основной поток;",
|
||||||
|
|
@ -213,6 +214,7 @@ function buildCapabilityContractReplyFromRegistry() {
|
||||||
"- кому мы должны на сегодня",
|
"- кому мы должны на сегодня",
|
||||||
"- какое нетто по СВК за 2020",
|
"- какое нетто по СВК за 2020",
|
||||||
"- сколько НДС к уплате за 4 квартал 2019",
|
"- сколько НДС к уплате за 4 квартал 2019",
|
||||||
|
"",
|
||||||
"Что не делаю: не настраиваю 1С, не меняю конфигурацию, не создаю и не провожу документы, не выполняю админ-действия на сервере."
|
"Что не делаю: не настраиваю 1С, не меняю конфигурацию, не создаю и не провожу документы, не выполняю админ-действия на сервере."
|
||||||
].join("\n");
|
].join("\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4326,7 +4326,6 @@ function composeFactualReplyBody(
|
||||||
},
|
},
|
||||||
{ supplier_or_contractor: 0, bank_or_credit: 0, tax_or_state: 0, other: 0 }
|
{ supplier_or_contractor: 0, bank_or_credit: 0, tax_or_state: 0, other: 0 }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isDirectBalanceQuestion(options.userMessage)) {
|
if (isDirectBalanceQuestion(options.userMessage)) {
|
||||||
const leading = confirmedBalances[0] ?? null;
|
const leading = confirmedBalances[0] ?? null;
|
||||||
const compactLines: string[] = leading
|
const compactLines: string[] = leading
|
||||||
|
|
@ -4472,49 +4471,31 @@ function composeFactualReplyBody(
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines: string[] = [
|
const lines: string[] = [
|
||||||
`Коротко: подтвержденная дебиторская задолженность на ${formatDateRu(receivablesAsOfDate)} — ${formatMoneyRub(totalOutstandingAmount)}.`,
|
`Коротко: на ${formatDateRu(receivablesAsOfDate)} нам должны ${formatMoneyRub(totalOutstandingAmount)}.`
|
||||||
"Это подтвержденный срез дебиторской задолженности, а не эвристический shortlist."
|
|
||||||
];
|
];
|
||||||
|
if (periodScopeLine || carryoverLine) {
|
||||||
lines.push("");
|
lines.push("");
|
||||||
lines.push("Что учтено");
|
lines.push("Граница ответа:");
|
||||||
lines.push(`- Дата среза: ${formatDateRu(receivablesAsOfDate)}.`);
|
|
||||||
if (periodScopeLine) {
|
if (periodScopeLine) {
|
||||||
lines.push(periodScopeLine);
|
lines.push(periodScopeLine);
|
||||||
}
|
}
|
||||||
lines.push("- Контур: дебиторская задолженность по счетам 62/76.");
|
|
||||||
if (carryoverLine) {
|
if (carryoverLine) {
|
||||||
lines.push(carryoverLine);
|
lines.push(carryoverLine);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lines.push("");
|
lines.push("");
|
||||||
lines.push("Сводка");
|
lines.push("К получению:");
|
||||||
lines.push(`- Строк в выборке: ${formatNumberWithDots(rows.length)}.`);
|
|
||||||
lines.push(`- Контрагентов с подтвержденным остатком к получению: ${formatNumberWithDots(confirmedBalances.length)}.`);
|
|
||||||
appendDebtMirrorDisclosure(lines, balanceSnapshot, "receivables");
|
|
||||||
|
|
||||||
lines.push("");
|
|
||||||
lines.push("Категории дебиторской задолженности");
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("supplier_or_contractor")}: ${formatNumberWithDots(categoryCounts.supplier_or_contractor)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("bank_or_credit")}: ${formatNumberWithDots(categoryCounts.bank_or_credit)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("tax_or_state")}: ${formatNumberWithDots(categoryCounts.tax_or_state)}.`);
|
|
||||||
lines.push(`- ${receivablesCategoryLabel("other")}: ${formatNumberWithDots(categoryCounts.other)}.`);
|
|
||||||
|
|
||||||
lines.push("");
|
|
||||||
lines.push("Подтвержденные позиции к получению");
|
|
||||||
if (confirmedBalances.length > 0) {
|
if (confirmedBalances.length > 0) {
|
||||||
lines.push(
|
lines.push(
|
||||||
...confirmedBalances.slice(0, 10).flatMap((item, index) => [
|
...confirmedBalances.slice(0, 10).map(
|
||||||
`${index + 1}. ${item.name} | категория: ${receivablesCategoryLabel(item.category)} | остаток к получению: ${formatMoneyRub(item.outstandingAmount)} | операций: ${formatNumberWithDots(item.operations)}${item.categoryReasons.length > 0 ? ` | основание: ${item.categoryReasons.join(", ")}` : ""}${formatPayablesEvidenceSuffix(item)}`,
|
(item, index) => `${index + 1}. ${item.name} — ${formatMoneyRub(item.outstandingAmount)} (${formatNumberWithDots(item.operations)} опер.).`
|
||||||
""
|
)
|
||||||
])
|
|
||||||
);
|
);
|
||||||
if (lines[lines.length - 1] === "") {
|
|
||||||
lines.pop();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
lines.push("- Подтвержденной открытой дебиторской задолженности на дату среза не найдено.");
|
lines.push("- Подтвержденной открытой дебиторской задолженности на дату среза не найдено.");
|
||||||
}
|
}
|
||||||
|
appendDebtMirrorDisclosure(lines, balanceSnapshot, "receivables");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
responseType: confirmedBalances.length > 0 ? "FACTUAL_LIST" : "FACTUAL_SUMMARY",
|
responseType: confirmedBalances.length > 0 ? "FACTUAL_LIST" : "FACTUAL_SUMMARY",
|
||||||
|
|
|
||||||
|
|
@ -472,9 +472,9 @@ function businessOverviewCoverageLimitLine(overview: Record<string, unknown>): s
|
||||||
limited.push("исходящие");
|
limited.push("исходящие");
|
||||||
}
|
}
|
||||||
const continuation =
|
const continuation =
|
||||||
"Если нужен полный сквозной ответ, безопасный следующий шаг — выбрать конкретный год или квартал для дозапроса: тогда широкий срез можно собрать частями без выдачи непроверенного итога.";
|
"Для полного сквозного итога лучше разбить проверку по годам или кварталам.";
|
||||||
return limited.length > 0
|
return limited.length > 0
|
||||||
? `Важно: по направлению ${limited.join(" и ")} проверка достигла лимита строк; это расширенный проверенный срез найденных строк, но не гарантия полного бухгалтерского оборота без отдельной полной выгрузки. ${continuation}`
|
? `Ограничение: широкий денежный срез по направлению ${limited.join(" и ")} не считаю полным бухгалтерским оборотом без отдельной полной выгрузки. ${continuation}`
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,8 @@ export function loadCapabilitiesRegistry(): CapabilityRegistry {
|
||||||
|
|
||||||
export function buildCapabilityContractReplyFromRegistry(): string {
|
export function buildCapabilityContractReplyFromRegistry(): string {
|
||||||
return [
|
return [
|
||||||
"Могу быстро смотреть управленческие вещи по данным 1С в режиме чтения:",
|
"Могу быстро смотреть управленческие вещи по данным 1С в режиме чтения.",
|
||||||
|
"",
|
||||||
"- кто должен денег и кому должны;",
|
"- кто должен денег и кому должны;",
|
||||||
"- какой год или месяц был самым денежным;",
|
"- какой год или месяц был самым денежным;",
|
||||||
"- какие контрагенты дают основной поток;",
|
"- какие контрагенты дают основной поток;",
|
||||||
|
|
@ -234,6 +235,7 @@ export function buildCapabilityContractReplyFromRegistry(): string {
|
||||||
"- кому мы должны на сегодня",
|
"- кому мы должны на сегодня",
|
||||||
"- какое нетто по СВК за 2020",
|
"- какое нетто по СВК за 2020",
|
||||||
"- сколько НДС к уплате за 4 квартал 2019",
|
"- сколько НДС к уплате за 4 квартал 2019",
|
||||||
|
"",
|
||||||
"Что не делаю: не настраиваю 1С, не меняю конфигурацию, не создаю и не провожу документы, не выполняю админ-действия на сервере."
|
"Что не делаю: не настраиваю 1С, не меняю конфигурацию, не создаю и не провожу документы, не выполняю админ-действия на сервере."
|
||||||
].join("\n");
|
].join("\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -796,12 +796,11 @@ describe("address compose stage utf8 headers", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(reply.responseType).toBe("FACTUAL_LIST");
|
expect(reply.responseType).toBe("FACTUAL_LIST");
|
||||||
expect(reply.text).toContain("Коротко: подтвержденная дебиторская задолженность на 31.05.2020");
|
expect(reply.text).toContain("Коротко: на 31.05.2020 нам должны");
|
||||||
expect(reply.text).toContain("Это подтвержденный срез дебиторской задолженности");
|
expect(reply.text).toContain("К получению:");
|
||||||
expect(reply.text).toContain("Что учтено");
|
expect(reply.text).not.toContain("эвристический shortlist");
|
||||||
expect(reply.text).toContain("Сводка");
|
expect(reply.text).not.toContain("Строк в выборке");
|
||||||
expect(reply.text).toContain("Категории дебиторской задолженности");
|
expect(reply.text).not.toContain("Категории дебиторской задолженности");
|
||||||
expect(reply.text).toContain("Подтвержденные позиции к получению");
|
|
||||||
expect(reply.text).not.toContain("Блок 1");
|
expect(reply.text).not.toContain("Блок 1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,11 @@ 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).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).toContain("без выдачи непроверенного итога");
|
|
||||||
expect(candidate.reply_text).not.toContain("По расчетному операционному нетто лучший год");
|
expect(candidate.reply_text).not.toContain("По расчетному операционному нетто лучший год");
|
||||||
expect(candidate.reply_text).not.toContain("По годам:");
|
expect(candidate.reply_text).not.toContain("По годам:");
|
||||||
|
expect(candidate.reply_text).not.toContain("проверка достигла лимита строк");
|
||||||
expect(candidate.reply_text).not.toContain("лимит выборки MCP");
|
expect(candidate.reply_text).not.toContain("лимит выборки MCP");
|
||||||
expect(candidate.reply_text).not.toContain("MCP-срез");
|
expect(candidate.reply_text).not.toContain("MCP-срез");
|
||||||
expect(candidate.reply_text).not.toContain("Что подтверждено:");
|
expect(candidate.reply_text).not.toContain("Что подтверждено:");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue