159 lines
4.8 KiB
TypeScript
159 lines
4.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { RouteHintSummary } from "../src/types/normalizer";
|
|
import type { UnifiedRetrievalResult } from "../src/types/assistant";
|
|
import { createEmptyInvestigationState } from "../src/services/investigationState";
|
|
import {
|
|
buildAssistantInvestigationStateSnapshot,
|
|
persistAssistantInvestigationStateSnapshot
|
|
} from "../src/services/assistantInvestigationStateRuntimeAdapter";
|
|
|
|
function buildRouteSummary(): RouteHintSummary {
|
|
return {
|
|
mode: "deterministic_v2",
|
|
message_in_scope: true,
|
|
scope_confidence: "high",
|
|
planner: {
|
|
total_fragments: 1,
|
|
in_scope_fragments: 1,
|
|
out_of_scope_fragments: 0,
|
|
discarded_fragments: 0,
|
|
contains_multiple_tasks: false
|
|
},
|
|
decisions: [
|
|
{
|
|
fragment_id: "F1",
|
|
domain_relevance: "in_scope",
|
|
business_scope: "company_specific_accounting",
|
|
candidate_labels: ["anomaly_probe"],
|
|
decision_flags: {
|
|
has_multi_entity_scope: false,
|
|
asks_for_chain_explanation: false,
|
|
asks_for_ranking_or_top: false,
|
|
asks_for_period_summary: false,
|
|
asks_for_rule_check: true,
|
|
asks_for_anomaly_scan: true,
|
|
asks_for_exact_object_trace: false,
|
|
asks_for_evidence: true,
|
|
mentions_period_close_context: false
|
|
},
|
|
route: "store_feature_risk",
|
|
reason: "test-route"
|
|
}
|
|
],
|
|
fallback: {
|
|
type: "none",
|
|
message: null
|
|
}
|
|
};
|
|
}
|
|
|
|
function buildRetrievalResult(): UnifiedRetrievalResult {
|
|
return {
|
|
fragment_id: "F1",
|
|
requirement_ids: ["R1"],
|
|
route: "store_feature_risk",
|
|
status: "ok",
|
|
result_type: "summary",
|
|
items: [],
|
|
summary: {},
|
|
evidence: [],
|
|
why_included: [],
|
|
selection_reason: [],
|
|
risk_factors: [],
|
|
business_interpretation: [],
|
|
confidence: "medium",
|
|
limitations: [],
|
|
errors: []
|
|
};
|
|
}
|
|
|
|
describe("assistant investigation state runtime adapter", () => {
|
|
it("returns null and skips persist when feature disabled", () => {
|
|
const snapshot = buildAssistantInvestigationStateSnapshot({
|
|
featureEnabled: false,
|
|
previousState: createEmptyInvestigationState("asst-1", "2026-04-10T10:00:00.000Z"),
|
|
timestamp: "2026-04-10T10:01:00.000Z",
|
|
questionId: "msg-1",
|
|
userMessage: "проверь 60.01",
|
|
routeSummary: buildRouteSummary(),
|
|
requirements: [],
|
|
coverageReport: {
|
|
requirements_total: 0,
|
|
requirements_covered: 0,
|
|
requirements_uncovered: [],
|
|
requirements_partially_covered: [],
|
|
clarification_needed_for: [],
|
|
out_of_scope_requirements: []
|
|
},
|
|
retrievalResults: [],
|
|
replyType: "factual",
|
|
followupApplied: false
|
|
});
|
|
expect(snapshot).toBeNull();
|
|
|
|
let persistCalled = false;
|
|
const persisted = persistAssistantInvestigationStateSnapshot({
|
|
featureEnabled: false,
|
|
sessionId: "asst-1",
|
|
snapshot: null,
|
|
persist: () => {
|
|
persistCalled = true;
|
|
}
|
|
});
|
|
expect(persisted).toBe(false);
|
|
expect(persistCalled).toBe(false);
|
|
});
|
|
|
|
it("builds snapshot and persists it when feature enabled", () => {
|
|
const previous = createEmptyInvestigationState("asst-2", "2026-04-10T10:00:00.000Z");
|
|
const snapshot = buildAssistantInvestigationStateSnapshot({
|
|
featureEnabled: true,
|
|
previousState: previous,
|
|
timestamp: "2026-04-10T10:01:00.000Z",
|
|
questionId: "msg-2",
|
|
userMessage: "проверь счет 60.01 за 2020-07",
|
|
routeSummary: buildRouteSummary(),
|
|
requirements: [
|
|
{
|
|
requirement_id: "R1",
|
|
source_fragment_id: "F1",
|
|
requirement_text: "проверить счет 60.01",
|
|
subject_tokens: ["account_60.01"],
|
|
status: "covered",
|
|
route: "store_feature_risk"
|
|
}
|
|
],
|
|
coverageReport: {
|
|
requirements_total: 1,
|
|
requirements_covered: 1,
|
|
requirements_uncovered: [],
|
|
requirements_partially_covered: [],
|
|
clarification_needed_for: [],
|
|
out_of_scope_requirements: []
|
|
},
|
|
retrievalResults: [buildRetrievalResult()],
|
|
replyType: "factual",
|
|
followupApplied: false
|
|
});
|
|
|
|
expect(snapshot).not.toBeNull();
|
|
expect(snapshot?.turn_index).toBe(1);
|
|
expect(snapshot?.question_id).toBe("msg-2");
|
|
|
|
let persistedSessionId: string | null = null;
|
|
let persistedQuestionId: string | null = null;
|
|
const persisted = persistAssistantInvestigationStateSnapshot({
|
|
featureEnabled: true,
|
|
sessionId: "asst-2",
|
|
snapshot: snapshot,
|
|
persist: (sessionId, state) => {
|
|
persistedSessionId = sessionId;
|
|
persistedQuestionId = state.question_id;
|
|
}
|
|
});
|
|
expect(persisted).toBe(true);
|
|
expect(persistedSessionId).toBe("asst-2");
|
|
expect(persistedQuestionId).toBe("msg-2");
|
|
});
|
|
});
|