Kansho/backend/tests/test_privacy_detect_eval.py
2026-08-28 08:40:28 +02:00

46 lines
1.7 KiB
Python

"""Eval harness contract. Does not call a live provider."""
from __future__ import annotations
import os
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
os.environ.setdefault("KANSHO_FAKE_DETECT", "1")
from entity_detect_eval import CASES, run_fake, score_spans
def expect(ok: bool, message: str) -> None:
if not ok:
raise SystemExit(f"FAIL: {message}")
print(f"OK {message}")
def main() -> None:
payload = run_fake()
expect(payload["mode"] == "fake", "eval default is fake")
expect(payload["live_quality"] == "unconfirmed", "live quality stays unconfirmed")
expect(payload["detect_model_unconfirmed"] == "openai/gpt-4.1-nano", "configured detect model stays unconfirmed")
expect(len(payload["cases"]) >= 8, "synthetic span cases exist")
person = next(item for item in CASES if item["id"] == "no_sentence_span")
metrics = score_spans(
[{"start": 9, "end": 13, "text": "Anna", "entity_type": "PERSON"}],
person["expected"],
)
expect(metrics["expected_found"] == 1, "exact expected span is counted")
expect(metrics["precision"] == 1.0 and metrics["recall"] == 1.0, "exact span match is precision 1")
wrong = score_spans(
[{"start": 0, "end": 28, "text": "Ich traf Anna am Nachmittag.", "entity_type": "PERSON"}],
person["expected"],
)
expect(wrong["unexpected"] == 1, "sentence-sized span is unexpected")
food = next(item for item in payload["cases"] if item["id"] == "same_word_two_roles")
expect(food["entities"]["metrics"]["expected_found"] == 1, "fake contract finds only the identity sushi")
print("All detect eval harness tests passed.")
if __name__ == "__main__":
main()