ГЛОБАЛЬНЫЙ РЕФАКТОРИНГ АРХИТЕКТУРЫ - Рефакторинг этапов 3.1 - Добавлен строгий контракт семантического извлечения (валидность, качество, reason-codes, рекомендация применять canonical). Подключен semantic guard в predecompose/runtime: мягкое отклонение плохого canonical: отдельный safe-кейс для сырого полезного raw-фрагмента; fallback теперь выигрывает только когда это оправдано. Подключty semantic arbitration в tool-gate
This commit is contained in:
@@ -1047,14 +1047,16 @@ describe("assistant address llm pre-decompose candidate preference", () => {
|
||||
} as any);
|
||||
|
||||
expect(response.ok).toBe(true);
|
||||
expect(response.reply_type).toBe("factual");
|
||||
expect(calls).toHaveLength(1);
|
||||
expect(calls[0].message).toBe("заказчики компании svk");
|
||||
expect(response.debug?.llm_decomposition_attempted).toBe(true);
|
||||
expect(response.debug?.llm_decomposition_applied).toBe(true);
|
||||
expect(response.debug?.llm_canonical_candidate_detected).toBe(true);
|
||||
expect(response.debug?.tool_gate_decision).toBe("run_address_lane");
|
||||
expect(["llm_canonical_candidate_detected", "llm_canonical_data_signal_detected", "address_mode_classifier_detected"]).toContain(response.debug?.tool_gate_reason);
|
||||
expect(response.reply_type).toBe("clarification_required");
|
||||
expect(calls).toHaveLength(0);
|
||||
expect(response.debug?.address_tool_gate_decision).toBe("skip_address_lane");
|
||||
expect(
|
||||
[
|
||||
"llm_predecompose_semantic_guard_rejected",
|
||||
"llm_predecompose_unsupported_mode",
|
||||
"address_signal_unsupported_intent_fallback_to_deep"
|
||||
]
|
||||
).toContain(response.debug?.address_tool_gate_reason);
|
||||
});
|
||||
|
||||
it("normalizes short ordinal year like '20й' in noisy docs phrasing", async () => {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user