NODEDC_1C/llm_normalizer/backend/src/services/assistantDebugPayloadAssemb...

196 lines
10 KiB
TypeScript

import type {
AssistantAddressRuntimeMetaForDeep,
AssistantDebugPayload,
AssistantDebugRouteRecord,
AssistantFallbackType,
AssistantProblemAnswerMode,
AssistantRequirement,
UnifiedRetrievalResult,
FaLiveRouteAuditDebug,
RbpLiveRouteAuditDebug
} from "../types/assistant";
import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer";
import type { AnswerStructureV11 } from "../types/stage1Contracts";
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
import type { ClaimBoundAnchorAudit, TargetedEvidenceAcquisitionAudit } from "./assistantClaimBoundEvidence";
import type { AssistantContractsBundleV1 } from "./assistantContractsBundleAssembler";
import type { AssistantOutcomeClassV1 } from "./assistantOrchestrationContracts";
import type { AssistantFollowupUsage } from "./assistantFollowupUsage";
import type { CompanyAnchorSet } from "./companyAnchorResolver";
import type {
DomainPolarityGuardAudit,
EvidenceAdmissibilityAudit,
GroundedAnswerEligibilityAudit,
TemporalGuardAudit
} from "./assistantRuntimeGuards";
import { attachAssistantRuntimeContractShadow } from "./assistantRuntimeContractResolver";
import { attachAssistantStateTransition } from "./assistantStateTransitionRuntimeAdapter";
import { attachAssistantTruthAnswerPolicy } from "./assistantTruthAnswerPolicyRuntimeAdapter";
import { buildStage4AnswerContractAuditV1 } from "./assistantStage4AnswerContractAudit";
type RetrievalStatusItem = AssistantDebugPayload["retrieval_status"][number];
export interface DeepAnalysisDebugPayloadInput {
traceId: string;
promptVersion: string;
schemaVersion: string;
fallbackType: AssistantFallbackType;
routeSummary: RouteHintSummary | null;
fragments: unknown[];
requirementsExtracted: AssistantRequirement[];
coverageReport: AssistantDebugPayload["coverage_report"];
routes: AssistantDebugRouteRecord[];
retrievalStatus: RetrievalStatusItem[];
retrievalResults: UnifiedRetrievalResult[];
groundingCheck: AssistantDebugPayload["answer_grounding_check"];
droppedIntentSegments: string[];
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;
compositionDebug: {
problem_centric_answer_applied?: boolean;
problem_units_used_count?: number;
problem_answer_mode?: AssistantProblemAnswerMode;
problem_unit_ids_used?: string[];
};
addressRuntimeMetaForDeep: AssistantAddressRuntimeMetaForDeep | null | undefined;
outcomeClassV1: AssistantOutcomeClassV1;
assistantOrchestrationContractsV1: AssistantContractsBundleV1["assistantOrchestrationContractsV1"];
answerStructureV11: AnswerStructureV11 | null;
assistantReply: string;
investigationStateSnapshot: InvestigationStateWithProblemUnits | null;
normalizedPayload: NormalizeResponsePayload["normalized"];
}
function toAnalysisContext(input: DeepAnalysisDebugPayloadInput["runtimeAnalysisContext"]): Record<string, unknown> | null {
if (!input.active) {
return null;
}
return {
as_of_date: input.as_of_date,
period_from: input.period_from,
period_to: input.period_to,
source: input.source,
snapshot_mode: input.snapshot_mode
};
}
export function buildDeepAnalysisDebugPayload(input: DeepAnalysisDebugPayloadInput): AssistantDebugPayload {
const analysisContext = toAnalysisContext(input.runtimeAnalysisContext);
const answerContractStage4Audit = buildStage4AnswerContractAuditV1(input.assistantReply);
const debugPayload = {
trace_id: input.traceId,
prompt_version: input.promptVersion,
schema_version: input.schemaVersion,
fallback_type: input.fallbackType,
route_summary: input.routeSummary,
fragments: input.fragments,
requirements_extracted: input.requirementsExtracted,
coverage_report: input.coverageReport,
routes: input.routes,
retrieval_status: input.retrievalStatus,
retrieval_results: input.retrievalResults,
answer_grounding_check: input.groundingCheck,
dropped_intent_segments: input.droppedIntentSegments,
question_type_class: input.questionTypeClass,
company_anchors: input.companyAnchors,
analysis_context_applied: input.runtimeAnalysisContext.active,
analysis_context: analysisContext,
business_scope_raw: input.businessScopeResolution.business_scope_raw,
business_scope_resolved: input.businessScopeResolution.business_scope_resolved,
company_grounding_applied: input.businessScopeResolution.company_grounding_applied,
scope_resolution_reason: input.businessScopeResolution.scope_resolution_reason,
company_scope_resolution_reason: input.businessScopeResolution.scope_resolution_reason,
raw_time_anchor: input.temporalGuard.raw_time_anchor,
raw_time_scope: input.temporalGuard.raw_time_scope,
resolved_time_anchor: input.temporalGuard.resolved_time_anchor,
resolved_primary_period: input.temporalGuard.resolved_primary_period,
effective_primary_period: input.temporalGuard.effective_primary_period,
temporal_guard_input: input.temporalGuard.temporal_guard_input,
temporal_alignment_status: input.temporalGuard.temporal_alignment_status,
temporal_resolution_source: input.temporalGuard.temporal_resolution_source,
temporal_guard_basis: input.temporalGuard.temporal_guard_basis,
temporal_guard_applied: input.temporalGuard.temporal_guard_applied,
temporal_guard_outcome: input.temporalGuard.temporal_guard_outcome,
temporal_guard: input.temporalGuard,
raw_numeric_tokens: input.polarityAudit.raw_numeric_tokens,
classified_numeric_tokens: input.polarityAudit.classified_numeric_tokens,
rejected_as_non_accounts: input.polarityAudit.rejected_as_non_accounts,
resolved_account_anchors: input.polarityAudit.resolved_account_anchors,
domain_polarity_guard: input.polarityAudit,
claim_anchor_audit: input.claimAnchorAudit,
settlement_role: input.claimAnchorAudit.settlement_role ?? null,
settlement_role_resolution_reason: input.claimAnchorAudit.settlement_role_resolution_reason ?? [],
polarity_resolution_status: input.claimAnchorAudit.polarity_resolution_status ?? "not_applicable",
targeted_evidence_acquisition: input.targetedEvidenceAudit,
evidence_admissibility_gate: input.evidenceAdmissibilityGateAudit,
...(input.rbpLiveRouteAudit ? { rbp_live_route_audit: input.rbpLiveRouteAudit } : {}),
...(input.faLiveRouteAudit ? { fa_live_route_audit: input.faLiveRouteAudit } : {}),
eligibility_time_basis: input.groundedAnswerEligibilityGuard.eligibility_time_basis,
grounded_answer_eligibility_guard: input.groundedAnswerEligibilityGuard,
...(input.followupStateUsage ? { followup_state_usage: input.followupStateUsage } : {}),
problem_centric_answer_applied: input.compositionDebug.problem_centric_answer_applied ?? false,
problem_units_used_count: input.compositionDebug.problem_units_used_count ?? 0,
problem_answer_mode: input.compositionDebug.problem_answer_mode ?? "stage1_policy_v11",
...(Array.isArray(input.compositionDebug.problem_unit_ids_used) && input.compositionDebug.problem_unit_ids_used.length > 0
? {
problem_unit_ids_used: input.compositionDebug.problem_unit_ids_used
}
: {}),
address_llm_predecompose_attempted: Boolean(input.addressRuntimeMetaForDeep?.attempted),
address_llm_predecompose_applied: Boolean(input.addressRuntimeMetaForDeep?.applied),
address_llm_predecompose_reason: input.addressRuntimeMetaForDeep?.reason ?? null,
address_llm_predecompose_provider: input.addressRuntimeMetaForDeep?.provider ?? null,
address_fallback_rule_hit: input.addressRuntimeMetaForDeep?.fallbackRuleHit ?? null,
address_tool_gate_decision: input.addressRuntimeMetaForDeep?.toolGateDecision ?? null,
address_tool_gate_reason: input.addressRuntimeMetaForDeep?.toolGateReason ?? null,
address_llm_predecompose_contract: input.addressRuntimeMetaForDeep?.predecomposeContract ?? null,
address_semantic_extraction_contract: input.addressRuntimeMetaForDeep?.semanticExtractionContract ?? null,
orchestration_contract_v1: input.addressRuntimeMetaForDeep?.orchestrationContract ?? null,
assistant_outcome_class_v1: input.outcomeClassV1,
assistant_orchestration_contracts_v1: input.assistantOrchestrationContractsV1,
answer_contract_stage4_v1: answerContractStage4Audit,
answer_structure_v11: input.answerStructureV11,
investigation_state_snapshot: input.investigationStateSnapshot,
normalized: input.normalizedPayload
} as unknown as AssistantDebugPayload;
const debugWithRuntimeContracts = attachAssistantRuntimeContractShadow(debugPayload as unknown as Record<string, unknown>, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status
});
const debugWithTruthAnswerPolicy = attachAssistantTruthAnswerPolicy(debugWithRuntimeContracts, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport as unknown as Record<string, unknown>,
replyType: "deep_analysis"
});
return attachAssistantStateTransition(debugWithTruthAnswerPolicy, {
addressRuntimeMeta: input.addressRuntimeMetaForDeep as unknown as Record<string, unknown> | null | undefined,
groundingStatus: input.groundingCheck.status,
coverageReport: input.coverageReport as unknown as Record<string, unknown>,
replyType: "deep_analysis"
}) as unknown as AssistantDebugPayload;
}