106 lines
4.1 KiB
TypeScript
106 lines
4.1 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
runAssistantAddressLaneRuntime,
|
|
type AssistantAddressFollowupCarryoverLike,
|
|
type AssistantAddressLaneLike
|
|
} from "../src/services/assistantAddressLaneRuntimeAdapter";
|
|
|
|
function limitedLane(category: string): AssistantAddressLaneLike {
|
|
return {
|
|
handled: true,
|
|
debug: {
|
|
limited_reason_category: category
|
|
}
|
|
};
|
|
}
|
|
|
|
function factualLane(): AssistantAddressLaneLike {
|
|
return {
|
|
handled: true,
|
|
debug: {}
|
|
};
|
|
}
|
|
|
|
function unhandledLane(): AssistantAddressLaneLike {
|
|
return {
|
|
handled: false,
|
|
debug: {}
|
|
};
|
|
}
|
|
|
|
describe("assistant address lane runtime adapter", () => {
|
|
it("returns contextual lane immediately when preferred contextual attempt is factual", async () => {
|
|
const carryover: AssistantAddressFollowupCarryoverLike = { followupContext: { scope: "ctx" } };
|
|
const runAddressLaneAttempt = vi.fn(async () => factualLane());
|
|
|
|
const result = await runAssistantAddressLaneRuntime({
|
|
userMessage: "сырой вопрос",
|
|
addressInputMessage: "нормализованный вопрос",
|
|
carryover,
|
|
shouldPreferContextualLane: true,
|
|
canRetryWithRawUserMessage: true,
|
|
runAddressLaneAttempt,
|
|
isRetryableAddressLimitedResult: (lane) => Boolean(lane?.debug?.limited_reason_category)
|
|
});
|
|
|
|
expect(result.handled).toBe(true);
|
|
expect(result.selection?.messageUsed).toBe("нормализованный вопрос");
|
|
expect(result.selection?.carryMeta).toBe(carryover);
|
|
expect(result.retryAudit.attempted).toBe(false);
|
|
expect(runAddressLaneAttempt).toHaveBeenCalledTimes(1);
|
|
expect(runAddressLaneAttempt).toHaveBeenCalledWith("нормализованный вопрос", carryover);
|
|
});
|
|
|
|
it("retries with raw message after limited result and returns factual retry", async () => {
|
|
const carryover: AssistantAddressFollowupCarryoverLike = { followupContext: { scope: "ctx" } };
|
|
const runAddressLaneAttempt = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(limitedLane("empty_match")) // primary
|
|
.mockResolvedValueOnce(limitedLane("empty_match")) // contextual
|
|
.mockResolvedValueOnce(factualLane()); // raw contextual retry
|
|
|
|
const result = await runAssistantAddressLaneRuntime({
|
|
userMessage: "сырой вопрос",
|
|
addressInputMessage: "нормализованный вопрос",
|
|
carryover,
|
|
shouldPreferContextualLane: false,
|
|
canRetryWithRawUserMessage: true,
|
|
runAddressLaneAttempt,
|
|
isRetryableAddressLimitedResult: (lane) => Boolean(lane?.debug?.limited_reason_category)
|
|
});
|
|
|
|
expect(result.handled).toBe(true);
|
|
expect(result.selection?.messageUsed).toBe("сырой вопрос");
|
|
expect(result.selection?.carryMeta).toBe(carryover);
|
|
expect(result.retryAudit.attempted).toBe(true);
|
|
expect(result.retryAudit.reason).toBe("limited_result_retry_with_raw_message");
|
|
expect(result.retryAudit.initial_limited_category).toBe("empty_match");
|
|
expect(result.retryAudit.retry_used_followup_context).toBe(true);
|
|
expect(result.retryAudit.retry_result_category).toBe(null);
|
|
expect(runAddressLaneAttempt).toHaveBeenCalledTimes(3);
|
|
});
|
|
|
|
it("returns pending limited result when retry is disabled", async () => {
|
|
const runAddressLaneAttempt = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(limitedLane("missing_anchor")) // primary
|
|
.mockResolvedValueOnce(unhandledLane()); // contextual fallback
|
|
|
|
const result = await runAssistantAddressLaneRuntime({
|
|
userMessage: "сырой вопрос",
|
|
addressInputMessage: "нормализованный вопрос",
|
|
carryover: { followupContext: { scope: "ctx" } },
|
|
shouldPreferContextualLane: false,
|
|
canRetryWithRawUserMessage: false,
|
|
runAddressLaneAttempt,
|
|
isRetryableAddressLimitedResult: (lane) => Boolean(lane?.debug?.limited_reason_category)
|
|
});
|
|
|
|
expect(result.handled).toBe(true);
|
|
expect(result.selection?.messageUsed).toBe("нормализованный вопрос");
|
|
expect(result.selection?.addressLane.debug?.limited_reason_category).toBe("missing_anchor");
|
|
expect(result.retryAudit.attempted).toBe(false);
|
|
});
|
|
});
|
|
|