NODEDC_1C/llm_normalizer/backend/dist/services/assistantAddressOrchestrati...

111 lines
6.7 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";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildAssistantAddressOrchestrationRuntime = buildAssistantAddressOrchestrationRuntime;
const assistantRoutePolicyRuntimeAdapter_1 = require("./assistantRoutePolicyRuntimeAdapter");
function hasSelectedObjectInventorySignal(text) {
return /(?:по\s+выбранному\s+объекту|по\s+выбранной\s+позиции|по\s+этой\s+позиции|по\s+этому\s+товару|по\s+ним|selected\s+object)/iu.test(String(text ?? ""));
}
function hasSelectedObjectInventoryActionCue(text) {
return /(?:кому[\s\S]{0,80}(?:продал[аи]?|реализова[нлт][а-я]*|поставил[аи]?|поставлен[а-я]*|отгрузил[аи]?|отгружен[а-я]*)|кому\s+был\s+продан|куда[\s\S]{0,80}(?:продал[аи]?|реализова[нлт][а-я]*|поставил[аи]?|поставлен[а-я]*|отгрузил[аи]?|отгружен[а-я]*)|кто[\s\S]{0,40}купил|кто\s+это\s+поставил|кто\s+поставил|у\s+кого\s+купили|у\s+кого\s+куплено|где\s+мы\s+купили|где\s+куплено|по\s+каким\s+документам|какими\s+документами|покажи\s+документы|документы[\s\S]{0,80}(?:по\s+(?:ним|ней|нему|этой\s+позиции|этому\s+товару)|операци)|документы\s+закупки|buyer|sale\s+trace|supplier|vendor|purchase\s+documents|purchase[\s-]?to[\s-]?sale|old\s+purchase|aged\s+stock)/iu.test(String(text ?? ""));
}
function isGenericCanonicalDriftIntent(intent) {
return (intent === "open_items_by_counterparty_or_contract" ||
intent === "list_documents_by_counterparty" ||
intent === "list_documents_by_contract" ||
intent === "bank_operations_by_counterparty" ||
intent === "bank_operations_by_contract" ||
intent === "documents_forming_balance");
}
function shouldPreferRawFollowupMessage(userMessage, addressInputMessage, carryover, addressPreDecompose, toNonEmptyString) {
if (!carryover?.followupContext || typeof carryover.followupContext !== "object") {
return false;
}
const rawMessage = toNonEmptyString(userMessage);
const canonicalMessage = toNonEmptyString(addressInputMessage);
if (!rawMessage || !canonicalMessage || rawMessage === canonicalMessage) {
return false;
}
const predecomposeContract = addressPreDecompose?.predecomposeContract && typeof addressPreDecompose.predecomposeContract === "object"
? addressPreDecompose.predecomposeContract
: null;
const mode = toNonEmptyString(predecomposeContract?.mode) ?? "unknown";
const intent = toNonEmptyString(predecomposeContract?.intent) ?? "unknown";
if (mode === "unsupported" && intent === "unknown") {
return true;
}
return (hasSelectedObjectInventorySignal(rawMessage) &&
hasSelectedObjectInventoryActionCue(rawMessage) &&
isGenericCanonicalDriftIntent(intent));
}
function fallbackAddressPreDecompose(userMessage, llmProvider, buildAddressLlmPredecomposeContractV1, sanitizeAddressMessageForFallback) {
const provider = llmProvider === "local" ? "local" : llmProvider === "openai" ? "openai" : null;
return {
attempted: false,
applied: false,
provider,
traceId: null,
effectiveMessage: userMessage,
reason: "disabled_by_feature_flag",
llmCanonicalCandidateDetected: false,
predecomposeContract: buildAddressLlmPredecomposeContractV1({
sourceMessage: userMessage,
canonicalMessage: userMessage
}),
fallbackRuleHit: null,
sanitizedUserMessage: sanitizeAddressMessageForFallback(userMessage),
toolGateDecision: null,
toolGateReason: null
};
}
async function buildAssistantAddressOrchestrationRuntime(input) {
const initialAddressPreDecompose = input.featureAddressLlmPredecomposeV1
? await input.runAddressLlmPreDecompose()
: fallbackAddressPreDecompose(input.userMessage, input.llmProvider, input.buildAddressLlmPredecomposeContractV1, input.sanitizeAddressMessageForFallback);
let addressPreDecompose = initialAddressPreDecompose;
let addressInputMessage = input.toNonEmptyString(addressPreDecompose?.effectiveMessage) ?? input.userMessage;
let carryover = input.resolveAddressFollowupCarryoverContext(input.userMessage, input.sessionItems, addressInputMessage, addressPreDecompose, input.sessionAddressNavigationState);
if (shouldPreferRawFollowupMessage(input.userMessage, addressInputMessage, carryover, addressPreDecompose, input.toNonEmptyString)) {
addressInputMessage = input.userMessage;
addressPreDecompose = {
...addressPreDecompose,
applied: false,
effectiveMessage: input.userMessage,
reason: "followup_raw_message_preferred_over_llm_rewrite",
predecomposeContract: input.buildAddressLlmPredecomposeContractV1({
sourceMessage: input.userMessage,
canonicalMessage: input.userMessage
})
};
carryover = input.resolveAddressFollowupCarryoverContext(input.userMessage, input.sessionItems, addressInputMessage, addressPreDecompose, input.sessionAddressNavigationState);
}
const followupContext = carryover?.followupContext ?? null;
const routePolicyRuntime = (0, assistantRoutePolicyRuntimeAdapter_1.runAssistantRoutePolicyRuntime)({
rawUserMessage: input.userMessage,
effectiveAddressUserMessage: addressInputMessage,
followupContext,
llmPreDecomposeMeta: addressPreDecompose,
sessionItems: input.sessionItems,
sessionOrganizationScope: input.sessionOrganizationScope ?? null,
useMock: input.useMock,
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision
});
const orchestrationDecision = routePolicyRuntime.orchestrationDecision;
const dialogContinuationContract = input.buildAddressDialogContinuationContractV2(input.userMessage, addressInputMessage, carryover, addressPreDecompose);
const addressRuntimeMeta = {
...addressPreDecompose,
toolGateDecision: orchestrationDecision.toolGateDecision ?? null,
toolGateReason: orchestrationDecision.toolGateReason ?? null,
dialogContinuationContract,
orchestrationContract: orchestrationDecision.orchestrationContract ?? null,
routePolicyContract: routePolicyRuntime.routePolicyContract
};
return {
addressPreDecompose,
addressInputMessage,
carryover,
orchestrationDecision,
addressRuntimeMeta,
livingModeDecision: routePolicyRuntime.livingModeDecision
};
}