import { describe, expect, it } from "vitest"; import { createAssistantTransitionPolicy } from "../src/services/assistantTransitionPolicy"; function toNonEmptyString(value: unknown): string | null { if (value === null || value === undefined) { return null; } const text = String(value).trim(); return text.length > 0 ? text : null; } function buildPolicy(overrides: Record = {}) { return createAssistantTransitionPolicy({ compactWhitespace: (value: string) => String(value ?? "").replace(/\s+/g, " ").trim(), repairAddressMojibake: (value: string) => value, countTokens: (value: string) => String(value ?? "").split(/\s+/).filter(Boolean).length, findLastAddressAssistantItem: () => ({ text: "1. Рабочая станция", debug: { detected_intent: "inventory_purchase_documents_for_item", extracted_filters: { item: "Рабочая станция" }, anchor_type: "item", anchor_value_resolved: "Рабочая станция" } }), findLastOrganizationClarificationAddressDebug: () => null, mergeKnownOrganizations: (values: unknown[]) => values, resolveOrganizationSelectionFromMessage: () => null, toNonEmptyString, buildAddressFollowupOffer: () => null, isImplicitAddressContinuationByLlm: () => false, isInventorySelectedObjectIntent: (intent: unknown) => [ "inventory_purchase_provenance_for_item", "inventory_purchase_documents_for_item", "inventory_sale_trace_for_item", "inventory_profitability_for_item", "inventory_purchase_to_sale_chain", "inventory_aging_by_purchase_date" ].includes(String(intent ?? "")), hasShortInventoryObjectFollowupSignal: () => false, resolveDebtRoleSwapFollowupIntent: () => null, hasAddressFollowupContextSignal: () => false, extractDisplayedEntityIndexMention: () => null, findRecentInventoryRootFrame: () => ({ intent: "inventory_on_hand_as_of_date", filters: { as_of_date: "2020-03-31", organization: 'ООО "Альтернатива Плюс"' }, anchorType: "organization", anchorValue: 'ООО "Альтернатива Плюс"' }), hasInventoryRootTemporalFollowupSignal: (message: string) => /март 2020/i.test(message), hasFollowupMarker: () => false, hasReferentialPointer: () => false, hasStandaloneAddressTopicSignal: () => false, resolveAddressIntent: () => ({ intent: "unknown" }), resolveAddressIntentFamily: (intent: unknown) => (intent ? String(intent) : null), readAddressFilterString: (debug: Record, key: string) => debug?.extracted_filters && typeof debug.extracted_filters === "object" ? toNonEmptyString((debug.extracted_filters as Record)[key]) : null, normalizeOrganizationScopeValue: (value: unknown) => toNonEmptyString(value), isInventoryDrilldownFrameIntent: (intent: unknown) => [ "inventory_purchase_provenance_for_item", "inventory_purchase_documents_for_item", "inventory_sale_trace_for_item", "inventory_profitability_for_item", "inventory_purchase_to_sale_chain", "inventory_aging_by_purchase_date" ].includes(String(intent ?? "")), isInventoryRootFrameIntent: (intent: unknown) => String(intent ?? "") === "inventory_on_hand_as_of_date", findRecentAddressFilterValue: () => null, hasForeignAccountingPivotOverInventoryMessage: () => false, buildRootScopedCarryoverFilters: (_previousFilters: Record, inventoryRootFrame: Record) => ({ ...(inventoryRootFrame?.filters ?? {}) }), inferDisplayedEntityTypeFromIntent: () => "item", extractDisplayedAddressEntityCandidates: () => [], resolveDisplayedAddressEntityMention: () => null, ...overrides }); } describe("assistantTransitionPolicy", () => { it("promotes inventory temporal follow-up into root-scoped carryover", () => { const policy = buildPolicy(); const carryover = policy.resolveAddressFollowupCarryoverContext( "остатки на март 2020", [], null, null, { session_context: { active_focus_object: { object_type: "item", label: "Рабочая станция" } } } ); expect(carryover?.followupSelectionMode).toBe("carry_root_context"); expect(carryover?.followupContext?.root_context_only).toBe(true); expect(carryover?.followupContext?.target_intent).toBe("inventory_on_hand_as_of_date"); expect(carryover?.followupContext?.root_intent).toBe("inventory_on_hand_as_of_date"); expect(carryover?.followupContext?.previous_filters).toEqual({ as_of_date: "2020-03-31", organization: 'ООО "Альтернатива Плюс"' }); }); it("builds continuation contract from extracted root carryover", () => { const policy = buildPolicy(); const contract = policy.buildAddressDialogContinuationContractV2( "остатки на эту дату", "остатки на эту дату", { followupContext: { root_intent: "inventory_on_hand_as_of_date", previous_anchor_type: "item", previous_anchor_value: "Рабочая станция" }, previousSourceIntent: "inventory_purchase_documents_for_item", previousAddressIntent: null, followupSelectionMode: "carry_root_context", hasImplicitContinuationSignal: true }, { predecomposeContract: { intent: "unknown" } } ); expect(contract.decision).toBe("continue_previous"); expect(contract.target_intent).toBe("inventory_on_hand_as_of_date"); expect(contract.decision_reasons).toContain("root_context_only_carryover"); expect(contract.decision_reasons).toContain("implicit_continuation_by_llm"); expect(contract.anchor_type).toBe("item"); expect(contract.anchor_value).toBe("Рабочая станция"); }); });