ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.772.80 - Убрано as any из адресного response-runtime и добавил явную нормализацию перед финализацией / Убран cast в builderе deep-response composition

This commit is contained in:
2026-04-11 10:35:29 +03:00
parent 9f3749fd4a
commit dedf193542
6 changed files with 532 additions and 59 deletions
@@ -1,4 +1,4 @@
import type { AssistantMessageResponsePayload, AssistantReplyType } from "../types/assistant";
import type { AssistantMessageResponsePayload } from "../types/assistant";
import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer";
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
import {
@@ -11,11 +11,6 @@ import {
type FinalizeAssistantDeepTurnInput
} from "./assistantDeepTurnFinalizeRuntimeAdapter";
type CompositionLike = {
reply_type: AssistantReplyType;
[key: string]: unknown;
};
export interface RunAssistantDeepTurnResponseRuntimeInput {
featureInvestigationStateV1: boolean;
featureContractsV11: boolean;
@@ -32,14 +27,14 @@ export interface RunAssistantDeepTurnResponseRuntimeInput {
normalizedQuestion: string;
routeSummary: RouteHintSummary | null;
executionPlan: unknown[];
requirementExtractionRequirements: unknown[];
coverageEvaluationRequirements: unknown[];
coverageReport: unknown;
groundingCheck: unknown;
requirementExtractionRequirements: AssistantDeepTurnPackagingRuntimeInput["requirementExtractionRequirements"];
coverageEvaluationRequirements: AssistantDeepTurnPackagingRuntimeInput["coverageEvaluationRequirements"];
coverageReport: AssistantDeepTurnPackagingRuntimeInput["coverageReport"];
groundingCheck: AssistantDeepTurnPackagingRuntimeInput["groundingCheck"];
retrievalCalls: unknown[];
retrievalResultsRaw: unknown[];
retrievalResults: unknown[];
questionTypeClass: string;
retrievalResults: AssistantDeepTurnPackagingRuntimeInput["retrievalResults"];
questionTypeClass: AssistantDeepTurnPackagingRuntimeInput["questionTypeClass"];
companyAnchors: unknown;
runtimeAnalysisContext: unknown;
businessScopeResolution: unknown;
@@ -51,10 +46,10 @@ export interface RunAssistantDeepTurnResponseRuntimeInput {
rbpLiveRouteAudit: unknown;
faLiveRouteAudit: unknown;
groundedAnswerEligibilityGuard: unknown;
followupStateUsage: unknown;
followupStateUsage: AssistantDeepTurnPackagingRuntimeInput["followupStateUsage"];
followupApplied: boolean;
composition: CompositionLike;
previousInvestigationState: InvestigationStateWithProblemUnits | null | undefined;
composition: AssistantDeepTurnPackagingRuntimeInput["composition"];
previousInvestigationState: AssistantDeepTurnPackagingRuntimeInput["previousInvestigationState"];
addressRuntimeMetaForDeep: unknown;
extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[];
buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array<Record<string, unknown>>;
@@ -78,6 +73,110 @@ export interface RunAssistantDeepTurnResponseRuntimeOutput {
debug: Record<string, unknown>;
}
function toRecordObject(value: unknown): Record<string, unknown> | null {
if (!value || typeof value !== "object") {
return null;
}
return value as Record<string, unknown>;
}
function toNullableString(value: unknown): string | null {
if (typeof value !== "string") {
return null;
}
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : null;
}
function toStringArray(value: unknown): string[] {
if (!Array.isArray(value)) {
return [];
}
return value
.map((item) => (typeof item === "string" ? item.trim() : ""))
.filter((item) => item.length > 0);
}
function toSnapshotMode(value: unknown): "auto" | "force_snapshot" | "force_live" {
return value === "force_snapshot" || value === "force_live" ? value : "auto";
}
function normalizeExecutionPlan(value: unknown[]): AssistantDeepTurnPackagingRuntimeInput["executionPlan"] {
if (!Array.isArray(value)) {
return [];
}
return value.map((item, index) => {
const source = toRecordObject(item);
return {
fragment_id: toNullableString(source?.fragment_id) ?? `fragment_${index + 1}`,
requirement_ids: toStringArray(source?.requirement_ids),
route: toNullableString(source?.route) ?? "unknown_route",
should_execute: Boolean(source?.should_execute),
no_route_reason: toNullableString(source?.no_route_reason),
clarification_reason: toNullableString(source?.clarification_reason)
};
});
}
function normalizeRecordArray(value: unknown[]): Array<Record<string, unknown>> {
if (!Array.isArray(value)) {
return [];
}
return value
.map((item) => toRecordObject(item))
.filter((item): item is Record<string, unknown> => Boolean(item));
}
function normalizeRecord(value: unknown): Record<string, unknown> {
return toRecordObject(value) ?? {};
}
function normalizeRuntimeAnalysisContext(
value: unknown
): AssistantDeepTurnPackagingRuntimeInput["runtimeAnalysisContext"] {
const source = toRecordObject(value);
return {
active: Boolean(source?.active),
as_of_date: toNullableString(source?.as_of_date),
period_from: toNullableString(source?.period_from),
period_to: toNullableString(source?.period_to),
source: toNullableString(source?.source),
snapshot_mode: toSnapshotMode(source?.snapshot_mode)
};
}
function normalizeBusinessScopeResolution(
value: unknown
): AssistantDeepTurnPackagingRuntimeInput["businessScopeResolution"] {
const source = toRecordObject(value);
return {
business_scope_raw: toStringArray(source?.business_scope_raw),
business_scope_resolved: toStringArray(source?.business_scope_resolved),
company_grounding_applied: Boolean(source?.company_grounding_applied),
scope_resolution_reason: toStringArray(source?.scope_resolution_reason)
};
}
function normalizeAddressRuntimeMetaForDeep(
value: unknown
): AssistantDeepTurnPackagingRuntimeInput["addressRuntimeMetaForDeep"] {
const source = toRecordObject(value);
if (!source) {
return null;
}
return {
attempted: typeof source.attempted === "boolean" ? source.attempted : undefined,
applied: typeof source.applied === "boolean" ? source.applied : undefined,
reason: toNullableString(source.reason),
provider: toNullableString(source.provider),
fallbackRuleHit: toNullableString(source.fallbackRuleHit),
toolGateDecision: toNullableString(source.toolGateDecision),
toolGateReason: toNullableString(source.toolGateReason),
predecomposeContract: toRecordObject(source.predecomposeContract),
orchestrationContract: toRecordObject(source.orchestrationContract)
};
}
export function runAssistantDeepTurnResponseRuntime(
input: RunAssistantDeepTurnResponseRuntimeInput
): RunAssistantDeepTurnResponseRuntimeOutput {
@@ -92,33 +191,33 @@ export function runAssistantDeepTurnResponseRuntime(
normalized: input.normalized,
normalizedQuestion: input.normalizedQuestion,
routeSummary: input.routeSummary,
executionPlan: input.executionPlan as any,
requirementExtractionRequirements: input.requirementExtractionRequirements as any,
coverageEvaluationRequirements: input.coverageEvaluationRequirements as any,
coverageReport: input.coverageReport as any,
groundingCheck: input.groundingCheck as any,
retrievalCalls: input.retrievalCalls as any,
retrievalResultsRaw: input.retrievalResultsRaw as any,
retrievalResults: input.retrievalResults as any,
executionPlan: normalizeExecutionPlan(input.executionPlan),
requirementExtractionRequirements: input.requirementExtractionRequirements,
coverageEvaluationRequirements: input.coverageEvaluationRequirements,
coverageReport: input.coverageReport,
groundingCheck: input.groundingCheck,
retrievalCalls: normalizeRecordArray(input.retrievalCalls),
retrievalResultsRaw: Array.isArray(input.retrievalResultsRaw) ? input.retrievalResultsRaw : [],
retrievalResults: input.retrievalResults,
questionTypeClass: input.questionTypeClass,
companyAnchors: input.companyAnchors,
runtimeAnalysisContext: input.runtimeAnalysisContext as any,
businessScopeResolution: input.businessScopeResolution as any,
temporalGuard: input.temporalGuard as any,
polarityAudit: input.polarityAudit as any,
claimAnchorAudit: input.claimAnchorAudit as any,
targetedEvidenceAudit: input.targetedEvidenceAudit as any,
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit as any,
rbpLiveRouteAudit: input.rbpLiveRouteAudit as any,
faLiveRouteAudit: input.faLiveRouteAudit as any,
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard as any,
followupStateUsage: input.followupStateUsage as any,
runtimeAnalysisContext: normalizeRuntimeAnalysisContext(input.runtimeAnalysisContext),
businessScopeResolution: normalizeBusinessScopeResolution(input.businessScopeResolution),
temporalGuard: normalizeRecord(input.temporalGuard),
polarityAudit: normalizeRecord(input.polarityAudit),
claimAnchorAudit: normalizeRecord(input.claimAnchorAudit),
targetedEvidenceAudit: input.targetedEvidenceAudit,
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit,
rbpLiveRouteAudit: input.rbpLiveRouteAudit ?? null,
faLiveRouteAudit: input.faLiveRouteAudit ?? null,
groundedAnswerEligibilityGuard: normalizeRecord(input.groundedAnswerEligibilityGuard),
followupStateUsage: input.followupStateUsage,
followupApplied: input.followupApplied,
composition: input.composition as any,
composition: input.composition,
featureContractsV11: input.featureContractsV11,
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
previousInvestigationState: input.previousInvestigationState ?? null,
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep as any,
addressRuntimeMetaForDeep: normalizeAddressRuntimeMetaForDeep(input.addressRuntimeMetaForDeep),
extractDroppedIntentSegments: input.extractDroppedIntentSegments,
buildDebugRoutes: input.buildDebugRoutes,
extractExecutionState: input.extractExecutionState,