113 lines
4.2 KiB
TypeScript
113 lines
4.2 KiB
TypeScript
import type { AssistantMessageRequestPayload } from "../types/assistant";
|
|
import type { NormalizeRequestPayload, NormalizeResponsePayload } from "../types/normalizer";
|
|
import type { InvestigationStateWithProblemUnits } from "../types/stage2ProblemUnits";
|
|
import type { AssistantFollowupUsage } from "./assistantFollowupUsage";
|
|
import { toRouteHintSummary } from "./routeHintAdapter";
|
|
|
|
export interface AssistantDeepTurnFollowupBinding {
|
|
normalizedQuestion: string;
|
|
mergedContext: NormalizeRequestPayload["context"] | undefined;
|
|
usage: AssistantFollowupUsage | null;
|
|
}
|
|
|
|
export interface BuildAssistantDeepTurnNormalizationRuntimeInput {
|
|
userMessage: string;
|
|
payload: AssistantMessageRequestPayload;
|
|
featureInvestigationStateV1: boolean;
|
|
featureStateFollowupBindingV1: boolean;
|
|
sessionInvestigationState: InvestigationStateWithProblemUnits | null | undefined;
|
|
buildFollowupStateBinding: (input: {
|
|
userMessage: string;
|
|
payloadContext: NormalizeRequestPayload["context"] | undefined;
|
|
investigationState: InvestigationStateWithProblemUnits;
|
|
}) => AssistantDeepTurnFollowupBinding;
|
|
normalize: (payload: NormalizeRequestPayload) => Promise<NormalizeResponsePayload>;
|
|
}
|
|
|
|
export interface BuildAssistantDeepTurnNormalizationRuntimeOutput {
|
|
followupBinding: AssistantDeepTurnFollowupBinding;
|
|
normalizePayload: NormalizeRequestPayload;
|
|
normalized: NormalizeResponsePayload;
|
|
}
|
|
|
|
function resolveDeepTurnNormalizerPromptVersion(promptVersion: NormalizeRequestPayload["promptVersion"]): string {
|
|
const normalized = String(promptVersion ?? "").trim().toLowerCase();
|
|
if (
|
|
normalized === "normalizer_v2_0_2" ||
|
|
normalized === "normalizer_v2_0_1" ||
|
|
normalized === "normalizer_v2" ||
|
|
normalized === "normalizer_v1"
|
|
) {
|
|
return String(promptVersion);
|
|
}
|
|
return "normalizer_v2_0_2";
|
|
}
|
|
|
|
function canSynthesizeRouteSummary(normalized: NormalizeResponsePayload["normalized"]): boolean {
|
|
if (!normalized || typeof normalized !== "object") {
|
|
return false;
|
|
}
|
|
const source = normalized as unknown as Record<string, unknown>;
|
|
return Array.isArray(source.fragments);
|
|
}
|
|
|
|
export async function buildAssistantDeepTurnNormalizationRuntime(
|
|
input: BuildAssistantDeepTurnNormalizationRuntimeInput
|
|
): Promise<BuildAssistantDeepTurnNormalizationRuntimeOutput> {
|
|
const investigationState = input.sessionInvestigationState;
|
|
const canUseFollowupBinding =
|
|
input.featureInvestigationStateV1 &&
|
|
input.featureStateFollowupBindingV1 &&
|
|
investigationState !== null &&
|
|
investigationState !== undefined;
|
|
const followupBinding =
|
|
canUseFollowupBinding
|
|
? input.buildFollowupStateBinding({
|
|
userMessage: input.userMessage,
|
|
payloadContext: input.payload.context,
|
|
investigationState
|
|
})
|
|
: {
|
|
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: resolveDeepTurnNormalizerPromptVersion(input.payload.promptVersion),
|
|
schemaVersion: "v2_0_2",
|
|
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);
|
|
const normalizedPayload = normalized.normalized;
|
|
const synthesizedRouteSummary =
|
|
normalized.route_hint_summary ??
|
|
(normalizedPayload && canSynthesizeRouteSummary(normalizedPayload) ? toRouteHintSummary(normalizedPayload) : null);
|
|
const normalizedWithRouteSummary: NormalizeResponsePayload =
|
|
synthesizedRouteSummary === normalized.route_hint_summary
|
|
? normalized
|
|
: {
|
|
...normalized,
|
|
route_hint_summary: synthesizedRouteSummary
|
|
};
|
|
|
|
return {
|
|
followupBinding,
|
|
normalizePayload,
|
|
normalized: normalizedWithRouteSummary
|
|
};
|
|
}
|