ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.34 вынос address-ветку (orchestration + lane + finalize) в единый runtime-оркестратор, чтобы handleMessage стал почти плоским.

This commit is contained in:
2026-04-10 22:26:05 +03:00
parent 353cbc1763
commit 9c22460e8b
9 changed files with 869 additions and 185 deletions
@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAssistantAddressLaneResponseRuntime = runAssistantAddressLaneResponseRuntime;
const assistantAddressTurnFinalizeRuntimeAdapter_1 = require("./assistantAddressTurnFinalizeRuntimeAdapter");
function runAssistantAddressLaneResponseRuntime(input) {
const finalizeAddressTurnSafe = input.finalizeAddressTurn ?? assistantAddressTurnFinalizeRuntimeAdapter_1.finalizeAssistantAddressTurn;
const safeAddressReply = input.sanitizeOutgoingAssistantText(input.addressLane.reply_text);
const debug = input.buildAddressDebugPayload(input.addressLane.debug, input.llmPreDecomposeMeta);
const followupOffer = input.buildAddressFollowupOffer(debug);
if (followupOffer) {
debug.address_followup_offer = followupOffer;
}
const debugKnownOrganizations = input.mergeKnownOrganizations(input.knownOrganizations);
const debugFilters = debug?.extracted_filters && typeof debug.extracted_filters === "object"
? debug.extracted_filters
: null;
const debugActiveOrganization = input.toNonEmptyString(debugFilters?.organization) ??
input.toNonEmptyString(input.activeOrganization);
if (debugKnownOrganizations.length > 0) {
debug.assistant_known_organizations = debugKnownOrganizations;
}
if (debugActiveOrganization) {
debug.assistant_active_organization = debugActiveOrganization;
}
const finalization = finalizeAddressTurnSafe({
sessionId: input.sessionId,
userMessage: input.userMessage,
effectiveAddressUserMessage: input.effectiveAddressUserMessage,
assistantReply: safeAddressReply,
replyType: input.addressLane.reply_type,
addressLaneDebug: (input.addressLane.debug ?? null),
debug,
carryoverMeta: (input.carryoverMeta ?? null),
llmPreDecomposeMeta: (input.llmPreDecomposeMeta ?? null),
appendItem: input.appendItem,
getSession: input.getSession,
persistSession: input.persistSession,
cloneConversation: input.cloneConversation,
logEvent: input.logEvent,
messageIdFactory: input.messageIdFactory
});
return {
response: finalization.response,
debug
};
}
@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAssistantAddressRuntime = runAssistantAddressRuntime;
const assistantAddressOrchestrationRuntimeAdapter_1 = require("./assistantAddressOrchestrationRuntimeAdapter");
const assistantAddressLaneRuntimeAdapter_1 = require("./assistantAddressLaneRuntimeAdapter");
const assistantAddressToolGateRuntimeAdapter_1 = require("./assistantAddressToolGateRuntimeAdapter");
async function runAssistantAddressRuntime(input) {
if (!input.featureAssistantAddressQueryV1) {
return {
handled: false,
response: null,
addressRuntimeMetaForDeep: null
};
}
const runAddressOrchestrationRuntimeSafe = input.runAddressOrchestrationRuntime ?? assistantAddressOrchestrationRuntimeAdapter_1.buildAssistantAddressOrchestrationRuntime;
const runAddressToolGateRuntimeSafe = input.runAddressToolGateRuntime ?? assistantAddressToolGateRuntimeAdapter_1.runAssistantAddressToolGateRuntime;
const runAddressLaneRuntimeSafe = input.runAddressLaneRuntime ?? assistantAddressLaneRuntimeAdapter_1.runAssistantAddressLaneRuntime;
const addressOrchestrationRuntime = await runAddressOrchestrationRuntimeSafe({
userMessage: input.userMessage,
sessionItems: input.sessionItems,
llmProvider: input.llmProvider,
useMock: input.useMock,
featureAddressLlmPredecomposeV1: input.featureAddressLlmPredecomposeV1,
runAddressLlmPreDecompose: input.runAddressLlmPreDecompose,
buildAddressLlmPredecomposeContractV1: input.buildAddressLlmPredecomposeContractV1,
sanitizeAddressMessageForFallback: input.sanitizeAddressMessageForFallback,
toNonEmptyString: input.toNonEmptyString,
resolveAddressFollowupCarryoverContext: input.resolveAddressFollowupCarryoverContext,
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision,
buildAddressDialogContinuationContractV2: input.buildAddressDialogContinuationContractV2
});
const addressInputMessage = addressOrchestrationRuntime.addressInputMessage;
const carryover = addressOrchestrationRuntime.carryover;
const orchestrationDecision = addressOrchestrationRuntime.orchestrationDecision;
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
const addressRuntimeMetaForDeep = addressRuntimeMeta;
const toolGateRuntime = await runAddressToolGateRuntimeSafe({
sessionId: input.sessionId,
userMessage: input.userMessage,
addressInputMessage,
orchestrationDecision,
livingModeDecision,
addressRuntimeMeta,
logEvent: input.logEvent,
tryHandleLivingChat: input.tryHandleLivingChat,
nowIso: input.nowIso
});
if (toolGateRuntime.handled && toolGateRuntime.response) {
return {
handled: true,
response: toolGateRuntime.response,
addressRuntimeMetaForDeep
};
}
if (Boolean(orchestrationDecision.runAddressLane)) {
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
const analysisDateHint = input.runtimeAnalysisContextAsOfDate ?? input.toNonEmptyString(input.payloadContextPeriodHint);
const canRetryWithRawUserMessage = input.compactWhitespace(String(addressInputMessage ?? "").toLowerCase()) !==
input.compactWhitespace(String(input.userMessage ?? "").toLowerCase());
const addressLaneRuntime = await runAddressLaneRuntimeSafe({
userMessage: input.userMessage,
addressInputMessage,
carryover,
shouldPreferContextualLane,
canRetryWithRawUserMessage,
runAddressLaneAttempt: (messageUsed, carryMeta) => input.runAddressLaneAttempt(messageUsed, carryMeta, analysisDateHint),
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult
});
if (addressLaneRuntime.handled && addressLaneRuntime.selection) {
const response = input.finalizeAddressLaneResponse(addressLaneRuntime.selection.addressLane, addressLaneRuntime.selection.messageUsed, addressLaneRuntime.selection.carryMeta, {
...addressRuntimeMeta,
addressRetryAudit: { ...addressLaneRuntime.retryAudit }
});
return {
handled: true,
response,
addressRuntimeMetaForDeep
};
}
}
return {
handled: false,
response: null,
addressRuntimeMetaForDeep
};
}
+50 -92
View File
@@ -65,7 +65,7 @@ const openaiResponsesClient_1 = __importStar(require("./openaiResponsesClient"))
const addressMcpClient_1 = __importStar(require("./addressMcpClient"));
const capabilitiesRegistry_1 = __importStar(require("./capabilitiesRegistry"));
const assistantCanon_1 = __importStar(require("./assistantCanon"));
const assistantAddressTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantAddressTurnFinalizeRuntimeAdapter"));
const assistantAddressLaneResponseRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneResponseRuntimeAdapter"));
const assistantCoverageGrounding_1 = __importStar(require("./assistantCoverageGrounding"));
const assistantDeepTurnAnalysisRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnAnalysisRuntimeAdapter"));
const assistantDeepTurnCompositionRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnCompositionRuntimeAdapter"));
@@ -78,9 +78,7 @@ const assistantDeepTurnPlanRuntimeAdapter_1 = __importStar(require("./assistantD
const assistantDeepTurnNormalizationRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnNormalizationRuntimeAdapter"));
const assistantDeepTurnResponseRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnResponseRuntimeAdapter"));
const assistantDeepTurnRetrievalRuntimeAdapter_1 = __importStar(require("./assistantDeepTurnRetrievalRuntimeAdapter"));
const assistantAddressLaneRuntimeAdapter_1 = __importStar(require("./assistantAddressLaneRuntimeAdapter"));
const assistantAddressOrchestrationRuntimeAdapter_1 = __importStar(require("./assistantAddressOrchestrationRuntimeAdapter"));
const assistantAddressToolGateRuntimeAdapter_1 = __importStar(require("./assistantAddressToolGateRuntimeAdapter"));
const assistantAddressRuntimeAdapter_1 = __importStar(require("./assistantAddressRuntimeAdapter"));
const assistantLivingChatTurnFinalizeRuntimeAdapter_1 = __importStar(require("./assistantLivingChatTurnFinalizeRuntimeAdapter"));
const assistantLivingChatRuntimeAdapter_1 = __importStar(require("./assistantLivingChatRuntimeAdapter"));
const assistantQueryPlanning_1 = __importStar(require("./assistantQueryPlanning"));
@@ -4432,31 +4430,20 @@ class AssistantService {
}
const sessionOrganizationScope = resolveSessionOrganizationScopeContext(userMessage, session.items);
const finalizeAddressLaneResponse = (addressLane, effectiveAddressUserMessage, carryoverMeta = null, llmPreDecomposeMeta = null) => {
const safeAddressReply = sanitizeOutgoingAssistantText(addressLane.reply_text);
const debug = buildAddressDebugPayload(addressLane.debug, llmPreDecomposeMeta);
const followupOffer = buildAddressFollowupOffer(debug);
if (followupOffer) {
debug.address_followup_offer = followupOffer;
}
const debugKnownOrganizations = mergeKnownOrganizations(sessionOrganizationScope.knownOrganizations);
const debugActiveOrganization = toNonEmptyString(debug?.extracted_filters?.organization) ??
toNonEmptyString(sessionOrganizationScope.activeOrganization);
if (debugKnownOrganizations.length > 0) {
debug.assistant_known_organizations = debugKnownOrganizations;
}
if (debugActiveOrganization) {
debug.assistant_active_organization = debugActiveOrganization;
}
const finalization = (0, assistantAddressTurnFinalizeRuntimeAdapter_1.finalizeAssistantAddressTurn)({
const runtime = (0, assistantAddressLaneResponseRuntimeAdapter_1.runAssistantAddressLaneResponseRuntime)({
sessionId,
userMessage,
effectiveAddressUserMessage,
assistantReply: safeAddressReply,
replyType: addressLane.reply_type,
addressLaneDebug: addressLane.debug,
debug,
addressLane,
carryoverMeta,
llmPreDecomposeMeta,
knownOrganizations: sessionOrganizationScope.knownOrganizations,
activeOrganization: sessionOrganizationScope.activeOrganization,
sanitizeOutgoingAssistantText,
buildAddressDebugPayload,
buildAddressFollowupOffer,
mergeKnownOrganizations,
toNonEmptyString,
appendItem: (targetSessionId, item) => this.sessions.appendItem(targetSessionId, item),
getSession: (targetSessionId) => this.sessions.getSession(targetSessionId),
persistSession: (sessionState) => this.sessionLogger.persistSession(sessionState),
@@ -4464,7 +4451,7 @@ class AssistantService {
logEvent: (payload) => (0, log_1.logJson)(payload),
messageIdFactory: () => `msg-${(0, nanoid_1.nanoid)(10)}`
});
return finalization.response;
return runtime.response;
};
const tryHandleLivingChat = async (modeDecision, addressRuntimeMeta = null) => {
try {
@@ -4565,75 +4552,46 @@ class AssistantService {
}
};
let addressRuntimeMetaForDeep = null;
if (config_1.FEATURE_ASSISTANT_ADDRESS_QUERY_V1) {
const addressOrchestrationRuntime = await (0, assistantAddressOrchestrationRuntimeAdapter_1.buildAssistantAddressOrchestrationRuntime)({
userMessage,
sessionItems: session.items,
llmProvider: payload?.llmProvider,
useMock: Boolean(payload.useMock),
featureAddressLlmPredecomposeV1: config_1.FEATURE_ASSISTANT_ADDRESS_QUERY_LLM_PREDECOMPOSE_V1,
runAddressLlmPreDecompose: async () => runAddressLlmPreDecompose(this.normalizerService, payload, userMessage),
buildAddressLlmPredecomposeContractV1: predecomposeContract_1.buildAddressLlmPredecomposeContractV1,
sanitizeAddressMessageForFallback,
toNonEmptyString,
resolveAddressFollowupCarryoverContext,
resolveAssistantOrchestrationDecision,
buildAddressDialogContinuationContractV2
});
const addressPreDecompose = addressOrchestrationRuntime.addressPreDecompose;
const addressInputMessage = addressOrchestrationRuntime.addressInputMessage;
const carryover = addressOrchestrationRuntime.carryover;
const orchestrationDecision = addressOrchestrationRuntime.orchestrationDecision;
const addressRuntimeMeta = addressOrchestrationRuntime.addressRuntimeMeta;
addressRuntimeMetaForDeep = addressRuntimeMeta;
const livingModeDecision = addressOrchestrationRuntime.livingModeDecision;
const toolGateRuntime = await (0, assistantAddressToolGateRuntimeAdapter_1.runAssistantAddressToolGateRuntime)({
sessionId,
userMessage,
addressInputMessage,
orchestrationDecision,
livingModeDecision,
addressRuntimeMeta,
logEvent: (payload) => (0, log_1.logJson)(payload),
tryHandleLivingChat: (modeDecision, runtimeMeta) => tryHandleLivingChat(modeDecision, runtimeMeta),
nowIso: () => new Date().toISOString()
});
if (toolGateRuntime.handled && toolGateRuntime.response) {
return toolGateRuntime.response;
}
if (orchestrationDecision.runAddressLane) {
const shouldPreferContextualLane = Boolean(carryover?.followupContext);
const analysisDateHint = runtimeAnalysisContext.as_of_date ?? toNonEmptyString(payload?.context?.period_hint);
const canRetryWithRawUserMessage = compactWhitespace(String(addressInputMessage ?? "").toLowerCase()) !==
compactWhitespace(String(userMessage ?? "").toLowerCase());
const runAddressLaneAttempt = async (messageUsed, carryMeta) => {
const scopedFollowupContext = mergeFollowupContextWithOrganizationScope(carryMeta?.followupContext ?? null, sessionOrganizationScope.activeOrganization);
if (scopedFollowupContext) {
return this.addressQueryService.tryHandle(messageUsed, {
followupContext: scopedFollowupContext,
analysisDateHint
});
}
return this.addressQueryService.tryHandle(messageUsed, {
analysisDateHint
});
};
const addressLaneRuntime = await (0, assistantAddressLaneRuntimeAdapter_1.runAssistantAddressLaneRuntime)({
userMessage,
addressInputMessage,
carryover,
shouldPreferContextualLane,
canRetryWithRawUserMessage,
runAddressLaneAttempt,
isRetryableAddressLimitedResult
const runAddressLaneAttempt = async (messageUsed, carryMeta, analysisDateHint) => {
const scopedFollowupContext = mergeFollowupContextWithOrganizationScope(carryMeta?.followupContext ?? null, sessionOrganizationScope.activeOrganization);
if (scopedFollowupContext) {
return this.addressQueryService.tryHandle(messageUsed, {
followupContext: scopedFollowupContext,
analysisDateHint
});
if (addressLaneRuntime.handled && addressLaneRuntime.selection) {
return finalizeAddressLaneResponse(addressLaneRuntime.selection.addressLane, addressLaneRuntime.selection.messageUsed, addressLaneRuntime.selection.carryMeta, {
...addressRuntimeMeta,
addressRetryAudit: { ...addressLaneRuntime.retryAudit }
});
}
}
return this.addressQueryService.tryHandle(messageUsed, {
analysisDateHint
});
};
const addressRuntime = await (0, assistantAddressRuntimeAdapter_1.runAssistantAddressRuntime)({
featureAssistantAddressQueryV1: config_1.FEATURE_ASSISTANT_ADDRESS_QUERY_V1,
sessionId,
userMessage,
sessionItems: session.items,
llmProvider: payload?.llmProvider,
useMock: Boolean(payload.useMock),
featureAddressLlmPredecomposeV1: config_1.FEATURE_ASSISTANT_ADDRESS_QUERY_LLM_PREDECOMPOSE_V1,
runAddressLlmPreDecompose: async () => runAddressLlmPreDecompose(this.normalizerService, payload, userMessage),
buildAddressLlmPredecomposeContractV1: predecomposeContract_1.buildAddressLlmPredecomposeContractV1,
sanitizeAddressMessageForFallback,
toNonEmptyString,
resolveAddressFollowupCarryoverContext,
resolveAssistantOrchestrationDecision,
buildAddressDialogContinuationContractV2,
runtimeAnalysisContextAsOfDate: runtimeAnalysisContext.as_of_date,
payloadContextPeriodHint: payload?.context?.period_hint,
compactWhitespace,
runAddressLaneAttempt,
isRetryableAddressLimitedResult,
finalizeAddressLaneResponse,
tryHandleLivingChat: (modeDecision, runtimeMeta) => tryHandleLivingChat(modeDecision, runtimeMeta),
logEvent: (payload) => (0, log_1.logJson)(payload),
nowIso: () => new Date().toISOString()
});
addressRuntimeMetaForDeep = addressRuntime.addressRuntimeMetaForDeep;
if (addressRuntime.handled && addressRuntime.response) {
return addressRuntime.response;
}
const normalizationRuntime = await (0, assistantDeepTurnNormalizationRuntimeAdapter_1.buildAssistantDeepTurnNormalizationRuntime)({
userMessage,