NODEDC_1C/llm_normalizer/backend/src/services/assistantAddressLaneRuntime...

180 lines
5.6 KiB
TypeScript

export interface AssistantAddressFollowupCarryoverLike {
followupContext?: unknown | null;
[key: string]: unknown;
}
export interface AssistantAddressLaneLike {
handled?: boolean;
debug?: {
limited_reason_category?: string | null;
[key: string]: unknown;
} | null;
[key: string]: unknown;
}
export interface AssistantAddressLaneSelection {
addressLane: AssistantAddressLaneLike;
messageUsed: string;
carryMeta: AssistantAddressFollowupCarryoverLike | null;
}
export interface AssistantAddressLaneRetryAudit {
attempted: boolean;
reason: string | null;
initial_limited_category: string | null;
retry_message: string | null;
retry_used_followup_context: boolean;
retry_result_category: string | null;
}
export interface RunAssistantAddressLaneRuntimeInput {
userMessage: string;
addressInputMessage: string;
carryover: AssistantAddressFollowupCarryoverLike | null;
shouldPreferContextualLane: boolean;
canRetryWithRawUserMessage: boolean;
runAddressLaneAttempt: (
messageUsed: string,
carryMeta: AssistantAddressFollowupCarryoverLike | null
) => Promise<AssistantAddressLaneLike | null>;
isRetryableAddressLimitedResult: (addressLane: AssistantAddressLaneLike | null | undefined) => boolean;
}
export interface RunAssistantAddressLaneRuntimeOutput {
handled: boolean;
selection: AssistantAddressLaneSelection | null;
retryAudit: AssistantAddressLaneRetryAudit;
}
function limitedCategory(addressLane: AssistantAddressLaneLike | null | undefined): string | null {
return typeof addressLane?.debug?.limited_reason_category === "string"
? addressLane.debug.limited_reason_category
: null;
}
export async function runAssistantAddressLaneRuntime(
input: RunAssistantAddressLaneRuntimeInput
): Promise<RunAssistantAddressLaneRuntimeOutput> {
const retryAudit: AssistantAddressLaneRetryAudit = {
attempted: false,
reason: null,
initial_limited_category: null,
retry_message: null,
retry_used_followup_context: false,
retry_result_category: null
};
let pendingLimited: AssistantAddressLaneSelection | null = null;
const evaluateAddressLane = (
addressLane: AssistantAddressLaneLike | null,
messageUsed: string,
carryMeta: AssistantAddressFollowupCarryoverLike | null
): { action: "return"; selection: AssistantAddressLaneSelection } | { action: "continue" } => {
if (!addressLane?.handled) {
return { action: "continue" };
}
if (!input.isRetryableAddressLimitedResult(addressLane)) {
return {
action: "return",
selection: {
addressLane,
messageUsed,
carryMeta
}
};
}
if (!pendingLimited) {
pendingLimited = {
addressLane,
messageUsed,
carryMeta
};
}
return { action: "continue" };
};
if (input.shouldPreferContextualLane) {
const contextualAddressLane = await input.runAddressLaneAttempt(input.addressInputMessage, input.carryover);
const decision = evaluateAddressLane(contextualAddressLane, input.addressInputMessage, input.carryover);
if (decision.action === "return") {
return {
handled: true,
selection: decision.selection,
retryAudit
};
}
}
const primaryAddressLane = await input.runAddressLaneAttempt(input.addressInputMessage, null);
const primaryDecision = evaluateAddressLane(primaryAddressLane, input.addressInputMessage, null);
if (primaryDecision.action === "return") {
return {
handled: true,
selection: primaryDecision.selection,
retryAudit
};
}
if (!input.shouldPreferContextualLane && input.carryover?.followupContext) {
const contextualAddressLane = await input.runAddressLaneAttempt(input.addressInputMessage, input.carryover);
const contextualDecision = evaluateAddressLane(contextualAddressLane, input.addressInputMessage, input.carryover);
if (contextualDecision.action === "return") {
return {
handled: true,
selection: contextualDecision.selection,
retryAudit
};
}
}
const pendingLimitedSelection = pendingLimited;
if (pendingLimitedSelection && input.canRetryWithRawUserMessage) {
retryAudit.attempted = true;
retryAudit.reason = "limited_result_retry_with_raw_message";
retryAudit.initial_limited_category = limitedCategory(
(pendingLimitedSelection as AssistantAddressLaneSelection | null)?.addressLane ?? null
);
retryAudit.retry_message = input.userMessage;
if (input.carryover?.followupContext) {
retryAudit.retry_used_followup_context = true;
const rawContextualLane = await input.runAddressLaneAttempt(input.userMessage, input.carryover);
const rawContextualDecision = evaluateAddressLane(rawContextualLane, input.userMessage, input.carryover);
if (rawContextualDecision.action === "return") {
retryAudit.retry_result_category = limitedCategory(rawContextualDecision.selection.addressLane);
return {
handled: true,
selection: rawContextualDecision.selection,
retryAudit
};
}
}
const rawPrimaryLane = await input.runAddressLaneAttempt(input.userMessage, null);
retryAudit.retry_result_category = limitedCategory(rawPrimaryLane);
const rawPrimaryDecision = evaluateAddressLane(rawPrimaryLane, input.userMessage, null);
if (rawPrimaryDecision.action === "return") {
return {
handled: true,
selection: rawPrimaryDecision.selection,
retryAudit
};
}
}
if (pendingLimited) {
return {
handled: true,
selection: pendingLimited,
retryAudit
};
}
return {
handled: false,
selection: null,
retryAudit
};
}