diff --git a/docs/module-internals.md b/docs/module-internals.md index 69deca3..684d5ae 100644 --- a/docs/module-internals.md +++ b/docs/module-internals.md @@ -1166,7 +1166,8 @@ entry point. Its NPZ schema contains only complex spectral filters, spatial templates, and thresholds; the runtime pins the Hub revision and SHA-256, rejects unknown fields and invalid shapes, and never loads pickles. The result has `watermark_truth="unknown"` even when a provider pattern matches. A -simultaneous provider match abstains. Tests in +simultaneous provider match abstains. `PROVIDERS` exports only the calibrated +provider labels for callers that route processing from a source hint. Tests in `tests/test_source_classify_v2.py` cover the public seam and changed-threshold behavior; the [model card](image-source-hf/README.md) records the frozen aggregate evidence and limits. This does not change the earlier diff --git a/src/remove_ai_watermarks/source_classify_v2.py b/src/remove_ai_watermarks/source_classify_v2.py index ca2a00e..05e27d1 100644 --- a/src/remove_ai_watermarks/source_classify_v2.py +++ b/src/remove_ai_watermarks/source_classify_v2.py @@ -12,7 +12,7 @@ from functools import lru_cache from hashlib import file_digest from importlib import import_module from pathlib import Path -from typing import TYPE_CHECKING, Any, Literal +from typing import TYPE_CHECKING, Any, Literal, get_args if TYPE_CHECKING: from numpy.typing import NDArray @@ -51,6 +51,7 @@ CLAIM = "likely image source/export pattern; not SynthID detection" SourceLabel = Literal["openai", "google", "unknown"] SourceReason = Literal["classified", "abstained", "conflict", "feature_unavailable"] +PROVIDERS = tuple(label for label in get_args(SourceLabel) if label != "unknown") @dataclass(frozen=True) diff --git a/tests/test_source_classify_v2.py b/tests/test_source_classify_v2.py index cc5fd7d..8f61b68 100644 --- a/tests/test_source_classify_v2.py +++ b/tests/test_source_classify_v2.py @@ -61,6 +61,7 @@ def test_top_level_api_is_lazy_and_points_to_new_runtime() -> None: assert raiw.classify_image_source is model.classify_image_source assert raiw.ImageSourceClassification is model.ImageSourceClassification + assert model.PROVIDERS == ("openai", "google") assert len(model.WEIGHTS_REVISION) == 40 assert all(character in "0123456789abcdef" for character in model.WEIGHTS_REVISION)