180 lines
5.6 KiB
TypeScript
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
|
|
};
|
|
}
|