CoolFace
Apppublic

Pandago/graphstrike-model-training

sourceHugging Facemitupdated 5mo agoView on Hugging Face
0likes
models.py138 linesDownload Raw Back to root
1from __future__ import annotations2 3from enum import Enum4from typing import Dict, List, Optional5 6from pydantic import BaseModel7 8# ---------------------------------------------------------------------------9# OpenEnv base types10# Use real SDK when available; fall back to stubs for local dev without SDK.11# ---------------------------------------------------------------------------12try:13    from openenv.core.env_server import Action, Observation, State  # type: ignore14except ImportError:15    class Action(BaseModel):  # type: ignore[no-redef]16        pass17 18    class Observation(BaseModel):  # type: ignore[no-redef]19        done: bool = False20        reward: Optional[float] = None21 22    class State(BaseModel):  # type: ignore[no-redef]23        episode_id: str = ""24        step_count: int = 025 26# ---------------------------------------------------------------------------27# Domain types28# ---------------------------------------------------------------------------29 30class ActionType(str, Enum):31    INSPECT = "inspect"                       # reveal full profile + edges, costs 1 step32    INVESTIGATE_NETWORK = "investigate_network"  # expand graph 1 hop, costs 2 steps33    FLAG = "flag"                             # mark account fake (free)34    UNFLAG = "unflag"                         # unmark account (free)35    SUBMIT = "submit"                         # end episode, trigger scoring36    # Round 2: New tool-call actions37    REVERSE_IMAGE_SEARCH = "reverse_image_search"  # reveal photo_reuse_score, costs 1 step38    ANALYZE_BIO = "analyze_bio"               # reveal bio_template_score, costs 1 step39    CHECK_IP = "check_ip"                     # reveal ip_cluster_signal, costs 2 steps40    GET_POLICY = "get_policy"                 # get platform policy, costs 0 steps41 42 43class AccountStatus(str, Enum):44    NORMAL = "normal"45    SUSPECT = "suspect"           # auto-elevated when a neighbor is flagged46    CONFIRMED_FAKE = "confirmed_fake"  # agent explicitly flagged this account47 48 49class FakeGangAction(Action):50    action_type: ActionType51    account_id: Optional[str] = None  # required for all actions except SUBMIT52 53 54class AccountProfile(BaseModel):55    account_id: str56    follower_count: int57    following_count: int58    post_count: int59    avg_post_hour: float        # 0–2360    photo_reuse_score: float    # 0–1 — pre-computed: fraction of posts using stolen celebrity photos61    bio_template_score: float   # 0–1 — pre-computed: cosine similarity to known fake bio templates62    account_age_days: int63    name_change_count: int = 0  # incremented by hard-mode evasion events64 65    # ── Derived graph features (computed at INSPECT time from live graph state) ──66    flagged_neighbor_count: int = 0    # how many of this account's follows are currently flagged67                                       # high value = deep inside a cluster you're already tracking68    mutual_follow_rate: float = 0.0    # fraction of follows that also follow back (0–1)69                                       # real fans: low; fake gangs: high (they mutually inflate each other)70    avg_neighbor_photo_reuse: float = 0.0  # mean photo_reuse_score of inspected follows71                                           # gang members cluster: if neighbors are fake, this is high72 73    visible_follows: List[str] = []    # IDs of accounts this account follows (revealed by INSPECT)74 75    # ── Account status ──76    status: AccountStatus = AccountStatus.NORMAL77 78    # ── Full risk breakdown (computed via scoring.py at INSPECT time) ──79    fake_risk_score: float = 0.080    node_risk: float = 0.081    behavior_risk: float = 0.082    graph_risk: float = 0.083    hub_legitimacy_score: float = 0.084 85    # ── New raw features (from generator) ──86    comment_repeat_score: float = 0.0   # fakes: 0.6-0.9 | decoys: 0.1-0.3 | reals: 0.0-0.0887    shared_ip_count: int = 0            # fakes: 9 (gang shares 1 IP) | reals: 0-188 89    # ── Extended runtime graph features ──90    inspected_neighbor_count: int = 0   # denominator for flagged_neighbor_ratio91    post_hour_cluster_score: float = 0.0  # hour alignment to flagged cluster mean92    suspicious_mutual_ratio: float = 0.0  # used in hub legitimacy computation93 94 95class FakeGangObservation(Observation):96    visible_accounts: List[AccountProfile] = []97    visible_account_ids: List[str] = []   # all account IDs the agent knows exist98    flagged_ids: List[str] = []99    inspected_ids: List[str] = []100    graph_edges: Dict[str, List[str]] = {}  # account_id -> list of accounts it follows101    steps_remaining: int = 0102    evasion_triggered: bool = False103    evasion_count: int = 0104    task: str = "easy"105    message: str = ""106    suspect_ids: List[str] = []  # auto-elevated neighbors of flagged accounts107    platform: str = ""  # Round 2: Platform name (Instagram/Snapchat) - passed from state108 109 110class FakeGangState(State):111    task: str = "easy"112    score_so_far: float = 0.0113    evasion_count: int = 0114    network_size: int = 0115    gang_size: int = 10116    episode_seed: int = 0117    platform: str = ""  # Round 2: Platform name (Instagram/Snapchat)118 119 120# ---------------------------------------------------------------------------121# Round 2: Platform Policy Model122# ---------------------------------------------------------------------------123 124class PlatformPolicy(BaseModel):125    """Dynamically compiled platform policy from transparency reports."""126    platform: str                    # "Instagram" or "Snapchat"127    threshold: float                 # θ* - computed Bayesian threshold for flagging128    base_rate: float                 # π - prevalence of fake accounts129    fn_cost_signal: str              # "low" | "medium" | "high" | "critical"130    fp_cost_signal: str              # "low" | "medium" | "high"131    harm_weight: float               # enforcement vs creator balance (0.5-2.0)132    primary_enforcement_signal: str  # "photo_reuse" | "bio_template" | "ip_cluster"133    fp_penalty_weight: float         # C_fp for reward function134    sources: List[str] = []          # URLs used for extraction135    confidence: float = 0.0          # LLM extraction confidence (0.0-1.0)136    compiled_at: str = ""            # ISO timestamp137    used_fallback: bool = False      # True if fallback policy was used due to extraction failure138