ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.2 - Усилена оркестрацию в deep/address гейте и follow-up binding в assistantService.ts. Починен кейс UTF-8 follow-up refinement (теперь followup_state_usage.applied=true в нужном сценарии). Убраны регрессии по assistantLivingRouter и stage3 lifecycle probe. Корректное поведение для llm canonical candidate (чтобы не уезжало в clarification_required там, где должен быть address factual).
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../types/assistant";
|
||||
import type {
|
||||
AssistantAddressRuntimeMetaForDeep,
|
||||
AssistantDebugPayload,
|
||||
AssistantDebugRouteRecord,
|
||||
AssistantExecutionStateRecord,
|
||||
AssistantMessageResponsePayload,
|
||||
FaLiveRouteAuditDebug,
|
||||
RbpLiveRouteAuditDebug
|
||||
} from "../types/assistant";
|
||||
import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer";
|
||||
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
|
||||
import {
|
||||
@@ -7,10 +15,23 @@ import {
|
||||
type AssistantDeepTurnPackagingRuntimeOutput
|
||||
} from "./assistantDeepTurnPackagingRuntimeAdapter";
|
||||
import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter";
|
||||
import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning";
|
||||
import {
|
||||
finalizeAssistantDeepTurn,
|
||||
type FinalizeAssistantDeepTurnInput
|
||||
} from "./assistantDeepTurnFinalizeRuntimeAdapter";
|
||||
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 RunAssistantDeepTurnResponseRuntimeInput {
|
||||
featureInvestigationStateV1: boolean;
|
||||
@@ -27,16 +48,16 @@ export interface RunAssistantDeepTurnResponseRuntimeInput {
|
||||
};
|
||||
normalizedQuestion: string;
|
||||
routeSummary: RouteHintSummary | null;
|
||||
executionPlan: unknown[];
|
||||
executionPlan: AssistantExecutionPlanItem[];
|
||||
requirementExtractionRequirements: AssistantDeepTurnPackagingRuntimeInput["requirementExtractionRequirements"];
|
||||
coverageEvaluationRequirements: AssistantDeepTurnPackagingRuntimeInput["coverageEvaluationRequirements"];
|
||||
coverageReport: AssistantDeepTurnPackagingRuntimeInput["coverageReport"];
|
||||
groundingCheck: AssistantDeepTurnPackagingRuntimeInput["groundingCheck"];
|
||||
retrievalCalls: unknown[];
|
||||
retrievalResultsRaw: unknown[];
|
||||
retrievalCalls: AssistantRetrievalCallRecord[];
|
||||
retrievalResultsRaw: AssistantRetrievalRawResultRecord[];
|
||||
retrievalResults: AssistantDeepTurnPackagingRuntimeInput["retrievalResults"];
|
||||
questionTypeClass: AssistantDeepTurnPackagingRuntimeInput["questionTypeClass"];
|
||||
companyAnchors: RunAssistantDeepTurnAnalysisRuntimeOutput["companyAnchors"];
|
||||
companyAnchors: CompanyAnchorSet | null;
|
||||
runtimeAnalysisContext: {
|
||||
active: boolean;
|
||||
as_of_date: string | null;
|
||||
@@ -46,22 +67,22 @@ export interface RunAssistantDeepTurnResponseRuntimeInput {
|
||||
snapshot_mode?: "auto" | "force_snapshot" | "force_live";
|
||||
};
|
||||
businessScopeResolution: RunAssistantDeepTurnAnalysisRuntimeOutput["businessScopeResolution"];
|
||||
temporalGuard: unknown;
|
||||
polarityAudit: unknown;
|
||||
claimAnchorAudit: unknown;
|
||||
targetedEvidenceAudit: unknown;
|
||||
evidenceAdmissibilityGateAudit: unknown;
|
||||
rbpLiveRouteAudit: unknown;
|
||||
faLiveRouteAudit: unknown;
|
||||
groundedAnswerEligibilityGuard: unknown;
|
||||
temporalGuard: TemporalGuardAudit;
|
||||
polarityAudit: DomainPolarityGuardAudit;
|
||||
claimAnchorAudit: ClaimBoundAnchorAudit;
|
||||
targetedEvidenceAudit: TargetedEvidenceAcquisitionAudit;
|
||||
evidenceAdmissibilityGateAudit: EvidenceAdmissibilityAudit;
|
||||
rbpLiveRouteAudit: RbpLiveRouteAuditDebug | null;
|
||||
faLiveRouteAudit: FaLiveRouteAuditDebug | null;
|
||||
groundedAnswerEligibilityGuard: GroundedAnswerEligibilityAudit;
|
||||
followupStateUsage: AssistantDeepTurnPackagingRuntimeInput["followupStateUsage"];
|
||||
followupApplied: boolean;
|
||||
composition: AssistantDeepTurnPackagingRuntimeInput["composition"];
|
||||
previousInvestigationState: AssistantDeepTurnPackagingRuntimeInput["previousInvestigationState"];
|
||||
addressRuntimeMetaForDeep: AssistantDeepTurnPackagingRuntimeInput["addressRuntimeMetaForDeep"];
|
||||
extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[];
|
||||
buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array<Record<string, unknown>>;
|
||||
extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => unknown[];
|
||||
buildDebugRoutes: (routeSummary: RouteHintSummary | null) => AssistantDebugRouteRecord[];
|
||||
extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => AssistantExecutionStateRecord[];
|
||||
sanitizeReply: (value: string, fallback?: string) => string;
|
||||
persistInvestigationState: (sessionId: string, snapshot: InvestigationStateWithProblemUnits) => void;
|
||||
messageIdFactory: () => string;
|
||||
@@ -81,14 +102,7 @@ export interface RunAssistantDeepTurnResponseRuntimeOutput {
|
||||
debug: AssistantDebugPayload;
|
||||
}
|
||||
|
||||
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 {
|
||||
function toNullableString(value: string | null | undefined): string | null {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
@@ -96,7 +110,7 @@ function toNullableString(value: unknown): string | null {
|
||||
return trimmed.length > 0 ? trimmed : null;
|
||||
}
|
||||
|
||||
function toStringArray(value: unknown): string[] {
|
||||
function toStringArray(value: string[] | null | undefined): string[] {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
}
|
||||
@@ -105,44 +119,30 @@ function toStringArray(value: unknown): string[] {
|
||||
.filter((item) => item.length > 0);
|
||||
}
|
||||
|
||||
function toSnapshotMode(value: unknown): "auto" | "force_snapshot" | "force_live" {
|
||||
function toSnapshotMode(value: string | null | undefined): "auto" | "force_snapshot" | "force_live" {
|
||||
return value === "force_snapshot" || value === "force_live" ? value : "auto";
|
||||
}
|
||||
|
||||
function normalizeExecutionPlan(value: unknown[]): AssistantDeepTurnPackagingRuntimeInput["executionPlan"] {
|
||||
function normalizeExecutionPlan(
|
||||
value: AssistantExecutionPlanItem[]
|
||||
): 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) ?? {};
|
||||
return value.map((item, index) => ({
|
||||
fragment_id: toNullableString(item.fragment_id) ?? `fragment_${index + 1}`,
|
||||
requirement_ids: toStringArray(item.requirement_ids),
|
||||
route: toNullableString(item.route) ?? "unknown_route",
|
||||
should_execute: Boolean(item.should_execute),
|
||||
no_route_reason: toNullableString(item.no_route_reason ?? null),
|
||||
clarification_reason: toNullableString(item.clarification_reason ?? null)
|
||||
}));
|
||||
}
|
||||
|
||||
function normalizeRuntimeAnalysisContext(
|
||||
value: unknown
|
||||
value: RunAssistantDeepTurnResponseRuntimeInput["runtimeAnalysisContext"] | null | undefined
|
||||
): AssistantDeepTurnPackagingRuntimeInput["runtimeAnalysisContext"] {
|
||||
const source = toRecordObject(value);
|
||||
const source = value;
|
||||
return {
|
||||
active: Boolean(source?.active),
|
||||
as_of_date: toNullableString(source?.as_of_date),
|
||||
@@ -154,9 +154,9 @@ function normalizeRuntimeAnalysisContext(
|
||||
}
|
||||
|
||||
function normalizeBusinessScopeResolution(
|
||||
value: unknown
|
||||
value: RunAssistantDeepTurnAnalysisRuntimeOutput["businessScopeResolution"] | null | undefined
|
||||
): AssistantDeepTurnPackagingRuntimeInput["businessScopeResolution"] {
|
||||
const source = toRecordObject(value);
|
||||
const source = value;
|
||||
return {
|
||||
business_scope_raw: toStringArray(source?.business_scope_raw),
|
||||
business_scope_resolved: toStringArray(source?.business_scope_resolved),
|
||||
@@ -166,9 +166,9 @@ function normalizeBusinessScopeResolution(
|
||||
}
|
||||
|
||||
function normalizeAddressRuntimeMetaForDeep(
|
||||
value: unknown
|
||||
): AssistantDeepTurnPackagingRuntimeInput["addressRuntimeMetaForDeep"] {
|
||||
const source = toRecordObject(value);
|
||||
value: AssistantAddressRuntimeMetaForDeep | null | undefined
|
||||
): AssistantAddressRuntimeMetaForDeep | null {
|
||||
const source = value;
|
||||
if (!source) {
|
||||
return null;
|
||||
}
|
||||
@@ -180,8 +180,8 @@ function normalizeAddressRuntimeMetaForDeep(
|
||||
fallbackRuleHit: toNullableString(source.fallbackRuleHit),
|
||||
toolGateDecision: toNullableString(source.toolGateDecision),
|
||||
toolGateReason: toNullableString(source.toolGateReason),
|
||||
predecomposeContract: toRecordObject(source.predecomposeContract),
|
||||
orchestrationContract: toRecordObject(source.orchestrationContract)
|
||||
predecomposeContract: source.predecomposeContract ?? null,
|
||||
orchestrationContract: source.orchestrationContract ?? null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -204,21 +204,21 @@ export function runAssistantDeepTurnResponseRuntime(
|
||||
coverageEvaluationRequirements: input.coverageEvaluationRequirements,
|
||||
coverageReport: input.coverageReport,
|
||||
groundingCheck: input.groundingCheck,
|
||||
retrievalCalls: normalizeRecordArray(input.retrievalCalls),
|
||||
retrievalResultsRaw: Array.isArray(input.retrievalResultsRaw) ? input.retrievalResultsRaw : [],
|
||||
retrievalCalls: input.retrievalCalls,
|
||||
retrievalResultsRaw: input.retrievalResultsRaw,
|
||||
retrievalResults: input.retrievalResults,
|
||||
questionTypeClass: input.questionTypeClass,
|
||||
companyAnchors: input.companyAnchors,
|
||||
runtimeAnalysisContext: normalizeRuntimeAnalysisContext(input.runtimeAnalysisContext),
|
||||
businessScopeResolution: normalizeBusinessScopeResolution(input.businessScopeResolution),
|
||||
temporalGuard: normalizeRecord(input.temporalGuard),
|
||||
polarityAudit: normalizeRecord(input.polarityAudit),
|
||||
claimAnchorAudit: normalizeRecord(input.claimAnchorAudit),
|
||||
temporalGuard: input.temporalGuard,
|
||||
polarityAudit: input.polarityAudit,
|
||||
claimAnchorAudit: input.claimAnchorAudit,
|
||||
targetedEvidenceAudit: input.targetedEvidenceAudit,
|
||||
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit,
|
||||
rbpLiveRouteAudit: input.rbpLiveRouteAudit ?? null,
|
||||
faLiveRouteAudit: input.faLiveRouteAudit ?? null,
|
||||
groundedAnswerEligibilityGuard: normalizeRecord(input.groundedAnswerEligibilityGuard),
|
||||
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard,
|
||||
followupStateUsage: input.followupStateUsage,
|
||||
followupApplied: input.followupApplied,
|
||||
composition: input.composition,
|
||||
|
||||
Reference in New Issue
Block a user