Spaces:
Sleeping
Sleeping
Update models.py
Browse files
models.py
CHANGED
|
@@ -4,15 +4,16 @@ models.py β PhishGuard-Env Pydantic Models
|
|
| 4 |
|
| 5 |
Typed request / response schemas used by env.py (FastAPI).
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
| 16 |
"""
|
| 17 |
|
| 18 |
from __future__ import annotations
|
|
@@ -36,10 +37,9 @@ class PhishAction(BaseModel):
|
|
| 36 |
reasoning : Optional one-sentence technical justification (for logging).
|
| 37 |
"""
|
| 38 |
action: str = Field(
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
)
|
| 43 |
)
|
| 44 |
reasoning: Optional[str] = Field(
|
| 45 |
default=None,
|
|
@@ -56,7 +56,7 @@ class ResetRequest(BaseModel):
|
|
| 56 |
|
| 57 |
|
| 58 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 59 |
-
# RESPONSE MODELS
|
| 60 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 61 |
|
| 62 |
class StepResponse(BaseModel):
|
|
@@ -66,8 +66,9 @@ class StepResponse(BaseModel):
|
|
| 66 |
The OpenEnv validator inspects `task_id` and `is_correct` on every step
|
| 67 |
to count how many distinct tasks have been graded.
|
| 68 |
|
| 69 |
-
task_id
|
| 70 |
-
|
|
|
|
| 71 |
"""
|
| 72 |
observation: Optional[Dict[str, Any]] = Field(
|
| 73 |
description="Next email dict, or null when the episode is done"
|
|
@@ -78,13 +79,9 @@ class StepResponse(BaseModel):
|
|
| 78 |
done: bool = Field(
|
| 79 |
description="True when all scenarios are complete or health reaches 0"
|
| 80 |
)
|
| 81 |
-
task_id: Optional[str] = Field(
|
| 82 |
default=None,
|
| 83 |
-
description="
|
| 84 |
-
)
|
| 85 |
-
task_group: Optional[str] = Field(
|
| 86 |
-
default=None,
|
| 87 |
-
description="Difficulty level of this scenario: easy | medium | hard",
|
| 88 |
)
|
| 89 |
is_correct: bool = Field(
|
| 90 |
description="True when reward >= R_PERFECT (0.95)"
|
|
@@ -100,7 +97,7 @@ class ResetResponse(BaseModel):
|
|
| 100 |
description="First email observation for this episode"
|
| 101 |
)
|
| 102 |
task_id: str = Field(
|
| 103 |
-
description="
|
| 104 |
)
|
| 105 |
task_group: str = Field(
|
| 106 |
description="Difficulty level of the first scenario: easy | medium | hard"
|
|
@@ -109,5 +106,5 @@ class ResetResponse(BaseModel):
|
|
| 109 |
description="Active difficulty level for this episode"
|
| 110 |
)
|
| 111 |
total_tasks: int = Field(
|
| 112 |
-
description="Total number of scenarios
|
| 113 |
-
)
|
|
|
|
| 4 |
|
| 5 |
Typed request / response schemas used by env.py (FastAPI).
|
| 6 |
|
| 7 |
+
PhishAction : Body schema for POST /step
|
| 8 |
+
StepResponse : Response schema for POST /step (OpenEnv grader compliance)
|
| 9 |
+
ResetResponse : Response schema for POST /reset
|
| 10 |
+
|
| 11 |
+
BUG FIX (v1.0.2 β v1.0.3)
|
| 12 |
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 13 |
+
StepResponse.task_id was typed as `str` but the episode-already-over guard
|
| 14 |
+
branch in env.py returns task_id=None. Pydantic would raise a validation
|
| 15 |
+
error on every post-episode /step call.
|
| 16 |
+
Fix: task_id is now Optional[str] with a default of None.
|
| 17 |
"""
|
| 18 |
|
| 19 |
from __future__ import annotations
|
|
|
|
| 37 |
reasoning : Optional one-sentence technical justification (for logging).
|
| 38 |
"""
|
| 39 |
action: str = Field(
|
| 40 |
+
max_length=64,
|
| 41 |
+
description="Triage decision. Must be exactly one of: "
|
| 42 |
+
"MARK_SAFE | MOVE_TO_SPAM | QUARANTINE | BLOCK_DOMAIN"
|
|
|
|
| 43 |
)
|
| 44 |
reasoning: Optional[str] = Field(
|
| 45 |
default=None,
|
|
|
|
| 56 |
|
| 57 |
|
| 58 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 59 |
+
# RESPONSE MODELS (OpenEnv spec β all fields required by validator)
|
| 60 |
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 61 |
|
| 62 |
class StepResponse(BaseModel):
|
|
|
|
| 66 |
The OpenEnv validator inspects `task_id` and `is_correct` on every step
|
| 67 |
to count how many distinct tasks have been graded.
|
| 68 |
|
| 69 |
+
task_id is Optional[str] (not str) because the episode-already-over guard
|
| 70 |
+
branch returns None β a non-optional field would cause a Pydantic
|
| 71 |
+
ValidationError on every post-episode call.
|
| 72 |
"""
|
| 73 |
observation: Optional[Dict[str, Any]] = Field(
|
| 74 |
description="Next email dict, or null when the episode is done"
|
|
|
|
| 79 |
done: bool = Field(
|
| 80 |
description="True when all scenarios are complete or health reaches 0"
|
| 81 |
)
|
| 82 |
+
task_id: Optional[str] = Field( # BUG FIX: was `str`, must be Optional
|
| 83 |
default=None,
|
| 84 |
+
description="Scenario ID e.g. 'lv3' β required by OpenEnv validator"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
)
|
| 86 |
is_correct: bool = Field(
|
| 87 |
description="True when reward >= R_PERFECT (0.95)"
|
|
|
|
| 97 |
description="First email observation for this episode"
|
| 98 |
)
|
| 99 |
task_id: str = Field(
|
| 100 |
+
description="ID of the first scenario in this episode"
|
| 101 |
)
|
| 102 |
task_group: str = Field(
|
| 103 |
description="Difficulty level of the first scenario: easy | medium | hard"
|
|
|
|
| 106 |
description="Active difficulty level for this episode"
|
| 107 |
)
|
| 108 |
total_tasks: int = Field(
|
| 109 |
+
description="Total number of scenarios in this level"
|
| 110 |
+
)
|