Coverage for transformer_lens/tools/model_registry/verification.py: 98%
50 statements
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-01 16:23 +0000
« prev ^ index » next coverage.py v7.10.1, created at 2026-09-01 16:23 +0000
1"""Verification tracking for model compatibility.
3This module provides dataclasses and utilities for tracking which models
4have been verified to work with TransformerLens.
5"""
7from dataclasses import dataclass, field
8from datetime import date, datetime
9from typing import Optional
12@dataclass
13class VerificationRecord:
14 """A record of a model verification.
16 Attributes:
17 model_id: The HuggingFace model ID that was verified
18 architecture_id: The architecture type of the model
19 verified_date: Date when verification was performed
20 verified_by: Who performed the verification (user, CI, etc.)
21 transformerlens_version: Version of TransformerLens used
22 notes: Optional notes about the verification
23 invalidated: Whether this verification has been invalidated
24 invalidation_reason: Reason for invalidation if applicable
25 """
27 model_id: str
28 verified_date: date
29 architecture_id: str = "Unknown"
30 verified_by: Optional[str] = None
31 transformerlens_version: Optional[str] = None
32 # P4 verdict flips are undiagnosable without knowing which profile and
33 # scoring scale produced the record.
34 prompt_profile: Optional[str] = None
35 p4_scoring_version: Optional[int] = None
36 notes: Optional[str] = None
37 invalidated: bool = False
38 invalidation_reason: Optional[str] = None
40 def to_dict(self) -> dict:
41 """Convert to a JSON-serializable dictionary."""
42 return {
43 "model_id": self.model_id,
44 "architecture_id": self.architecture_id,
45 "verified_date": self.verified_date.isoformat(),
46 "verified_by": self.verified_by,
47 "transformerlens_version": self.transformerlens_version,
48 "prompt_profile": self.prompt_profile,
49 "p4_scoring_version": self.p4_scoring_version,
50 "notes": self.notes,
51 "invalidated": self.invalidated,
52 "invalidation_reason": self.invalidation_reason,
53 }
55 @classmethod
56 def from_dict(cls, data: dict) -> "VerificationRecord":
57 """Create from a dictionary."""
58 return cls(
59 model_id=data["model_id"],
60 architecture_id=data.get("architecture_id", "Unknown"),
61 verified_date=date.fromisoformat(data["verified_date"]),
62 verified_by=data.get("verified_by"),
63 transformerlens_version=data.get("transformerlens_version"),
64 prompt_profile=data.get("prompt_profile"),
65 p4_scoring_version=data.get("p4_scoring_version"),
66 notes=data.get("notes"),
67 invalidated=data.get("invalidated", False),
68 invalidation_reason=data.get("invalidation_reason"),
69 )
72@dataclass
73class VerificationHistory:
74 """History of all model verifications.
76 Attributes:
77 records: List of all verification records
78 last_updated: When this history was last updated
79 """
81 records: list[VerificationRecord] = field(default_factory=list)
82 last_updated: Optional[datetime] = None
84 def to_dict(self) -> dict:
85 """Convert to a JSON-serializable dictionary."""
86 return {
87 "last_updated": self.last_updated.isoformat() if self.last_updated else None,
88 "records": [r.to_dict() for r in self.records],
89 }
91 @classmethod
92 def from_dict(cls, data: dict) -> "VerificationHistory":
93 """Create from a dictionary."""
94 last_updated = None
95 if data.get("last_updated"): 95 ↛ 97line 95 didn't jump to line 97 because the condition on line 95 was always true
96 last_updated = datetime.fromisoformat(data["last_updated"])
97 return cls(
98 records=[VerificationRecord.from_dict(r) for r in data.get("records", [])],
99 last_updated=last_updated,
100 )
102 def get_record(self, model_id: str) -> Optional[VerificationRecord]:
103 """Get the most recent valid verification record for a model.
105 Args:
106 model_id: The model ID to look up
108 Returns:
109 The verification record, or None if not found or invalidated
110 """
111 for record in reversed(self.records):
112 if record.model_id == model_id and not record.invalidated:
113 return record
114 return None
116 def is_verified(self, model_id: str) -> bool:
117 """Check if a model has a valid verification.
119 Args:
120 model_id: The model ID to check
122 Returns:
123 True if the model has a valid (non-invalidated) verification
124 """
125 return self.get_record(model_id) is not None
127 def add_record(self, record: VerificationRecord) -> None:
128 """Add a new verification record.
130 Args:
131 record: The verification record to add
132 """
133 self.records.append(record)
134 self.last_updated = datetime.now()
136 def invalidate(self, model_id: str, reason: str) -> bool:
137 """Invalidate the most recent verification for a model.
139 Args:
140 model_id: The model ID to invalidate
141 reason: Reason for invalidation
143 Returns:
144 True if a record was invalidated, False if not found
145 """
146 record = self.get_record(model_id)
147 if record:
148 record.invalidated = True
149 record.invalidation_reason = reason
150 self.last_updated = datetime.now()
151 return True
152 return False