Prince9868 commited on
Commit
869af79
·
1 Parent(s): c98fd97

fix: rename 'final_score' to 'score' in inference output payload

Browse files

The Phase 2 deep validator task parser strictly expects the key 'score' within the JSON output of inference execution. Because we mapped the metric to 'final_score', the validator defaulted parsing to 0.0 or failed schema coercion, driving the 'Task Validation: Not enough tasks with graders / scores out of range' error pipeline failure.

guardian_openenv/inference_runtime.py CHANGED
@@ -362,7 +362,7 @@ def run_inference(
362
  BaselineEpisodeResult(
363
  task_id=task.task_id,
364
  difficulty=task.difficulty,
365
- final_score=final_score,
366
  total_reward=round(total_reward, 4),
367
  steps_taken=state.step_count,
368
  final_decision=state.decision,
@@ -370,7 +370,7 @@ def run_inference(
370
  )
371
  )
372
 
373
- raw_mean = sum(item.final_score for item in results) / len(results) if results else 0.001
374
  summary = BaselineRunSummary(
375
  model=model,
376
  tasks=results,
 
362
  BaselineEpisodeResult(
363
  task_id=task.task_id,
364
  difficulty=task.difficulty,
365
+ score=final_score,
366
  total_reward=round(total_reward, 4),
367
  steps_taken=state.step_count,
368
  final_decision=state.decision,
 
370
  )
371
  )
372
 
373
+ raw_mean = sum(item.score for item in results) / len(results) if results else 0.001
374
  summary = BaselineRunSummary(
375
  model=model,
376
  tasks=results,
guardian_openenv/models.py CHANGED
@@ -164,7 +164,7 @@ class StepResult(BaseModel):
164
  class BaselineEpisodeResult(BaseModel):
165
  task_id: str
166
  difficulty: Literal["easy", "medium", "hard"]
167
- final_score: float = Field(gt=0.0, lt=1.0)
168
  total_reward: float
169
  steps_taken: int = Field(ge=0)
170
  final_decision: CurrentDecision
 
164
  class BaselineEpisodeResult(BaseModel):
165
  task_id: str
166
  difficulty: Literal["easy", "medium", "hard"]
167
+ score: float = Field(gt=0.0, lt=1.0)
168
  total_reward: float
169
  steps_taken: int = Field(ge=0)
170
  final_decision: CurrentDecision
inference.py CHANGED
@@ -72,7 +72,7 @@ def main() -> None:
72
 
73
  print(f"[DONE] mean_score={summary.mean_score}", flush=True)
74
  for task in summary.tasks:
75
- print(f" {task.task_id}: final_score={task.final_score}", flush=True)
76
 
77
 
78
  if __name__ == "__main__":
 
72
 
73
  print(f"[DONE] mean_score={summary.mean_score}", flush=True)
74
  for task in summary.tasks:
75
+ print(f" {task.task_id}: score={task.score}", flush=True)
76
 
77
 
78
  if __name__ == "__main__":
outputs/inference_scores.json CHANGED
@@ -1,94 +1,84 @@
1
  {
2
- "model": "llama-3.3-70b-versatile",
3
  "tasks": [
4
  {
5
  "task_id": "value-hotel-budget-guard",
6
  "difficulty": "easy",
7
- "final_score": 0.261,
8
- "total_reward": 0.701,
9
- "steps_taken": 9,
10
  "final_decision": {
11
  "flagged_patterns": [],
12
- "removed_addon_ids": [
13
- "insurance",
14
- "newsletter"
15
- ],
16
  "kept_addon_ids": [],
17
  "timer_verdicts": {},
18
- "estimated_true_total": 187.0,
19
  "recommendation": null,
20
  "summary": ""
21
  },
22
  "grader_breakdown": {
23
  "pattern_score": 0.001,
24
- "addon_score": 0.999,
25
  "timer_score": 0.001,
26
- "total_score": 0.0038,
27
  "recommendation_score": 0.001,
28
  "evidence_score": 0.999,
29
  "summary_score": 0.001,
30
- "final_score": 0.261
31
  }
32
  },
33
  {
34
  "task_id": "airline-seat-upsell-gauntlet",
35
  "difficulty": "medium",
36
- "final_score": 0.4301,
37
- "total_reward": 1.1692,
38
- "steps_taken": 8,
39
  "final_decision": {
40
- "flagged_patterns": [
41
- "confirm_shaming"
42
- ],
43
- "removed_addon_ids": [
44
- "travelguard"
45
- ],
46
  "kept_addon_ids": [],
47
  "timer_verdicts": {},
48
- "estimated_true_total": 276.98,
49
  "recommendation": null,
50
  "summary": ""
51
  },
52
  "grader_breakdown": {
53
- "pattern_score": 0.3333,
54
- "addon_score": 0.5,
55
  "timer_score": 0.001,
56
- "total_score": 0.999,
57
  "recommendation_score": 0.001,
58
  "evidence_score": 0.999,
59
  "summary_score": 0.001,
60
- "final_score": 0.4301
61
  }
62
  },
63
  {
64
  "task_id": "marketplace-ghost-checkout",
65
  "difficulty": "hard",
66
- "final_score": 0.2442,
67
- "total_reward": 0.6874,
68
- "steps_taken": 9,
69
  "final_decision": {
70
  "flagged_patterns": [],
71
- "removed_addon_ids": [
72
- "protection-plan",
73
- "seller-donation"
74
- ],
75
  "kept_addon_ids": [],
76
  "timer_verdicts": {},
77
- "estimated_true_total": 139.98,
78
  "recommendation": null,
79
  "summary": ""
80
  },
81
  "grader_breakdown": {
82
  "pattern_score": 0.001,
83
- "addon_score": 0.8,
84
  "timer_score": 0.001,
85
- "total_score": 0.1094,
86
  "recommendation_score": 0.001,
87
  "evidence_score": 0.999,
88
  "summary_score": 0.001,
89
- "final_score": 0.2442
90
  }
91
  }
92
  ],
93
- "mean_score": 0.3118
94
  }
 
1
  {
2
+ "model": "rule-based-fallback",
3
  "tasks": [
4
  {
5
  "task_id": "value-hotel-budget-guard",
6
  "difficulty": "easy",
7
+ "score": 0.0808,
8
+ "total_reward": 0.3106,
9
+ "steps_taken": 5,
10
  "final_decision": {
11
  "flagged_patterns": [],
12
+ "removed_addon_ids": [],
 
 
 
13
  "kept_addon_ids": [],
14
  "timer_verdicts": {},
15
+ "estimated_true_total": null,
16
  "recommendation": null,
17
  "summary": ""
18
  },
19
  "grader_breakdown": {
20
  "pattern_score": 0.001,
21
+ "addon_score": 0.001,
22
  "timer_score": 0.001,
23
+ "total_score": 0.001,
24
  "recommendation_score": 0.001,
25
  "evidence_score": 0.999,
26
  "summary_score": 0.001,
27
+ "final_score": 0.0808
28
  }
29
  },
30
  {
31
  "task_id": "airline-seat-upsell-gauntlet",
32
  "difficulty": "medium",
33
+ "score": 0.0808,
34
+ "total_reward": 0.3106,
35
+ "steps_taken": 5,
36
  "final_decision": {
37
+ "flagged_patterns": [],
38
+ "removed_addon_ids": [],
 
 
 
 
39
  "kept_addon_ids": [],
40
  "timer_verdicts": {},
41
+ "estimated_true_total": null,
42
  "recommendation": null,
43
  "summary": ""
44
  },
45
  "grader_breakdown": {
46
+ "pattern_score": 0.001,
47
+ "addon_score": 0.001,
48
  "timer_score": 0.001,
49
+ "total_score": 0.001,
50
  "recommendation_score": 0.001,
51
  "evidence_score": 0.999,
52
  "summary_score": 0.001,
53
+ "final_score": 0.0808
54
  }
55
  },
56
  {
57
  "task_id": "marketplace-ghost-checkout",
58
  "difficulty": "hard",
59
+ "score": 0.0808,
60
+ "total_reward": 0.3106,
61
+ "steps_taken": 6,
62
  "final_decision": {
63
  "flagged_patterns": [],
64
+ "removed_addon_ids": [],
 
 
 
65
  "kept_addon_ids": [],
66
  "timer_verdicts": {},
67
+ "estimated_true_total": null,
68
  "recommendation": null,
69
  "summary": ""
70
  },
71
  "grader_breakdown": {
72
  "pattern_score": 0.001,
73
+ "addon_score": 0.001,
74
  "timer_score": 0.001,
75
+ "total_score": 0.001,
76
  "recommendation_score": 0.001,
77
  "evidence_score": 0.999,
78
  "summary_score": 0.001,
79
+ "final_score": 0.0808
80
  }
81
  }
82
  ],
83
+ "mean_score": 0.0808
84
  }
server/app.py CHANGED
@@ -190,7 +190,7 @@ def baseline() -> dict:
190
  {
191
  "task_id": t.task_id,
192
  "difficulty": t.difficulty,
193
- "final_score": t.final_score,
194
  "total_reward": t.total_reward,
195
  "grader_breakdown": t.grader_breakdown,
196
  }
 
190
  {
191
  "task_id": t.task_id,
192
  "difficulty": t.difficulty,
193
+ "score": t.score,
194
  "total_reward": t.total_reward,
195
  "grader_breakdown": t.grader_breakdown,
196
  }
test_grader_direct.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Test grader functions the way the OpenEnv validator would call them."""
2
+ from guardian_openenv.task_graders import (
3
+ grade_value_hotel_budget_guard,
4
+ grade_airline_seat_upsell_gauntlet,
5
+ grade_marketplace_ghost_checkout,
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 ===")
15
+ for task_id, fn in GRADERS:
16
+ result = fn()
17
+ score = result["score"]
18
+ valid = 0 < score < 1
19
+ print(f" {task_id}: score={score} valid={valid}")
20
+ if not valid:
21
+ print(f" *** FAIL: score is out of (0,1) range!")
22
+ # Check breakdown
23
+ for k, v in result.get("grader_breakdown", {}).items():
24
+ if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
25
+ print(f" *** breakdown {k}={v} OUT OF RANGE")
26
+
27
+ print()
28
+ print("=== Test 2: Called with trajectory=[] ===")
29
+ for task_id, fn in GRADERS:
30
+ result = fn(trajectory=[])
31
+ score = result["score"]
32
+ valid = 0 < score < 1
33
+ print(f" {task_id}: score={score} valid={valid}")
34
+
35
+ print()
36
+ print("=== Test 3: Called with environment=None, trajectory=[] ===")
37
+ for task_id, fn in GRADERS:
38
+ result = fn(environment=None, trajectory=[])
39
+ score = result["score"]
40
+ valid = 0 < score < 1
41
+ print(f" {task_id}: score={score} valid={valid}")
42
+
43
+ print()
44
+ print("=== Test 4: Run full episode then grade ===")
45
+ from guardian_openenv.environment import GuardianReviewEnvironment
46
+ from guardian_openenv.models import GuardianAction, ActionType
47
+
48
+ env = GuardianReviewEnvironment()
49
+ for task_id, fn in GRADERS:
50
+ env.reset(task_id)
51
+ # Take a few actions
52
+ env.step(GuardianAction(action_type=ActionType.INSPECT_SECTION, section_id=env._task.sections[0].section_id))
53
+ env.step(GuardianAction(action_type=ActionType.SUBMIT_DECISION))
54
+
55
+ # Now grade using the environment
56
+ result = fn(environment=env)
57
+ score = result["score"]
58
+ valid = 0 < score < 1
59
+ print(f" {task_id}: score={score} valid={valid}")
60
+ if not valid:
61
+ print(f" *** FAIL: score is out of (0,1) range!")
62
+ for k, v in result.get("grader_breakdown", {}).items():
63
+ if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
64
+ print(f" *** breakdown {k}={v} OUT OF RANGE")
65
+
66
+ print()
67
+ print("=== Test 5: Grade with state dict (as validator might pass) ===")
68
+ for task_id, fn in GRADERS:
69
+ env.reset(task_id)
70
+ state_dict = env.state().model_dump()
71
+ result = fn(environment=state_dict)
72
+ score = result["score"]
73
+ valid = 0 < score < 1
74
+ print(f" {task_id}: score={score} valid={valid}")
75
+
76
+ print()
77
+ print("=== Test 6: inference_scores.json check ===")
78
+ import json
79
+ from pathlib import Path
80
+ scores_path = Path("outputs/inference_scores.json")
81
+ if scores_path.exists():
82
+ data = json.loads(scores_path.read_text())
83
+ for task in data.get("tasks", []):
84
+ tid = task["task_id"]
85
+ fs = task.get("score")
86
+ if fs is not None:
87
+ valid = 0 < fs < 1
88
+ print(f" {tid}: score={fs} valid={valid}")
89
+ else:
90
+ print(f" {tid}: MISSING score FIELD")
91
+ valid = False
92
+ if not valid:
93
+ print(f" *** FAIL!")
94
+ for k, v in task.get("grader_breakdown", {}).items():
95
+ if isinstance(v, float) and (v <= 0.0 or v >= 1.0):
96
+ print(f" *** breakdown {k}={v} OUT OF RANGE")
97
+ ms = data.get("mean_score")
98
+ print(f" mean_score={ms} valid={0 < ms < 1}")
99
+ else:
100
+ print(" (file not found)")
101
+
102
+ print()
103
+ print("ALL TESTS COMPLETE")