"""Does clicking this element commit something? (decosa-commit-detector) python usage.py '{"role":"button","name":"Weiter","heading":"Bestellung prüfen","title":"Kasse","url":"/checkout/review","context":"Gesamt 49,90 EUR, zahlungspflichtig"}' Apache-2.0, Copyright 2026 Decosa. """ import json import sys import torch from transformers import AutoModelForSequenceClassification, AutoTokenizer REPO = "decosaai/decosa-commit-detector-xlmr-large" def text_of(r: dict) -> str: """The exact input format used in training: element first, so truncation only cuts page text.""" parts = [f"{r.get('role', '')}: {r.get('name', '')}"] for k in ("heading", "title", "url", "context"): v = (r.get(k) or "").strip() if v: parts.append(f"{k}: {v}") return " | ".join(parts) class CommitDetector: def __init__(self, repo: str = REPO, threshold_pnone: float | None = None): from huggingface_hub import hf_hub_download import os path = os.path.join(repo, "decosa_commit.json") if os.path.isdir(repo) else hf_hub_download(repo, "decosa_commit.json") self.cfg = json.load(open(path)) self.tok = AutoTokenizer.from_pretrained(repo) self.model = AutoModelForSequenceClassification.from_pretrained(repo).eval() self.thr = threshold_pnone if threshold_pnone is not None else self.cfg["safety_threshold_pnone"] @torch.no_grad() def __call__(self, rows: list[dict]) -> list[dict]: x = self.tok([text_of(r) for r in rows], truncation=True, max_length=self.cfg["maxlen"], padding=True, return_tensors="pt") P = torch.softmax(self.model(**x).logits.float(), -1).tolist() out = [] for p in P: probs = dict(zip(self.cfg["kinds"], p)) commit = probs["none"] < self.thr kind = max((k for k in self.cfg["kinds"] if k != "none"), key=probs.get) if commit else "none" out.append({"commit": commit, "kind": kind, "probs": {k: round(v, 4) for k, v in probs.items()}}) return out if __name__ == "__main__": repo = sys.argv[2] if len(sys.argv) > 2 else REPO print(json.dumps(CommitDetector(repo)([json.loads(sys.argv[1])])[0], ensure_ascii=False))