diff --git a/docs/TECH/1CLLMARCH-FACT.md b/docs/TECH/1CLLMARCH-FACT.md index afdc670..04029ce 100644 --- a/docs/TECH/1CLLMARCH-FACT.md +++ b/docs/TECH/1CLLMARCH-FACT.md @@ -1974,7 +1974,58 @@ Validation: - `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts` - `assistantDeepTurnAttemptRuntimeAdapter.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 + 2.46 + 2.47 + 2.48 + 2.49 + 2.50 + 2.51 + 2.52 + 2.53 + 2.54 + 2.55 + 2.56 + 2.57 + 2.58 + 2.59 + 2.60 + 2.61 + 2.62 + 2.63 + 2.64 + 2.65 + 2.66 + 2.67 + 2.68 + 2.69 + 2.70 + 2.71 + 2.72 + 2.73 + 2.74 + 2.75 + 2.76 + 2.77 + 2.78 + 2.79 + 2.80 + 2.81 + 2.82 + 2.83 + 2.84 + 2.85 + 2.86 + 2.87 + 2.88 completed)** +Implemented in current pass (Phase 2.89 + 2.90 + 2.91 + 2.92): +1. Hardened deep-turn response envelope contract: + - `assistantDeepTurnResponseBuilder.ts` + - removed weak `debug` union (`AssistantDebugPayload | Record`); + - response builder now accepts and propagates `AssistantDebugPayload` strictly. +2. Hardened deep-turn finalize runtime contract: + - `assistantDeepTurnFinalizeRuntimeAdapter.ts` + - aligned finalize input to strict `AssistantDebugPayload` for `debug`. +3. Preserved behavior: + - no runtime logic changes; only stricter contract enforcement for debug payload type at finalize/response boundary. + +Validation: +1. `npm run build` passed. +2. Targeted deep finalize/response pack passed: + - `assistantDeepTurnResponseBuilder.test.ts` + - `assistantDeepTurnFinalizeRuntimeAdapter.test.ts` + - `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts` + - `assistantDeepTurnAttemptRuntimeAdapter.test.ts` + +Implemented in current pass (Phase 2.93 + 2.94 + 2.95 + 2.96): +1. Introduced shared followup-usage contract and helper: + - `assistantFollowupUsage.ts` + - added: + - `AssistantFollowupUsage` + - `isAssistantFollowupApplied(...)` +2. Replaced weak `unknown` followup usage contracts across deep-turn chain: + - `assistantDeepTurnNormalizationRuntimeAdapter.ts` + - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts` + - `assistantDeepTurnContextRuntimeAdapter.ts` + - `assistantDeepTurnCompositionRuntimeAdapter.ts` + - `assistantDeepTurnAttemptInputBuilder.ts` + - `assistantDeepTurnResponseAttemptRuntimeAdapter.ts` + - `assistantDeepTurnInputBuilder.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnPackaging.ts` +3. Removed inline followup casts: + - switched `Boolean((... as { applied?: unknown })?.applied)` style checks to shared helper usage. +4. Preserved behavior: + - no logic changes, only contract normalization and reuse of a single applied-check helper. + +Validation: +1. `npm run build` passed. +2. Targeted deep followup chain pack passed: + - `assistantDeepTurnNormalizationRuntimeAdapter.test.ts` + - `assistantDeepTurnContextRuntimeAdapter.test.ts` + - `assistantDeepTurnCompositionRuntimeAdapter.test.ts` + - `assistantDeepTurnAttemptInputBuilder.test.ts` + - `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.test.ts` + - `assistantDeepTurnPackaging.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 + 2.46 + 2.47 + 2.48 + 2.49 + 2.50 + 2.51 + 2.52 + 2.53 + 2.54 + 2.55 + 2.56 + 2.57 + 2.58 + 2.59 + 2.60 + 2.61 + 2.62 + 2.63 + 2.64 + 2.65 + 2.66 + 2.67 + 2.68 + 2.69 + 2.70 + 2.71 + 2.72 + 2.73 + 2.74 + 2.75 + 2.76 + 2.77 + 2.78 + 2.79 + 2.80 + 2.81 + 2.82 + 2.83 + 2.84 + 2.85 + 2.86 + 2.87 + 2.88 + 2.89 + 2.90 + 2.91 + 2.92 + 2.93 + 2.94 + 2.95 + 2.96 completed)** ## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards) diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnAttemptInputBuilder.js b/llm_normalizer/backend/dist/services/assistantDeepTurnAttemptInputBuilder.js index bd7ac94..7d52636 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnAttemptInputBuilder.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnAttemptInputBuilder.js @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAssistantDeepTurnNormalizationRuntimeInput = buildAssistantDeepTurnNormalizationRuntimeInput; exports.buildAssistantDeepTurnAnalysisAttemptRuntimeInput = buildAssistantDeepTurnAnalysisAttemptRuntimeInput; exports.buildAssistantDeepTurnResponseAttemptRuntimeInput = buildAssistantDeepTurnResponseAttemptRuntimeInput; +const assistantFollowupUsage_1 = require("./assistantFollowupUsage"); function buildAssistantDeepTurnNormalizationRuntimeInput(input) { return { userMessage: input.userMessage, @@ -60,7 +61,7 @@ function buildAssistantDeepTurnResponseAttemptRuntimeInput(input) { deepTurnAnalysisRuntime: input.deepTurnAnalysisRuntime, runtimeAnalysisContext: input.runtimeAnalysisContext, followupStateUsage: input.normalizationRuntime.followupBinding.usage, - followupApplied: Boolean(input.normalizationRuntime.followupBinding.usage?.applied), + followupApplied: (0, assistantFollowupUsage_1.isAssistantFollowupApplied)(input.normalizationRuntime.followupBinding.usage), previousInvestigationState: input.sessionInvestigationState, addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep, extractDroppedIntentSegments: input.extractDroppedIntentSegments, diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js index b4781ce..6557d65 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAssistantDeepTurnComposition = buildAssistantDeepTurnComposition; const questionTypeResolver_1 = require("./questionTypeResolver"); const answerComposer_1 = require("./answerComposer"); +const assistantFollowupUsage_1 = require("./assistantFollowupUsage"); function toStringArray(value) { if (!Array.isArray(value)) { return []; @@ -30,7 +31,7 @@ function normalizeCompanyAnchorSet(value) { function buildAssistantDeepTurnComposition(input) { const resolveQuestionTypeSafe = input.resolveQuestionTypeFn ?? questionTypeResolver_1.resolveQuestionType; const composeAssistantAnswerSafe = input.composeAssistantAnswerFn ?? answerComposer_1.composeAssistantAnswer; - const followupApplied = Boolean(input.followupUsage?.applied); + const followupApplied = (0, assistantFollowupUsage_1.isAssistantFollowupApplied)(input.followupUsage); const focusDomainHint = followupApplied ? input.investigationState?.followup_context?.active_domain ?? input.investigationState?.focus.domain ?? null : null; diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnContextRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnContextRuntimeAdapter.js index 5a37c58..3dd260d 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnContextRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnContextRuntimeAdapter.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAssistantDeepTurnRuntimeContext = buildAssistantDeepTurnRuntimeContext; +const assistantFollowupUsage_1 = require("./assistantFollowupUsage"); const KNOWN_P0_DOMAINS = new Set([ "settlements_60_62", "vat_document_register_book", @@ -53,7 +54,7 @@ function buildAssistantDeepTurnRuntimeContext(input) { focusDomainHint: focusDomainForGuards, userMessage: input.userMessage, companyAnchors, - followupApplied: Boolean(input.followupUsage?.applied) + followupApplied: (0, assistantFollowupUsage_1.isAssistantFollowupApplied)(input.followupUsage) }); const resolvedRouteSummary = businessScopeResolution.route_summary_resolved; const liveTemporalHint = toAnalysisContext(input.runtimeAnalysisContext); diff --git a/llm_normalizer/backend/dist/services/assistantFollowupUsage.js b/llm_normalizer/backend/dist/services/assistantFollowupUsage.js new file mode 100644 index 0000000..c99c2d9 --- /dev/null +++ b/llm_normalizer/backend/dist/services/assistantFollowupUsage.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isAssistantFollowupApplied = isAssistantFollowupApplied; +function isAssistantFollowupApplied(usage) { + return Boolean(usage?.applied); +} diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts index 66c6eb7..6c6bec0 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptRuntimeAdapter.ts @@ -35,6 +35,7 @@ import { } from "./assistantDeepTurnCompositionRuntimeAdapter"; import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; import { buildAssistantDeepTurnAnalysisRuntimeInput } from "./assistantDeepTurnAnalysisAttemptInputBuilder"; interface RuntimeAnalysisContextLike { @@ -50,7 +51,7 @@ export interface RunAssistantDeepTurnAnalysisAttemptRuntimeInput { normalizedPayload: NormalizeResponsePayload["normalized"]; routeSummary: RouteHintSummary | null; runtimeAnalysisContext: RuntimeAnalysisContextLike; - followupUsage: unknown | null | undefined; + followupUsage: AssistantFollowupUsage | null | undefined; investigationState: InvestigationStateWithProblemUnits | null | undefined; featureAnswerPolicyV11: boolean; featureProblemCentricAnswerV1: boolean; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts index 769b090..8704470 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptInputBuilder.ts @@ -5,6 +5,7 @@ import type { import type { RunAssistantDeepTurnAnalysisAttemptRuntimeInput } from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter"; import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter"; import type { RunAssistantDeepTurnResponseAttemptRuntimeInput } from "./assistantDeepTurnResponseAttemptRuntimeAdapter"; +import { isAssistantFollowupApplied } from "./assistantFollowupUsage"; export interface BuildAssistantDeepTurnNormalizationRuntimeInputInput { userMessage: string; @@ -134,9 +135,7 @@ export function buildAssistantDeepTurnResponseAttemptRuntimeInput unknown; resolveBusinessScopeAlignment: (input: { userMessage: string; @@ -138,7 +139,7 @@ export function buildAssistantDeepTurnRuntimeContext( focusDomainHint: focusDomainForGuards, userMessage: input.userMessage, companyAnchors, - followupApplied: Boolean((input.followupUsage as { applied?: unknown } | null)?.applied) + followupApplied: isAssistantFollowupApplied(input.followupUsage) }); const resolvedRouteSummary = businessScopeResolution.route_summary_resolved; const liveTemporalHint = toAnalysisContext(input.runtimeAnalysisContext); diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts index f62e07be..88e8b00 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnFinalizeRuntimeAdapter.ts @@ -8,7 +8,7 @@ export interface FinalizeAssistantDeepTurnInput { assistantReply: string; replyType: AssistantReplyType; assistantItem: AssistantConversationItem; - debug: AssistantDebugPayload | Record; + debug: AssistantDebugPayload; deepAnalysisLogDetails: Record; appendItem: Parameters[0]["appendItem"]; getSession: Parameters[0]["getSession"]; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts index 8653dc4..8f923f8 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnInputBuilder.ts @@ -2,6 +2,7 @@ import type { AssistantReplyType, AssistantRequirement, AnswerGroundingCheck, Re import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { AnswerStructureV11 } from "../types/stage1Contracts"; import type { AssistantDeepTurnPackagingInput } from "./assistantDeepTurnPackaging"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; export interface AssistantDeepTurnInputBuilderArgs { sessionId: string; @@ -64,7 +65,7 @@ export interface AssistantDeepTurnInputBuilderArgs { rbpLiveRouteAudit: unknown | null; faLiveRouteAudit: unknown | null; groundedAnswerEligibilityGuard: Record; - followupStateUsage?: unknown; + followupStateUsage?: AssistantFollowupUsage | null; composition: { reply_type: AssistantReplyType; fallback_type: unknown; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts index 84f9802..d758c69 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnNormalizationRuntimeAdapter.ts @@ -1,10 +1,11 @@ import type { AssistantMessageRequestPayload } from "../types/assistant"; import type { NormalizeRequestPayload, NormalizeResponsePayload } from "../types/normalizer"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; export interface AssistantDeepTurnFollowupBinding { normalizedQuestion: string; mergedContext: NormalizeRequestPayload["context"] | undefined; - usage: unknown | null; + usage: AssistantFollowupUsage | null; } export interface BuildAssistantDeepTurnNormalizationRuntimeInput { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts index c55ee41..a041afe 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts @@ -17,6 +17,7 @@ import { assembleAssistantContractsBundleV1, type AssistantContractsBundleV1 } f import { buildDeepAnswerArtifacts, buildAssistantConversationItem, type DeepAnswerArtifacts } from "./assistantDeepResponseAssembler"; import { buildDeepAnalysisDebugPayload } from "./assistantDebugPayloadAssembler"; import { buildDeepAnalysisProcessedLogDetails } from "./assistantMessageLogAssembler"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; export interface AssistantDeepTurnPackagingInput { sessionId: string; @@ -79,7 +80,7 @@ export interface AssistantDeepTurnPackagingInput { rbpLiveRouteAudit: unknown | null; faLiveRouteAudit: unknown | null; groundedAnswerEligibilityGuard: Record; - followupStateUsage: unknown | null; + followupStateUsage: AssistantFollowupUsage | null; composition: { reply_type: AssistantReplyType; fallback_type: unknown; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts index a7ff3c8..c27bb12 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts @@ -12,6 +12,7 @@ import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemU import type { AssistantDeepTurnInputBuilderArgs } from "./assistantDeepTurnInputBuilder"; import { buildAssistantDeepTurnPackagingInput } from "./assistantDeepTurnInputBuilder"; import { assembleAssistantDeepTurnPackaging } from "./assistantDeepTurnPackaging"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; import type { AssistantAnalysisContextForContract, AssistantRuntimeAnalysisContextForPrePackaging @@ -59,7 +60,7 @@ export interface AssistantDeepTurnPackagingRuntimeInput { rbpLiveRouteAudit: unknown | null; faLiveRouteAudit: unknown | null; groundedAnswerEligibilityGuard: Record; - followupStateUsage?: unknown; + followupStateUsage?: AssistantFollowupUsage | null; followupApplied: boolean; composition: AssistantDeepTurnCompositionForPackaging; featureContractsV11: boolean; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts index e4a9931..5d67097 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts @@ -2,6 +2,7 @@ import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../ import type { NormalizeResponsePayload } from "../types/normalizer"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter"; +import type { AssistantFollowupUsage } from "./assistantFollowupUsage"; import { runAssistantDeepTurnResponseRuntime, type RunAssistantDeepTurnResponseRuntimeInput, @@ -27,7 +28,7 @@ export interface RunAssistantDeepTurnResponseAttemptRuntimeInput< normalizedQuestion: string; deepTurnAnalysisRuntime: RunAssistantDeepTurnAnalysisRuntimeOutput; runtimeAnalysisContext: unknown; - followupStateUsage: unknown; + followupStateUsage: AssistantFollowupUsage | null; followupApplied: boolean; previousInvestigationState: InvestigationStateWithProblemUnits | null | undefined; addressRuntimeMetaForDeep: unknown; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnResponseBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnResponseBuilder.ts index 0e0e6ff..903d475 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnResponseBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnResponseBuilder.ts @@ -10,7 +10,7 @@ export interface BuildAssistantDeepTurnSuccessResponseInput { assistantReply: string; replyType: AssistantReplyType; conversationItem: AssistantConversationItem; - debug: AssistantDebugPayload | Record; + debug: AssistantDebugPayload; conversation: AssistantConversationItem[]; } @@ -23,7 +23,7 @@ export function buildAssistantDeepTurnSuccessResponse( assistant_reply: input.assistantReply, reply_type: input.replyType, conversation_item: input.conversationItem, - debug: input.debug as AssistantDebugPayload, + debug: input.debug, conversation: input.conversation }; } diff --git a/llm_normalizer/backend/src/services/assistantFollowupUsage.ts b/llm_normalizer/backend/src/services/assistantFollowupUsage.ts new file mode 100644 index 0000000..36768cf --- /dev/null +++ b/llm_normalizer/backend/src/services/assistantFollowupUsage.ts @@ -0,0 +1,8 @@ +export interface AssistantFollowupUsage { + applied?: unknown; + [key: string]: unknown; +} + +export function isAssistantFollowupApplied(usage: AssistantFollowupUsage | null | undefined): boolean { + return Boolean(usage?.applied); +}