NODEDC_1C/llm_normalizer/backend/dist/services/assistantTurnMeaningPolicy.js

236 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
// @ts-nocheck
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAssistantTurnMeaningPolicy = createAssistantTurnMeaningPolicy;
const SUPPORTED_ADDRESS_INTENTS = new Set([
"receivables_confirmed_as_of_date",
"payables_confirmed_as_of_date",
"list_documents_by_counterparty",
"customer_revenue_and_payments",
"inventory_on_hand_as_of_date",
"vat_liability_confirmed_for_tax_period",
"vat_payable_confirmed_as_of_date",
"vat_payable_forecast"
]);
function fallbackCompactWhitespace(value) {
return String(value ?? "").replace(/\s+/g, " ").trim();
}
function normalizeTurnText(value, deps) {
const compactWhitespace = typeof deps?.compactWhitespace === "function" ? deps.compactWhitespace : fallbackCompactWhitespace;
const repaired = typeof deps?.repairAddressMojibake === "function"
? deps.repairAddressMojibake(String(value ?? ""))
: String(value ?? "");
return compactWhitespace(repaired.toLowerCase())
.replace(/\u0451/gu, "\u0435")
.replace(/(^|[^\p{L}0-9_])\u043d\u0430\u043c\u0441(?=$|[^\p{L}0-9_])/giu, "$1\u043d\u0430\u043c")
.replace(/(^|[^\p{L}0-9_])\u043a\u0430\u043a\u0438\u0435\u043a(?=$|[^\p{L}0-9_])/giu, "$1\u043a\u0430\u043a\u0438\u0435");
}
function toNonEmptyString(value, deps) {
if (typeof deps?.toNonEmptyString === "function") {
return deps.toNonEmptyString(value);
}
if (value === null || value === undefined) {
return null;
}
const text = String(value).trim();
return text.length > 0 ? text : null;
}
function detectSupportedIntent(text, deps) {
const resolved = typeof deps?.resolveAddressIntent === "function" ? deps.resolveAddressIntent(text) : null;
const resolverIntent = toNonEmptyString(resolved?.intent, deps);
if (resolverIntent && resolverIntent !== "unknown" && SUPPORTED_ADDRESS_INTENTS.has(resolverIntent)) {
return {
intent: resolverIntent,
confidence: toNonEmptyString(resolved?.confidence, deps) ?? "medium",
reason: "address_intent_resolver_current_turn_signal"
};
}
if (/(?:\u043a\u0442\u043e\s+\u043d\u0430\u043c\s+\u0434\u043e\u043b\u0436|\u043d\u0430\u043c\s+\u043a\u0442\u043e\s+\u0434\u043e\u043b\u0436|\u0434\u0435\u0431\u0438\u0442\u043e\u0440|\u0434\u0435\u0431\u0438\u0442\u043e\u0440\u0441\u043a|\breceivables?\b)/iu.test(text)) {
return {
intent: "receivables_confirmed_as_of_date",
confidence: "high",
reason: "receivables_current_turn_meaning_signal"
};
}
if (/(?:\u043a\u043e\u043c\u0443\s+\u043c\u044b\s+\u0434\u043e\u043b\u0436|\u043c\u044b\s+\u043a\u043e\u043c\u0443\s+\u0434\u043e\u043b\u0436|\u043c\u044b\s+\u0434\u043e\u043b\u0436\u043d|\u043a\u0440\u0435\u0434\u0438\u0442\u043e\u0440|\bpayables?\b)/iu.test(text)) {
return {
intent: "payables_confirmed_as_of_date",
confidence: "high",
reason: "payables_current_turn_meaning_signal"
};
}
if (/(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0434\u043e\u043a\u0438|docs?|documents?)/iu.test(text) && /(?:\u043f\u043e|by)\s+[\p{L}0-9._-]{2,}/iu.test(text)) {
return {
intent: "list_documents_by_counterparty",
confidence: "medium",
reason: "counterparty_documents_current_turn_signal"
};
}
if (/(?:\u043e\u0441\u0442\u0430\u0442|\u0441\u043a\u043b\u0430\u0434|inventory|stock)/iu.test(text)) {
return {
intent: "inventory_on_hand_as_of_date",
confidence: "medium",
reason: "inventory_snapshot_current_turn_signal"
};
}
return null;
}
function detectCounterpartyTurnoverFamily(text) {
const hasTurnoverCue = /(?:\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\u043a|\u0434\u043e\u0445\u043e\u0434|turnover|revenue)/iu.test(text);
if (!hasTurnoverCue) {
return null;
}
const explicitEntityMatch = text.match(/(?:\u043f\u043e|by|for)?\s*([\p{L}0-9._-]{2,})\s*$/iu);
const rawEntity = explicitEntityMatch?.[1] ?? null;
const ignored = new Set([
"\u043e\u0431\u043e\u0440\u043e\u0442",
"\u0432\u044b\u0440\u0443\u0447\u043a\u0430",
"\u0434\u043e\u0445\u043e\u0434",
"\u0431\u044b\u043b",
"\u0431\u044b\u043b\u0430",
"\u0432\u0440\u0435\u043c\u044f",
"\u0432\u0440\u0435\u043c\u0435\u043d\u0438",
"\u0433\u043e\u0434",
"\u0433\u043e\u0434\u0430",
"\u043f\u0435\u0440\u0438\u043e\u0434",
"\u043f\u0435\u0440\u0438\u043e\u0434\u0430",
"\u043c\u0435\u0441\u044f\u0446",
"\u043c\u0435\u0441\u044f\u0446\u0430",
"\u043a\u0432\u0430\u0440\u0442\u0430\u043b",
"\u043a\u0432\u0430\u0440\u0442\u0430\u043b\u0430",
"turnover",
"revenue",
"time",
"year",
"period",
"month",
"quarter"
]);
const entity = rawEntity && !ignored.has(rawEntity) ? rawEntity : null;
return {
family: "counterparty_value_or_turnover",
entity
};
}
function detectBroadBusinessEvaluation(text) {
const normalized = String(text ?? "");
if (!normalized) {
return null;
}
if (/(?:как\s+ты\s+оценишь\s+деятельност[ьи]\s+компан|оценк[аи]?\s+деятельност[ьи]\s+компан|что\s+у\s+нас\s+вообще\s+происход|где\s+главн(?:ые|ый)\s+риски|как\s+у\s+нас\s+дела\s+по\s+компан)/iu.test(normalized)) {
return {
family: "broad_business_evaluation"
};
}
return null;
}
function buildEntityCandidates(counterpartyTurnover) {
if (!counterpartyTurnover?.entity) {
return [];
}
return [
{
type: "counterparty",
value: counterpartyTurnover.entity,
source: "current_turn_loose_entity_tail"
}
];
}
function createAssistantTurnMeaningPolicy(deps = {}) {
function resolveAssistantTurnMeaning(input = {}) {
const rawMessage = String(input?.rawUserMessage ?? input?.userMessage ?? "");
const effectiveMessage = String(input?.effectiveAddressUserMessage ?? rawMessage);
const rawText = normalizeTurnText(rawMessage, deps);
const effectiveText = normalizeTurnText(effectiveMessage, deps);
const joinedText = fallbackCompactWhitespace(`${rawText} ${effectiveText}`);
const supportedIntent = detectSupportedIntent(joinedText, deps);
const counterpartyTurnover = detectCounterpartyTurnoverFamily(joinedText);
const broadBusinessEvaluation = detectBroadBusinessEvaluation(joinedText);
const llmIntent = toNonEmptyString(input?.llmPreDecomposeMeta?.predecomposeContract?.intent, deps);
const explicitIntentCandidate = broadBusinessEvaluation?.family
? null
: supportedIntent?.intent ?? (llmIntent && llmIntent !== "unknown" ? llmIntent : null);
const unsupportedFamily = broadBusinessEvaluation?.family
? broadBusinessEvaluation.family
: !explicitIntentCandidate && counterpartyTurnover?.family
? counterpartyTurnover.family
: null;
const reasonCodes = [];
if (supportedIntent?.reason) {
reasonCodes.push(supportedIntent.reason);
}
if (counterpartyTurnover?.family) {
reasonCodes.push("counterparty_turnover_current_turn_signal");
}
if (broadBusinessEvaluation?.family) {
reasonCodes.push("broad_business_evaluation_current_turn_signal");
}
if (rawText !== normalizeTurnText(rawMessage, { ...deps, repairAddressMojibake: (value) => String(value ?? "") })) {
reasonCodes.push("mojibake_repair_applied");
}
if (rawText.includes("\u043d\u0430\u043c") &&
/(^|[^\p{L}0-9_])\u043d\u0430\u043c\u0441(?=$|[^\p{L}0-9_])/iu.test(String(rawMessage ?? ""))) {
reasonCodes.push("known_turn_typo_normalized");
}
const askedDomainFamily = explicitIntentCandidate?.startsWith("receivables_")
? "receivables"
: explicitIntentCandidate?.startsWith("payables_")
? "payables"
: explicitIntentCandidate?.startsWith("vat_")
? "vat"
: explicitIntentCandidate?.startsWith("inventory_")
? "inventory"
: broadBusinessEvaluation?.family
? "business_summary"
: explicitIntentCandidate?.includes("counterparty")
? "counterparty"
: counterpartyTurnover?.family
? "counterparty"
: null;
const askedActionFamily = explicitIntentCandidate === "receivables_confirmed_as_of_date" ||
explicitIntentCandidate === "payables_confirmed_as_of_date" ||
explicitIntentCandidate === "inventory_on_hand_as_of_date"
? "confirmed_snapshot"
: broadBusinessEvaluation?.family
? "broad_evaluation"
: explicitIntentCandidate === "vat_liability_confirmed_for_tax_period"
? "confirmed_tax_period"
: explicitIntentCandidate === "vat_payable_confirmed_as_of_date"
? "confirmed_snapshot"
: explicitIntentCandidate === "vat_payable_forecast"
? "forecast"
: explicitIntentCandidate === "list_documents_by_counterparty"
? "list_documents"
: counterpartyTurnover?.family
? "counterparty_value_or_turnover"
: null;
const staleReplayForbidden = Boolean(unsupportedFamily || broadBusinessEvaluation?.family || (counterpartyTurnover?.entity && !explicitIntentCandidate));
return {
schema_version: "assistant_turn_meaning_v1",
raw_message: rawMessage,
effective_message: effectiveMessage,
normalized_raw_message: rawText,
normalized_effective_message: effectiveText,
asked_domain_family: askedDomainFamily,
asked_action_family: askedActionFamily,
explicit_intent_candidate: explicitIntentCandidate,
explicit_entity_candidates: buildEntityCandidates(counterpartyTurnover),
meaning_confidence: broadBusinessEvaluation?.family
? "medium"
: supportedIntent?.confidence ?? (counterpartyTurnover?.family ? "medium" : "low"),
intent_override_strength: explicitIntentCandidate
? "explicit_current_turn_intent"
: staleReplayForbidden
? "explicit_new_action_or_entity"
: "none",
carryover_budget: staleReplayForbidden ? "none" : explicitIntentCandidate ? "matching_family_only" : "normal",
unsupported_but_understood_family: unsupportedFamily,
stale_replay_forbidden: staleReplayForbidden,
reason_codes: reasonCodes
};
}
return {
resolveAssistantTurnMeaning
};
}