payops_env / server /graders.py
padmapriyagosakan's picture
Add score:0.5 to all YAML tasks, make graders callable without args, fix health status
f4fa44f
Raw
History Blame Contribute Delete
6.04 kB
"""
Grader callables for PayOps OpenEnv tasks.
Referenced from openenv.yaml as: server.graders:EASY001Grader
Each grader is fully self-contained (zero external imports) so the platform
validator can import and call them in any isolated environment.
Returns {"score": float, "feedback": str} as required by the platform.
Scores are always strictly in (0, 1) — never exactly 0.0 or 1.0.
"""
from __future__ import annotations
# Platform requires scores strictly between 0 and 1 (exclusive).
_SCORE_MIN = 0.001
_SCORE_MAX = 0.999
def _clamp(score: float) -> float:
"""Clamp score to the open interval (0, 1)."""
if score <= 0.0:
return _SCORE_MIN
if score >= 1.0:
return _SCORE_MAX
return score
class _BaseGrader:
"""
Self-contained base grader.
Subclasses set:
correct_action : str
partial_credit : dict[str, float] (action -> score, all in (0, 1))
"""
correct_action: str = ""
partial_credit: dict = {}
def grade(self, action: str = "", **kwargs):
if not action:
return {"score": 0.5, "feedback": "No action provided"}
if action == self.correct_action:
return {"score": _SCORE_MAX, "feedback": "Correct action"}
raw = float(self.partial_credit.get(action, 0.0))
score = _clamp(raw)
return {
"score": score,
"feedback": "Partial credit" if raw > 0 else "Incorrect action",
}
def __call__(self, *args, **kwargs):
action = args[0] if args else kwargs.get("action", "")
return self.grade(action, **{k: v for k, v in kwargs.items() if k != "action"})
# ── Easy ─────────────────────────────────────────────────────────────────────
class EASY001Grader(_BaseGrader):
correct_action = "approve"
partial_credit = {}
class EASY002Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.4}
class EASY003Grader(_BaseGrader):
correct_action = "approve"
partial_credit = {}
class EASY004Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"escalate": 0.6, "hold": 0.5}
class EASY005Grader(_BaseGrader):
correct_action = "approve"
partial_credit = {}
class EASY006Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"hold": 0.6}
# ── Medium ────────────────────────────────────────────────────────────────────
class MED001Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"flag": 0.5, "hold": 0.4}
class MED002Grader(_BaseGrader):
correct_action = "hold"
partial_credit = {"escalate": 0.6, "flag": 0.4}
class MED003Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"hold": 0.5, "escalate": 0.3}
class MED004Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"escalate": 0.5, "hold": 0.4}
class MED005Grader(_BaseGrader):
correct_action = "hold"
partial_credit = {"flag": 0.5, "escalate": 0.4}
class MED006Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"flag": 0.4, "hold": 0.5}
class MED007Grader(_BaseGrader):
correct_action = "hold"
partial_credit = {"escalate": 0.6, "flag": 0.4}
class MED008Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"hold": 0.6, "escalate": 0.4}
# ── Hard ──────────────────────────────────────────────────────────────────────
class HARD001Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"flag": 0.6, "hold": 0.5, "reject": 0.3}
class HARD002Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.6, "hold": 0.5, "flag": 0.3}
class HARD003Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.5, "flag": 0.2}
class HARD004Grader(_BaseGrader):
correct_action = "approve"
partial_credit = {"escalate": 0.5, "hold": 0.4, "flag": 0.3}
class HARD005Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"flag": 0.5, "hold": 0.4, "reject": 0.3}
class HARD006Grader(_BaseGrader):
correct_action = "flag"
partial_credit = {"hold": 0.6, "escalate": 0.5}
class HARD007Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"hold": 0.5, "escalate": 0.4, "flag": 0.3}
class HARD008Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"hold": 0.5, "escalate": 0.4, "flag": 0.3}
class HARD009Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"hold": 0.5, "flag": 0.4, "reject": 0.3}
class HARD010Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"hold": 0.5, "escalate": 0.4, "flag": 0.3}
# ── Critical ──────────────────────────────────────────────────────────────────
class CRIT001Grader(_BaseGrader):
correct_action = "approve"
partial_credit = {"escalate": 0.5, "hold": 0.4, "flag": 0.3}
class CRIT002Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.4, "flag": 0.2}
class CRIT003Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"flag": 0.4, "hold": 0.35, "reject": 0.3}
class CRIT004Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.5, "hold": 0.4}
class CRIT005Grader(_BaseGrader):
correct_action = "reject"
partial_credit = {"escalate": 0.5, "hold": 0.4}
class CRIT006Grader(_BaseGrader):
correct_action = "escalate"
partial_credit = {"hold": 0.5, "reject": 0.4}