ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.44 - Вынос deep-response склейку из assistantService в новый bridge и Переподключение assistantService на этот адаптер

This commit is contained in:
dctouch 2026-04-10 23:43:55 +03:00
parent 80754e016c
commit fcfcba47b0
6 changed files with 355 additions and 97 deletions

View File

@ -1374,7 +1374,38 @@ Validation:
- `assistantDeepTurnPackagingRuntimeAdapter.test.ts` - `assistantDeepTurnPackagingRuntimeAdapter.test.ts`
- `assistantWave10SettlementCorrectiveRegression.test.ts` - `assistantWave10SettlementCorrectiveRegression.test.ts`
Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 + 2.30 + 2.31 + 2.32 + 2.33 + 2.34 + 2.35 + 2.36 + 2.37 + 2.38 + 2.39 + 2.40 + 2.41 + 2.42 + 2.43 completed)** Implemented in current pass (Phase 2.44):
1. Extracted deep-response bridge (`deepTurnResponseRuntime` wiring) from `assistantService` into dedicated runtime adapter:
- `assistantDeepTurnResponseAttemptRuntimeAdapter.ts`
- introduced:
- `runAssistantDeepTurnResponseAttemptRuntime(...)`
2. Centralized deep-response handoff logic (behavior-preserving):
- mapping from deep-analysis runtime output into response/packaging/finalization runtime contract moved behind a single runtime boundary;
- preserved existing debug/state persistence hooks and session finalization callbacks.
3. Rewired `assistantService` to consume deep-response attempt runtime adapter.
4. Added focused unit tests:
- `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts`
Validation:
1. `npm run build` passed.
2. Targeted living/address/deep followup pack passed:
- `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts`
- `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts`
- `assistantDeepTurnAnalysisRuntimeAdapter.test.ts`
- `assistantAddressLaneResponseAttemptRuntimeAdapter.test.ts`
- `assistantLivingChatAttemptRuntimeAdapter.test.ts`
- `assistantAddressLaneAttemptRuntimeAdapter.test.ts`
- `assistantUserTurnBootstrapRuntimeAdapter.test.ts`
- `assistantLivingChatLlmRuntimeAdapter.test.ts`
- `assistantLivingChatHandlerRuntimeAdapter.test.ts`
- `assistantLivingChatRuntimeAdapter.test.ts`
- `assistantAddressRuntimeAdapter.test.ts`
- `assistantAddressLaneResponseRuntimeAdapter.test.ts`
- `assistantDeepTurnResponseRuntimeAdapter.test.ts`
- `assistantDeepTurnPackagingRuntimeAdapter.test.ts`
- `assistantWave10SettlementCorrectiveRegression.test.ts`
Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 + 2.30 + 2.31 + 2.32 + 2.33 + 2.34 + 2.35 + 2.36 + 2.37 + 2.38 + 2.39 + 2.40 + 2.41 + 2.42 + 2.43 + 2.44 completed)**
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards) ## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)

View File

@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAssistantDeepTurnResponseAttemptRuntime = runAssistantDeepTurnResponseAttemptRuntime;
const assistantDeepTurnResponseRuntimeAdapter_1 = require("./assistantDeepTurnResponseRuntimeAdapter");
function runAssistantDeepTurnResponseAttemptRuntime(input) {
const runDeepTurnResponseRuntimeSafe = input.runDeepTurnResponseRuntime ?? assistantDeepTurnResponseRuntimeAdapter_1.runAssistantDeepTurnResponseRuntime;
const analysis = input.deepTurnAnalysisRuntime;
const responseRuntime = runDeepTurnResponseRuntimeSafe({
featureInvestigationStateV1: input.featureInvestigationStateV1,
featureContractsV11: input.featureContractsV11,
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
sessionId: input.sessionId,
questionId: input.questionId,
userMessage: input.userMessage,
normalized: input.normalized,
normalizedQuestion: input.normalizedQuestion,
routeSummary: analysis.resolvedRouteSummary,
executionPlan: analysis.executionPlan,
requirementExtractionRequirements: analysis.requirementExtraction.requirements,
coverageEvaluationRequirements: analysis.coverageEvaluation.requirements,
coverageReport: analysis.coverageEvaluation.coverage,
groundingCheck: analysis.groundingCheck,
retrievalCalls: analysis.retrievalCalls,
retrievalResultsRaw: analysis.retrievalResultsRaw,
retrievalResults: analysis.retrievalResults,
questionTypeClass: analysis.questionTypeClass,
companyAnchors: analysis.companyAnchors,
runtimeAnalysisContext: input.runtimeAnalysisContext,
businessScopeResolution: analysis.businessScopeResolution,
temporalGuard: analysis.temporalGuard,
polarityAudit: analysis.polarityGuardResult.audit,
claimAnchorAudit: analysis.claimAnchorAudit,
targetedEvidenceAudit: analysis.targetedEvidenceResult.audit,
evidenceAdmissibilityGateAudit: analysis.evidenceGateResult.audit,
rbpLiveRouteAudit: analysis.rbpLiveRouteAudit,
faLiveRouteAudit: analysis.faLiveRouteAudit,
groundedAnswerEligibilityGuard: analysis.groundedAnswerEligibilityGuard,
followupStateUsage: input.followupStateUsage,
followupApplied: input.followupApplied,
composition: analysis.composition,
previousInvestigationState: input.previousInvestigationState ?? null,
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep,
extractDroppedIntentSegments: input.extractDroppedIntentSegments,
buildDebugRoutes: input.buildDebugRoutes,
extractExecutionState: input.extractExecutionState,
sanitizeReply: input.sanitizeReply,
persistInvestigationState: input.persistInvestigationState,
messageIdFactory: input.messageIdFactory,
appendItem: input.appendItem,
getSession: input.getSession,
persistSession: input.persistSession,
cloneConversation: input.cloneConversation,
logEvent: input.logEvent,
runPackagingRuntime: input.runPackagingRuntime,
runFinalizeDeepTurn: input.runFinalizeDeepTurn
});
return {
response: responseRuntime.response,
debug: responseRuntime.debug
};
}

View File

@ -65,10 +65,8 @@ const assistantCanon_1 = __importStar(require("./assistantCanon"));
const assistantAddressLaneResponseAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneResponseAttemptRuntimeAdapter")); const assistantAddressLaneResponseAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneResponseAttemptRuntimeAdapter"));
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding")); const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
const assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisAttemptRuntimeAdapter")); const assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisAttemptRuntimeAdapter"));
const assistantDeepTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnFinalizeRuntimeAdapter"));
const assistantDeepTurnPackagingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPackagingRuntimeAdapter"));
const assistantDeepTurnNormalizationRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnNormalizationRuntimeAdapter")); const assistantDeepTurnNormalizationRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnNormalizationRuntimeAdapter"));
const assistantDeepTurnResponseRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnResponseRuntimeAdapter")); const assistantDeepTurnResponseAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnResponseAttemptRuntimeAdapter"));
const assistantAddressRuntimeAdapter_1 = __importStar(require("./assistantAddressRuntimeAdapter")); const assistantAddressRuntimeAdapter_1 = __importStar(require("./assistantAddressRuntimeAdapter"));
const assistantAddressLaneAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneAttemptRuntimeAdapter")); const assistantAddressLaneAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneAttemptRuntimeAdapter"));
const assistantLivingChatAttemptRuntimeAdapter_1 = __importStar(require("./assistantLivingChatAttemptRuntimeAdapter")); const assistantLivingChatAttemptRuntimeAdapter_1 = __importStar(require("./assistantLivingChatAttemptRuntimeAdapter"));
@ -4532,27 +4530,7 @@ class AssistantService {
collectFaLiveRouteAudit, collectFaLiveRouteAudit,
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload)
}); });
const companyAnchors = deepTurnAnalysisRuntime.companyAnchors; const deepTurnResponseRuntime = (0, assistantDeepTurnResponseAttemptRuntimeAdapter_1.runAssistantDeepTurnResponseAttemptRuntime)({
const temporalGuard = deepTurnAnalysisRuntime.temporalGuard;
const claimAnchorAudit = deepTurnAnalysisRuntime.claimAnchorAudit;
const businessScopeResolution = deepTurnAnalysisRuntime.businessScopeResolution;
const resolvedRouteSummary = deepTurnAnalysisRuntime.resolvedRouteSummary;
const requirementExtraction = deepTurnAnalysisRuntime.requirementExtraction;
const executionPlan = deepTurnAnalysisRuntime.executionPlan;
const retrievalCalls = deepTurnAnalysisRuntime.retrievalCalls;
const retrievalResultsRaw = deepTurnAnalysisRuntime.retrievalResultsRaw;
const retrievalResults = deepTurnAnalysisRuntime.retrievalResults;
const polarityGuardResult = deepTurnAnalysisRuntime.polarityGuardResult;
const targetedEvidenceResult = deepTurnAnalysisRuntime.targetedEvidenceResult;
const evidenceGateResult = deepTurnAnalysisRuntime.evidenceGateResult;
const rbpLiveRouteAudit = deepTurnAnalysisRuntime.rbpLiveRouteAudit;
const faLiveRouteAudit = deepTurnAnalysisRuntime.faLiveRouteAudit;
const coverageEvaluation = deepTurnAnalysisRuntime.coverageEvaluation;
const groundedAnswerEligibilityGuard = deepTurnAnalysisRuntime.groundedAnswerEligibilityGuard;
const groundingCheck = deepTurnAnalysisRuntime.groundingCheck;
const questionTypeClass = deepTurnAnalysisRuntime.questionTypeClass;
const composition = deepTurnAnalysisRuntime.composition;
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseRuntimeAdapter_1.runAssistantDeepTurnResponseRuntime)({
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1, featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11, featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11, featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
@ -4566,30 +4544,10 @@ class AssistantService {
normalized: normalized.normalized normalized: normalized.normalized
}, },
normalizedQuestion: followupBinding.normalizedQuestion, normalizedQuestion: followupBinding.normalizedQuestion,
routeSummary: resolvedRouteSummary, deepTurnAnalysisRuntime,
executionPlan,
requirementExtractionRequirements: requirementExtraction.requirements,
coverageEvaluationRequirements: coverageEvaluation.requirements,
coverageReport: coverageEvaluation.coverage,
groundingCheck,
retrievalCalls,
retrievalResultsRaw,
retrievalResults,
questionTypeClass,
companyAnchors,
runtimeAnalysisContext, runtimeAnalysisContext,
businessScopeResolution,
temporalGuard,
polarityAudit: polarityGuardResult.audit,
claimAnchorAudit,
targetedEvidenceAudit: targetedEvidenceResult.audit,
evidenceAdmissibilityGateAudit: evidenceGateResult.audit,
rbpLiveRouteAudit,
faLiveRouteAudit,
groundedAnswerEligibilityGuard,
followupStateUsage: followupBinding.usage, followupStateUsage: followupBinding.usage,
followupApplied: Boolean(followupBinding.usage?.applied), followupApplied: Boolean(followupBinding.usage?.applied),
composition,
previousInvestigationState: session.investigation_state, previousInvestigationState: session.investigation_state,
addressRuntimeMetaForDeep, addressRuntimeMetaForDeep,
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload), extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
@ -4602,9 +4560,7 @@ class AssistantService {
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId), getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState), persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
cloneConversation: (items) => cloneItems(items), cloneConversation: (items) => cloneItems(items),
logEvent: (payload) => (0, log_1.logJson)(payload), logEvent: (payload) => (0, log_1.logJson)(payload)
runPackagingRuntime: (input) => (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)(input),
runFinalizeDeepTurn: (input) => (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)(input)
}); });
return deepTurnResponseRuntime.response; return deepTurnResponseRuntime.response;
} }

View File

@ -0,0 +1,116 @@
import type { AssistantMessageResponsePayload } from "../types/assistant";
import type { NormalizeResponsePayload } from "../types/normalizer";
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter";
import {
runAssistantDeepTurnResponseRuntime,
type RunAssistantDeepTurnResponseRuntimeInput,
type RunAssistantDeepTurnResponseRuntimeOutput
} from "./assistantDeepTurnResponseRuntimeAdapter";
export interface RunAssistantDeepTurnResponseAttemptRuntimeInput<
ResponseType = AssistantMessageResponsePayload
> {
featureInvestigationStateV1: boolean;
featureContractsV11: boolean;
featureAnswerPolicyV11: boolean;
sessionId: string;
questionId: string;
userMessage: string;
normalized: {
trace_id: string;
prompt_version: string;
schema_version: string;
normalized: NormalizeResponsePayload["normalized"];
};
normalizedQuestion: string;
deepTurnAnalysisRuntime: RunAssistantDeepTurnAnalysisRuntimeOutput;
runtimeAnalysisContext: unknown;
followupStateUsage: unknown;
followupApplied: boolean;
previousInvestigationState: InvestigationStateWithProblemUnits | null | undefined;
addressRuntimeMetaForDeep: unknown;
extractDroppedIntentSegments: RunAssistantDeepTurnResponseRuntimeInput["extractDroppedIntentSegments"];
buildDebugRoutes: RunAssistantDeepTurnResponseRuntimeInput["buildDebugRoutes"];
extractExecutionState: RunAssistantDeepTurnResponseRuntimeInput["extractExecutionState"];
sanitizeReply: RunAssistantDeepTurnResponseRuntimeInput["sanitizeReply"];
persistInvestigationState: RunAssistantDeepTurnResponseRuntimeInput["persistInvestigationState"];
messageIdFactory: RunAssistantDeepTurnResponseRuntimeInput["messageIdFactory"];
appendItem: RunAssistantDeepTurnResponseRuntimeInput["appendItem"];
getSession: RunAssistantDeepTurnResponseRuntimeInput["getSession"];
persistSession: RunAssistantDeepTurnResponseRuntimeInput["persistSession"];
cloneConversation: RunAssistantDeepTurnResponseRuntimeInput["cloneConversation"];
logEvent: RunAssistantDeepTurnResponseRuntimeInput["logEvent"];
runPackagingRuntime?: RunAssistantDeepTurnResponseRuntimeInput["runPackagingRuntime"];
runFinalizeDeepTurn?: RunAssistantDeepTurnResponseRuntimeInput["runFinalizeDeepTurn"];
runDeepTurnResponseRuntime?: (
input: RunAssistantDeepTurnResponseRuntimeInput
) => RunAssistantDeepTurnResponseRuntimeOutput;
}
export function runAssistantDeepTurnResponseAttemptRuntime<
ResponseType = AssistantMessageResponsePayload
>(
input: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>
): {
response: ResponseType;
debug: Record<string, unknown>;
} {
const runDeepTurnResponseRuntimeSafe =
input.runDeepTurnResponseRuntime ?? runAssistantDeepTurnResponseRuntime;
const analysis = input.deepTurnAnalysisRuntime;
const responseRuntime = runDeepTurnResponseRuntimeSafe({
featureInvestigationStateV1: input.featureInvestigationStateV1,
featureContractsV11: input.featureContractsV11,
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
sessionId: input.sessionId,
questionId: input.questionId,
userMessage: input.userMessage,
normalized: input.normalized,
normalizedQuestion: input.normalizedQuestion,
routeSummary: analysis.resolvedRouteSummary,
executionPlan: analysis.executionPlan,
requirementExtractionRequirements: analysis.requirementExtraction.requirements,
coverageEvaluationRequirements: analysis.coverageEvaluation.requirements,
coverageReport: analysis.coverageEvaluation.coverage,
groundingCheck: analysis.groundingCheck,
retrievalCalls: analysis.retrievalCalls,
retrievalResultsRaw: analysis.retrievalResultsRaw,
retrievalResults: analysis.retrievalResults,
questionTypeClass: analysis.questionTypeClass,
companyAnchors: analysis.companyAnchors,
runtimeAnalysisContext: input.runtimeAnalysisContext,
businessScopeResolution: analysis.businessScopeResolution,
temporalGuard: analysis.temporalGuard,
polarityAudit: analysis.polarityGuardResult.audit,
claimAnchorAudit: analysis.claimAnchorAudit,
targetedEvidenceAudit: analysis.targetedEvidenceResult.audit,
evidenceAdmissibilityGateAudit: analysis.evidenceGateResult.audit,
rbpLiveRouteAudit: analysis.rbpLiveRouteAudit,
faLiveRouteAudit: analysis.faLiveRouteAudit,
groundedAnswerEligibilityGuard: analysis.groundedAnswerEligibilityGuard,
followupStateUsage: input.followupStateUsage,
followupApplied: input.followupApplied,
composition: analysis.composition as any,
previousInvestigationState: input.previousInvestigationState ?? null,
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep,
extractDroppedIntentSegments: input.extractDroppedIntentSegments,
buildDebugRoutes: input.buildDebugRoutes,
extractExecutionState: input.extractExecutionState,
sanitizeReply: input.sanitizeReply,
persistInvestigationState: input.persistInvestigationState,
messageIdFactory: input.messageIdFactory,
appendItem: input.appendItem,
getSession: input.getSession,
persistSession: input.persistSession,
cloneConversation: input.cloneConversation,
logEvent: input.logEvent,
runPackagingRuntime: input.runPackagingRuntime,
runFinalizeDeepTurn: input.runFinalizeDeepTurn
});
return {
response: responseRuntime.response as ResponseType,
debug: responseRuntime.debug
};
}

View File

@ -19,10 +19,8 @@ import * as assistantCanon_1 from "./assistantCanon";
import * as assistantAddressLaneResponseAttemptRuntimeAdapter_1 from "./assistantAddressLaneResponseAttemptRuntimeAdapter"; import * as assistantAddressLaneResponseAttemptRuntimeAdapter_1 from "./assistantAddressLaneResponseAttemptRuntimeAdapter";
import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding"; import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding";
import * as assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter"; import * as assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter";
import * as assistantDeepTurnFinalizeRuntimeAdapter_1 from "./assistantDeepTurnFinalizeRuntimeAdapter";
import * as assistantDeepTurnPackagingRuntimeAdapter_1 from "./assistantDeepTurnPackagingRuntimeAdapter";
import * as assistantDeepTurnNormalizationRuntimeAdapter_1 from "./assistantDeepTurnNormalizationRuntimeAdapter"; import * as assistantDeepTurnNormalizationRuntimeAdapter_1 from "./assistantDeepTurnNormalizationRuntimeAdapter";
import * as assistantDeepTurnResponseRuntimeAdapter_1 from "./assistantDeepTurnResponseRuntimeAdapter"; import * as assistantDeepTurnResponseAttemptRuntimeAdapter_1 from "./assistantDeepTurnResponseAttemptRuntimeAdapter";
import * as assistantAddressRuntimeAdapter_1 from "./assistantAddressRuntimeAdapter"; import * as assistantAddressRuntimeAdapter_1 from "./assistantAddressRuntimeAdapter";
import * as assistantAddressLaneAttemptRuntimeAdapter_1 from "./assistantAddressLaneAttemptRuntimeAdapter"; import * as assistantAddressLaneAttemptRuntimeAdapter_1 from "./assistantAddressLaneAttemptRuntimeAdapter";
import * as assistantLivingChatAttemptRuntimeAdapter_1 from "./assistantLivingChatAttemptRuntimeAdapter"; import * as assistantLivingChatAttemptRuntimeAdapter_1 from "./assistantLivingChatAttemptRuntimeAdapter";
@ -4487,27 +4485,7 @@ export class AssistantService {
collectFaLiveRouteAudit, collectFaLiveRouteAudit,
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload)
}); });
const companyAnchors = deepTurnAnalysisRuntime.companyAnchors; const deepTurnResponseRuntime = (0, assistantDeepTurnResponseAttemptRuntimeAdapter_1.runAssistantDeepTurnResponseAttemptRuntime)({
const temporalGuard = deepTurnAnalysisRuntime.temporalGuard;
const claimAnchorAudit = deepTurnAnalysisRuntime.claimAnchorAudit;
const businessScopeResolution = deepTurnAnalysisRuntime.businessScopeResolution;
const resolvedRouteSummary = deepTurnAnalysisRuntime.resolvedRouteSummary;
const requirementExtraction = deepTurnAnalysisRuntime.requirementExtraction;
const executionPlan = deepTurnAnalysisRuntime.executionPlan;
const retrievalCalls = deepTurnAnalysisRuntime.retrievalCalls;
const retrievalResultsRaw = deepTurnAnalysisRuntime.retrievalResultsRaw;
const retrievalResults = deepTurnAnalysisRuntime.retrievalResults;
const polarityGuardResult = deepTurnAnalysisRuntime.polarityGuardResult;
const targetedEvidenceResult = deepTurnAnalysisRuntime.targetedEvidenceResult;
const evidenceGateResult = deepTurnAnalysisRuntime.evidenceGateResult;
const rbpLiveRouteAudit = deepTurnAnalysisRuntime.rbpLiveRouteAudit;
const faLiveRouteAudit = deepTurnAnalysisRuntime.faLiveRouteAudit;
const coverageEvaluation = deepTurnAnalysisRuntime.coverageEvaluation;
const groundedAnswerEligibilityGuard = deepTurnAnalysisRuntime.groundedAnswerEligibilityGuard;
const groundingCheck = deepTurnAnalysisRuntime.groundingCheck;
const questionTypeClass = deepTurnAnalysisRuntime.questionTypeClass;
const composition = deepTurnAnalysisRuntime.composition;
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseRuntimeAdapter_1.runAssistantDeepTurnResponseRuntime)({
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1, featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11, featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11, featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
@ -4521,30 +4499,10 @@ export class AssistantService {
normalized: normalized.normalized normalized: normalized.normalized
}, },
normalizedQuestion: followupBinding.normalizedQuestion, normalizedQuestion: followupBinding.normalizedQuestion,
routeSummary: resolvedRouteSummary, deepTurnAnalysisRuntime,
executionPlan,
requirementExtractionRequirements: requirementExtraction.requirements,
coverageEvaluationRequirements: coverageEvaluation.requirements,
coverageReport: coverageEvaluation.coverage,
groundingCheck,
retrievalCalls,
retrievalResultsRaw,
retrievalResults,
questionTypeClass,
companyAnchors,
runtimeAnalysisContext, runtimeAnalysisContext,
businessScopeResolution,
temporalGuard,
polarityAudit: polarityGuardResult.audit,
claimAnchorAudit,
targetedEvidenceAudit: targetedEvidenceResult.audit,
evidenceAdmissibilityGateAudit: evidenceGateResult.audit,
rbpLiveRouteAudit,
faLiveRouteAudit,
groundedAnswerEligibilityGuard,
followupStateUsage: followupBinding.usage, followupStateUsage: followupBinding.usage,
followupApplied: Boolean(followupBinding.usage?.applied), followupApplied: Boolean(followupBinding.usage?.applied),
composition,
previousInvestigationState: session.investigation_state, previousInvestigationState: session.investigation_state,
addressRuntimeMetaForDeep, addressRuntimeMetaForDeep,
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload), extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
@ -4557,9 +4515,7 @@ export class AssistantService {
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId), getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState), persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
cloneConversation: (items) => cloneItems(items), cloneConversation: (items) => cloneItems(items),
logEvent: (payload) => (0, log_1.logJson)(payload), logEvent: (payload) => (0, log_1.logJson)(payload)
runPackagingRuntime: (input) => (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)(input),
runFinalizeDeepTurn: (input) => (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)(input)
}); });
return deepTurnResponseRuntime.response; return deepTurnResponseRuntime.response;
} }

View File

@ -0,0 +1,138 @@
import { describe, expect, it, vi } from "vitest";
import { runAssistantDeepTurnResponseAttemptRuntime } from "../src/services/assistantDeepTurnResponseAttemptRuntimeAdapter";
function buildDeepRuntime() {
return {
companyAnchors: { accounts: ["60.01"] },
temporalGuard: { primary_period_window: { from: "2020-07-01", to: "2020-07-31" } },
claimAnchorAudit: { claim_type: "prove_settlement_closure_state" },
businessScopeResolution: { business_scope_resolved: ["company_specific_accounting"] },
resolvedRouteSummary: { mode: "deterministic_v2", decisions: [] as any[] },
requirementExtraction: {
requirements: [{ id: "R1" }],
byFragment: new Map<string, string[]>([["F1", ["R1"]]])
},
executionPlan: [{ fragment_id: "F1", route: "store_canonical" }],
retrievalCalls: [{ fragment_id: "F1", route: "store_canonical" }],
retrievalResultsRaw: [{ fragment_id: "F1", route: "store_canonical", raw_result: {} }],
retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"] }],
polarityGuardResult: { audit: { polarity: "supplier_payable" } },
targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: 1 } },
evidenceGateResult: { audit: { admissible_evidence_count: 2 } },
rbpLiveRouteAudit: { routed: 1 },
faLiveRouteAudit: { routed: 1 },
coverageEvaluation: {
requirements: [{ id: "R1" }],
coverage: { requirements_total: 1, requirements_covered: 1 }
},
groundedAnswerEligibilityGuard: { eligible: true },
groundingCheck: { status: "grounded", reasons: [] },
questionTypeClass: "causal_trace",
composition: { reply_type: "factual_with_explanation", assistant_reply: "ok" }
} as any;
}
function buildInput(overrides: Record<string, unknown> = {}) {
return {
featureInvestigationStateV1: true,
featureContractsV11: true,
featureAnswerPolicyV11: true,
sessionId: "asst-1",
questionId: "msg-q1",
userMessage: "почему долг не закрылся",
normalized: {
trace_id: "trace-1",
prompt_version: "normalizer_v2_0_2",
schema_version: "normalized_query_v2_0_2",
normalized: { fragments: [] }
},
normalizedQuestion: "почему долг не закрылся",
deepTurnAnalysisRuntime: buildDeepRuntime(),
runtimeAnalysisContext: { as_of_date: "2020-07-31" },
followupStateUsage: { applied: true },
followupApplied: true,
previousInvestigationState: null,
addressRuntimeMetaForDeep: null,
extractDroppedIntentSegments: () => [],
buildDebugRoutes: () => [],
extractExecutionState: () => [],
sanitizeReply: (value: string) => value,
persistInvestigationState: () => {},
messageIdFactory: () => "msg-a1",
appendItem: () => {},
getSession: () => ({ session_id: "asst-1", items: [] }),
persistSession: () => {},
cloneConversation: () => [],
logEvent: () => {},
...overrides
} as any;
}
describe("assistant deep turn response attempt runtime adapter", () => {
it("maps deep-analysis runtime output into response runtime input", () => {
const runDeepTurnResponseRuntime = vi.fn(() => ({
response: {
ok: true,
session_id: "asst-1",
conversation: [],
debug: { trace_id: "trace-1" }
},
debug: { trace_id: "trace-1" }
}));
const runtime = runAssistantDeepTurnResponseAttemptRuntime(
buildInput({
runDeepTurnResponseRuntime
})
);
expect(runDeepTurnResponseRuntime).toHaveBeenCalledWith(
expect.objectContaining({
routeSummary: expect.objectContaining({ mode: "deterministic_v2" }),
requirementExtractionRequirements: [{ id: "R1" }],
coverageEvaluationRequirements: [{ id: "R1" }],
questionTypeClass: "causal_trace",
polarityAudit: { polarity: "supplier_payable" },
targetedEvidenceAudit: { targeted_evidence_hit_rate: 1 },
evidenceAdmissibilityGateAudit: { admissible_evidence_count: 2 },
composition: expect.objectContaining({ reply_type: "factual_with_explanation" })
})
);
expect(runtime.response).toEqual(
expect.objectContaining({
ok: true
})
);
});
it("forwards callbacks and state flags", () => {
const extractDroppedIntentSegments = vi.fn(() => []);
const persistInvestigationState = vi.fn();
const runDeepTurnResponseRuntime = vi.fn(() => ({
response: {
ok: true,
session_id: "asst-1",
conversation: [],
debug: null
},
debug: {}
}));
runAssistantDeepTurnResponseAttemptRuntime(
buildInput({
followupApplied: false,
extractDroppedIntentSegments,
persistInvestigationState,
runDeepTurnResponseRuntime
})
);
expect(runDeepTurnResponseRuntime).toHaveBeenCalledWith(
expect.objectContaining({
followupApplied: false,
extractDroppedIntentSegments,
persistInvestigationState
})
);
});
});