Укрепить smoke для open-contracts и VAT acceptance

This commit is contained in:
dctouch 2026-05-24 12:40:27 +03:00
parent 08615aaa7c
commit cd8e98bd3f
4 changed files with 38 additions and 4 deletions

View File

@ -3842,7 +3842,7 @@ function hasDeepAnalysisPreferenceSignal(text) {
/(?:договор|контракт|документ|аванс|отгрузк)/iu.test(lower) &&
/(?:какие|какой|где|покажи|показать|список|проверь|проверить|уточни)/iu.test(lower) &&
!/(?:разложи|разложить|цепочк|механизм|почему|root\s*cause|trace\s*chain|корнев[а-я]*\s+причин)/iu.test(lower);
if (openContractsListQuestionSignal) {
if (openContractsListQuestionSignal || hasOpenContractsListQuestionSignal(lower)) {
return false;
}
const broadOverviewRiskSignal = /(?:\u0432\s+\u0446\u0435\u043b\u043e\u043c|\u043e\u0431\u0449\p{L}*\s+\u043a\u0430\u0440\u0442\u0438\u043d|\u0442\u043e\u043f\s+\u0440\u0438\u0441\u043a|\u0447\u0442\u043e\s+\u043d\u0435\s+\u0442\u0430\u043a)/iu.test(lower);
@ -3875,6 +3875,9 @@ function hasDirectDeepAnalysisSignal(text) {
if (!normalized) {
return false;
}
if (hasOpenContractsListQuestionSignal(normalized)) {
return false;
}
const fixedAssetAmortizationCompletenessSignal = /(?:\u0430\u043c\u043e\u0440\u0442\u0438\u0437|\u043e\u0441\u043d\u043e\u0432\u043d[\u0430-\u044f]*\s+\u0441\u0440\u0435\u0434\u0441\u0442\u0432|fixed\s*asset|depreciat|\b\u043e\u0441\b|\b0?1\s*[/\\]\s*0?2\b|\u0441\u0447[\u0435\u0451]\u0442[^\n]{0,16}\b0?1\b[^\n]{0,16}\b0?2\b)/iu.test(normalized) &&
/(?:\u043f\u043e\u043b\u043d[\u0430-\u044f]*|\u043f\u0440\u043e\u043f\u0443\u0449|\u043d\u0430\u0447\u0438\u0441\u043b|\u043f\u0440\u043e\u0432\u0435\u0440|\u043e\u0431\u044a\u0435\u043a\u0442|coverage|missing|expected|actual)/iu.test(normalized);
const deferredExpenseDeepSignal = /(?:\b97(?:[.,]\d{1,2})?\b|\u0440\u0431\u043f|\u0440\u0430\u0441\u0445\u043e\u0434[\u044b\u043e\u0432\s]+\u0431\u0443\u0434\u0443\u0449[\u0438\u0445\u0435]\s+\u043f\u0435\u0440\u0438\u043e\u0434|deferred)/iu.test(normalized) &&
@ -3919,6 +3922,9 @@ function hasOpenContractsAddressSignal(text) {
if (!normalized) {
return false;
}
if (hasOpenContractsListQuestionSignal(normalized)) {
return true;
}
const hasContractCue = /(?:договор|контракт|contract)/iu.test(normalized);
if (!hasContractCue) {
return false;
@ -3931,6 +3937,17 @@ function hasOpenContractsAddressSignal(text) {
const hasTemporalCue = hasPeriodLiteral(normalized) || /\b\d{4}[-/.]\d{2}[-/.]\d{2}\b/.test(normalized);
return hasRequestCue || hasTemporalCue;
}
function hasOpenContractsListQuestionSignal(text) {
const normalized = compactWhitespace(repairAddressMojibake(String(text ?? "")).toLowerCase());
if (!normalized) {
return false;
}
const hasSettlementCue = /(?:договор|контракт|contract|взаиморасч[её]т|расч[её]т|оплат|плат[её]ж|документ|аванс|отгруз)/iu.test(normalized);
const hasOpenGapCue = /(?:незакрыт|не\s+закрыт|открыт|без[^\n]{0,40}(?:закрыт|документ|оплат)|нет[^\n]{0,40}(?:документ|оплат|закрыт)|оплат[а-я]*[^\n]{0,80}без[^\n]{0,40}закрыт|плат[её]ж[а-я]*[^\n]{0,80}без[^\n]{0,40}закрыт|требует[^\n]{0,40}ручн[а-я]*\s+проверк)/iu.test(normalized);
const hasListCue = /(?:какие|какой|где|покажи|показать|список|shortlist|найди|проверь|проверить|что\s+надо\s+проверить)/iu.test(normalized);
const hasDeepDiagnosticCue = /(?:разложи|разложить|цепочк|механизм|почему|root\s*cause|trace\s*chain|корнев[а-я]*\s+причин|что\s+меша[а-я]+\s+закрыт)/iu.test(normalized);
return hasSettlementCue && hasOpenGapCue && hasListCue && !hasDeepDiagnosticCue;
}
function resolveAssistantOrchestrationDecision(input) {
return assistantRoutePolicy.resolveAssistantOrchestrationDecision(input);
}

View File

@ -3800,7 +3800,7 @@ function hasDeepAnalysisPreferenceSignal(text) {
/(?:договор|контракт|документ|аванс|отгрузк)/iu.test(lower) &&
/(?:какие|какой|где|покажи|показать|список|проверь|проверить|уточни)/iu.test(lower) &&
!/(?:разложи|разложить|цепочк|механизм|почему|root\s*cause|trace\s*chain|корнев[а-я]*\s+причин)/iu.test(lower);
if (openContractsListQuestionSignal) {
if (openContractsListQuestionSignal || hasOpenContractsListQuestionSignal(lower)) {
return false;
}
const broadOverviewRiskSignal =
@ -3834,6 +3834,9 @@ function hasDirectDeepAnalysisSignal(text) {
if (!normalized) {
return false;
}
if (hasOpenContractsListQuestionSignal(normalized)) {
return false;
}
const fixedAssetAmortizationCompletenessSignal =
/(?:\u0430\u043c\u043e\u0440\u0442\u0438\u0437|\u043e\u0441\u043d\u043e\u0432\u043d[\u0430-\u044f]*\s+\u0441\u0440\u0435\u0434\u0441\u0442\u0432|fixed\s*asset|depreciat|\b\u043e\u0441\b|\b0?1\s*[/\\]\s*0?2\b|\u0441\u0447[\u0435\u0451]\u0442[^\n]{0,16}\b0?1\b[^\n]{0,16}\b0?2\b)/iu.test(normalized) &&
/(?:\u043f\u043e\u043b\u043d[\u0430-\u044f]*|\u043f\u0440\u043e\u043f\u0443\u0449|\u043d\u0430\u0447\u0438\u0441\u043b|\u043f\u0440\u043e\u0432\u0435\u0440|\u043e\u0431\u044a\u0435\u043a\u0442|coverage|missing|expected|actual)/iu.test(normalized);
@ -3881,6 +3884,9 @@ function hasOpenContractsAddressSignal(text) {
if (!normalized) {
return false;
}
if (hasOpenContractsListQuestionSignal(normalized)) {
return true;
}
const hasContractCue = /(?:договор|контракт|contract)/iu.test(normalized);
if (!hasContractCue) {
return false;
@ -3893,6 +3899,17 @@ function hasOpenContractsAddressSignal(text) {
const hasTemporalCue = hasPeriodLiteral(normalized) || /\b\d{4}[-/.]\d{2}[-/.]\d{2}\b/.test(normalized);
return hasRequestCue || hasTemporalCue;
}
function hasOpenContractsListQuestionSignal(text) {
const normalized = compactWhitespace(repairAddressMojibake(String(text ?? "")).toLowerCase());
if (!normalized) {
return false;
}
const hasSettlementCue = /(?:договор|контракт|contract|взаиморасч[её]т|расч[её]т|оплат|плат[её]ж|документ|аванс|отгруз)/iu.test(normalized);
const hasOpenGapCue = /(?:незакрыт|не\s+закрыт|открыт|без[^\n]{0,40}(?:закрыт|документ|оплат)|нет[^\n]{0,40}(?:документ|оплат|закрыт)|оплат[а-я]*[^\n]{0,80}без[^\n]{0,40}закрыт|плат[её]ж[а-я]*[^\n]{0,80}без[^\n]{0,40}закрыт|требует[^\n]{0,40}ручн[а-я]*\s+проверк)/iu.test(normalized);
const hasListCue = /(?:какие|какой|где|покажи|показать|список|shortlist|найди|проверь|проверить|что\s+надо\s+проверить)/iu.test(normalized);
const hasDeepDiagnosticCue = /(?:разложи|разложить|цепочк|механизм|почему|root\s*cause|trace\s*chain|корнев[а-я]*\s+причин|что\s+меша[а-я]+\s+закрыт)/iu.test(normalized);
return hasSettlementCue && hasOpenGapCue && hasListCue && !hasDeepDiagnosticCue;
}
export function resolveAssistantOrchestrationDecision(input) {
return assistantRoutePolicy.resolveAssistantOrchestrationDecision(input);
}

View File

@ -3528,7 +3528,7 @@ describe("address filter extraction for balance drilldown", () => {
});
});
describe("address query limited taxonomy and stage diagnostics", { timeout: 15000 }, () => {
describe("address query limited taxonomy and stage diagnostics", { timeout: 90000 }, () => {
it("does not default standalone item provenance questions to today without explicit temporal cue", () => {
const result = extractAddressFilters(
"От какого поставщика куплен товар Столешница 600*3050*26 дуб ниагара",

View File

@ -86,5 +86,5 @@ describe("vat payable confirmed as-of route", () => {
expect(result?.debug.requested_result_mode).toBe("confirmed_balance");
expect(result?.debug.route_expectation_status).toBe("matched");
expect(result?.debug.limited_reason_category).not.toBe("unsupported");
}, 30000);
}, 90000);
});