NODEDC_1C/llm_normalizer/backend/tests/assistantDeepTurnRetrievalR...

159 lines
5.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AssistantExecutionPlanItem } from "../src/services/assistantQueryPlanning";
import { executeAssistantDeepTurnRetrievalPlan } from "../src/services/assistantDeepTurnRetrievalRuntimeAdapter";
describe("assistant deep turn retrieval runtime adapter", () => {
it("handles skipped, executed and failed plan items with stable call records", async () => {
const executionPlan: AssistantExecutionPlanItem[] = [
{
fragment_id: "F1",
requirement_ids: ["R1"],
route: "no_route",
should_execute: false,
fragment_text: "clarify period",
no_route_reason: "insufficient_specificity",
clarification_reason: "domain_or_scope_unclear"
},
{
fragment_id: "F2",
requirement_ids: ["R2"],
route: "store_canonical",
should_execute: true,
fragment_text: "show balances",
no_route_reason: null,
clarification_reason: null
},
{
fragment_id: "F3",
requirement_ids: ["R3"],
route: "live_mcp_drilldown",
should_execute: true,
fragment_text: "tail check",
no_route_reason: null,
clarification_reason: null
}
];
const normalizeCalls: Array<{ fragmentId: string; route: string; rawStatus: string | null }> = [];
const output = await executeAssistantDeepTurnRetrievalPlan({
executionPlan,
liveTemporalHint: null,
executeRouteRuntime: async (route) => {
if (route === "live_mcp_drilldown") {
throw new Error("route failed");
}
return {
status: "ok",
result_type: "summary",
items: [],
summary: { route },
evidence: [],
why_included: [],
selection_reason: [],
risk_factors: [],
business_interpretation: [],
confidence: "high",
limitations: [],
errors: []
};
},
mapNoRouteReason: (reason) => (reason === "insufficient_specificity" ? "Needs clarification." : "No-route decision."),
buildSkippedResult: () =>
({
fragment_id: "F1",
route: "no_route",
status: "partial"
}) as any,
normalizeRetrievalResultFn: ((fragmentId: string, _requirementIds: string[], route: string, raw: Record<string, unknown>) => {
normalizeCalls.push({
fragmentId,
route,
rawStatus: typeof raw.status === "string" ? raw.status : null
});
return {
fragment_id: fragmentId,
route,
status: raw.status
} as any;
}) as any
});
expect(output.retrievalCalls).toEqual([
{
fragment_id: "F1",
requirement_ids: ["R1"],
route: "no_route",
status: "skipped",
query_text: "clarify period",
reason: "Needs clarification."
},
{
fragment_id: "F2",
requirement_ids: ["R2"],
route: "store_canonical",
status: "executed",
query_text: "show balances",
reason: null
},
{
fragment_id: "F3",
requirement_ids: ["R3"],
route: "live_mcp_drilldown",
status: "failed",
query_text: "tail check",
reason: "route failed"
}
]);
expect(output.retrievalResultsRaw).toHaveLength(2);
expect((output.retrievalResultsRaw[0].raw_result as Record<string, unknown>).status).toBe("ok");
expect((output.retrievalResultsRaw[1].raw_result as Record<string, unknown>).status).toBe("error");
expect((output.retrievalResultsRaw[1].raw_result as Record<string, unknown>).limitations).toEqual(["Route executor failed."]);
expect(output.retrievalResults).toHaveLength(3);
expect(output.retrievalResults[0].status).toBe("partial");
expect(normalizeCalls).toEqual([
{ fragmentId: "F2", route: "store_canonical", rawStatus: "ok" },
{ fragmentId: "F3", route: "live_mcp_drilldown", rawStatus: "error" }
]);
});
it("passes live temporal hint into route runtime execution", async () => {
const executionPlan: AssistantExecutionPlanItem[] = [
{
fragment_id: "F1",
requirement_ids: ["R1"],
route: "hybrid_store_plus_live",
should_execute: true,
fragment_text: "check as of date",
no_route_reason: null,
clarification_reason: null
}
];
let capturedTemporalHint: Record<string, unknown> | null = null;
await executeAssistantDeepTurnRetrievalPlan({
executionPlan,
liveTemporalHint: {
as_of_date: "2020-07-31",
period_from: null,
period_to: null,
source: "analysis_context"
},
executeRouteRuntime: async (_route, _fragmentText, options) => {
capturedTemporalHint = options.temporalHint as unknown as Record<string, unknown>;
return { status: "ok" };
},
mapNoRouteReason: () => "No-route decision.",
buildSkippedResult: (() => ({ status: "partial" })) as any,
normalizeRetrievalResultFn: (() => ({ status: "ok" })) as any
});
expect(capturedTemporalHint).toEqual({
as_of_date: "2020-07-31",
period_from: null,
period_to: null,
source: "analysis_context"
});
});
});