NODEDC_1C/llm_normalizer/backend/src/services/assistantLivingChatHandlerR...

130 lines
7.2 KiB
TypeScript

import {
runAssistantLivingChatRuntime,
type AssistantLivingChatRuntimeInput,
type AssistantLivingChatRuntimeOutput
} from "./assistantLivingChatRuntimeAdapter";
import {
finalizeAssistantLivingChatTurn,
type FinalizeAssistantLivingChatTurnInput
} from "./assistantLivingChatTurnFinalizeRuntimeAdapter";
export interface TryHandleAssistantLivingChatRuntimeInput<ResponseType = unknown> {
sessionId: string;
userMessage: string;
sessionItems: unknown[];
modeDecision?: AssistantLivingChatRuntimeInput["modeDecision"];
sessionScope: AssistantLivingChatRuntimeInput["sessionScope"];
addressRuntimeMeta?: AssistantLivingChatRuntimeInput["addressRuntimeMeta"];
traceIdFactory: AssistantLivingChatRuntimeInput["traceIdFactory"];
toNonEmptyString: AssistantLivingChatRuntimeInput["toNonEmptyString"];
mergeKnownOrganizations: AssistantLivingChatRuntimeInput["mergeKnownOrganizations"];
hasAssistantDataScopeMetaQuestionSignal: AssistantLivingChatRuntimeInput["hasAssistantDataScopeMetaQuestionSignal"];
shouldHandleAsAssistantCapabilityMetaQuery: AssistantLivingChatRuntimeInput["shouldHandleAsAssistantCapabilityMetaQuery"];
hasDestructiveDataActionSignal: AssistantLivingChatRuntimeInput["hasDestructiveDataActionSignal"];
hasDangerOrCoercionSignal: AssistantLivingChatRuntimeInput["hasDangerOrCoercionSignal"];
hasOperationalAdminActionRequestSignal: AssistantLivingChatRuntimeInput["hasOperationalAdminActionRequestSignal"];
hasOrganizationFactLookupSignal: AssistantLivingChatRuntimeInput["hasOrganizationFactLookupSignal"];
hasOrganizationFactFollowupSignal: AssistantLivingChatRuntimeInput["hasOrganizationFactFollowupSignal"];
hasLivingChatSignal: AssistantLivingChatRuntimeInput["hasLivingChatSignal"];
shouldEmitOrganizationSelectionReply: AssistantLivingChatRuntimeInput["shouldEmitOrganizationSelectionReply"];
hasAssistantCapabilityQuestionSignal: AssistantLivingChatRuntimeInput["hasAssistantCapabilityQuestionSignal"];
resolveDataScopeProbe: AssistantLivingChatRuntimeInput["resolveDataScopeProbe"];
executeLlmChat: AssistantLivingChatRuntimeInput["executeLlmChat"];
applyScriptGuard: AssistantLivingChatRuntimeInput["applyScriptGuard"];
applyGroundingGuard: AssistantLivingChatRuntimeInput["applyGroundingGuard"];
buildAssistantSafetyRefusalReply: AssistantLivingChatRuntimeInput["buildAssistantSafetyRefusalReply"];
buildAssistantDataScopeContractReply: AssistantLivingChatRuntimeInput["buildAssistantDataScopeContractReply"];
buildAssistantProactiveOrganizationOfferReply: AssistantLivingChatRuntimeInput["buildAssistantProactiveOrganizationOfferReply"];
buildAssistantOrganizationFactBoundaryReply: AssistantLivingChatRuntimeInput["buildAssistantOrganizationFactBoundaryReply"];
buildAssistantDataScopeSelectionReply: AssistantLivingChatRuntimeInput["buildAssistantDataScopeSelectionReply"];
buildAssistantOperationalBoundaryReply: AssistantLivingChatRuntimeInput["buildAssistantOperationalBoundaryReply"];
buildAssistantCapabilityContractReply: AssistantLivingChatRuntimeInput["buildAssistantCapabilityContractReply"];
appendItem: FinalizeAssistantLivingChatTurnInput["appendItem"];
getSession: FinalizeAssistantLivingChatTurnInput["getSession"];
persistSession: FinalizeAssistantLivingChatTurnInput["persistSession"];
cloneConversation: FinalizeAssistantLivingChatTurnInput["cloneConversation"];
logEvent: (payload: Record<string, unknown>) => void;
messageIdFactory: FinalizeAssistantLivingChatTurnInput["messageIdFactory"];
nowIso: () => string;
runLivingChatRuntime?: (
input: AssistantLivingChatRuntimeInput
) => Promise<AssistantLivingChatRuntimeOutput>;
finalizeLivingChatTurn?: (
input: FinalizeAssistantLivingChatTurnInput
) => {
response: ResponseType;
};
}
export async function tryHandleAssistantLivingChatRuntime<ResponseType = unknown>(
input: TryHandleAssistantLivingChatRuntimeInput<ResponseType>
): Promise<ResponseType | null> {
const runLivingChatRuntimeSafe = input.runLivingChatRuntime ?? runAssistantLivingChatRuntime;
const finalizeLivingChatTurnSafe = input.finalizeLivingChatTurn ?? finalizeAssistantLivingChatTurn;
try {
const runtime = await runLivingChatRuntimeSafe({
userMessage: input.userMessage,
sessionItems: input.sessionItems,
modeDecision: input.modeDecision,
sessionScope: input.sessionScope,
addressRuntimeMeta: input.addressRuntimeMeta,
traceIdFactory: input.traceIdFactory,
toNonEmptyString: input.toNonEmptyString,
mergeKnownOrganizations: input.mergeKnownOrganizations,
hasAssistantDataScopeMetaQuestionSignal: input.hasAssistantDataScopeMetaQuestionSignal,
shouldHandleAsAssistantCapabilityMetaQuery: input.shouldHandleAsAssistantCapabilityMetaQuery,
hasDestructiveDataActionSignal: input.hasDestructiveDataActionSignal,
hasDangerOrCoercionSignal: input.hasDangerOrCoercionSignal,
hasOperationalAdminActionRequestSignal: input.hasOperationalAdminActionRequestSignal,
hasOrganizationFactLookupSignal: input.hasOrganizationFactLookupSignal,
hasOrganizationFactFollowupSignal: input.hasOrganizationFactFollowupSignal,
hasLivingChatSignal: input.hasLivingChatSignal,
shouldEmitOrganizationSelectionReply: input.shouldEmitOrganizationSelectionReply,
hasAssistantCapabilityQuestionSignal: input.hasAssistantCapabilityQuestionSignal,
resolveDataScopeProbe: input.resolveDataScopeProbe,
executeLlmChat: input.executeLlmChat,
applyScriptGuard: input.applyScriptGuard,
applyGroundingGuard: input.applyGroundingGuard,
buildAssistantSafetyRefusalReply: input.buildAssistantSafetyRefusalReply,
buildAssistantDataScopeContractReply: input.buildAssistantDataScopeContractReply,
buildAssistantProactiveOrganizationOfferReply: input.buildAssistantProactiveOrganizationOfferReply,
buildAssistantOrganizationFactBoundaryReply: input.buildAssistantOrganizationFactBoundaryReply,
buildAssistantDataScopeSelectionReply: input.buildAssistantDataScopeSelectionReply,
buildAssistantOperationalBoundaryReply: input.buildAssistantOperationalBoundaryReply,
buildAssistantCapabilityContractReply: input.buildAssistantCapabilityContractReply
});
if (!runtime.handled || !runtime.debug) {
return null;
}
const finalization = finalizeLivingChatTurnSafe({
sessionId: input.sessionId,
userMessage: input.userMessage,
assistantReply: runtime.chatText,
replyType: "factual_with_explanation",
debug: runtime.debug,
modeDecision: input.modeDecision,
appendItem: input.appendItem,
getSession: input.getSession,
persistSession: input.persistSession,
cloneConversation: input.cloneConversation,
logEvent: input.logEvent as FinalizeAssistantLivingChatTurnInput["logEvent"],
messageIdFactory: input.messageIdFactory
});
return finalization.response as ResponseType;
} catch (error) {
input.logEvent({
timestamp: input.nowIso(),
level: "warn",
service: "assistant_loop",
message: "assistant_living_chat_failed_fallback_to_deep",
sessionId: input.sessionId,
details: {
session_id: input.sessionId,
user_message: input.userMessage,
reason: error instanceof Error ? error.message : String(error)
}
});
return null;
}
}