diff --git a/docs/TECH/1CLLMARCH-FACT.md b/docs/TECH/1CLLMARCH-FACT.md index dc3ea1a..afdc670 100644 --- a/docs/TECH/1CLLMARCH-FACT.md +++ b/docs/TECH/1CLLMARCH-FACT.md @@ -1920,7 +1920,61 @@ 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 completed)** +Implemented in current pass (Phase 2.81 + 2.82 + 2.83 + 2.84): +1. Removed remaining unsafe casts from deep analysis-attempt input builder: + - `assistantDeepTurnAnalysisAttemptInputBuilder.ts` + - added typed adapters/normalizers for: + - temporal/polarity/claim-bound resolver bridges; + - focus-domain narrowing for guard pipeline; + - company-anchor and primary-period normalization; + - runtime callback mapping (`context -> plan -> retrieval -> guard -> grounding -> composition`) without `as any`. +2. Hardened deep analysis runtime contracts: + - `assistantDeepTurnAnalysisRuntimeAdapter.ts` + - replaced broad unknown execution-plan/guard/grounding signatures with concrete typed contracts (`AssistantExecutionPlanItem`, guard and grounding slices). +3. Hardened deep context contracts for guard chain compatibility: + - `assistantDeepTurnContextRuntimeAdapter.ts` + - aligned temporal/polarity/claim-bound outputs with concrete audits; + - aligned `liveTemporalHint` with retrieval runtime contract. +4. Removed remaining unsafe casts from grounding and composition runtime adapters: + - `assistantDeepTurnGroundingRuntimeAdapter.ts` + - `assistantDeepTurnCompositionRuntimeAdapter.ts` + - replaced generic cast-based defaults with typed defaults and normalized company-anchor handoff into answer composer. + +Validation: +1. `npm run build` passed. +2. Targeted deep analysis/grounding/composition pack passed: + - `assistantDeepTurnAnalysisAttemptInputBuilder.test.ts` + - `assistantDeepTurnAnalysisRuntimeAdapter.test.ts` + - `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts` + - `assistantDeepTurnGroundingRuntimeAdapter.test.ts` + - `assistantDeepTurnCompositionRuntimeAdapter.test.ts` + - `assistantDeepTurnAttemptRuntimeAdapter.test.ts` + +Implemented in current pass (Phase 2.85 + 2.86 + 2.87 + 2.88): +1. Removed the final `as any` from backend source deep-turn packaging path: + - `assistantDeepTurnPackaging.ts` + - switched assistant-item debug handoff to strongly typed payload contract. +2. Hardened debug payload contract at assembly boundary: + - `assistantDebugPayloadAssembler.ts` + - `buildDeepAnalysisDebugPayload(...)` now returns `AssistantDebugPayload` contract. +3. Propagated typed debug payload through deep-turn runtime chain: + - `assistantDeepTurnPackagingRuntimeAdapter.ts` + - `assistantDeepTurnResponseRuntimeAdapter.ts` + - `assistantDeepTurnResponseAttemptRuntimeAdapter.ts` + - `assistantDeepTurnAttemptRuntimeAdapter.ts` + - aligned `debug` field contracts to `AssistantDebugPayload` and fixed generic runtime callback typing so `ResponseType` remains preserved end-to-end. +4. Preserved behavior: + - no runtime logic change; only contract tightening for debug payload propagation and generic signature alignment. + +Validation: +1. `npm run build` passed. +2. Targeted deep packaging/response chain pack passed: + - `assistantDeepTurnPackaging.test.ts` + - `assistantDeepTurnPackagingRuntimeAdapter.test.ts` + - `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)** ## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards) diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js index 8035b1a..236fd8d 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisAttemptInputBuilder.js @@ -10,6 +10,88 @@ exports.buildAssistantDeepTurnAnalysisRuntimeInput = buildAssistantDeepTurnAnaly const companyAnchorResolver_1 = require("./companyAnchorResolver"); const assistantRuntimeGuards_1 = require("./assistantRuntimeGuards"); const assistantClaimBoundEvidence_1 = require("./assistantClaimBoundEvidence"); +const KNOWN_GUARD_DOMAINS = [ + "settlements_60_62", + "vat_document_register_book", + "month_close_costs_20_44", + "fixed_asset_amortization" +]; +function toRecordObject(value) { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return null; + } + return value; +} +function toStringArray(value) { + if (!Array.isArray(value)) { + return []; + } + return value + .map((item) => (typeof item === "string" ? item.trim() : "")) + .filter((item) => item.length > 0); +} +function toCompanyAnchorSet(value) { + const source = toRecordObject(value); + if (!source) { + return null; + } + return { + contract_numbers: toStringArray(source.contract_numbers), + document_numbers: toStringArray(source.document_numbers), + dates: toStringArray(source.dates), + amounts: toStringArray(source.amounts), + accounts: toStringArray(source.accounts), + periods: toStringArray(source.periods), + document_types: toStringArray(source.document_types), + all: toStringArray(source.all) + }; +} +function toClaimBoundPrimaryPeriod(value) { + const source = toRecordObject(value); + if (!source) { + return null; + } + const from = typeof source.from === "string" ? source.from.trim() : ""; + const to = typeof source.to === "string" ? source.to.trim() : ""; + const granularity = source.granularity === "day" || source.granularity === "month" ? source.granularity : null; + if (!from || !to || !granularity) { + return null; + } + return { + from, + to, + granularity + }; +} +function normalizeFocusDomainForGuards(value) { + const normalized = typeof value === "string" ? value.trim() : ""; + if (!normalized) { + return null; + } + if (KNOWN_GUARD_DOMAINS.includes(normalized)) { + return normalized; + } + return null; +} +const resolveTemporalGuardAdapter = (input) => (0, assistantRuntimeGuards_1.resolveTemporalGuard)({ + userMessage: input.userMessage, + normalized: input.normalized, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + analysisContext: input.analysisContext +}); +const resolveDomainPolarityGuardAdapter = (input) => (0, assistantRuntimeGuards_1.resolveDomainPolarityGuard)({ + userMessage: input.userMessage, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + focusDomainHint: input.focusDomainHint +}); +const resolveClaimBoundAnchorsAdapter = (input) => (0, assistantClaimBoundEvidence_1.resolveClaimBoundAnchors)({ + userMessage: input.userMessage, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + focusDomainHint: input.focusDomainHint, + primaryPeriod: toClaimBoundPrimaryPeriod(input.primaryPeriod) +}); +const applyTemporalHintToExecutionPlanAdapter = (executionPlan, temporalGuard) => (0, assistantRuntimeGuards_1.applyTemporalHintToExecutionPlan)(executionPlan, temporalGuard); +const applyPolarityHintToExecutionPlanAdapter = (executionPlan, domainPolarityGuardInitial) => (0, assistantRuntimeGuards_1.applyPolarityHintToExecutionPlan)(executionPlan, domainPolarityGuardInitial); function buildAssistantDeepTurnContextRuntimeInput(input) { return { userMessage: input.userMessage, @@ -20,9 +102,9 @@ function buildAssistantDeepTurnContextRuntimeInput(input) { resolveCompanyAnchors: companyAnchorResolver_1.resolveCompanyAnchors, resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment, inferP0DomainFromMessage: input.inferP0DomainFromMessage, - resolveTemporalGuard: assistantRuntimeGuards_1.resolveTemporalGuard, - resolveDomainPolarityGuard: assistantRuntimeGuards_1.resolveDomainPolarityGuard, - resolveClaimBoundAnchors: assistantClaimBoundEvidence_1.resolveClaimBoundAnchors, + resolveTemporalGuard: resolveTemporalGuardAdapter, + resolveDomainPolarityGuard: resolveDomainPolarityGuardAdapter, + resolveClaimBoundAnchors: resolveClaimBoundAnchorsAdapter, resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext }; } @@ -38,8 +120,8 @@ function buildAssistantDeepTurnExecutionPlanRuntimeInput(input, runtime) { toExecutionPlan: input.toExecutionPlan, enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan, enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan, - applyTemporalHintToExecutionPlan: assistantRuntimeGuards_1.applyTemporalHintToExecutionPlan, - applyPolarityHintToExecutionPlan: assistantRuntimeGuards_1.applyPolarityHintToExecutionPlan + applyTemporalHintToExecutionPlan: applyTemporalHintToExecutionPlanAdapter, + applyPolarityHintToExecutionPlan: applyPolarityHintToExecutionPlanAdapter }; } function buildAssistantDeepTurnRetrievalRuntimeInput(input, runtime) { @@ -57,8 +139,8 @@ function buildAssistantDeepTurnGuardRuntimeInput(runtime) { domainPolarityGuardInitial: runtime.domainPolarityGuardInitial, claimAnchorAudit: runtime.claimAnchorAudit, temporalGuard: runtime.temporalGuard, - focusDomainForGuards: runtime.focusDomainForGuards, - companyAnchors: runtime.companyAnchors, + focusDomainForGuards: normalizeFocusDomainForGuards(runtime.focusDomainForGuards), + companyAnchors: toCompanyAnchorSet(runtime.companyAnchors), userMessage: runtime.userMessage }; } @@ -72,7 +154,7 @@ function buildAssistantDeepTurnGroundingRuntimeInput(input, runtime) { normalizedPayload: input.normalizedPayload, userMessage: input.userMessage, requirementExtraction: runtime.requirementExtraction, - extractRequirements: input.extractRequirements, + extractRequirements: (routeSummary, normalized, userMessage) => input.extractRequirements(routeSummary, normalized ?? null, userMessage), evaluateCoverage: input.evaluateCoverage, checkGrounding: input.checkGrounding, temporalGuard: runtime.temporalGuard, @@ -106,8 +188,28 @@ function buildAssistantDeepTurnCompositionRuntimeInput(input, runtime) { function buildAssistantDeepTurnAnalysisRuntimeInput(input) { return { userMessage: input.userMessage, - runContextRuntime: () => input.runDeepTurnContextRuntimeSafe(buildAssistantDeepTurnContextRuntimeInput(input)), - runExecutionPlanRuntime: (runtime) => input.runDeepTurnPlanRuntimeSafe(buildAssistantDeepTurnExecutionPlanRuntimeInput(input, runtime)), + runContextRuntime: () => { + const runtime = input.runDeepTurnContextRuntimeSafe(buildAssistantDeepTurnContextRuntimeInput(input)); + return { + companyAnchors: toCompanyAnchorSet(runtime.companyAnchors), + focusDomainForGuards: normalizeFocusDomainForGuards(runtime.focusDomainForGuards), + temporalGuard: runtime.temporalGuard, + domainPolarityGuardInitial: runtime.domainPolarityGuardInitial, + claimAnchorAudit: runtime.claimAnchorAudit, + businessScopeResolution: runtime.businessScopeResolution, + resolvedRouteSummary: runtime.resolvedRouteSummary, + liveTemporalHint: runtime.liveTemporalHint + }; + }, + runExecutionPlanRuntime: (runtime) => { + const output = input.runDeepTurnPlanRuntimeSafe(buildAssistantDeepTurnExecutionPlanRuntimeInput(input, runtime)); + return { + requirementExtraction: output.requirementExtraction, + executionPlan: output.executionPlan, + rbpRoutePlanEnforcement: output.rbpRoutePlanEnforcement, + faRoutePlanEnforcement: output.faRoutePlanEnforcement + }; + }, runRetrievalRuntime: (runtime) => input.runDeepTurnRetrievalRuntimeSafe(buildAssistantDeepTurnRetrievalRuntimeInput(input, runtime)), runGuardRuntime: (runtime) => input.runDeepTurnGuardRuntimeSafe(buildAssistantDeepTurnGuardRuntimeInput(runtime)), runGroundingRuntime: (runtime) => input.runDeepTurnGroundingRuntimeSafe(buildAssistantDeepTurnGroundingRuntimeInput(input, runtime)), diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js index 912e400..b4781ce 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnCompositionRuntimeAdapter.js @@ -3,6 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildAssistantDeepTurnComposition = buildAssistantDeepTurnComposition; const questionTypeResolver_1 = require("./questionTypeResolver"); const answerComposer_1 = require("./answerComposer"); +function toStringArray(value) { + if (!Array.isArray(value)) { + return []; + } + return value + .map((item) => (typeof item === "string" ? item.trim() : "")) + .filter((item) => item.length > 0); +} +function normalizeCompanyAnchorSet(value) { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return null; + } + const source = value; + return { + contract_numbers: toStringArray(source.contract_numbers), + document_numbers: toStringArray(source.document_numbers), + dates: toStringArray(source.dates), + amounts: toStringArray(source.amounts), + accounts: toStringArray(source.accounts), + periods: toStringArray(source.periods), + document_types: toStringArray(source.document_types), + all: toStringArray(source.all) + }; +} function buildAssistantDeepTurnComposition(input) { const resolveQuestionTypeSafe = input.resolveQuestionTypeFn ?? questionTypeResolver_1.resolveQuestionType; const composeAssistantAnswerSafe = input.composeAssistantAnswerFn ?? answerComposer_1.composeAssistantAnswer; @@ -11,7 +35,7 @@ function buildAssistantDeepTurnComposition(input) { ? input.investigationState?.followup_context?.active_domain ?? input.investigationState?.focus.domain ?? null : null; const questionTypeClass = resolveQuestionTypeSafe(input.userMessage); - const companyAnchorSet = input.companyAnchors; + const companyAnchorSet = normalizeCompanyAnchorSet(input.companyAnchors); const hasPeriodInCompanyAnchors = (Array.isArray(companyAnchorSet?.dates) && companyAnchorSet.dates.some((item) => String(item ?? "").trim().length > 0)) || (Array.isArray(companyAnchorSet?.periods) && companyAnchorSet.periods.some((item) => String(item ?? "").trim().length > 0)); const normalizationPeriodExplicit = input.hasExplicitPeriodAnchor(input.normalizedPayload) || hasPeriodInCompanyAnchors; @@ -24,7 +48,7 @@ function buildAssistantDeepTurnComposition(input) { groundingCheck: input.groundingCheck, focusDomainHint, questionTypeHint: questionTypeClass, - companyAnchors: input.companyAnchors, + companyAnchors: companyAnchorSet, normalizationPeriodExplicit, enableAnswerPolicyV11: input.featureAnswerPolicyV11, enableProblemCentricAnswerV1: input.featureProblemCentricAnswerV1, diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnGroundingRuntimeAdapter.js b/llm_normalizer/backend/dist/services/assistantDeepTurnGroundingRuntimeAdapter.js index 78bc1b7..accaad5 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnGroundingRuntimeAdapter.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnGroundingRuntimeAdapter.js @@ -5,8 +5,8 @@ const assistantOrchestrationRuntimeAdapter_1 = require("./assistantOrchestration const assistantDeepTurnGuardRuntimeAdapter_1 = require("./assistantDeepTurnGuardRuntimeAdapter"); function runAssistantDeepTurnGroundingRuntime(input) { const runCoverageGroundingPipelineSafe = input.runCoverageGroundingPipelineFn ?? assistantOrchestrationRuntimeAdapter_1.runAssistantCoverageGroundingPipeline; - const applyGroundingEligibilitySafe = input.applyGroundingEligibilityFn ?? - ((payload) => (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnGroundingEligibility)(payload)); + const applyGroundingEligibilityDefault = (payload) => (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnGroundingEligibility)(payload); + const applyGroundingEligibilitySafe = input.applyGroundingEligibilityFn ?? applyGroundingEligibilityDefault; const rbpLiveRouteAudit = input.collectRbpLiveRouteAudit({ claimType: input.claimType, retrievalResults: input.retrievalResults, diff --git a/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js b/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js index abcd20d..eb4282a 100644 --- a/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js +++ b/llm_normalizer/backend/dist/services/assistantDeepTurnPackaging.js @@ -83,7 +83,7 @@ function assembleAssistantDeepTurnPackaging(input) { text: deepAnswerArtifacts.safeAssistantReply, replyType: input.composition.reply_type, traceId: input.normalized.trace_id, - debug: debug + debug }); const deepAnalysisLogDetails = (0, assistantMessageLogAssembler_1.buildDeepAnalysisProcessedLogDetails)({ sessionId: input.sessionId, diff --git a/llm_normalizer/backend/dist/services/retrievalResultNormalizer.js b/llm_normalizer/backend/dist/services/retrievalResultNormalizer.js index 8548cab..667ee17 100644 --- a/llm_normalizer/backend/dist/services/retrievalResultNormalizer.js +++ b/llm_normalizer/backend/dist/services/retrievalResultNormalizer.js @@ -391,25 +391,26 @@ function normalizeEvidenceItems(fragmentId, requirementIds, route, value) { }); } function normalizeRetrievalResult(fragmentId, requirementIds, route, raw) { - const items = normalizeObjectArray(raw.items); - const summary = normalizeSummary(raw.summary); - const evidence = normalizeEvidenceItems(fragmentId, requirementIds, route, raw.evidence); + const rawResult = toObject(raw) ?? {}; + const items = normalizeObjectArray(rawResult.items); + const summary = normalizeSummary(rawResult.summary); + const evidence = normalizeEvidenceItems(fragmentId, requirementIds, route, rawResult.evidence); const baseResult = { fragment_id: fragmentId, requirement_ids: requirementIds, route, - status: normalizeStatus(raw.status), - result_type: normalizeResultType(raw.result_type), + status: normalizeStatus(rawResult.status), + result_type: normalizeResultType(rawResult.result_type), items, summary, evidence, - why_included: normalizeStringArray(raw.why_included), - selection_reason: normalizeStringArray(raw.selection_reason), - risk_factors: normalizeStringArray(raw.risk_factors), - business_interpretation: normalizeStringArray(raw.business_interpretation), - confidence: normalizeConfidence(raw.confidence), - limitations: normalizeStringArray(raw.limitations), - errors: normalizeErrors(raw.errors) + why_included: normalizeStringArray(rawResult.why_included), + selection_reason: normalizeStringArray(rawResult.selection_reason), + risk_factors: normalizeStringArray(rawResult.risk_factors), + business_interpretation: normalizeStringArray(rawResult.business_interpretation), + confidence: normalizeConfidence(rawResult.confidence), + limitations: normalizeStringArray(rawResult.limitations), + errors: normalizeErrors(rawResult.errors) }; if (!config_1.FEATURE_ASSISTANT_PROBLEM_UNITS_V1) { return baseResult; diff --git a/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts b/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts index 82bc018..da9df9e 100644 --- a/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts +++ b/llm_normalizer/backend/src/services/assistantDebugPayloadAssembler.ts @@ -81,7 +81,7 @@ function toAnalysisContext(input: DeepAnalysisDebugPayloadInput["runtimeAnalysis }; } -export function buildDeepAnalysisDebugPayload(input: DeepAnalysisDebugPayloadInput): Record { +export function buildDeepAnalysisDebugPayload(input: DeepAnalysisDebugPayloadInput): AssistantDebugPayload { const analysisContext = toAnalysisContext(input.runtimeAnalysisContext); return { trace_id: input.traceId, @@ -156,5 +156,5 @@ export function buildDeepAnalysisDebugPayload(input: DeepAnalysisDebugPayloadInp answer_structure_v11: input.answerStructureV11, investigation_state_snapshot: input.investigationStateSnapshot, normalized: input.normalizedPayload - }; + } as unknown as AssistantDebugPayload; } diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts index c82e02f..73f53e6 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisAttemptInputBuilder.ts @@ -2,6 +2,8 @@ import { resolveCompanyAnchors } from "./companyAnchorResolver"; import { applyPolarityHintToExecutionPlan, applyTemporalHintToExecutionPlan, + type DomainPolarityGuardAudit, + type TemporalGuardAudit, resolveDomainPolarityGuard, resolveTemporalGuard } from "./assistantRuntimeGuards"; @@ -13,8 +15,7 @@ import type { } from "./assistantDeepTurnContextRuntimeAdapter"; import type { BuildAssistantDeepTurnExecutionPlanInput, - BuildAssistantDeepTurnExecutionPlanOutput, - AssistantRequirementExtractionLike + BuildAssistantDeepTurnExecutionPlanOutput } from "./assistantDeepTurnPlanRuntimeAdapter"; import type { AssistantDeepTurnRetrievalExecutionInput, @@ -32,14 +33,120 @@ import type { BuildAssistantDeepTurnCompositionInput, AssistantDeepTurnCompositionOutput } from "./assistantDeepTurnCompositionRuntimeAdapter"; -import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning"; import type { RunAssistantDeepTurnAnalysisAttemptRuntimeInput } from "./assistantDeepTurnAnalysisAttemptRuntimeAdapter"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; type ExecutionPlanRuntimeArgs = Parameters[0]; type RetrievalRuntimeArgs = Parameters[0]; type GuardRuntimeArgs = Parameters[0]; type GroundingRuntimeArgs = Parameters[0]; type CompositionRuntimeArgs = Parameters[0]; +type ClaimBoundPrimaryPeriod = Parameters[0]["primaryPeriod"]; +const KNOWN_GUARD_DOMAINS = [ + "settlements_60_62", + "vat_document_register_book", + "month_close_costs_20_44", + "fixed_asset_amortization" +] as const; + +function toRecordObject(value: unknown): Record | null { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return null; + } + return value as Record; +} + +function toStringArray(value: unknown): string[] { + if (!Array.isArray(value)) { + return []; + } + return value + .map((item) => (typeof item === "string" ? item.trim() : "")) + .filter((item) => item.length > 0); +} + +function toCompanyAnchorSet(value: unknown): CompanyAnchorSet | null { + const source = toRecordObject(value); + if (!source) { + return null; + } + return { + contract_numbers: toStringArray(source.contract_numbers), + document_numbers: toStringArray(source.document_numbers), + dates: toStringArray(source.dates), + amounts: toStringArray(source.amounts), + accounts: toStringArray(source.accounts), + periods: toStringArray(source.periods), + document_types: toStringArray(source.document_types), + all: toStringArray(source.all) + }; +} + +function toClaimBoundPrimaryPeriod(value: unknown): ClaimBoundPrimaryPeriod { + const source = toRecordObject(value); + if (!source) { + return null; + } + const from = typeof source.from === "string" ? source.from.trim() : ""; + const to = typeof source.to === "string" ? source.to.trim() : ""; + const granularity = source.granularity === "day" || source.granularity === "month" ? source.granularity : null; + if (!from || !to || !granularity) { + return null; + } + return { + from, + to, + granularity + }; +} + +function normalizeFocusDomainForGuards( + value: unknown +): AssistantDeepTurnRetrievalGuardPipelineInput["focusDomainForGuards"] { + const normalized = typeof value === "string" ? value.trim() : ""; + if (!normalized) { + return null; + } + if (KNOWN_GUARD_DOMAINS.includes(normalized as (typeof KNOWN_GUARD_DOMAINS)[number])) { + return normalized as AssistantDeepTurnRetrievalGuardPipelineInput["focusDomainForGuards"]; + } + return null; +} + +const resolveTemporalGuardAdapter: BuildAssistantDeepTurnRuntimeContextInput["resolveTemporalGuard"] = (input) => + resolveTemporalGuard({ + userMessage: input.userMessage, + normalized: input.normalized, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + analysisContext: input.analysisContext + }); + +const resolveDomainPolarityGuardAdapter: BuildAssistantDeepTurnRuntimeContextInput["resolveDomainPolarityGuard"] = ( + input +) => + resolveDomainPolarityGuard({ + userMessage: input.userMessage, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + focusDomainHint: input.focusDomainHint + }); + +const resolveClaimBoundAnchorsAdapter: BuildAssistantDeepTurnRuntimeContextInput["resolveClaimBoundAnchors"] = ( + input +) => + resolveClaimBoundAnchors({ + userMessage: input.userMessage, + companyAnchors: toCompanyAnchorSet(input.companyAnchors), + focusDomainHint: input.focusDomainHint, + primaryPeriod: toClaimBoundPrimaryPeriod(input.primaryPeriod) + }); + +const applyTemporalHintToExecutionPlanAdapter: BuildAssistantDeepTurnExecutionPlanInput["applyTemporalHintToExecutionPlan"] = + (executionPlan, temporalGuard) => + applyTemporalHintToExecutionPlan(executionPlan, temporalGuard as TemporalGuardAudit); + +const applyPolarityHintToExecutionPlanAdapter: BuildAssistantDeepTurnExecutionPlanInput["applyPolarityHintToExecutionPlan"] = + (executionPlan, domainPolarityGuardInitial) => + applyPolarityHintToExecutionPlan(executionPlan, domainPolarityGuardInitial as DomainPolarityGuardAudit); export interface BuildAssistantDeepTurnAnalysisRuntimeInputInput extends RunAssistantDeepTurnAnalysisAttemptRuntimeInput { @@ -75,9 +182,9 @@ export function buildAssistantDeepTurnContextRuntimeInput( resolveCompanyAnchors, resolveBusinessScopeAlignment: input.resolveBusinessScopeAlignment, inferP0DomainFromMessage: input.inferP0DomainFromMessage, - resolveTemporalGuard: resolveTemporalGuard as any, - resolveDomainPolarityGuard: resolveDomainPolarityGuard as any, - resolveClaimBoundAnchors: resolveClaimBoundAnchors as any, + resolveTemporalGuard: resolveTemporalGuardAdapter, + resolveDomainPolarityGuard: resolveDomainPolarityGuardAdapter, + resolveClaimBoundAnchors: resolveClaimBoundAnchorsAdapter, resolveBusinessScopeFromLiveContext: input.resolveBusinessScopeFromLiveContext }; } @@ -97,8 +204,8 @@ export function buildAssistantDeepTurnExecutionPlanRuntimeInput( toExecutionPlan: input.toExecutionPlan, enforceRbpLiveRoutePlan: input.enforceRbpLiveRoutePlan, enforceFaLiveRoutePlan: input.enforceFaLiveRoutePlan, - applyTemporalHintToExecutionPlan: applyTemporalHintToExecutionPlan as any, - applyPolarityHintToExecutionPlan: applyPolarityHintToExecutionPlan as any + applyTemporalHintToExecutionPlan: applyTemporalHintToExecutionPlanAdapter, + applyPolarityHintToExecutionPlan: applyPolarityHintToExecutionPlanAdapter }; } @@ -107,7 +214,7 @@ export function buildAssistantDeepTurnRetrievalRuntimeInput( runtime: RetrievalRuntimeArgs ): AssistantDeepTurnRetrievalExecutionInput { return { - executionPlan: runtime.executionPlan as AssistantExecutionPlanItem[], + executionPlan: runtime.executionPlan, liveTemporalHint: runtime.liveTemporalHint, executeRouteRuntime: input.executeRouteRuntime, mapNoRouteReason: input.mapNoRouteReason, @@ -120,11 +227,11 @@ export function buildAssistantDeepTurnGuardRuntimeInput( ): AssistantDeepTurnRetrievalGuardPipelineInput { return { retrievalResults: runtime.retrievalResults, - domainPolarityGuardInitial: runtime.domainPolarityGuardInitial as any, - claimAnchorAudit: runtime.claimAnchorAudit as any, - temporalGuard: runtime.temporalGuard as any, - focusDomainForGuards: runtime.focusDomainForGuards as any, - companyAnchors: runtime.companyAnchors as any, + domainPolarityGuardInitial: runtime.domainPolarityGuardInitial, + claimAnchorAudit: runtime.claimAnchorAudit, + temporalGuard: runtime.temporalGuard, + focusDomainForGuards: normalizeFocusDomainForGuards(runtime.focusDomainForGuards), + companyAnchors: toCompanyAnchorSet(runtime.companyAnchors), userMessage: runtime.userMessage }; } @@ -141,18 +248,19 @@ export function buildAssistantDeepTurnGroundingRuntimeInput( routeSummary: runtime.routeSummary, normalizedPayload: input.normalizedPayload, userMessage: input.userMessage, - requirementExtraction: runtime.requirementExtraction as AssistantRequirementExtractionLike, - extractRequirements: input.extractRequirements as any, - evaluateCoverage: input.evaluateCoverage as any, - checkGrounding: input.checkGrounding as any, + requirementExtraction: runtime.requirementExtraction, + extractRequirements: (routeSummary, normalized, userMessage) => + input.extractRequirements(routeSummary, normalized ?? null, userMessage), + evaluateCoverage: input.evaluateCoverage, + checkGrounding: input.checkGrounding, temporalGuard: runtime.temporalGuard, polarityAudit: runtime.polarityAudit, evidenceAudit: runtime.evidenceAudit, claimAnchorAudit: runtime.claimAnchorAudit, targetedEvidenceHitRate: runtime.targetedEvidenceHitRate, businessScopeResolved: runtime.businessScopeResolved, - collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit as any, - collectFaLiveRouteAudit: input.collectFaLiveRouteAudit as any + collectRbpLiveRouteAudit: input.collectRbpLiveRouteAudit, + collectFaLiveRouteAudit: input.collectFaLiveRouteAudit }; } @@ -183,25 +291,37 @@ export function buildAssistantDeepTurnAnalysisRuntimeInput( ): RunAssistantDeepTurnAnalysisRuntimeInput { return { userMessage: input.userMessage, - runContextRuntime: () => - input.runDeepTurnContextRuntimeSafe(buildAssistantDeepTurnContextRuntimeInput(input)) as any, - runExecutionPlanRuntime: (runtime) => - input.runDeepTurnPlanRuntimeSafe( + runContextRuntime: () => { + const runtime = input.runDeepTurnContextRuntimeSafe(buildAssistantDeepTurnContextRuntimeInput(input)); + return { + companyAnchors: toCompanyAnchorSet(runtime.companyAnchors), + focusDomainForGuards: normalizeFocusDomainForGuards(runtime.focusDomainForGuards), + temporalGuard: runtime.temporalGuard, + domainPolarityGuardInitial: runtime.domainPolarityGuardInitial, + claimAnchorAudit: runtime.claimAnchorAudit, + businessScopeResolution: runtime.businessScopeResolution, + resolvedRouteSummary: runtime.resolvedRouteSummary, + liveTemporalHint: runtime.liveTemporalHint + }; + }, + runExecutionPlanRuntime: (runtime) => { + const output = input.runDeepTurnPlanRuntimeSafe( buildAssistantDeepTurnExecutionPlanRuntimeInput(input, runtime) - ) as any, + ); + return { + requirementExtraction: output.requirementExtraction, + executionPlan: output.executionPlan, + rbpRoutePlanEnforcement: output.rbpRoutePlanEnforcement, + faRoutePlanEnforcement: output.faRoutePlanEnforcement + }; + }, runRetrievalRuntime: (runtime) => - input.runDeepTurnRetrievalRuntimeSafe( - buildAssistantDeepTurnRetrievalRuntimeInput(input, runtime) - ) as any, + input.runDeepTurnRetrievalRuntimeSafe(buildAssistantDeepTurnRetrievalRuntimeInput(input, runtime)), runGuardRuntime: (runtime) => - input.runDeepTurnGuardRuntimeSafe(buildAssistantDeepTurnGuardRuntimeInput(runtime) as any), + input.runDeepTurnGuardRuntimeSafe(buildAssistantDeepTurnGuardRuntimeInput(runtime)), runGroundingRuntime: (runtime) => - input.runDeepTurnGroundingRuntimeSafe( - buildAssistantDeepTurnGroundingRuntimeInput(input, runtime) - ) as any, + input.runDeepTurnGroundingRuntimeSafe(buildAssistantDeepTurnGroundingRuntimeInput(input, runtime)), runCompositionRuntime: (runtime) => - input.runDeepTurnCompositionRuntimeSafe( - buildAssistantDeepTurnCompositionRuntimeInput(input, runtime) - ) as any + input.runDeepTurnCompositionRuntimeSafe(buildAssistantDeepTurnCompositionRuntimeInput(input, runtime)) }; } diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisRuntimeAdapter.ts index c907df8..e9ee695 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAnalysisRuntimeAdapter.ts @@ -1,26 +1,32 @@ import type { AnswerGroundingCheck, AssistantRequirement, RequirementCoverageReport, UnifiedRetrievalResult } from "../types/assistant"; import type { RouteHintSummary } from "../types/normalizer"; +import type { ClaimBoundAnchorAudit } from "./assistantClaimBoundEvidence"; +import type { + AssistantDeepTurnRetrievalGuardPipelineInput, + AssistantDeepTurnRetrievalGuardPipelineOutput +} from "./assistantDeepTurnGuardRuntimeAdapter"; import type { AssistantPlanEnforcementAuditLike, AssistantRequirementExtractionLike } from "./assistantDeepTurnPlanRuntimeAdapter"; +import type { AssistantExecutionPlanItem } from "./assistantQueryPlanning"; import type { AssistantDeepTurnRetrievalExecutionOutput, AssistantLiveTemporalHint } from "./assistantDeepTurnRetrievalRuntimeAdapter"; -import type { AssistantDeepTurnRetrievalGuardPipelineOutput } from "./assistantDeepTurnGuardRuntimeAdapter"; -import type { AssistantDeepTurnGroundingRuntimeOutput } from "./assistantDeepTurnGroundingRuntimeAdapter"; +import type { + AssistantDeepTurnGroundingRuntimeInput, + AssistantDeepTurnGroundingRuntimeOutput +} from "./assistantDeepTurnGroundingRuntimeAdapter"; import type { AssistantDeepTurnCompositionOutput } from "./assistantDeepTurnCompositionRuntimeAdapter"; +import type { DomainPolarityGuardAudit, TemporalGuardAudit } from "./assistantRuntimeGuards"; export interface AssistantDeepTurnRuntimeContextLike { - companyAnchors: unknown; - focusDomainForGuards: string | null; - temporalGuard: unknown; - domainPolarityGuardInitial: unknown; - claimAnchorAudit: { - claim_type: string; - [key: string]: unknown; - }; + companyAnchors: AssistantDeepTurnRetrievalGuardPipelineInput["companyAnchors"]; + focusDomainForGuards: AssistantDeepTurnRetrievalGuardPipelineInput["focusDomainForGuards"]; + temporalGuard: TemporalGuardAudit; + domainPolarityGuardInitial: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; businessScopeResolution: { business_scope_resolved?: string[] | null; [key: string]: unknown; @@ -35,25 +41,25 @@ export interface RunAssistantDeepTurnAnalysisRuntimeInput { runExecutionPlanRuntime: (input: { resolvedRouteSummary: RouteHintSummary | null; claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"]; - temporalGuard: unknown; - domainPolarityGuardInitial: unknown; + temporalGuard: TemporalGuardAudit; + domainPolarityGuardInitial: DomainPolarityGuardAudit; }) => { requirementExtraction: AssistantRequirementExtractionLike; - executionPlan: unknown[]; + executionPlan: AssistantExecutionPlanItem[]; rbpRoutePlanEnforcement: AssistantPlanEnforcementAuditLike; faRoutePlanEnforcement: AssistantPlanEnforcementAuditLike; }; runRetrievalRuntime: (input: { - executionPlan: unknown[]; + executionPlan: AssistantExecutionPlanItem[]; liveTemporalHint: AssistantLiveTemporalHint | null; }) => Promise; runGuardRuntime: (input: { retrievalResults: UnifiedRetrievalResult[]; - domainPolarityGuardInitial: unknown; + domainPolarityGuardInitial: DomainPolarityGuardAudit; claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"]; - temporalGuard: unknown; - focusDomainForGuards: string | null; - companyAnchors: unknown; + temporalGuard: TemporalGuardAudit; + focusDomainForGuards: AssistantDeepTurnRetrievalGuardPipelineInput["focusDomainForGuards"]; + companyAnchors: AssistantDeepTurnRetrievalGuardPipelineInput["companyAnchors"]; userMessage: string; }) => AssistantDeepTurnRetrievalGuardPipelineOutput; runGroundingRuntime: (input: { @@ -63,10 +69,10 @@ export interface RunAssistantDeepTurnAnalysisRuntimeInput { faPlanAudit: unknown; routeSummary: RouteHintSummary | null; requirementExtraction: AssistantRequirementExtractionLike; - temporalGuard: unknown; - polarityAudit: unknown; - evidenceAudit: unknown; - claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"]; + temporalGuard: AssistantDeepTurnGroundingRuntimeInput["temporalGuard"]; + polarityAudit: AssistantDeepTurnGroundingRuntimeInput["polarityAudit"]; + evidenceAudit: AssistantDeepTurnGroundingRuntimeInput["evidenceAudit"]; + claimAnchorAudit: AssistantDeepTurnGroundingRuntimeInput["claimAnchorAudit"]; targetedEvidenceHitRate?: number | null; businessScopeResolved?: string[] | null; }) => AssistantDeepTurnGroundingRuntimeOutput; @@ -87,7 +93,7 @@ export interface RunAssistantDeepTurnAnalysisRuntimeOutput { businessScopeResolution: AssistantDeepTurnRuntimeContextLike["businessScopeResolution"]; resolvedRouteSummary: RouteHintSummary | null; requirementExtraction: AssistantRequirementExtractionLike; - executionPlan: unknown[]; + executionPlan: AssistantExecutionPlanItem[]; retrievalCalls: AssistantDeepTurnRetrievalExecutionOutput["retrievalCalls"]; retrievalResultsRaw: AssistantDeepTurnRetrievalExecutionOutput["retrievalResultsRaw"]; retrievalResults: UnifiedRetrievalResult[]; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptRuntimeAdapter.ts index c391f43..e6dc3ac 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnAttemptRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnAttemptRuntimeAdapter.ts @@ -1,4 +1,4 @@ -import type { AssistantMessageResponsePayload } from "../types/assistant"; +import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../types/assistant"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import { buildAssistantDeepTurnNormalizationRuntime, @@ -74,13 +74,13 @@ export interface RunAssistantDeepTurnAttemptRuntimeInput ) => { response: ResponseType; - debug: Record; + debug: AssistantDebugPayload; }; } export interface RunAssistantDeepTurnAttemptRuntimeOutput { response: ResponseType; - debug: Record; + debug: AssistantDebugPayload; normalizationRuntime: BuildAssistantDeepTurnNormalizationRuntimeOutput; deepTurnAnalysisRuntime: RunAssistantDeepTurnAnalysisRuntimeOutput; } @@ -92,8 +92,12 @@ export async function runAssistantDeepTurnAttemptRuntime + ) => { + response: ResponseType; + debug: AssistantDebugPayload; + } = input.runDeepTurnResponseAttemptRuntime ?? runAssistantDeepTurnResponseAttemptRuntime; const normalizationRuntime = await runDeepTurnNormalizationRuntimeSafe( buildAssistantDeepTurnNormalizationRuntimeInput({ diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts index 016872d..1e1ac93 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnCompositionRuntimeAdapter.ts @@ -4,6 +4,7 @@ import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemU import type { QuestionTypeClass } from "./questionTypeResolver"; import { resolveQuestionType } from "./questionTypeResolver"; import { composeAssistantAnswer } from "./answerComposer"; +import type { CompanyAnchorSet } from "./companyAnchorResolver"; export interface BuildAssistantDeepTurnCompositionInput { userMessage: string; @@ -32,6 +33,32 @@ export interface AssistantDeepTurnCompositionOutput { composition: ReturnType; } +function toStringArray(value: unknown): string[] { + if (!Array.isArray(value)) { + return []; + } + return value + .map((item) => (typeof item === "string" ? item.trim() : "")) + .filter((item) => item.length > 0); +} + +function normalizeCompanyAnchorSet(value: unknown): CompanyAnchorSet | null { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return null; + } + const source = value as Record; + return { + contract_numbers: toStringArray(source.contract_numbers), + document_numbers: toStringArray(source.document_numbers), + dates: toStringArray(source.dates), + amounts: toStringArray(source.amounts), + accounts: toStringArray(source.accounts), + periods: toStringArray(source.periods), + document_types: toStringArray(source.document_types), + all: toStringArray(source.all) + }; +} + export function buildAssistantDeepTurnComposition( input: BuildAssistantDeepTurnCompositionInput ): AssistantDeepTurnCompositionOutput { @@ -43,10 +70,7 @@ export function buildAssistantDeepTurnComposition( ? input.investigationState?.followup_context?.active_domain ?? input.investigationState?.focus.domain ?? null : null; const questionTypeClass = resolveQuestionTypeSafe(input.userMessage); - const companyAnchorSet = input.companyAnchors as { - dates?: unknown[]; - periods?: unknown[]; - } | null; + const companyAnchorSet = normalizeCompanyAnchorSet(input.companyAnchors); const hasPeriodInCompanyAnchors = (Array.isArray(companyAnchorSet?.dates) && companyAnchorSet.dates.some((item) => String(item ?? "").trim().length > 0)) || (Array.isArray(companyAnchorSet?.periods) && companyAnchorSet.periods.some((item) => String(item ?? "").trim().length > 0)); @@ -60,7 +84,7 @@ export function buildAssistantDeepTurnComposition( groundingCheck: input.groundingCheck, focusDomainHint, questionTypeHint: questionTypeClass, - companyAnchors: input.companyAnchors as any, + companyAnchors: companyAnchorSet, normalizationPeriodExplicit, enableAnswerPolicyV11: input.featureAnswerPolicyV11, enableProblemCentricAnswerV1: input.featureProblemCentricAnswerV1, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts index 9a67c8f..b33f329 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnContextRuntimeAdapter.ts @@ -1,4 +1,7 @@ import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; +import type { ClaimBoundAnchorAudit } from "./assistantClaimBoundEvidence"; +import type { AssistantLiveTemporalHint } from "./assistantDeepTurnRetrievalRuntimeAdapter"; +import type { DomainPolarityGuardAudit, TemporalGuardAudit } from "./assistantRuntimeGuards"; const KNOWN_P0_DOMAINS = new Set([ "settlements_60_62", @@ -9,7 +12,7 @@ const KNOWN_P0_DOMAINS = new Set([ function toAnalysisContext( runtimeAnalysisContext: BuildAssistantDeepTurnRuntimeContextInput["runtimeAnalysisContext"] -): Record | null { +): AssistantLiveTemporalHint | null { if (!runtimeAnalysisContext.active) { return null; } @@ -48,26 +51,19 @@ export interface BuildAssistantDeepTurnRuntimeContextInput { userMessage: string; normalized: NormalizeResponsePayload["normalized"]; companyAnchors: unknown; - analysisContext: Record | null; - }) => { - effective_primary_period?: unknown; - primary_period_window?: unknown; - [key: string]: unknown; - }; + analysisContext: AssistantLiveTemporalHint | null; + }) => TemporalGuardAudit; resolveDomainPolarityGuard: (input: { userMessage: string; companyAnchors: unknown; focusDomainHint: string | null; - }) => unknown; + }) => DomainPolarityGuardAudit; resolveClaimBoundAnchors: (input: { userMessage: string; companyAnchors: unknown; focusDomainHint: string | null; primaryPeriod: unknown; - }) => { - claim_type: string; - [key: string]: unknown; - }; + }) => ClaimBoundAnchorAudit; resolveBusinessScopeFromLiveContext: (input: { current: { route_summary_resolved: RouteHintSummary | null; @@ -93,22 +89,15 @@ export interface BuildAssistantDeepTurnRuntimeContextOutput { }; inferredDomainByMessage: string | null; focusDomainForGuards: string | null; - temporalGuard: { - effective_primary_period?: unknown; - primary_period_window?: unknown; - [key: string]: unknown; - }; - domainPolarityGuardInitial: unknown; - claimAnchorAudit: { - claim_type: string; - [key: string]: unknown; - }; + temporalGuard: TemporalGuardAudit; + domainPolarityGuardInitial: DomainPolarityGuardAudit; + claimAnchorAudit: ClaimBoundAnchorAudit; businessScopeResolution: { route_summary_resolved: RouteHintSummary | null; [key: string]: unknown; }; resolvedRouteSummary: RouteHintSummary | null; - liveTemporalHint: Record | null; + liveTemporalHint: AssistantLiveTemporalHint | null; } export function buildAssistantDeepTurnRuntimeContext( diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnGroundingRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnGroundingRuntimeAdapter.ts index cdd8f2e..f5fc50b 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnGroundingRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnGroundingRuntimeAdapter.ts @@ -8,7 +8,10 @@ import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normal import type { AssistantRequirementExtractionResult, AssistantCoverageEvaluationResult } from "./assistantOrchestrationRuntimeAdapter"; import { runAssistantCoverageGroundingPipeline } from "./assistantOrchestrationRuntimeAdapter"; import type { AssistantDeepTurnGroundingEligibilityOutput } from "./assistantDeepTurnGuardRuntimeAdapter"; -import { applyAssistantDeepTurnGroundingEligibility } from "./assistantDeepTurnGuardRuntimeAdapter"; +import { + applyAssistantDeepTurnGroundingEligibility, + type AssistantDeepTurnGroundingEligibilityInput +} from "./assistantDeepTurnGuardRuntimeAdapter"; export interface AssistantDeepTurnGroundingRuntimeInput { claimType: string; @@ -34,10 +37,10 @@ export interface AssistantDeepTurnGroundingRuntimeInput { coverage: RequirementCoverageReport, retrievalResults: UnifiedRetrievalResult[] ) => AnswerGroundingCheck; - temporalGuard: unknown; - polarityAudit: unknown; - evidenceAudit: unknown; - claimAnchorAudit: unknown; + temporalGuard: AssistantDeepTurnGroundingEligibilityInput["temporalGuard"]; + polarityAudit: AssistantDeepTurnGroundingEligibilityInput["polarityAudit"]; + evidenceAudit: AssistantDeepTurnGroundingEligibilityInput["evidenceAudit"]; + claimAnchorAudit: AssistantDeepTurnGroundingEligibilityInput["claimAnchorAudit"]; targetedEvidenceHitRate?: number | null; businessScopeResolved?: string[] | null; collectRbpLiveRouteAudit: (input: { @@ -51,15 +54,9 @@ export interface AssistantDeepTurnGroundingRuntimeInput { planAudit: unknown; }) => unknown; runCoverageGroundingPipelineFn?: typeof runAssistantCoverageGroundingPipeline; - applyGroundingEligibilityFn?: (input: { - groundingCheckBase: AnswerGroundingCheck; - temporalGuard: unknown; - polarityAudit: unknown; - evidenceAudit: unknown; - claimAnchorAudit?: unknown; - targetedEvidenceHitRate?: number | null; - businessScopeResolved?: string[] | null; - }) => AssistantDeepTurnGroundingEligibilityOutput; + applyGroundingEligibilityFn?: ( + input: AssistantDeepTurnGroundingEligibilityInput + ) => AssistantDeepTurnGroundingEligibilityOutput; } export interface AssistantDeepTurnGroundingRuntimeOutput { @@ -75,9 +72,11 @@ export function runAssistantDeepTurnGroundingRuntime( input: AssistantDeepTurnGroundingRuntimeInput ): AssistantDeepTurnGroundingRuntimeOutput { const runCoverageGroundingPipelineSafe = input.runCoverageGroundingPipelineFn ?? runAssistantCoverageGroundingPipeline; + const applyGroundingEligibilityDefault: NonNullable< + AssistantDeepTurnGroundingRuntimeInput["applyGroundingEligibilityFn"] + > = (payload) => applyAssistantDeepTurnGroundingEligibility(payload); const applyGroundingEligibilitySafe = - input.applyGroundingEligibilityFn ?? - ((payload) => applyAssistantDeepTurnGroundingEligibility(payload as any) as any); + input.applyGroundingEligibilityFn ?? applyGroundingEligibilityDefault; const rbpLiveRouteAudit = input.collectRbpLiveRouteAudit({ claimType: input.claimType, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts index 536c413..c55ee41 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackaging.ts @@ -1,5 +1,6 @@ import type { AssistantConversationItem, + AssistantDebugPayload, AssistantReplyType, AssistantRequirement, AnswerGroundingCheck, @@ -112,7 +113,7 @@ export interface AssistantDeepTurnPackagingOutput { evidenceBundleAssembly: AssistantEvidenceBundleAssembly; contractsBundleV1: AssistantContractsBundleV1; deepAnswerArtifacts: DeepAnswerArtifacts; - debug: Record; + debug: AssistantDebugPayload; assistantItem: AssistantConversationItem; deepAnalysisLogDetails: Record; } @@ -194,7 +195,7 @@ export function assembleAssistantDeepTurnPackaging(input: AssistantDeepTurnPacka text: deepAnswerArtifacts.safeAssistantReply, replyType: input.composition.reply_type, traceId: input.normalized.trace_id, - debug: debug as any + debug }); const deepAnalysisLogDetails = buildDeepAnalysisProcessedLogDetails({ sessionId: input.sessionId, diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts index e7460b9..a7ff3c8 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnPackagingRuntimeAdapter.ts @@ -1,6 +1,7 @@ import { nanoid } from "nanoid"; import type { AssistantConversationItem, + AssistantDebugPayload, AssistantRequirement, AnswerGroundingCheck, RequirementCoverageReport, @@ -101,7 +102,7 @@ export interface AssistantDeepTurnPackagingRuntimeOutput { resolvedExecutionState: unknown; safeAssistantReplyBase: string; safeAssistantReply: string; - debug: Record; + debug: AssistantDebugPayload; assistantItem: AssistantConversationItem; deepAnalysisLogDetails: Record; } diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts index 2b4a8ef..e4a9931 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnResponseAttemptRuntimeAdapter.ts @@ -1,4 +1,4 @@ -import type { AssistantMessageResponsePayload } from "../types/assistant"; +import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../types/assistant"; import type { NormalizeResponsePayload } from "../types/normalizer"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import type { RunAssistantDeepTurnAnalysisRuntimeOutput } from "./assistantDeepTurnAnalysisRuntimeAdapter"; @@ -55,7 +55,7 @@ export function runAssistantDeepTurnResponseAttemptRuntime< input: RunAssistantDeepTurnResponseAttemptRuntimeInput ): { response: ResponseType; - debug: Record; + debug: AssistantDebugPayload; } { const runDeepTurnResponseRuntimeSafe = input.runDeepTurnResponseRuntime ?? runAssistantDeepTurnResponseRuntime; diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts index 94eae35..ee793b7 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnResponseRuntimeAdapter.ts @@ -1,4 +1,4 @@ -import type { AssistantMessageResponsePayload } from "../types/assistant"; +import type { AssistantDebugPayload, AssistantMessageResponsePayload } from "../types/assistant"; import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer"; import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits"; import { @@ -70,7 +70,7 @@ export interface RunAssistantDeepTurnResponseRuntimeInput { export interface RunAssistantDeepTurnResponseRuntimeOutput { response: AssistantMessageResponsePayload; - debug: Record; + debug: AssistantDebugPayload; } function toRecordObject(value: unknown): Record | null { diff --git a/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts b/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts index 834422a..acaac03 100644 --- a/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts +++ b/llm_normalizer/backend/src/services/assistantDeepTurnRetrievalRuntimeAdapter.ts @@ -105,7 +105,7 @@ export async function executeAssistantDeepTurnRetrievalPlan( raw_result: raw }); retrievalResults.push( - normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, raw as any) + normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, raw) ); } catch (error) { const message = error instanceof Error ? error.message : String(error); @@ -118,7 +118,7 @@ export async function executeAssistantDeepTurnRetrievalPlan( raw_result: rawError }); retrievalResults.push( - normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, rawError as any) + normalizeRetrievalResultSafe(planItem.fragment_id, planItem.requirement_ids, planItem.route, rawError) ); } } diff --git a/llm_normalizer/backend/src/services/retrievalResultNormalizer.ts b/llm_normalizer/backend/src/services/retrievalResultNormalizer.ts index 437e2be..5a9bedd 100644 --- a/llm_normalizer/backend/src/services/retrievalResultNormalizer.ts +++ b/llm_normalizer/backend/src/services/retrievalResultNormalizer.ts @@ -509,28 +509,29 @@ export function normalizeRetrievalResult( fragmentId: string, requirementIds: string[], route: string, - raw: RawRetrievalResult + raw: unknown ): UnifiedRetrievalResult { - const items = normalizeObjectArray(raw.items); - const summary = normalizeSummary(raw.summary); - const evidence = normalizeEvidenceItems(fragmentId, requirementIds, route, raw.evidence); + const rawResult = (toObject(raw) as RawRetrievalResult | null) ?? {}; + const items = normalizeObjectArray(rawResult.items); + const summary = normalizeSummary(rawResult.summary); + const evidence = normalizeEvidenceItems(fragmentId, requirementIds, route, rawResult.evidence); const baseResult: UnifiedRetrievalResult = { fragment_id: fragmentId, requirement_ids: requirementIds, route, - status: normalizeStatus(raw.status), - result_type: normalizeResultType(raw.result_type), + status: normalizeStatus(rawResult.status), + result_type: normalizeResultType(rawResult.result_type), items, summary, evidence, - why_included: normalizeStringArray(raw.why_included), - selection_reason: normalizeStringArray(raw.selection_reason), - risk_factors: normalizeStringArray(raw.risk_factors), - business_interpretation: normalizeStringArray(raw.business_interpretation), - confidence: normalizeConfidence(raw.confidence), - limitations: normalizeStringArray(raw.limitations), - errors: normalizeErrors(raw.errors) + why_included: normalizeStringArray(rawResult.why_included), + selection_reason: normalizeStringArray(rawResult.selection_reason), + risk_factors: normalizeStringArray(rawResult.risk_factors), + business_interpretation: normalizeStringArray(rawResult.business_interpretation), + confidence: normalizeConfidence(rawResult.confidence), + limitations: normalizeStringArray(rawResult.limitations), + errors: normalizeErrors(rawResult.errors) }; if (!FEATURE_ASSISTANT_PROBLEM_UNITS_V1) {