Files
NODEDC_1C/llm_normalizer/backend/src/services/assistantMetaFollowupPolicy.ts
T

141 lines
4.2 KiB
TypeScript

// @ts-nocheck
export interface ResolveAssistantMetaSignalSetInput {
rawUserMessage?: unknown;
repairedRawUserMessage?: unknown;
effectiveAddressUserMessage?: unknown;
repairedEffectiveAddressUserMessage?: unknown;
}
export interface ResolveAssistantMetaFollowupOverGroundedAnswerInput {
followupContext?: unknown;
hasPriorAddressAnswerContext?: boolean;
metaAnswerFollowupSignal?: boolean;
vatEvaluativeFollowupSignal?: boolean;
dataScopeMetaQuery?: boolean;
capabilityMetaQuery?: boolean;
aggregateBusinessAnalyticsSignal?: boolean;
dataRetrievalSignal?: boolean;
strongDataSignal?: boolean;
resolvedMode?: unknown;
resolvedIntent?: unknown;
llmContractIntent?: unknown;
llmContractMode?: unknown;
}
export interface ResolveAssistantHardMetaModeInput {
dataScopeMetaQuery?: boolean;
capabilityMetaQuery?: boolean;
dataRetrievalSignal?: boolean;
}
export interface AssistantMetaSignalSet {
dataScopeMetaQuery: boolean;
capabilityMetaQuery: boolean;
metaAnswerFollowupSignal: boolean;
}
export interface AssistantMetaFollowupPolicyDeps {
hasAssistantDataScopeMetaQuestionSignal: (text: unknown) => boolean;
shouldHandleAsAssistantCapabilityMetaQuery: (text: unknown) => boolean;
hasMetaAnswerFollowupSignal: (text: unknown) => boolean;
}
function collectMessageSamples(input: ResolveAssistantMetaSignalSetInput): string[] {
const values = [
input.rawUserMessage,
input.repairedRawUserMessage,
input.effectiveAddressUserMessage,
input.repairedEffectiveAddressUserMessage
];
return Array.from(
new Set(
values
.map((item) => String(item ?? "").trim())
.filter((item) => item.length > 0)
)
);
}
function hasSignalAcrossSamples(
samples: string[],
detector: (text: unknown) => boolean
): boolean {
return samples.some((sample) => detector(sample));
}
function hasImplicitHistoricalCapabilityMetaSignal(samples: string[]): boolean {
return samples.some(
(sample) =>
/(?:историческ|история|архив|раньше|ретро|старые\s+данные)/iu.test(sample) &&
/(?:мож(?:ешь|ем|но)|уме(?:ешь|ете))/iu.test(sample)
);
}
export function createAssistantMetaFollowupPolicy(
deps: AssistantMetaFollowupPolicyDeps
) {
function resolveMetaSignalSet(
input: ResolveAssistantMetaSignalSetInput
): AssistantMetaSignalSet {
const samples = collectMessageSamples(input);
if (samples.length === 0) {
return {
dataScopeMetaQuery: false,
capabilityMetaQuery: false,
metaAnswerFollowupSignal: false
};
}
return {
dataScopeMetaQuery: hasSignalAcrossSamples(
samples,
deps.hasAssistantDataScopeMetaQuestionSignal
),
capabilityMetaQuery:
hasSignalAcrossSamples(samples, deps.shouldHandleAsAssistantCapabilityMetaQuery) ||
hasImplicitHistoricalCapabilityMetaSignal(samples),
metaAnswerFollowupSignal: hasSignalAcrossSamples(
samples,
deps.hasMetaAnswerFollowupSignal
)
};
}
function resolveHardMetaMode(
input: ResolveAssistantHardMetaModeInput
): "data_scope" | "capability" | null {
if (Boolean(input.dataScopeMetaQuery)) {
return "data_scope";
}
if (Boolean(input.capabilityMetaQuery) && !Boolean(input.dataRetrievalSignal)) {
return "capability";
}
return null;
}
function isMetaFollowupOverGroundedAnswer(
input: ResolveAssistantMetaFollowupOverGroundedAnswerInput
): boolean {
return Boolean(
input.followupContext &&
input.hasPriorAddressAnswerContext &&
(input.metaAnswerFollowupSignal || input.vatEvaluativeFollowupSignal) &&
!input.dataScopeMetaQuery &&
!input.capabilityMetaQuery &&
!input.aggregateBusinessAnalyticsSignal &&
!input.dataRetrievalSignal &&
!input.strongDataSignal &&
String(input.resolvedMode ?? "") !== "address_query" &&
String(input.resolvedIntent ?? "") === "unknown" &&
(!input.llmContractIntent || String(input.llmContractIntent) === "unknown") &&
String(input.llmContractMode ?? "") !== "address_query"
);
}
return {
resolveMetaSignalSet,
resolveHardMetaMode,
isMetaFollowupOverGroundedAnswer
};
}