"""Base interfaces for token-level hallucination baseline detectors. Concrete baseline implementations live in follow-up branches. """ from __future__ import annotations from abc import ABC, abstractmethod from pathlib import Path from typing import Sequence from .structs import BaselineExample, TokenScoreResult class TokenScoreDetector(ABC): """Interface for baselines that return one score per answer token.""" @abstractmethod def score( self, prompt: str, answer: str, answer_token_ids: Sequence[int] | None = None, ) -> TokenScoreResult: """Score generated answer tokens conditioned on the original prompt.""" raise NotImplementedError class TrainableTokenScoreDetector(TokenScoreDetector): """Interface for token-score baselines that require fitting.""" @abstractmethod def fit(self, examples: Sequence[BaselineExample]) -> "TrainableTokenScoreDetector": """Fit the detector on labelled prompt/answer examples.""" raise NotImplementedError @abstractmethod def save(self, path: str | Path) -> None: """Persist the fitted detector.""" raise NotImplementedError @classmethod @abstractmethod def load(cls, path: str | Path) -> "TrainableTokenScoreDetector": """Load a fitted detector.""" raise NotImplementedError