ДОМЕНЫ - ВОПРОСЫ - Исправить обработку коротких debt follow-up и защиту от диагностических LLM rewrite
This commit is contained in:
@@ -1990,7 +1990,7 @@ function textMojibakeScoreForAddress(value) {
|
||||
const source = String(value ?? "");
|
||||
const cyrillic = (source.match(/[А-Яа-яЁё]/g) ?? []).length;
|
||||
const latin = (source.match(/[A-Za-z]/g) ?? []).length;
|
||||
const hardMarkers = (source.match(/[Ѓѓ‚„…†‡€‰‹ЉЊЌЋЏ‘’“”•–—™љ›њќћџ]/g) ?? []).length;
|
||||
const hardMarkers = (source.match(/[Ѓѓ‚„…†‡€‰‹ЉЊЌЋЏ�?’“”•–—™љ›њќћџ]/g) ?? []).length;
|
||||
const pairMarkers = (source.match(/(?:Р.|С.|Ð.|Ñ.)/g) ?? []).length;
|
||||
const doubleEncodedMarkers = (source.match(/(?:Г[Ђ-џ]|В[Ђ-џ]|Ã.|Â.)/gu) ?? []).length;
|
||||
return cyrillic + latin - hardMarkers * 3 - pairMarkers * 2 - doubleEncodedMarkers * 2;
|
||||
@@ -2000,7 +2000,7 @@ function looksLikeMojibakeForAddress(value) {
|
||||
if (!source.trim()) {
|
||||
return false;
|
||||
}
|
||||
if (/[Ѓѓ‚„…†‡€‰‹ЉЊЌЋЏ‘’“”•–—™љ›њќћџ]/.test(source)) {
|
||||
if (/[Ѓѓ‚„…†‡€‰‹ЉЊЌЋЏ�?’“”•–—™љ›њќћџ]/.test(source)) {
|
||||
return true;
|
||||
}
|
||||
if ((source.match(/(?:Р.|С.|Ð.|Ñ.)/g) ?? []).length >= 2) {
|
||||
@@ -2205,7 +2205,7 @@ function normalizeCounterpartyForFollowupMatch(value) {
|
||||
return compactWhitespace(repairAddressMojibake(String(value ?? ""))
|
||||
.toLowerCase()
|
||||
.replace(/ё/g, "е")
|
||||
.replace(/[«»"'`“”„’‘]/g, " ")
|
||||
.replace(/[«»"'`“”„’�?]/g, " ")
|
||||
.replace(/[^a-zа-я0-9\s._-]+/giu, " "));
|
||||
}
|
||||
function normalizeCounterpartyTokenForFollowupMatch(value) {
|
||||
@@ -2251,7 +2251,7 @@ function extractDisplayedAddressEntityCandidates(replyText, entityType = "unknow
|
||||
if (parts.length >= 2 && /^\d{4}-\d{2}-\d{2}/.test(parts[0] ?? "")) {
|
||||
counterpartyCandidate = parts[1] ?? counterpartyCandidate;
|
||||
}
|
||||
const cleanedCandidate = compactWhitespace(counterpartyCandidate.replace(/^["'«»“”„`’‘]+|["'«»“”„`’‘]+$/gu, ""));
|
||||
const cleanedCandidate = compactWhitespace(counterpartyCandidate.replace(/^["'«»“”„`’�?]+|["'«»“”„`’�?]+$/gu, ""));
|
||||
if (!cleanedCandidate || cleanedCandidate.length < 2) {
|
||||
continue;
|
||||
}
|
||||
@@ -2515,61 +2515,133 @@ function isImplicitAddressContinuationByLlm(userMessage, llmPreDecomposeMeta) {
|
||||
return tokenCount > 0 && tokenCount <= 4;
|
||||
}
|
||||
function hasAddressFollowupContextSignal(userMessage) {
|
||||
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
|
||||
const repaired = repairAddressMojibake(String(userMessage ?? ""));
|
||||
const text = compactWhitespace(repaired.toLowerCase());
|
||||
if (!text) {
|
||||
const repairedText = compactWhitespace(repaired.toLowerCase());
|
||||
const samples = [rawText, repairedText].filter((item) => item.length > 0);
|
||||
if (samples.length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (hasStandaloneAddressTopicSignal(text)) {
|
||||
const hasAny = (pattern) => samples.some((sample) => pattern.test(sample));
|
||||
const hasMarker = () => samples.some((sample) => hasFollowupMarker(sample));
|
||||
const hasPointer = () => samples.some((sample) => hasReferentialPointer(sample));
|
||||
const minTokens = samples.reduce((min, sample) => Math.min(min, countTokens(sample)), Number.POSITIVE_INFINITY);
|
||||
const shortFollowup = minTokens <= 8;
|
||||
const ultraShortFollowup = minTokens <= 3;
|
||||
const debtRoleSwapToReceivables = shortFollowup &&
|
||||
(/^(?:\u0430|a|\u0438|i)\s+(?:\u043d\u0430\u043c\s+)?\u043a\u0442\u043e(?=$|[\s,.;:!?])/iu.test(rawText) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рЅр°рј\s+)?рєс‚рѕ(?=$|[\s,.;:!?])/iu.test(rawText));
|
||||
if (debtRoleSwapToReceivables) {
|
||||
return true;
|
||||
}
|
||||
const debtRoleSwapToPayables = shortFollowup &&
|
||||
(/^(?:\u0430|a|\u0438|i)\s+(?:\u043c\u044b\s+)?\u043a\u043e\u043c\u0443(?=$|[\s,.;:!?])/iu.test(rawText) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рјс‹\s+)?рєрѕрјсѓ(?=$|[\s,.;:!?])/iu.test(rawText));
|
||||
if (debtRoleSwapToPayables) {
|
||||
return true;
|
||||
}
|
||||
const shortContinuationCue = ultraShortFollowup &&
|
||||
(/^(?:\u0434\u0430\u0432\u0430\u0439|\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0439|\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u044b\u0430\u0439|\u0435\u0449[\u0435\u0451]|also|again|go|ok|okay)(?=$|[\s,.;:!?])/iu.test(rawText) ||
|
||||
/^(?:рґр°рір°р№|рїрѕрєр°р·с‹рір°р№|рїрѕрєр°р·с‹ріс‹р°р№|рµс‰[рµс‘]|also|again|go|ok|okay)(?=$|[\s,.;:!?])/iu.test(rawText));
|
||||
if (shortContinuationCue) {
|
||||
return true;
|
||||
}
|
||||
const shortVatCue = ultraShortFollowup &&
|
||||
/^(?:(?:\u0430|\u0438)\s+)?(?:(?:\u043f\u043e|po)\s+)?(?:\u043d\u0434\u0441|vat)(?=$|[\s,.;:!?])/iu.test(rawText);
|
||||
if (shortVatCue) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && hasAny(/^(?:а|a|и|i)\s+(?:нам\s+)?кто(?=$|[\s,.;:!?])/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && hasAny(/^(?:а|a|и|i)\s+(?:мы\s+)?кому(?=$|[\s,.;:!?])/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (ultraShortFollowup && hasAny(/^(?:давай|показывай|показывыай|ещ[её]|also|again|go|ok|okay)(?=$|[\s,.;:!?])/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (hasStandaloneAddressTopicSignal(rawText || repairedText)) {
|
||||
return false;
|
||||
}
|
||||
if (shouldHandleAsAssistantCapabilityMetaQuery(text)) {
|
||||
if (shouldHandleAsAssistantCapabilityMetaQuery(rawText || repairedText)) {
|
||||
return false;
|
||||
}
|
||||
if (/(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+всю\s+истори(?:ю|и)|за\s+любой\s+период|for\s+all\s+time|all\s+time|for\s+entire\s+period|entire\s+period|for\s+any\s+period|any\s+period)/iu.test(text)) {
|
||||
if (hasAny(/(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+всю\s+истори(?:ю|и)|за\s+любой\s+период|for\s+all\s+time|all\s+time|for\s+entire\s+period|entire\s+period|for\s+any\s+period|any\s+period)/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (hasReferentialPointer(text)) {
|
||||
if (hasPointer()) {
|
||||
return true;
|
||||
}
|
||||
if (/(?:на\s+ту\s+же\s+дат[ауеы]|на\s+эту\s+же\s+дат[ауеы]|same\s+date|the\s+same\s+date|as\s+of\s+same\s+date)/iu.test(text)) {
|
||||
if (hasAny(/(?:на\s+ту\s+же\s+дат[ауеы]|на\s+эту\s+же\s+дат[ауеы]|same\s+date|the\s+same\s+date|as\s+of\s+same\s+date)/iu)) {
|
||||
return true;
|
||||
}
|
||||
const shortFollowup = countTokens(text) <= 8;
|
||||
if (/(?:кроме|помимо)\s+(?:этого|этой|этот|эту|этих|этого\s+документа|этого\s+договора|этого\s+контрагента)/iu.test(text)) {
|
||||
if (hasAny(/(?:кроме|помимо)\s+(?:этого|этой|этот|эту|этих|этого\s+документа|этого\s+договора|этого\s+контрагента)/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (/(?:есть\s+ещ[её]|что\s+ещ[её]|ещ[её]\s+что|ещ[её]\s+что-?то|остал(?:ось|ось\?)|друг(?:ое|ие))/iu.test(text) && countTokens(text) <= 12) {
|
||||
if (hasAny(/(?:есть\s+ещ[её]|что\s+ещ[её]|ещ[её]\s+что|ещ[её]\s+что-?то|остал(?:ось|ось\?)|друг(?:ое|ие))/iu) && minTokens <= 12) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && hasFollowupMarker(text)) {
|
||||
if (shortFollowup && hasMarker()) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && /(?:^|\s)(?:также|тоже|also|same|again|ещ[её]|теперь|then|now)(?=$|[\s,.;:!?])/iu.test(text)) {
|
||||
if (shortFollowup && hasAny(/(?:^|\s)(?:также|тоже|also|same|again|ещ[её]|теперь|then|now)(?=$|[\s,.;:!?])/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && hasAny(/(?:кто\s+из\s+(?:них|этих|тех)|кто\s+нов(?:ые|ых|ый)|кто\s+потом\s+исчез|кто\s+был\s+(?:только|ровно)\s+один\s+раз)/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup &&
|
||||
/(?:кто\s+из\s+(?:них|этих|тех)|кто\s+нов(?:ые|ых|ый)|кто\s+потом\s+исчез|кто\s+был\s+(?:только|ровно)\s+один\s+раз)/iu.test(text)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && /^(?:а|и)\s+кто\b/iu.test(text)) {
|
||||
hasAny(/(?:почему|why|из[-\s]?за\s+чего|как\s+так|reason)/iu) &&
|
||||
hasAny(/(?:ндс|vat|прогноз|к\s+уплате|нул|ноль|\b0(?:[.,]0+)?\b)/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup &&
|
||||
/(?:почему|why|из[-\s]?за\s+чего|как\s+так|reason)/iu.test(text) &&
|
||||
/(?:ндс|vat|прогноз|к\s+уплате|нул|ноль|\b0(?:[.,]0+)?\b)/iu.test(text)) {
|
||||
hasAny(/(?:^|\s)по\s+[a-zа-яё][a-zа-яё0-9._-]{1,}(?=$|[\s,.;:!?])/iu) &&
|
||||
!hasAny(/(?:по\s+этому|по\s+тому|по\s+нему|по\s+ней|по\s+ним)/iu)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup &&
|
||||
/(?:^|\s)по\s+[a-zа-яё][a-zа-яё0-9._-]{1,}(?=$|[\s,.;:!?])/iu.test(text) &&
|
||||
!/(?:по\s+этому|по\s+тому|по\s+нему|по\s+ней|по\s+ним)/iu.test(text)) {
|
||||
return true;
|
||||
}
|
||||
if (shortFollowup && hasPeriodLiteral(text)) {
|
||||
if (shortFollowup && samples.some((sample) => hasPeriodLiteral(sample))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function hasShortDebtMirrorFollowupSignal(userMessage) {
|
||||
const rawText = compactWhitespace(String(userMessage ?? "").toLowerCase());
|
||||
const repairedText = compactWhitespace(repairAddressMojibake(String(userMessage ?? "")).toLowerCase());
|
||||
const samples = [rawText, repairedText].filter((item) => item.length > 0);
|
||||
if (samples.length === 0) {
|
||||
return false;
|
||||
}
|
||||
const minTokens = samples.reduce((min, sample) => Math.min(min, countTokens(sample)), Number.POSITIVE_INFINITY);
|
||||
if (minTokens > 8) {
|
||||
return false;
|
||||
}
|
||||
return samples.some((sample) => /^(?:а|a|и|i)\s+(?:нам\s+)?кто(?=$|[\s,.;:!?])/iu.test(sample) ||
|
||||
/^(?:а|a|и|i)\s+(?:мы\s+)?кому(?=$|[\s,.;:!?])/iu.test(sample) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рЅр°рј\s+)?рєс‚рѕ(?=$|[\s,.;:!?])/iu.test(sample) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рјс‹\s+)?рєрѕрјсѓ(?=$|[\s,.;:!?])/iu.test(sample));
|
||||
}
|
||||
function resolveDebtRoleSwapFollowupIntent(userMessage, previousIntent) {
|
||||
const normalized = compactWhitespace(String(userMessage ?? "").toLowerCase());
|
||||
if (!normalized || countTokens(normalized) > 10) {
|
||||
return null;
|
||||
}
|
||||
const hasReceivablesCue = /(?:нам\s+кто\s+долж|кто\s+нам\s+долж|кто\s+долж[а-яё]*\s+нам|дебитор|к\s+получению|к\s+взысканию|receivable)/iu.test(normalized) ||
|
||||
/^(?:а|a|и|i)\s+(?:нам\s+)?кто(?=$|[\s,.;:!?])/iu.test(normalized) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рЅр°рј\s+)?рєс‚рѕ(?=$|[\s,.;:!?])/iu.test(normalized);
|
||||
const hasPayablesCue = /(?:мы\s+кому\s+долж|кому\s+мы\s+долж|кому\s+долж[а-яё]*\s+мы|кредитор|к\s+уплате|payable)/iu.test(normalized) ||
|
||||
/^(?:а|a|и|i)\s+(?:мы\s+)?кому(?=$|[\s,.;:!?])/iu.test(normalized) ||
|
||||
/^(?:р°|a|рё|i)\s+(?:рјс‹\s+)?рєрѕрјсѓ(?=$|[\s,.;:!?])/iu.test(normalized);
|
||||
if ((previousIntent === "payables_confirmed_as_of_date" || previousIntent === "list_payables_counterparties") &&
|
||||
hasReceivablesCue) {
|
||||
return "receivables_confirmed_as_of_date";
|
||||
}
|
||||
if ((previousIntent === "receivables_confirmed_as_of_date" || previousIntent === "list_receivables_counterparties") &&
|
||||
hasPayablesCue) {
|
||||
return "payables_confirmed_as_of_date";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMessage = null, llmPreDecomposeMeta = null) {
|
||||
const previousAddressItem = findLastAddressAssistantItem(items);
|
||||
const previousAddressDebug = previousAddressItem?.debug ?? null;
|
||||
@@ -2578,9 +2650,15 @@ function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMes
|
||||
Boolean(followupOffer?.enabled) &&
|
||||
(isImplicitAddressContinuationByLlm(userMessage, llmPreDecomposeMeta) ||
|
||||
(toNonEmptyString(alternateMessage) ? isImplicitAddressContinuationByLlm(alternateMessage, llmPreDecomposeMeta) : false));
|
||||
const hasPrimaryFollowupSignal = hasAddressFollowupContextSignal(userMessage);
|
||||
const sourceIntentHint = toNonEmptyString(previousAddressDebug?.detected_intent);
|
||||
const debtRoleSwapPrimary = sourceIntentHint ? resolveDebtRoleSwapFollowupIntent(userMessage, sourceIntentHint) : null;
|
||||
const debtRoleSwapAlternate = sourceIntentHint && toNonEmptyString(alternateMessage)
|
||||
? resolveDebtRoleSwapFollowupIntent(String(alternateMessage ?? ""), sourceIntentHint)
|
||||
: null;
|
||||
const debtRoleSwapIntent = debtRoleSwapPrimary ?? debtRoleSwapAlternate ?? null;
|
||||
const hasPrimaryFollowupSignal = hasAddressFollowupContextSignal(userMessage) || Boolean(debtRoleSwapPrimary);
|
||||
const hasAlternateFollowupSignal = toNonEmptyString(alternateMessage)
|
||||
? hasAddressFollowupContextSignal(alternateMessage)
|
||||
? hasAddressFollowupContextSignal(alternateMessage) || Boolean(debtRoleSwapAlternate)
|
||||
: false;
|
||||
const hasPrimaryIndexReferenceSignal = extractDisplayedEntityIndexMention(userMessage) !== null;
|
||||
const hasAlternateIndexReferenceSignal = toNonEmptyString(alternateMessage)
|
||||
@@ -2589,7 +2667,11 @@ function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMes
|
||||
const hasIndexReferenceSignal = hasPrimaryIndexReferenceSignal || hasAlternateIndexReferenceSignal;
|
||||
const hasStandaloneAddressTopic = hasStandaloneAddressTopicSignal(userMessage) ||
|
||||
(toNonEmptyString(alternateMessage) ? hasStandaloneAddressTopicSignal(alternateMessage) : false);
|
||||
if (hasStandaloneAddressTopic && !hasImplicitContinuationSignal && !hasIndexReferenceSignal) {
|
||||
if (hasStandaloneAddressTopic &&
|
||||
!hasPrimaryFollowupSignal &&
|
||||
!hasAlternateFollowupSignal &&
|
||||
!hasImplicitContinuationSignal &&
|
||||
!hasIndexReferenceSignal) {
|
||||
return null;
|
||||
}
|
||||
if (!hasPrimaryFollowupSignal && !hasAlternateFollowupSignal && !hasImplicitContinuationSignal && !hasIndexReferenceSignal) {
|
||||
@@ -2601,6 +2683,9 @@ function resolveAddressFollowupCarryoverContext(userMessage, items, alternateMes
|
||||
const sourceIntent = toNonEmptyString(previousAddressDebug.detected_intent);
|
||||
let previousIntent = sourceIntent;
|
||||
let followupSelectionMode = "carry_previous_intent";
|
||||
if (debtRoleSwapIntent) {
|
||||
previousIntent = debtRoleSwapIntent;
|
||||
}
|
||||
if (hasImplicitContinuationSignal) {
|
||||
const suggestedIntent = Array.isArray(followupOffer?.suggested_intents)
|
||||
? toNonEmptyString(followupOffer.suggested_intents[0])
|
||||
@@ -3106,6 +3191,13 @@ function hasSameDateAccountFollowupSignalForPredecompose(text) {
|
||||
/(?:^|\s)по\s+\d{2}(?:[.,]\d{1,2})?(?=$|[\s,.;:!?])/iu.test(source) ||
|
||||
/\b\d{2}(?:[.,]\d{1,2})\b/u.test(source));
|
||||
}
|
||||
function hasPredecomposeDiagnosticUncertaintyLead(text) {
|
||||
const normalized = compactWhitespace(repairAddressMojibake(String(text ?? "")).toLowerCase());
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
return /^(?:неясно|не\s+ясно|непонятно|не\s+понятно|unclear|not\s+clear|ambiguous|unknown)(?=$|[\s,.;:!?])/iu.test(normalized);
|
||||
}
|
||||
function attachAddressPredecomposeContract(meta, sourceMessage) {
|
||||
const canonicalMessage = toNonEmptyString(meta?.effectiveMessage) ?? String(sourceMessage ?? "");
|
||||
const predecomposeContract = (0, predecomposeContract_1.buildAddressLlmPredecomposeContractV1)({
|
||||
@@ -3207,6 +3299,20 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
|
||||
const candidateIntentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(candidate);
|
||||
const sourceIntentKnown = sourceIntentResolution.intent !== "unknown";
|
||||
const candidateIntentKnown = candidateIntentResolution.intent !== "unknown";
|
||||
const candidateStartsWithDiagnosticUncertainty = hasPredecomposeDiagnosticUncertaintyLead(candidate);
|
||||
if (candidateStartsWithDiagnosticUncertainty && sourceIntentKnown) {
|
||||
return attachAddressPredecomposeContract({
|
||||
...baseMeta,
|
||||
attempted: true,
|
||||
applied: false,
|
||||
traceId: normalized?.trace_id ?? null,
|
||||
llmCanonicalCandidateDetected: true,
|
||||
effectiveMessage: userMessage,
|
||||
reason: "normalized_fragment_rejected_diagnostic_rewrite",
|
||||
fallbackRuleHit: null,
|
||||
sanitizedUserMessage
|
||||
}, userMessage);
|
||||
}
|
||||
const intentConflict = sourceIntentKnown &&
|
||||
candidateIntentKnown &&
|
||||
sourceIntentResolution.intent !== candidateIntentResolution.intent;
|
||||
@@ -3473,6 +3579,8 @@ function resolveAddressToolGateDecision(addressInputMessage, followupContext, ll
|
||||
isAddressLlmPreDecomposeCandidate(repairedInputMessage) ||
|
||||
hasAccountingSignal(addressInputMessage) ||
|
||||
hasAccountingSignal(repairedInputMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(rawMessageForGate) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedInputMessage) ||
|
||||
sameDateAccountFollowupSignal;
|
||||
const hasUnsupportedLowConfidencePredecomposeSignal = llmContractMode === "unsupported" &&
|
||||
(llmContractModeConfidence === "low" || llmContractModeConfidence === "medium") &&
|
||||
@@ -3491,6 +3599,7 @@ function resolveAddressToolGateDecision(addressInputMessage, followupContext, ll
|
||||
!followupContext &&
|
||||
!hasClassifierSignal &&
|
||||
!hasIntentSignal &&
|
||||
!hasLexicalAddressSignal &&
|
||||
!strongDataSignalFromRawMessage &&
|
||||
!strongDataSignalFromEffectiveMessage) {
|
||||
return {
|
||||
@@ -3683,7 +3792,8 @@ const ADDRESS_INTENTS_KEEP_ADDRESS_LANE = new Set([
|
||||
"list_contracts_by_counterparty",
|
||||
"contract_usage_overview",
|
||||
"contract_usage_and_value",
|
||||
"vat_payable_forecast"
|
||||
"vat_payable_forecast",
|
||||
"vat_payable_confirmed_as_of_date"
|
||||
]);
|
||||
export function resolveAssistantOrchestrationDecision(input) {
|
||||
const rawUserMessage = String(input?.rawUserMessage ?? input?.userMessage ?? "");
|
||||
@@ -3764,7 +3874,11 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
const explicitAddressFollowupSignal = hasAddressFollowupContextSignal(rawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedRawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(effectiveAddressUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage);
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(rawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage);
|
||||
const effectiveAddressFollowupSignal = explicitAddressFollowupSignal && !dangerOrCoercionSignal;
|
||||
const deterministicNonDomainGuard = Boolean(!dataScopeMetaQuery &&
|
||||
!capabilityMetaQuery &&
|
||||
@@ -3879,7 +3993,11 @@ export function resolveAssistantOrchestrationDecision(input) {
|
||||
hasAddressFollowupContextSignal(rawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(effectiveAddressUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedRawUserMessage) ||
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage));
|
||||
hasAddressFollowupContextSignal(repairedEffectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(rawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(effectiveAddressUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) ||
|
||||
hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage));
|
||||
const supportedAddressIntentDetected = !strictDeepInvestigationCueDetected &&
|
||||
Boolean((intentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(intentResolution.intent)) ||
|
||||
(llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) ||
|
||||
@@ -4896,14 +5014,14 @@ async function resolveAssistantDataScopeProbe() {
|
||||
};
|
||||
}
|
||||
const catalogQueryCandidates = [
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 ПРЕДСТАВЛЕНИЕ(Организации.Ссылка) КАК Организация ИЗ Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 Организации.Наименование КАК Организация ИЗ Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 Организации.НаименованиеПолное КАК Организация ИЗ Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 100 Организации.Ссылка КАК Организация, ПРЕДСТАВЛЕНИЕ(Организации.Ссылка) КАК ОрганизацияПредставление ИЗ Справочник.Организации КАК Организации"
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 ПРЕДСТАВЛЕН�?Е(Организации.Ссылка) КАК Организация �?З Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 Организации.Наименование КАК Организация �?З Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 20 Организации.НаименованиеПолное КАК Организация �?З Справочник.Организации КАК Организации",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 100 Организации.Ссылка КАК Организация, ПРЕДСТАВЛЕН�?Е(Организации.Ссылка) КАК ОрганизацияПредставление �?З Справочник.Организации КАК Организации"
|
||||
];
|
||||
const movementProbeCandidates = [
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 60 Движения.Организация КАК Организация, ПРЕДСТАВЛЕНИЕ(Движения.Организация) КАК ОрганизацияПредставление ИЗ РегистрБухгалтерии.Хозрасчетный КАК Движения УПОРЯДОЧИТЬ ПО Движения.Период УБЫВ",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 60 Движения.Организация КАК Организация ИЗ РегистрБухгалтерии.Хозрасчетный КАК Движения"
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 60 Движения.Организация КАК Организация, ПРЕДСТАВЛЕН�?Е(Движения.Организация) КАК ОрганизацияПредставление �?З РегистрБухгалтерии.Хозрасчетный КАК Движения УПОРЯДОЧ�?ТЬ ПО Движения.Период УБЫВ",
|
||||
"ВЫБРАТЬ ПЕРВЫЕ 60 Движения.Организация КАК Организация �?З РегистрБухгалтерии.Хозрасчетный КАК Движения"
|
||||
];
|
||||
let lastError = null;
|
||||
const catalogFacts = { names: [], refs: [], pairs: [] };
|
||||
@@ -5034,7 +5152,7 @@ function buildAssistantOperationalBoundaryReply() {
|
||||
return [
|
||||
"Понимаю, что ситуация срочная.",
|
||||
"Я не могу сам настраивать 1С или менять базу/конфигурацию.",
|
||||
"Могу помочь безопасно: разберем симптомы и подготовим точные шаги для вашего 1С/ИТ-админа."
|
||||
"Могу помочь безопасно: разберем симптомы и подготовим точные шаги для вашего 1С/�?Т-админа."
|
||||
].join(" ");
|
||||
}
|
||||
function buildAssistantSafetyRefusalReply() {
|
||||
|
||||
Reference in New Issue
Block a user