File size: 4,068 Bytes
11fd923
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
Bug Report Structuring Environment - Data Models

Defines typed request/response models for the OpenEnv API:
- BugReportAction: What the agent submits (structured bug report)
- BugReportObservation: What the environment returns (feedback + score)
- BugReportState: Episode metadata
"""

from pydantic import BaseModel, Field
from typing import Optional, Dict, List


# ─── Request Models ───────────────────────────────────────────────

class ResetRequest(BaseModel):
    """Request body for POST /reset"""
    task_id: Optional[str] = Field(
        default=None,
        description="Task difficulty: 'easy', 'medium', or 'hard'. Random if not specified."
    )
    seed: Optional[int] = Field(default=None, description="Random seed for reproducibility")
    episode_id: Optional[str] = Field(default=None, description="Custom episode ID")


class BugReportAction(BaseModel):
    """
    The structured bug report submitted by the agent.
    This is the action the agent takes at each step.
    """
    title: str = Field(
        ...,
        description="Clear, concise bug title"
    )
    steps_to_reproduce: str = Field(
        ...,
        description="Step-by-step reproduction instructions"
    )
    expected_behavior: str = Field(
        ...,
        description="What should happen"
    )
    actual_behavior: str = Field(
        ...,
        description="What actually happens"
    )
    severity: str = Field(
        ...,
        description="Severity level: 'low', 'medium', 'high', or 'critical'"
    )
    environment: str = Field(
        ...,
        description="OS, browser, version, platform info"
    )
    additional_notes: Optional[str] = Field(
        default="",
        description="Any additional relevant information"
    )


class StepRequest(BaseModel):
    """Request body for POST /step"""
    action: BugReportAction


# ─── Response Models ──────────────────────────────────────────────

class BugReportObservation(BaseModel):
    """
    What the environment returns after reset() or step().
    Contains the raw report, feedback, and scoring.
    """
    raw_report: str = Field(
        ...,
        description="The messy, unstructured bug report to process"
    )
    feedback: str = Field(
        default="",
        description="Grading feedback explaining the score"
    )
    score: float = Field(
        default=0.0,
        description="Overall score from 0.0 to 1.0"
    )
    field_scores: Dict[str, float] = Field(
        default_factory=dict,
        description="Per-field scores: title, steps, expected, actual, severity, environment"
    )
    done: bool = Field(
        default=False,
        description="Whether the episode is complete"
    )
    reward: float = Field(
        default=0.0,
        description="Reward signal for this step"
    )
    step_count: int = Field(
        default=0,
        description="Current step number"
    )
    task_id: str = Field(
        default="",
        description="Current task identifier"
    )
    max_steps: int = Field(
        default=5,
        description="Maximum steps allowed for this task"
    )


class BugReportState(BaseModel):
    """
    Episode state metadata returned by GET /state.
    """
    episode_id: str = Field(default="", description="Unique episode identifier")
    step_count: int = Field(default=0, description="Steps taken so far")
    task_id: str = Field(default="", description="Current task ID")
    max_steps: int = Field(default=5, description="Maximum steps for this task")
    current_score: float = Field(default=0.0, description="Best score achieved so far")
    best_score: float = Field(default=0.0, description="Best score across all steps")
    done: bool = Field(default=False, description="Whether episode is complete")
    rewards: List[float] = Field(default_factory=list, description="Rewards per step")