204 lines
8.8 KiB
TypeScript
204 lines
8.8 KiB
TypeScript
import {
|
|
buildAssistantAddressOrchestrationRuntime,
|
|
type AssistantAddressCarryoverLike,
|
|
type BuildAssistantAddressOrchestrationRuntimeInput,
|
|
type BuildAssistantAddressOrchestrationRuntimeOutput
|
|
} from "./assistantAddressOrchestrationRuntimeAdapter";
|
|
import {
|
|
runAssistantAddressLaneRuntime,
|
|
type AssistantAddressLaneLike,
|
|
type RunAssistantAddressLaneRuntimeOutput
|
|
} from "./assistantAddressLaneRuntimeAdapter";
|
|
import {
|
|
runAssistantAddressToolGateRuntime,
|
|
type AssistantAddressToolGateRuntimeOutput
|
|
} from "./assistantAddressToolGateRuntimeAdapter";
|
|
|
|
export interface RunAssistantAddressRuntimeInput<ResponseType = unknown> {
|
|
featureAssistantAddressQueryV1: boolean;
|
|
sessionId: string;
|
|
userMessage: string;
|
|
sessionItems: unknown[];
|
|
sessionAddressNavigationState?: unknown;
|
|
sessionOrganizationScope?: {
|
|
knownOrganizations?: unknown;
|
|
selectedOrganization?: unknown;
|
|
activeOrganization?: unknown;
|
|
} | null;
|
|
llmProvider: unknown;
|
|
useMock: boolean;
|
|
featureAddressLlmPredecomposeV1: boolean;
|
|
runAddressLlmPreDecompose: () => Promise<Record<string, unknown>>;
|
|
buildAddressLlmPredecomposeContractV1: BuildAssistantAddressOrchestrationRuntimeInput["buildAddressLlmPredecomposeContractV1"];
|
|
sanitizeAddressMessageForFallback: BuildAssistantAddressOrchestrationRuntimeInput["sanitizeAddressMessageForFallback"];
|
|
toNonEmptyString: (value: unknown) => string | null;
|
|
resolveAddressFollowupCarryoverContext: BuildAssistantAddressOrchestrationRuntimeInput["resolveAddressFollowupCarryoverContext"];
|
|
resolveAssistantOrchestrationDecision: BuildAssistantAddressOrchestrationRuntimeInput["resolveAssistantOrchestrationDecision"];
|
|
buildAddressDialogContinuationContractV2: BuildAssistantAddressOrchestrationRuntimeInput["buildAddressDialogContinuationContractV2"];
|
|
runtimeAnalysisContextAsOfDate: string | null;
|
|
payloadContextPeriodHint: unknown;
|
|
compactWhitespace: (value: string) => string;
|
|
runAddressLaneAttempt: (
|
|
messageUsed: string,
|
|
carryMeta: AssistantAddressCarryoverLike | null,
|
|
analysisDateHint: string | null,
|
|
llmSemanticHints?: Record<string, unknown> | null
|
|
) => Promise<AssistantAddressLaneLike | null>;
|
|
isRetryableAddressLimitedResult: (addressLane: AssistantAddressLaneLike | null | undefined) => boolean;
|
|
finalizeAddressLaneResponse: (
|
|
addressLane: AssistantAddressLaneLike,
|
|
effectiveAddressUserMessage: string,
|
|
carryoverMeta?: AssistantAddressCarryoverLike | null,
|
|
llmPreDecomposeMeta?: Record<string, unknown> | null
|
|
) => ResponseType;
|
|
tryHandleLivingChat: (
|
|
modeDecision: { mode?: unknown; reason?: unknown },
|
|
addressRuntimeMeta: Record<string, unknown> | null
|
|
) => Promise<ResponseType | null>;
|
|
logEvent: (payload: Record<string, unknown>) => void;
|
|
nowIso: () => string;
|
|
runAddressOrchestrationRuntime?: (
|
|
input: BuildAssistantAddressOrchestrationRuntimeInput
|
|
) => Promise<BuildAssistantAddressOrchestrationRuntimeOutput>;
|
|
runAddressToolGateRuntime?: (
|
|
input: {
|
|
sessionId: string;
|
|
userMessage: string;
|
|
addressInputMessage: string;
|
|
orchestrationDecision: BuildAssistantAddressOrchestrationRuntimeOutput["orchestrationDecision"];
|
|
livingModeDecision: BuildAssistantAddressOrchestrationRuntimeOutput["livingModeDecision"];
|
|
addressRuntimeMeta: BuildAssistantAddressOrchestrationRuntimeOutput["addressRuntimeMeta"];
|
|
logEvent: (payload: Record<string, unknown>) => void;
|
|
tryHandleLivingChat: (
|
|
modeDecision: { mode?: unknown; reason?: unknown },
|
|
addressRuntimeMeta: Record<string, unknown> | null
|
|
) => Promise<ResponseType | null>;
|
|
nowIso: () => string;
|
|
}
|
|
) => Promise<AssistantAddressToolGateRuntimeOutput<ResponseType>>;
|
|
runAddressLaneRuntime?: (
|
|
input: {
|
|
userMessage: string;
|
|
addressInputMessage: string;
|
|
carryover: AssistantAddressCarryoverLike | null;
|
|
shouldPreferContextualLane: boolean;
|
|
canRetryWithRawUserMessage: boolean;
|
|
runAddressLaneAttempt: (
|
|
messageUsed: string,
|
|
carryMeta: AssistantAddressCarryoverLike | null,
|
|
llmSemanticHints?: Record<string, unknown> | null
|
|
) => Promise<AssistantAddressLaneLike | null>;
|
|
isRetryableAddressLimitedResult: (addressLane: AssistantAddressLaneLike | null | undefined) => boolean;
|
|
}
|
|
) => Promise<RunAssistantAddressLaneRuntimeOutput>;
|
|
}
|
|
|
|
export interface RunAssistantAddressRuntimeOutput<ResponseType = unknown> {
|
|
handled: boolean;
|
|
response: ResponseType | null;
|
|
addressRuntimeMetaForDeep: Record<string, unknown> | null;
|
|
}
|
|
|
|
export async function runAssistantAddressRuntime<ResponseType = unknown>(
|
|
input: RunAssistantAddressRuntimeInput<ResponseType>
|
|
): Promise<RunAssistantAddressRuntimeOutput<ResponseType>> {
|
|
if (!input.featureAssistantAddressQueryV1) {
|
|
return {
|
|
handled: false,
|
|
response: null,
|
|
addressRuntimeMetaForDeep: null
|
|
};
|
|
}
|
|
|
|
const runAddressOrchestrationRuntimeSafe =
|
|
input.runAddressOrchestrationRuntime ?? buildAssistantAddressOrchestrationRuntime;
|
|
const runAddressToolGateRuntimeSafe = input.runAddressToolGateRuntime ?? runAssistantAddressToolGateRuntime;
|
|
const runAddressLaneRuntimeSafe = input.runAddressLaneRuntime ?? runAssistantAddressLaneRuntime;
|
|
|
|
const addressOrchestrationRuntime = await runAddressOrchestrationRuntimeSafe({
|
|
userMessage: input.userMessage,
|
|
sessionItems: input.sessionItems,
|
|
sessionAddressNavigationState: input.sessionAddressNavigationState,
|
|
sessionOrganizationScope: input.sessionOrganizationScope ?? null,
|
|
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,
|
|
llmSemanticHints:
|
|
addressRuntimeMeta && typeof addressRuntimeMeta === "object"
|
|
? ((addressRuntimeMeta as { semanticHints?: unknown }).semanticHints as Record<string, unknown> | null) ?? null
|
|
: null,
|
|
shouldPreferContextualLane,
|
|
canRetryWithRawUserMessage,
|
|
runAddressLaneAttempt: (messageUsed, carryMeta, llmSemanticHints = null) =>
|
|
input.runAddressLaneAttempt(messageUsed, carryMeta, analysisDateHint, llmSemanticHints),
|
|
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
|
|
};
|
|
}
|