saiK90/image-forensics-env
0
1"""2Typed data models for ImageForensicsEnv.3Defines the Action and Observation contracts for the OpenEnv spec.4"""5 6from pydantic import BaseModel, Field7from typing import Optional, Literal, List, Dict, Any8 9 10# ── Action ────────────────────────────────────────────────────────────────────11 12class ForensicsAction(BaseModel):13 """14 Action submitted by the agent after observing image features.15 16 verdict : The agent's classification decision.17 confidence : Agent's confidence score 0.0–1.0.18 reasoning : Optional chain-of-thought explanation (used for grading bonuses).19 task_id : Which task the agent is responding to.20 """21 verdict: Literal["AI_GENERATED", "AUTHENTIC", "UNCERTAIN"]22 confidence: float = Field(ge=0.0, le=1.0, description="Agent confidence 0.0–1.0")23 reasoning: Optional[str] = Field(default=None, description="Optional CoT reasoning")24 task_id: str = Field(description="Task ID: easy_detection | medium_detection | hard_detection")25 26 27# ── Observation ───────────────────────────────────────────────────────────────28 29class SignalFeature(BaseModel):30 """A single forensic signal feature extracted from the image."""31 name: str32 score: float = Field(ge=0.0, le=1.0, description="Signal anomaly score 0=natural, 1=synthetic")33 description: str34 35 36class ForensicsObservation(BaseModel):37 """38 Observation returned to the agent after reset() or step().39 40 image_id : Unique identifier for the current image sample.41 task_id : Active task difficulty level.42 signals : List of forensic feature signals for the agent to reason over.43 image_b64 : Base64-encoded image (JPEG). Multimodal agents can use this directly.44 ground_truth : Only revealed after step() — None during reset().45 reward : Reward received for the last action (0.0 on reset).46 done : Whether the current episode is complete.47 success : Whether the last action was correct.48 feedback : Human-readable feedback string.49 step_count : Number of steps taken in this episode.50 """51 image_id: str52 task_id: str53 signals: List[SignalFeature]54 image_b64: Optional[str] = Field(default=None, description="Base64 JPEG for multimodal agents")55 ground_truth: Optional[Literal["AI_GENERATED", "AUTHENTIC"]] = None56 reward: float = 0.057 done: bool = False58 success: Optional[bool] = None59 feedback: str = ""60 step_count: int = 061 metadata: Dict[str, Any] = Field(default_factory=dict)62 