ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 2.522.55 - Перевод finalizeAddressLaneResponse на builder вместо inline-сборки в assistantAddressAttemptRuntimeAdapter.ts \ Добавлен builder для lane-attempt input: assistantAddressLaneAttemptInputBuilder.ts. \ Добавлен builder для финального address-runtime input: assistantAddressRuntimeInputBuilder.ts.
This commit is contained in:
parent
b612615219
commit
c849eb5f5b
|
|
@ -1645,7 +1645,51 @@ Validation:
|
||||||
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
- `assistantLivingChatMode.test.ts`
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
|
||||||
Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 + 2.30 + 2.31 + 2.32 + 2.33 + 2.34 + 2.35 + 2.36 + 2.37 + 2.38 + 2.39 + 2.40 + 2.41 + 2.42 + 2.43 + 2.44 + 2.45 + 2.46 + 2.47 + 2.48 + 2.49 + 2.50 + 2.51 completed)**
|
Implemented in current pass (Phase 2.52 + 2.53 + 2.54 + 2.55):
|
||||||
|
1. Removed remaining inline address-lane response input assembly from `assistantAddressAttemptRuntimeAdapter`:
|
||||||
|
- rewired `finalizeAddressLaneResponse` to `buildAssistantAddressLaneResponseAttemptRuntimeInput(...)`.
|
||||||
|
2. Added dedicated lane-attempt input builder and rewired adapter call-site:
|
||||||
|
- `assistantAddressLaneAttemptInputBuilder.ts`
|
||||||
|
- introduced:
|
||||||
|
- `buildAssistantAddressLaneAttemptRuntimeInput(...)`
|
||||||
|
3. Added dedicated address-runtime input builder and rewired final runtime invocation:
|
||||||
|
- `assistantAddressRuntimeInputBuilder.ts`
|
||||||
|
- introduced:
|
||||||
|
- `buildAssistantAddressRuntimeInput(...)`
|
||||||
|
4. Added focused builder tests:
|
||||||
|
- `assistantAddressLaneResponseAttemptInputBuilder.test.ts`
|
||||||
|
- `assistantAddressLaneAttemptInputBuilder.test.ts`
|
||||||
|
- `assistantAddressRuntimeInputBuilder.test.ts`
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
1. `npm run build` passed.
|
||||||
|
2. Targeted living/address/deep followup pack passed:
|
||||||
|
- `assistantAddressLaneResponseAttemptInputBuilder.test.ts`
|
||||||
|
- `assistantAddressLaneAttemptInputBuilder.test.ts`
|
||||||
|
- `assistantAddressRuntimeInputBuilder.test.ts`
|
||||||
|
- `assistantLivingChatAttemptInputBuilder.test.ts`
|
||||||
|
- `assistantAddressAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantLivingChatAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantLivingChatHandlerRuntimeAdapter.test.ts`
|
||||||
|
- `assistantLivingChatRuntimeAdapter.test.ts`
|
||||||
|
- `assistantTurnRuntimeDepsAdapter.test.ts`
|
||||||
|
- `assistantTurnRuntimeInputBuilder.test.ts`
|
||||||
|
- `assistantTurnAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantOrganizationScopeRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneResponseAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressRuntimeAdapter.test.ts`
|
||||||
|
- `assistantAddressLaneResponseRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnResponseAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnAnalysisAttemptRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnAnalysisRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnResponseRuntimeAdapter.test.ts`
|
||||||
|
- `assistantDeepTurnPackagingRuntimeAdapter.test.ts`
|
||||||
|
- `assistantWave10SettlementCorrectiveRegression.test.ts`
|
||||||
|
- `assistantLivingChatMode.test.ts`
|
||||||
|
|
||||||
|
Status: **In progress (Phase 2.1 + 2.2 + 2.3 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 2.10 + 2.11 + 2.12 + 2.13 + 2.14 + 2.15 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.21 + 2.22 + 2.23 + 2.24 + 2.25 + 2.26 + 2.27 + 2.28 + 2.29 + 2.30 + 2.31 + 2.32 + 2.33 + 2.34 + 2.35 + 2.36 + 2.37 + 2.38 + 2.39 + 2.40 + 2.41 + 2.42 + 2.43 + 2.44 + 2.45 + 2.46 + 2.47 + 2.48 + 2.49 + 2.50 + 2.51 + 2.52 + 2.53 + 2.54 + 2.55 completed)**
|
||||||
|
|
||||||
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)
|
## Stage 3 (P2): Hybrid Semantic Layer (LLM + Deterministic Guards)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,17 @@ exports.runAssistantAddressAttemptRuntime = runAssistantAddressAttemptRuntime;
|
||||||
const assistantAddressRuntimeAdapter_1 = require("./assistantAddressRuntimeAdapter");
|
const assistantAddressRuntimeAdapter_1 = require("./assistantAddressRuntimeAdapter");
|
||||||
const assistantAddressLaneAttemptRuntimeAdapter_1 = require("./assistantAddressLaneAttemptRuntimeAdapter");
|
const assistantAddressLaneAttemptRuntimeAdapter_1 = require("./assistantAddressLaneAttemptRuntimeAdapter");
|
||||||
const assistantAddressLaneResponseAttemptRuntimeAdapter_1 = require("./assistantAddressLaneResponseAttemptRuntimeAdapter");
|
const assistantAddressLaneResponseAttemptRuntimeAdapter_1 = require("./assistantAddressLaneResponseAttemptRuntimeAdapter");
|
||||||
|
const assistantAddressLaneResponseAttemptInputBuilder_1 = require("./assistantAddressLaneResponseAttemptInputBuilder");
|
||||||
const assistantLivingChatAttemptRuntimeAdapter_1 = require("./assistantLivingChatAttemptRuntimeAdapter");
|
const assistantLivingChatAttemptRuntimeAdapter_1 = require("./assistantLivingChatAttemptRuntimeAdapter");
|
||||||
const assistantLivingChatAttemptInputBuilder_1 = require("./assistantLivingChatAttemptInputBuilder");
|
const assistantLivingChatAttemptInputBuilder_1 = require("./assistantLivingChatAttemptInputBuilder");
|
||||||
|
const assistantAddressLaneAttemptInputBuilder_1 = require("./assistantAddressLaneAttemptInputBuilder");
|
||||||
|
const assistantAddressRuntimeInputBuilder_1 = require("./assistantAddressRuntimeInputBuilder");
|
||||||
async function runAssistantAddressAttemptRuntime(input) {
|
async function runAssistantAddressAttemptRuntime(input) {
|
||||||
const runAddressRuntimeSafe = input.runAddressRuntime ?? assistantAddressRuntimeAdapter_1.runAssistantAddressRuntime;
|
const runAddressRuntimeSafe = input.runAddressRuntime ?? assistantAddressRuntimeAdapter_1.runAssistantAddressRuntime;
|
||||||
const runAddressLaneAttemptRuntimeSafe = input.runAddressLaneAttemptRuntime ?? assistantAddressLaneAttemptRuntimeAdapter_1.runAssistantAddressLaneAttemptRuntime;
|
const runAddressLaneAttemptRuntimeSafe = input.runAddressLaneAttemptRuntime ?? assistantAddressLaneAttemptRuntimeAdapter_1.runAssistantAddressLaneAttemptRuntime;
|
||||||
const runAddressLaneResponseAttemptRuntimeSafe = input.runAddressLaneResponseAttemptRuntime ?? assistantAddressLaneResponseAttemptRuntimeAdapter_1.runAssistantAddressLaneResponseAttemptRuntime;
|
const runAddressLaneResponseAttemptRuntimeSafe = input.runAddressLaneResponseAttemptRuntime ?? assistantAddressLaneResponseAttemptRuntimeAdapter_1.runAssistantAddressLaneResponseAttemptRuntime;
|
||||||
const runLivingChatAttemptRuntimeSafe = input.runLivingChatAttemptRuntime ?? assistantLivingChatAttemptRuntimeAdapter_1.runAssistantLivingChatAttemptRuntime;
|
const runLivingChatAttemptRuntimeSafe = input.runLivingChatAttemptRuntime ?? assistantLivingChatAttemptRuntimeAdapter_1.runAssistantLivingChatAttemptRuntime;
|
||||||
const finalizeAddressLaneResponse = (addressLane, effectiveAddressUserMessage, carryoverMeta = null, llmPreDecomposeMeta = null) => runAddressLaneResponseAttemptRuntimeSafe({
|
const finalizeAddressLaneResponse = (addressLane, effectiveAddressUserMessage, carryoverMeta = null, llmPreDecomposeMeta = null) => runAddressLaneResponseAttemptRuntimeSafe((0, assistantAddressLaneResponseAttemptInputBuilder_1.buildAssistantAddressLaneResponseAttemptRuntimeInput)({
|
||||||
sessionId: input.sessionId,
|
sessionId: input.sessionId,
|
||||||
userMessage: input.userMessage,
|
userMessage: input.userMessage,
|
||||||
effectiveAddressUserMessage,
|
effectiveAddressUserMessage,
|
||||||
|
|
@ -31,7 +34,7 @@ async function runAssistantAddressAttemptRuntime(input) {
|
||||||
cloneConversation: input.cloneConversation,
|
cloneConversation: input.cloneConversation,
|
||||||
logEvent: input.logEvent,
|
logEvent: input.logEvent,
|
||||||
messageIdFactory: input.messageIdFactory
|
messageIdFactory: input.messageIdFactory
|
||||||
});
|
}));
|
||||||
const tryHandleLivingChat = async (modeDecision, addressRuntimeMeta = null) => runLivingChatAttemptRuntimeSafe((0, assistantLivingChatAttemptInputBuilder_1.buildAssistantLivingChatAttemptRuntimeInput)({
|
const tryHandleLivingChat = async (modeDecision, addressRuntimeMeta = null) => runLivingChatAttemptRuntimeSafe((0, assistantLivingChatAttemptInputBuilder_1.buildAssistantLivingChatAttemptRuntimeInput)({
|
||||||
sessionId: input.sessionId,
|
sessionId: input.sessionId,
|
||||||
userMessage: input.userMessage,
|
userMessage: input.userMessage,
|
||||||
|
|
@ -78,21 +81,20 @@ async function runAssistantAddressAttemptRuntime(input) {
|
||||||
defaultBaseUrl: input.defaultBaseUrl,
|
defaultBaseUrl: input.defaultBaseUrl,
|
||||||
defaultApiKey: input.defaultApiKey
|
defaultApiKey: input.defaultApiKey
|
||||||
}));
|
}));
|
||||||
const runAddressLaneAttempt = async (messageUsed, carryMeta, analysisDateHint) => runAddressLaneAttemptRuntimeSafe({
|
const runAddressLaneAttempt = async (messageUsed, carryMeta, analysisDateHint) => runAddressLaneAttemptRuntimeSafe((0, assistantAddressLaneAttemptInputBuilder_1.buildAssistantAddressLaneAttemptRuntimeInput)({
|
||||||
messageUsed,
|
messageUsed,
|
||||||
carryMeta,
|
carryMeta,
|
||||||
analysisDateHint,
|
analysisDateHint,
|
||||||
activeOrganization: input.sessionScope.activeOrganization,
|
activeOrganization: input.sessionScope.activeOrganization,
|
||||||
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
||||||
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
||||||
});
|
}));
|
||||||
return runAddressRuntimeSafe({
|
return runAddressRuntimeSafe((0, assistantAddressRuntimeInputBuilder_1.buildAssistantAddressRuntimeInput)({
|
||||||
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
||||||
sessionId: input.sessionId,
|
sessionId: input.sessionId,
|
||||||
userMessage: input.userMessage,
|
userMessage: input.userMessage,
|
||||||
sessionItems: input.sessionItems,
|
sessionItems: input.sessionItems,
|
||||||
llmProvider: input.payload.llmProvider,
|
payload: input.payload,
|
||||||
useMock: Boolean(input.payload.useMock),
|
|
||||||
featureAddressLlmPredecomposeV1: input.featureAddressLlmPredecomposeV1,
|
featureAddressLlmPredecomposeV1: input.featureAddressLlmPredecomposeV1,
|
||||||
runAddressLlmPreDecompose: input.runAddressLlmPreDecompose,
|
runAddressLlmPreDecompose: input.runAddressLlmPreDecompose,
|
||||||
buildAddressLlmPredecomposeContractV1: input.buildAddressLlmPredecomposeContractV1,
|
buildAddressLlmPredecomposeContractV1: input.buildAddressLlmPredecomposeContractV1,
|
||||||
|
|
@ -102,7 +104,6 @@ async function runAssistantAddressAttemptRuntime(input) {
|
||||||
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision,
|
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision,
|
||||||
buildAddressDialogContinuationContractV2: input.buildAddressDialogContinuationContractV2,
|
buildAddressDialogContinuationContractV2: input.buildAddressDialogContinuationContractV2,
|
||||||
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
||||||
payloadContextPeriodHint: input.payload?.context?.period_hint,
|
|
||||||
compactWhitespace: input.compactWhitespace,
|
compactWhitespace: input.compactWhitespace,
|
||||||
runAddressLaneAttempt,
|
runAddressLaneAttempt,
|
||||||
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
||||||
|
|
@ -113,5 +114,5 @@ async function runAssistantAddressAttemptRuntime(input) {
|
||||||
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
||||||
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
||||||
runAddressLaneRuntime: input.runAddressLaneRuntime
|
runAddressLaneRuntime: input.runAddressLaneRuntime
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
llm_normalizer/backend/dist/services/assistantAddressLaneAttemptInputBuilder.js
vendored
Normal file
13
llm_normalizer/backend/dist/services/assistantAddressLaneAttemptInputBuilder.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.buildAssistantAddressLaneAttemptRuntimeInput = buildAssistantAddressLaneAttemptRuntimeInput;
|
||||||
|
function buildAssistantAddressLaneAttemptRuntimeInput(input) {
|
||||||
|
return {
|
||||||
|
messageUsed: input.messageUsed,
|
||||||
|
carryMeta: input.carryMeta,
|
||||||
|
analysisDateHint: input.analysisDateHint,
|
||||||
|
activeOrganization: input.activeOrganization,
|
||||||
|
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
||||||
|
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
||||||
|
};
|
||||||
|
}
|
||||||
26
llm_normalizer/backend/dist/services/assistantAddressLaneResponseAttemptInputBuilder.js
vendored
Normal file
26
llm_normalizer/backend/dist/services/assistantAddressLaneResponseAttemptInputBuilder.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.buildAssistantAddressLaneResponseAttemptRuntimeInput = buildAssistantAddressLaneResponseAttemptRuntimeInput;
|
||||||
|
function buildAssistantAddressLaneResponseAttemptRuntimeInput(input) {
|
||||||
|
return {
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
effectiveAddressUserMessage: input.effectiveAddressUserMessage,
|
||||||
|
addressLane: input.addressLane,
|
||||||
|
carryoverMeta: input.carryoverMeta ?? null,
|
||||||
|
llmPreDecomposeMeta: input.llmPreDecomposeMeta ?? null,
|
||||||
|
knownOrganizations: input.knownOrganizations,
|
||||||
|
activeOrganization: input.activeOrganization,
|
||||||
|
sanitizeOutgoingAssistantText: input.sanitizeOutgoingAssistantText,
|
||||||
|
buildAddressDebugPayload: input.buildAddressDebugPayload,
|
||||||
|
buildAddressFollowupOffer: input.buildAddressFollowupOffer,
|
||||||
|
mergeKnownOrganizations: input.mergeKnownOrganizations,
|
||||||
|
toNonEmptyString: input.toNonEmptyString,
|
||||||
|
appendItem: input.appendItem,
|
||||||
|
getSession: input.getSession,
|
||||||
|
persistSession: input.persistSession,
|
||||||
|
cloneConversation: input.cloneConversation,
|
||||||
|
logEvent: input.logEvent,
|
||||||
|
messageIdFactory: input.messageIdFactory
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.buildAssistantAddressRuntimeInput = buildAssistantAddressRuntimeInput;
|
||||||
|
function buildAssistantAddressRuntimeInput(input) {
|
||||||
|
return {
|
||||||
|
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
sessionItems: input.sessionItems,
|
||||||
|
llmProvider: input.payload.llmProvider,
|
||||||
|
useMock: Boolean(input.payload.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,
|
||||||
|
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
||||||
|
payloadContextPeriodHint: input.payload?.context?.period_hint,
|
||||||
|
compactWhitespace: input.compactWhitespace,
|
||||||
|
runAddressLaneAttempt: input.runAddressLaneAttempt,
|
||||||
|
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
||||||
|
finalizeAddressLaneResponse: input.finalizeAddressLaneResponse,
|
||||||
|
tryHandleLivingChat: input.tryHandleLivingChat,
|
||||||
|
logEvent: input.logEvent,
|
||||||
|
nowIso: input.nowIso,
|
||||||
|
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
||||||
|
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
||||||
|
runAddressLaneRuntime: input.runAddressLaneRuntime
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -11,11 +11,14 @@ import {
|
||||||
runAssistantAddressLaneResponseAttemptRuntime,
|
runAssistantAddressLaneResponseAttemptRuntime,
|
||||||
type RunAssistantAddressLaneResponseAttemptRuntimeInput
|
type RunAssistantAddressLaneResponseAttemptRuntimeInput
|
||||||
} from "./assistantAddressLaneResponseAttemptRuntimeAdapter";
|
} from "./assistantAddressLaneResponseAttemptRuntimeAdapter";
|
||||||
|
import { buildAssistantAddressLaneResponseAttemptRuntimeInput } from "./assistantAddressLaneResponseAttemptInputBuilder";
|
||||||
import {
|
import {
|
||||||
runAssistantLivingChatAttemptRuntime,
|
runAssistantLivingChatAttemptRuntime,
|
||||||
type RunAssistantLivingChatAttemptRuntimeInput
|
type RunAssistantLivingChatAttemptRuntimeInput
|
||||||
} from "./assistantLivingChatAttemptRuntimeAdapter";
|
} from "./assistantLivingChatAttemptRuntimeAdapter";
|
||||||
import { buildAssistantLivingChatAttemptRuntimeInput } from "./assistantLivingChatAttemptInputBuilder";
|
import { buildAssistantLivingChatAttemptRuntimeInput } from "./assistantLivingChatAttemptInputBuilder";
|
||||||
|
import { buildAssistantAddressLaneAttemptRuntimeInput } from "./assistantAddressLaneAttemptInputBuilder";
|
||||||
|
import { buildAssistantAddressRuntimeInput } from "./assistantAddressRuntimeInputBuilder";
|
||||||
|
|
||||||
interface AddressAttemptPayload {
|
interface AddressAttemptPayload {
|
||||||
llmProvider?: unknown;
|
llmProvider?: unknown;
|
||||||
|
|
@ -110,27 +113,29 @@ export async function runAssistantAddressAttemptRuntime<ResponseType = unknown>(
|
||||||
carryoverMeta = null,
|
carryoverMeta = null,
|
||||||
llmPreDecomposeMeta = null
|
llmPreDecomposeMeta = null
|
||||||
) =>
|
) =>
|
||||||
runAddressLaneResponseAttemptRuntimeSafe({
|
runAddressLaneResponseAttemptRuntimeSafe(
|
||||||
sessionId: input.sessionId,
|
buildAssistantAddressLaneResponseAttemptRuntimeInput({
|
||||||
userMessage: input.userMessage,
|
sessionId: input.sessionId,
|
||||||
effectiveAddressUserMessage,
|
userMessage: input.userMessage,
|
||||||
addressLane,
|
effectiveAddressUserMessage,
|
||||||
carryoverMeta,
|
addressLane,
|
||||||
llmPreDecomposeMeta,
|
carryoverMeta,
|
||||||
knownOrganizations: input.sessionScope.knownOrganizations,
|
llmPreDecomposeMeta,
|
||||||
activeOrganization: input.sessionScope.activeOrganization,
|
knownOrganizations: input.sessionScope.knownOrganizations,
|
||||||
sanitizeOutgoingAssistantText: input.sanitizeOutgoingAssistantText,
|
activeOrganization: input.sessionScope.activeOrganization,
|
||||||
buildAddressDebugPayload: input.buildAddressDebugPayload,
|
sanitizeOutgoingAssistantText: input.sanitizeOutgoingAssistantText,
|
||||||
buildAddressFollowupOffer: input.buildAddressFollowupOffer,
|
buildAddressDebugPayload: input.buildAddressDebugPayload,
|
||||||
mergeKnownOrganizations: input.mergeKnownOrganizations as any,
|
buildAddressFollowupOffer: input.buildAddressFollowupOffer,
|
||||||
toNonEmptyString: input.toNonEmptyString,
|
mergeKnownOrganizations: input.mergeKnownOrganizations,
|
||||||
appendItem: input.appendItem,
|
toNonEmptyString: input.toNonEmptyString,
|
||||||
getSession: input.getSession,
|
appendItem: input.appendItem,
|
||||||
persistSession: input.persistSession,
|
getSession: input.getSession,
|
||||||
cloneConversation: input.cloneConversation,
|
persistSession: input.persistSession,
|
||||||
logEvent: input.logEvent,
|
cloneConversation: input.cloneConversation,
|
||||||
messageIdFactory: input.messageIdFactory
|
logEvent: input.logEvent,
|
||||||
} as RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>);
|
messageIdFactory: input.messageIdFactory
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const tryHandleLivingChat: RunAssistantAddressRuntimeInput<ResponseType>["tryHandleLivingChat"] = async (
|
const tryHandleLivingChat: RunAssistantAddressRuntimeInput<ResponseType>["tryHandleLivingChat"] = async (
|
||||||
modeDecision,
|
modeDecision,
|
||||||
|
|
@ -190,41 +195,43 @@ export async function runAssistantAddressAttemptRuntime<ResponseType = unknown>(
|
||||||
carryMeta,
|
carryMeta,
|
||||||
analysisDateHint
|
analysisDateHint
|
||||||
) =>
|
) =>
|
||||||
runAddressLaneAttemptRuntimeSafe({
|
runAddressLaneAttemptRuntimeSafe(
|
||||||
messageUsed,
|
buildAssistantAddressLaneAttemptRuntimeInput({
|
||||||
carryMeta,
|
messageUsed,
|
||||||
analysisDateHint,
|
carryMeta,
|
||||||
activeOrganization: input.sessionScope.activeOrganization,
|
analysisDateHint,
|
||||||
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
activeOrganization: input.sessionScope.activeOrganization,
|
||||||
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
||||||
});
|
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return runAddressRuntimeSafe({
|
return runAddressRuntimeSafe(
|
||||||
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
buildAssistantAddressRuntimeInput({
|
||||||
sessionId: input.sessionId,
|
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
||||||
userMessage: input.userMessage,
|
sessionId: input.sessionId,
|
||||||
sessionItems: input.sessionItems,
|
userMessage: input.userMessage,
|
||||||
llmProvider: input.payload.llmProvider,
|
sessionItems: input.sessionItems,
|
||||||
useMock: Boolean(input.payload.useMock),
|
payload: input.payload,
|
||||||
featureAddressLlmPredecomposeV1: input.featureAddressLlmPredecomposeV1,
|
featureAddressLlmPredecomposeV1: input.featureAddressLlmPredecomposeV1,
|
||||||
runAddressLlmPreDecompose: input.runAddressLlmPreDecompose,
|
runAddressLlmPreDecompose: input.runAddressLlmPreDecompose,
|
||||||
buildAddressLlmPredecomposeContractV1: input.buildAddressLlmPredecomposeContractV1,
|
buildAddressLlmPredecomposeContractV1: input.buildAddressLlmPredecomposeContractV1,
|
||||||
sanitizeAddressMessageForFallback: input.sanitizeAddressMessageForFallback,
|
sanitizeAddressMessageForFallback: input.sanitizeAddressMessageForFallback,
|
||||||
toNonEmptyString: input.toNonEmptyString,
|
toNonEmptyString: input.toNonEmptyString,
|
||||||
resolveAddressFollowupCarryoverContext: input.resolveAddressFollowupCarryoverContext,
|
resolveAddressFollowupCarryoverContext: input.resolveAddressFollowupCarryoverContext,
|
||||||
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision,
|
resolveAssistantOrchestrationDecision: input.resolveAssistantOrchestrationDecision,
|
||||||
buildAddressDialogContinuationContractV2: input.buildAddressDialogContinuationContractV2,
|
buildAddressDialogContinuationContractV2: input.buildAddressDialogContinuationContractV2,
|
||||||
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
||||||
payloadContextPeriodHint: input.payload?.context?.period_hint,
|
compactWhitespace: input.compactWhitespace,
|
||||||
compactWhitespace: input.compactWhitespace,
|
runAddressLaneAttempt,
|
||||||
runAddressLaneAttempt,
|
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
||||||
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
finalizeAddressLaneResponse,
|
||||||
finalizeAddressLaneResponse,
|
tryHandleLivingChat,
|
||||||
tryHandleLivingChat,
|
logEvent: input.logEvent,
|
||||||
logEvent: input.logEvent,
|
nowIso: input.nowIso,
|
||||||
nowIso: input.nowIso,
|
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
||||||
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
||||||
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
runAddressLaneRuntime: input.runAddressLaneRuntime
|
||||||
runAddressLaneRuntime: input.runAddressLaneRuntime
|
})
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import type { RunAssistantAddressLaneAttemptRuntimeInput } from "./assistantAddressLaneAttemptRuntimeAdapter";
|
||||||
|
|
||||||
|
export interface BuildAssistantAddressLaneAttemptRuntimeInputInput {
|
||||||
|
messageUsed: RunAssistantAddressLaneAttemptRuntimeInput["messageUsed"];
|
||||||
|
carryMeta: RunAssistantAddressLaneAttemptRuntimeInput["carryMeta"];
|
||||||
|
analysisDateHint: RunAssistantAddressLaneAttemptRuntimeInput["analysisDateHint"];
|
||||||
|
activeOrganization: RunAssistantAddressLaneAttemptRuntimeInput["activeOrganization"];
|
||||||
|
mergeFollowupContextWithOrganizationScope:
|
||||||
|
RunAssistantAddressLaneAttemptRuntimeInput["mergeFollowupContextWithOrganizationScope"];
|
||||||
|
runAddressQueryTryHandle: RunAssistantAddressLaneAttemptRuntimeInput["runAddressQueryTryHandle"];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildAssistantAddressLaneAttemptRuntimeInput(
|
||||||
|
input: BuildAssistantAddressLaneAttemptRuntimeInputInput
|
||||||
|
): RunAssistantAddressLaneAttemptRuntimeInput {
|
||||||
|
return {
|
||||||
|
messageUsed: input.messageUsed,
|
||||||
|
carryMeta: input.carryMeta,
|
||||||
|
analysisDateHint: input.analysisDateHint,
|
||||||
|
activeOrganization: input.activeOrganization,
|
||||||
|
mergeFollowupContextWithOrganizationScope: input.mergeFollowupContextWithOrganizationScope,
|
||||||
|
runAddressQueryTryHandle: input.runAddressQueryTryHandle
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import type { RunAssistantAddressLaneResponseAttemptRuntimeInput } from "./assistantAddressLaneResponseAttemptRuntimeAdapter";
|
||||||
|
|
||||||
|
export interface BuildAssistantAddressLaneResponseAttemptRuntimeInputInput<ResponseType = unknown> {
|
||||||
|
sessionId: string;
|
||||||
|
userMessage: string;
|
||||||
|
effectiveAddressUserMessage: string;
|
||||||
|
addressLane: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["addressLane"];
|
||||||
|
carryoverMeta?: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["carryoverMeta"];
|
||||||
|
llmPreDecomposeMeta?: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["llmPreDecomposeMeta"];
|
||||||
|
knownOrganizations: string[];
|
||||||
|
activeOrganization: string | null;
|
||||||
|
sanitizeOutgoingAssistantText:
|
||||||
|
RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["sanitizeOutgoingAssistantText"];
|
||||||
|
buildAddressDebugPayload:
|
||||||
|
RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["buildAddressDebugPayload"];
|
||||||
|
buildAddressFollowupOffer:
|
||||||
|
RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["buildAddressFollowupOffer"];
|
||||||
|
mergeKnownOrganizations:
|
||||||
|
RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["mergeKnownOrganizations"];
|
||||||
|
toNonEmptyString: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["toNonEmptyString"];
|
||||||
|
appendItem: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["appendItem"];
|
||||||
|
getSession: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["getSession"];
|
||||||
|
persistSession: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["persistSession"];
|
||||||
|
cloneConversation: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["cloneConversation"];
|
||||||
|
logEvent: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["logEvent"];
|
||||||
|
messageIdFactory?: RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType>["messageIdFactory"];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType = unknown>(
|
||||||
|
input: BuildAssistantAddressLaneResponseAttemptRuntimeInputInput<ResponseType>
|
||||||
|
): RunAssistantAddressLaneResponseAttemptRuntimeInput<ResponseType> {
|
||||||
|
return {
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
effectiveAddressUserMessage: input.effectiveAddressUserMessage,
|
||||||
|
addressLane: input.addressLane,
|
||||||
|
carryoverMeta: input.carryoverMeta ?? null,
|
||||||
|
llmPreDecomposeMeta: input.llmPreDecomposeMeta ?? null,
|
||||||
|
knownOrganizations: input.knownOrganizations,
|
||||||
|
activeOrganization: input.activeOrganization,
|
||||||
|
sanitizeOutgoingAssistantText: input.sanitizeOutgoingAssistantText,
|
||||||
|
buildAddressDebugPayload: input.buildAddressDebugPayload,
|
||||||
|
buildAddressFollowupOffer: input.buildAddressFollowupOffer,
|
||||||
|
mergeKnownOrganizations: input.mergeKnownOrganizations,
|
||||||
|
toNonEmptyString: input.toNonEmptyString,
|
||||||
|
appendItem: input.appendItem,
|
||||||
|
getSession: input.getSession,
|
||||||
|
persistSession: input.persistSession,
|
||||||
|
cloneConversation: input.cloneConversation,
|
||||||
|
logEvent: input.logEvent,
|
||||||
|
messageIdFactory: input.messageIdFactory
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import type { RunAssistantAddressRuntimeInput } from "./assistantAddressRuntimeAdapter";
|
||||||
|
|
||||||
|
interface AssistantAddressAttemptPayloadLike {
|
||||||
|
llmProvider?: unknown;
|
||||||
|
useMock?: unknown;
|
||||||
|
context?: {
|
||||||
|
period_hint?: unknown;
|
||||||
|
} | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuildAssistantAddressRuntimeInputInput<ResponseType = unknown>
|
||||||
|
extends Omit<RunAssistantAddressRuntimeInput<ResponseType>, "llmProvider" | "useMock" | "payloadContextPeriodHint"> {
|
||||||
|
payload: AssistantAddressAttemptPayloadLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildAssistantAddressRuntimeInput<ResponseType = unknown>(
|
||||||
|
input: BuildAssistantAddressRuntimeInputInput<ResponseType>
|
||||||
|
): RunAssistantAddressRuntimeInput<ResponseType> {
|
||||||
|
return {
|
||||||
|
featureAssistantAddressQueryV1: input.featureAssistantAddressQueryV1,
|
||||||
|
sessionId: input.sessionId,
|
||||||
|
userMessage: input.userMessage,
|
||||||
|
sessionItems: input.sessionItems,
|
||||||
|
llmProvider: input.payload.llmProvider,
|
||||||
|
useMock: Boolean(input.payload.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,
|
||||||
|
runtimeAnalysisContextAsOfDate: input.runtimeAnalysisContextAsOfDate,
|
||||||
|
payloadContextPeriodHint: input.payload?.context?.period_hint,
|
||||||
|
compactWhitespace: input.compactWhitespace,
|
||||||
|
runAddressLaneAttempt: input.runAddressLaneAttempt,
|
||||||
|
isRetryableAddressLimitedResult: input.isRetryableAddressLimitedResult,
|
||||||
|
finalizeAddressLaneResponse: input.finalizeAddressLaneResponse,
|
||||||
|
tryHandleLivingChat: input.tryHandleLivingChat,
|
||||||
|
logEvent: input.logEvent,
|
||||||
|
nowIso: input.nowIso,
|
||||||
|
runAddressOrchestrationRuntime: input.runAddressOrchestrationRuntime,
|
||||||
|
runAddressToolGateRuntime: input.runAddressToolGateRuntime,
|
||||||
|
runAddressLaneRuntime: input.runAddressLaneRuntime
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { buildAssistantAddressLaneAttemptRuntimeInput } from "../src/services/assistantAddressLaneAttemptInputBuilder";
|
||||||
|
|
||||||
|
function buildInput(overrides: Record<string, unknown> = {}) {
|
||||||
|
const mergeFollowupContextWithOrganizationScope = vi.fn((followupContext: Record<string, unknown> | null) =>
|
||||||
|
followupContext
|
||||||
|
);
|
||||||
|
const runAddressQueryTryHandle = vi.fn(async () => ({ response_type: "READY" }));
|
||||||
|
return {
|
||||||
|
messageUsed: "Show overdue docs",
|
||||||
|
carryMeta: { followupContext: { previous_intent: "docs_by_counterparty" } },
|
||||||
|
analysisDateHint: "2020-08-31",
|
||||||
|
activeOrganization: "Org A",
|
||||||
|
mergeFollowupContextWithOrganizationScope,
|
||||||
|
runAddressQueryTryHandle,
|
||||||
|
...overrides
|
||||||
|
} as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("assistant address lane attempt input builder", () => {
|
||||||
|
it("builds lane-attempt runtime input with message, carry meta and analysis date", () => {
|
||||||
|
const runtimeInput = buildAssistantAddressLaneAttemptRuntimeInput(buildInput());
|
||||||
|
|
||||||
|
expect(runtimeInput.messageUsed).toBe("Show overdue docs");
|
||||||
|
expect(runtimeInput.analysisDateHint).toBe("2020-08-31");
|
||||||
|
expect(runtimeInput.activeOrganization).toBe("Org A");
|
||||||
|
expect(runtimeInput.carryMeta).toEqual({
|
||||||
|
followupContext: { previous_intent: "docs_by_counterparty" }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves injected callbacks and nullable fields", async () => {
|
||||||
|
const mergeFollowupContextWithOrganizationScope = vi.fn(() => null);
|
||||||
|
const runAddressQueryTryHandle = vi.fn(async () => ({ response_type: "NEEDS_CONTEXT" }));
|
||||||
|
const runtimeInput = buildAssistantAddressLaneAttemptRuntimeInput(
|
||||||
|
buildInput({
|
||||||
|
carryMeta: null,
|
||||||
|
analysisDateHint: null,
|
||||||
|
activeOrganization: null,
|
||||||
|
mergeFollowupContextWithOrganizationScope,
|
||||||
|
runAddressQueryTryHandle
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await runtimeInput.runAddressQueryTryHandle("message", { analysisDateHint: null });
|
||||||
|
runtimeInput.mergeFollowupContextWithOrganizationScope(null, null);
|
||||||
|
|
||||||
|
expect(runAddressQueryTryHandle).toHaveBeenCalledWith("message", { analysisDateHint: null });
|
||||||
|
expect(mergeFollowupContextWithOrganizationScope).toHaveBeenCalledWith(null, null);
|
||||||
|
expect(runtimeInput.carryMeta).toBeNull();
|
||||||
|
expect(runtimeInput.analysisDateHint).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { buildAssistantAddressLaneResponseAttemptRuntimeInput } from "../src/services/assistantAddressLaneResponseAttemptInputBuilder";
|
||||||
|
|
||||||
|
function buildInput(overrides: Record<string, unknown> = {}) {
|
||||||
|
return {
|
||||||
|
sessionId: "asst-1",
|
||||||
|
userMessage: "Show overdue docs",
|
||||||
|
effectiveAddressUserMessage: "Show overdue docs for Org A",
|
||||||
|
addressLane: {
|
||||||
|
handled: true,
|
||||||
|
reply_text: "ok",
|
||||||
|
reply_type: "factual_with_explanation",
|
||||||
|
debug: {}
|
||||||
|
},
|
||||||
|
knownOrganizations: ["Org A"],
|
||||||
|
activeOrganization: "Org A",
|
||||||
|
sanitizeOutgoingAssistantText: (value: unknown, fallback = "") =>
|
||||||
|
typeof value === "string" && value.trim().length > 0 ? value.trim() : fallback,
|
||||||
|
buildAddressDebugPayload: () => ({}),
|
||||||
|
buildAddressFollowupOffer: () => null,
|
||||||
|
mergeKnownOrganizations: (organizations: string[]) => organizations,
|
||||||
|
toNonEmptyString: (value: unknown) =>
|
||||||
|
typeof value === "string" && value.trim().length > 0 ? value.trim() : null,
|
||||||
|
appendItem: vi.fn(),
|
||||||
|
getSession: vi.fn(),
|
||||||
|
persistSession: vi.fn(),
|
||||||
|
cloneConversation: vi.fn((items: unknown[]) => items),
|
||||||
|
logEvent: vi.fn(),
|
||||||
|
messageIdFactory: vi.fn(() => "msg-1"),
|
||||||
|
...overrides
|
||||||
|
} as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("assistant address lane response attempt input builder", () => {
|
||||||
|
it("normalizes optional carryover and predecompose meta to null", () => {
|
||||||
|
const runtimeInput = buildAssistantAddressLaneResponseAttemptRuntimeInput(
|
||||||
|
buildInput({
|
||||||
|
carryoverMeta: undefined,
|
||||||
|
llmPreDecomposeMeta: undefined
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runtimeInput.carryoverMeta).toBeNull();
|
||||||
|
expect(runtimeInput.llmPreDecomposeMeta).toBeNull();
|
||||||
|
expect(runtimeInput.effectiveAddressUserMessage).toBe("Show overdue docs for Org A");
|
||||||
|
expect(runtimeInput.knownOrganizations).toEqual(["Org A"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves explicit metadata and callback wiring", () => {
|
||||||
|
const logEvent = vi.fn();
|
||||||
|
const runtimeInput = buildAssistantAddressLaneResponseAttemptRuntimeInput(
|
||||||
|
buildInput({
|
||||||
|
carryoverMeta: { followupContext: { previous_intent: "docs_by_counterparty" } },
|
||||||
|
llmPreDecomposeMeta: { mode: "supported" },
|
||||||
|
logEvent
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runtimeInput.carryoverMeta).toEqual({
|
||||||
|
followupContext: { previous_intent: "docs_by_counterparty" }
|
||||||
|
});
|
||||||
|
expect(runtimeInput.llmPreDecomposeMeta).toEqual({ mode: "supported" });
|
||||||
|
runtimeInput.logEvent({ event: "address_done" });
|
||||||
|
expect(logEvent).toHaveBeenCalledWith({ event: "address_done" });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { buildAssistantAddressRuntimeInput } from "../src/services/assistantAddressRuntimeInputBuilder";
|
||||||
|
|
||||||
|
function buildInput(overrides: Record<string, unknown> = {}) {
|
||||||
|
return {
|
||||||
|
featureAssistantAddressQueryV1: true,
|
||||||
|
sessionId: "asst-1",
|
||||||
|
userMessage: "Show overdue docs",
|
||||||
|
sessionItems: [],
|
||||||
|
payload: {
|
||||||
|
llmProvider: "openai",
|
||||||
|
useMock: 1,
|
||||||
|
context: {
|
||||||
|
period_hint: "2020-07-31"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
featureAddressLlmPredecomposeV1: true,
|
||||||
|
runAddressLlmPreDecompose: vi.fn(async () => ({})),
|
||||||
|
buildAddressLlmPredecomposeContractV1: vi.fn(() => ({})),
|
||||||
|
sanitizeAddressMessageForFallback: vi.fn((value: string) => value),
|
||||||
|
toNonEmptyString: vi.fn((value: unknown) =>
|
||||||
|
typeof value === "string" && value.trim().length > 0 ? value.trim() : null
|
||||||
|
),
|
||||||
|
resolveAddressFollowupCarryoverContext: vi.fn(() => null),
|
||||||
|
resolveAssistantOrchestrationDecision: vi.fn(() => ({ mode: "address_query", runAddressLane: true })),
|
||||||
|
buildAddressDialogContinuationContractV2: vi.fn(() => ({})),
|
||||||
|
runtimeAnalysisContextAsOfDate: "2020-07-31",
|
||||||
|
compactWhitespace: vi.fn((value: string) => value.trim()),
|
||||||
|
runAddressLaneAttempt: vi.fn(async () => null),
|
||||||
|
isRetryableAddressLimitedResult: vi.fn(() => false),
|
||||||
|
finalizeAddressLaneResponse: vi.fn(() => ({ kind: "address" })),
|
||||||
|
tryHandleLivingChat: vi.fn(async () => null),
|
||||||
|
logEvent: vi.fn(),
|
||||||
|
nowIso: vi.fn(() => "2026-04-11T00:00:00.000Z"),
|
||||||
|
runAddressOrchestrationRuntime: vi.fn(async () => ({})),
|
||||||
|
runAddressToolGateRuntime: vi.fn(async () => ({ handled: false, response: null })),
|
||||||
|
runAddressLaneRuntime: vi.fn(async () => ({ handled: false, selection: null, retryAudit: {} })),
|
||||||
|
...overrides
|
||||||
|
} as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("assistant address runtime input builder", () => {
|
||||||
|
it("maps payload provider/useMock/period hint into address runtime input", () => {
|
||||||
|
const runtimeInput = buildAssistantAddressRuntimeInput(buildInput());
|
||||||
|
|
||||||
|
expect(runtimeInput.llmProvider).toBe("openai");
|
||||||
|
expect(runtimeInput.useMock).toBe(true);
|
||||||
|
expect(runtimeInput.payloadContextPeriodHint).toBe("2020-07-31");
|
||||||
|
expect(runtimeInput.sessionId).toBe("asst-1");
|
||||||
|
expect(runtimeInput.userMessage).toBe("Show overdue docs");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps empty payload fields safe and preserves runtime callbacks", () => {
|
||||||
|
const runAddressLaneAttempt = vi.fn(async () => null);
|
||||||
|
const tryHandleLivingChat = vi.fn(async () => null);
|
||||||
|
const runtimeInput = buildAssistantAddressRuntimeInput(
|
||||||
|
buildInput({
|
||||||
|
payload: {},
|
||||||
|
runAddressLaneAttempt,
|
||||||
|
tryHandleLivingChat
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runtimeInput.llmProvider).toBeUndefined();
|
||||||
|
expect(runtimeInput.useMock).toBe(false);
|
||||||
|
expect(runtimeInput.payloadContextPeriodHint).toBeUndefined();
|
||||||
|
expect(runtimeInput.runAddressLaneAttempt).toBe(runAddressLaneAttempt);
|
||||||
|
expect(runtimeInput.tryHandleLivingChat).toBe(tryHandleLivingChat);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue