diff --git a/docs/TECH/1CLLMARCH-FACT.md b/docs/TECH/1CLLMARCH-FACT.md index fed2be7..5d81a75 100644 --- a/docs/TECH/1CLLMARCH-FACT.md +++ b/docs/TECH/1CLLMARCH-FACT.md @@ -1344,7 +1344,37 @@ 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 completed)** +Implemented in current pass (Phase 2.43): +1. Extracted deep-analysis bridge (`deepTurnAnalysisRuntime` wiring) from `assistantService` into dedicated runtime adapter: + - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts` + - introduced: + - `runAssistantDeepTurnAnalysisAttemptRuntime(...)` +2. Centralized deep-analysis handoff logic (behavior-preserving): + - context/plan/retrieval/guard/grounding/composition chain wiring moved behind a single runtime boundary; + - preserved feature flags and all existing local helper hooks (`extractRequirements`, route enforcement, coverage/grounding evaluators, audits). +3. Rewired `assistantService` to consume deep-analysis attempt runtime adapter. +4. Added focused unit tests: + - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts` + +Validation: +1. `npm run build` passed. +2. Targeted living/address/deep followup pack passed: + - `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 completed)** ## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards) diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.js new file mode 100644 index 0000000..4a64156 --- /dev/null +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.js @@ -0,0 +1,106 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.runAssistantDeepTurnAnalysisAttemptRuntime = runAssistantDeepTurnAnalysisAttemptRuntime; +const companyAnchorResolver_1 = require("./companyAnchorResolver"); +const assistantRuntimeGuards_1 = require("./assistantRuntimeGuards"); +const assistantClaimBoundEvidence_1 = require("./assistantClaimBoundEvidence"); +const assistantDeepTurnAnalysisRuntimeAdapter_1 = require("./assistantDeepTurnAnalysisRuntimeAdapter"); +const assistantDeepTurnContextRuntimeAdapter_1 = require("./assistantDeepTurnContextRuntimeAdapter"); +const assistantDeepTurnPlanRuntimeAdapter_1 = require("./assistantDeepTurnPlanRuntimeAdapter"); +const assistantDeepTurnRetrievalRuntimeAdapter_1 = require("./assistantDeepTurnRetrievalRuntimeAdapter"); +const assistantDeepTurnGuardRuntimeAdapter_1 = require("./assistantDeepTurnGuardRuntimeAdapter"); +const assistantDeepTurnGroundingRuntimeAdapter_1 = require("./assistantDeepTurnGroundingRuntimeAdapter"); +const assistantDeepTurnCompositionRuntimeAdapter_1 = require("./assistantDeepTurnCompositionRuntimeAdapter"); +async function runAssistantDeepTurnAnalysisAttemptRuntime(input) { + const runDeepTurnAnalysisRuntimeSafe = input.runDeepTurnAnalysisRuntime ?? assistantDeepTurnAnalysisRuntimeAdapter_1.runAssistantDeepTurnAnalysisRuntime; + const runDeepTurnContextRuntimeSafe = input.runDeepTurnContextRuntime ?? assistantDeepTurnContextRuntimeAdapter_1.buildAssistantDeepTurnRuntimeContext; + const runDeepTurnPlanRuntimeSafe = input.runDeepTurnPlanRuntime ?? assistantDeepTurnPlanRuntimeAdapter_1.buildAssistantDeepTurnExecutionPlan; + const runDeepTurnRetrievalRuntimeSafe = input.runDeepTurnRetrievalRuntime ?? assistantDeepTurnRetrievalRuntimeAdapter_1.executeAssistantDeepTurnRetrievalPlan; + const runDeepTurnGuardRuntimeSafe = input.runDeepTurnGuardRuntime ?? assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnRetrievalGuards; + const runDeepTurnGroundingRuntimeSafe = input.runDeepTurnGroundingRuntime ?? assistantDeepTurnGroundingRuntimeAdapter_1.runAssistantDeepTurnGroundingRuntime; + const runDeepTurnCompositionRuntimeSafe = input.runDeepTurnCompositionRuntime ?? assistantDeepTurnCompositionRuntimeAdapter_1.buildAssistantDeepTurnComposition; + return runDeepTurnAnalysisRuntimeSafe({ + userMessage: input.userMessage, + runContextRuntime: () => runDeepTurnContextRuntimeSafe({ + userMessage: input.userMessage, + normalizedPayload: input.normalizedPayload, + routeSummary: input.routeSummary, + runtimeAnalysisContext: input.runtimeAnalysisContext, + followupUsage: input.followupUsage, + resolveCompanyAnchors: companyAnchorResolver_1.resolveCompanyAnchors, + resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment, + inferP0DomainFromMessage: input.inferP0DomainFromMessage, + resolveTemporalGuard: assistantRuntimeGuards_1.resolveTemporalGuard, + resolveDomainPolarityGuard: assistantRuntimeGuards_1.resolveDomainPolarityGuard, + resolveClaimBoundAnchors: assistantClaimBoundEvidence_1.resolveClaimBoundAnchors, + resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext + }), + runExecutionPlanRuntime: ({ resolvedRouteSummary, claimAnchorAudit, temporalGuard, domainPolarityGuardInitial }) => runDeepTurnPlanRuntimeSafe({ + routeSummary: resolvedRouteSummary, + normalizedPayload: input.normalizedPayload, + userMessage: input.userMessage, + claimType: claimAnchorAudit.claim_type, + temporalGuard, + domainPolarityGuardInitial, + extractRequirements: input.extractRequirements, + toExecutionPlan: input.toExecutionPlan, + enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan, + enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan, + applyTemporalHintToExecutionPlan: assistantRuntimeGuards_1.applyTemporalHintToExecutionPlan, + applyPolarityHintToExecutionPlan: assistantRuntimeGuards_1.applyPolarityHintToExecutionPlan + }), + runRetrievalRuntime: ({ executionPlan, liveTemporalHint }) => runDeepTurnRetrievalRuntimeSafe({ + executionPlan: executionPlan, + liveTemporalHint, + executeRouteRuntime: input.executeRouteRuntime, + mapNoRouteReason: input.mapNoRouteReason, + buildSkippedResult: input.buildSkippedResult + }), + runGuardRuntime: ({ retrievalResults, domainPolarityGuardInitial, claimAnchorAudit, temporalGuard, focusDomainForGuards, companyAnchors, userMessage: runtimeUserMessage }) => runDeepTurnGuardRuntimeSafe({ + retrievalResults, + domainPolarityGuardInitial: domainPolarityGuardInitial, + claimAnchorAudit: claimAnchorAudit, + temporalGuard: temporalGuard, + focusDomainForGuards: focusDomainForGuards, + companyAnchors: companyAnchors, + userMessage: runtimeUserMessage + }), + runGroundingRuntime: ({ claimType, retrievalResults, rbpPlanAudit, faPlanAudit, routeSummary, requirementExtraction, temporalGuard, polarityAudit, evidenceAudit, claimAnchorAudit, targetedEvidenceHitRate, businessScopeResolved }) => runDeepTurnGroundingRuntimeSafe({ + claimType, + retrievalResults, + rbpPlanAudit, + faPlanAudit, + routeSummary, + normalizedPayload: input.normalizedPayload, + userMessage: input.userMessage, + requirementExtraction: requirementExtraction, + extractRequirements: input.extractRequirements, + evaluateCoverage: input.evaluateCoverage, + checkGrounding: input.checkGrounding, + temporalGuard, + polarityAudit, + evidenceAudit, + claimAnchorAudit, + targetedEvidenceHitRate, + businessScopeResolved, + collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit, + collectFaLiveRouteAudit: input.collectFaLiveRouteAudit + }), + runCompositionRuntime: ({ resolvedRouteSummary, retrievalResults, requirements, coverageReport, groundingCheck, companyAnchors }) => runDeepTurnCompositionRuntimeSafe({ + userMessage: input.userMessage, + routeSummary: resolvedRouteSummary, + retrievalResults, + requirements, + coverageReport, + groundingCheck, + followupUsage: input.followupUsage, + investigationState: input.investigationState, + companyAnchors, + normalizedPayload: input.normalizedPayload, + featureAnswerPolicyV11: input.featureAnswerPolicyV11, + featureProblemCentricAnswerV1: input.featureProblemCentricAnswerV1, + featureLifecycleAnswerV1: input.featureLifecycleAnswerV1, + hasExplicitPeriodAnchor: input.hasExplicitPeriodAnchor + }) + }); +} diff --git a/llm_normalizer/backend/dist/services/assistantService.js b/llm_normalizer/backend/dist/services/assistantService.js index 6fb8b97..b77c117 100644 --- a/llm_normalizer/backend/dist/services/assistantService.js +++ b/llm_normalizer/backend/dist/services/assistantService.js @@ -53,9 +53,6 @@ const assistantDataLayer_1 = __importStar(require("./assistantDataLayer")); const assistantSessionLogger_1 = __importStar(require("./assistantSessionLogger")); const investigationState_1 = __importStar(require("./investigationState")); const retrievalResultNormalizer_1 = __importStar(require("./retrievalResultNormalizer")); -const companyAnchorResolver_1 = __importStar(require("./companyAnchorResolver")); -const assistantRuntimeGuards_1 = __importStar(require("./assistantRuntimeGuards")); -const assistantClaimBoundEvidence_1 = __importStar(require("./assistantClaimBoundEvidence")); const addressQueryService_1 = __importStar(require("./addressQueryService")); const addressQueryClassifier_1 = __importStar(require("./addressQueryClassifier")); const addressIntentResolver_1 = __importStar(require("./addressIntentResolver")); @@ -67,17 +64,11 @@ 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 assistantDeepTurnAnalysisRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisRuntimeAdapter")); -const assistantDeepTurnCompositionRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnCompositionRuntimeAdapter")); -const assistantDeepTurnContextRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnContextRuntimeAdapter")); +const assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisAttemptRuntimeAdapter")); const assistantDeepTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnFinalizeRuntimeAdapter")); -const assistantDeepTurnGuardRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnGuardRuntimeAdapter")); -const assistantDeepTurnGroundingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnGroundingRuntimeAdapter")); const assistantDeepTurnPackagingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPackagingRuntimeAdapter")); -const assistantDeepTurnPlanRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPlanRuntimeAdapter")); const assistantDeepTurnNormalizationRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnNormalizationRuntimeAdapter")); const assistantDeepTurnResponseRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnResponseRuntimeAdapter")); -const assistantDeepTurnRetrievalRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnRetrievalRuntimeAdapter")); const assistantAddressRuntimeAdapter_1 = __importStar(require("./assistantAddressRuntimeAdapter")); const assistantAddressLaneAttemptRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneAttemptRuntimeAdapter")); const assistantLivingChatAttemptRuntimeAdapter_1 = __importStar(require("./assistantLivingChatAttemptRuntimeAdapter")); @@ -4515,89 +4506,31 @@ class AssistantService { }); const followupBinding = normalizationRuntime.followupBinding; const normalized = normalizationRuntime.normalized; - const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisRuntimeAdapter_1.runAssistantDeepTurnAnalysisRuntime)({ + const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisAttemptRuntimeAdapter_1.runAssistantDeepTurnAnalysisAttemptRuntime)({ userMessage, - runContextRuntime: () => (0, assistantDeepTurnContextRuntimeAdapter_1.buildAssistantDeepTurnRuntimeContext)({ - userMessage, - normalizedPayload: normalized.normalized, - routeSummary: normalized.route_hint_summary, - runtimeAnalysisContext, - followupUsage: followupBinding.usage, - resolveCompanyAnchors: companyAnchorResolver_1.resolveCompanyAnchors, - resolveBusinessScopeAlignment, - inferP0DomainFromMessage, - resolveTemporalGuard: assistantRuntimeGuards_1.resolveTemporalGuard, - resolveDomainPolarityGuard: assistantRuntimeGuards_1.resolveDomainPolarityGuard, - resolveClaimBoundAnchors: assistantClaimBoundEvidence_1.resolveClaimBoundAnchors, - resolveBusinessScopeFromLiveContext - }), - runExecutionPlanRuntime: ({ resolvedRouteSummary, claimAnchorAudit, temporalGuard, domainPolarityGuardInitial }) => (0, assistantDeepTurnPlanRuntimeAdapter_1.buildAssistantDeepTurnExecutionPlan)({ - routeSummary: resolvedRouteSummary, - normalizedPayload: normalized.normalized, - userMessage, - claimType: claimAnchorAudit.claim_type, - temporalGuard, - domainPolarityGuardInitial, - extractRequirements, - toExecutionPlan, - enforceRbpLiveRoutePlan, - enforceFaLiveRoutePlan, - applyTemporalHintToExecutionPlan: assistantRuntimeGuards_1.applyTemporalHintToExecutionPlan, - applyPolarityHintToExecutionPlan: assistantRuntimeGuards_1.applyPolarityHintToExecutionPlan - }), - runRetrievalRuntime: ({ executionPlan, liveTemporalHint }) => (0, assistantDeepTurnRetrievalRuntimeAdapter_1.executeAssistantDeepTurnRetrievalPlan)({ - executionPlan: executionPlan, - liveTemporalHint, - executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options), - mapNoRouteReason, - buildSkippedResult - }), - runGuardRuntime: ({ retrievalResults, domainPolarityGuardInitial, claimAnchorAudit, temporalGuard, focusDomainForGuards, companyAnchors, userMessage: runtimeUserMessage }) => (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnRetrievalGuards)({ - retrievalResults, - domainPolarityGuardInitial, - claimAnchorAudit, - temporalGuard, - focusDomainForGuards, - companyAnchors, - userMessage: runtimeUserMessage - }), - runGroundingRuntime: ({ claimType, retrievalResults, rbpPlanAudit, faPlanAudit, routeSummary, requirementExtraction, temporalGuard, polarityAudit, evidenceAudit, claimAnchorAudit, targetedEvidenceHitRate, businessScopeResolved }) => (0, assistantDeepTurnGroundingRuntimeAdapter_1.runAssistantDeepTurnGroundingRuntime)({ - claimType, - retrievalResults, - rbpPlanAudit, - faPlanAudit, - routeSummary, - normalizedPayload: normalized.normalized, - userMessage, - requirementExtraction, - extractRequirements, - evaluateCoverage, - checkGrounding, - temporalGuard, - polarityAudit, - evidenceAudit, - claimAnchorAudit, - targetedEvidenceHitRate, - businessScopeResolved, - collectRbpLiveRouteAudit, - collectFaLiveRouteAudit - }), - runCompositionRuntime: ({ resolvedRouteSummary, retrievalResults, requirements, coverageReport, groundingCheck, companyAnchors }) => (0, assistantDeepTurnCompositionRuntimeAdapter_1.buildAssistantDeepTurnComposition)({ - userMessage, - routeSummary: resolvedRouteSummary, - retrievalResults, - requirements, - coverageReport, - groundingCheck, - followupUsage: followupBinding.usage, - investigationState: session.investigation_state, - companyAnchors, - normalizedPayload: normalized.normalized, - 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, - hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) - }) + normalizedPayload: normalized.normalized, + routeSummary: normalized.route_hint_summary, + runtimeAnalysisContext, + followupUsage: followupBinding.usage, + investigationState: session.investigation_state, + 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, + resolveBusinessScopeAlignment, + inferP0DomainFromMessage, + resolveBusinessScopeFromLiveContext, + extractRequirements, + toExecutionPlan, + enforceRbpLiveRoutePlan, + enforceFaLiveRoutePlan, + executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options), + mapNoRouteReason, + buildSkippedResult, + evaluateCoverage, + checkGrounding, + collectRbpLiveRouteAudit, + collectFaLiveRouteAudit, + hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) }); const companyAnchors = deepTurnAnalysisRuntime.companyAnchors; const temporalGuard = deepTurnAnalysisRuntime.temporalGuard; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts new file mode 100644 index 0000000..e37cc51 --- /dev/null +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts @@ -0,0 +1,243 @@ +import { resolveCompanyAnchors } from "./companyAnchorResolver"; +import { + applyPolarityHintToExecutionPlan, + applyTemporalHintToExecutionPlan, + resolveDomainPolarityGuard, + resolveTemporalGuard +} from "./assistantRuntimeGuards"; +import { resolveClaimBoundAnchors } from "./assistantClaimBoundEvidence"; +import { + runAssistantDeepTurnAnalysisRuntime, + type RunAssistantDeepTurnAnalysisRuntimeInput, + type RunAssistantDeepTurnAnalysisRuntimeOutput +} from "./assistantDeepTurnAnalysisRuntimeAdapter"; +import { + buildAssistantDeepTurnRuntimeContext, + type BuildAssistantDeepTurnRuntimeContextInput, + type BuildAssistantDeepTurnRuntimeContextOutput +} from "./assistantDeepTurnContextRuntimeAdapter"; +import { + buildAssistantDeepTurnExecutionPlan, + type BuildAssistantDeepTurnExecutionPlanInput, + type BuildAssistantDeepTurnExecutionPlanOutput +} from "./assistantDeepTurnPlanRuntimeAdapter"; +import { + executeAssistantDeepTurnRetrievalPlan, + type AssistantDeepTurnRetrievalExecutionInput, + type AssistantDeepTurnRetrievalExecutionOutput +} from "./assistantDeepTurnRetrievalRuntimeAdapter"; +import { + applyAssistantDeepTurnRetrievalGuards, + type AssistantDeepTurnRetrievalGuardPipelineInput, + type AssistantDeepTurnRetrievalGuardPipelineOutput +} from "./assistantDeepTurnGuardRuntimeAdapter"; +import { + runAssistantDeepTurnGroundingRuntime, + type AssistantDeepTurnGroundingRuntimeInput, + type AssistantDeepTurnGroundingRuntimeOutput +} from "./assistantDeepTurnGroundingRuntimeAdapter"; +import { + buildAssistantDeepTurnComposition, + type BuildAssistantDeepTurnCompositionInput, + type AssistantDeepTurnCompositionOutput +} from "./assistantDeepTurnCompositionRuntimeAdapter"; +import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; +import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; +import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning"; +import type { AssistantRequirementExtractionLike } from "./assistantDeepTurnPlanRuntimeAdapter"; + +interface RuntimeAnalysisContextLike { + active: boolean; + as_of_date: string | null; + period_from: string | null; + period_to: string | null; + source: string | null; +} + +export interface RunAssistantDeepTurnAnalysisAttemptRuntimeInput { + userMessage: string; + normalizedPayload: NormalizeResponsePayload["normalized"]; + routeSummary: RouteHintSummary | null; + runtimeAnalysisContext: RuntimeAnalysisContextLike; + followupUsage: unknown | null | undefined; + investigationState: InvestigationStateWithProblemUnits | null | undefined; + featureAnswerPolicyV11: boolean; + featureProblemCentricAnswerV1: boolean; + featureLifecycleAnswerV1: boolean; + resolveBusinessScopeAlignment: BuildAssistantDeepTurnRuntimeContextInput["resolveBusinessScopeAlignment"]; + inferP0DomainFromMessage: BuildAssistantDeepTurnRuntimeContextInput["inferP0DomainFromMessage"]; + resolveBusinessScopeFromLiveContext: BuildAssistantDeepTurnRuntimeContextInput["resolveBusinessScopeFromLiveContext"]; + extractRequirements: BuildAssistantDeepTurnExecutionPlanInput["extractRequirements"]; + toExecutionPlan: BuildAssistantDeepTurnExecutionPlanInput["toExecutionPlan"]; + enforceRbpLiveRoutePlan: BuildAssistantDeepTurnExecutionPlanInput["enforceRbpLiveRoutePlan"]; + enforceFaLiveRoutePlan: BuildAssistantDeepTurnExecutionPlanInput["enforceFaLiveRoutePlan"]; + executeRouteRuntime: AssistantDeepTurnRetrievalExecutionInput["executeRouteRuntime"]; + mapNoRouteReason: AssistantDeepTurnRetrievalExecutionInput["mapNoRouteReason"]; + buildSkippedResult: AssistantDeepTurnRetrievalExecutionInput["buildSkippedResult"]; + evaluateCoverage: AssistantDeepTurnGroundingRuntimeInput["evaluateCoverage"]; + checkGrounding: AssistantDeepTurnGroundingRuntimeInput["checkGrounding"]; + collectRbpLiveRouteAudit: AssistantDeepTurnGroundingRuntimeInput["collectRbpLiveRouteAudit"]; + collectFaLiveRouteAudit: AssistantDeepTurnGroundingRuntimeInput["collectFaLiveRouteAudit"]; + hasExplicitPeriodAnchor: BuildAssistantDeepTurnCompositionInput["hasExplicitPeriodAnchor"]; + runDeepTurnAnalysisRuntime?: ( + input: RunAssistantDeepTurnAnalysisRuntimeInput + ) => Promise; + runDeepTurnContextRuntime?: ( + input: BuildAssistantDeepTurnRuntimeContextInput + ) => BuildAssistantDeepTurnRuntimeContextOutput; + runDeepTurnPlanRuntime?: ( + input: BuildAssistantDeepTurnExecutionPlanInput + ) => BuildAssistantDeepTurnExecutionPlanOutput; + runDeepTurnRetrievalRuntime?: ( + input: AssistantDeepTurnRetrievalExecutionInput + ) => Promise; + runDeepTurnGuardRuntime?: ( + input: AssistantDeepTurnRetrievalGuardPipelineInput + ) => AssistantDeepTurnRetrievalGuardPipelineOutput; + runDeepTurnGroundingRuntime?: ( + input: AssistantDeepTurnGroundingRuntimeInput + ) => AssistantDeepTurnGroundingRuntimeOutput; + runDeepTurnCompositionRuntime?: ( + input: BuildAssistantDeepTurnCompositionInput + ) => AssistantDeepTurnCompositionOutput; +} + +export async function runAssistantDeepTurnAnalysisAttemptRuntime( + input: RunAssistantDeepTurnAnalysisAttemptRuntimeInput +): Promise { + const runDeepTurnAnalysisRuntimeSafe = + input.runDeepTurnAnalysisRuntime ?? runAssistantDeepTurnAnalysisRuntime; + const runDeepTurnContextRuntimeSafe = input.runDeepTurnContextRuntime ?? buildAssistantDeepTurnRuntimeContext; + const runDeepTurnPlanRuntimeSafe = input.runDeepTurnPlanRuntime ?? buildAssistantDeepTurnExecutionPlan; + const runDeepTurnRetrievalRuntimeSafe = + input.runDeepTurnRetrievalRuntime ?? executeAssistantDeepTurnRetrievalPlan; + const runDeepTurnGuardRuntimeSafe = input.runDeepTurnGuardRuntime ?? applyAssistantDeepTurnRetrievalGuards; + const runDeepTurnGroundingRuntimeSafe = + input.runDeepTurnGroundingRuntime ?? runAssistantDeepTurnGroundingRuntime; + const runDeepTurnCompositionRuntimeSafe = + input.runDeepTurnCompositionRuntime ?? buildAssistantDeepTurnComposition; + + return runDeepTurnAnalysisRuntimeSafe({ + userMessage: input.userMessage, + runContextRuntime: () => + runDeepTurnContextRuntimeSafe({ + userMessage: input.userMessage, + normalizedPayload: input.normalizedPayload, + routeSummary: input.routeSummary, + runtimeAnalysisContext: input.runtimeAnalysisContext, + followupUsage: input.followupUsage, + resolveCompanyAnchors, + resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment, + inferP0DomainFromMessage: input.inferP0DomainFromMessage, + resolveTemporalGuard: resolveTemporalGuard as any, + resolveDomainPolarityGuard: resolveDomainPolarityGuard as any, + resolveClaimBoundAnchors: resolveClaimBoundAnchors as any, + resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext + }) as any, + runExecutionPlanRuntime: ({ + resolvedRouteSummary, + claimAnchorAudit, + temporalGuard, + domainPolarityGuardInitial + }) => + runDeepTurnPlanRuntimeSafe({ + routeSummary: resolvedRouteSummary, + normalizedPayload: input.normalizedPayload, + userMessage: input.userMessage, + claimType: claimAnchorAudit.claim_type, + temporalGuard, + domainPolarityGuardInitial, + extractRequirements: input.extractRequirements, + toExecutionPlan: input.toExecutionPlan, + enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan, + enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan, + applyTemporalHintToExecutionPlan: applyTemporalHintToExecutionPlan as any, + applyPolarityHintToExecutionPlan: applyPolarityHintToExecutionPlan as any + }) as any, + runRetrievalRuntime: ({ executionPlan, liveTemporalHint }) => + runDeepTurnRetrievalRuntimeSafe({ + executionPlan: executionPlan as AssistantExecutionPlanItem[], + liveTemporalHint, + executeRouteRuntime: input.executeRouteRuntime, + mapNoRouteReason: input.mapNoRouteReason, + buildSkippedResult: input.buildSkippedResult + }) as any, + runGuardRuntime: ({ + retrievalResults, + domainPolarityGuardInitial, + claimAnchorAudit, + temporalGuard, + focusDomainForGuards, + companyAnchors, + userMessage: runtimeUserMessage + }) => + runDeepTurnGuardRuntimeSafe({ + retrievalResults, + domainPolarityGuardInitial: domainPolarityGuardInitial as any, + claimAnchorAudit: claimAnchorAudit as any, + temporalGuard: temporalGuard as any, + focusDomainForGuards: focusDomainForGuards as any, + companyAnchors: companyAnchors as any, + userMessage: runtimeUserMessage + } as any), + runGroundingRuntime: ({ + claimType, + retrievalResults, + rbpPlanAudit, + faPlanAudit, + routeSummary, + requirementExtraction, + temporalGuard, + polarityAudit, + evidenceAudit, + claimAnchorAudit, + targetedEvidenceHitRate, + businessScopeResolved + }) => + runDeepTurnGroundingRuntimeSafe({ + claimType, + retrievalResults, + rbpPlanAudit, + faPlanAudit, + routeSummary, + normalizedPayload: input.normalizedPayload, + userMessage: input.userMessage, + requirementExtraction: requirementExtraction as AssistantRequirementExtractionLike, + extractRequirements: input.extractRequirements as any, + evaluateCoverage: input.evaluateCoverage as any, + checkGrounding: input.checkGrounding as any, + temporalGuard, + polarityAudit, + evidenceAudit, + claimAnchorAudit, + targetedEvidenceHitRate, + businessScopeResolved, + collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit as any, + collectFaLiveRouteAudit: input.collectFaLiveRouteAudit as any + } as any), + runCompositionRuntime: ({ + resolvedRouteSummary, + retrievalResults, + requirements, + coverageReport, + groundingCheck, + companyAnchors + }) => + runDeepTurnCompositionRuntimeSafe({ + userMessage: input.userMessage, + routeSummary: resolvedRouteSummary, + retrievalResults, + requirements, + coverageReport, + groundingCheck, + followupUsage: input.followupUsage, + investigationState: input.investigationState, + companyAnchors, + normalizedPayload: input.normalizedPayload, + featureAnswerPolicyV11: input.featureAnswerPolicyV11, + featureProblemCentricAnswerV1: input.featureProblemCentricAnswerV1, + featureLifecycleAnswerV1: input.featureLifecycleAnswerV1, + hasExplicitPeriodAnchor: input.hasExplicitPeriodAnchor + }) as any + }); +} diff --git a/llm_normalizer/backend/src/services/assistantService.ts b/llm_normalizer/backend/src/services/assistantService.ts index 2917c58..0399b59 100644 --- a/llm_normalizer/backend/src/services/assistantService.ts +++ b/llm_normalizer/backend/src/services/assistantService.ts @@ -7,9 +7,6 @@ import * as assistantDataLayer_1 from "./assistantDataLayer"; import * as assistantSessionLogger_1 from "./assistantSessionLogger"; import * as investigationState_1 from "./investigationState"; import * as retrievalResultNormalizer_1 from "./retrievalResultNormalizer"; -import * as companyAnchorResolver_1 from "./companyAnchorResolver"; -import * as assistantRuntimeGuards_1 from "./assistantRuntimeGuards"; -import * as assistantClaimBoundEvidence_1 from "./assistantClaimBoundEvidence"; import * as addressQueryService_1 from "./addressQueryService"; import * as addressQueryClassifier_1 from "./addressQueryClassifier"; import * as addressIntentResolver_1 from "./addressIntentResolver"; @@ -21,17 +18,11 @@ 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 assistantDeepTurnAnalysisRuntimeAdapter_1 from "./assistantDeepTurnAnalysisRuntimeAdapter"; -import * as assistantDeepTurnCompositionRuntimeAdapter_1 from "./assistantDeepTurnCompositionRuntimeAdapter"; -import * as assistantDeepTurnContextRuntimeAdapter_1 from "./assistantDeepTurnContextRuntimeAdapter"; +import * as assistantDeepTurnAnalysisAttemptRuntimeAdapter_1 from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter"; import * as assistantDeepTurnFinalizeRuntimeAdapter_1 from "./assistantDeepTurnFinalizeRuntimeAdapter"; -import * as assistantDeepTurnGuardRuntimeAdapter_1 from "./assistantDeepTurnGuardRuntimeAdapter"; -import * as assistantDeepTurnGroundingRuntimeAdapter_1 from "./assistantDeepTurnGroundingRuntimeAdapter"; import * as assistantDeepTurnPackagingRuntimeAdapter_1 from "./assistantDeepTurnPackagingRuntimeAdapter"; -import * as assistantDeepTurnPlanRuntimeAdapter_1 from "./assistantDeepTurnPlanRuntimeAdapter"; import * as assistantDeepTurnNormalizationRuntimeAdapter_1 from "./assistantDeepTurnNormalizationRuntimeAdapter"; import * as assistantDeepTurnResponseRuntimeAdapter_1 from "./assistantDeepTurnResponseRuntimeAdapter"; -import * as assistantDeepTurnRetrievalRuntimeAdapter_1 from "./assistantDeepTurnRetrievalRuntimeAdapter"; import * as assistantAddressRuntimeAdapter_1 from "./assistantAddressRuntimeAdapter"; import * as assistantAddressLaneAttemptRuntimeAdapter_1 from "./assistantAddressLaneAttemptRuntimeAdapter"; import * as assistantLivingChatAttemptRuntimeAdapter_1 from "./assistantLivingChatAttemptRuntimeAdapter"; @@ -4470,89 +4461,31 @@ export class AssistantService { }); const followupBinding = normalizationRuntime.followupBinding; const normalized = normalizationRuntime.normalized; - const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisRuntimeAdapter_1.runAssistantDeepTurnAnalysisRuntime)({ + const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisAttemptRuntimeAdapter_1.runAssistantDeepTurnAnalysisAttemptRuntime)({ userMessage, - runContextRuntime: () => (0, assistantDeepTurnContextRuntimeAdapter_1.buildAssistantDeepTurnRuntimeContext)({ - userMessage, - normalizedPayload: normalized.normalized, - routeSummary: normalized.route_hint_summary, - runtimeAnalysisContext, - followupUsage: followupBinding.usage, - resolveCompanyAnchors: companyAnchorResolver_1.resolveCompanyAnchors, - resolveBusinessScopeAlignment, - inferP0DomainFromMessage, - resolveTemporalGuard: assistantRuntimeGuards_1.resolveTemporalGuard, - resolveDomainPolarityGuard: assistantRuntimeGuards_1.resolveDomainPolarityGuard, - resolveClaimBoundAnchors: assistantClaimBoundEvidence_1.resolveClaimBoundAnchors, - resolveBusinessScopeFromLiveContext - }), - runExecutionPlanRuntime: ({ resolvedRouteSummary, claimAnchorAudit, temporalGuard, domainPolarityGuardInitial }) => (0, assistantDeepTurnPlanRuntimeAdapter_1.buildAssistantDeepTurnExecutionPlan)({ - routeSummary: resolvedRouteSummary, - normalizedPayload: normalized.normalized, - userMessage, - claimType: claimAnchorAudit.claim_type, - temporalGuard, - domainPolarityGuardInitial, - extractRequirements, - toExecutionPlan, - enforceRbpLiveRoutePlan, - enforceFaLiveRoutePlan, - applyTemporalHintToExecutionPlan: assistantRuntimeGuards_1.applyTemporalHintToExecutionPlan, - applyPolarityHintToExecutionPlan: assistantRuntimeGuards_1.applyPolarityHintToExecutionPlan - }), - runRetrievalRuntime: ({ executionPlan, liveTemporalHint }) => (0, assistantDeepTurnRetrievalRuntimeAdapter_1.executeAssistantDeepTurnRetrievalPlan)({ - executionPlan: executionPlan, - liveTemporalHint, - executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options), - mapNoRouteReason, - buildSkippedResult - }), - runGuardRuntime: ({ retrievalResults, domainPolarityGuardInitial, claimAnchorAudit, temporalGuard, focusDomainForGuards, companyAnchors, userMessage: runtimeUserMessage }) => (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnRetrievalGuards)({ - retrievalResults, - domainPolarityGuardInitial, - claimAnchorAudit, - temporalGuard, - focusDomainForGuards, - companyAnchors, - userMessage: runtimeUserMessage - }), - runGroundingRuntime: ({ claimType, retrievalResults, rbpPlanAudit, faPlanAudit, routeSummary, requirementExtraction, temporalGuard, polarityAudit, evidenceAudit, claimAnchorAudit, targetedEvidenceHitRate, businessScopeResolved }) => (0, assistantDeepTurnGroundingRuntimeAdapter_1.runAssistantDeepTurnGroundingRuntime)({ - claimType, - retrievalResults, - rbpPlanAudit, - faPlanAudit, - routeSummary, - normalizedPayload: normalized.normalized, - userMessage, - requirementExtraction, - extractRequirements, - evaluateCoverage, - checkGrounding, - temporalGuard, - polarityAudit, - evidenceAudit, - claimAnchorAudit, - targetedEvidenceHitRate, - businessScopeResolved, - collectRbpLiveRouteAudit, - collectFaLiveRouteAudit - }), - runCompositionRuntime: ({ resolvedRouteSummary, retrievalResults, requirements, coverageReport, groundingCheck, companyAnchors }) => (0, assistantDeepTurnCompositionRuntimeAdapter_1.buildAssistantDeepTurnComposition)({ - userMessage, - routeSummary: resolvedRouteSummary, - retrievalResults, - requirements, - coverageReport, - groundingCheck, - followupUsage: followupBinding.usage, - investigationState: session.investigation_state, - companyAnchors, - normalizedPayload: normalized.normalized, - 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, - hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) - }) + normalizedPayload: normalized.normalized, + routeSummary: normalized.route_hint_summary, + runtimeAnalysisContext, + followupUsage: followupBinding.usage, + investigationState: session.investigation_state, + 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, + resolveBusinessScopeAlignment, + inferP0DomainFromMessage, + resolveBusinessScopeFromLiveContext, + extractRequirements, + toExecutionPlan, + enforceRbpLiveRoutePlan, + enforceFaLiveRoutePlan, + executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options), + mapNoRouteReason, + buildSkippedResult, + evaluateCoverage, + checkGrounding, + collectRbpLiveRouteAudit, + collectFaLiveRouteAudit, + hasExplicitPeriodAnchor: (normalizedPayload) => hasExplicitPeriodAnchorFromNormalized(normalizedPayload) }); const companyAnchors = deepTurnAnalysisRuntime.companyAnchors; const temporalGuard = deepTurnAnalysisRuntime.temporalGuard; diff --git a/llm_normalizer/backend/tests/assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts b/llm_normalizer/backend/tests/assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts new file mode 100644 index 0000000..c74185c --- /dev/null +++ b/llm_normalizer/backend/tests/assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts @@ -0,0 +1,337 @@ +import { describe, expect, it, vi } from "vitest"; +import { + runAssistantDeepTurnAnalysisAttemptRuntime, + type RunAssistantDeepTurnAnalysisAttemptRuntimeInput +} from "../src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter"; + +function buildInput( + overrides: Partial = {} +): RunAssistantDeepTurnAnalysisAttemptRuntimeInput { + return { + userMessage: "почему долг не закрылся", + normalizedPayload: { fragments: [] } as any, + routeSummary: { mode: "deterministic_v2", decisions: [] } as any, + runtimeAnalysisContext: { + active: true, + as_of_date: "2020-07-31", + period_from: null, + period_to: null, + source: "analysis_context" + }, + followupUsage: { applied: true }, + investigationState: { session_id: "asst-1", followup_context: { active_domain: "settlements_60_62" } } as any, + featureAnswerPolicyV11: true, + featureProblemCentricAnswerV1: true, + featureLifecycleAnswerV1: true, + resolveBusinessScopeAlignment: () => ({ route_summary_resolved: { mode: "deterministic_v2", decisions: [] } }), + inferP0DomainFromMessage: () => "settlements_60_62", + resolveBusinessScopeFromLiveContext: ({ current }) => current, + extractRequirements: () => ({ + requirements: [{ id: "R1" }], + byFragment: new Map([["F1", ["R1"]]]) + }), + toExecutionPlan: () => + [ + { + fragment_id: "F1", + requirement_ids: ["R1"], + route: "store_canonical", + should_execute: true, + fragment_text: "fragment", + no_route_reason: null + } + ] as any, + enforceRbpLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: { rbp: true } }), + enforceFaLiveRoutePlan: ({ executionPlan }) => ({ executionPlan, audit: { fa: true } }), + executeRouteRuntime: async () => ({ + status: "ok", + result_type: "summary", + items: [], + summary: {}, + evidence: [], + limitations: [] + }), + mapNoRouteReason: () => "skipped", + buildSkippedResult: (item) => + ({ + fragment_id: item.fragment_id, + requirement_ids: item.requirement_ids ?? [], + route: item.route, + status: "skipped" + }) as any, + evaluateCoverage: () => ({ + requirements: [{ id: "R1" }], + coverage: { requirements_total: 1, requirements_covered: 1 } + }), + checkGrounding: () => ({ + status: "grounded", + reasons: [] + }), + collectRbpLiveRouteAudit: () => ({ routed: 1 }), + collectFaLiveRouteAudit: () => ({ routed: 1 }), + hasExplicitPeriodAnchor: () => false, + ...overrides + } as RunAssistantDeepTurnAnalysisAttemptRuntimeInput; +} + +describe("assistant deep turn analysis attempt runtime adapter", () => { + it("wires deep-analysis callbacks through delegated runtime", async () => { + const runDeepTurnContextRuntime = vi.fn(() => ({ + companyAnchors: { accounts: ["60.01"] }, + initialBusinessScopeResolution: { route_summary_resolved: { mode: "deterministic_v2", decisions: [] } }, + inferredDomainByMessage: "settlements_60_62", + focusDomainForGuards: "settlements_60_62", + temporalGuard: { primary_period_window: { from: "2020-07-01", to: "2020-07-31" } }, + domainPolarityGuardInitial: { polarity: "supplier_payable" }, + claimAnchorAudit: { claim_type: "prove_settlement_closure_state" }, + businessScopeResolution: { + route_summary_resolved: { mode: "deterministic_v2", decisions: [] }, + business_scope_resolved: ["company_specific_accounting"] + }, + resolvedRouteSummary: { mode: "deterministic_v2", decisions: [] }, + liveTemporalHint: { + as_of_date: "2020-07-31", + period_from: null, + period_to: null, + source: "analysis_context" + } + })); + const runDeepTurnPlanRuntime = vi.fn(() => ({ + requirementExtraction: { + requirements: [{ id: "R1" }], + byFragment: new Map([["F1", ["R1"]]]) + }, + executionPlan: [ + { + fragment_id: "F1", + requirement_ids: ["R1"], + route: "store_canonical", + should_execute: true, + fragment_text: "fragment", + no_route_reason: null + } + ], + rbpRoutePlanEnforcement: { executionPlan: [], audit: { rbp: true } }, + faRoutePlanEnforcement: { executionPlan: [], audit: { fa: true } } + })); + const executeRouteRuntime = vi.fn(async () => ({ + status: "ok", + result_type: "summary", + items: [], + summary: {}, + evidence: [], + limitations: [] + })); + const runDeepTurnRetrievalRuntime = vi.fn(async (input) => { + expect(input.executeRouteRuntime).toBe(executeRouteRuntime); + return { + retrievalCalls: [{ fragment_id: "F1", route: "store_canonical" }], + retrievalResultsRaw: [{ fragment_id: "F1", route: "store_canonical", raw_result: {} }], + retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"], route: "store_canonical" }] + } as any; + }); + const runDeepTurnGuardRuntime = vi.fn(() => ({ + retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"], route: "store_canonical" }], + polarityGuardResult: { audit: { polarity: "supplier_payable" } }, + targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: 1 } }, + evidenceGateResult: { audit: { admissible_evidence_count: 1 } } + })); + const runDeepTurnGroundingRuntime = vi.fn(() => ({ + rbpLiveRouteAudit: { routed: 1 }, + faLiveRouteAudit: { routed: 1 }, + coverageEvaluation: { + requirements: [{ id: "R1" }], + coverage: { requirements_total: 1, requirements_covered: 1 } + }, + groundedAnswerEligibilityGuard: { eligible: true }, + groundingCheck: { status: "grounded", reasons: [] } + })); + const runDeepTurnCompositionRuntime = vi.fn(() => ({ + questionTypeClass: "causal_trace", + composition: { reply_type: "factual_with_explanation" } + })); + const runDeepTurnAnalysisRuntime = vi.fn(async (input) => { + const contextRuntime = input.runContextRuntime(); + const executionPlanRuntime = input.runExecutionPlanRuntime({ + resolvedRouteSummary: contextRuntime.resolvedRouteSummary, + claimAnchorAudit: contextRuntime.claimAnchorAudit, + temporalGuard: contextRuntime.temporalGuard, + domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial + }); + const retrievalRuntime = await input.runRetrievalRuntime({ + executionPlan: executionPlanRuntime.executionPlan, + liveTemporalHint: contextRuntime.liveTemporalHint + }); + const guardRuntime = input.runGuardRuntime({ + retrievalResults: retrievalRuntime.retrievalResults as any, + domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial, + claimAnchorAudit: contextRuntime.claimAnchorAudit, + temporalGuard: contextRuntime.temporalGuard, + focusDomainForGuards: contextRuntime.focusDomainForGuards, + companyAnchors: contextRuntime.companyAnchors, + userMessage: "runtime-user-message" + }); + const groundingRuntime = input.runGroundingRuntime({ + claimType: contextRuntime.claimAnchorAudit.claim_type, + retrievalResults: guardRuntime.retrievalResults as any, + rbpPlanAudit: executionPlanRuntime.rbpRoutePlanEnforcement.audit, + faPlanAudit: executionPlanRuntime.faRoutePlanEnforcement.audit, + routeSummary: contextRuntime.resolvedRouteSummary, + requirementExtraction: executionPlanRuntime.requirementExtraction, + temporalGuard: contextRuntime.temporalGuard, + polarityAudit: guardRuntime.polarityGuardResult.audit, + evidenceAudit: guardRuntime.evidenceGateResult.audit, + claimAnchorAudit: contextRuntime.claimAnchorAudit, + targetedEvidenceHitRate: guardRuntime.targetedEvidenceResult.audit.targeted_evidence_hit_rate, + businessScopeResolved: contextRuntime.businessScopeResolution.business_scope_resolved + }); + const compositionRuntime = input.runCompositionRuntime({ + resolvedRouteSummary: contextRuntime.resolvedRouteSummary, + retrievalResults: guardRuntime.retrievalResults as any, + requirements: groundingRuntime.coverageEvaluation.requirements as any, + coverageReport: groundingRuntime.coverageEvaluation.coverage as any, + groundingCheck: groundingRuntime.groundingCheck as any, + companyAnchors: contextRuntime.companyAnchors + }); + + return { + companyAnchors: contextRuntime.companyAnchors, + temporalGuard: contextRuntime.temporalGuard, + claimAnchorAudit: contextRuntime.claimAnchorAudit, + businessScopeResolution: contextRuntime.businessScopeResolution, + resolvedRouteSummary: contextRuntime.resolvedRouteSummary, + requirementExtraction: executionPlanRuntime.requirementExtraction as any, + executionPlan: executionPlanRuntime.executionPlan as any, + retrievalCalls: retrievalRuntime.retrievalCalls as any, + retrievalResultsRaw: retrievalRuntime.retrievalResultsRaw as any, + retrievalResults: guardRuntime.retrievalResults as any, + polarityGuardResult: guardRuntime.polarityGuardResult as any, + targetedEvidenceResult: guardRuntime.targetedEvidenceResult as any, + evidenceGateResult: guardRuntime.evidenceGateResult as any, + rbpLiveRouteAudit: groundingRuntime.rbpLiveRouteAudit as any, + faLiveRouteAudit: groundingRuntime.faLiveRouteAudit as any, + coverageEvaluation: groundingRuntime.coverageEvaluation as any, + groundedAnswerEligibilityGuard: groundingRuntime.groundedAnswerEligibilityGuard as any, + groundingCheck: groundingRuntime.groundingCheck as any, + questionTypeClass: compositionRuntime.questionTypeClass as any, + composition: compositionRuntime.composition as any + }; + }); + + const runtime = await runAssistantDeepTurnAnalysisAttemptRuntime( + buildInput({ + executeRouteRuntime, + runDeepTurnAnalysisRuntime, + runDeepTurnContextRuntime, + runDeepTurnPlanRuntime, + runDeepTurnRetrievalRuntime, + runDeepTurnGuardRuntime, + runDeepTurnGroundingRuntime, + runDeepTurnCompositionRuntime + }) + ); + + expect(runDeepTurnAnalysisRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnContextRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnPlanRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnRetrievalRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnGuardRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnGroundingRuntime).toHaveBeenCalledTimes(1); + expect(runDeepTurnCompositionRuntime).toHaveBeenCalledTimes(1); + expect(runtime.questionTypeClass).toBe("causal_trace"); + }); + + it("forwards composition feature flags and investigation state", async () => { + const runDeepTurnCompositionRuntime = vi.fn(() => ({ + questionTypeClass: "single_fact_lookup", + composition: { reply_type: "partial_coverage" } + })); + const runDeepTurnAnalysisRuntime = vi.fn(async (input) => { + input.runContextRuntime(); + input.runExecutionPlanRuntime({ + resolvedRouteSummary: null, + claimAnchorAudit: { claim_type: "unknown" }, + temporalGuard: {}, + domainPolarityGuardInitial: {} + }); + await input.runRetrievalRuntime({ + executionPlan: [], + liveTemporalHint: null + }); + input.runGuardRuntime({ + retrievalResults: [], + domainPolarityGuardInitial: {}, + claimAnchorAudit: { claim_type: "unknown" }, + temporalGuard: {}, + focusDomainForGuards: null, + companyAnchors: {}, + userMessage: "message" + }); + input.runGroundingRuntime({ + claimType: "unknown", + retrievalResults: [], + rbpPlanAudit: {}, + faPlanAudit: {}, + routeSummary: null, + requirementExtraction: { requirements: [], byFragment: new Map() } as any, + temporalGuard: {}, + polarityAudit: {}, + evidenceAudit: {}, + claimAnchorAudit: { claim_type: "unknown" }, + targetedEvidenceHitRate: null, + businessScopeResolved: null + }); + input.runCompositionRuntime({ + resolvedRouteSummary: null, + retrievalResults: [], + requirements: [], + coverageReport: {}, + groundingCheck: { status: "grounded", reasons: [] }, + companyAnchors: {} + }); + return { + companyAnchors: {}, + temporalGuard: {}, + claimAnchorAudit: { claim_type: "unknown" }, + businessScopeResolution: {}, + resolvedRouteSummary: null, + requirementExtraction: { requirements: [], byFragment: new Map() } as any, + executionPlan: [], + retrievalCalls: [], + retrievalResultsRaw: [], + retrievalResults: [], + polarityGuardResult: { audit: {} } as any, + targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: null } } as any, + evidenceGateResult: { audit: {} } as any, + rbpLiveRouteAudit: {}, + faLiveRouteAudit: {}, + coverageEvaluation: { requirements: [], coverage: {} } as any, + groundedAnswerEligibilityGuard: {}, + groundingCheck: { status: "grounded", reasons: [] } as any, + questionTypeClass: "single_fact_lookup" as any, + composition: { reply_type: "partial_coverage" } as any + }; + }); + + const investigationState = { session_id: "asst-2" } as any; + await runAssistantDeepTurnAnalysisAttemptRuntime( + buildInput({ + investigationState, + featureAnswerPolicyV11: false, + featureProblemCentricAnswerV1: false, + featureLifecycleAnswerV1: false, + runDeepTurnCompositionRuntime, + runDeepTurnAnalysisRuntime + }) + ); + + expect(runDeepTurnCompositionRuntime).toHaveBeenCalledWith( + expect.objectContaining({ + investigationState, + featureAnswerPolicyV11: false, + featureProblemCentricAnswerV1: false, + featureLifecycleAnswerV1: false + }) + ); + }); +});