ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.45 - объединены три выделенных слоя (NormalizationAttempt + AnalysisAttempt + ResponseAttempt) в один assistantDeepTurnAttemptRuntimeAdapter, после чего в handleMessage остался один вызов вместо трёх
This commit is contained in:
parent
fcfcba47b0
commit
5790e25b68
|
|
@ -1405,7 +1405,39 @@ Validation:
|
|||
- `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)**
|
||||
Implemented in current pass (Phase 2.45):
|
||||
1. Extracted full deep-turn chain (`normalization -> analysis -> response`) from `assistantService` into dedicated runtime adapter:
|
||||
- `assistantDeepTurnAttemptRuntimeAdapter.ts`
|
||||
- introduced:
|
||||
- `runAssistantDeepTurnAttemptRuntime(...)`
|
||||
2. Centralized deep-turn orchestration handoff (behavior-preserving):
|
||||
- unified composition over existing attempt adapters (`Normalization`, `Analysis`, `Response`);
|
||||
- preserved followup binding, runtime context propagation, response finalization hooks and investigation-state persistence callbacks.
|
||||
3. Rewired `assistantService` to consume a single deep-turn runtime adapter call.
|
||||
4. Added focused unit tests:
|
||||
- `assistantDeepTurnAttemptRuntimeAdapter.test.ts`
|
||||
|
||||
Validation:
|
||||
1. `npm run build` passed.
|
||||
2. Targeted living/address/deep followup pack passed:
|
||||
- `assistantDeepTurnAttemptRuntimeAdapter.test.ts`
|
||||
- `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 + 2.45 completed)**
|
||||
|
||||
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)
|
||||
|
||||
|
|
|
|||
88
llm_normalizer/backend/dist/services/assistantDeepTurnAttemptRuntimeAdapter.js
vendored
Normal file
88
llm_normalizer/backend/dist/services/assistantDeepTurnAttemptRuntimeAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runAssistantDeepTurnAttemptRuntime = runAssistantDeepTurnAttemptRuntime;
|
||||
const assistantDeepTurnNormalizationRuntimeAdapter_1 = require("./assistantDeepTurnNormalizationRuntimeAdapter");
|
||||
const assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 = require("./assistantDeepTurnAnalysisAttemptRuntimeAdapter");
|
||||
const assistantDeepTurnResponseAttemptRuntimeAdapter_1 = require("./assistantDeepTurnResponseAttemptRuntimeAdapter");
|
||||
async function runAssistantDeepTurnAttemptRuntime(input) {
|
||||
const runDeepTurnNormalizationRuntimeSafe = input.runDeepTurnNormalizationRuntime ?? assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime;
|
||||
const runDeepTurnAnalysisAttemptRuntimeSafe = input.runDeepTurnAnalysisAttemptRuntime ?? assistantDeepTurnAnalysisAttemptRuntimeAdapter_1.runAssistantDeepTurnAnalysisAttemptRuntime;
|
||||
const runDeepTurnResponseAttemptRuntimeSafe = input.runDeepTurnResponseAttemptRuntime ?? assistantDeepTurnResponseAttemptRuntimeAdapter_1.runAssistantDeepTurnResponseAttemptRuntime;
|
||||
const normalizationRuntime = await runDeepTurnNormalizationRuntimeSafe({
|
||||
userMessage: input.userMessage,
|
||||
payload: input.payload,
|
||||
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||
featureStateFollowupBindingV1: input.featureStateFollowupBindingV1,
|
||||
sessionInvestigationState: input.sessionInvestigationState,
|
||||
buildFollowupStateBinding: input.buildFollowupStateBinding,
|
||||
normalize: input.normalize
|
||||
});
|
||||
const followupBinding = normalizationRuntime.followupBinding;
|
||||
const normalized = normalizationRuntime.normalized;
|
||||
const deepTurnAnalysisRuntime = await runDeepTurnAnalysisAttemptRuntimeSafe({
|
||||
userMessage: input.userMessage,
|
||||
normalizedPayload: normalized.normalized,
|
||||
routeSummary: normalized.route_hint_summary,
|
||||
runtimeAnalysisContext: input.runtimeAnalysisContext,
|
||||
followupUsage: followupBinding.usage,
|
||||
investigationState: input.sessionInvestigationState,
|
||||
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||
featureProblemCentricAnswerV1: input.featureProblemCentricAnswerV1,
|
||||
featureLifecycleAnswerV1: input.featureLifecycleAnswerV1,
|
||||
resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment,
|
||||
inferP0DomainFromMessage: input.inferP0DomainFromMessage,
|
||||
resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext,
|
||||
extractRequirements: input.extractRequirements,
|
||||
toExecutionPlan: input.toExecutionPlan,
|
||||
enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan,
|
||||
enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan,
|
||||
executeRouteRuntime: input.executeRouteRuntime,
|
||||
mapNoRouteReason: input.mapNoRouteReason,
|
||||
buildSkippedResult: input.buildSkippedResult,
|
||||
evaluateCoverage: input.evaluateCoverage,
|
||||
checkGrounding: input.checkGrounding,
|
||||
collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit,
|
||||
collectFaLiveRouteAudit: input.collectFaLiveRouteAudit,
|
||||
hasExplicitPeriodAnchor: input.hasExplicitPeriodAnchor
|
||||
});
|
||||
const deepTurnResponseRuntime = runDeepTurnResponseAttemptRuntimeSafe({
|
||||
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||
featureContractsV11: input.featureContractsV11,
|
||||
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||
sessionId: input.sessionId,
|
||||
questionId: input.questionId,
|
||||
userMessage: input.userMessage,
|
||||
normalized: {
|
||||
trace_id: normalized.trace_id,
|
||||
prompt_version: normalized.prompt_version,
|
||||
schema_version: normalized.schema_version,
|
||||
normalized: normalized.normalized
|
||||
},
|
||||
normalizedQuestion: followupBinding.normalizedQuestion,
|
||||
deepTurnAnalysisRuntime,
|
||||
runtimeAnalysisContext: input.runtimeAnalysisContext,
|
||||
followupStateUsage: followupBinding.usage,
|
||||
followupApplied: Boolean(followupBinding.usage?.applied),
|
||||
previousInvestigationState: input.sessionInvestigationState,
|
||||
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: deepTurnResponseRuntime.response,
|
||||
debug: deepTurnResponseRuntime.debug,
|
||||
normalizationRuntime,
|
||||
deepTurnAnalysisRuntime
|
||||
};
|
||||
}
|
||||
|
|
@ -64,9 +64,7 @@ const capabilitiesRegistry_1 = __importStar(require("./capabilitiesRegistry"));
|
|||
const assistantCanon_1 = __importStar(require("./assistantCanon"));
|
||||
const assistantAddressLaneResponseAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneResponseAttemptRuntimeAdapter"));
|
||||
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
|
||||
const assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisAttemptRuntimeAdapter"));
|
||||
const assistantDeepTurnNormalizationRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnNormalizationRuntimeAdapter"));
|
||||
const assistantDeepTurnResponseAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnResponseAttemptRuntimeAdapter"));
|
||||
const assistantDeepTurnAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAttemptRuntimeAdapter"));
|
||||
const assistantAddressRuntimeAdapter_1 = __importStar(require("./assistantAddressRuntimeAdapter"));
|
||||
const assistantAddressLaneAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneAttemptRuntimeAdapter"));
|
||||
const assistantLivingChatAttemptRuntimeAdapter_1 = __importStar(require("./assistantLivingChatAttemptRuntimeAdapter"));
|
||||
|
|
@ -4493,27 +4491,22 @@ class AssistantService {
|
|||
if (addressRuntime.handled && addressRuntime.response) {
|
||||
return addressRuntime.response;
|
||||
}
|
||||
const normalizationRuntime = await (0, assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime)({
|
||||
const deepTurnRuntime = await (0, assistantDeepTurnAttemptRuntimeAdapter_1.runAssistantDeepTurnAttemptRuntime)({
|
||||
sessionId,
|
||||
questionId: userItem.message_id,
|
||||
userMessage,
|
||||
payload,
|
||||
runtimeAnalysisContext,
|
||||
sessionInvestigationState: session.investigation_state,
|
||||
addressRuntimeMetaForDeep,
|
||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||
featureStateFollowupBindingV1: config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1,
|
||||
sessionInvestigationState: session.investigation_state,
|
||||
buildFollowupStateBinding,
|
||||
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload)
|
||||
});
|
||||
const followupBinding = normalizationRuntime.followupBinding;
|
||||
const normalized = normalizationRuntime.normalized;
|
||||
const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisAttemptRuntimeAdapter_1.runAssistantDeepTurnAnalysisAttemptRuntime)({
|
||||
userMessage,
|
||||
normalizedPayload: normalized.normalized,
|
||||
routeSummary: normalized.route_hint_summary,
|
||||
runtimeAnalysisContext,
|
||||
followupUsage: followupBinding.usage,
|
||||
investigationState: session.investigation_state,
|
||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||
featureProblemCentricAnswerV1: config_1.FEATURE_ASSISTANT_PROBLEM_CENTRIC_ANSWER_V1,
|
||||
featureLifecycleAnswerV1: config_1.FEATURE_ASSISTANT_LIFECYCLE_ANSWER_V1,
|
||||
buildFollowupStateBinding,
|
||||
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload),
|
||||
resolveBusinessScopeAlignment,
|
||||
inferP0DomainFromMessage,
|
||||
resolveBusinessScopeFromLiveContext,
|
||||
|
|
@ -4528,28 +4521,7 @@ class AssistantService {
|
|||
checkGrounding,
|
||||
collectRbpLiveRouteAudit,
|
||||
collectFaLiveRouteAudit,
|
||||
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload)
|
||||
});
|
||||
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseAttemptRuntimeAdapter_1.runAssistantDeepTurnResponseAttemptRuntime)({
|
||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||
sessionId,
|
||||
questionId: userItem.message_id,
|
||||
userMessage,
|
||||
normalized: {
|
||||
trace_id: normalized.trace_id,
|
||||
prompt_version: normalized.prompt_version,
|
||||
schema_version: normalized.schema_version,
|
||||
normalized: normalized.normalized
|
||||
},
|
||||
normalizedQuestion: followupBinding.normalizedQuestion,
|
||||
deepTurnAnalysisRuntime,
|
||||
runtimeAnalysisContext,
|
||||
followupStateUsage: followupBinding.usage,
|
||||
followupApplied: Boolean(followupBinding.usage?.applied),
|
||||
previousInvestigationState: session.investigation_state,
|
||||
addressRuntimeMetaForDeep,
|
||||
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload),
|
||||
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
||||
buildDebugRoutes: (routeSummary) => toDebugRoutes(routeSummary),
|
||||
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
||||
|
|
@ -4562,7 +4534,7 @@ class AssistantService {
|
|||
cloneConversation: (items) => cloneItems(items),
|
||||
logEvent: (payload) => (0, log_1.logJson)(payload)
|
||||
});
|
||||
return deepTurnResponseRuntime.response;
|
||||
return deepTurnRuntime.response;
|
||||
}
|
||||
}
|
||||
exports.AssistantService = AssistantService;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
import type { AssistantMessageResponsePayload } from "../types/assistant";
|
||||
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
|
||||
import {
|
||||
buildAssistantDeepTurnNormalizationRuntime,
|
||||
type BuildAssistantDeepTurnNormalizationRuntimeInput,
|
||||
type BuildAssistantDeepTurnNormalizationRuntimeOutput
|
||||
} from "./assistantDeepTurnNormalizationRuntimeAdapter";
|
||||
import {
|
||||
runAssistantDeepTurnAnalysisAttemptRuntime,
|
||||
type RunAssistantDeepTurnAnalysisAttemptRuntimeInput
|
||||
} from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter";
|
||||
import {
|
||||
runAssistantDeepTurnResponseAttemptRuntime,
|
||||
type RunAssistantDeepTurnResponseAttemptRuntimeInput
|
||||
} from "./assistantDeepTurnResponseAttemptRuntimeAdapter";
|
||||
import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter";
|
||||
|
||||
export interface RunAssistantDeepTurnAttemptRuntimeInput<ResponseType = AssistantMessageResponsePayload> {
|
||||
sessionId: string;
|
||||
questionId: string;
|
||||
userMessage: string;
|
||||
payload: BuildAssistantDeepTurnNormalizationRuntimeInput["payload"];
|
||||
runtimeAnalysisContext: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["runtimeAnalysisContext"];
|
||||
sessionInvestigationState: InvestigationStateWithProblemUnits | null | undefined;
|
||||
addressRuntimeMetaForDeep: unknown;
|
||||
featureInvestigationStateV1: boolean;
|
||||
featureStateFollowupBindingV1: boolean;
|
||||
featureContractsV11: boolean;
|
||||
featureAnswerPolicyV11: boolean;
|
||||
featureProblemCentricAnswerV1: boolean;
|
||||
featureLifecycleAnswerV1: boolean;
|
||||
buildFollowupStateBinding: BuildAssistantDeepTurnNormalizationRuntimeInput["buildFollowupStateBinding"];
|
||||
normalize: BuildAssistantDeepTurnNormalizationRuntimeInput["normalize"];
|
||||
resolveBusinessScopeAlignment: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["resolveBusinessScopeAlignment"];
|
||||
inferP0DomainFromMessage: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["inferP0DomainFromMessage"];
|
||||
resolveBusinessScopeFromLiveContext: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["resolveBusinessScopeFromLiveContext"];
|
||||
extractRequirements: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["extractRequirements"];
|
||||
toExecutionPlan: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["toExecutionPlan"];
|
||||
enforceRbpLiveRoutePlan: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["enforceRbpLiveRoutePlan"];
|
||||
enforceFaLiveRoutePlan: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["enforceFaLiveRoutePlan"];
|
||||
executeRouteRuntime: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["executeRouteRuntime"];
|
||||
mapNoRouteReason: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["mapNoRouteReason"];
|
||||
buildSkippedResult: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["buildSkippedResult"];
|
||||
evaluateCoverage: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["evaluateCoverage"];
|
||||
checkGrounding: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["checkGrounding"];
|
||||
collectRbpLiveRouteAudit: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["collectRbpLiveRouteAudit"];
|
||||
collectFaLiveRouteAudit: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["collectFaLiveRouteAudit"];
|
||||
hasExplicitPeriodAnchor: RunAssistantDeepTurnAnalysisAttemptRuntimeInput["hasExplicitPeriodAnchor"];
|
||||
extractDroppedIntentSegments: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["extractDroppedIntentSegments"];
|
||||
buildDebugRoutes: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["buildDebugRoutes"];
|
||||
extractExecutionState: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["extractExecutionState"];
|
||||
sanitizeReply: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["sanitizeReply"];
|
||||
persistInvestigationState: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["persistInvestigationState"];
|
||||
messageIdFactory: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["messageIdFactory"];
|
||||
appendItem: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["appendItem"];
|
||||
getSession: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["getSession"];
|
||||
persistSession: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["persistSession"];
|
||||
cloneConversation: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["cloneConversation"];
|
||||
logEvent: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["logEvent"];
|
||||
runPackagingRuntime?: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["runPackagingRuntime"];
|
||||
runFinalizeDeepTurn?: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>["runFinalizeDeepTurn"];
|
||||
runDeepTurnNormalizationRuntime?: (
|
||||
input: BuildAssistantDeepTurnNormalizationRuntimeInput
|
||||
) => Promise<BuildAssistantDeepTurnNormalizationRuntimeOutput>;
|
||||
runDeepTurnAnalysisAttemptRuntime?: (
|
||||
input: RunAssistantDeepTurnAnalysisAttemptRuntimeInput
|
||||
) => Promise<RunAssistantDeepTurnAnalysisRuntimeOutput>;
|
||||
runDeepTurnResponseAttemptRuntime?: (
|
||||
input: RunAssistantDeepTurnResponseAttemptRuntimeInput<ResponseType>
|
||||
) => {
|
||||
response: ResponseType;
|
||||
debug: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface RunAssistantDeepTurnAttemptRuntimeOutput<ResponseType = AssistantMessageResponsePayload> {
|
||||
response: ResponseType;
|
||||
debug: Record<string, unknown>;
|
||||
normalizationRuntime: BuildAssistantDeepTurnNormalizationRuntimeOutput;
|
||||
deepTurnAnalysisRuntime: RunAssistantDeepTurnAnalysisRuntimeOutput;
|
||||
}
|
||||
|
||||
export async function runAssistantDeepTurnAttemptRuntime<ResponseType = AssistantMessageResponsePayload>(
|
||||
input: RunAssistantDeepTurnAttemptRuntimeInput<ResponseType>
|
||||
): Promise<RunAssistantDeepTurnAttemptRuntimeOutput<ResponseType>> {
|
||||
const runDeepTurnNormalizationRuntimeSafe =
|
||||
input.runDeepTurnNormalizationRuntime ?? buildAssistantDeepTurnNormalizationRuntime;
|
||||
const runDeepTurnAnalysisAttemptRuntimeSafe =
|
||||
input.runDeepTurnAnalysisAttemptRuntime ?? runAssistantDeepTurnAnalysisAttemptRuntime;
|
||||
const runDeepTurnResponseAttemptRuntimeSafe =
|
||||
input.runDeepTurnResponseAttemptRuntime ?? runAssistantDeepTurnResponseAttemptRuntime;
|
||||
|
||||
const normalizationRuntime = await runDeepTurnNormalizationRuntimeSafe({
|
||||
userMessage: input.userMessage,
|
||||
payload: input.payload,
|
||||
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||
featureStateFollowupBindingV1: input.featureStateFollowupBindingV1,
|
||||
sessionInvestigationState: input.sessionInvestigationState,
|
||||
buildFollowupStateBinding: input.buildFollowupStateBinding,
|
||||
normalize: input.normalize
|
||||
});
|
||||
|
||||
const followupBinding = normalizationRuntime.followupBinding;
|
||||
const normalized = normalizationRuntime.normalized;
|
||||
|
||||
const deepTurnAnalysisRuntime = await runDeepTurnAnalysisAttemptRuntimeSafe({
|
||||
userMessage: input.userMessage,
|
||||
normalizedPayload: normalized.normalized,
|
||||
routeSummary: normalized.route_hint_summary,
|
||||
runtimeAnalysisContext: input.runtimeAnalysisContext,
|
||||
followupUsage: followupBinding.usage,
|
||||
investigationState: input.sessionInvestigationState,
|
||||
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||
featureProblemCentricAnswerV1: input.featureProblemCentricAnswerV1,
|
||||
featureLifecycleAnswerV1: input.featureLifecycleAnswerV1,
|
||||
resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment,
|
||||
inferP0DomainFromMessage: input.inferP0DomainFromMessage,
|
||||
resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext,
|
||||
extractRequirements: input.extractRequirements,
|
||||
toExecutionPlan: input.toExecutionPlan,
|
||||
enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan,
|
||||
enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan,
|
||||
executeRouteRuntime: input.executeRouteRuntime,
|
||||
mapNoRouteReason: input.mapNoRouteReason,
|
||||
buildSkippedResult: input.buildSkippedResult,
|
||||
evaluateCoverage: input.evaluateCoverage,
|
||||
checkGrounding: input.checkGrounding,
|
||||
collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit,
|
||||
collectFaLiveRouteAudit: input.collectFaLiveRouteAudit,
|
||||
hasExplicitPeriodAnchor: input.hasExplicitPeriodAnchor
|
||||
});
|
||||
|
||||
const deepTurnResponseRuntime = runDeepTurnResponseAttemptRuntimeSafe({
|
||||
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||
featureContractsV11: input.featureContractsV11,
|
||||
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||
sessionId: input.sessionId,
|
||||
questionId: input.questionId,
|
||||
userMessage: input.userMessage,
|
||||
normalized: {
|
||||
trace_id: normalized.trace_id,
|
||||
prompt_version: normalized.prompt_version,
|
||||
schema_version: normalized.schema_version,
|
||||
normalized: normalized.normalized
|
||||
},
|
||||
normalizedQuestion: followupBinding.normalizedQuestion,
|
||||
deepTurnAnalysisRuntime,
|
||||
runtimeAnalysisContext: input.runtimeAnalysisContext,
|
||||
followupStateUsage: followupBinding.usage,
|
||||
followupApplied: Boolean((followupBinding.usage as { applied?: unknown } | null)?.applied),
|
||||
previousInvestigationState: input.sessionInvestigationState,
|
||||
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: deepTurnResponseRuntime.response,
|
||||
debug: deepTurnResponseRuntime.debug,
|
||||
normalizationRuntime,
|
||||
deepTurnAnalysisRuntime
|
||||
};
|
||||
}
|
||||
|
|
@ -18,9 +18,7 @@ import * as capabilitiesRegistry_1 from "./capabilitiesRegistry";
|
|||
import * as assistantCanon_1 from "./assistantCanon";
|
||||
import * as assistantAddressLaneResponseAttemptRuntimeAdapter_1 from "./assistantAddressLaneResponseAttemptRuntimeAdapter";
|
||||
import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding";
|
||||
import * as assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter";
|
||||
import * as assistantDeepTurnNormalizationRuntimeAdapter_1 from "./assistantDeepTurnNormalizationRuntimeAdapter";
|
||||
import * as assistantDeepTurnResponseAttemptRuntimeAdapter_1 from "./assistantDeepTurnResponseAttemptRuntimeAdapter";
|
||||
import * as assistantDeepTurnAttemptRuntimeAdapter_1 from "./assistantDeepTurnAttemptRuntimeAdapter";
|
||||
import * as assistantAddressRuntimeAdapter_1 from "./assistantAddressRuntimeAdapter";
|
||||
import * as assistantAddressLaneAttemptRuntimeAdapter_1 from "./assistantAddressLaneAttemptRuntimeAdapter";
|
||||
import * as assistantLivingChatAttemptRuntimeAdapter_1 from "./assistantLivingChatAttemptRuntimeAdapter";
|
||||
|
|
@ -4448,27 +4446,22 @@ export class AssistantService {
|
|||
if (addressRuntime.handled && addressRuntime.response) {
|
||||
return addressRuntime.response;
|
||||
}
|
||||
const normalizationRuntime = await (0, assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime)({
|
||||
const deepTurnRuntime = await (0, assistantDeepTurnAttemptRuntimeAdapter_1.runAssistantDeepTurnAttemptRuntime)({
|
||||
sessionId,
|
||||
questionId: userItem.message_id,
|
||||
userMessage,
|
||||
payload,
|
||||
runtimeAnalysisContext,
|
||||
sessionInvestigationState: session.investigation_state,
|
||||
addressRuntimeMetaForDeep,
|
||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||
featureStateFollowupBindingV1: config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1,
|
||||
sessionInvestigationState: session.investigation_state,
|
||||
buildFollowupStateBinding,
|
||||
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload)
|
||||
});
|
||||
const followupBinding = normalizationRuntime.followupBinding;
|
||||
const normalized = normalizationRuntime.normalized;
|
||||
const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisAttemptRuntimeAdapter_1.runAssistantDeepTurnAnalysisAttemptRuntime)({
|
||||
userMessage,
|
||||
normalizedPayload: normalized.normalized,
|
||||
routeSummary: normalized.route_hint_summary,
|
||||
runtimeAnalysisContext,
|
||||
followupUsage: followupBinding.usage,
|
||||
investigationState: session.investigation_state,
|
||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||
featureProblemCentricAnswerV1: config_1.FEATURE_ASSISTANT_PROBLEM_CENTRIC_ANSWER_V1,
|
||||
featureLifecycleAnswerV1: config_1.FEATURE_ASSISTANT_LIFECYCLE_ANSWER_V1,
|
||||
buildFollowupStateBinding,
|
||||
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload),
|
||||
resolveBusinessScopeAlignment,
|
||||
inferP0DomainFromMessage,
|
||||
resolveBusinessScopeFromLiveContext,
|
||||
|
|
@ -4483,28 +4476,7 @@ export class AssistantService {
|
|||
checkGrounding,
|
||||
collectRbpLiveRouteAudit,
|
||||
collectFaLiveRouteAudit,
|
||||
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload)
|
||||
});
|
||||
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseAttemptRuntimeAdapter_1.runAssistantDeepTurnResponseAttemptRuntime)({
|
||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||
sessionId,
|
||||
questionId: userItem.message_id,
|
||||
userMessage,
|
||||
normalized: {
|
||||
trace_id: normalized.trace_id,
|
||||
prompt_version: normalized.prompt_version,
|
||||
schema_version: normalized.schema_version,
|
||||
normalized: normalized.normalized
|
||||
},
|
||||
normalizedQuestion: followupBinding.normalizedQuestion,
|
||||
deepTurnAnalysisRuntime,
|
||||
runtimeAnalysisContext,
|
||||
followupStateUsage: followupBinding.usage,
|
||||
followupApplied: Boolean(followupBinding.usage?.applied),
|
||||
previousInvestigationState: session.investigation_state,
|
||||
addressRuntimeMetaForDeep,
|
||||
hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload),
|
||||
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
||||
buildDebugRoutes: (routeSummary) => toDebugRoutes(routeSummary),
|
||||
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
||||
|
|
@ -4517,6 +4489,6 @@ export class AssistantService {
|
|||
cloneConversation: (items) => cloneItems(items),
|
||||
logEvent: (payload) => (0, log_1.logJson)(payload)
|
||||
});
|
||||
return deepTurnResponseRuntime.response;
|
||||
return deepTurnRuntime.response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,221 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
import { runAssistantDeepTurnAttemptRuntime } from "../src/services/assistantDeepTurnAttemptRuntimeAdapter";
|
||||
|
||||
function buildInput(overrides: Record<string, unknown> = {}) {
|
||||
return {
|
||||
sessionId: "asst-1",
|
||||
questionId: "msg-q1",
|
||||
userMessage: "почему не закрыт долг",
|
||||
payload: {
|
||||
llmProvider: "openai",
|
||||
apiKey: "key",
|
||||
model: "gpt-5",
|
||||
baseUrl: "http://localhost",
|
||||
temperature: 0.2,
|
||||
maxOutputTokens: 400,
|
||||
context: {}
|
||||
},
|
||||
runtimeAnalysisContext: {
|
||||
active: true,
|
||||
as_of_date: "2020-07-31",
|
||||
period_from: null,
|
||||
period_to: null,
|
||||
source: "analysis_context"
|
||||
},
|
||||
sessionInvestigationState: null,
|
||||
addressRuntimeMetaForDeep: null,
|
||||
featureInvestigationStateV1: true,
|
||||
featureStateFollowupBindingV1: true,
|
||||
featureContractsV11: true,
|
||||
featureAnswerPolicyV11: true,
|
||||
featureProblemCentricAnswerV1: true,
|
||||
featureLifecycleAnswerV1: true,
|
||||
buildFollowupStateBinding: () => ({
|
||||
normalizedQuestion: "normalized-question",
|
||||
mergedContext: {},
|
||||
usage: null
|
||||
}),
|
||||
normalize: async () =>
|
||||
({
|
||||
trace_id: "trace-1",
|
||||
prompt_version: "normalizer_v2_0_2",
|
||||
schema_version: "normalized_query_v2_0_2",
|
||||
normalized: { fragments: [] },
|
||||
route_hint_summary: { mode: "deterministic_v2", decisions: [] }
|
||||
}) as any,
|
||||
resolveBusinessScopeAlignment: ({ routeSummary }) => ({
|
||||
route_summary_resolved: routeSummary
|
||||
}),
|
||||
inferP0DomainFromMessage: () => null,
|
||||
resolveBusinessScopeFromLiveContext: ({ current }) => current,
|
||||
extractRequirements: () => ({ requirements: [], byFragment: new Map() }),
|
||||
toExecutionPlan: () => [],
|
||||
enforceRbpLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: {} }),
|
||||
enforceFaLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: {} }),
|
||||
executeRouteRuntime: async () => ({
|
||||
status: "ok",
|
||||
result_type: "summary",
|
||||
items: [],
|
||||
summary: {},
|
||||
evidence: [],
|
||||
limitations: []
|
||||
}),
|
||||
mapNoRouteReason: () => "no_route",
|
||||
buildSkippedResult: () => ({}) as any,
|
||||
evaluateCoverage: () => ({ requirements: [], coverage: {} }),
|
||||
checkGrounding: () => ({ status: "no_grounded_answer", reasons: [] }),
|
||||
collectRbpLiveRouteAudit: () => ({}),
|
||||
collectFaLiveRouteAudit: () => ({}),
|
||||
hasExplicitPeriodAnchor: () => false,
|
||||
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 attempt runtime adapter", () => {
|
||||
it("orchestrates normalization, analysis and response attempts in order", async () => {
|
||||
const callOrder: string[] = [];
|
||||
const normalizationRuntime = {
|
||||
followupBinding: {
|
||||
normalizedQuestion: "NQ",
|
||||
mergedContext: {},
|
||||
usage: { applied: true }
|
||||
},
|
||||
normalizePayload: { userQuestion: "NQ" },
|
||||
normalized: {
|
||||
trace_id: "trace-1",
|
||||
prompt_version: "normalizer_v2_0_2",
|
||||
schema_version: "normalized_query_v2_0_2",
|
||||
normalized: { fragments: [] },
|
||||
route_hint_summary: { mode: "deterministic_v2", decisions: [] }
|
||||
}
|
||||
} as any;
|
||||
const analysisRuntime = {
|
||||
resolvedRouteSummary: { mode: "deterministic_v2", decisions: [] },
|
||||
requirementExtraction: { requirements: [], byFragment: new Map() },
|
||||
coverageEvaluation: { requirements: [], coverage: {} },
|
||||
groundingCheck: { status: "no_grounded_answer", reasons: [] },
|
||||
executionPlan: [],
|
||||
retrievalCalls: [],
|
||||
retrievalResultsRaw: [],
|
||||
retrievalResults: [],
|
||||
questionTypeClass: "single_fact_lookup",
|
||||
companyAnchors: {},
|
||||
businessScopeResolution: {},
|
||||
temporalGuard: {},
|
||||
polarityGuardResult: { audit: {} },
|
||||
claimAnchorAudit: { claim_type: "unknown" },
|
||||
targetedEvidenceResult: { audit: {} },
|
||||
evidenceGateResult: { audit: {} },
|
||||
rbpLiveRouteAudit: {},
|
||||
faLiveRouteAudit: {},
|
||||
groundedAnswerEligibilityGuard: {},
|
||||
composition: { reply_type: "partial_coverage" }
|
||||
} as any;
|
||||
|
||||
const runDeepTurnNormalizationRuntime = vi.fn(async () => {
|
||||
callOrder.push("normalization");
|
||||
return normalizationRuntime;
|
||||
});
|
||||
const runDeepTurnAnalysisAttemptRuntime = vi.fn(async (input) => {
|
||||
callOrder.push("analysis");
|
||||
expect(input.normalizedPayload).toEqual(normalizationRuntime.normalized.normalized);
|
||||
expect(input.routeSummary).toEqual(normalizationRuntime.normalized.route_hint_summary);
|
||||
expect(input.followupUsage).toEqual({ applied: true });
|
||||
return analysisRuntime;
|
||||
});
|
||||
const runDeepTurnResponseAttemptRuntime = vi.fn((input) => {
|
||||
callOrder.push("response");
|
||||
expect(input.normalizedQuestion).toBe("NQ");
|
||||
expect(input.deepTurnAnalysisRuntime).toBe(analysisRuntime);
|
||||
expect(input.followupApplied).toBe(true);
|
||||
return {
|
||||
response: { ok: true },
|
||||
debug: { trace_id: "trace-1" }
|
||||
};
|
||||
});
|
||||
|
||||
const runtime = await runAssistantDeepTurnAttemptRuntime(
|
||||
buildInput({
|
||||
runDeepTurnNormalizationRuntime,
|
||||
runDeepTurnAnalysisAttemptRuntime,
|
||||
runDeepTurnResponseAttemptRuntime
|
||||
})
|
||||
);
|
||||
|
||||
expect(callOrder).toEqual(["normalization", "analysis", "response"]);
|
||||
expect(runtime.response).toEqual({ ok: true });
|
||||
expect(runtime.debug).toEqual({ trace_id: "trace-1" });
|
||||
});
|
||||
|
||||
it("computes followupApplied=false when followup usage is absent", async () => {
|
||||
const runDeepTurnNormalizationRuntime = vi.fn(async () => ({
|
||||
followupBinding: {
|
||||
normalizedQuestion: "NQ",
|
||||
mergedContext: {},
|
||||
usage: null
|
||||
},
|
||||
normalizePayload: {},
|
||||
normalized: {
|
||||
trace_id: "trace-1",
|
||||
prompt_version: "normalizer_v2_0_2",
|
||||
schema_version: "normalized_query_v2_0_2",
|
||||
normalized: { fragments: [] },
|
||||
route_hint_summary: null
|
||||
}
|
||||
}));
|
||||
const runDeepTurnResponseAttemptRuntime = vi.fn(() => ({
|
||||
response: { ok: true },
|
||||
debug: {}
|
||||
}));
|
||||
const investigationState = { session_id: "asst-1" } as any;
|
||||
|
||||
await runAssistantDeepTurnAttemptRuntime(
|
||||
buildInput({
|
||||
sessionInvestigationState: investigationState,
|
||||
runDeepTurnNormalizationRuntime,
|
||||
runDeepTurnAnalysisAttemptRuntime: async () =>
|
||||
({
|
||||
resolvedRouteSummary: null,
|
||||
requirementExtraction: { requirements: [], byFragment: new Map() },
|
||||
coverageEvaluation: { requirements: [], coverage: {} },
|
||||
groundingCheck: { status: "no_grounded_answer", reasons: [] },
|
||||
executionPlan: [],
|
||||
retrievalCalls: [],
|
||||
retrievalResultsRaw: [],
|
||||
retrievalResults: [],
|
||||
questionTypeClass: "single_fact_lookup",
|
||||
companyAnchors: {},
|
||||
businessScopeResolution: {},
|
||||
temporalGuard: {},
|
||||
polarityGuardResult: { audit: {} },
|
||||
claimAnchorAudit: { claim_type: "unknown" },
|
||||
targetedEvidenceResult: { audit: {} },
|
||||
evidenceGateResult: { audit: {} },
|
||||
rbpLiveRouteAudit: {},
|
||||
faLiveRouteAudit: {},
|
||||
groundedAnswerEligibilityGuard: {},
|
||||
composition: { reply_type: "partial_coverage" }
|
||||
}) as any,
|
||||
runDeepTurnResponseAttemptRuntime
|
||||
})
|
||||
);
|
||||
|
||||
expect(runDeepTurnResponseAttemptRuntime).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
followupApplied: false,
|
||||
previousInvestigationState: investigationState
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue