netweaver_sre / local_validator.py
Shasidharyadav
fix: clamp all scores strictly to (0.001, 0.999) - fix Phase 2 validation
45e4806
Raw
History Blame Contribute Delete
6.15 kB
"""
local_validator.py — Pre-submission validation for OpenEnv.
Checks:
1. openenv.yaml has 3+ tasks with inline grader: blocks
2. inference.py has proper [START]/[END] format
3. Task IDs match between openenv.yaml and inference.py
4. Score clamping is in place
"""
import yaml
import re
import sys
def check_openenv_yaml():
"""Verify openenv.yaml has 3+ tasks with inline graders."""
print("=" * 60)
print("CHECK 1: openenv.yaml — Tasks with inline graders")
print("=" * 60)
try:
with open("openenv.yaml", "r") as f:
d = yaml.safe_load(f)
except FileNotFoundError:
print(" FAIL: openenv.yaml not found!")
return False, []
tasks = d.get("tasks", [])
if not tasks:
print(" FAIL: No 'tasks' block found in openenv.yaml")
return False, []
ok = 0
task_ids = []
for t in tasks:
tid = t.get("id", "UNKNOWN")
task_ids.append(tid)
has_grader = t.get("grader") is not None
grader_type = t.get("grader", {}).get("type", "N/A") if has_grader else "N/A"
grader_endpoint = t.get("grader", {}).get("endpoint", "N/A") if has_grader else "N/A"
status = "OK" if has_grader else "FAIL"
print(f" {status} {tid}")
print(f" grader={has_grader} type={grader_type} endpoint={grader_endpoint}")
if has_grader:
ok += 1
print(f"\n Tasks with graders: {ok}/{len(tasks)}")
passed = ok >= 3
print(f" {'PASS' if passed else 'FAIL'}: need at least 3")
return passed, task_ids
def check_inference_py(yaml_task_ids):
"""Verify inference.py has matching task IDs and proper format."""
print("\n" + "=" * 60)
print("CHECK 2: inference.py — Task IDs and format")
print("=" * 60)
try:
with open("inference.py", "r") as f:
content = f.read()
except FileNotFoundError:
print(" FAIL: inference.py not found!")
return False
all_ok = True
# Check API_KEY usage (not HF_TOKEN as primary)
if 'os.environ.get("API_KEY")' in content:
print(" OK Uses API_KEY env var")
else:
print(" FAIL Missing os.environ.get('API_KEY')")
all_ok = False
# Check API_BASE_URL usage
if 'os.environ.get("API_BASE_URL"' in content:
print(" OK Uses API_BASE_URL env var")
else:
print(" FAIL Missing API_BASE_URL")
all_ok = False
# Check for from_docker_image
if "from_docker_image" in content:
print(" FAIL Uses from_docker_image() — must use HTTP requests")
all_ok = False
else:
print(" OK No from_docker_image() usage")
# Check [START] format
if "[START] task=" in content:
print(" OK Has [START] task= format")
else:
print(" FAIL Missing [START] task= format")
all_ok = False
# Check [END] format with task= and score=
if "task=" in content and "score=" in content:
print(" OK Has [END] with task= and score= fields")
else:
print(" FAIL Missing task= or score= in [END] line")
all_ok = False
# Check score clamping
if "0.001" in content and "0.999" in content:
print(" OK Score clamping to (0.001, 0.999)")
else:
print(" WARN Score clamping might be missing")
# Check that TASKS list matches openenv.yaml task IDs
print("\n Task ID matching:")
for tid in yaml_task_ids:
if tid in content:
print(f" OK '{tid}' found in inference.py")
else:
print(f" FAIL '{tid}' NOT found in inference.py")
all_ok = False
# Check task count in TASKS list
task_count = content.count('"netweaver_sre_')
print(f"\n Task references in code: {task_count}")
# Check finally: block for guaranteed [END]
if "finally:" in content:
print(" OK Has finally: block for guaranteed [END] emission")
else:
print(" WARN No finally: block — [END] may not emit on crash")
return all_ok
def check_environment():
"""Verify the environment clamps scores."""
print("\n" + "=" * 60)
print("CHECK 3: Environment — Score clamping")
print("=" * 60)
try:
with open("server/netweaver_sre_environment.py", "r") as f:
content = f.read()
except FileNotFoundError:
print(" FAIL: server/netweaver_sre_environment.py not found!")
return False
if "clamp_score" in content:
print(" OK Uses clamp_score() function")
else:
print(" WARN No clamp_score() found — check manual clamping")
if "0.001" in content and "0.999" in content:
print(" OK Clamp boundaries set to (0.001, 0.999)")
else:
print(" FAIL Clamp boundaries might allow 0.0 or 1.0")
return False
# Check for exact 0.0 or 1.0 reward returns
lines = content.split("\n")
for i, line in enumerate(lines, 1):
stripped = line.strip()
if "reward" in stripped and ("= 0.0" in stripped or "= 1.0" in stripped):
if "clamp_score" not in stripped and "raw_score" not in stripped:
print(f" WARN Line {i}: Possible unclamped reward: {stripped}")
return True
def main():
print("\n>>> OpenEnv Pre-Submission Validator")
print("=" * 60)
yaml_ok, task_ids = check_openenv_yaml()
inference_ok = check_inference_py(task_ids)
env_ok = check_environment()
print("\n" + "=" * 60)
print("SUMMARY")
print("=" * 60)
results = [
("openenv.yaml — 3+ tasks with graders", yaml_ok),
("inference.py — format and task IDs", inference_ok),
("Environment — score clamping", env_ok),
]
all_pass = True
for name, passed in results:
status = "[PASS]" if passed else "[FAIL]"
print(f" {status} {name}")
if not passed:
all_pass = False
print()
if all_pass:
print("*** All checks passed! Ready to submit. ***")
else:
print("!!! Fix the above issues before submitting. !!!")
sys.exit(1)
if __name__ == "__main__":
main()