Prince9868 commited on
Commit
f18b8fb
·
1 Parent(s): 1702b97

Fix validator discovery for Phase 2: point openenv.yaml back to tasks.X.grader:grade

Browse files
openenv.yaml CHANGED
@@ -20,7 +20,7 @@ tasks:
20
  are fake, estimate the true final price against the shopper budget,
21
  and decide if the shopper should proceed.
22
  difficulty: "easy"
23
- grader: "guardian_openenv.task_graders:grade_value_hotel_budget_guard"
24
 
25
  - id: "airline_seat_upsell_gauntlet"
26
  name: "Navigate an airline upsell funnel before purchase"
@@ -30,7 +30,7 @@ tasks:
30
  is fake, calculate the true checkout total, and recommend whether to
31
  continue.
32
  difficulty: "medium"
33
- grader: "guardian_openenv.task_graders:grade_airline_seat_upsell_gauntlet"
34
 
35
  - id: "marketplace_ghost_checkout"
36
  name: "Run a ghost checkout before the shopper commits"
@@ -40,4 +40,4 @@ tasks:
40
  verify timers, and determine the real final total before the shopper
41
  falls for sunk-cost pressure.
42
  difficulty: "hard"
43
- grader: "guardian_openenv.task_graders:grade_marketplace_ghost_checkout"
 
20
  are fake, estimate the true final price against the shopper budget,
21
  and decide if the shopper should proceed.
22
  difficulty: "easy"
23
+ grader: "tasks.value_hotel_budget_guard.grader:grade"
24
 
25
  - id: "airline_seat_upsell_gauntlet"
26
  name: "Navigate an airline upsell funnel before purchase"
 
30
  is fake, calculate the true checkout total, and recommend whether to
31
  continue.
32
  difficulty: "medium"
33
+ grader: "tasks.airline_seat_upsell_gauntlet.grader:grade"
34
 
35
  - id: "marketplace_ghost_checkout"
36
  name: "Run a ghost checkout before the shopper commits"
 
40
  verify timers, and determine the real final total before the shopper
41
  falls for sunk-cost pressure.
42
  difficulty: "hard"
43
+ grader: "tasks.marketplace_ghost_checkout.grader:grade"
server/app.py CHANGED
@@ -81,7 +81,7 @@ def list_tasks() -> list[dict]:
81
  "description": task.objective,
82
  "difficulty": task.difficulty,
83
  "has_grader": True,
84
- "grader": f"guardian_openenv.task_graders:grade_{task.task_id.replace('-', '_')}",
85
  })
86
  return results
87
 
 
81
  "description": task.objective,
82
  "difficulty": task.difficulty,
83
  "has_grader": True,
84
+ "grader": f"tasks.{task.task_id}.grader:grade",
85
  })
86
  return results
87
 
test_grader_direct.py CHANGED
@@ -6,9 +6,9 @@ from guardian_openenv.task_graders import (
6
  )
7
 
8
  GRADERS = [
9
- ("value-hotel-budget-guard", grade_value_hotel_budget_guard),
10
- ("airline-seat-upsell-gauntlet", grade_airline_seat_upsell_gauntlet),
11
- ("marketplace-ghost-checkout", grade_marketplace_ghost_checkout),
12
  ]
13
 
14
  print("=== Test 1: Called with no arguments ===")
 
6
  )
7
 
8
  GRADERS = [
9
+ ("value_hotel_budget_guard", grade_value_hotel_budget_guard),
10
+ ("airline_seat_upsell_gauntlet", grade_airline_seat_upsell_gauntlet),
11
+ ("marketplace_ghost_checkout", grade_marketplace_ghost_checkout),
12
  ]
13
 
14
  print("=== Test 1: Called with no arguments ===")
test_live_space.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Test the live HF Space grader endpoint with step+grade flow."""
2
+ import requests
3
+ import json
4
+
5
+ BASE = "https://prince9868-guardian-agent.hf.space"
6
+
7
+ tasks = [
8
+ "value_hotel_budget_guard",
9
+ "airline_seat_upsell_gauntlet",
10
+ "marketplace_ghost_checkout",
11
+ ]
12
+
13
+ print("=== Test: reset -> submit -> grade flow ===")
14
+ for task_id in tasks:
15
+ # Reset
16
+ r = requests.post(f"{BASE}/reset", json={"task_id": task_id}, timeout=30)
17
+ print(f"RESET {task_id}: {r.status_code}")
18
+
19
+ # Immediately submit
20
+ r = requests.post(f"{BASE}/step", json={"action_type": "submit_decision"}, timeout=30)
21
+ step_data = r.json()
22
+ reward = step_data.get("reward", {})
23
+ score_val = reward.get("score")
24
+ value_val = reward.get("value")
25
+ done = step_data.get("done")
26
+ info = step_data.get("info", {})
27
+ final_score = info.get("final_score")
28
+
29
+ print(f" STEP: score={score_val}, value={value_val}, done={done}")
30
+ print(f" INFO final_score={final_score}")
31
+
32
+ # Check ranges
33
+ if score_val is not None:
34
+ if score_val <= 0.0 or score_val >= 1.0:
35
+ print(f" *** reward.score OUT OF RANGE: {score_val}")
36
+ if value_val is not None:
37
+ if value_val == 0.0:
38
+ print(f" ** reward.value is exactly 0.0 (might flag validator)")
39
+ if final_score is not None:
40
+ if final_score <= 0.0 or final_score >= 1.0:
41
+ print(f" *** final_score OUT OF RANGE: {final_score}")
42
+
43
+ # Grade
44
+ r = requests.post(f"{BASE}/grader", json={"task_id": task_id}, timeout=30)
45
+ grade_data = r.json()
46
+ gscore = grade_data.get("score")
47
+ print(f" GRADER: score={gscore}")
48
+ if gscore is not None and (gscore <= 0.0 or gscore >= 1.0):
49
+ print(f" *** GRADER score OUT OF RANGE: {gscore}")
50
+
51
+ breakdown = grade_data.get("grader_breakdown", {})
52
+ for k, v in breakdown.items():
53
+ if isinstance(v, (int, float)) and (v <= 0.0 or v >= 1.0):
54
+ print(f" *** breakdown.{k}={v} OUT OF RANGE")
55
+ print()
56
+
57
+ print("=== Test: empty POST to /reset then /grader ===")
58
+ r = requests.post(f"{BASE}/reset", timeout=30)
59
+ print(f"RESET (empty): {r.status_code}")
60
+ r = requests.post(f"{BASE}/grader", timeout=30)
61
+ grade_data = r.json()
62
+ print(f"GRADER (empty): score={grade_data.get('score')}")
63
+
64
+ print()
65
+ print("=== Test: POST /grade (alias) ===")
66
+ for task_id in tasks:
67
+ requests.post(f"{BASE}/reset", json={"task_id": task_id}, timeout=30)
68
+ r = requests.post(f"{BASE}/grade", json={"task_id": task_id}, timeout=30)
69
+ print(f" /grade {task_id}: {r.status_code} score={r.json().get('score')}")
70
+
71
+ print()
72
+ print("ALL LIVE TESTS COMPLETE")
tests/test_environment.py CHANGED
@@ -12,10 +12,10 @@ from guardian_openenv.tasks import TASKS, TASKS_BY_ID
12
 
13
  def test_reset_returns_expected_task():
14
  env = GuardianReviewEnvironment()
15
- observation = env.reset("value-hotel-budget-guard")
16
 
17
- task = TASKS_BY_ID["value-hotel-budget-guard"]
18
- assert observation.task_id == "value-hotel-budget-guard"
19
  # remaining_steps equals the task's max_steps right after reset
20
  assert observation.remaining_steps == task.max_steps
21
  assert observation.current_decision.flagged_patterns == []
@@ -24,9 +24,9 @@ def test_reset_returns_expected_task():
24
 
25
  def test_state_reflects_task_after_reset():
26
  env = GuardianReviewEnvironment()
27
- env.reset("airline-seat-upsell-gauntlet")
28
  state = env.state()
29
- assert state.task_id == "airline-seat-upsell-gauntlet"
30
  assert state.difficulty == "medium"
31
  assert state.step_count == 0
32
  assert state.done is False
@@ -34,8 +34,8 @@ def test_state_reflects_task_after_reset():
34
 
35
  def test_step_increases_step_count():
36
  env = GuardianReviewEnvironment()
37
- obs = env.reset("value-hotel-budget-guard")
38
- task = TASKS_BY_ID["value-hotel-budget-guard"]
39
 
40
  result = env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id=task.sections[0].section_id))
41
  assert env.state().step_count == 1
@@ -59,7 +59,7 @@ def test_reward_score_always_in_open_range():
59
 
60
  def test_invalid_section_penalised():
61
  env = GuardianReviewEnvironment()
62
- env.reset("value-hotel-budget-guard")
63
  result = env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="NONEXISTENT"))
64
  assert result.reward.value < 0.0
65
 
@@ -68,7 +68,7 @@ def test_invalid_section_penalised():
68
 
69
  def test_dense_progress_and_final_grade():
70
  env = GuardianReviewEnvironment()
71
- env.reset("value-hotel-budget-guard")
72
 
73
  env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="listing-banner"))
74
  env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="price-summary"))
@@ -99,7 +99,7 @@ def test_dense_progress_and_final_grade():
99
 
100
  def test_medium_task_completes():
101
  env = GuardianReviewEnvironment()
102
- env.reset("airline-seat-upsell-gauntlet")
103
  result = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
104
  assert result.done is True
105
  assert 0.0 < result.reward.score < 1.0
@@ -107,7 +107,7 @@ def test_medium_task_completes():
107
 
108
  def test_hard_task_completes():
109
  env = GuardianReviewEnvironment()
110
- env.reset("marketplace-ghost-checkout")
111
  result = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
112
  assert result.done is True
113
  assert 0.0 < result.reward.score < 1.0
@@ -117,7 +117,7 @@ def test_hard_task_completes():
117
 
118
  def test_actions_after_done_return_reward_zero():
119
  env = GuardianReviewEnvironment()
120
- env.reset("value-hotel-budget-guard")
121
  env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
122
  # Further steps should be no-ops with value=0
123
  noop = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
 
12
 
13
  def test_reset_returns_expected_task():
14
  env = GuardianReviewEnvironment()
15
+ observation = env.reset("value_hotel_budget_guard")
16
 
17
+ task = TASKS_BY_ID["value_hotel_budget_guard"]
18
+ assert observation.task_id == "value_hotel_budget_guard"
19
  # remaining_steps equals the task's max_steps right after reset
20
  assert observation.remaining_steps == task.max_steps
21
  assert observation.current_decision.flagged_patterns == []
 
24
 
25
  def test_state_reflects_task_after_reset():
26
  env = GuardianReviewEnvironment()
27
+ env.reset("airline_seat_upsell_gauntlet")
28
  state = env.state()
29
+ assert state.task_id == "airline_seat_upsell_gauntlet"
30
  assert state.difficulty == "medium"
31
  assert state.step_count == 0
32
  assert state.done is False
 
34
 
35
  def test_step_increases_step_count():
36
  env = GuardianReviewEnvironment()
37
+ obs = env.reset("value_hotel_budget_guard")
38
+ task = TASKS_BY_ID["value_hotel_budget_guard"]
39
 
40
  result = env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id=task.sections[0].section_id))
41
  assert env.state().step_count == 1
 
59
 
60
  def test_invalid_section_penalised():
61
  env = GuardianReviewEnvironment()
62
+ env.reset("value_hotel_budget_guard")
63
  result = env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="NONEXISTENT"))
64
  assert result.reward.value < 0.0
65
 
 
68
 
69
  def test_dense_progress_and_final_grade():
70
  env = GuardianReviewEnvironment()
71
+ env.reset("value_hotel_budget_guard")
72
 
73
  env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="listing-banner"))
74
  env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id="price-summary"))
 
99
 
100
  def test_medium_task_completes():
101
  env = GuardianReviewEnvironment()
102
+ env.reset("airline_seat_upsell_gauntlet")
103
  result = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
104
  assert result.done is True
105
  assert 0.0 < result.reward.score < 1.0
 
107
 
108
  def test_hard_task_completes():
109
  env = GuardianReviewEnvironment()
110
+ env.reset("marketplace_ghost_checkout")
111
  result = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
112
  assert result.done is True
113
  assert 0.0 < result.reward.score < 1.0
 
117
 
118
  def test_actions_after_done_return_reward_zero():
119
  env = GuardianReviewEnvironment()
120
+ env.reset("value_hotel_budget_guard")
121
  env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
122
  # Further steps should be no-ops with value=0
123
  noop = env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))