110 lines
5.9 KiB
JavaScript
110 lines
5.9 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.buildAssistantAddressOrchestrationRuntime = buildAssistantAddressOrchestrationRuntime;
|
||
function hasSelectedObjectInventorySignal(text) {
|
||
return /(?:по\s+выбранному\s+объекту|по\s+этой\s+позиции|по\s+этому\s+товару|selected\s+object)/iu.test(String(text ?? ""));
|
||
}
|
||
function hasSelectedObjectInventoryActionCue(text) {
|
||
return /(?:кому[\s\S]{0,80}продал[аи]?|кому[\s\S]{0,80}реализова[нлт][а-я]*|кому\s+был\s+продан|кто[\s\S]{0,40}купил|кто\s+это\s+поставил|кто\s+поставил|у\s+кого\s+купили|у\s+кого\s+куплено|где\s+мы\s+купили|где\s+куплено|по\s+каким\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);
|
||
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);
|
||
}
|
||
const followupContext = carryover?.followupContext ?? null;
|
||
const orchestrationDecision = input.resolveAssistantOrchestrationDecision({
|
||
rawUserMessage: input.userMessage,
|
||
effectiveAddressUserMessage: addressInputMessage,
|
||
followupContext,
|
||
llmPreDecomposeMeta: addressPreDecompose,
|
||
sessionItems: input.sessionItems,
|
||
useMock: input.useMock
|
||
});
|
||
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
|
||
};
|
||
const livingModeDecision = {
|
||
mode: orchestrationDecision.livingMode,
|
||
reason: orchestrationDecision.livingReason
|
||
};
|
||
return {
|
||
addressPreDecompose,
|
||
addressInputMessage,
|
||
carryover,
|
||
orchestrationDecision,
|
||
addressRuntimeMeta,
|
||
livingModeDecision
|
||
};
|
||
}
|