File size: 3,706 Bytes
27d7338
 
 
 
 
 
 
 
f8cc947
27d7338
f8cc947
27d7338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f8cc947
 
 
27d7338
 
 
 
 
 
 
f8cc947
27d7338
 
 
 
 
f8cc947
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27d7338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f8cc947
 
 
 
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
"""Pydantic models for the Code Review OpenEnv environment.

These models define the observation, action, reward, and ground-truth bug schema
used across the environment, server API, and inference baseline.
"""

from __future__ import annotations

from typing import Dict, List, Literal, Optional

from pydantic import BaseModel, ConfigDict, Field, field_validator


class ReviewComment(BaseModel):
    """A single review comment placed by the agent on a specific line."""

    model_config = ConfigDict(extra="forbid")

    line_number: int = Field(..., ge=1)
    severity: Literal["critical", "major", "minor", "nit"]
    category: Literal["bug", "security", "performance", "style"]
    message: str = Field(..., min_length=1)
    step_added: int = Field(..., ge=1)


class CodeReviewObservation(BaseModel):
    """Observation returned to the agent at each step."""

    model_config = ConfigDict(extra="forbid")

    task_id: str = Field(..., min_length=1)
    language: str = Field(..., min_length=1)
    pr_title: str = Field(..., min_length=1)
    pr_description: str = Field(..., min_length=1)
    code_diff: str
    full_file: str
    existing_comments: List[ReviewComment]
    step_number: int = Field(..., ge=1)
    max_steps: int = Field(..., ge=1)
    review_status: Literal["pending", "in_review", "submitted"]
    # Upgrade 4: Multi-file repository support
    repository_files: Optional[Dict[str, str]] = None
    available_files: Optional[List[str]] = None


class CodeReviewAction(BaseModel):
    """Action sent by the agent to the environment."""

    model_config = ConfigDict(extra="forbid")

    operation: Literal["add_comment", "approve", "request_changes", "done", "inspect_file", "inspect_lines"]
    line_number: Optional[int] = Field(default=None, ge=1)
    severity: Optional[Literal["critical", "major", "minor", "nit"]] = None
    category: Optional[Literal["bug", "security", "performance", "style"]] = None
    message: Optional[str] = Field(default=None, min_length=1)
    summary: Optional[str] = Field(default=None, min_length=1)
    # Upgrade 1: Confidence calibration
    confidence: Optional[int] = None
    # Upgrade 4: Multi-file support
    filename: Optional[str] = None
    # Upgrade 4: inspect_lines support
    start_line: Optional[int] = Field(default=None, ge=1)
    end_line: Optional[int] = Field(default=None, ge=1)

    @field_validator("confidence")
    @classmethod
    def validate_confidence(cls, v: Optional[int]) -> Optional[int]:
        """Ensure confidence is between 0 and 100 inclusive if provided."""
        if v is not None and (v < 0 or v > 100):
            raise ValueError("confidence must be between 0 and 100 inclusive")
        return v


class CodeReviewReward(BaseModel):
    """Reward breakdown returned by reward engine and recorded in state."""

    model_config = ConfigDict(extra="forbid")

    score: float
    reason: str = Field(..., min_length=1)
    cumulative_score: float
    bugs_found_so_far: int = Field(..., ge=0)
    false_positives_so_far: int = Field(..., ge=0)


class GroundTruthBug(BaseModel):
    """Ground-truth bug metadata used for rewards and grading."""

    model_config = ConfigDict(extra="forbid")

    line_number: int = Field(..., ge=1)
    severity: Literal["critical", "major", "minor", "nit"]
    category: Literal["bug", "security", "performance", "style"]
    description: str = Field(..., min_length=1)
    required_keywords: List[str] = Field(default_factory=list)
    is_red_herring: bool = False
    # Upgrade 2: Explanation quality tiering
    explanation_tiers: Optional[dict] = None
    # Upgrade 4: Multi-file support — which file this bug is in
    source_file: Optional[str] = None