ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.30: вынос ветки tool_gate_skip + chat fallback из assistantService в отдельный runtime-адаптер, чтобы в сервисе остался только orchestration flow.
This commit is contained in:
parent
3531f7ddfe
commit
353cbc1763
|
|
@ -996,7 +996,109 @@ Validation:
|
||||||
- `assistantLivingRouter.test.ts`
|
- `assistantLivingRouter.test.ts`
|
||||||
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
|
|
||||||
Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 completed)**
|
Implemented in current pass (Phase 2.30):
|
||||||
|
1. Extracted address tool-gate skip branch from `assistantService` into dedicated runtime adapter:
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.ts`
|
||||||
|
- introduced:
|
||||||
|
- `runAssistantAddressToolGateRuntime(...)`
|
||||||
|
2. Centralized tool-gate skip/runtime sequence (behavior-preserving):
|
||||||
|
- deterministic early noop when `runAddressLane=true`;
|
||||||
|
- structured `assistant_address_tool_gate_skip` logging payload projection;
|
||||||
|
- conditional living-chat fallback invocation when mode is `chat`.
|
||||||
|
3. Rewired `assistantService` to consume tool-gate runtime adapter output and preserve existing early-return contract for handled chat fallback.
|
||||||
|
4. Added focused unit tests:
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.test.ts`
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
1. `npm run build` passed.
|
||||||
|
2. Targeted living/address followup pack passed:
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressOrchestrationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressFollowupContext.test.ts`
|
||||||
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
- `assistantLivingRouter.test.ts`
|
||||||
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
|
|
||||||
|
Implemented in current pass (Phase 2.31):
|
||||||
|
1. Extracted deep-lane followup binding + normalize bootstrap block from `assistantService` into dedicated runtime adapter:
|
||||||
|
- `assistantDeepTurnNormalizationRuntimeAdapter.ts`
|
||||||
|
- introduced:
|
||||||
|
- `buildAssistantDeepTurnNormalizationRuntime(...)`
|
||||||
|
2. Centralized deep normalization bootstrap sequence (behavior-preserving):
|
||||||
|
- followup state binding projection when feature flags are enabled;
|
||||||
|
- deterministic fallback to raw user question when followup binding is disabled/unavailable;
|
||||||
|
- normalize request payload assembly and normalizer invocation.
|
||||||
|
3. Rewired `assistantService` deep-lane bootstrap to consume normalization runtime adapter output.
|
||||||
|
4. Added focused unit tests:
|
||||||
|
- `assistantDeepTurnNormalizationRuntimeAdapter.test.ts`
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
1. `npm run build` passed.
|
||||||
|
2. Targeted living/address/deep followup pack passed:
|
||||||
|
- `assistantDeepTurnNormalizationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressOrchestrationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressFollowupContext.test.ts`
|
||||||
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
- `assistantLivingRouter.test.ts`
|
||||||
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
|
|
||||||
|
Implemented in current pass (Phase 2.32):
|
||||||
|
1. Extracted deep-lane context/plan/retrieval/guard/grounding/composition orchestration block from `assistantService` into dedicated runtime adapter:
|
||||||
|
- `assistantDeepTurnAnalysisRuntimeAdapter.ts`
|
||||||
|
- introduced:
|
||||||
|
- `runAssistantDeepTurnAnalysisRuntime(...)`
|
||||||
|
2. Centralized deep analysis sequence wiring (behavior-preserving):
|
||||||
|
- runtime context stage output propagation;
|
||||||
|
- execution-plan, retrieval, guard and grounding stage chaining;
|
||||||
|
- composition stage input projection from grounded retrieval output.
|
||||||
|
3. Rewired `assistantService` deep-lane middle pipeline to consume analysis runtime adapter output while preserving existing packaging/finalization contracts.
|
||||||
|
4. Added focused unit tests:
|
||||||
|
- `assistantDeepTurnAnalysisRuntimeAdapter.test.ts`
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
1. `npm run build` passed.
|
||||||
|
2. Targeted living/address/deep followup pack passed:
|
||||||
|
- `assistantDeepTurnAnalysisRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnNormalizationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressOrchestrationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressFollowupContext.test.ts`
|
||||||
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
- `assistantLivingRouter.test.ts`
|
||||||
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
|
|
||||||
|
Implemented in current pass (Phase 2.33):
|
||||||
|
1. Extracted deep-lane response tail (packaging + finalize) from `assistantService` into dedicated runtime adapter:
|
||||||
|
- `assistantDeepTurnResponseRuntimeAdapter.ts`
|
||||||
|
- introduced:
|
||||||
|
- `runAssistantDeepTurnResponseRuntime(...)`
|
||||||
|
2. Centralized deep response-tail sequence (behavior-preserving):
|
||||||
|
- packaging runtime invocation with full debug/contract payload projection;
|
||||||
|
- deep finalization invocation with packaged reply/debug artifacts;
|
||||||
|
- single response projection back to caller.
|
||||||
|
3. Rewired `assistantService` deep-lane tail to consume response runtime adapter output.
|
||||||
|
4. Added focused unit tests:
|
||||||
|
- `assistantDeepTurnResponseRuntimeAdapter.test.ts`
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
1. `npm run build` passed.
|
||||||
|
2. Targeted living/address/deep followup pack passed:
|
||||||
|
- `assistantDeepTurnResponseRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnAnalysisRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnNormalizationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressToolGateRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressOrchestrationRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressFollowupContext.test.ts`
|
||||||
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
- `assistantLivingRouter.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 completed)**
|
||||||
|
|
||||||
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)
|
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)
|
||||||
|
|
||||||
|
|
|
||||||
56
llm_normalizer/backend/dist/services/assistantAddressToolGateRuntimeAdapter.js
vendored
Normal file
56
llm_normalizer/backend/dist/services/assistantAddressToolGateRuntimeAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.runAssistantAddressToolGateRuntime = runAssistantAddressToolGateRuntime;
|
||||||
|
async function runAssistantAddressToolGateRuntime(input) {
|
||||||
|
if (Boolean(input.orchestrationDecision?.runAddressLane)) {
|
||||||
|
return {
|
||||||
|
handled: false,
|
||||||
|
response: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const runtimeMeta = input.addressRuntimeMeta && typeof input.addressRuntimeMeta === "object"
|
||||||
|
? input.addressRuntimeMeta
|
||||||
|
: {};
|
||||||
|
const predecomposeContract = runtimeMeta.predecomposeContract && typeof runtimeMeta.predecomposeContract === "object"
|
||||||
|
? runtimeMeta.predecomposeContract
|
||||||
|
: null;
|
||||||
|
const predecomposePeriod = predecomposeContract?.period && typeof predecomposeContract.period === "object"
|
||||||
|
? predecomposeContract.period
|
||||||
|
: null;
|
||||||
|
input.logEvent({
|
||||||
|
timestamp: input.nowIso(),
|
||||||
|
level: "info",
|
||||||
|
service: "assistant_loop",
|
||||||
|
message: "assistant_address_tool_gate_skip",
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
details: {
|
||||||
|
session_id: input.sessionId,
|
||||||
|
user_message: input.userMessage,
|
||||||
|
effective_address_user_message: input.addressInputMessage,
|
||||||
|
address_llm_predecompose_attempted: Boolean(runtimeMeta.attempted),
|
||||||
|
address_llm_predecompose_applied: Boolean(runtimeMeta.applied),
|
||||||
|
address_llm_predecompose_reason: runtimeMeta.reason ?? null,
|
||||||
|
address_fallback_rule_hit: runtimeMeta.fallbackRuleHit ?? null,
|
||||||
|
address_sanitized_user_message: runtimeMeta.sanitizedUserMessage ?? null,
|
||||||
|
assistant_orchestration_contract_v1: runtimeMeta.orchestrationContract ?? null,
|
||||||
|
address_tool_gate_decision: runtimeMeta.toolGateDecision ?? null,
|
||||||
|
address_tool_gate_reason: runtimeMeta.toolGateReason ?? null,
|
||||||
|
address_llm_predecompose_contract_intent: predecomposeContract?.intent ?? null,
|
||||||
|
address_llm_predecompose_contract_aggregation_profile: predecomposeContract?.aggregation_profile ?? null,
|
||||||
|
address_llm_predecompose_contract_period_scope: predecomposePeriod?.scope ?? null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (input.livingModeDecision?.mode === "chat") {
|
||||||
|
const chatHandled = await input.tryHandleLivingChat(input.livingModeDecision, runtimeMeta);
|
||||||
|
if (chatHandled) {
|
||||||
|
return {
|
||||||
|
handled: true,
|
||||||
|
response: chatHandled
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
handled: false,
|
||||||
|
response: null
|
||||||
|
};
|
||||||
|
}
|
||||||
69
llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisRuntimeAdapter.js
vendored
Normal file
69
llm_normalizer/backend/dist/services/assistantDeepTurnAnalysisRuntimeAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.runAssistantDeepTurnAnalysisRuntime = runAssistantDeepTurnAnalysisRuntime;
|
||||||
|
async function runAssistantDeepTurnAnalysisRuntime(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,
|
||||||
|
domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial,
|
||||||
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
||||||
|
temporalGuard: contextRuntime.temporalGuard,
|
||||||
|
focusDomainForGuards: contextRuntime.focusDomainForGuards,
|
||||||
|
companyAnchors: contextRuntime.companyAnchors,
|
||||||
|
userMessage: input.userMessage
|
||||||
|
});
|
||||||
|
const groundingRuntime = input.runGroundingRuntime({
|
||||||
|
claimType: contextRuntime.claimAnchorAudit.claim_type,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
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 ?? null
|
||||||
|
});
|
||||||
|
const compositionRuntime = input.runCompositionRuntime({
|
||||||
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
requirements: groundingRuntime.coverageEvaluation.requirements,
|
||||||
|
coverageReport: groundingRuntime.coverageEvaluation.coverage,
|
||||||
|
groundingCheck: groundingRuntime.groundingCheck,
|
||||||
|
companyAnchors: contextRuntime.companyAnchors
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
companyAnchors: contextRuntime.companyAnchors,
|
||||||
|
temporalGuard: contextRuntime.temporalGuard,
|
||||||
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
||||||
|
businessScopeResolution: contextRuntime.businessScopeResolution,
|
||||||
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
||||||
|
requirementExtraction: executionPlanRuntime.requirementExtraction,
|
||||||
|
executionPlan: executionPlanRuntime.executionPlan,
|
||||||
|
retrievalCalls: retrievalRuntime.retrievalCalls,
|
||||||
|
retrievalResultsRaw: retrievalRuntime.retrievalResultsRaw,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
polarityGuardResult: guardRuntime.polarityGuardResult,
|
||||||
|
targetedEvidenceResult: guardRuntime.targetedEvidenceResult,
|
||||||
|
evidenceGateResult: guardRuntime.evidenceGateResult,
|
||||||
|
rbpLiveRouteAudit: groundingRuntime.rbpLiveRouteAudit,
|
||||||
|
faLiveRouteAudit: groundingRuntime.faLiveRouteAudit,
|
||||||
|
coverageEvaluation: groundingRuntime.coverageEvaluation,
|
||||||
|
groundedAnswerEligibilityGuard: groundingRuntime.groundedAnswerEligibilityGuard,
|
||||||
|
groundingCheck: groundingRuntime.groundingCheck,
|
||||||
|
questionTypeClass: compositionRuntime.questionTypeClass,
|
||||||
|
composition: compositionRuntime.composition
|
||||||
|
};
|
||||||
|
}
|
||||||
40
llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js
vendored
Normal file
40
llm_normalizer/backend/dist/services/assistantDeepTurnNormalizationRuntimeAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.buildAssistantDeepTurnNormalizationRuntime = buildAssistantDeepTurnNormalizationRuntime;
|
||||||
|
async function buildAssistantDeepTurnNormalizationRuntime(input) {
|
||||||
|
const followupBinding = input.featureInvestigationStateV1 &&
|
||||||
|
input.featureStateFollowupBindingV1 &&
|
||||||
|
Boolean(input.sessionInvestigationState)
|
||||||
|
? input.buildFollowupStateBinding({
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
payloadContext: input.payload.context,
|
||||||
|
investigationState: input.sessionInvestigationState
|
||||||
|
})
|
||||||
|
: {
|
||||||
|
normalizedQuestion: input.userMessage,
|
||||||
|
mergedContext: input.payload.context,
|
||||||
|
usage: null
|
||||||
|
};
|
||||||
|
const normalizePayload = {
|
||||||
|
llmProvider: input.payload.llmProvider,
|
||||||
|
apiKey: input.payload.apiKey,
|
||||||
|
model: input.payload.model,
|
||||||
|
baseUrl: input.payload.baseUrl,
|
||||||
|
temperature: input.payload.temperature,
|
||||||
|
maxOutputTokens: input.payload.maxOutputTokens,
|
||||||
|
promptVersion: input.payload.promptVersion ?? "address_query_runtime_v1",
|
||||||
|
systemPrompt: input.payload.systemPrompt,
|
||||||
|
developerPrompt: input.payload.developerPrompt,
|
||||||
|
domainPrompt: input.payload.domainPrompt,
|
||||||
|
fewShotExamples: input.payload.fewShotExamples,
|
||||||
|
userQuestion: followupBinding.normalizedQuestion,
|
||||||
|
context: followupBinding.mergedContext,
|
||||||
|
useMock: Boolean(input.payload.useMock)
|
||||||
|
};
|
||||||
|
const normalized = await input.normalize(normalizePayload);
|
||||||
|
return {
|
||||||
|
followupBinding,
|
||||||
|
normalizePayload,
|
||||||
|
normalized
|
||||||
|
};
|
||||||
|
}
|
||||||
68
llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js
vendored
Normal file
68
llm_normalizer/backend/dist/services/assistantDeepTurnResponseRuntimeAdapter.js
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.runAssistantDeepTurnResponseRuntime = runAssistantDeepTurnResponseRuntime;
|
||||||
|
const assistantDeepTurnPackagingRuntimeAdapter_1 = require("./assistantDeepTurnPackagingRuntimeAdapter");
|
||||||
|
const assistantDeepTurnFinalizeRuntimeAdapter_1 = require("./assistantDeepTurnFinalizeRuntimeAdapter");
|
||||||
|
function runAssistantDeepTurnResponseRuntime(input) {
|
||||||
|
const runPackagingRuntimeSafe = input.runPackagingRuntime ?? assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime;
|
||||||
|
const runFinalizeDeepTurnSafe = input.runFinalizeDeepTurn ?? assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn;
|
||||||
|
const packagingRuntime = runPackagingRuntimeSafe({
|
||||||
|
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
questionId: input.questionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
normalized: input.normalized,
|
||||||
|
normalizedQuestion: input.normalizedQuestion,
|
||||||
|
routeSummary: input.routeSummary,
|
||||||
|
executionPlan: input.executionPlan,
|
||||||
|
requirementExtractionRequirements: input.requirementExtractionRequirements,
|
||||||
|
coverageEvaluationRequirements: input.coverageEvaluationRequirements,
|
||||||
|
coverageReport: input.coverageReport,
|
||||||
|
groundingCheck: input.groundingCheck,
|
||||||
|
retrievalCalls: input.retrievalCalls,
|
||||||
|
retrievalResultsRaw: input.retrievalResultsRaw,
|
||||||
|
retrievalResults: input.retrievalResults,
|
||||||
|
questionTypeClass: input.questionTypeClass,
|
||||||
|
companyAnchors: input.companyAnchors,
|
||||||
|
runtimeAnalysisContext: input.runtimeAnalysisContext,
|
||||||
|
businessScopeResolution: input.businessScopeResolution,
|
||||||
|
temporalGuard: input.temporalGuard,
|
||||||
|
polarityAudit: input.polarityAudit,
|
||||||
|
claimAnchorAudit: input.claimAnchorAudit,
|
||||||
|
targetedEvidenceAudit: input.targetedEvidenceAudit,
|
||||||
|
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit,
|
||||||
|
rbpLiveRouteAudit: input.rbpLiveRouteAudit,
|
||||||
|
faLiveRouteAudit: input.faLiveRouteAudit,
|
||||||
|
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard,
|
||||||
|
followupStateUsage: input.followupStateUsage,
|
||||||
|
followupApplied: input.followupApplied,
|
||||||
|
composition: input.composition,
|
||||||
|
featureContractsV11: input.featureContractsV11,
|
||||||
|
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||||
|
previousInvestigationState: input.previousInvestigationState ?? null,
|
||||||
|
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep,
|
||||||
|
extractDroppedIntentSegments: input.extractDroppedIntentSegments,
|
||||||
|
buildDebugRoutes: input.buildDebugRoutes,
|
||||||
|
extractExecutionState: input.extractExecutionState,
|
||||||
|
sanitizeReply: input.sanitizeReply,
|
||||||
|
persistInvestigationState: input.persistInvestigationState,
|
||||||
|
messageIdFactory: input.messageIdFactory
|
||||||
|
});
|
||||||
|
const finalization = runFinalizeDeepTurnSafe({
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
assistantReply: packagingRuntime.safeAssistantReply,
|
||||||
|
replyType: input.composition.reply_type,
|
||||||
|
assistantItem: packagingRuntime.assistantItem,
|
||||||
|
debug: packagingRuntime.debug,
|
||||||
|
deepAnalysisLogDetails: packagingRuntime.deepAnalysisLogDetails,
|
||||||
|
appendItem: input.appendItem,
|
||||||
|
getSession: input.getSession,
|
||||||
|
persistSession: input.persistSession,
|
||||||
|
cloneConversation: input.cloneConversation,
|
||||||
|
logEvent: input.logEvent
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
response: finalization.response,
|
||||||
|
debug: packagingRuntime.debug
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -67,6 +67,7 @@ const capabilitiesRegistry_1 = __importStar(require("./capabilitiesRegistry"));
|
||||||
const assistantCanon_1 = __importStar(require("./assistantCanon"));
|
const assistantCanon_1 = __importStar(require("./assistantCanon"));
|
||||||
const assistantAddressTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantAddressTurnFinalizeRuntimeAdapter"));
|
const assistantAddressTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantAddressTurnFinalizeRuntimeAdapter"));
|
||||||
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
|
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
|
||||||
|
const assistantDeepTurnAnalysisRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisRuntimeAdapter"));
|
||||||
const assistantDeepTurnCompositionRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnCompositionRuntimeAdapter"));
|
const assistantDeepTurnCompositionRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnCompositionRuntimeAdapter"));
|
||||||
const assistantDeepTurnContextRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnContextRuntimeAdapter"));
|
const assistantDeepTurnContextRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnContextRuntimeAdapter"));
|
||||||
const assistantDeepTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnFinalizeRuntimeAdapter"));
|
const assistantDeepTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnFinalizeRuntimeAdapter"));
|
||||||
|
|
@ -74,9 +75,12 @@ const assistantDeepTurnGuardRuntimeAdapter_1 = __importStar(require("./assistant
|
||||||
const assistantDeepTurnGroundingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnGroundingRuntimeAdapter"));
|
const assistantDeepTurnGroundingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnGroundingRuntimeAdapter"));
|
||||||
const assistantDeepTurnPackagingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPackagingRuntimeAdapter"));
|
const assistantDeepTurnPackagingRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPackagingRuntimeAdapter"));
|
||||||
const assistantDeepTurnPlanRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnPlanRuntimeAdapter"));
|
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 assistantDeepTurnRetrievalRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnRetrievalRuntimeAdapter"));
|
||||||
const assistantAddressLaneRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneRuntimeAdapter"));
|
const assistantAddressLaneRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneRuntimeAdapter"));
|
||||||
const assistantAddressOrchestrationRuntimeAdapter_1 = __importStar(require("./assistantAddressOrchestrationRuntimeAdapter"));
|
const assistantAddressOrchestrationRuntimeAdapter_1 = __importStar(require("./assistantAddressOrchestrationRuntimeAdapter"));
|
||||||
|
const assistantAddressToolGateRuntimeAdapter_1 = __importStar(require("./assistantAddressToolGateRuntimeAdapter"));
|
||||||
const assistantLivingChatTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantLivingChatTurnFinalizeRuntimeAdapter"));
|
const assistantLivingChatTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantLivingChatTurnFinalizeRuntimeAdapter"));
|
||||||
const assistantLivingChatRuntimeAdapter_1 = __importStar(require("./assistantLivingChatRuntimeAdapter"));
|
const assistantLivingChatRuntimeAdapter_1 = __importStar(require("./assistantLivingChatRuntimeAdapter"));
|
||||||
const assistantQueryPlanning_1 = __importStar(require("./assistantQueryPlanning"));
|
const assistantQueryPlanning_1 = __importStar(require("./assistantQueryPlanning"));
|
||||||
|
|
@ -4583,36 +4587,19 @@ class AssistantService {
|
||||||
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
|
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
|
||||||
addressRuntimeMetaForDeep = addressRuntimeMeta;
|
addressRuntimeMetaForDeep = addressRuntimeMeta;
|
||||||
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
|
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
|
||||||
if (!orchestrationDecision.runAddressLane) {
|
const toolGateRuntime = await (0, assistantAddressToolGateRuntimeAdapter_1.runAssistantAddressToolGateRuntime)({
|
||||||
(0, log_1.logJson)({
|
sessionId,
|
||||||
timestamp: new Date().toISOString(),
|
userMessage,
|
||||||
level: "info",
|
addressInputMessage,
|
||||||
service: "assistant_loop",
|
orchestrationDecision,
|
||||||
message: "assistant_address_tool_gate_skip",
|
livingModeDecision,
|
||||||
sessionId,
|
addressRuntimeMeta,
|
||||||
details: {
|
logEvent: (payload) => (0, log_1.logJson)(payload),
|
||||||
session_id: sessionId,
|
tryHandleLivingChat: (modeDecision, runtimeMeta) => tryHandleLivingChat(modeDecision, runtimeMeta),
|
||||||
user_message: userMessage,
|
nowIso: () => new Date().toISOString()
|
||||||
effective_address_user_message: addressInputMessage,
|
});
|
||||||
address_llm_predecompose_attempted: Boolean(addressRuntimeMeta?.attempted),
|
if (toolGateRuntime.handled && toolGateRuntime.response) {
|
||||||
address_llm_predecompose_applied: Boolean(addressRuntimeMeta?.applied),
|
return toolGateRuntime.response;
|
||||||
address_llm_predecompose_reason: addressRuntimeMeta?.reason ?? null,
|
|
||||||
address_fallback_rule_hit: addressRuntimeMeta?.fallbackRuleHit ?? null,
|
|
||||||
address_sanitized_user_message: addressRuntimeMeta?.sanitizedUserMessage ?? null,
|
|
||||||
assistant_orchestration_contract_v1: addressRuntimeMeta?.orchestrationContract ?? null,
|
|
||||||
address_tool_gate_decision: addressRuntimeMeta?.toolGateDecision ?? null,
|
|
||||||
address_tool_gate_reason: addressRuntimeMeta?.toolGateReason ?? null,
|
|
||||||
address_llm_predecompose_contract_intent: addressRuntimeMeta?.predecomposeContract?.intent ?? null,
|
|
||||||
address_llm_predecompose_contract_aggregation_profile: addressRuntimeMeta?.predecomposeContract?.aggregation_profile ?? null,
|
|
||||||
address_llm_predecompose_contract_period_scope: addressRuntimeMeta?.predecomposeContract?.period?.scope ?? null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (livingModeDecision.mode === "chat") {
|
|
||||||
const chatHandled = await tryHandleLivingChat(livingModeDecision, addressRuntimeMeta);
|
|
||||||
if (chatHandled) {
|
|
||||||
return chatHandled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (orchestrationDecision.runAddressLane) {
|
if (orchestrationDecision.runAddressLane) {
|
||||||
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
|
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
|
||||||
|
|
@ -4648,145 +4635,125 @@ class AssistantService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const followupBinding = config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1 &&
|
const normalizationRuntime = await (0, assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime)({
|
||||||
config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1 &&
|
|
||||||
session.investigation_state
|
|
||||||
? buildFollowupStateBinding({
|
|
||||||
userMessage,
|
|
||||||
payloadContext: payload.context,
|
|
||||||
investigationState: session.investigation_state
|
|
||||||
})
|
|
||||||
: {
|
|
||||||
normalizedQuestion: userMessage,
|
|
||||||
mergedContext: payload.context,
|
|
||||||
usage: null
|
|
||||||
};
|
|
||||||
const normalizePayload = {
|
|
||||||
llmProvider: payload.llmProvider,
|
|
||||||
apiKey: payload.apiKey,
|
|
||||||
model: payload.model,
|
|
||||||
baseUrl: payload.baseUrl,
|
|
||||||
temperature: payload.temperature,
|
|
||||||
maxOutputTokens: payload.maxOutputTokens,
|
|
||||||
promptVersion: payload.promptVersion ?? "address_query_runtime_v1",
|
|
||||||
systemPrompt: payload.systemPrompt,
|
|
||||||
developerPrompt: payload.developerPrompt,
|
|
||||||
domainPrompt: payload.domainPrompt,
|
|
||||||
fewShotExamples: payload.fewShotExamples,
|
|
||||||
userQuestion: followupBinding.normalizedQuestion,
|
|
||||||
context: followupBinding.mergedContext,
|
|
||||||
useMock: Boolean(payload.useMock)
|
|
||||||
};
|
|
||||||
const normalized = await this.normalizerService.normalize(normalizePayload);
|
|
||||||
const contextRuntime = (0, assistantDeepTurnContextRuntimeAdapter_1.buildAssistantDeepTurnRuntimeContext)({
|
|
||||||
userMessage,
|
userMessage,
|
||||||
normalizedPayload: normalized.normalized,
|
payload,
|
||||||
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
|
|
||||||
});
|
|
||||||
const companyAnchors = contextRuntime.companyAnchors;
|
|
||||||
const focusDomainForGuards = contextRuntime.focusDomainForGuards;
|
|
||||||
const temporalGuard = contextRuntime.temporalGuard;
|
|
||||||
const domainPolarityGuardInitial = contextRuntime.domainPolarityGuardInitial;
|
|
||||||
const claimAnchorAudit = contextRuntime.claimAnchorAudit;
|
|
||||||
const businessScopeResolution = contextRuntime.businessScopeResolution;
|
|
||||||
const resolvedRouteSummary = contextRuntime.resolvedRouteSummary;
|
|
||||||
const liveTemporalHint = contextRuntime.liveTemporalHint;
|
|
||||||
const executionPlanRuntime = (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
|
|
||||||
});
|
|
||||||
const requirementExtraction = executionPlanRuntime.requirementExtraction;
|
|
||||||
const rbpRoutePlanEnforcement = executionPlanRuntime.rbpRoutePlanEnforcement;
|
|
||||||
const faRoutePlanEnforcement = executionPlanRuntime.faRoutePlanEnforcement;
|
|
||||||
const executionPlan = executionPlanRuntime.executionPlan;
|
|
||||||
const retrievalRuntime = await (0, assistantDeepTurnRetrievalRuntimeAdapter_1.executeAssistantDeepTurnRetrievalPlan)({
|
|
||||||
executionPlan,
|
|
||||||
liveTemporalHint,
|
|
||||||
executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options),
|
|
||||||
mapNoRouteReason,
|
|
||||||
buildSkippedResult
|
|
||||||
});
|
|
||||||
const retrievalCalls = retrievalRuntime.retrievalCalls;
|
|
||||||
const retrievalResultsRaw = retrievalRuntime.retrievalResultsRaw;
|
|
||||||
let retrievalResults = retrievalRuntime.retrievalResults;
|
|
||||||
const guardRuntime = (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnRetrievalGuards)({
|
|
||||||
retrievalResults,
|
|
||||||
domainPolarityGuardInitial,
|
|
||||||
claimAnchorAudit,
|
|
||||||
temporalGuard,
|
|
||||||
focusDomainForGuards,
|
|
||||||
companyAnchors,
|
|
||||||
userMessage
|
|
||||||
});
|
|
||||||
retrievalResults = guardRuntime.retrievalResults;
|
|
||||||
const polarityGuardResult = guardRuntime.polarityGuardResult;
|
|
||||||
const targetedEvidenceResult = guardRuntime.targetedEvidenceResult;
|
|
||||||
const evidenceGateResult = guardRuntime.evidenceGateResult;
|
|
||||||
const groundingRuntime = (0, assistantDeepTurnGroundingRuntimeAdapter_1.runAssistantDeepTurnGroundingRuntime)({
|
|
||||||
claimType: claimAnchorAudit.claim_type,
|
|
||||||
retrievalResults,
|
|
||||||
rbpPlanAudit: rbpRoutePlanEnforcement.audit,
|
|
||||||
faPlanAudit: faRoutePlanEnforcement.audit,
|
|
||||||
routeSummary: resolvedRouteSummary,
|
|
||||||
normalizedPayload: normalized.normalized,
|
|
||||||
userMessage,
|
|
||||||
requirementExtraction,
|
|
||||||
extractRequirements,
|
|
||||||
evaluateCoverage,
|
|
||||||
checkGrounding,
|
|
||||||
temporalGuard,
|
|
||||||
polarityAudit: polarityGuardResult.audit,
|
|
||||||
evidenceAudit: evidenceGateResult.audit,
|
|
||||||
claimAnchorAudit,
|
|
||||||
targetedEvidenceHitRate: targetedEvidenceResult.audit.targeted_evidence_hit_rate,
|
|
||||||
businessScopeResolved: businessScopeResolution.business_scope_resolved,
|
|
||||||
collectRbpLiveRouteAudit,
|
|
||||||
collectFaLiveRouteAudit
|
|
||||||
});
|
|
||||||
const rbpLiveRouteAudit = groundingRuntime.rbpLiveRouteAudit;
|
|
||||||
const faLiveRouteAudit = groundingRuntime.faLiveRouteAudit;
|
|
||||||
const coverageEvaluation = groundingRuntime.coverageEvaluation;
|
|
||||||
const groundedAnswerEligibilityGuard = groundingRuntime.groundedAnswerEligibilityGuard;
|
|
||||||
const groundingCheck = groundingRuntime.groundingCheck;
|
|
||||||
const deepTurnComposition = (0, assistantDeepTurnCompositionRuntimeAdapter_1.buildAssistantDeepTurnComposition)({
|
|
||||||
userMessage,
|
|
||||||
routeSummary: resolvedRouteSummary,
|
|
||||||
retrievalResults,
|
|
||||||
requirements: coverageEvaluation.requirements,
|
|
||||||
coverageReport: coverageEvaluation.coverage,
|
|
||||||
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)
|
|
||||||
});
|
|
||||||
const questionTypeClass = deepTurnComposition.questionTypeClass;
|
|
||||||
const composition = deepTurnComposition.composition;
|
|
||||||
const packagingRuntime = (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)({
|
|
||||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||||
|
featureStateFollowupBindingV1: config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1,
|
||||||
|
sessionInvestigationState: session.investigation_state,
|
||||||
|
buildFollowupStateBinding,
|
||||||
|
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload)
|
||||||
|
});
|
||||||
|
const followupBinding = normalizationRuntime.followupBinding;
|
||||||
|
const normalized = normalizationRuntime.normalized;
|
||||||
|
const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisRuntimeAdapter_1.runAssistantDeepTurnAnalysisRuntime)({
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const companyAnchors = deepTurnAnalysisRuntime.companyAnchors;
|
||||||
|
const temporalGuard = deepTurnAnalysisRuntime.temporalGuard;
|
||||||
|
const claimAnchorAudit = deepTurnAnalysisRuntime.claimAnchorAudit;
|
||||||
|
const businessScopeResolution = deepTurnAnalysisRuntime.businessScopeResolution;
|
||||||
|
const resolvedRouteSummary = deepTurnAnalysisRuntime.resolvedRouteSummary;
|
||||||
|
const requirementExtraction = deepTurnAnalysisRuntime.requirementExtraction;
|
||||||
|
const executionPlan = deepTurnAnalysisRuntime.executionPlan;
|
||||||
|
const retrievalCalls = deepTurnAnalysisRuntime.retrievalCalls;
|
||||||
|
const retrievalResultsRaw = deepTurnAnalysisRuntime.retrievalResultsRaw;
|
||||||
|
const retrievalResults = deepTurnAnalysisRuntime.retrievalResults;
|
||||||
|
const polarityGuardResult = deepTurnAnalysisRuntime.polarityGuardResult;
|
||||||
|
const targetedEvidenceResult = deepTurnAnalysisRuntime.targetedEvidenceResult;
|
||||||
|
const evidenceGateResult = deepTurnAnalysisRuntime.evidenceGateResult;
|
||||||
|
const rbpLiveRouteAudit = deepTurnAnalysisRuntime.rbpLiveRouteAudit;
|
||||||
|
const faLiveRouteAudit = deepTurnAnalysisRuntime.faLiveRouteAudit;
|
||||||
|
const coverageEvaluation = deepTurnAnalysisRuntime.coverageEvaluation;
|
||||||
|
const groundedAnswerEligibilityGuard = deepTurnAnalysisRuntime.groundedAnswerEligibilityGuard;
|
||||||
|
const groundingCheck = deepTurnAnalysisRuntime.groundingCheck;
|
||||||
|
const questionTypeClass = deepTurnAnalysisRuntime.questionTypeClass;
|
||||||
|
const composition = deepTurnAnalysisRuntime.composition;
|
||||||
|
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseRuntimeAdapter_1.runAssistantDeepTurnResponseRuntime)({
|
||||||
|
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||||
|
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||||
|
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||||
sessionId,
|
sessionId,
|
||||||
questionId: userItem.message_id,
|
questionId: userItem.message_id,
|
||||||
userMessage,
|
userMessage,
|
||||||
|
|
@ -4821,8 +4788,6 @@ class AssistantService {
|
||||||
followupStateUsage: followupBinding.usage,
|
followupStateUsage: followupBinding.usage,
|
||||||
followupApplied: Boolean(followupBinding.usage?.applied),
|
followupApplied: Boolean(followupBinding.usage?.applied),
|
||||||
composition,
|
composition,
|
||||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
|
||||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
|
||||||
previousInvestigationState: session.investigation_state,
|
previousInvestigationState: session.investigation_state,
|
||||||
addressRuntimeMetaForDeep,
|
addressRuntimeMetaForDeep,
|
||||||
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
||||||
|
|
@ -4830,26 +4795,16 @@ class AssistantService {
|
||||||
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
||||||
sanitizeReply: (value, fallback) => sanitizeOutgoingAssistantText(value, fallback),
|
sanitizeReply: (value, fallback) => sanitizeOutgoingAssistantText(value, fallback),
|
||||||
persistInvestigationState: (targetSessionId, snapshot) => this.sessions.setInvestigationState(targetSessionId, snapshot),
|
persistInvestigationState: (targetSessionId, snapshot) => this.sessions.setInvestigationState(targetSessionId, snapshot),
|
||||||
messageIdFactory: () => `msg-${(0, nanoid_1.nanoid)(10)}`
|
messageIdFactory: () => `msg-${(0, nanoid_1.nanoid)(10)}`,
|
||||||
});
|
|
||||||
const safeAssistantReply = packagingRuntime.safeAssistantReply;
|
|
||||||
const debug = packagingRuntime.debug;
|
|
||||||
const assistantItem = packagingRuntime.assistantItem;
|
|
||||||
const deepAnalysisLogDetails = packagingRuntime.deepAnalysisLogDetails;
|
|
||||||
const finalization = (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)({
|
|
||||||
sessionId,
|
|
||||||
assistantReply: safeAssistantReply,
|
|
||||||
replyType: composition.reply_type,
|
|
||||||
assistantItem,
|
|
||||||
debug,
|
|
||||||
deepAnalysisLogDetails,
|
|
||||||
appendItem: (targetSessionId, item) => this.sessions.appendItem(targetSessionId, item),
|
appendItem: (targetSessionId, item) => this.sessions.appendItem(targetSessionId, item),
|
||||||
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
|
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
|
||||||
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
|
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
|
||||||
cloneConversation: (items) => cloneItems(items),
|
cloneConversation: (items) => cloneItems(items),
|
||||||
logEvent: (payload) => (0, log_1.logJson)(payload)
|
logEvent: (payload) => (0, log_1.logJson)(payload),
|
||||||
|
runPackagingRuntime: (input) => (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)(input),
|
||||||
|
runFinalizeDeepTurn: (input) => (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)(input)
|
||||||
});
|
});
|
||||||
return finalization.response;
|
return deepTurnResponseRuntime.response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.AssistantService = AssistantService;
|
exports.AssistantService = AssistantService;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
export interface AssistantAddressToolGateRuntimeInput<ResponseType = unknown> {
|
||||||
|
sessionId: string;
|
||||||
|
userMessage: string;
|
||||||
|
addressInputMessage: string;
|
||||||
|
orchestrationDecision: {
|
||||||
|
runAddressLane?: boolean;
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
|
livingModeDecision: {
|
||||||
|
mode?: unknown;
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
|
addressRuntimeMeta: {
|
||||||
|
attempted?: unknown;
|
||||||
|
applied?: unknown;
|
||||||
|
reason?: unknown;
|
||||||
|
fallbackRuleHit?: unknown;
|
||||||
|
sanitizedUserMessage?: unknown;
|
||||||
|
orchestrationContract?: unknown;
|
||||||
|
toolGateDecision?: unknown;
|
||||||
|
toolGateReason?: unknown;
|
||||||
|
predecomposeContract?: {
|
||||||
|
intent?: unknown;
|
||||||
|
aggregation_profile?: unknown;
|
||||||
|
period?: {
|
||||||
|
scope?: unknown;
|
||||||
|
} | null;
|
||||||
|
} | null;
|
||||||
|
[key: string]: unknown;
|
||||||
|
} | null;
|
||||||
|
logEvent: (payload: Record<string, unknown>) => void;
|
||||||
|
tryHandleLivingChat: (
|
||||||
|
modeDecision: { mode?: unknown; reason?: unknown },
|
||||||
|
addressRuntimeMeta: Record<string, unknown> | null
|
||||||
|
) => Promise<ResponseType | null>;
|
||||||
|
nowIso: () => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssistantAddressToolGateRuntimeOutput<ResponseType = unknown> {
|
||||||
|
handled: boolean;
|
||||||
|
response: ResponseType | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runAssistantAddressToolGateRuntime<ResponseType = unknown>(
|
||||||
|
input: AssistantAddressToolGateRuntimeInput<ResponseType>
|
||||||
|
): Promise<AssistantAddressToolGateRuntimeOutput<ResponseType>> {
|
||||||
|
if (Boolean(input.orchestrationDecision?.runAddressLane)) {
|
||||||
|
return {
|
||||||
|
handled: false,
|
||||||
|
response: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const runtimeMeta =
|
||||||
|
input.addressRuntimeMeta && typeof input.addressRuntimeMeta === "object"
|
||||||
|
? input.addressRuntimeMeta
|
||||||
|
: ({} as Record<string, unknown>);
|
||||||
|
const predecomposeContract =
|
||||||
|
runtimeMeta.predecomposeContract && typeof runtimeMeta.predecomposeContract === "object"
|
||||||
|
? (runtimeMeta.predecomposeContract as {
|
||||||
|
intent?: unknown;
|
||||||
|
aggregation_profile?: unknown;
|
||||||
|
period?: { scope?: unknown } | null;
|
||||||
|
})
|
||||||
|
: null;
|
||||||
|
const predecomposePeriod =
|
||||||
|
predecomposeContract?.period && typeof predecomposeContract.period === "object"
|
||||||
|
? predecomposeContract.period
|
||||||
|
: null;
|
||||||
|
|
||||||
|
input.logEvent({
|
||||||
|
timestamp: input.nowIso(),
|
||||||
|
level: "info",
|
||||||
|
service: "assistant_loop",
|
||||||
|
message: "assistant_address_tool_gate_skip",
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
details: {
|
||||||
|
session_id: input.sessionId,
|
||||||
|
user_message: input.userMessage,
|
||||||
|
effective_address_user_message: input.addressInputMessage,
|
||||||
|
address_llm_predecompose_attempted: Boolean(runtimeMeta.attempted),
|
||||||
|
address_llm_predecompose_applied: Boolean(runtimeMeta.applied),
|
||||||
|
address_llm_predecompose_reason: runtimeMeta.reason ?? null,
|
||||||
|
address_fallback_rule_hit: runtimeMeta.fallbackRuleHit ?? null,
|
||||||
|
address_sanitized_user_message: runtimeMeta.sanitizedUserMessage ?? null,
|
||||||
|
assistant_orchestration_contract_v1: runtimeMeta.orchestrationContract ?? null,
|
||||||
|
address_tool_gate_decision: runtimeMeta.toolGateDecision ?? null,
|
||||||
|
address_tool_gate_reason: runtimeMeta.toolGateReason ?? null,
|
||||||
|
address_llm_predecompose_contract_intent: predecomposeContract?.intent ?? null,
|
||||||
|
address_llm_predecompose_contract_aggregation_profile: predecomposeContract?.aggregation_profile ?? null,
|
||||||
|
address_llm_predecompose_contract_period_scope: predecomposePeriod?.scope ?? null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (input.livingModeDecision?.mode === "chat") {
|
||||||
|
const chatHandled = await input.tryHandleLivingChat(input.livingModeDecision, runtimeMeta);
|
||||||
|
if (chatHandled) {
|
||||||
|
return {
|
||||||
|
handled: true,
|
||||||
|
response: chatHandled
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
handled: false,
|
||||||
|
response: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
import type { AnswerGroundingCheck, AssistantRequirement, RequirementCoverageReport, UnifiedRetrievalResult } from "../types/assistant";
|
||||||
|
import type { RouteHintSummary } from "../types/normalizer";
|
||||||
|
import type {
|
||||||
|
AssistantPlanEnforcementAuditLike,
|
||||||
|
AssistantRequirementExtractionLike
|
||||||
|
} from "./assistantDeepTurnPlanRuntimeAdapter";
|
||||||
|
import type {
|
||||||
|
AssistantDeepTurnRetrievalExecutionOutput,
|
||||||
|
AssistantLiveTemporalHint
|
||||||
|
} from "./assistantDeepTurnRetrievalRuntimeAdapter";
|
||||||
|
import type { AssistantDeepTurnRetrievalGuardPipelineOutput } from "./assistantDeepTurnGuardRuntimeAdapter";
|
||||||
|
import type { AssistantDeepTurnGroundingRuntimeOutput } from "./assistantDeepTurnGroundingRuntimeAdapter";
|
||||||
|
import type { AssistantDeepTurnCompositionOutput } from "./assistantDeepTurnCompositionRuntimeAdapter";
|
||||||
|
|
||||||
|
export interface AssistantDeepTurnRuntimeContextLike {
|
||||||
|
companyAnchors: unknown;
|
||||||
|
focusDomainForGuards: string | null;
|
||||||
|
temporalGuard: unknown;
|
||||||
|
domainPolarityGuardInitial: unknown;
|
||||||
|
claimAnchorAudit: {
|
||||||
|
claim_type: string;
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
|
businessScopeResolution: {
|
||||||
|
business_scope_resolved?: string[] | null;
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
|
resolvedRouteSummary: RouteHintSummary | null;
|
||||||
|
liveTemporalHint: AssistantLiveTemporalHint | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RunAssistantDeepTurnAnalysisRuntimeInput {
|
||||||
|
userMessage: string;
|
||||||
|
runContextRuntime: () => AssistantDeepTurnRuntimeContextLike;
|
||||||
|
runExecutionPlanRuntime: (input: {
|
||||||
|
resolvedRouteSummary: RouteHintSummary | null;
|
||||||
|
claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"];
|
||||||
|
temporalGuard: unknown;
|
||||||
|
domainPolarityGuardInitial: unknown;
|
||||||
|
}) => {
|
||||||
|
requirementExtraction: AssistantRequirementExtractionLike;
|
||||||
|
executionPlan: unknown[];
|
||||||
|
rbpRoutePlanEnforcement: AssistantPlanEnforcementAuditLike;
|
||||||
|
faRoutePlanEnforcement: AssistantPlanEnforcementAuditLike;
|
||||||
|
};
|
||||||
|
runRetrievalRuntime: (input: {
|
||||||
|
executionPlan: unknown[];
|
||||||
|
liveTemporalHint: AssistantLiveTemporalHint | null;
|
||||||
|
}) => Promise<AssistantDeepTurnRetrievalExecutionOutput>;
|
||||||
|
runGuardRuntime: (input: {
|
||||||
|
retrievalResults: UnifiedRetrievalResult[];
|
||||||
|
domainPolarityGuardInitial: unknown;
|
||||||
|
claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"];
|
||||||
|
temporalGuard: unknown;
|
||||||
|
focusDomainForGuards: string | null;
|
||||||
|
companyAnchors: unknown;
|
||||||
|
userMessage: string;
|
||||||
|
}) => AssistantDeepTurnRetrievalGuardPipelineOutput;
|
||||||
|
runGroundingRuntime: (input: {
|
||||||
|
claimType: string;
|
||||||
|
retrievalResults: UnifiedRetrievalResult[];
|
||||||
|
rbpPlanAudit: unknown;
|
||||||
|
faPlanAudit: unknown;
|
||||||
|
routeSummary: RouteHintSummary | null;
|
||||||
|
requirementExtraction: AssistantRequirementExtractionLike;
|
||||||
|
temporalGuard: unknown;
|
||||||
|
polarityAudit: unknown;
|
||||||
|
evidenceAudit: unknown;
|
||||||
|
claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"];
|
||||||
|
targetedEvidenceHitRate?: number | null;
|
||||||
|
businessScopeResolved?: string[] | null;
|
||||||
|
}) => AssistantDeepTurnGroundingRuntimeOutput;
|
||||||
|
runCompositionRuntime: (input: {
|
||||||
|
resolvedRouteSummary: RouteHintSummary | null;
|
||||||
|
retrievalResults: UnifiedRetrievalResult[];
|
||||||
|
requirements: AssistantRequirement[];
|
||||||
|
coverageReport: RequirementCoverageReport;
|
||||||
|
groundingCheck: AnswerGroundingCheck;
|
||||||
|
companyAnchors: unknown;
|
||||||
|
}) => AssistantDeepTurnCompositionOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RunAssistantDeepTurnAnalysisRuntimeOutput {
|
||||||
|
companyAnchors: unknown;
|
||||||
|
temporalGuard: unknown;
|
||||||
|
claimAnchorAudit: AssistantDeepTurnRuntimeContextLike["claimAnchorAudit"];
|
||||||
|
businessScopeResolution: AssistantDeepTurnRuntimeContextLike["businessScopeResolution"];
|
||||||
|
resolvedRouteSummary: RouteHintSummary | null;
|
||||||
|
requirementExtraction: AssistantRequirementExtractionLike;
|
||||||
|
executionPlan: unknown[];
|
||||||
|
retrievalCalls: AssistantDeepTurnRetrievalExecutionOutput["retrievalCalls"];
|
||||||
|
retrievalResultsRaw: AssistantDeepTurnRetrievalExecutionOutput["retrievalResultsRaw"];
|
||||||
|
retrievalResults: UnifiedRetrievalResult[];
|
||||||
|
polarityGuardResult: AssistantDeepTurnRetrievalGuardPipelineOutput["polarityGuardResult"];
|
||||||
|
targetedEvidenceResult: AssistantDeepTurnRetrievalGuardPipelineOutput["targetedEvidenceResult"];
|
||||||
|
evidenceGateResult: AssistantDeepTurnRetrievalGuardPipelineOutput["evidenceGateResult"];
|
||||||
|
rbpLiveRouteAudit: AssistantDeepTurnGroundingRuntimeOutput["rbpLiveRouteAudit"];
|
||||||
|
faLiveRouteAudit: AssistantDeepTurnGroundingRuntimeOutput["faLiveRouteAudit"];
|
||||||
|
coverageEvaluation: AssistantDeepTurnGroundingRuntimeOutput["coverageEvaluation"];
|
||||||
|
groundedAnswerEligibilityGuard: AssistantDeepTurnGroundingRuntimeOutput["groundedAnswerEligibilityGuard"];
|
||||||
|
groundingCheck: AssistantDeepTurnGroundingRuntimeOutput["groundingCheck"];
|
||||||
|
questionTypeClass: AssistantDeepTurnCompositionOutput["questionTypeClass"];
|
||||||
|
composition: AssistantDeepTurnCompositionOutput["composition"];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runAssistantDeepTurnAnalysisRuntime(
|
||||||
|
input: RunAssistantDeepTurnAnalysisRuntimeInput
|
||||||
|
): Promise<RunAssistantDeepTurnAnalysisRuntimeOutput> {
|
||||||
|
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,
|
||||||
|
domainPolarityGuardInitial: contextRuntime.domainPolarityGuardInitial,
|
||||||
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
||||||
|
temporalGuard: contextRuntime.temporalGuard,
|
||||||
|
focusDomainForGuards: contextRuntime.focusDomainForGuards,
|
||||||
|
companyAnchors: contextRuntime.companyAnchors,
|
||||||
|
userMessage: input.userMessage
|
||||||
|
});
|
||||||
|
const groundingRuntime = input.runGroundingRuntime({
|
||||||
|
claimType: contextRuntime.claimAnchorAudit.claim_type,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
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 ?? null
|
||||||
|
});
|
||||||
|
const compositionRuntime = input.runCompositionRuntime({
|
||||||
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
requirements: groundingRuntime.coverageEvaluation.requirements,
|
||||||
|
coverageReport: groundingRuntime.coverageEvaluation.coverage,
|
||||||
|
groundingCheck: groundingRuntime.groundingCheck,
|
||||||
|
companyAnchors: contextRuntime.companyAnchors
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
companyAnchors: contextRuntime.companyAnchors,
|
||||||
|
temporalGuard: contextRuntime.temporalGuard,
|
||||||
|
claimAnchorAudit: contextRuntime.claimAnchorAudit,
|
||||||
|
businessScopeResolution: contextRuntime.businessScopeResolution,
|
||||||
|
resolvedRouteSummary: contextRuntime.resolvedRouteSummary,
|
||||||
|
requirementExtraction: executionPlanRuntime.requirementExtraction,
|
||||||
|
executionPlan: executionPlanRuntime.executionPlan,
|
||||||
|
retrievalCalls: retrievalRuntime.retrievalCalls,
|
||||||
|
retrievalResultsRaw: retrievalRuntime.retrievalResultsRaw,
|
||||||
|
retrievalResults: guardRuntime.retrievalResults,
|
||||||
|
polarityGuardResult: guardRuntime.polarityGuardResult,
|
||||||
|
targetedEvidenceResult: guardRuntime.targetedEvidenceResult,
|
||||||
|
evidenceGateResult: guardRuntime.evidenceGateResult,
|
||||||
|
rbpLiveRouteAudit: groundingRuntime.rbpLiveRouteAudit,
|
||||||
|
faLiveRouteAudit: groundingRuntime.faLiveRouteAudit,
|
||||||
|
coverageEvaluation: groundingRuntime.coverageEvaluation,
|
||||||
|
groundedAnswerEligibilityGuard: groundingRuntime.groundedAnswerEligibilityGuard,
|
||||||
|
groundingCheck: groundingRuntime.groundingCheck,
|
||||||
|
questionTypeClass: compositionRuntime.questionTypeClass,
|
||||||
|
composition: compositionRuntime.composition
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import type { AssistantMessageRequestPayload } from "../types/assistant";
|
||||||
|
import type { NormalizeRequestPayload, NormalizeResponsePayload } from "../types/normalizer";
|
||||||
|
|
||||||
|
export interface AssistantDeepTurnFollowupBinding {
|
||||||
|
normalizedQuestion: string;
|
||||||
|
mergedContext: NormalizeRequestPayload["context"] | undefined;
|
||||||
|
usage: unknown | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuildAssistantDeepTurnNormalizationRuntimeInput {
|
||||||
|
userMessage: string;
|
||||||
|
payload: AssistantMessageRequestPayload;
|
||||||
|
featureInvestigationStateV1: boolean;
|
||||||
|
featureStateFollowupBindingV1: boolean;
|
||||||
|
sessionInvestigationState: unknown | null | undefined;
|
||||||
|
buildFollowupStateBinding: (input: {
|
||||||
|
userMessage: string;
|
||||||
|
payloadContext: NormalizeRequestPayload["context"] | undefined;
|
||||||
|
investigationState: unknown;
|
||||||
|
}) => AssistantDeepTurnFollowupBinding;
|
||||||
|
normalize: (payload: NormalizeRequestPayload) => Promise<NormalizeResponsePayload>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuildAssistantDeepTurnNormalizationRuntimeOutput {
|
||||||
|
followupBinding: AssistantDeepTurnFollowupBinding;
|
||||||
|
normalizePayload: NormalizeRequestPayload;
|
||||||
|
normalized: NormalizeResponsePayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buildAssistantDeepTurnNormalizationRuntime(
|
||||||
|
input: BuildAssistantDeepTurnNormalizationRuntimeInput
|
||||||
|
): Promise<BuildAssistantDeepTurnNormalizationRuntimeOutput> {
|
||||||
|
const followupBinding =
|
||||||
|
input.featureInvestigationStateV1 &&
|
||||||
|
input.featureStateFollowupBindingV1 &&
|
||||||
|
Boolean(input.sessionInvestigationState)
|
||||||
|
? input.buildFollowupStateBinding({
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
payloadContext: input.payload.context,
|
||||||
|
investigationState: input.sessionInvestigationState as unknown
|
||||||
|
})
|
||||||
|
: {
|
||||||
|
normalizedQuestion: input.userMessage,
|
||||||
|
mergedContext: input.payload.context,
|
||||||
|
usage: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizePayload: NormalizeRequestPayload = {
|
||||||
|
llmProvider: input.payload.llmProvider,
|
||||||
|
apiKey: input.payload.apiKey,
|
||||||
|
model: input.payload.model,
|
||||||
|
baseUrl: input.payload.baseUrl,
|
||||||
|
temperature: input.payload.temperature,
|
||||||
|
maxOutputTokens: input.payload.maxOutputTokens,
|
||||||
|
promptVersion: input.payload.promptVersion ?? "address_query_runtime_v1",
|
||||||
|
systemPrompt: input.payload.systemPrompt,
|
||||||
|
developerPrompt: input.payload.developerPrompt,
|
||||||
|
domainPrompt: input.payload.domainPrompt,
|
||||||
|
fewShotExamples: input.payload.fewShotExamples,
|
||||||
|
userQuestion: followupBinding.normalizedQuestion,
|
||||||
|
context: followupBinding.mergedContext,
|
||||||
|
useMock: Boolean(input.payload.useMock)
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalized = await input.normalize(normalizePayload);
|
||||||
|
|
||||||
|
return {
|
||||||
|
followupBinding,
|
||||||
|
normalizePayload,
|
||||||
|
normalized
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
import type { AssistantMessageResponsePayload, AssistantReplyType } from "../types/assistant";
|
||||||
|
import type { NormalizeResponsePayload, RouteHintSummary } from "../types/normalizer";
|
||||||
|
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
|
||||||
|
import {
|
||||||
|
runAssistantDeepTurnPackagingRuntime,
|
||||||
|
type AssistantDeepTurnPackagingRuntimeInput,
|
||||||
|
type AssistantDeepTurnPackagingRuntimeOutput
|
||||||
|
} from "./assistantDeepTurnPackagingRuntimeAdapter";
|
||||||
|
import {
|
||||||
|
finalizeAssistantDeepTurn,
|
||||||
|
type FinalizeAssistantDeepTurnInput
|
||||||
|
} from "./assistantDeepTurnFinalizeRuntimeAdapter";
|
||||||
|
|
||||||
|
type CompositionLike = {
|
||||||
|
reply_type: AssistantReplyType;
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface RunAssistantDeepTurnResponseRuntimeInput {
|
||||||
|
featureInvestigationStateV1: boolean;
|
||||||
|
featureContractsV11: boolean;
|
||||||
|
featureAnswerPolicyV11: boolean;
|
||||||
|
sessionId: string;
|
||||||
|
questionId: string;
|
||||||
|
userMessage: string;
|
||||||
|
normalized: {
|
||||||
|
trace_id: string;
|
||||||
|
prompt_version: string;
|
||||||
|
schema_version: string;
|
||||||
|
normalized: NormalizeResponsePayload["normalized"];
|
||||||
|
};
|
||||||
|
normalizedQuestion: string;
|
||||||
|
routeSummary: RouteHintSummary | null;
|
||||||
|
executionPlan: unknown[];
|
||||||
|
requirementExtractionRequirements: unknown[];
|
||||||
|
coverageEvaluationRequirements: unknown[];
|
||||||
|
coverageReport: unknown;
|
||||||
|
groundingCheck: unknown;
|
||||||
|
retrievalCalls: unknown[];
|
||||||
|
retrievalResultsRaw: unknown[];
|
||||||
|
retrievalResults: unknown[];
|
||||||
|
questionTypeClass: string;
|
||||||
|
companyAnchors: unknown;
|
||||||
|
runtimeAnalysisContext: unknown;
|
||||||
|
businessScopeResolution: unknown;
|
||||||
|
temporalGuard: unknown;
|
||||||
|
polarityAudit: unknown;
|
||||||
|
claimAnchorAudit: unknown;
|
||||||
|
targetedEvidenceAudit: unknown;
|
||||||
|
evidenceAdmissibilityGateAudit: unknown;
|
||||||
|
rbpLiveRouteAudit: unknown;
|
||||||
|
faLiveRouteAudit: unknown;
|
||||||
|
groundedAnswerEligibilityGuard: unknown;
|
||||||
|
followupStateUsage: unknown;
|
||||||
|
followupApplied: boolean;
|
||||||
|
composition: CompositionLike;
|
||||||
|
previousInvestigationState: InvestigationStateWithProblemUnits | null | undefined;
|
||||||
|
addressRuntimeMetaForDeep: unknown;
|
||||||
|
extractDroppedIntentSegments: (normalizedPayload: NormalizeResponsePayload["normalized"]) => string[];
|
||||||
|
buildDebugRoutes: (routeSummary: RouteHintSummary | null) => Array<Record<string, unknown>>;
|
||||||
|
extractExecutionState: (normalizedPayload: NormalizeResponsePayload["normalized"]) => unknown[];
|
||||||
|
sanitizeReply: (value: string, fallback?: string) => string;
|
||||||
|
persistInvestigationState: (sessionId: string, snapshot: InvestigationStateWithProblemUnits) => void;
|
||||||
|
messageIdFactory: () => string;
|
||||||
|
appendItem: FinalizeAssistantDeepTurnInput["appendItem"];
|
||||||
|
getSession: FinalizeAssistantDeepTurnInput["getSession"];
|
||||||
|
persistSession: FinalizeAssistantDeepTurnInput["persistSession"];
|
||||||
|
cloneConversation: FinalizeAssistantDeepTurnInput["cloneConversation"];
|
||||||
|
logEvent: FinalizeAssistantDeepTurnInput["logEvent"];
|
||||||
|
runPackagingRuntime?: (
|
||||||
|
input: AssistantDeepTurnPackagingRuntimeInput
|
||||||
|
) => AssistantDeepTurnPackagingRuntimeOutput;
|
||||||
|
runFinalizeDeepTurn?: (input: FinalizeAssistantDeepTurnInput) => { response: AssistantMessageResponsePayload };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RunAssistantDeepTurnResponseRuntimeOutput {
|
||||||
|
response: AssistantMessageResponsePayload;
|
||||||
|
debug: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function runAssistantDeepTurnResponseRuntime(
|
||||||
|
input: RunAssistantDeepTurnResponseRuntimeInput
|
||||||
|
): RunAssistantDeepTurnResponseRuntimeOutput {
|
||||||
|
const runPackagingRuntimeSafe = input.runPackagingRuntime ?? runAssistantDeepTurnPackagingRuntime;
|
||||||
|
const runFinalizeDeepTurnSafe = input.runFinalizeDeepTurn ?? finalizeAssistantDeepTurn;
|
||||||
|
|
||||||
|
const packagingRuntime = runPackagingRuntimeSafe({
|
||||||
|
featureInvestigationStateV1: input.featureInvestigationStateV1,
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
questionId: input.questionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
normalized: input.normalized,
|
||||||
|
normalizedQuestion: input.normalizedQuestion,
|
||||||
|
routeSummary: input.routeSummary,
|
||||||
|
executionPlan: input.executionPlan as any,
|
||||||
|
requirementExtractionRequirements: input.requirementExtractionRequirements as any,
|
||||||
|
coverageEvaluationRequirements: input.coverageEvaluationRequirements as any,
|
||||||
|
coverageReport: input.coverageReport as any,
|
||||||
|
groundingCheck: input.groundingCheck as any,
|
||||||
|
retrievalCalls: input.retrievalCalls as any,
|
||||||
|
retrievalResultsRaw: input.retrievalResultsRaw as any,
|
||||||
|
retrievalResults: input.retrievalResults as any,
|
||||||
|
questionTypeClass: input.questionTypeClass,
|
||||||
|
companyAnchors: input.companyAnchors,
|
||||||
|
runtimeAnalysisContext: input.runtimeAnalysisContext as any,
|
||||||
|
businessScopeResolution: input.businessScopeResolution as any,
|
||||||
|
temporalGuard: input.temporalGuard as any,
|
||||||
|
polarityAudit: input.polarityAudit as any,
|
||||||
|
claimAnchorAudit: input.claimAnchorAudit as any,
|
||||||
|
targetedEvidenceAudit: input.targetedEvidenceAudit as any,
|
||||||
|
evidenceAdmissibilityGateAudit: input.evidenceAdmissibilityGateAudit as any,
|
||||||
|
rbpLiveRouteAudit: input.rbpLiveRouteAudit as any,
|
||||||
|
faLiveRouteAudit: input.faLiveRouteAudit as any,
|
||||||
|
groundedAnswerEligibilityGuard: input.groundedAnswerEligibilityGuard as any,
|
||||||
|
followupStateUsage: input.followupStateUsage as any,
|
||||||
|
followupApplied: input.followupApplied,
|
||||||
|
composition: input.composition as any,
|
||||||
|
featureContractsV11: input.featureContractsV11,
|
||||||
|
featureAnswerPolicyV11: input.featureAnswerPolicyV11,
|
||||||
|
previousInvestigationState: input.previousInvestigationState ?? null,
|
||||||
|
addressRuntimeMetaForDeep: input.addressRuntimeMetaForDeep as any,
|
||||||
|
extractDroppedIntentSegments: input.extractDroppedIntentSegments,
|
||||||
|
buildDebugRoutes: input.buildDebugRoutes,
|
||||||
|
extractExecutionState: input.extractExecutionState,
|
||||||
|
sanitizeReply: input.sanitizeReply,
|
||||||
|
persistInvestigationState: input.persistInvestigationState,
|
||||||
|
messageIdFactory: input.messageIdFactory
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalization = runFinalizeDeepTurnSafe({
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
assistantReply: packagingRuntime.safeAssistantReply,
|
||||||
|
replyType: input.composition.reply_type,
|
||||||
|
assistantItem: packagingRuntime.assistantItem,
|
||||||
|
debug: packagingRuntime.debug,
|
||||||
|
deepAnalysisLogDetails: packagingRuntime.deepAnalysisLogDetails,
|
||||||
|
appendItem: input.appendItem,
|
||||||
|
getSession: input.getSession,
|
||||||
|
persistSession: input.persistSession,
|
||||||
|
cloneConversation: input.cloneConversation,
|
||||||
|
logEvent: input.logEvent
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: finalization.response,
|
||||||
|
debug: packagingRuntime.debug
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ import * as capabilitiesRegistry_1 from "./capabilitiesRegistry";
|
||||||
import * as assistantCanon_1 from "./assistantCanon";
|
import * as assistantCanon_1 from "./assistantCanon";
|
||||||
import * as assistantAddressTurnFinalizeRuntimeAdapter_1 from "./assistantAddressTurnFinalizeRuntimeAdapter";
|
import * as assistantAddressTurnFinalizeRuntimeAdapter_1 from "./assistantAddressTurnFinalizeRuntimeAdapter";
|
||||||
import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding";
|
import * as assistantCoverageGrounding_1 from "./assistantCoverageGrounding";
|
||||||
|
import * as assistantDeepTurnAnalysisRuntimeAdapter_1 from "./assistantDeepTurnAnalysisRuntimeAdapter";
|
||||||
import * as assistantDeepTurnCompositionRuntimeAdapter_1 from "./assistantDeepTurnCompositionRuntimeAdapter";
|
import * as assistantDeepTurnCompositionRuntimeAdapter_1 from "./assistantDeepTurnCompositionRuntimeAdapter";
|
||||||
import * as assistantDeepTurnContextRuntimeAdapter_1 from "./assistantDeepTurnContextRuntimeAdapter";
|
import * as assistantDeepTurnContextRuntimeAdapter_1 from "./assistantDeepTurnContextRuntimeAdapter";
|
||||||
import * as assistantDeepTurnFinalizeRuntimeAdapter_1 from "./assistantDeepTurnFinalizeRuntimeAdapter";
|
import * as assistantDeepTurnFinalizeRuntimeAdapter_1 from "./assistantDeepTurnFinalizeRuntimeAdapter";
|
||||||
|
|
@ -28,9 +29,12 @@ import * as assistantDeepTurnGuardRuntimeAdapter_1 from "./assistantDeepTurnGuar
|
||||||
import * as assistantDeepTurnGroundingRuntimeAdapter_1 from "./assistantDeepTurnGroundingRuntimeAdapter";
|
import * as assistantDeepTurnGroundingRuntimeAdapter_1 from "./assistantDeepTurnGroundingRuntimeAdapter";
|
||||||
import * as assistantDeepTurnPackagingRuntimeAdapter_1 from "./assistantDeepTurnPackagingRuntimeAdapter";
|
import * as assistantDeepTurnPackagingRuntimeAdapter_1 from "./assistantDeepTurnPackagingRuntimeAdapter";
|
||||||
import * as assistantDeepTurnPlanRuntimeAdapter_1 from "./assistantDeepTurnPlanRuntimeAdapter";
|
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 assistantDeepTurnRetrievalRuntimeAdapter_1 from "./assistantDeepTurnRetrievalRuntimeAdapter";
|
||||||
import * as assistantAddressLaneRuntimeAdapter_1 from "./assistantAddressLaneRuntimeAdapter";
|
import * as assistantAddressLaneRuntimeAdapter_1 from "./assistantAddressLaneRuntimeAdapter";
|
||||||
import * as assistantAddressOrchestrationRuntimeAdapter_1 from "./assistantAddressOrchestrationRuntimeAdapter";
|
import * as assistantAddressOrchestrationRuntimeAdapter_1 from "./assistantAddressOrchestrationRuntimeAdapter";
|
||||||
|
import * as assistantAddressToolGateRuntimeAdapter_1 from "./assistantAddressToolGateRuntimeAdapter";
|
||||||
import * as assistantLivingChatTurnFinalizeRuntimeAdapter_1 from "./assistantLivingChatTurnFinalizeRuntimeAdapter";
|
import * as assistantLivingChatTurnFinalizeRuntimeAdapter_1 from "./assistantLivingChatTurnFinalizeRuntimeAdapter";
|
||||||
import * as assistantLivingChatRuntimeAdapter_1 from "./assistantLivingChatRuntimeAdapter";
|
import * as assistantLivingChatRuntimeAdapter_1 from "./assistantLivingChatRuntimeAdapter";
|
||||||
import * as assistantQueryPlanning_1 from "./assistantQueryPlanning";
|
import * as assistantQueryPlanning_1 from "./assistantQueryPlanning";
|
||||||
|
|
@ -4538,36 +4542,19 @@ export class AssistantService {
|
||||||
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
|
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
|
||||||
addressRuntimeMetaForDeep = addressRuntimeMeta;
|
addressRuntimeMetaForDeep = addressRuntimeMeta;
|
||||||
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
|
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
|
||||||
if (!orchestrationDecision.runAddressLane) {
|
const toolGateRuntime = await (0, assistantAddressToolGateRuntimeAdapter_1.runAssistantAddressToolGateRuntime)({
|
||||||
(0, log_1.logJson)({
|
sessionId,
|
||||||
timestamp: new Date().toISOString(),
|
userMessage,
|
||||||
level: "info",
|
addressInputMessage,
|
||||||
service: "assistant_loop",
|
orchestrationDecision,
|
||||||
message: "assistant_address_tool_gate_skip",
|
livingModeDecision,
|
||||||
sessionId,
|
addressRuntimeMeta,
|
||||||
details: {
|
logEvent: (payload) => (0, log_1.logJson)(payload),
|
||||||
session_id: sessionId,
|
tryHandleLivingChat: (modeDecision, runtimeMeta) => tryHandleLivingChat(modeDecision, runtimeMeta),
|
||||||
user_message: userMessage,
|
nowIso: () => new Date().toISOString()
|
||||||
effective_address_user_message: addressInputMessage,
|
});
|
||||||
address_llm_predecompose_attempted: Boolean(addressRuntimeMeta?.attempted),
|
if (toolGateRuntime.handled && toolGateRuntime.response) {
|
||||||
address_llm_predecompose_applied: Boolean(addressRuntimeMeta?.applied),
|
return toolGateRuntime.response;
|
||||||
address_llm_predecompose_reason: addressRuntimeMeta?.reason ?? null,
|
|
||||||
address_fallback_rule_hit: addressRuntimeMeta?.fallbackRuleHit ?? null,
|
|
||||||
address_sanitized_user_message: addressRuntimeMeta?.sanitizedUserMessage ?? null,
|
|
||||||
assistant_orchestration_contract_v1: addressRuntimeMeta?.orchestrationContract ?? null,
|
|
||||||
address_tool_gate_decision: addressRuntimeMeta?.toolGateDecision ?? null,
|
|
||||||
address_tool_gate_reason: addressRuntimeMeta?.toolGateReason ?? null,
|
|
||||||
address_llm_predecompose_contract_intent: addressRuntimeMeta?.predecomposeContract?.intent ?? null,
|
|
||||||
address_llm_predecompose_contract_aggregation_profile: addressRuntimeMeta?.predecomposeContract?.aggregation_profile ?? null,
|
|
||||||
address_llm_predecompose_contract_period_scope: addressRuntimeMeta?.predecomposeContract?.period?.scope ?? null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (livingModeDecision.mode === "chat") {
|
|
||||||
const chatHandled = await tryHandleLivingChat(livingModeDecision, addressRuntimeMeta);
|
|
||||||
if (chatHandled) {
|
|
||||||
return chatHandled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (orchestrationDecision.runAddressLane) {
|
if (orchestrationDecision.runAddressLane) {
|
||||||
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
|
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
|
||||||
|
|
@ -4603,145 +4590,125 @@ export class AssistantService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const followupBinding = config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1 &&
|
const normalizationRuntime = await (0, assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime)({
|
||||||
config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1 &&
|
|
||||||
session.investigation_state
|
|
||||||
? buildFollowupStateBinding({
|
|
||||||
userMessage,
|
|
||||||
payloadContext: payload.context,
|
|
||||||
investigationState: session.investigation_state
|
|
||||||
})
|
|
||||||
: {
|
|
||||||
normalizedQuestion: userMessage,
|
|
||||||
mergedContext: payload.context,
|
|
||||||
usage: null
|
|
||||||
};
|
|
||||||
const normalizePayload = {
|
|
||||||
llmProvider: payload.llmProvider,
|
|
||||||
apiKey: payload.apiKey,
|
|
||||||
model: payload.model,
|
|
||||||
baseUrl: payload.baseUrl,
|
|
||||||
temperature: payload.temperature,
|
|
||||||
maxOutputTokens: payload.maxOutputTokens,
|
|
||||||
promptVersion: payload.promptVersion ?? "address_query_runtime_v1",
|
|
||||||
systemPrompt: payload.systemPrompt,
|
|
||||||
developerPrompt: payload.developerPrompt,
|
|
||||||
domainPrompt: payload.domainPrompt,
|
|
||||||
fewShotExamples: payload.fewShotExamples,
|
|
||||||
userQuestion: followupBinding.normalizedQuestion,
|
|
||||||
context: followupBinding.mergedContext,
|
|
||||||
useMock: Boolean(payload.useMock)
|
|
||||||
};
|
|
||||||
const normalized = await this.normalizerService.normalize(normalizePayload);
|
|
||||||
const contextRuntime = (0, assistantDeepTurnContextRuntimeAdapter_1.buildAssistantDeepTurnRuntimeContext)({
|
|
||||||
userMessage,
|
userMessage,
|
||||||
normalizedPayload: normalized.normalized,
|
payload,
|
||||||
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
|
|
||||||
});
|
|
||||||
const companyAnchors = contextRuntime.companyAnchors;
|
|
||||||
const focusDomainForGuards = contextRuntime.focusDomainForGuards;
|
|
||||||
const temporalGuard = contextRuntime.temporalGuard;
|
|
||||||
const domainPolarityGuardInitial = contextRuntime.domainPolarityGuardInitial;
|
|
||||||
const claimAnchorAudit = contextRuntime.claimAnchorAudit;
|
|
||||||
const businessScopeResolution = contextRuntime.businessScopeResolution;
|
|
||||||
const resolvedRouteSummary = contextRuntime.resolvedRouteSummary;
|
|
||||||
const liveTemporalHint = contextRuntime.liveTemporalHint;
|
|
||||||
const executionPlanRuntime = (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
|
|
||||||
});
|
|
||||||
const requirementExtraction = executionPlanRuntime.requirementExtraction;
|
|
||||||
const rbpRoutePlanEnforcement = executionPlanRuntime.rbpRoutePlanEnforcement;
|
|
||||||
const faRoutePlanEnforcement = executionPlanRuntime.faRoutePlanEnforcement;
|
|
||||||
const executionPlan = executionPlanRuntime.executionPlan;
|
|
||||||
const retrievalRuntime = await (0, assistantDeepTurnRetrievalRuntimeAdapter_1.executeAssistantDeepTurnRetrievalPlan)({
|
|
||||||
executionPlan,
|
|
||||||
liveTemporalHint,
|
|
||||||
executeRouteRuntime: (route, fragmentText, options) => this.dataLayer.executeRouteRuntime(route, fragmentText, options),
|
|
||||||
mapNoRouteReason,
|
|
||||||
buildSkippedResult
|
|
||||||
});
|
|
||||||
const retrievalCalls = retrievalRuntime.retrievalCalls;
|
|
||||||
const retrievalResultsRaw = retrievalRuntime.retrievalResultsRaw;
|
|
||||||
let retrievalResults = retrievalRuntime.retrievalResults;
|
|
||||||
const guardRuntime = (0, assistantDeepTurnGuardRuntimeAdapter_1.applyAssistantDeepTurnRetrievalGuards)({
|
|
||||||
retrievalResults,
|
|
||||||
domainPolarityGuardInitial,
|
|
||||||
claimAnchorAudit,
|
|
||||||
temporalGuard,
|
|
||||||
focusDomainForGuards,
|
|
||||||
companyAnchors,
|
|
||||||
userMessage
|
|
||||||
});
|
|
||||||
retrievalResults = guardRuntime.retrievalResults;
|
|
||||||
const polarityGuardResult = guardRuntime.polarityGuardResult;
|
|
||||||
const targetedEvidenceResult = guardRuntime.targetedEvidenceResult;
|
|
||||||
const evidenceGateResult = guardRuntime.evidenceGateResult;
|
|
||||||
const groundingRuntime = (0, assistantDeepTurnGroundingRuntimeAdapter_1.runAssistantDeepTurnGroundingRuntime)({
|
|
||||||
claimType: claimAnchorAudit.claim_type,
|
|
||||||
retrievalResults,
|
|
||||||
rbpPlanAudit: rbpRoutePlanEnforcement.audit,
|
|
||||||
faPlanAudit: faRoutePlanEnforcement.audit,
|
|
||||||
routeSummary: resolvedRouteSummary,
|
|
||||||
normalizedPayload: normalized.normalized,
|
|
||||||
userMessage,
|
|
||||||
requirementExtraction,
|
|
||||||
extractRequirements,
|
|
||||||
evaluateCoverage,
|
|
||||||
checkGrounding,
|
|
||||||
temporalGuard,
|
|
||||||
polarityAudit: polarityGuardResult.audit,
|
|
||||||
evidenceAudit: evidenceGateResult.audit,
|
|
||||||
claimAnchorAudit,
|
|
||||||
targetedEvidenceHitRate: targetedEvidenceResult.audit.targeted_evidence_hit_rate,
|
|
||||||
businessScopeResolved: businessScopeResolution.business_scope_resolved,
|
|
||||||
collectRbpLiveRouteAudit,
|
|
||||||
collectFaLiveRouteAudit
|
|
||||||
});
|
|
||||||
const rbpLiveRouteAudit = groundingRuntime.rbpLiveRouteAudit;
|
|
||||||
const faLiveRouteAudit = groundingRuntime.faLiveRouteAudit;
|
|
||||||
const coverageEvaluation = groundingRuntime.coverageEvaluation;
|
|
||||||
const groundedAnswerEligibilityGuard = groundingRuntime.groundedAnswerEligibilityGuard;
|
|
||||||
const groundingCheck = groundingRuntime.groundingCheck;
|
|
||||||
const deepTurnComposition = (0, assistantDeepTurnCompositionRuntimeAdapter_1.buildAssistantDeepTurnComposition)({
|
|
||||||
userMessage,
|
|
||||||
routeSummary: resolvedRouteSummary,
|
|
||||||
retrievalResults,
|
|
||||||
requirements: coverageEvaluation.requirements,
|
|
||||||
coverageReport: coverageEvaluation.coverage,
|
|
||||||
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)
|
|
||||||
});
|
|
||||||
const questionTypeClass = deepTurnComposition.questionTypeClass;
|
|
||||||
const composition = deepTurnComposition.composition;
|
|
||||||
const packagingRuntime = (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)({
|
|
||||||
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||||
|
featureStateFollowupBindingV1: config_1.FEATURE_ASSISTANT_STATE_FOLLOWUP_BINDING_V1,
|
||||||
|
sessionInvestigationState: session.investigation_state,
|
||||||
|
buildFollowupStateBinding,
|
||||||
|
normalize: (normalizePayload) => this.normalizerService.normalize(normalizePayload)
|
||||||
|
});
|
||||||
|
const followupBinding = normalizationRuntime.followupBinding;
|
||||||
|
const normalized = normalizationRuntime.normalized;
|
||||||
|
const deepTurnAnalysisRuntime = await (0, assistantDeepTurnAnalysisRuntimeAdapter_1.runAssistantDeepTurnAnalysisRuntime)({
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const companyAnchors = deepTurnAnalysisRuntime.companyAnchors;
|
||||||
|
const temporalGuard = deepTurnAnalysisRuntime.temporalGuard;
|
||||||
|
const claimAnchorAudit = deepTurnAnalysisRuntime.claimAnchorAudit;
|
||||||
|
const businessScopeResolution = deepTurnAnalysisRuntime.businessScopeResolution;
|
||||||
|
const resolvedRouteSummary = deepTurnAnalysisRuntime.resolvedRouteSummary;
|
||||||
|
const requirementExtraction = deepTurnAnalysisRuntime.requirementExtraction;
|
||||||
|
const executionPlan = deepTurnAnalysisRuntime.executionPlan;
|
||||||
|
const retrievalCalls = deepTurnAnalysisRuntime.retrievalCalls;
|
||||||
|
const retrievalResultsRaw = deepTurnAnalysisRuntime.retrievalResultsRaw;
|
||||||
|
const retrievalResults = deepTurnAnalysisRuntime.retrievalResults;
|
||||||
|
const polarityGuardResult = deepTurnAnalysisRuntime.polarityGuardResult;
|
||||||
|
const targetedEvidenceResult = deepTurnAnalysisRuntime.targetedEvidenceResult;
|
||||||
|
const evidenceGateResult = deepTurnAnalysisRuntime.evidenceGateResult;
|
||||||
|
const rbpLiveRouteAudit = deepTurnAnalysisRuntime.rbpLiveRouteAudit;
|
||||||
|
const faLiveRouteAudit = deepTurnAnalysisRuntime.faLiveRouteAudit;
|
||||||
|
const coverageEvaluation = deepTurnAnalysisRuntime.coverageEvaluation;
|
||||||
|
const groundedAnswerEligibilityGuard = deepTurnAnalysisRuntime.groundedAnswerEligibilityGuard;
|
||||||
|
const groundingCheck = deepTurnAnalysisRuntime.groundingCheck;
|
||||||
|
const questionTypeClass = deepTurnAnalysisRuntime.questionTypeClass;
|
||||||
|
const composition = deepTurnAnalysisRuntime.composition;
|
||||||
|
const deepTurnResponseRuntime = (0, assistantDeepTurnResponseRuntimeAdapter_1.runAssistantDeepTurnResponseRuntime)({
|
||||||
|
featureInvestigationStateV1: config_1.FEATURE_ASSISTANT_INVESTIGATION_STATE_V1,
|
||||||
|
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
||||||
|
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
||||||
sessionId,
|
sessionId,
|
||||||
questionId: userItem.message_id,
|
questionId: userItem.message_id,
|
||||||
userMessage,
|
userMessage,
|
||||||
|
|
@ -4776,8 +4743,6 @@ export class AssistantService {
|
||||||
followupStateUsage: followupBinding.usage,
|
followupStateUsage: followupBinding.usage,
|
||||||
followupApplied: Boolean(followupBinding.usage?.applied),
|
followupApplied: Boolean(followupBinding.usage?.applied),
|
||||||
composition,
|
composition,
|
||||||
featureContractsV11: config_1.FEATURE_ASSISTANT_CONTRACTS_V11,
|
|
||||||
featureAnswerPolicyV11: config_1.FEATURE_ASSISTANT_ANSWER_POLICY_V11,
|
|
||||||
previousInvestigationState: session.investigation_state,
|
previousInvestigationState: session.investigation_state,
|
||||||
addressRuntimeMetaForDeep,
|
addressRuntimeMetaForDeep,
|
||||||
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
extractDroppedIntentSegments: (normalizedPayload) => extractDiscardedIntentSegments(normalizedPayload),
|
||||||
|
|
@ -4785,26 +4750,16 @@ export class AssistantService {
|
||||||
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
extractExecutionState: (normalizedPayload) => extractExecutionState(normalizedPayload),
|
||||||
sanitizeReply: (value, fallback) => sanitizeOutgoingAssistantText(value, fallback),
|
sanitizeReply: (value, fallback) => sanitizeOutgoingAssistantText(value, fallback),
|
||||||
persistInvestigationState: (targetSessionId, snapshot) => this.sessions.setInvestigationState(targetSessionId, snapshot),
|
persistInvestigationState: (targetSessionId, snapshot) => this.sessions.setInvestigationState(targetSessionId, snapshot),
|
||||||
messageIdFactory: () => `msg-${(0, nanoid_1.nanoid)(10)}`
|
messageIdFactory: () => `msg-${(0, nanoid_1.nanoid)(10)}`,
|
||||||
});
|
|
||||||
const safeAssistantReply = packagingRuntime.safeAssistantReply;
|
|
||||||
const debug = packagingRuntime.debug;
|
|
||||||
const assistantItem = packagingRuntime.assistantItem;
|
|
||||||
const deepAnalysisLogDetails = packagingRuntime.deepAnalysisLogDetails;
|
|
||||||
const finalization = (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)({
|
|
||||||
sessionId,
|
|
||||||
assistantReply: safeAssistantReply,
|
|
||||||
replyType: composition.reply_type,
|
|
||||||
assistantItem,
|
|
||||||
debug,
|
|
||||||
deepAnalysisLogDetails,
|
|
||||||
appendItem: (targetSessionId, item) => this.sessions.appendItem(targetSessionId, item),
|
appendItem: (targetSessionId, item) => this.sessions.appendItem(targetSessionId, item),
|
||||||
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
|
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
|
||||||
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
|
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
|
||||||
cloneConversation: (items) => cloneItems(items),
|
cloneConversation: (items) => cloneItems(items),
|
||||||
logEvent: (payload) => (0, log_1.logJson)(payload)
|
logEvent: (payload) => (0, log_1.logJson)(payload),
|
||||||
|
runPackagingRuntime: (input) => (0, assistantDeepTurnPackagingRuntimeAdapter_1.runAssistantDeepTurnPackagingRuntime)(input),
|
||||||
|
runFinalizeDeepTurn: (input) => (0, assistantDeepTurnFinalizeRuntimeAdapter_1.finalizeAssistantDeepTurn)(input)
|
||||||
});
|
});
|
||||||
return finalization.response;
|
return deepTurnResponseRuntime.response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { runAssistantAddressToolGateRuntime } from "../src/services/assistantAddressToolGateRuntimeAdapter";
|
||||||
|
|
||||||
|
describe("assistant address tool-gate runtime adapter", () => {
|
||||||
|
it("does nothing when runAddressLane is true", async () => {
|
||||||
|
const logEvent = vi.fn();
|
||||||
|
const tryHandleLivingChat = vi.fn(async () => "chat-response");
|
||||||
|
|
||||||
|
const result = await runAssistantAddressToolGateRuntime({
|
||||||
|
sessionId: "asst-1",
|
||||||
|
userMessage: "вопрос",
|
||||||
|
addressInputMessage: "вопрос",
|
||||||
|
orchestrationDecision: { runAddressLane: true },
|
||||||
|
livingModeDecision: { mode: "chat", reason: "x" },
|
||||||
|
addressRuntimeMeta: {},
|
||||||
|
logEvent,
|
||||||
|
tryHandleLivingChat,
|
||||||
|
nowIso: () => "2026-04-10T00:00:00.000Z"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.handled).toBe(false);
|
||||||
|
expect(result.response).toBeNull();
|
||||||
|
expect(logEvent).not.toHaveBeenCalled();
|
||||||
|
expect(tryHandleLivingChat).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("logs skip and returns chat response when chat fallback handles", async () => {
|
||||||
|
const logEvent = vi.fn();
|
||||||
|
const tryHandleLivingChat = vi.fn(async () => ({ ok: true }));
|
||||||
|
|
||||||
|
const result = await runAssistantAddressToolGateRuntime({
|
||||||
|
sessionId: "asst-2",
|
||||||
|
userMessage: "вопрос",
|
||||||
|
addressInputMessage: "канон",
|
||||||
|
orchestrationDecision: { runAddressLane: false },
|
||||||
|
livingModeDecision: { mode: "chat", reason: "predecompose_unsupported_mode" },
|
||||||
|
addressRuntimeMeta: {
|
||||||
|
attempted: true,
|
||||||
|
applied: false,
|
||||||
|
reason: "normalize_failed",
|
||||||
|
predecomposeContract: {
|
||||||
|
intent: "unknown",
|
||||||
|
aggregation_profile: "unknown",
|
||||||
|
period: { scope: "unspecified" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logEvent,
|
||||||
|
tryHandleLivingChat,
|
||||||
|
nowIso: () => "2026-04-10T00:00:00.000Z"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.handled).toBe(true);
|
||||||
|
expect(result.response).toEqual({ ok: true });
|
||||||
|
expect(logEvent).toHaveBeenCalledTimes(1);
|
||||||
|
expect(tryHandleLivingChat).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("logs skip and returns unhandled when mode is not chat", async () => {
|
||||||
|
const logEvent = vi.fn();
|
||||||
|
const tryHandleLivingChat = vi.fn(async () => ({ ok: true }));
|
||||||
|
|
||||||
|
const result = await runAssistantAddressToolGateRuntime({
|
||||||
|
sessionId: "asst-3",
|
||||||
|
userMessage: "вопрос",
|
||||||
|
addressInputMessage: "канон",
|
||||||
|
orchestrationDecision: { runAddressLane: false },
|
||||||
|
livingModeDecision: { mode: "deep_analysis", reason: "strong_data_signal_detected" },
|
||||||
|
addressRuntimeMeta: {},
|
||||||
|
logEvent,
|
||||||
|
tryHandleLivingChat,
|
||||||
|
nowIso: () => "2026-04-10T00:00:00.000Z"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.handled).toBe(false);
|
||||||
|
expect(result.response).toBeNull();
|
||||||
|
expect(logEvent).toHaveBeenCalledTimes(1);
|
||||||
|
expect(tryHandleLivingChat).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { runAssistantDeepTurnAnalysisRuntime } from "../src/services/assistantDeepTurnAnalysisRuntimeAdapter";
|
||||||
|
|
||||||
|
describe("assistant deep turn analysis runtime adapter", () => {
|
||||||
|
it("orchestrates deep pipeline steps in deterministic order", async () => {
|
||||||
|
const callOrder: string[] = [];
|
||||||
|
|
||||||
|
const runContextRuntime = vi.fn(() => {
|
||||||
|
callOrder.push("context");
|
||||||
|
return {
|
||||||
|
companyAnchors: { accounts: ["60.01"] },
|
||||||
|
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: { business_scope_resolved: ["company_specific_accounting"] },
|
||||||
|
resolvedRouteSummary: { mode: "deterministic_v2", decisions: [] as any[] } as any,
|
||||||
|
liveTemporalHint: {
|
||||||
|
as_of_date: "2020-07-31",
|
||||||
|
period_from: null,
|
||||||
|
period_to: null,
|
||||||
|
source: "analysis_context"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const runExecutionPlanRuntime = vi.fn((input) => {
|
||||||
|
callOrder.push("plan");
|
||||||
|
expect(input.claimAnchorAudit.claim_type).toBe("prove_settlement_closure_state");
|
||||||
|
return {
|
||||||
|
requirementExtraction: {
|
||||||
|
requirements: [{ id: "R1" }],
|
||||||
|
byFragment: new Map<string, string[]>([["F1", ["R1"]]])
|
||||||
|
},
|
||||||
|
executionPlan: [{ fragment_id: "F1" }],
|
||||||
|
rbpRoutePlanEnforcement: { executionPlan: [{ fragment_id: "F1" }], audit: { rbp: true } },
|
||||||
|
faRoutePlanEnforcement: { executionPlan: [{ fragment_id: "F1" }], audit: { fa: true } }
|
||||||
|
} as any;
|
||||||
|
});
|
||||||
|
const runRetrievalRuntime = vi.fn(async (input) => {
|
||||||
|
callOrder.push("retrieval");
|
||||||
|
expect(input.liveTemporalHint?.as_of_date).toBe("2020-07-31");
|
||||||
|
return {
|
||||||
|
retrievalCalls: [{ fragment_id: "F1", route: "store_canonical" }],
|
||||||
|
retrievalResultsRaw: [{ fragment_id: "F1", route: "store_canonical", raw_result: {} }],
|
||||||
|
retrievalResults: [{ fragment_id: "F1", requirement_ids: ["R1"] }]
|
||||||
|
} as any;
|
||||||
|
});
|
||||||
|
const runGuardRuntime = vi.fn((input) => {
|
||||||
|
callOrder.push("guard");
|
||||||
|
expect(input.retrievalResults[0].fragment_id).toBe("F1");
|
||||||
|
return {
|
||||||
|
retrievalResults: [{ fragment_id: "F1-guarded", requirement_ids: ["R1"] }],
|
||||||
|
polarityGuardResult: { audit: { polarity: "supplier_payable" } },
|
||||||
|
targetedEvidenceResult: {
|
||||||
|
audit: {
|
||||||
|
targeted_evidence_hit_rate: 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
evidenceGateResult: {
|
||||||
|
audit: {
|
||||||
|
admissible_evidence_count: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as any;
|
||||||
|
});
|
||||||
|
const runGroundingRuntime = vi.fn((input) => {
|
||||||
|
callOrder.push("grounding");
|
||||||
|
expect(input.claimType).toBe("prove_settlement_closure_state");
|
||||||
|
expect(input.targetedEvidenceHitRate).toBe(0.5);
|
||||||
|
expect(input.businessScopeResolved).toEqual(["company_specific_accounting"]);
|
||||||
|
return {
|
||||||
|
rbpLiveRouteAudit: { routed: 1 },
|
||||||
|
faLiveRouteAudit: { routed: 1 },
|
||||||
|
coverageEvaluation: {
|
||||||
|
requirements: [{ id: "R1" }],
|
||||||
|
coverage: { requirements_total: 1, requirements_covered: 1 }
|
||||||
|
},
|
||||||
|
groundedAnswerEligibilityGuard: { eligible: true },
|
||||||
|
groundingCheck: { status: "grounded", reasons: [] }
|
||||||
|
} as any;
|
||||||
|
});
|
||||||
|
const runCompositionRuntime = vi.fn((input) => {
|
||||||
|
callOrder.push("composition");
|
||||||
|
expect(input.retrievalResults[0].fragment_id).toBe("F1-guarded");
|
||||||
|
return {
|
||||||
|
questionTypeClass: "causal_trace",
|
||||||
|
composition: { reply_type: "factual", answer: "ok" }
|
||||||
|
} as any;
|
||||||
|
});
|
||||||
|
|
||||||
|
const runtime = await runAssistantDeepTurnAnalysisRuntime({
|
||||||
|
userMessage: "where closure failed",
|
||||||
|
runContextRuntime,
|
||||||
|
runExecutionPlanRuntime,
|
||||||
|
runRetrievalRuntime,
|
||||||
|
runGuardRuntime,
|
||||||
|
runGroundingRuntime,
|
||||||
|
runCompositionRuntime
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(callOrder).toEqual(["context", "plan", "retrieval", "guard", "grounding", "composition"]);
|
||||||
|
expect(runtime.retrievalResults[0].fragment_id).toBe("F1-guarded");
|
||||||
|
expect(runtime.questionTypeClass).toBe("causal_trace");
|
||||||
|
expect(runtime.composition.reply_type).toBe("factual");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes null business scope when not resolved", async () => {
|
||||||
|
const runGroundingRuntime = vi.fn(() => ({
|
||||||
|
rbpLiveRouteAudit: {},
|
||||||
|
faLiveRouteAudit: {},
|
||||||
|
coverageEvaluation: { requirements: [], coverage: {} },
|
||||||
|
groundedAnswerEligibilityGuard: {},
|
||||||
|
groundingCheck: { status: "no_grounded_answer", reasons: [] }
|
||||||
|
}));
|
||||||
|
|
||||||
|
await runAssistantDeepTurnAnalysisRuntime({
|
||||||
|
userMessage: "question",
|
||||||
|
runContextRuntime: () =>
|
||||||
|
({
|
||||||
|
companyAnchors: {},
|
||||||
|
focusDomainForGuards: null,
|
||||||
|
temporalGuard: {},
|
||||||
|
domainPolarityGuardInitial: {},
|
||||||
|
claimAnchorAudit: { claim_type: "unknown" },
|
||||||
|
businessScopeResolution: {},
|
||||||
|
resolvedRouteSummary: null,
|
||||||
|
liveTemporalHint: null
|
||||||
|
}) as any,
|
||||||
|
runExecutionPlanRuntime: () =>
|
||||||
|
({
|
||||||
|
requirementExtraction: { requirements: [], byFragment: new Map() },
|
||||||
|
executionPlan: [],
|
||||||
|
rbpRoutePlanEnforcement: { executionPlan: [], audit: {} },
|
||||||
|
faRoutePlanEnforcement: { executionPlan: [], audit: {} }
|
||||||
|
}) as any,
|
||||||
|
runRetrievalRuntime: async () =>
|
||||||
|
({
|
||||||
|
retrievalCalls: [],
|
||||||
|
retrievalResultsRaw: [],
|
||||||
|
retrievalResults: []
|
||||||
|
}) as any,
|
||||||
|
runGuardRuntime: () =>
|
||||||
|
({
|
||||||
|
retrievalResults: [],
|
||||||
|
polarityGuardResult: { audit: {} },
|
||||||
|
targetedEvidenceResult: { audit: { targeted_evidence_hit_rate: null } },
|
||||||
|
evidenceGateResult: { audit: {} }
|
||||||
|
}) as any,
|
||||||
|
runGroundingRuntime: runGroundingRuntime as any,
|
||||||
|
runCompositionRuntime: () =>
|
||||||
|
({
|
||||||
|
questionTypeClass: "single_fact_lookup",
|
||||||
|
composition: { reply_type: "partial_coverage" }
|
||||||
|
}) as any
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(runGroundingRuntime).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
routeSummary: null,
|
||||||
|
businessScopeResolved: null
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { buildAssistantDeepTurnNormalizationRuntime } from "../src/services/assistantDeepTurnNormalizationRuntimeAdapter";
|
||||||
|
|
||||||
|
describe("assistant deep turn normalization runtime adapter", () => {
|
||||||
|
it("uses followup state binding when feature flags are enabled and state exists", async () => {
|
||||||
|
const followupBinding = {
|
||||||
|
normalizedQuestion: "normalized question",
|
||||||
|
mergedContext: {
|
||||||
|
period_hint: "2020-07",
|
||||||
|
business_context: "ctx-from-followup"
|
||||||
|
},
|
||||||
|
usage: {
|
||||||
|
applied: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const buildFollowupStateBinding = vi.fn(() => followupBinding);
|
||||||
|
const normalize = vi.fn(async (request) => ({
|
||||||
|
trace_id: "trace-1",
|
||||||
|
ok: true,
|
||||||
|
normalized: { schema_version: "normalized_query_v2_0_2" } as any,
|
||||||
|
route_hint_summary: null,
|
||||||
|
raw_model_output: {},
|
||||||
|
validation: { passed: true, errors: [] },
|
||||||
|
usage: { input_tokens: 10, output_tokens: 20, total_tokens: 30 },
|
||||||
|
latency_ms: 7,
|
||||||
|
prompt_version: String(request.promptVersion ?? ""),
|
||||||
|
schema_version: "normalized_query_v2_0_2",
|
||||||
|
request_count_for_case: 1
|
||||||
|
}));
|
||||||
|
|
||||||
|
const runtime = await buildAssistantDeepTurnNormalizationRuntime({
|
||||||
|
userMessage: "raw question",
|
||||||
|
payload: {
|
||||||
|
llmProvider: "openai",
|
||||||
|
apiKey: "k",
|
||||||
|
model: "m",
|
||||||
|
baseUrl: "https://api.example.com",
|
||||||
|
temperature: 0.2,
|
||||||
|
maxOutputTokens: 333,
|
||||||
|
promptVersion: "normalizer_v2_0_2",
|
||||||
|
systemPrompt: "sys",
|
||||||
|
developerPrompt: "dev",
|
||||||
|
domainPrompt: "dom",
|
||||||
|
fewShotExamples: "few",
|
||||||
|
context: {
|
||||||
|
period_hint: "2020-06"
|
||||||
|
},
|
||||||
|
useMock: true
|
||||||
|
},
|
||||||
|
featureInvestigationStateV1: true,
|
||||||
|
featureStateFollowupBindingV1: true,
|
||||||
|
sessionInvestigationState: {
|
||||||
|
active_domain: "settlements_60_62"
|
||||||
|
},
|
||||||
|
buildFollowupStateBinding,
|
||||||
|
normalize
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(buildFollowupStateBinding).toHaveBeenCalledTimes(1);
|
||||||
|
expect(normalize).toHaveBeenCalledTimes(1);
|
||||||
|
expect(normalize).toHaveBeenCalledWith({
|
||||||
|
llmProvider: "openai",
|
||||||
|
apiKey: "k",
|
||||||
|
model: "m",
|
||||||
|
baseUrl: "https://api.example.com",
|
||||||
|
temperature: 0.2,
|
||||||
|
maxOutputTokens: 333,
|
||||||
|
promptVersion: "normalizer_v2_0_2",
|
||||||
|
systemPrompt: "sys",
|
||||||
|
developerPrompt: "dev",
|
||||||
|
domainPrompt: "dom",
|
||||||
|
fewShotExamples: "few",
|
||||||
|
userQuestion: "normalized question",
|
||||||
|
context: {
|
||||||
|
period_hint: "2020-07",
|
||||||
|
business_context: "ctx-from-followup"
|
||||||
|
},
|
||||||
|
useMock: true
|
||||||
|
});
|
||||||
|
expect(runtime.followupBinding).toBe(followupBinding);
|
||||||
|
expect(runtime.normalizePayload.userQuestion).toBe("normalized question");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to raw user message when followup binding is disabled", async () => {
|
||||||
|
const buildFollowupStateBinding = vi.fn();
|
||||||
|
const normalize = vi.fn(async () => ({
|
||||||
|
trace_id: "trace-2",
|
||||||
|
ok: true,
|
||||||
|
normalized: { schema_version: "normalized_query_v2_0_2" } as any,
|
||||||
|
route_hint_summary: null,
|
||||||
|
raw_model_output: {},
|
||||||
|
validation: { passed: true, errors: [] },
|
||||||
|
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
|
||||||
|
latency_ms: 1,
|
||||||
|
prompt_version: "address_query_runtime_v1",
|
||||||
|
schema_version: "normalized_query_v2_0_2",
|
||||||
|
request_count_for_case: 1
|
||||||
|
}));
|
||||||
|
|
||||||
|
const runtime = await buildAssistantDeepTurnNormalizationRuntime({
|
||||||
|
userMessage: "raw fallback",
|
||||||
|
payload: {
|
||||||
|
llmProvider: "openai",
|
||||||
|
context: {
|
||||||
|
business_context: "payload-context"
|
||||||
|
},
|
||||||
|
useMock: undefined
|
||||||
|
},
|
||||||
|
featureInvestigationStateV1: false,
|
||||||
|
featureStateFollowupBindingV1: true,
|
||||||
|
sessionInvestigationState: {
|
||||||
|
some: "state"
|
||||||
|
},
|
||||||
|
buildFollowupStateBinding,
|
||||||
|
normalize
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(buildFollowupStateBinding).not.toHaveBeenCalled();
|
||||||
|
expect(normalize).toHaveBeenCalledWith({
|
||||||
|
llmProvider: "openai",
|
||||||
|
apiKey: undefined,
|
||||||
|
model: undefined,
|
||||||
|
baseUrl: undefined,
|
||||||
|
temperature: undefined,
|
||||||
|
maxOutputTokens: undefined,
|
||||||
|
promptVersion: "address_query_runtime_v1",
|
||||||
|
systemPrompt: undefined,
|
||||||
|
developerPrompt: undefined,
|
||||||
|
domainPrompt: undefined,
|
||||||
|
fewShotExamples: undefined,
|
||||||
|
userQuestion: "raw fallback",
|
||||||
|
context: {
|
||||||
|
business_context: "payload-context"
|
||||||
|
},
|
||||||
|
useMock: false
|
||||||
|
});
|
||||||
|
expect(runtime.followupBinding).toEqual({
|
||||||
|
normalizedQuestion: "raw fallback",
|
||||||
|
mergedContext: {
|
||||||
|
business_context: "payload-context"
|
||||||
|
},
|
||||||
|
usage: null
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { runAssistantDeepTurnResponseRuntime } from "../src/services/assistantDeepTurnResponseRuntimeAdapter";
|
||||||
|
|
||||||
|
function buildBaseInput(overrides: Record<string, unknown> = {}) {
|
||||||
|
return {
|
||||||
|
featureInvestigationStateV1: true,
|
||||||
|
featureContractsV11: true,
|
||||||
|
featureAnswerPolicyV11: true,
|
||||||
|
sessionId: "asst-1",
|
||||||
|
questionId: "msg-q1",
|
||||||
|
userMessage: "question",
|
||||||
|
normalized: {
|
||||||
|
trace_id: "trace-1",
|
||||||
|
prompt_version: "normalizer_v2_0_2",
|
||||||
|
schema_version: "normalized_query_v2_0_2",
|
||||||
|
normalized: { schema_version: "normalized_query_v2_0_2" }
|
||||||
|
},
|
||||||
|
normalizedQuestion: "normalized-question",
|
||||||
|
routeSummary: { mode: "deterministic_v2", decisions: [] as any[] },
|
||||||
|
executionPlan: [],
|
||||||
|
requirementExtractionRequirements: [],
|
||||||
|
coverageEvaluationRequirements: [],
|
||||||
|
coverageReport: {},
|
||||||
|
groundingCheck: { status: "no_grounded_answer", reasons: [] },
|
||||||
|
retrievalCalls: [],
|
||||||
|
retrievalResultsRaw: [],
|
||||||
|
retrievalResults: [],
|
||||||
|
questionTypeClass: "single_fact_lookup",
|
||||||
|
companyAnchors: {},
|
||||||
|
runtimeAnalysisContext: {},
|
||||||
|
businessScopeResolution: {},
|
||||||
|
temporalGuard: {},
|
||||||
|
polarityAudit: {},
|
||||||
|
claimAnchorAudit: {},
|
||||||
|
targetedEvidenceAudit: {},
|
||||||
|
evidenceAdmissibilityGateAudit: {},
|
||||||
|
rbpLiveRouteAudit: {},
|
||||||
|
faLiveRouteAudit: {},
|
||||||
|
groundedAnswerEligibilityGuard: {},
|
||||||
|
followupStateUsage: null,
|
||||||
|
followupApplied: false,
|
||||||
|
composition: {
|
||||||
|
reply_type: "factual",
|
||||||
|
assistant_reply: "assistant answer"
|
||||||
|
},
|
||||||
|
previousInvestigationState: null,
|
||||||
|
addressRuntimeMetaForDeep: null,
|
||||||
|
extractDroppedIntentSegments: () => [],
|
||||||
|
buildDebugRoutes: () => [],
|
||||||
|
extractExecutionState: () => [],
|
||||||
|
sanitizeReply: (value: string) => value,
|
||||||
|
persistInvestigationState: () => {},
|
||||||
|
messageIdFactory: () => "msg-a1",
|
||||||
|
appendItem: () => {},
|
||||||
|
getSession: () => ({ session_id: "asst-1", items: [] }),
|
||||||
|
persistSession: () => {},
|
||||||
|
cloneConversation: () => [],
|
||||||
|
logEvent: () => {},
|
||||||
|
...overrides
|
||||||
|
} as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("assistant deep turn response runtime adapter", () => {
|
||||||
|
it("wires packaging output into deep finalization", () => {
|
||||||
|
const runPackagingRuntime = vi.fn(() => ({
|
||||||
|
messageId: "msg-a1",
|
||||||
|
investigationStateSnapshot: null,
|
||||||
|
droppedIntentSegments: [],
|
||||||
|
analysisContextForContract: null,
|
||||||
|
routesForDebug: [],
|
||||||
|
resolvedExecutionState: [],
|
||||||
|
safeAssistantReplyBase: "base",
|
||||||
|
safeAssistantReply: "safe-reply",
|
||||||
|
debug: { trace_id: "trace-1" },
|
||||||
|
assistantItem: {
|
||||||
|
message_id: "msg-a1",
|
||||||
|
session_id: "asst-1",
|
||||||
|
role: "assistant",
|
||||||
|
text: "safe-reply",
|
||||||
|
reply_type: "factual",
|
||||||
|
created_at: "2026-04-10T00:00:00.000Z",
|
||||||
|
trace_id: "trace-1",
|
||||||
|
debug: null
|
||||||
|
},
|
||||||
|
deepAnalysisLogDetails: { info: "ok" }
|
||||||
|
}));
|
||||||
|
const responsePayload = {
|
||||||
|
ok: true,
|
||||||
|
session_id: "asst-1",
|
||||||
|
conversation: [],
|
||||||
|
debug: { trace_id: "trace-1" }
|
||||||
|
};
|
||||||
|
const runFinalizeDeepTurn = vi.fn(() => ({
|
||||||
|
response: responsePayload
|
||||||
|
}));
|
||||||
|
|
||||||
|
const runtime = runAssistantDeepTurnResponseRuntime(
|
||||||
|
buildBaseInput({
|
||||||
|
runPackagingRuntime,
|
||||||
|
runFinalizeDeepTurn
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runPackagingRuntime).toHaveBeenCalledTimes(1);
|
||||||
|
expect(runFinalizeDeepTurn).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
sessionId: "asst-1",
|
||||||
|
assistantReply: "safe-reply",
|
||||||
|
replyType: "factual"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(runtime.response).toEqual(responsePayload);
|
||||||
|
expect(runtime.debug).toEqual({ trace_id: "trace-1" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes feature flags and followup flags into packaging stage", () => {
|
||||||
|
const runPackagingRuntime = vi.fn(() => ({
|
||||||
|
messageId: "msg-a1",
|
||||||
|
investigationStateSnapshot: null,
|
||||||
|
droppedIntentSegments: [],
|
||||||
|
analysisContextForContract: null,
|
||||||
|
routesForDebug: [],
|
||||||
|
resolvedExecutionState: [],
|
||||||
|
safeAssistantReplyBase: "base",
|
||||||
|
safeAssistantReply: "safe-reply",
|
||||||
|
debug: {},
|
||||||
|
assistantItem: {
|
||||||
|
message_id: "msg-a1",
|
||||||
|
session_id: "asst-1",
|
||||||
|
role: "assistant",
|
||||||
|
text: "safe-reply",
|
||||||
|
reply_type: "factual",
|
||||||
|
created_at: "2026-04-10T00:00:00.000Z",
|
||||||
|
trace_id: "trace-1",
|
||||||
|
debug: null
|
||||||
|
},
|
||||||
|
deepAnalysisLogDetails: {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
runAssistantDeepTurnResponseRuntime(
|
||||||
|
buildBaseInput({
|
||||||
|
featureInvestigationStateV1: false,
|
||||||
|
followupApplied: true,
|
||||||
|
runPackagingRuntime,
|
||||||
|
runFinalizeDeepTurn: () => ({
|
||||||
|
response: {
|
||||||
|
ok: true,
|
||||||
|
session_id: "asst-1",
|
||||||
|
conversation: [],
|
||||||
|
debug: null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runPackagingRuntime).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
featureInvestigationStateV1: false,
|
||||||
|
followupApplied: true
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -171,11 +171,11 @@
|
||||||
"comment": "вопрос не отрабатываем но нужно обратить внимание что ассистент выдал список активности - то есть не понял контекст и дал совершенновне контекста выдачу",
|
"comment": "вопрос не отрабатываем но нужно обратить внимание что ассистент выдал список активности - то есть не понял контекст и дал совершенновне контекста выдачу",
|
||||||
"manual_case_decision": "out_of_scope_but_answer_softly",
|
"manual_case_decision": "out_of_scope_but_answer_softly",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:28:38.335Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:11:53.544Z",
|
"created_at": "2026-04-10T09:11:53.544Z",
|
||||||
"updated_at": "2026-04-10T09:11:53.544Z",
|
"updated_at": "2026-04-10T17:28:38.335Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-RDpaUn4py2",
|
"message_id": "msg-RDpaUn4py2",
|
||||||
"trace_id": "address-pQYUVty09a",
|
"trace_id": "address-pQYUVty09a",
|
||||||
|
|
@ -225,11 +225,11 @@
|
||||||
"comment": "мы разве не можем прокинуть маршрут по не закрытиым авансам на актами на дату рассмотрения???",
|
"comment": "мы разве не можем прокинуть маршрут по не закрытиым авансам на актами на дату рассмотрения???",
|
||||||
"manual_case_decision": "needs_routing_extension",
|
"manual_case_decision": "needs_routing_extension",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:28:00.389Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:14:16.180Z",
|
"created_at": "2026-04-10T09:14:16.180Z",
|
||||||
"updated_at": "2026-04-10T09:14:16.180Z",
|
"updated_at": "2026-04-10T17:28:00.389Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-XjaJdWuftN",
|
"message_id": "msg-XjaJdWuftN",
|
||||||
"trace_id": "address-m9ZE6DBr7R",
|
"trace_id": "address-m9ZE6DBr7R",
|
||||||
|
|
@ -252,11 +252,11 @@
|
||||||
"comment": "вопрос не актуален",
|
"comment": "вопрос не актуален",
|
||||||
"manual_case_decision": "out_of_scope_but_answer_softly",
|
"manual_case_decision": "out_of_scope_but_answer_softly",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:27:36.886Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:14:39.227Z",
|
"created_at": "2026-04-10T09:14:39.227Z",
|
||||||
"updated_at": "2026-04-10T09:14:39.227Z",
|
"updated_at": "2026-04-10T17:27:36.886Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-6N2xTrZA3p",
|
"message_id": "msg-6N2xTrZA3p",
|
||||||
"trace_id": "address-XQrnJFW_v1",
|
"trace_id": "address-XQrnJFW_v1",
|
||||||
|
|
@ -306,11 +306,11 @@
|
||||||
"comment": "тут надо вывести самых доходном контр агентов - мы уже это умееем но запрос распознался не правильно? где наша ллс констекстная аналитика? тут явно сильныо торчащий контекст",
|
"comment": "тут надо вывести самых доходном контр агентов - мы уже это умееем но запрос распознался не правильно? где наша ллс констекстная аналитика? тут явно сильныо торчащий контекст",
|
||||||
"manual_case_decision": "covered_but_bad_answer",
|
"manual_case_decision": "covered_but_bad_answer",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:26:51.525Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:17:19.668Z",
|
"created_at": "2026-04-10T09:17:19.668Z",
|
||||||
"updated_at": "2026-04-10T09:17:19.668Z",
|
"updated_at": "2026-04-10T17:26:51.525Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-7Fi7216TqF",
|
"message_id": "msg-7Fi7216TqF",
|
||||||
"trace_id": "address-pL6IUlwjAP",
|
"trace_id": "address-pL6IUlwjAP",
|
||||||
|
|
@ -360,11 +360,11 @@
|
||||||
"comment": "какой еще инн? юзер задает максимально конкретыный вопрос. типа авансы закрыты дибо не закрыты - нужна конкретная адресная проверка по базе 1с",
|
"comment": "какой еще инн? юзер задает максимально конкретыный вопрос. типа авансы закрыты дибо не закрыты - нужна конкретная адресная проверка по базе 1с",
|
||||||
"manual_case_decision": "needs_routing_extension",
|
"manual_case_decision": "needs_routing_extension",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:26:16.682Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:19:30.315Z",
|
"created_at": "2026-04-10T09:19:30.315Z",
|
||||||
"updated_at": "2026-04-10T09:19:30.315Z",
|
"updated_at": "2026-04-10T17:26:16.682Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-qyrc6Jek0h",
|
"message_id": "msg-qyrc6Jek0h",
|
||||||
"trace_id": "address-K97ICzNyLf",
|
"trace_id": "address-K97ICzNyLf",
|
||||||
|
|
@ -387,11 +387,11 @@
|
||||||
"comment": "не отрабатываем - почему выскачела техничка???? нужен мягкий отказ",
|
"comment": "не отрабатываем - почему выскачела техничка???? нужен мягкий отказ",
|
||||||
"manual_case_decision": "out_of_scope_but_answer_softly",
|
"manual_case_decision": "out_of_scope_but_answer_softly",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:25:55.103Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:19:59.184Z",
|
"created_at": "2026-04-10T09:19:59.184Z",
|
||||||
"updated_at": "2026-04-10T09:20:29.316Z",
|
"updated_at": "2026-04-10T17:25:55.103Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-2BXINs6O5A",
|
"message_id": "msg-2BXINs6O5A",
|
||||||
"trace_id": "iUWtcr5ZfOqMvU",
|
"trace_id": "iUWtcr5ZfOqMvU",
|
||||||
|
|
@ -441,11 +441,11 @@
|
||||||
"comment": "нельзя вообще даваать такие ответы - нужно технически отработать этот марштрут",
|
"comment": "нельзя вообще даваать такие ответы - нужно технически отработать этот марштрут",
|
||||||
"manual_case_decision": "candidate_for_implementation",
|
"manual_case_decision": "candidate_for_implementation",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:24:56.029Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:23:01.330Z",
|
"created_at": "2026-04-10T09:23:01.330Z",
|
||||||
"updated_at": "2026-04-10T09:23:01.330Z",
|
"updated_at": "2026-04-10T17:24:56.029Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-CBXmhYfjcw",
|
"message_id": "msg-CBXmhYfjcw",
|
||||||
"trace_id": "XHuO-nGyt2K1Sc",
|
"trace_id": "XHuO-nGyt2K1Sc",
|
||||||
|
|
@ -495,11 +495,11 @@
|
||||||
"comment": "мы точно отработали этот кейс маршрутом - схуя он опять упал в шаблонный ответ - мы уже точно умеем выводить топ по даходам и суммам контрактов",
|
"comment": "мы точно отработали этот кейс маршрутом - схуя он опять упал в шаблонный ответ - мы уже точно умеем выводить топ по даходам и суммам контрактов",
|
||||||
"manual_case_decision": "covered_but_bad_answer",
|
"manual_case_decision": "covered_but_bad_answer",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:25:11.918Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:26:31.131Z",
|
"created_at": "2026-04-10T09:26:31.131Z",
|
||||||
"updated_at": "2026-04-10T09:26:31.131Z",
|
"updated_at": "2026-04-10T17:25:11.918Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-WmJg1Kp0tt",
|
"message_id": "msg-WmJg1Kp0tt",
|
||||||
"trace_id": "address-jDze8Tv0JS",
|
"trace_id": "address-jDze8Tv0JS",
|
||||||
|
|
@ -549,11 +549,11 @@
|
||||||
"comment": "почему показаны актиные заказчики? вопрос был про не закрытые актими и приходами денег договора на момент рассмотрения",
|
"comment": "почему показаны актиные заказчики? вопрос был про не закрытые актими и приходами денег договора на момент рассмотрения",
|
||||||
"manual_case_decision": "covered_but_bad_answer",
|
"manual_case_decision": "covered_but_bad_answer",
|
||||||
"annotation_author": "manual_reviewer",
|
"annotation_author": "manual_reviewer",
|
||||||
"resolved": false,
|
"resolved": true,
|
||||||
"resolved_at": null,
|
"resolved_at": "2026-04-10T17:28:51.491Z",
|
||||||
"resolved_by": null,
|
"resolved_by": "manual_reviewer",
|
||||||
"created_at": "2026-04-10T09:29:32.681Z",
|
"created_at": "2026-04-10T09:29:32.681Z",
|
||||||
"updated_at": "2026-04-10T09:29:32.681Z",
|
"updated_at": "2026-04-10T17:28:51.491Z",
|
||||||
"context": {
|
"context": {
|
||||||
"message_id": "msg-XsyFjMyJS2",
|
"message_id": "msg-XsyFjMyJS2",
|
||||||
"trace_id": "address-xexv2UQ5mP",
|
"trace_id": "address-xexv2UQ5mP",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue