Guardian-Agent / test_grader_direct.py
Prince9868's picture
Fix validator discovery for Phase 2: point openenv.yaml back to tasks.X.grader:grade
f18b8fb
Raw
History Blame Contribute Delete
3.64 kB
"""Test grader functions the way the OpenEnv validator would call them."""
from guardian_openenv.task_graders import (
grade_value_hotel_budget_guard,
grade_airline_seat_upsell_gauntlet,
grade_marketplace_ghost_checkout,
)
GRADERS = [
("value_hotel_budget_guard", grade_value_hotel_budget_guard),
("airline_seat_upsell_gauntlet", grade_airline_seat_upsell_gauntlet),
("marketplace_ghost_checkout", grade_marketplace_ghost_checkout),
]
print("=== Test 1: Called with no arguments ===")
for task_id, fn in GRADERS:
result = fn()
score = result["score"]
valid = 0 < score < 1
print(f" {task_id}: score={score} valid={valid}")
if not valid:
print(f" *** FAIL: score is out of (0,1) range!")
# Check breakdown
for k, v in result.get("grader_breakdown", {}).items():
if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
print(f" *** breakdown {k}={v} OUT OF RANGE")
print()
print("=== Test 2: Called with trajectory=[] ===")
for task_id, fn in GRADERS:
result = fn(trajectory=[])
score = result["score"]
valid = 0 < score < 1
print(f" {task_id}: score={score} valid={valid}")
print()
print("=== Test 3: Called with environment=None, trajectory=[] ===")
for task_id, fn in GRADERS:
result = fn(environment=None, trajectory=[])
score = result["score"]
valid = 0 < score < 1
print(f" {task_id}: score={score} valid={valid}")
print()
print("=== Test 4: Run full episode then grade ===")
from guardian_openenv.environment import GuardianReviewEnvironment
from guardian_openenv.models import GuardianAction, ActionType
env = GuardianReviewEnvironment()
for task_id, fn in GRADERS:
env.reset(task_id)
# Take a few actions
env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id=env._task.sections[0].section_id))
env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
# Now grade using the environment
result = fn(environment=env)
score = result["score"]
valid = 0 < score < 1
print(f" {task_id}: score={score} valid={valid}")
if not valid:
print(f" *** FAIL: score is out of (0,1) range!")
for k, v in result.get("grader_breakdown", {}).items():
if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
print(f" *** breakdown {k}={v} OUT OF RANGE")
print()
print("=== Test 5: Grade with state dict (as validator might pass) ===")
for task_id, fn in GRADERS:
env.reset(task_id)
state_dict = env.state().model_dump()
result = fn(environment=state_dict)
score = result["score"]
valid = 0 < score < 1
print(f" {task_id}: score={score} valid={valid}")
print()
print("=== Test 6: inference_scores.json check ===")
import json
from pathlib import Path
scores_path = Path("outputs/inference_scores.json")
if scores_path.exists():
data = json.loads(scores_path.read_text())
for task in data.get("tasks", []):
tid = task["task_id"]
fs = task.get("score")
if fs is not None:
valid = 0 < fs < 1
print(f" {tid}: score={fs} valid={valid}")
else:
print(f" {tid}: MISSING score FIELD")
valid = False
if not valid:
print(f" *** FAIL!")
for k, v in task.get("grader_breakdown", {}).items():
if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
print(f" *** breakdown {k}={v} OUT OF RANGE")
ms = data.get("mean_score")
print(f" mean_score={ms} valid={0 < ms < 1}")
else:
print(" (file not found)")
print()
print("ALL TESTS COMPLETE")