import { describe, expect, it } from "vitest"; import { buildAddressLlmPredecomposeContractV1, buildAddressSemanticExtractionContractV1 } from "../src/services/address_runtime/predecomposeContract"; describe("address semantic extraction contract", () => { it("rejects low-confidence unsupported rewrite without data signal", () => { const sourceMessage = "yo"; const canonicalMessage = "yoft"; const predecomposeContract = buildAddressLlmPredecomposeContractV1({ sourceMessage, canonicalMessage }); const semantic = buildAddressSemanticExtractionContractV1({ sourceMessage, canonicalMessage, predecomposeContract }); expect(semantic.schema_version).toBe("address_semantic_extraction_contract_v1"); expect(semantic.guard_hints.source_data_signal_detected).toBe(false); expect(semantic.guard_hints.canonical_data_signal_detected).toBe(false); expect(semantic.guard_hints.unsupported_low_confidence).toBe(true); expect(semantic.valid).toBe(false); expect(semantic.apply_canonical_recommended).toBe(false); expect(semantic.reason_codes).toContain("unsupported_low_confidence_contract"); }); it("flags semantic drift when canonical loses data intent", () => { const sourceMessage = "покажи документы по договору 12"; const canonicalMessage = "помоги разобраться"; const semantic = buildAddressSemanticExtractionContractV1({ sourceMessage, canonicalMessage }); expect(semantic.guard_hints.source_data_signal_detected).toBe(true); expect(semantic.guard_hints.canonical_data_signal_detected).toBe(false); expect(semantic.guard_hints.semantic_drift_suspected).toBe(true); expect(semantic.valid).toBe(false); expect(semantic.apply_canonical_recommended).toBe(false); expect(semantic.reason_codes).toContain("semantic_drift_source_vs_canonical"); }); it("keeps canonical rewrite when semantic contract remains coherent", () => { const sourceMessage = "Покажи незакрытые договоры на 2020-12-31"; const canonicalMessage = "Показать незакрытые договоры по состоянию на конец декабря 2020 года."; const semantic = buildAddressSemanticExtractionContractV1({ sourceMessage, canonicalMessage }); expect(semantic.guard_hints.source_data_signal_detected).toBe(true); expect(semantic.guard_hints.canonical_data_signal_detected).toBe(true); expect(semantic.valid).toBe(true); expect(semantic.apply_canonical_recommended).toBe(true); expect(["high", "medium"]).toContain(semantic.quality); }); });