NODEDC_1C/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts

283 lines
12 KiB
TypeScript

import type {
AssistantAddressRuntimeMetaForDeep,
AssistantConversationItem,
AssistantDebugPayload,
AssistantDebugRouteRecord,
AssistantExecutionStateRecord,
AssistantFallbackType,
AssistantProblemAnswerMode,
AssistantReplyType,
AssistantRequirement,
AnswerGroundingCheck,
FaLiveRouteAuditDebug,
RbpLiveRouteAuditDebug,
RequirementCoverageReport,
UnifiedRetrievalResult
} from "../types/assistant";
import type {
NormalizeResponsePayload,
NormalizedQueryV2,
NormalizedQueryV2_0_1,
NormalizedQueryV2_0_2,
RouteHintSummary
} from "../types/normalizer";
import type { AnswerStructureV11 } from "../types/stage1Contracts";
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
import {
assembleAssistantEvidenceBundle,
type AssistantEvidenceBundleAssembly
} from "./assistantEvidenceBundleAssembler";
import { assembleAssistantContractsBundleV1, type AssistantContractsBundleV1 } from "./assistantContractsBundleAssembler";
import { buildDeepAnswerArtifacts, buildAssistantConversationItem, type DeepAnswerArtifacts } from "./assistantDeepResponseAssembler";
import { buildDeepAnalysisDebugPayload } from "./assistantDebugPayloadAssembler";
import {
buildDeepAnalysisProcessedLogDetails,
type DeepAnalysisLogDetails
} from "./assistantMessageLogAssembler";
import type { AssistantFollowupUsage } from "./assistantFollowupUsage";
import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence";
import type { CompanyAnchorSet } from "./companyAnchorResolver";
import type {
DomainPolarityGuardAudit,
EvidenceAdmissibilityAudit,
GroundedAnswerEligibilityAudit,
TemporalGuardAudit
} from "./assistantRuntimeGuards";
import type {
AssistantRetrievalCallRecord,
AssistantRetrievalRawResultRecord
} from "./assistantDeepTurnRetrievalRuntimeAdapter";
export interface AssistantDeepTurnPackagingInput {
sessionId: string;
messageId: string;
userMessage: string;
normalized: {
trace_id: string;
prompt_version: string;
schema_version: string;
normalized: NormalizeResponsePayload["normalized"];
};
normalizedQuestion: string;
routeSummary: RouteHintSummary | null;
droppedIntentSegments: string[];
analysisContextForContract: {
as_of_date: string | null;
period_from: string | null;
period_to: string | null;
source: string | null;
snapshot_mode: "auto" | "force_snapshot" | "force_live";
} | null;
executionPlan: Array<{
fragment_id: string;
requirement_ids: string[];
route: string;
should_execute: boolean;
no_route_reason?: string | null;
clarification_reason?: string | null;
}>;
requirementExtractionRequirements: AssistantRequirement[];
coverageEvaluationRequirements: AssistantRequirement[];
coverageReport: RequirementCoverageReport;
groundingCheck: AnswerGroundingCheck;
retrievalCalls: AssistantRetrievalCallRecord[];
retrievalResultsRaw: AssistantRetrievalRawResultRecord[];
retrievalResults: UnifiedRetrievalResult[];
routesForDebug: AssistantDebugRouteRecord[];
resolvedExecutionState: AssistantExecutionStateRecord[];
questionTypeClass: string;
companyAnchors: CompanyAnchorSet | null;
runtimeAnalysisContext: {
active: boolean;
as_of_date: string | null;
period_from: string | null;
period_to: string | null;
source: string | null;
snapshot_mode: "auto" | "force_snapshot" | "force_live";
};
businessScopeResolution: {
business_scope_raw?: string[];
business_scope_resolved?: string[];
company_grounding_applied?: boolean;
scope_resolution_reason?: string[];
};
temporalGuard: TemporalGuardAudit;
polarityAudit: DomainPolarityGuardAudit;
claimAnchorAudit: ClaimBoundAnchorAudit;
targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit;
evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit;
rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null;
faLiveRouteAudit: FaLiveRouteAuditDebug | null;
groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit;
followupStateUsage: AssistantFollowupUsage | null;
composition: {
reply_type: AssistantReplyType;
fallback_type: AssistantFallbackType;
answer_structure_v11?: AnswerStructureV11 | null;
problem_centric_answer_applied?: boolean;
problem_units_used_count?: number;
problem_answer_mode?: AssistantProblemAnswerMode;
problem_unit_ids_used?: string[];
};
safeAssistantReplyBase: string;
featureContractsV11: boolean;
featureAnswerPolicyV11: boolean;
investigationStateSnapshot: InvestigationStateWithProblemUnits | null;
addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined;
}
export interface AssistantDeepTurnPackagingOutput {
evidenceBundleAssembly: AssistantEvidenceBundleAssembly;
contractsBundleV1: AssistantContractsBundleV1;
deepAnswerArtifacts: DeepAnswerArtifacts;
debug: AssistantDebugPayload;
assistantItem: AssistantConversationItem;
deepAnalysisLogDetails: DeepAnalysisLogDetails;
}
type NormalizedFragments =
| NormalizedQueryV2["fragments"]
| NormalizedQueryV2_0_1["fragments"]
| NormalizedQueryV2_0_2["fragments"];
function extractNormalizedFragments(normalized: NormalizeResponsePayload["normalized"] | null): NormalizedFragments {
if (!normalized || typeof normalized !== "object") {
return [];
}
const source = normalized as NormalizedQueryV2 | NormalizedQueryV2_0_1 | NormalizedQueryV2_0_2;
return Array.isArray(source.fragments) ? source.fragments : [];
}
export function assembleAssistantDeepTurnPackaging(input: AssistantDeepTurnPackagingInput): AssistantDeepTurnPackagingOutput {
const normalizedPayload = input.normalized.normalized ?? null;
const normalizedFragments = extractNormalizedFragments(normalizedPayload);
const evidenceBundleAssembly = assembleAssistantEvidenceBundle({
retrievalCalls: input.retrievalCalls,
retrievalResults: input.retrievalResults
});
const contractsBundleV1 = assembleAssistantContractsBundleV1({
userMessage: input.userMessage,
normalizedQuestion: input.normalizedQuestion,
normalized: input.normalized.normalized,
routeSummary: input.routeSummary,
droppedIntentSegments: input.droppedIntentSegments,
analysisContext: input.analysisContextForContract,
executionPlan: input.executionPlan,
requirements: input.requirementExtractionRequirements,
evidenceBundleContractV1: evidenceBundleAssembly.evidenceBundleContractV1,
replyType: input.composition.reply_type,
coverageReport: input.coverageReport,
grounding: input.groundingCheck,
retrievalResults: input.retrievalResults
});
const deepAnswerArtifacts = buildDeepAnswerArtifacts({
safeAssistantReplyBase: input.safeAssistantReplyBase,
featureContractsV11: input.featureContractsV11,
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
compositionAnswerStructureV11: input.composition.answer_structure_v11 ?? null,
coverageReport: input.coverageReport,
groundingCheck: input.groundingCheck,
retrievalResults: input.retrievalResults
});
const debug = buildDeepAnalysisDebugPayload({
traceId: input.normalized.trace_id,
promptVersion: input.normalized.prompt_version,
schemaVersion: input.normalized.schema_version,
fallbackType: input.composition.fallback_type,
routeSummary: input.routeSummary,
fragments: normalizedFragments,
requirementsExtracted: input.coverageEvaluationRequirements,
coverageReport: input.coverageReport,
routes: input.routesForDebug,
retrievalStatus: evidenceBundleAssembly.retrievalStatus,
retrievalResults: input.retrievalResults,
groundingCheck: input.groundingCheck,
droppedIntentSegments: input.droppedIntentSegments,
questionTypeClass: input.questionTypeClass,
companyAnchors: input.companyAnchors,
runtimeAnalysisContext: input.runtimeAnalysisContext,
businessScopeResolution: input.businessScopeResolution,
temporalGuard: input.temporalGuard,
polarityAudit: input.polarityAudit,
claimAnchorAudit: input.claimAnchorAudit,
targetedEvidenceAudit: input.targetedEvidenceAudit,
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit,
rbpLiveRouteAudit: input.rbpLiveRouteAudit,
faLiveRouteAudit: input.faLiveRouteAudit,
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard,
followupStateUsage: input.followupStateUsage,
compositionDebug: {
problem_centric_answer_applied: input.composition.problem_centric_answer_applied ?? false,
problem_units_used_count: input.composition.problem_units_used_count ?? 0,
problem_answer_mode: input.composition.problem_answer_mode ?? "stage1_policy_v11",
problem_unit_ids_used: Array.isArray(input.composition.problem_unit_ids_used) ? input.composition.problem_unit_ids_used : []
},
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep,
outcomeClassV1: contractsBundleV1.outcomeClassV1,
assistantOrchestrationContractsV1: contractsBundleV1.assistantOrchestrationContractsV1,
answerStructureV11: deepAnswerArtifacts.answerStructureV11,
assistantReply: deepAnswerArtifacts.safeAssistantReply,
investigationStateSnapshot: input.investigationStateSnapshot,
normalizedPayload: normalizedPayload
});
const assistantItem = buildAssistantConversationItem({
messageId: input.messageId,
sessionId: input.sessionId,
text: deepAnswerArtifacts.safeAssistantReply,
replyType: input.composition.reply_type,
traceId: input.normalized.trace_id,
debug
});
const deepAnalysisLogDetails = buildDeepAnalysisProcessedLogDetails({
sessionId: input.sessionId,
messageId: input.messageId,
userMessage: input.userMessage,
normalizerOutput: input.normalized.normalized,
executionPlan: input.executionPlan,
resolvedExecutionState: input.resolvedExecutionState,
routes: input.routesForDebug,
retrievalCalls: input.retrievalCalls,
retrievalResultsRaw: input.retrievalResultsRaw,
retrievalResultsNormalized: input.retrievalResults,
requirementsExtracted: input.coverageEvaluationRequirements,
coverageReport: input.coverageReport,
groundingCheck: input.groundingCheck,
replyType: input.composition.reply_type,
droppedIntentSegments: input.droppedIntentSegments,
questionTypeClass: input.questionTypeClass,
companyAnchors: input.companyAnchors,
runtimeAnalysisContext: input.runtimeAnalysisContext,
businessScopeResolution: input.businessScopeResolution,
temporalGuard: input.temporalGuard,
polarityAudit: input.polarityAudit,
claimAnchorAudit: input.claimAnchorAudit,
targetedEvidenceAudit: input.targetedEvidenceAudit,
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit,
rbpLiveRouteAudit: input.rbpLiveRouteAudit,
faLiveRouteAudit: input.faLiveRouteAudit,
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard,
followupStateUsage: input.followupStateUsage,
compositionDebug: {
problem_centric_answer_applied: input.composition.problem_centric_answer_applied ?? false,
problem_units_used_count: input.composition.problem_units_used_count ?? 0,
problem_answer_mode: input.composition.problem_answer_mode ?? "stage1_policy_v11",
problem_unit_ids_used: Array.isArray(input.composition.problem_unit_ids_used) ? input.composition.problem_unit_ids_used : [],
fallback_type: input.composition.fallback_type
},
outcomeClassV1: contractsBundleV1.outcomeClassV1,
assistantOrchestrationContractsV1: contractsBundleV1.assistantOrchestrationContractsV1,
answerStructureV11: deepAnswerArtifacts.answerStructureV11,
investigationStateSnapshot: input.investigationStateSnapshot,
assistantReply: deepAnswerArtifacts.safeAssistantReply,
traceId: input.normalized.trace_id
});
return {
evidenceBundleAssembly,
contractsBundleV1,
deepAnswerArtifacts,
debug,
assistantItem,
deepAnalysisLogDetails
};
}