shank commited on
Commit Β·
13f7b8d
1
Parent(s): 2e70173
chore: Rename Dockerfile to fix HF Space deploy, and clean up AI slop
Browse files- Dockerfile β Dockerfile.hackathon +0 -0
- HANDOVER.md +0 -211
- calibrate.py +2 -2
- demo/gradio_app.py +16 -28
- env/__pycache__/environment.cpython-313.pyc +0 -0
- eval_run.log +12 -0
- evaluate_model.py +10 -10
- evaluation_results.json +540 -270
- images/gradio UI.png +3 -0
- images/hypothesis_quality.png +3 -0
- images/localize.png +3 -0
- images/penalty.png +3 -0
- images/semantic.png +3 -0
- inference.py +16 -30
- scratch/data_tier2.py +4 -4
- scratch/data_tier3.py +3 -3
- scratch/fix_all.py +4 -4
- scratch/gen_t1_base.py +4 -4
- scratch/merge.py +10 -10
- server/__init__.py +2 -2
- server/app.py +0 -6
- server/models.py +1 -6
- server/reward_calculator.py +53 -112
- tests/__init__.py +1 -1
- tests/test_environment.py +10 -13
- tests/test_graders.py +5 -18
- tests/test_integration.py +13 -26
- tests/test_sandbox.py +2 -16
- training/train_grpo.py +57 -85
- uv.lock +0 -0
- validator.py +6 -16
Dockerfile β Dockerfile.hackathon
RENAMED
|
File without changes
|
HANDOVER.md
DELETED
|
@@ -1,211 +0,0 @@
|
|
| 1 |
-
# AgentDebuggerEnv β Project Handover
|
| 2 |
-
|
| 3 |
-
## What This Project Is
|
| 4 |
-
A GRPO-trained LLM (Qwen2.5-Coder-7B-Instruct) that learns to debug Python code through
|
| 5 |
-
structured hypothesis-driven reasoning. Submitted to the Meta + PyTorch + HuggingFace OpenEnv Hackathon.
|
| 6 |
-
|
| 7 |
-
---
|
| 8 |
-
|
| 9 |
-
## Repo & Remotes
|
| 10 |
-
|
| 11 |
-
| Remote | URL |
|
| 12 |
-
|---|---|
|
| 13 |
-
| GitHub (source of truth) | https://github.com/shasshaank/meta_hackthon.git |
|
| 14 |
-
| HF Training Space | https://huggingface.co/spaces/shashaank0707/AgentDebugger-training-v2 |
|
| 15 |
-
| HF Trained Model | https://huggingface.co/shashaank0707/AgentDebugger-trained |
|
| 16 |
-
|
| 17 |
-
Push to GitHub first, then to HF Space if needed:
|
| 18 |
-
```bash
|
| 19 |
-
git push origin main
|
| 20 |
-
git push space main --force # space remote = HF training space
|
| 21 |
-
```
|
| 22 |
-
|
| 23 |
-
The `space` remote URL includes your HF token:
|
| 24 |
-
```
|
| 25 |
-
https://shashaank0707:YOUR_HF_TOKEN@huggingface.co/spaces/shashaank0707/AgentDebugger-training-v2
|
| 26 |
-
```
|
| 27 |
-
|
| 28 |
-
---
|
| 29 |
-
|
| 30 |
-
## Project Structure
|
| 31 |
-
|
| 32 |
-
```
|
| 33 |
-
meta_hackathon/
|
| 34 |
-
βββ app.py # Gradio training monitor β launched by HF Space SDK
|
| 35 |
-
βββ training/
|
| 36 |
-
β βββ train_grpo.py # Main training script (GRPO via TRL)
|
| 37 |
-
βββ server/
|
| 38 |
-
β βββ reward_calculator.py # Multi-component reward (format, hypothesis, fix, semantic)
|
| 39 |
-
β βββ models.py # parse_agent_output() β parses structured LLM output
|
| 40 |
-
β βββ app.py # FastAPI server (for the inference/env Space, not training)
|
| 41 |
-
βββ data/
|
| 42 |
-
β βββ bugs_tier1.jsonl # 9 easy bugs (used steps 0β150)
|
| 43 |
-
β βββ bugs_tier2.jsonl # 31 medium bugs (added at step 150)
|
| 44 |
-
β βββ bugs_tier3.jsonl # 21 hard bugs (added at step 350 β was 600)
|
| 45 |
-
β βββ generate_bugs.py # Script that generated the bug datasets
|
| 46 |
-
βββ requirements.txt # HF Space deps (gradio[oauth,mcp]==6.13.0, cu121 torch)
|
| 47 |
-
βββ requirements_kaggle.txt # Kaggle/RunPod deps (no torch pin, bitsandbytes==0.45.3)
|
| 48 |
-
βββ inference.py # Inference wrapper for evaluation
|
| 49 |
-
βββ Dockerfile # For the inference/env Space (not the training space)
|
| 50 |
-
βββ README.md # HF Space config header (sdk: gradio, app_file: app.py)
|
| 51 |
-
```
|
| 52 |
-
|
| 53 |
-
---
|
| 54 |
-
|
| 55 |
-
## Dependency Versions (locked β do not change without testing)
|
| 56 |
-
|
| 57 |
-
| Package | Version | Why pinned |
|
| 58 |
-
|---|---|---|
|
| 59 |
-
| `trl` | `0.14.0` | First version with `GRPOTrainer` + `GRPOConfig` |
|
| 60 |
-
| `pydantic` | `2.12.5` | Only version satisfying both gradio base AND gradio[mcp] constraints |
|
| 61 |
-
| `gradio` | `6.13.0[oauth,mcp]` | HF Space builder requires extras in one install pass |
|
| 62 |
-
| `bitsandbytes` | `0.45.3` (Kaggle) / `0.43.3` (HF Space cu121) | 0.45.3 has CUDA 12.x binaries; 0.43.3 works with cu121 |
|
| 63 |
-
| `transformers` | `4.46.3` | Tested with TRL 0.14.0 |
|
| 64 |
-
| `torch` | `2.5.1+cu121` (HF Space) / pre-installed (Kaggle) | |
|
| 65 |
-
|
| 66 |
-
**GRPOConfig param name:** `max_completion_length` (NOT `max_new_tokens` β that's the old name, breaks on 0.14.0)
|
| 67 |
-
|
| 68 |
-
---
|
| 69 |
-
|
| 70 |
-
## Training Script β Key Design Decisions
|
| 71 |
-
|
| 72 |
-
### GPU Auto-Detection (train_grpo.py ~line 260)
|
| 73 |
-
The script detects GPU at runtime and sets all hyperparams automatically:
|
| 74 |
-
|
| 75 |
-
| GPU | dtype | batch | grad_accum | num_gen | max_comp | lora_r |
|
| 76 |
-
|---|---|---|---|---|---|---|
|
| 77 |
-
| A100 40GB+ | bfloat16 | 2 | 4 | 8 | 256 | 16 |
|
| 78 |
-
| V100 32GB | float16 | 1 | 8 | 6 | 220 | 12 |
|
| 79 |
-
| T4 / β€16GB | float16 | 1 | 8 | 4 | 160 | 8 |
|
| 80 |
-
|
| 81 |
-
**Critical:** P100 is NOT supported β PyTorch 2.x dropped sm_60 support. Use T4 instead.
|
| 82 |
-
|
| 83 |
-
### Curriculum
|
| 84 |
-
- Steps 0β150: Tier 1 bugs only (9 bugs)
|
| 85 |
-
- Steps 150β350: Tier 1 + Tier 2 (40 bugs)
|
| 86 |
-
- Steps 350+: All tiers (61 bugs)
|
| 87 |
-
|
| 88 |
-
### Reward Components (server/reward_calculator.py)
|
| 89 |
-
| Component | Weight | What it measures |
|
| 90 |
-
|---|---|---|
|
| 91 |
-
| format_compliance | 0.10 | All 5 fields present (OBSERVATION/HYPOTHESIS/CONFIDENCE/ACTION/DETAIL) |
|
| 92 |
-
| hypothesis_quality | 0.20 | Length + references specific variable names |
|
| 93 |
-
| localization | 0.15 | Correct function/line identified |
|
| 94 |
-
| fix_quality | 0.35 | Tests pass on proposed fix |
|
| 95 |
-
| semantic_similarity | 0.10 | Similarity to canonical fix |
|
| 96 |
-
| efficiency_potential | 0.10 | Potential-based shaping (Ibrahim et al. 2024) |
|
| 97 |
-
|
| 98 |
-
### Required Output Format
|
| 99 |
-
```
|
| 100 |
-
OBSERVATION: [specific observations with line numbers]
|
| 101 |
-
HYPOTHESIS: [2+ sentences explaining root cause with variable names]
|
| 102 |
-
CONFIDENCE: [low | medium | high]
|
| 103 |
-
ACTION: [inspect_lines | run_tests | propose_fix | request_context | give_up]
|
| 104 |
-
DETAIL: [complete fixed function code if propose_fix, else details]
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
---
|
| 108 |
-
|
| 109 |
-
## Running Training
|
| 110 |
-
|
| 111 |
-
### On Kaggle (T4 β free):
|
| 112 |
-
```python
|
| 113 |
-
# Cell 1 β install
|
| 114 |
-
!pip install -q wandb==0.18.7 datasets==3.0.2 transformers==4.46.3 \
|
| 115 |
-
accelerate==1.0.1 trl==0.14.0 bitsandbytes==0.45.3 peft==0.13.2
|
| 116 |
-
|
| 117 |
-
# Cell 2 β clone + secrets
|
| 118 |
-
from kaggle_secrets import UserSecretsClient
|
| 119 |
-
import os
|
| 120 |
-
secrets = UserSecretsClient()
|
| 121 |
-
os.environ["WANDB_API_KEY"] = secrets.get_secret("WANDB_API_KEY")
|
| 122 |
-
os.environ["HF_TOKEN"] = secrets.get_secret("HF_TOKEN")
|
| 123 |
-
!git clone https://github.com/shasshaank/meta_hackthon.git /kaggle/working/repo
|
| 124 |
-
%cd /kaggle/working/repo
|
| 125 |
-
|
| 126 |
-
# Cell 3 β train (streams output live)
|
| 127 |
-
import subprocess, sys
|
| 128 |
-
proc = subprocess.Popen(
|
| 129 |
-
[sys.executable, "training/train_grpo.py"],
|
| 130 |
-
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
| 131 |
-
text=True, bufsize=1, cwd="/kaggle/working/repo"
|
| 132 |
-
)
|
| 133 |
-
for line in proc.stdout:
|
| 134 |
-
print(line, end="", flush=True)
|
| 135 |
-
proc.wait()
|
| 136 |
-
|
| 137 |
-
# Cell 4 β save outputs after training
|
| 138 |
-
import shutil
|
| 139 |
-
shutil.copytree("/kaggle/working/repo/checkpoints", "/kaggle/working/checkpoints", dirs_exist_ok=True)
|
| 140 |
-
```
|
| 141 |
-
|
| 142 |
-
**Kaggle secrets needed:** `WANDB_API_KEY`, `HF_TOKEN`
|
| 143 |
-
**Kaggle GPU:** T4 x1 (NOT P100 β incompatible with modern PyTorch)
|
| 144 |
-
**Expected time:** ~8β10 hours for 500 steps (default max_steps=500)
|
| 145 |
-
|
| 146 |
-
### On RunPod (A100 β ~$1.09/hr):
|
| 147 |
-
```bash
|
| 148 |
-
git clone https://github.com/shasshaank/meta_hackthon.git && cd meta_hackthon
|
| 149 |
-
pip install -q wandb==0.18.7 datasets==3.0.2 transformers==4.46.3 \
|
| 150 |
-
accelerate==1.0.1 trl==0.14.0 bitsandbytes==0.45.3 peft==0.13.2
|
| 151 |
-
WANDB_API_KEY=xxx HF_TOKEN=xxx python training/train_grpo.py
|
| 152 |
-
```
|
| 153 |
-
**Expected time:** ~3β4 hours for 1000 steps on A100 40GB
|
| 154 |
-
|
| 155 |
-
### Resume from checkpoint:
|
| 156 |
-
```bash
|
| 157 |
-
python training/train_grpo.py --resume ./checkpoints/checkpoint-400
|
| 158 |
-
```
|
| 159 |
-
|
| 160 |
-
### Local sanity check (no GPU):
|
| 161 |
-
```bash
|
| 162 |
-
python training/train_grpo.py --test-local
|
| 163 |
-
```
|
| 164 |
-
|
| 165 |
-
---
|
| 166 |
-
|
| 167 |
-
## HF Space Setup (training monitor)
|
| 168 |
-
|
| 169 |
-
The training Space (`AgentDebugger-training-v2`) is a Gradio app that:
|
| 170 |
-
1. On startup, spawns `training/train_grpo.py` in a background thread
|
| 171 |
-
2. Shows a live training log in the UI, auto-refreshing every 30s
|
| 172 |
-
|
| 173 |
-
**Required Space secrets:**
|
| 174 |
-
- `WANDB_API_KEY`
|
| 175 |
-
- `HF_TOKEN`
|
| 176 |
-
|
| 177 |
-
**Push to Space:**
|
| 178 |
-
```bash
|
| 179 |
-
git remote set-url space https://shashaank0707:YOUR_HF_TOKEN@huggingface.co/spaces/shashaank0707/AgentDebugger-training-v2
|
| 180 |
-
git push space main --force
|
| 181 |
-
```
|
| 182 |
-
|
| 183 |
-
---
|
| 184 |
-
|
| 185 |
-
## Known Issues Fixed (do not revert)
|
| 186 |
-
|
| 187 |
-
| Issue | Fix |
|
| 188 |
-
|---|---|
|
| 189 |
-
| `ImportError: cannot import name 'GRPOTrainer'` | `trl==0.12.2` β `trl==0.14.0` |
|
| 190 |
-
| `TypeError: GRPOConfig got unexpected keyword 'max_new_tokens'` | renamed to `max_completion_length` |
|
| 191 |
-
| `pydantic` conflict with `gradio[mcp]` | `pydantic==2.10.6` β `2.12.5` |
|
| 192 |
-
| `P100 not supported by PyTorch 2.x` | Switch to T4 on Kaggle |
|
| 193 |
-
| `bitsandbytes CUDA binary not found` | `bitsandbytes==0.43.3` β `0.45.3` on Kaggle |
|
| 194 |
-
| `unsloth` CUDA driver crash on HF A100 | Replaced with `bitsandbytes + peft` |
|
| 195 |
-
| `gradio every=` deprecation | Replaced with `gr.Timer(value=30)` |
|
| 196 |
-
|
| 197 |
-
---
|
| 198 |
-
|
| 199 |
-
## W&B Dashboard
|
| 200 |
-
https://wandb.ai/shashaankjain07-keshav-memorial-college-of-law/AgentDebuggerEnv
|
| 201 |
-
|
| 202 |
-
Training runs appear here automatically when `WANDB_API_KEY` is set.
|
| 203 |
-
|
| 204 |
-
---
|
| 205 |
-
|
| 206 |
-
## What's Left To Do
|
| 207 |
-
|
| 208 |
-
- [ ] **Finish training** β 500β1000 steps, model pushes to HF Hub automatically on completion
|
| 209 |
-
- [ ] **Verify trained model** β run `inference.py` against the trained model checkpoint
|
| 210 |
-
- [ ] **Update HF Space README** β change curriculum description to match actual step boundaries (150/350)
|
| 211 |
-
- [ ] **Submission** β ensure the inference/env Space (`AgentDebugger-env`) is live and healthy for judging
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
calibrate.py
CHANGED
|
@@ -15,9 +15,9 @@ def test_passes(code, func, inp, expected):
|
|
| 15 |
try:
|
| 16 |
r = {func}({args})
|
| 17 |
expected = {repr(expected)}
|
| 18 |
-
print("PASS" if r == expected else f"FAIL: got {
|
| 19 |
except Exception as e:
|
| 20 |
-
print(f"ERROR: {
|
| 21 |
"""
|
| 22 |
try:
|
| 23 |
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
|
|
| 15 |
try:
|
| 16 |
r = {func}({args})
|
| 17 |
expected = {repr(expected)}
|
| 18 |
+
print("PASS" if r == expected else f"FAIL: got { r} ")
|
| 19 |
except Exception as e:
|
| 20 |
+
print(f"ERROR: { e} ")
|
| 21 |
"""
|
| 22 |
try:
|
| 23 |
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
demo/gradio_app.py
CHANGED
|
@@ -1,9 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
AgentDebuggerEnv β Interactive Gradio Demo
|
| 3 |
-
==========================================
|
| 4 |
-
Demonstrates the live debugging environment with a rule-based agent.
|
| 5 |
-
Shows structured multi-turn reasoning, reward breakdown, and fix verification.
|
| 6 |
-
"""
|
| 7 |
|
| 8 |
import os
|
| 9 |
import sys
|
|
@@ -18,7 +12,7 @@ import gradio as gr
|
|
| 18 |
from env.models import parse_agent_output
|
| 19 |
from server.reward_calculator import DebugRewardCalculator
|
| 20 |
|
| 21 |
-
|
| 22 |
|
| 23 |
EXAMPLES = {
|
| 24 |
"π’ Off-by-One: binary_search": {
|
|
@@ -256,10 +250,9 @@ DETAIL: def fibonacci(n):
|
|
| 256 |
},
|
| 257 |
}
|
| 258 |
|
| 259 |
-
|
| 260 |
|
| 261 |
def _run_tests(code: str, function_name: str, test_cases: list) -> dict:
|
| 262 |
-
"""Run test cases against code in a subprocess. Returns pass/fail counts."""
|
| 263 |
passed = 0
|
| 264 |
python = shutil.which("python3") or shutil.which("python") or sys.executable
|
| 265 |
for tc in test_cases:
|
|
@@ -270,9 +263,9 @@ def _run_tests(code: str, function_name: str, test_cases: list) -> dict:
|
|
| 270 |
f"{code}\n"
|
| 271 |
f"try:\n"
|
| 272 |
f" r = {function_name}({args_str})\n"
|
| 273 |
-
f" print('PASS' if r == {repr(expected)} else f'FAIL: got {
|
| 274 |
f"except Exception as e:\n"
|
| 275 |
-
f" print(f'ERROR: {
|
| 276 |
)
|
| 277 |
try:
|
| 278 |
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
@@ -288,16 +281,12 @@ def _run_tests(code: str, function_name: str, test_cases: list) -> dict:
|
|
| 288 |
return {"passed": passed, "failed": total - passed, "total": total, "newly_broken": 0}
|
| 289 |
|
| 290 |
|
| 291 |
-
|
| 292 |
|
| 293 |
def run_debug_session(example_name: str, custom_code: str) -> str:
|
| 294 |
-
"""
|
| 295 |
-
Run the rule-based debug agent for 2 turns.
|
| 296 |
-
Returns a formatted string showing each turn's output and reward.
|
| 297 |
-
"""
|
| 298 |
calculator = DebugRewardCalculator()
|
| 299 |
|
| 300 |
-
|
| 301 |
if example_name and example_name in EXAMPLES:
|
| 302 |
bug = EXAMPLES[example_name]
|
| 303 |
code = bug["buggy_code"]
|
|
@@ -312,7 +301,7 @@ def run_debug_session(example_name: str, custom_code: str) -> str:
|
|
| 312 |
function_name = bug["function_name"]
|
| 313 |
initial_error = bug["initial_error"]
|
| 314 |
else:
|
| 315 |
-
|
| 316 |
code = custom_code.strip() if custom_code.strip() else "# No code provided"
|
| 317 |
agent_turns = [
|
| 318 |
"""\
|
|
@@ -336,7 +325,7 @@ DETAIL: """ + code,
|
|
| 336 |
function_name = ""
|
| 337 |
initial_error = "Unknown β paste your own code and observe the agent reasoning"
|
| 338 |
|
| 339 |
-
|
| 340 |
lines = []
|
| 341 |
lines.append("β" * 60)
|
| 342 |
lines.append(f"π BUGGY CODE")
|
|
@@ -356,12 +345,12 @@ DETAIL: """ + code,
|
|
| 356 |
|
| 357 |
agent_output = parse_agent_output(raw_turn)
|
| 358 |
|
| 359 |
-
|
| 360 |
test_results = {"passed": 0, "failed": 0, "total": len(test_cases), "newly_broken": 0}
|
| 361 |
if agent_output.action == "propose_fix" and test_cases and function_name:
|
| 362 |
test_results = _run_tests(agent_output.detail, function_name, test_cases)
|
| 363 |
|
| 364 |
-
|
| 365 |
reward = calculator.compute_turn_reward(
|
| 366 |
agent_output=agent_output,
|
| 367 |
ground_truth=ground_truth,
|
|
@@ -370,7 +359,7 @@ DETAIL: """ + code,
|
|
| 370 |
)
|
| 371 |
total_episode_reward += reward.total
|
| 372 |
|
| 373 |
-
|
| 374 |
lines.append(f"OBSERVATION: {agent_output.observation}")
|
| 375 |
lines.append("")
|
| 376 |
lines.append(f"HYPOTHESIS: {agent_output.hypothesis}")
|
|
@@ -380,7 +369,7 @@ DETAIL: """ + code,
|
|
| 380 |
lines.append(f"DETAIL: {agent_output.detail[:120]}{'...' if len(agent_output.detail) > 120 else ''}")
|
| 381 |
lines.append("")
|
| 382 |
|
| 383 |
-
|
| 384 |
lines.append("βββββββββββββββββββββββββββββββββββββββββββββββ")
|
| 385 |
lines.append("β Reward Breakdown β")
|
| 386 |
lines.append("ββββββββββββββββββββββββββββ¬βββββββββββββββββββ€")
|
|
@@ -395,7 +384,7 @@ DETAIL: """ + code,
|
|
| 395 |
lines.append(f"β TURN REWARD β {reward.total:+.4f} β")
|
| 396 |
lines.append("ββββββββββββββββββββββββββββ΄βββββββββββββββββββ")
|
| 397 |
|
| 398 |
-
|
| 399 |
if agent_output.action == "propose_fix" and test_results["total"] > 0:
|
| 400 |
p = test_results["passed"]
|
| 401 |
t = test_results["total"]
|
|
@@ -409,7 +398,7 @@ DETAIL: """ + code,
|
|
| 409 |
|
| 410 |
lines.append("")
|
| 411 |
|
| 412 |
-
|
| 413 |
lines.append("β" * 60)
|
| 414 |
if solved:
|
| 415 |
lines.append(f" β
SOLVED in {len(agent_turns)} turns | Episode reward: {total_episode_reward:+.3f}")
|
|
@@ -424,10 +413,9 @@ DETAIL: """ + code,
|
|
| 424 |
return "\n".join(lines)
|
| 425 |
|
| 426 |
|
| 427 |
-
|
| 428 |
|
| 429 |
def load_example(example_name: str) -> str:
|
| 430 |
-
"""Return the buggy code for the selected example."""
|
| 431 |
if example_name and example_name in EXAMPLES:
|
| 432 |
return EXAMPLES[example_name]["buggy_code"]
|
| 433 |
return ""
|
|
@@ -480,7 +468,7 @@ The environment scores every turn across 6 reward components grounded in two res
|
|
| 480 |
inputs=example_dropdown,
|
| 481 |
outputs=custom_code,
|
| 482 |
)
|
| 483 |
-
|
| 484 |
demo.load(
|
| 485 |
fn=lambda: load_example(example_names[0]),
|
| 486 |
outputs=custom_code,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import os
|
| 3 |
import sys
|
|
|
|
| 12 |
from env.models import parse_agent_output
|
| 13 |
from server.reward_calculator import DebugRewardCalculator
|
| 14 |
|
| 15 |
+
|
| 16 |
|
| 17 |
EXAMPLES = {
|
| 18 |
"π’ Off-by-One: binary_search": {
|
|
|
|
| 250 |
},
|
| 251 |
}
|
| 252 |
|
| 253 |
+
|
| 254 |
|
| 255 |
def _run_tests(code: str, function_name: str, test_cases: list) -> dict:
|
|
|
|
| 256 |
passed = 0
|
| 257 |
python = shutil.which("python3") or shutil.which("python") or sys.executable
|
| 258 |
for tc in test_cases:
|
|
|
|
| 263 |
f"{code}\n"
|
| 264 |
f"try:\n"
|
| 265 |
f" r = {function_name}({args_str})\n"
|
| 266 |
+
f" print('PASS' if r == {repr(expected)} else f'FAIL: got { r} ')\n"
|
| 267 |
f"except Exception as e:\n"
|
| 268 |
+
f" print(f'ERROR: { e} ')\n"
|
| 269 |
)
|
| 270 |
try:
|
| 271 |
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
|
|
|
|
| 281 |
return {"passed": passed, "failed": total - passed, "total": total, "newly_broken": 0}
|
| 282 |
|
| 283 |
|
| 284 |
+
|
| 285 |
|
| 286 |
def run_debug_session(example_name: str, custom_code: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
calculator = DebugRewardCalculator()
|
| 288 |
|
| 289 |
+
|
| 290 |
if example_name and example_name in EXAMPLES:
|
| 291 |
bug = EXAMPLES[example_name]
|
| 292 |
code = bug["buggy_code"]
|
|
|
|
| 301 |
function_name = bug["function_name"]
|
| 302 |
initial_error = bug["initial_error"]
|
| 303 |
else:
|
| 304 |
+
|
| 305 |
code = custom_code.strip() if custom_code.strip() else "# No code provided"
|
| 306 |
agent_turns = [
|
| 307 |
"""\
|
|
|
|
| 325 |
function_name = ""
|
| 326 |
initial_error = "Unknown β paste your own code and observe the agent reasoning"
|
| 327 |
|
| 328 |
+
|
| 329 |
lines = []
|
| 330 |
lines.append("β" * 60)
|
| 331 |
lines.append(f"π BUGGY CODE")
|
|
|
|
| 345 |
|
| 346 |
agent_output = parse_agent_output(raw_turn)
|
| 347 |
|
| 348 |
+
|
| 349 |
test_results = {"passed": 0, "failed": 0, "total": len(test_cases), "newly_broken": 0}
|
| 350 |
if agent_output.action == "propose_fix" and test_cases and function_name:
|
| 351 |
test_results = _run_tests(agent_output.detail, function_name, test_cases)
|
| 352 |
|
| 353 |
+
|
| 354 |
reward = calculator.compute_turn_reward(
|
| 355 |
agent_output=agent_output,
|
| 356 |
ground_truth=ground_truth,
|
|
|
|
| 359 |
)
|
| 360 |
total_episode_reward += reward.total
|
| 361 |
|
| 362 |
+
|
| 363 |
lines.append(f"OBSERVATION: {agent_output.observation}")
|
| 364 |
lines.append("")
|
| 365 |
lines.append(f"HYPOTHESIS: {agent_output.hypothesis}")
|
|
|
|
| 369 |
lines.append(f"DETAIL: {agent_output.detail[:120]}{'...' if len(agent_output.detail) > 120 else ''}")
|
| 370 |
lines.append("")
|
| 371 |
|
| 372 |
+
|
| 373 |
lines.append("βββββββββββββββββββββββββββββββββββββββββββββββ")
|
| 374 |
lines.append("β Reward Breakdown β")
|
| 375 |
lines.append("ββββββββββββββββββββββββββββ¬βββββββββββββββββββ€")
|
|
|
|
| 384 |
lines.append(f"β TURN REWARD β {reward.total:+.4f} β")
|
| 385 |
lines.append("ββββββββββββββββββββββββββββ΄βββββββββββββββββββ")
|
| 386 |
|
| 387 |
+
|
| 388 |
if agent_output.action == "propose_fix" and test_results["total"] > 0:
|
| 389 |
p = test_results["passed"]
|
| 390 |
t = test_results["total"]
|
|
|
|
| 398 |
|
| 399 |
lines.append("")
|
| 400 |
|
| 401 |
+
|
| 402 |
lines.append("β" * 60)
|
| 403 |
if solved:
|
| 404 |
lines.append(f" β
SOLVED in {len(agent_turns)} turns | Episode reward: {total_episode_reward:+.3f}")
|
|
|
|
| 413 |
return "\n".join(lines)
|
| 414 |
|
| 415 |
|
| 416 |
+
|
| 417 |
|
| 418 |
def load_example(example_name: str) -> str:
|
|
|
|
| 419 |
if example_name and example_name in EXAMPLES:
|
| 420 |
return EXAMPLES[example_name]["buggy_code"]
|
| 421 |
return ""
|
|
|
|
| 468 |
inputs=example_dropdown,
|
| 469 |
outputs=custom_code,
|
| 470 |
)
|
| 471 |
+
|
| 472 |
demo.load(
|
| 473 |
fn=lambda: load_example(example_names[0]),
|
| 474 |
outputs=custom_code,
|
env/__pycache__/environment.cpython-313.pyc
CHANGED
|
Binary files a/env/__pycache__/environment.cpython-313.pyc and b/env/__pycache__/environment.cpython-313.pyc differ
|
|
|
eval_run.log
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 0 |
0%| | 0/40 [00:00<?, ?it/s]The following generation flags are not valid and may be ignored: ['temperature', 'top_p', 'top_k']. Set `TRANSFORMERS_VERBOSITY=info` for more details.
|
|
|
|
| 1 |
+
W0707 11:06:09.884000 56937 .venv/lib/python3.13/site-packages/torch/distributed/elastic/multiprocessing/redirects.py:29] NOTE: Redirects are currently not supported in Windows or MacOs.
|
| 2 |
+
`torch_dtype` is deprecated! Use `dtype` instead!
|
| 3 |
+
Loading base model: Qwen/Qwen2.5-Coder-3B-Instruct...
|
| 4 |
+
Using device: mps | dtype: torch.float16
|
| 5 |
+
|
| 6 |
+
Loading LoRA adapter: shashaank0707/AgentDebugger-trained...
|
| 7 |
+
Moving model to target device: mps...
|
| 8 |
+
|
| 9 |
+
Initializing environment and loading bugs...
|
| 10 |
+
|
| 11 |
+
Evaluating Tier 1 bugs...
|
| 12 |
+
|
| 13 |
0%| | 0/40 [00:00<?, ?it/s]The following generation flags are not valid and may be ignored: ['temperature', 'top_p', 'top_k']. Set `TRANSFORMERS_VERBOSITY=info` for more details.
|
evaluate_model.py
CHANGED
|
@@ -8,16 +8,16 @@ from dotenv import load_dotenv
|
|
| 8 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 9 |
from peft import PeftModel
|
| 10 |
|
| 11 |
-
|
| 12 |
load_dotenv()
|
| 13 |
|
| 14 |
-
|
| 15 |
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
from env.environment import DebuggerEnvironment
|
| 17 |
from env.models import parse_agent_output
|
| 18 |
from server.reward_calculator import DebugRewardCalculator
|
| 19 |
|
| 20 |
-
|
| 21 |
SYSTEM_PROMPT = """You are an expert Python debugger. You reason through bugs systematically.
|
| 22 |
|
| 23 |
You MUST respond in EXACTLY this format β no exceptions, no extra text:
|
|
@@ -51,7 +51,7 @@ def main():
|
|
| 51 |
parser.add_argument("--base-model", type=str, default="Qwen/Qwen2.5-Coder-3B-Instruct", help="Base model identifier")
|
| 52 |
args = parser.parse_args()
|
| 53 |
|
| 54 |
-
|
| 55 |
hf_token = os.environ.get("HF_TOKEN")
|
| 56 |
if not hf_token:
|
| 57 |
print("WARNING: HF_TOKEN environment variable not set. Loading a private repository might fail.")
|
|
@@ -80,7 +80,7 @@ def main():
|
|
| 80 |
token=hf_token
|
| 81 |
)
|
| 82 |
|
| 83 |
-
|
| 84 |
if device in ["mps", "cpu"]:
|
| 85 |
print(f"Moving model to target device: {device}...")
|
| 86 |
model = model.to(device)
|
|
@@ -125,12 +125,12 @@ def main():
|
|
| 125 |
tier_solved = 0
|
| 126 |
|
| 127 |
for bug in tqdm(bugs):
|
| 128 |
-
|
| 129 |
env.current_bug = bug
|
| 130 |
env.current_episode_trajectory = []
|
| 131 |
env.turn_number = 0
|
| 132 |
|
| 133 |
-
|
| 134 |
prompt = bug_to_prompt(bug)
|
| 135 |
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 136 |
|
|
@@ -143,7 +143,7 @@ def main():
|
|
| 143 |
|
| 144 |
completion = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
|
| 145 |
|
| 146 |
-
|
| 147 |
step_result = env.step_curriculum(completion)
|
| 148 |
info = step_result["info"]
|
| 149 |
reward_breakdown = info["reward_breakdown"]
|
|
@@ -154,7 +154,7 @@ def main():
|
|
| 154 |
solved_bugs_count += 1
|
| 155 |
total_bugs_count += 1
|
| 156 |
|
| 157 |
-
|
| 158 |
bug_detail = {
|
| 159 |
"id": bug.get("id"),
|
| 160 |
"function_name": bug.get("function_name"),
|
|
@@ -190,7 +190,7 @@ def main():
|
|
| 190 |
"solve_rate": solved_bugs_count / total_bugs_count if total_bugs_count else 0.0,
|
| 191 |
}
|
| 192 |
|
| 193 |
-
|
| 194 |
output = {
|
| 195 |
"summary": summary,
|
| 196 |
"results": results
|
|
|
|
| 8 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 9 |
from peft import PeftModel
|
| 10 |
|
| 11 |
+
|
| 12 |
load_dotenv()
|
| 13 |
|
| 14 |
+
|
| 15 |
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
| 16 |
from env.environment import DebuggerEnvironment
|
| 17 |
from env.models import parse_agent_output
|
| 18 |
from server.reward_calculator import DebugRewardCalculator
|
| 19 |
|
| 20 |
+
|
| 21 |
SYSTEM_PROMPT = """You are an expert Python debugger. You reason through bugs systematically.
|
| 22 |
|
| 23 |
You MUST respond in EXACTLY this format β no exceptions, no extra text:
|
|
|
|
| 51 |
parser.add_argument("--base-model", type=str, default="Qwen/Qwen2.5-Coder-3B-Instruct", help="Base model identifier")
|
| 52 |
args = parser.parse_args()
|
| 53 |
|
| 54 |
+
|
| 55 |
hf_token = os.environ.get("HF_TOKEN")
|
| 56 |
if not hf_token:
|
| 57 |
print("WARNING: HF_TOKEN environment variable not set. Loading a private repository might fail.")
|
|
|
|
| 80 |
token=hf_token
|
| 81 |
)
|
| 82 |
|
| 83 |
+
|
| 84 |
if device in ["mps", "cpu"]:
|
| 85 |
print(f"Moving model to target device: {device}...")
|
| 86 |
model = model.to(device)
|
|
|
|
| 125 |
tier_solved = 0
|
| 126 |
|
| 127 |
for bug in tqdm(bugs):
|
| 128 |
+
|
| 129 |
env.current_bug = bug
|
| 130 |
env.current_episode_trajectory = []
|
| 131 |
env.turn_number = 0
|
| 132 |
|
| 133 |
+
|
| 134 |
prompt = bug_to_prompt(bug)
|
| 135 |
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 136 |
|
|
|
|
| 143 |
|
| 144 |
completion = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
|
| 145 |
|
| 146 |
+
|
| 147 |
step_result = env.step_curriculum(completion)
|
| 148 |
info = step_result["info"]
|
| 149 |
reward_breakdown = info["reward_breakdown"]
|
|
|
|
| 154 |
solved_bugs_count += 1
|
| 155 |
total_bugs_count += 1
|
| 156 |
|
| 157 |
+
|
| 158 |
bug_detail = {
|
| 159 |
"id": bug.get("id"),
|
| 160 |
"function_name": bug.get("function_name"),
|
|
|
|
| 190 |
"solve_rate": solved_bugs_count / total_bugs_count if total_bugs_count else 0.0,
|
| 191 |
}
|
| 192 |
|
| 193 |
+
|
| 194 |
output = {
|
| 195 |
"summary": summary,
|
| 196 |
"results": results
|
evaluation_results.json
CHANGED
|
@@ -41,9 +41,12 @@
|
|
| 41 |
},
|
| 42 |
"reward": 1.0,
|
| 43 |
"reward_breakdown": {
|
| 44 |
-
"
|
| 45 |
-
"
|
| 46 |
-
"
|
|
|
|
|
|
|
|
|
|
| 47 |
},
|
| 48 |
"test_results": {
|
| 49 |
"passed": 4,
|
|
@@ -65,9 +68,12 @@
|
|
| 65 |
},
|
| 66 |
"reward": 1.0,
|
| 67 |
"reward_breakdown": {
|
| 68 |
-
"
|
| 69 |
-
"
|
| 70 |
-
"
|
|
|
|
|
|
|
|
|
|
| 71 |
},
|
| 72 |
"test_results": {
|
| 73 |
"passed": 4,
|
|
@@ -89,9 +95,12 @@
|
|
| 89 |
},
|
| 90 |
"reward": 1.0,
|
| 91 |
"reward_breakdown": {
|
| 92 |
-
"
|
| 93 |
-
"
|
| 94 |
-
"
|
|
|
|
|
|
|
|
|
|
| 95 |
},
|
| 96 |
"test_results": {
|
| 97 |
"passed": 4,
|
|
@@ -113,9 +122,12 @@
|
|
| 113 |
},
|
| 114 |
"reward": 1.0,
|
| 115 |
"reward_breakdown": {
|
| 116 |
-
"
|
| 117 |
-
"
|
| 118 |
-
"
|
|
|
|
|
|
|
|
|
|
| 119 |
},
|
| 120 |
"test_results": {
|
| 121 |
"passed": 4,
|
|
@@ -137,9 +149,12 @@
|
|
| 137 |
},
|
| 138 |
"reward": 1.0,
|
| 139 |
"reward_breakdown": {
|
| 140 |
-
"
|
| 141 |
-
"
|
| 142 |
-
"
|
|
|
|
|
|
|
|
|
|
| 143 |
},
|
| 144 |
"test_results": {
|
| 145 |
"passed": 4,
|
|
@@ -161,9 +176,12 @@
|
|
| 161 |
},
|
| 162 |
"reward": 1.0,
|
| 163 |
"reward_breakdown": {
|
| 164 |
-
"
|
| 165 |
-
"
|
| 166 |
-
"
|
|
|
|
|
|
|
|
|
|
| 167 |
},
|
| 168 |
"test_results": {
|
| 169 |
"passed": 4,
|
|
@@ -185,9 +203,12 @@
|
|
| 185 |
},
|
| 186 |
"reward": 1.0,
|
| 187 |
"reward_breakdown": {
|
| 188 |
-
"
|
| 189 |
-
"
|
| 190 |
-
"
|
|
|
|
|
|
|
|
|
|
| 191 |
},
|
| 192 |
"test_results": {
|
| 193 |
"passed": 4,
|
|
@@ -209,9 +230,12 @@
|
|
| 209 |
},
|
| 210 |
"reward": 1.0,
|
| 211 |
"reward_breakdown": {
|
| 212 |
-
"
|
| 213 |
-
"
|
| 214 |
-
"
|
|
|
|
|
|
|
|
|
|
| 215 |
},
|
| 216 |
"test_results": {
|
| 217 |
"passed": 4,
|
|
@@ -233,9 +257,12 @@
|
|
| 233 |
},
|
| 234 |
"reward": 1.0,
|
| 235 |
"reward_breakdown": {
|
| 236 |
-
"
|
| 237 |
-
"
|
| 238 |
-
"
|
|
|
|
|
|
|
|
|
|
| 239 |
},
|
| 240 |
"test_results": {
|
| 241 |
"passed": 4,
|
|
@@ -257,9 +284,12 @@
|
|
| 257 |
},
|
| 258 |
"reward": 1.0,
|
| 259 |
"reward_breakdown": {
|
| 260 |
-
"
|
| 261 |
-
"
|
| 262 |
-
"
|
|
|
|
|
|
|
|
|
|
| 263 |
},
|
| 264 |
"test_results": {
|
| 265 |
"passed": 4,
|
|
@@ -281,9 +311,12 @@
|
|
| 281 |
},
|
| 282 |
"reward": 1.0,
|
| 283 |
"reward_breakdown": {
|
| 284 |
-
"
|
| 285 |
-
"
|
| 286 |
-
"
|
|
|
|
|
|
|
|
|
|
| 287 |
},
|
| 288 |
"test_results": {
|
| 289 |
"passed": 4,
|
|
@@ -305,9 +338,12 @@
|
|
| 305 |
},
|
| 306 |
"reward": 1.0,
|
| 307 |
"reward_breakdown": {
|
| 308 |
-
"
|
| 309 |
-
"
|
| 310 |
-
"
|
|
|
|
|
|
|
|
|
|
| 311 |
},
|
| 312 |
"test_results": {
|
| 313 |
"passed": 4,
|
|
@@ -329,9 +365,12 @@
|
|
| 329 |
},
|
| 330 |
"reward": 1.0,
|
| 331 |
"reward_breakdown": {
|
| 332 |
-
"
|
| 333 |
-
"
|
| 334 |
-
"
|
|
|
|
|
|
|
|
|
|
| 335 |
},
|
| 336 |
"test_results": {
|
| 337 |
"passed": 4,
|
|
@@ -353,9 +392,12 @@
|
|
| 353 |
},
|
| 354 |
"reward": 1.0,
|
| 355 |
"reward_breakdown": {
|
| 356 |
-
"
|
| 357 |
-
"
|
| 358 |
-
"
|
|
|
|
|
|
|
|
|
|
| 359 |
},
|
| 360 |
"test_results": {
|
| 361 |
"passed": 4,
|
|
@@ -377,9 +419,12 @@
|
|
| 377 |
},
|
| 378 |
"reward": 1.0,
|
| 379 |
"reward_breakdown": {
|
| 380 |
-
"
|
| 381 |
-
"
|
| 382 |
-
"
|
|
|
|
|
|
|
|
|
|
| 383 |
},
|
| 384 |
"test_results": {
|
| 385 |
"passed": 4,
|
|
@@ -401,9 +446,12 @@
|
|
| 401 |
},
|
| 402 |
"reward": 1.0,
|
| 403 |
"reward_breakdown": {
|
| 404 |
-
"
|
| 405 |
-
"
|
| 406 |
-
"
|
|
|
|
|
|
|
|
|
|
| 407 |
},
|
| 408 |
"test_results": {
|
| 409 |
"passed": 4,
|
|
@@ -425,9 +473,12 @@
|
|
| 425 |
},
|
| 426 |
"reward": 1.0,
|
| 427 |
"reward_breakdown": {
|
| 428 |
-
"
|
| 429 |
-
"
|
| 430 |
-
"
|
|
|
|
|
|
|
|
|
|
| 431 |
},
|
| 432 |
"test_results": {
|
| 433 |
"passed": 4,
|
|
@@ -449,9 +500,12 @@
|
|
| 449 |
},
|
| 450 |
"reward": 1.0,
|
| 451 |
"reward_breakdown": {
|
| 452 |
-
"
|
| 453 |
-
"
|
| 454 |
-
"
|
|
|
|
|
|
|
|
|
|
| 455 |
},
|
| 456 |
"test_results": {
|
| 457 |
"passed": 4,
|
|
@@ -473,9 +527,12 @@
|
|
| 473 |
},
|
| 474 |
"reward": 1.0,
|
| 475 |
"reward_breakdown": {
|
| 476 |
-
"
|
| 477 |
-
"
|
| 478 |
-
"
|
|
|
|
|
|
|
|
|
|
| 479 |
},
|
| 480 |
"test_results": {
|
| 481 |
"passed": 4,
|
|
@@ -497,9 +554,12 @@
|
|
| 497 |
},
|
| 498 |
"reward": 1.0,
|
| 499 |
"reward_breakdown": {
|
| 500 |
-
"
|
| 501 |
-
"
|
| 502 |
-
"
|
|
|
|
|
|
|
|
|
|
| 503 |
},
|
| 504 |
"test_results": {
|
| 505 |
"passed": 4,
|
|
@@ -521,9 +581,12 @@
|
|
| 521 |
},
|
| 522 |
"reward": 1.0,
|
| 523 |
"reward_breakdown": {
|
| 524 |
-
"
|
| 525 |
-
"
|
| 526 |
-
"
|
|
|
|
|
|
|
|
|
|
| 527 |
},
|
| 528 |
"test_results": {
|
| 529 |
"passed": 4,
|
|
@@ -545,9 +608,12 @@
|
|
| 545 |
},
|
| 546 |
"reward": 1.0,
|
| 547 |
"reward_breakdown": {
|
| 548 |
-
"
|
| 549 |
-
"
|
| 550 |
-
"
|
|
|
|
|
|
|
|
|
|
| 551 |
},
|
| 552 |
"test_results": {
|
| 553 |
"passed": 4,
|
|
@@ -569,9 +635,12 @@
|
|
| 569 |
},
|
| 570 |
"reward": 1.0,
|
| 571 |
"reward_breakdown": {
|
| 572 |
-
"
|
| 573 |
-
"
|
| 574 |
-
"
|
|
|
|
|
|
|
|
|
|
| 575 |
},
|
| 576 |
"test_results": {
|
| 577 |
"passed": 4,
|
|
@@ -593,9 +662,12 @@
|
|
| 593 |
},
|
| 594 |
"reward": 1.0,
|
| 595 |
"reward_breakdown": {
|
| 596 |
-
"
|
| 597 |
-
"
|
| 598 |
-
"
|
|
|
|
|
|
|
|
|
|
| 599 |
},
|
| 600 |
"test_results": {
|
| 601 |
"passed": 4,
|
|
@@ -617,9 +689,12 @@
|
|
| 617 |
},
|
| 618 |
"reward": 1.0,
|
| 619 |
"reward_breakdown": {
|
| 620 |
-
"
|
| 621 |
-
"
|
| 622 |
-
"
|
|
|
|
|
|
|
|
|
|
| 623 |
},
|
| 624 |
"test_results": {
|
| 625 |
"passed": 4,
|
|
@@ -641,9 +716,12 @@
|
|
| 641 |
},
|
| 642 |
"reward": 1.0,
|
| 643 |
"reward_breakdown": {
|
| 644 |
-
"
|
| 645 |
-
"
|
| 646 |
-
"
|
|
|
|
|
|
|
|
|
|
| 647 |
},
|
| 648 |
"test_results": {
|
| 649 |
"passed": 4,
|
|
@@ -665,9 +743,12 @@
|
|
| 665 |
},
|
| 666 |
"reward": 1.0,
|
| 667 |
"reward_breakdown": {
|
| 668 |
-
"
|
| 669 |
-
"
|
| 670 |
-
"
|
|
|
|
|
|
|
|
|
|
| 671 |
},
|
| 672 |
"test_results": {
|
| 673 |
"passed": 4,
|
|
@@ -689,9 +770,12 @@
|
|
| 689 |
},
|
| 690 |
"reward": 1.0,
|
| 691 |
"reward_breakdown": {
|
| 692 |
-
"
|
| 693 |
-
"
|
| 694 |
-
"
|
|
|
|
|
|
|
|
|
|
| 695 |
},
|
| 696 |
"test_results": {
|
| 697 |
"passed": 4,
|
|
@@ -713,9 +797,12 @@
|
|
| 713 |
},
|
| 714 |
"reward": 1.0,
|
| 715 |
"reward_breakdown": {
|
| 716 |
-
"
|
| 717 |
-
"
|
| 718 |
-
"
|
|
|
|
|
|
|
|
|
|
| 719 |
},
|
| 720 |
"test_results": {
|
| 721 |
"passed": 4,
|
|
@@ -737,9 +824,12 @@
|
|
| 737 |
},
|
| 738 |
"reward": 1.0,
|
| 739 |
"reward_breakdown": {
|
| 740 |
-
"
|
| 741 |
-
"
|
| 742 |
-
"
|
|
|
|
|
|
|
|
|
|
| 743 |
},
|
| 744 |
"test_results": {
|
| 745 |
"passed": 4,
|
|
@@ -761,9 +851,12 @@
|
|
| 761 |
},
|
| 762 |
"reward": 1.0,
|
| 763 |
"reward_breakdown": {
|
| 764 |
-
"
|
| 765 |
-
"
|
| 766 |
-
"
|
|
|
|
|
|
|
|
|
|
| 767 |
},
|
| 768 |
"test_results": {
|
| 769 |
"passed": 4,
|
|
@@ -785,9 +878,12 @@
|
|
| 785 |
},
|
| 786 |
"reward": 1.0,
|
| 787 |
"reward_breakdown": {
|
| 788 |
-
"
|
| 789 |
-
"
|
| 790 |
-
"
|
|
|
|
|
|
|
|
|
|
| 791 |
},
|
| 792 |
"test_results": {
|
| 793 |
"passed": 4,
|
|
@@ -809,9 +905,12 @@
|
|
| 809 |
},
|
| 810 |
"reward": 1.0,
|
| 811 |
"reward_breakdown": {
|
| 812 |
-
"
|
| 813 |
-
"
|
| 814 |
-
"
|
|
|
|
|
|
|
|
|
|
| 815 |
},
|
| 816 |
"test_results": {
|
| 817 |
"passed": 4,
|
|
@@ -833,9 +932,12 @@
|
|
| 833 |
},
|
| 834 |
"reward": 1.0,
|
| 835 |
"reward_breakdown": {
|
| 836 |
-
"
|
| 837 |
-
"
|
| 838 |
-
"
|
|
|
|
|
|
|
|
|
|
| 839 |
},
|
| 840 |
"test_results": {
|
| 841 |
"passed": 4,
|
|
@@ -857,9 +959,12 @@
|
|
| 857 |
},
|
| 858 |
"reward": 1.0,
|
| 859 |
"reward_breakdown": {
|
| 860 |
-
"
|
| 861 |
-
"
|
| 862 |
-
"
|
|
|
|
|
|
|
|
|
|
| 863 |
},
|
| 864 |
"test_results": {
|
| 865 |
"passed": 4,
|
|
@@ -881,9 +986,12 @@
|
|
| 881 |
},
|
| 882 |
"reward": 1.0,
|
| 883 |
"reward_breakdown": {
|
| 884 |
-
"
|
| 885 |
-
"
|
| 886 |
-
"
|
|
|
|
|
|
|
|
|
|
| 887 |
},
|
| 888 |
"test_results": {
|
| 889 |
"passed": 4,
|
|
@@ -905,9 +1013,12 @@
|
|
| 905 |
},
|
| 906 |
"reward": 1.0,
|
| 907 |
"reward_breakdown": {
|
| 908 |
-
"
|
| 909 |
-
"
|
| 910 |
-
"
|
|
|
|
|
|
|
|
|
|
| 911 |
},
|
| 912 |
"test_results": {
|
| 913 |
"passed": 4,
|
|
@@ -929,9 +1040,12 @@
|
|
| 929 |
},
|
| 930 |
"reward": 1.0,
|
| 931 |
"reward_breakdown": {
|
| 932 |
-
"
|
| 933 |
-
"
|
| 934 |
-
"
|
|
|
|
|
|
|
|
|
|
| 935 |
},
|
| 936 |
"test_results": {
|
| 937 |
"passed": 4,
|
|
@@ -953,9 +1067,12 @@
|
|
| 953 |
},
|
| 954 |
"reward": 1.0,
|
| 955 |
"reward_breakdown": {
|
| 956 |
-
"
|
| 957 |
-
"
|
| 958 |
-
"
|
|
|
|
|
|
|
|
|
|
| 959 |
},
|
| 960 |
"test_results": {
|
| 961 |
"passed": 4,
|
|
@@ -977,9 +1094,12 @@
|
|
| 977 |
},
|
| 978 |
"reward": 1.0,
|
| 979 |
"reward_breakdown": {
|
| 980 |
-
"
|
| 981 |
-
"
|
| 982 |
-
"
|
|
|
|
|
|
|
|
|
|
| 983 |
},
|
| 984 |
"test_results": {
|
| 985 |
"passed": 4,
|
|
@@ -1003,9 +1123,12 @@
|
|
| 1003 |
},
|
| 1004 |
"reward": 1.0,
|
| 1005 |
"reward_breakdown": {
|
| 1006 |
-
"
|
| 1007 |
-
"
|
| 1008 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1009 |
},
|
| 1010 |
"test_results": {
|
| 1011 |
"passed": 3,
|
|
@@ -1027,9 +1150,12 @@
|
|
| 1027 |
},
|
| 1028 |
"reward": 1.0,
|
| 1029 |
"reward_breakdown": {
|
| 1030 |
-
"
|
| 1031 |
-
"
|
| 1032 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1033 |
},
|
| 1034 |
"test_results": {
|
| 1035 |
"passed": 4,
|
|
@@ -1051,9 +1177,12 @@
|
|
| 1051 |
},
|
| 1052 |
"reward": -0.5,
|
| 1053 |
"reward_breakdown": {
|
| 1054 |
-
"
|
| 1055 |
-
"
|
| 1056 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1057 |
},
|
| 1058 |
"test_results": {
|
| 1059 |
"passed": 0,
|
|
@@ -1075,9 +1204,12 @@
|
|
| 1075 |
},
|
| 1076 |
"reward": 1.0,
|
| 1077 |
"reward_breakdown": {
|
| 1078 |
-
"
|
| 1079 |
-
"
|
| 1080 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1081 |
},
|
| 1082 |
"test_results": {
|
| 1083 |
"passed": 4,
|
|
@@ -1099,9 +1231,12 @@
|
|
| 1099 |
},
|
| 1100 |
"reward": 1.0,
|
| 1101 |
"reward_breakdown": {
|
| 1102 |
-
"
|
| 1103 |
-
"
|
| 1104 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1105 |
},
|
| 1106 |
"test_results": {
|
| 1107 |
"passed": 4,
|
|
@@ -1123,9 +1258,12 @@
|
|
| 1123 |
},
|
| 1124 |
"reward": 1.0,
|
| 1125 |
"reward_breakdown": {
|
| 1126 |
-
"
|
| 1127 |
-
"
|
| 1128 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1129 |
},
|
| 1130 |
"test_results": {
|
| 1131 |
"passed": 4,
|
|
@@ -1147,9 +1285,12 @@
|
|
| 1147 |
},
|
| 1148 |
"reward": 1.0,
|
| 1149 |
"reward_breakdown": {
|
| 1150 |
-
"
|
| 1151 |
-
"
|
| 1152 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1153 |
},
|
| 1154 |
"test_results": {
|
| 1155 |
"passed": 4,
|
|
@@ -1171,9 +1312,12 @@
|
|
| 1171 |
},
|
| 1172 |
"reward": -0.5,
|
| 1173 |
"reward_breakdown": {
|
| 1174 |
-
"
|
| 1175 |
-
"
|
| 1176 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1177 |
},
|
| 1178 |
"test_results": {
|
| 1179 |
"passed": 0,
|
|
@@ -1195,9 +1339,12 @@
|
|
| 1195 |
},
|
| 1196 |
"reward": 1.0,
|
| 1197 |
"reward_breakdown": {
|
| 1198 |
-
"
|
| 1199 |
-
"
|
| 1200 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1201 |
},
|
| 1202 |
"test_results": {
|
| 1203 |
"passed": 4,
|
|
@@ -1219,9 +1366,12 @@
|
|
| 1219 |
},
|
| 1220 |
"reward": 1.0,
|
| 1221 |
"reward_breakdown": {
|
| 1222 |
-
"
|
| 1223 |
-
"
|
| 1224 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1225 |
},
|
| 1226 |
"test_results": {
|
| 1227 |
"passed": 4,
|
|
@@ -1243,9 +1393,12 @@
|
|
| 1243 |
},
|
| 1244 |
"reward": 1.0,
|
| 1245 |
"reward_breakdown": {
|
| 1246 |
-
"
|
| 1247 |
-
"
|
| 1248 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1249 |
},
|
| 1250 |
"test_results": {
|
| 1251 |
"passed": 4,
|
|
@@ -1267,9 +1420,12 @@
|
|
| 1267 |
},
|
| 1268 |
"reward": 1.0,
|
| 1269 |
"reward_breakdown": {
|
| 1270 |
-
"
|
| 1271 |
-
"
|
| 1272 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1273 |
},
|
| 1274 |
"test_results": {
|
| 1275 |
"passed": 4,
|
|
@@ -1291,9 +1447,12 @@
|
|
| 1291 |
},
|
| 1292 |
"reward": -0.5,
|
| 1293 |
"reward_breakdown": {
|
| 1294 |
-
"
|
| 1295 |
-
"
|
| 1296 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1297 |
},
|
| 1298 |
"test_results": {
|
| 1299 |
"passed": 0,
|
|
@@ -1315,9 +1474,12 @@
|
|
| 1315 |
},
|
| 1316 |
"reward": 1.0,
|
| 1317 |
"reward_breakdown": {
|
| 1318 |
-
"
|
| 1319 |
-
"
|
| 1320 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1321 |
},
|
| 1322 |
"test_results": {
|
| 1323 |
"passed": 4,
|
|
@@ -1339,9 +1501,12 @@
|
|
| 1339 |
},
|
| 1340 |
"reward": 1.0,
|
| 1341 |
"reward_breakdown": {
|
| 1342 |
-
"
|
| 1343 |
-
"
|
| 1344 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1345 |
},
|
| 1346 |
"test_results": {
|
| 1347 |
"passed": 4,
|
|
@@ -1363,9 +1528,12 @@
|
|
| 1363 |
},
|
| 1364 |
"reward": 1.0,
|
| 1365 |
"reward_breakdown": {
|
| 1366 |
-
"
|
| 1367 |
-
"
|
| 1368 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1369 |
},
|
| 1370 |
"test_results": {
|
| 1371 |
"passed": 4,
|
|
@@ -1387,9 +1555,12 @@
|
|
| 1387 |
},
|
| 1388 |
"reward": 1.0,
|
| 1389 |
"reward_breakdown": {
|
| 1390 |
-
"
|
| 1391 |
-
"
|
| 1392 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1393 |
},
|
| 1394 |
"test_results": {
|
| 1395 |
"passed": 4,
|
|
@@ -1411,9 +1582,12 @@
|
|
| 1411 |
},
|
| 1412 |
"reward": -0.5,
|
| 1413 |
"reward_breakdown": {
|
| 1414 |
-
"
|
| 1415 |
-
"
|
| 1416 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1417 |
},
|
| 1418 |
"test_results": {
|
| 1419 |
"passed": 0,
|
|
@@ -1435,9 +1609,12 @@
|
|
| 1435 |
},
|
| 1436 |
"reward": 1.0,
|
| 1437 |
"reward_breakdown": {
|
| 1438 |
-
"
|
| 1439 |
-
"
|
| 1440 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1441 |
},
|
| 1442 |
"test_results": {
|
| 1443 |
"passed": 4,
|
|
@@ -1459,9 +1636,12 @@
|
|
| 1459 |
},
|
| 1460 |
"reward": 1.0,
|
| 1461 |
"reward_breakdown": {
|
| 1462 |
-
"
|
| 1463 |
-
"
|
| 1464 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1465 |
},
|
| 1466 |
"test_results": {
|
| 1467 |
"passed": 4,
|
|
@@ -1483,9 +1663,12 @@
|
|
| 1483 |
},
|
| 1484 |
"reward": 1.0,
|
| 1485 |
"reward_breakdown": {
|
| 1486 |
-
"
|
| 1487 |
-
"
|
| 1488 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1489 |
},
|
| 1490 |
"test_results": {
|
| 1491 |
"passed": 4,
|
|
@@ -1507,9 +1690,12 @@
|
|
| 1507 |
},
|
| 1508 |
"reward": 1.0,
|
| 1509 |
"reward_breakdown": {
|
| 1510 |
-
"
|
| 1511 |
-
"
|
| 1512 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1513 |
},
|
| 1514 |
"test_results": {
|
| 1515 |
"passed": 4,
|
|
@@ -1531,9 +1717,12 @@
|
|
| 1531 |
},
|
| 1532 |
"reward": -0.5,
|
| 1533 |
"reward_breakdown": {
|
| 1534 |
-
"
|
| 1535 |
-
"
|
| 1536 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1537 |
},
|
| 1538 |
"test_results": {
|
| 1539 |
"passed": 0,
|
|
@@ -1555,9 +1744,12 @@
|
|
| 1555 |
},
|
| 1556 |
"reward": 1.0,
|
| 1557 |
"reward_breakdown": {
|
| 1558 |
-
"
|
| 1559 |
-
"
|
| 1560 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1561 |
},
|
| 1562 |
"test_results": {
|
| 1563 |
"passed": 4,
|
|
@@ -1579,9 +1771,12 @@
|
|
| 1579 |
},
|
| 1580 |
"reward": 1.0,
|
| 1581 |
"reward_breakdown": {
|
| 1582 |
-
"
|
| 1583 |
-
"
|
| 1584 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1585 |
},
|
| 1586 |
"test_results": {
|
| 1587 |
"passed": 4,
|
|
@@ -1603,9 +1798,12 @@
|
|
| 1603 |
},
|
| 1604 |
"reward": 1.0,
|
| 1605 |
"reward_breakdown": {
|
| 1606 |
-
"
|
| 1607 |
-
"
|
| 1608 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1609 |
},
|
| 1610 |
"test_results": {
|
| 1611 |
"passed": 4,
|
|
@@ -1627,9 +1825,12 @@
|
|
| 1627 |
},
|
| 1628 |
"reward": 1.0,
|
| 1629 |
"reward_breakdown": {
|
| 1630 |
-
"
|
| 1631 |
-
"
|
| 1632 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1633 |
},
|
| 1634 |
"test_results": {
|
| 1635 |
"passed": 4,
|
|
@@ -1651,9 +1852,12 @@
|
|
| 1651 |
},
|
| 1652 |
"reward": -0.5,
|
| 1653 |
"reward_breakdown": {
|
| 1654 |
-
"
|
| 1655 |
-
"
|
| 1656 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1657 |
},
|
| 1658 |
"test_results": {
|
| 1659 |
"passed": 0,
|
|
@@ -1675,9 +1879,12 @@
|
|
| 1675 |
},
|
| 1676 |
"reward": 1.0,
|
| 1677 |
"reward_breakdown": {
|
| 1678 |
-
"
|
| 1679 |
-
"
|
| 1680 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1681 |
},
|
| 1682 |
"test_results": {
|
| 1683 |
"passed": 4,
|
|
@@ -1699,9 +1906,12 @@
|
|
| 1699 |
},
|
| 1700 |
"reward": -0.5,
|
| 1701 |
"reward_breakdown": {
|
| 1702 |
-
"
|
| 1703 |
-
"
|
| 1704 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1705 |
},
|
| 1706 |
"test_results": {
|
| 1707 |
"passed": 0,
|
|
@@ -1725,9 +1935,12 @@
|
|
| 1725 |
},
|
| 1726 |
"reward": 1.0,
|
| 1727 |
"reward_breakdown": {
|
| 1728 |
-
"
|
| 1729 |
-
"
|
| 1730 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1731 |
},
|
| 1732 |
"test_results": {
|
| 1733 |
"passed": 4,
|
|
@@ -1749,9 +1962,12 @@
|
|
| 1749 |
},
|
| 1750 |
"reward": -0.5,
|
| 1751 |
"reward_breakdown": {
|
| 1752 |
-
"
|
| 1753 |
-
"
|
| 1754 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1755 |
},
|
| 1756 |
"test_results": {
|
| 1757 |
"passed": 0,
|
|
@@ -1773,9 +1989,12 @@
|
|
| 1773 |
},
|
| 1774 |
"reward": 1.0,
|
| 1775 |
"reward_breakdown": {
|
| 1776 |
-
"
|
| 1777 |
-
"
|
| 1778 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1779 |
},
|
| 1780 |
"test_results": {
|
| 1781 |
"passed": 4,
|
|
@@ -1797,9 +2016,12 @@
|
|
| 1797 |
},
|
| 1798 |
"reward": -0.5,
|
| 1799 |
"reward_breakdown": {
|
| 1800 |
-
"
|
| 1801 |
-
"
|
| 1802 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1803 |
},
|
| 1804 |
"test_results": {
|
| 1805 |
"passed": 0,
|
|
@@ -1821,9 +2043,12 @@
|
|
| 1821 |
},
|
| 1822 |
"reward": 1.0,
|
| 1823 |
"reward_breakdown": {
|
| 1824 |
-
"
|
| 1825 |
-
"
|
| 1826 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1827 |
},
|
| 1828 |
"test_results": {
|
| 1829 |
"passed": 4,
|
|
@@ -1845,9 +2070,12 @@
|
|
| 1845 |
},
|
| 1846 |
"reward": -0.5,
|
| 1847 |
"reward_breakdown": {
|
| 1848 |
-
"
|
| 1849 |
-
"
|
| 1850 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1851 |
},
|
| 1852 |
"test_results": {
|
| 1853 |
"passed": 0,
|
|
@@ -1869,9 +2097,12 @@
|
|
| 1869 |
},
|
| 1870 |
"reward": 1.0,
|
| 1871 |
"reward_breakdown": {
|
| 1872 |
-
"
|
| 1873 |
-
"
|
| 1874 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1875 |
},
|
| 1876 |
"test_results": {
|
| 1877 |
"passed": 4,
|
|
@@ -1893,9 +2124,12 @@
|
|
| 1893 |
},
|
| 1894 |
"reward": -0.5,
|
| 1895 |
"reward_breakdown": {
|
| 1896 |
-
"
|
| 1897 |
-
"
|
| 1898 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1899 |
},
|
| 1900 |
"test_results": {
|
| 1901 |
"passed": 0,
|
|
@@ -1917,9 +2151,12 @@
|
|
| 1917 |
},
|
| 1918 |
"reward": 1.0,
|
| 1919 |
"reward_breakdown": {
|
| 1920 |
-
"
|
| 1921 |
-
"
|
| 1922 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1923 |
},
|
| 1924 |
"test_results": {
|
| 1925 |
"passed": 4,
|
|
@@ -1941,9 +2178,12 @@
|
|
| 1941 |
},
|
| 1942 |
"reward": -0.5,
|
| 1943 |
"reward_breakdown": {
|
| 1944 |
-
"
|
| 1945 |
-
"
|
| 1946 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1947 |
},
|
| 1948 |
"test_results": {
|
| 1949 |
"passed": 0,
|
|
@@ -1965,9 +2205,12 @@
|
|
| 1965 |
},
|
| 1966 |
"reward": -0.5,
|
| 1967 |
"reward_breakdown": {
|
| 1968 |
-
"
|
| 1969 |
-
"
|
| 1970 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1971 |
},
|
| 1972 |
"test_results": {
|
| 1973 |
"passed": 0,
|
|
@@ -1989,9 +2232,12 @@
|
|
| 1989 |
},
|
| 1990 |
"reward": -0.5,
|
| 1991 |
"reward_breakdown": {
|
| 1992 |
-
"
|
| 1993 |
-
"
|
| 1994 |
-
"
|
|
|
|
|
|
|
|
|
|
| 1995 |
},
|
| 1996 |
"test_results": {
|
| 1997 |
"passed": 0,
|
|
@@ -2013,9 +2259,12 @@
|
|
| 2013 |
},
|
| 2014 |
"reward": 1.0,
|
| 2015 |
"reward_breakdown": {
|
| 2016 |
-
"
|
| 2017 |
-
"
|
| 2018 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2019 |
},
|
| 2020 |
"test_results": {
|
| 2021 |
"passed": 4,
|
|
@@ -2037,9 +2286,12 @@
|
|
| 2037 |
},
|
| 2038 |
"reward": -0.5,
|
| 2039 |
"reward_breakdown": {
|
| 2040 |
-
"
|
| 2041 |
-
"
|
| 2042 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2043 |
},
|
| 2044 |
"test_results": {
|
| 2045 |
"passed": 0,
|
|
@@ -2061,9 +2313,12 @@
|
|
| 2061 |
},
|
| 2062 |
"reward": 1.0,
|
| 2063 |
"reward_breakdown": {
|
| 2064 |
-
"
|
| 2065 |
-
"
|
| 2066 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2067 |
},
|
| 2068 |
"test_results": {
|
| 2069 |
"passed": 4,
|
|
@@ -2085,9 +2340,12 @@
|
|
| 2085 |
},
|
| 2086 |
"reward": -0.5,
|
| 2087 |
"reward_breakdown": {
|
| 2088 |
-
"
|
| 2089 |
-
"
|
| 2090 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2091 |
},
|
| 2092 |
"test_results": {
|
| 2093 |
"passed": 0,
|
|
@@ -2109,9 +2367,12 @@
|
|
| 2109 |
},
|
| 2110 |
"reward": 1.0,
|
| 2111 |
"reward_breakdown": {
|
| 2112 |
-
"
|
| 2113 |
-
"
|
| 2114 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2115 |
},
|
| 2116 |
"test_results": {
|
| 2117 |
"passed": 4,
|
|
@@ -2133,9 +2394,12 @@
|
|
| 2133 |
},
|
| 2134 |
"reward": -0.5,
|
| 2135 |
"reward_breakdown": {
|
| 2136 |
-
"
|
| 2137 |
-
"
|
| 2138 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2139 |
},
|
| 2140 |
"test_results": {
|
| 2141 |
"passed": 0,
|
|
@@ -2157,9 +2421,12 @@
|
|
| 2157 |
},
|
| 2158 |
"reward": 1.0,
|
| 2159 |
"reward_breakdown": {
|
| 2160 |
-
"
|
| 2161 |
-
"
|
| 2162 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2163 |
},
|
| 2164 |
"test_results": {
|
| 2165 |
"passed": 4,
|
|
@@ -2181,9 +2448,12 @@
|
|
| 2181 |
},
|
| 2182 |
"reward": -0.5,
|
| 2183 |
"reward_breakdown": {
|
| 2184 |
-
"
|
| 2185 |
-
"
|
| 2186 |
-
"
|
|
|
|
|
|
|
|
|
|
| 2187 |
},
|
| 2188 |
"test_results": {
|
| 2189 |
"passed": 0,
|
|
|
|
| 41 |
},
|
| 42 |
"reward": 1.0,
|
| 43 |
"reward_breakdown": {
|
| 44 |
+
"format_compliance": 0.2,
|
| 45 |
+
"hypothesis_quality": 0.2,
|
| 46 |
+
"localization": 0.2,
|
| 47 |
+
"fix_quality": 0.3,
|
| 48 |
+
"semantic_similarity": 0.1,
|
| 49 |
+
"efficiency_potential": 0.0
|
| 50 |
},
|
| 51 |
"test_results": {
|
| 52 |
"passed": 4,
|
|
|
|
| 68 |
},
|
| 69 |
"reward": 1.0,
|
| 70 |
"reward_breakdown": {
|
| 71 |
+
"format_compliance": 0.2,
|
| 72 |
+
"hypothesis_quality": 0.2,
|
| 73 |
+
"localization": 0.2,
|
| 74 |
+
"fix_quality": 0.3,
|
| 75 |
+
"semantic_similarity": 0.1,
|
| 76 |
+
"efficiency_potential": 0.0
|
| 77 |
},
|
| 78 |
"test_results": {
|
| 79 |
"passed": 4,
|
|
|
|
| 95 |
},
|
| 96 |
"reward": 1.0,
|
| 97 |
"reward_breakdown": {
|
| 98 |
+
"format_compliance": 0.2,
|
| 99 |
+
"hypothesis_quality": 0.2,
|
| 100 |
+
"localization": 0.2,
|
| 101 |
+
"fix_quality": 0.3,
|
| 102 |
+
"semantic_similarity": 0.1,
|
| 103 |
+
"efficiency_potential": 0.0
|
| 104 |
},
|
| 105 |
"test_results": {
|
| 106 |
"passed": 4,
|
|
|
|
| 122 |
},
|
| 123 |
"reward": 1.0,
|
| 124 |
"reward_breakdown": {
|
| 125 |
+
"format_compliance": 0.2,
|
| 126 |
+
"hypothesis_quality": 0.2,
|
| 127 |
+
"localization": 0.2,
|
| 128 |
+
"fix_quality": 0.3,
|
| 129 |
+
"semantic_similarity": 0.1,
|
| 130 |
+
"efficiency_potential": 0.0
|
| 131 |
},
|
| 132 |
"test_results": {
|
| 133 |
"passed": 4,
|
|
|
|
| 149 |
},
|
| 150 |
"reward": 1.0,
|
| 151 |
"reward_breakdown": {
|
| 152 |
+
"format_compliance": 0.2,
|
| 153 |
+
"hypothesis_quality": 0.2,
|
| 154 |
+
"localization": 0.2,
|
| 155 |
+
"fix_quality": 0.3,
|
| 156 |
+
"semantic_similarity": 0.1,
|
| 157 |
+
"efficiency_potential": 0.0
|
| 158 |
},
|
| 159 |
"test_results": {
|
| 160 |
"passed": 4,
|
|
|
|
| 176 |
},
|
| 177 |
"reward": 1.0,
|
| 178 |
"reward_breakdown": {
|
| 179 |
+
"format_compliance": 0.2,
|
| 180 |
+
"hypothesis_quality": 0.2,
|
| 181 |
+
"localization": 0.2,
|
| 182 |
+
"fix_quality": 0.3,
|
| 183 |
+
"semantic_similarity": 0.1,
|
| 184 |
+
"efficiency_potential": 0.0
|
| 185 |
},
|
| 186 |
"test_results": {
|
| 187 |
"passed": 4,
|
|
|
|
| 203 |
},
|
| 204 |
"reward": 1.0,
|
| 205 |
"reward_breakdown": {
|
| 206 |
+
"format_compliance": 0.2,
|
| 207 |
+
"hypothesis_quality": 0.2,
|
| 208 |
+
"localization": 0.2,
|
| 209 |
+
"fix_quality": 0.3,
|
| 210 |
+
"semantic_similarity": 0.1,
|
| 211 |
+
"efficiency_potential": 0.0
|
| 212 |
},
|
| 213 |
"test_results": {
|
| 214 |
"passed": 4,
|
|
|
|
| 230 |
},
|
| 231 |
"reward": 1.0,
|
| 232 |
"reward_breakdown": {
|
| 233 |
+
"format_compliance": 0.2,
|
| 234 |
+
"hypothesis_quality": 0.2,
|
| 235 |
+
"localization": 0.2,
|
| 236 |
+
"fix_quality": 0.3,
|
| 237 |
+
"semantic_similarity": 0.1,
|
| 238 |
+
"efficiency_potential": 0.0
|
| 239 |
},
|
| 240 |
"test_results": {
|
| 241 |
"passed": 4,
|
|
|
|
| 257 |
},
|
| 258 |
"reward": 1.0,
|
| 259 |
"reward_breakdown": {
|
| 260 |
+
"format_compliance": 0.2,
|
| 261 |
+
"hypothesis_quality": 0.2,
|
| 262 |
+
"localization": 0.2,
|
| 263 |
+
"fix_quality": 0.3,
|
| 264 |
+
"semantic_similarity": 0.1,
|
| 265 |
+
"efficiency_potential": 0.0
|
| 266 |
},
|
| 267 |
"test_results": {
|
| 268 |
"passed": 4,
|
|
|
|
| 284 |
},
|
| 285 |
"reward": 1.0,
|
| 286 |
"reward_breakdown": {
|
| 287 |
+
"format_compliance": 0.2,
|
| 288 |
+
"hypothesis_quality": 0.2,
|
| 289 |
+
"localization": 0.2,
|
| 290 |
+
"fix_quality": 0.3,
|
| 291 |
+
"semantic_similarity": 0.1,
|
| 292 |
+
"efficiency_potential": 0.0
|
| 293 |
},
|
| 294 |
"test_results": {
|
| 295 |
"passed": 4,
|
|
|
|
| 311 |
},
|
| 312 |
"reward": 1.0,
|
| 313 |
"reward_breakdown": {
|
| 314 |
+
"format_compliance": 0.2,
|
| 315 |
+
"hypothesis_quality": 0.2,
|
| 316 |
+
"localization": 0.2,
|
| 317 |
+
"fix_quality": 0.3,
|
| 318 |
+
"semantic_similarity": 0.1,
|
| 319 |
+
"efficiency_potential": 0.0
|
| 320 |
},
|
| 321 |
"test_results": {
|
| 322 |
"passed": 4,
|
|
|
|
| 338 |
},
|
| 339 |
"reward": 1.0,
|
| 340 |
"reward_breakdown": {
|
| 341 |
+
"format_compliance": 0.2,
|
| 342 |
+
"hypothesis_quality": 0.2,
|
| 343 |
+
"localization": 0.2,
|
| 344 |
+
"fix_quality": 0.3,
|
| 345 |
+
"semantic_similarity": 0.1,
|
| 346 |
+
"efficiency_potential": 0.0
|
| 347 |
},
|
| 348 |
"test_results": {
|
| 349 |
"passed": 4,
|
|
|
|
| 365 |
},
|
| 366 |
"reward": 1.0,
|
| 367 |
"reward_breakdown": {
|
| 368 |
+
"format_compliance": 0.2,
|
| 369 |
+
"hypothesis_quality": 0.2,
|
| 370 |
+
"localization": 0.2,
|
| 371 |
+
"fix_quality": 0.3,
|
| 372 |
+
"semantic_similarity": 0.1,
|
| 373 |
+
"efficiency_potential": 0.0
|
| 374 |
},
|
| 375 |
"test_results": {
|
| 376 |
"passed": 4,
|
|
|
|
| 392 |
},
|
| 393 |
"reward": 1.0,
|
| 394 |
"reward_breakdown": {
|
| 395 |
+
"format_compliance": 0.2,
|
| 396 |
+
"hypothesis_quality": 0.2,
|
| 397 |
+
"localization": 0.2,
|
| 398 |
+
"fix_quality": 0.3,
|
| 399 |
+
"semantic_similarity": 0.1,
|
| 400 |
+
"efficiency_potential": 0.0
|
| 401 |
},
|
| 402 |
"test_results": {
|
| 403 |
"passed": 4,
|
|
|
|
| 419 |
},
|
| 420 |
"reward": 1.0,
|
| 421 |
"reward_breakdown": {
|
| 422 |
+
"format_compliance": 0.2,
|
| 423 |
+
"hypothesis_quality": 0.2,
|
| 424 |
+
"localization": 0.2,
|
| 425 |
+
"fix_quality": 0.3,
|
| 426 |
+
"semantic_similarity": 0.1,
|
| 427 |
+
"efficiency_potential": 0.0
|
| 428 |
},
|
| 429 |
"test_results": {
|
| 430 |
"passed": 4,
|
|
|
|
| 446 |
},
|
| 447 |
"reward": 1.0,
|
| 448 |
"reward_breakdown": {
|
| 449 |
+
"format_compliance": 0.2,
|
| 450 |
+
"hypothesis_quality": 0.2,
|
| 451 |
+
"localization": 0.2,
|
| 452 |
+
"fix_quality": 0.3,
|
| 453 |
+
"semantic_similarity": 0.1,
|
| 454 |
+
"efficiency_potential": 0.0
|
| 455 |
},
|
| 456 |
"test_results": {
|
| 457 |
"passed": 4,
|
|
|
|
| 473 |
},
|
| 474 |
"reward": 1.0,
|
| 475 |
"reward_breakdown": {
|
| 476 |
+
"format_compliance": 0.2,
|
| 477 |
+
"hypothesis_quality": 0.2,
|
| 478 |
+
"localization": 0.2,
|
| 479 |
+
"fix_quality": 0.3,
|
| 480 |
+
"semantic_similarity": 0.1,
|
| 481 |
+
"efficiency_potential": 0.0
|
| 482 |
},
|
| 483 |
"test_results": {
|
| 484 |
"passed": 4,
|
|
|
|
| 500 |
},
|
| 501 |
"reward": 1.0,
|
| 502 |
"reward_breakdown": {
|
| 503 |
+
"format_compliance": 0.2,
|
| 504 |
+
"hypothesis_quality": 0.2,
|
| 505 |
+
"localization": 0.2,
|
| 506 |
+
"fix_quality": 0.3,
|
| 507 |
+
"semantic_similarity": 0.1,
|
| 508 |
+
"efficiency_potential": 0.0
|
| 509 |
},
|
| 510 |
"test_results": {
|
| 511 |
"passed": 4,
|
|
|
|
| 527 |
},
|
| 528 |
"reward": 1.0,
|
| 529 |
"reward_breakdown": {
|
| 530 |
+
"format_compliance": 0.2,
|
| 531 |
+
"hypothesis_quality": 0.2,
|
| 532 |
+
"localization": 0.2,
|
| 533 |
+
"fix_quality": 0.3,
|
| 534 |
+
"semantic_similarity": 0.1,
|
| 535 |
+
"efficiency_potential": 0.0
|
| 536 |
},
|
| 537 |
"test_results": {
|
| 538 |
"passed": 4,
|
|
|
|
| 554 |
},
|
| 555 |
"reward": 1.0,
|
| 556 |
"reward_breakdown": {
|
| 557 |
+
"format_compliance": 0.2,
|
| 558 |
+
"hypothesis_quality": 0.2,
|
| 559 |
+
"localization": 0.2,
|
| 560 |
+
"fix_quality": 0.3,
|
| 561 |
+
"semantic_similarity": 0.1,
|
| 562 |
+
"efficiency_potential": 0.0
|
| 563 |
},
|
| 564 |
"test_results": {
|
| 565 |
"passed": 4,
|
|
|
|
| 581 |
},
|
| 582 |
"reward": 1.0,
|
| 583 |
"reward_breakdown": {
|
| 584 |
+
"format_compliance": 0.2,
|
| 585 |
+
"hypothesis_quality": 0.2,
|
| 586 |
+
"localization": 0.2,
|
| 587 |
+
"fix_quality": 0.3,
|
| 588 |
+
"semantic_similarity": 0.1,
|
| 589 |
+
"efficiency_potential": 0.0
|
| 590 |
},
|
| 591 |
"test_results": {
|
| 592 |
"passed": 4,
|
|
|
|
| 608 |
},
|
| 609 |
"reward": 1.0,
|
| 610 |
"reward_breakdown": {
|
| 611 |
+
"format_compliance": 0.2,
|
| 612 |
+
"hypothesis_quality": 0.2,
|
| 613 |
+
"localization": 0.2,
|
| 614 |
+
"fix_quality": 0.3,
|
| 615 |
+
"semantic_similarity": 0.1,
|
| 616 |
+
"efficiency_potential": 0.0
|
| 617 |
},
|
| 618 |
"test_results": {
|
| 619 |
"passed": 4,
|
|
|
|
| 635 |
},
|
| 636 |
"reward": 1.0,
|
| 637 |
"reward_breakdown": {
|
| 638 |
+
"format_compliance": 0.2,
|
| 639 |
+
"hypothesis_quality": 0.2,
|
| 640 |
+
"localization": 0.2,
|
| 641 |
+
"fix_quality": 0.3,
|
| 642 |
+
"semantic_similarity": 0.1,
|
| 643 |
+
"efficiency_potential": 0.0
|
| 644 |
},
|
| 645 |
"test_results": {
|
| 646 |
"passed": 4,
|
|
|
|
| 662 |
},
|
| 663 |
"reward": 1.0,
|
| 664 |
"reward_breakdown": {
|
| 665 |
+
"format_compliance": 0.2,
|
| 666 |
+
"hypothesis_quality": 0.2,
|
| 667 |
+
"localization": 0.2,
|
| 668 |
+
"fix_quality": 0.3,
|
| 669 |
+
"semantic_similarity": 0.1,
|
| 670 |
+
"efficiency_potential": 0.0
|
| 671 |
},
|
| 672 |
"test_results": {
|
| 673 |
"passed": 4,
|
|
|
|
| 689 |
},
|
| 690 |
"reward": 1.0,
|
| 691 |
"reward_breakdown": {
|
| 692 |
+
"format_compliance": 0.2,
|
| 693 |
+
"hypothesis_quality": 0.2,
|
| 694 |
+
"localization": 0.2,
|
| 695 |
+
"fix_quality": 0.3,
|
| 696 |
+
"semantic_similarity": 0.1,
|
| 697 |
+
"efficiency_potential": 0.0
|
| 698 |
},
|
| 699 |
"test_results": {
|
| 700 |
"passed": 4,
|
|
|
|
| 716 |
},
|
| 717 |
"reward": 1.0,
|
| 718 |
"reward_breakdown": {
|
| 719 |
+
"format_compliance": 0.2,
|
| 720 |
+
"hypothesis_quality": 0.2,
|
| 721 |
+
"localization": 0.2,
|
| 722 |
+
"fix_quality": 0.3,
|
| 723 |
+
"semantic_similarity": 0.1,
|
| 724 |
+
"efficiency_potential": 0.0
|
| 725 |
},
|
| 726 |
"test_results": {
|
| 727 |
"passed": 4,
|
|
|
|
| 743 |
},
|
| 744 |
"reward": 1.0,
|
| 745 |
"reward_breakdown": {
|
| 746 |
+
"format_compliance": 0.2,
|
| 747 |
+
"hypothesis_quality": 0.2,
|
| 748 |
+
"localization": 0.2,
|
| 749 |
+
"fix_quality": 0.3,
|
| 750 |
+
"semantic_similarity": 0.1,
|
| 751 |
+
"efficiency_potential": 0.0
|
| 752 |
},
|
| 753 |
"test_results": {
|
| 754 |
"passed": 4,
|
|
|
|
| 770 |
},
|
| 771 |
"reward": 1.0,
|
| 772 |
"reward_breakdown": {
|
| 773 |
+
"format_compliance": 0.2,
|
| 774 |
+
"hypothesis_quality": 0.2,
|
| 775 |
+
"localization": 0.2,
|
| 776 |
+
"fix_quality": 0.3,
|
| 777 |
+
"semantic_similarity": 0.1,
|
| 778 |
+
"efficiency_potential": 0.0
|
| 779 |
},
|
| 780 |
"test_results": {
|
| 781 |
"passed": 4,
|
|
|
|
| 797 |
},
|
| 798 |
"reward": 1.0,
|
| 799 |
"reward_breakdown": {
|
| 800 |
+
"format_compliance": 0.2,
|
| 801 |
+
"hypothesis_quality": 0.2,
|
| 802 |
+
"localization": 0.2,
|
| 803 |
+
"fix_quality": 0.3,
|
| 804 |
+
"semantic_similarity": 0.1,
|
| 805 |
+
"efficiency_potential": 0.0
|
| 806 |
},
|
| 807 |
"test_results": {
|
| 808 |
"passed": 4,
|
|
|
|
| 824 |
},
|
| 825 |
"reward": 1.0,
|
| 826 |
"reward_breakdown": {
|
| 827 |
+
"format_compliance": 0.2,
|
| 828 |
+
"hypothesis_quality": 0.2,
|
| 829 |
+
"localization": 0.2,
|
| 830 |
+
"fix_quality": 0.3,
|
| 831 |
+
"semantic_similarity": 0.1,
|
| 832 |
+
"efficiency_potential": 0.0
|
| 833 |
},
|
| 834 |
"test_results": {
|
| 835 |
"passed": 4,
|
|
|
|
| 851 |
},
|
| 852 |
"reward": 1.0,
|
| 853 |
"reward_breakdown": {
|
| 854 |
+
"format_compliance": 0.2,
|
| 855 |
+
"hypothesis_quality": 0.2,
|
| 856 |
+
"localization": 0.2,
|
| 857 |
+
"fix_quality": 0.3,
|
| 858 |
+
"semantic_similarity": 0.1,
|
| 859 |
+
"efficiency_potential": 0.0
|
| 860 |
},
|
| 861 |
"test_results": {
|
| 862 |
"passed": 4,
|
|
|
|
| 878 |
},
|
| 879 |
"reward": 1.0,
|
| 880 |
"reward_breakdown": {
|
| 881 |
+
"format_compliance": 0.2,
|
| 882 |
+
"hypothesis_quality": 0.2,
|
| 883 |
+
"localization": 0.2,
|
| 884 |
+
"fix_quality": 0.3,
|
| 885 |
+
"semantic_similarity": 0.1,
|
| 886 |
+
"efficiency_potential": 0.0
|
| 887 |
},
|
| 888 |
"test_results": {
|
| 889 |
"passed": 4,
|
|
|
|
| 905 |
},
|
| 906 |
"reward": 1.0,
|
| 907 |
"reward_breakdown": {
|
| 908 |
+
"format_compliance": 0.2,
|
| 909 |
+
"hypothesis_quality": 0.2,
|
| 910 |
+
"localization": 0.2,
|
| 911 |
+
"fix_quality": 0.3,
|
| 912 |
+
"semantic_similarity": 0.1,
|
| 913 |
+
"efficiency_potential": 0.0
|
| 914 |
},
|
| 915 |
"test_results": {
|
| 916 |
"passed": 4,
|
|
|
|
| 932 |
},
|
| 933 |
"reward": 1.0,
|
| 934 |
"reward_breakdown": {
|
| 935 |
+
"format_compliance": 0.2,
|
| 936 |
+
"hypothesis_quality": 0.2,
|
| 937 |
+
"localization": 0.2,
|
| 938 |
+
"fix_quality": 0.3,
|
| 939 |
+
"semantic_similarity": 0.1,
|
| 940 |
+
"efficiency_potential": 0.0
|
| 941 |
},
|
| 942 |
"test_results": {
|
| 943 |
"passed": 4,
|
|
|
|
| 959 |
},
|
| 960 |
"reward": 1.0,
|
| 961 |
"reward_breakdown": {
|
| 962 |
+
"format_compliance": 0.2,
|
| 963 |
+
"hypothesis_quality": 0.2,
|
| 964 |
+
"localization": 0.2,
|
| 965 |
+
"fix_quality": 0.3,
|
| 966 |
+
"semantic_similarity": 0.1,
|
| 967 |
+
"efficiency_potential": 0.0
|
| 968 |
},
|
| 969 |
"test_results": {
|
| 970 |
"passed": 4,
|
|
|
|
| 986 |
},
|
| 987 |
"reward": 1.0,
|
| 988 |
"reward_breakdown": {
|
| 989 |
+
"format_compliance": 0.2,
|
| 990 |
+
"hypothesis_quality": 0.2,
|
| 991 |
+
"localization": 0.2,
|
| 992 |
+
"fix_quality": 0.3,
|
| 993 |
+
"semantic_similarity": 0.1,
|
| 994 |
+
"efficiency_potential": 0.0
|
| 995 |
},
|
| 996 |
"test_results": {
|
| 997 |
"passed": 4,
|
|
|
|
| 1013 |
},
|
| 1014 |
"reward": 1.0,
|
| 1015 |
"reward_breakdown": {
|
| 1016 |
+
"format_compliance": 0.2,
|
| 1017 |
+
"hypothesis_quality": 0.2,
|
| 1018 |
+
"localization": 0.2,
|
| 1019 |
+
"fix_quality": 0.3,
|
| 1020 |
+
"semantic_similarity": 0.1,
|
| 1021 |
+
"efficiency_potential": 0.0
|
| 1022 |
},
|
| 1023 |
"test_results": {
|
| 1024 |
"passed": 4,
|
|
|
|
| 1040 |
},
|
| 1041 |
"reward": 1.0,
|
| 1042 |
"reward_breakdown": {
|
| 1043 |
+
"format_compliance": 0.2,
|
| 1044 |
+
"hypothesis_quality": 0.2,
|
| 1045 |
+
"localization": 0.2,
|
| 1046 |
+
"fix_quality": 0.3,
|
| 1047 |
+
"semantic_similarity": 0.1,
|
| 1048 |
+
"efficiency_potential": 0.0
|
| 1049 |
},
|
| 1050 |
"test_results": {
|
| 1051 |
"passed": 4,
|
|
|
|
| 1067 |
},
|
| 1068 |
"reward": 1.0,
|
| 1069 |
"reward_breakdown": {
|
| 1070 |
+
"format_compliance": 0.2,
|
| 1071 |
+
"hypothesis_quality": 0.2,
|
| 1072 |
+
"localization": 0.2,
|
| 1073 |
+
"fix_quality": 0.3,
|
| 1074 |
+
"semantic_similarity": 0.1,
|
| 1075 |
+
"efficiency_potential": 0.0
|
| 1076 |
},
|
| 1077 |
"test_results": {
|
| 1078 |
"passed": 4,
|
|
|
|
| 1094 |
},
|
| 1095 |
"reward": 1.0,
|
| 1096 |
"reward_breakdown": {
|
| 1097 |
+
"format_compliance": 0.2,
|
| 1098 |
+
"hypothesis_quality": 0.2,
|
| 1099 |
+
"localization": 0.2,
|
| 1100 |
+
"fix_quality": 0.3,
|
| 1101 |
+
"semantic_similarity": 0.1,
|
| 1102 |
+
"efficiency_potential": 0.0
|
| 1103 |
},
|
| 1104 |
"test_results": {
|
| 1105 |
"passed": 4,
|
|
|
|
| 1123 |
},
|
| 1124 |
"reward": 1.0,
|
| 1125 |
"reward_breakdown": {
|
| 1126 |
+
"format_compliance": 0.2,
|
| 1127 |
+
"hypothesis_quality": 0.2,
|
| 1128 |
+
"localization": 0.2,
|
| 1129 |
+
"fix_quality": 0.3,
|
| 1130 |
+
"semantic_similarity": 0.1,
|
| 1131 |
+
"efficiency_potential": 0.0
|
| 1132 |
},
|
| 1133 |
"test_results": {
|
| 1134 |
"passed": 3,
|
|
|
|
| 1150 |
},
|
| 1151 |
"reward": 1.0,
|
| 1152 |
"reward_breakdown": {
|
| 1153 |
+
"format_compliance": 0.2,
|
| 1154 |
+
"hypothesis_quality": 0.2,
|
| 1155 |
+
"localization": 0.2,
|
| 1156 |
+
"fix_quality": 0.3,
|
| 1157 |
+
"semantic_similarity": 0.1,
|
| 1158 |
+
"efficiency_potential": 0.0
|
| 1159 |
},
|
| 1160 |
"test_results": {
|
| 1161 |
"passed": 4,
|
|
|
|
| 1177 |
},
|
| 1178 |
"reward": -0.5,
|
| 1179 |
"reward_breakdown": {
|
| 1180 |
+
"format_compliance": 0.2,
|
| 1181 |
+
"hypothesis_quality": 0.0,
|
| 1182 |
+
"localization": 0.0,
|
| 1183 |
+
"fix_quality": 0.0,
|
| 1184 |
+
"semantic_similarity": 0.0,
|
| 1185 |
+
"efficiency_potential": 0.0
|
| 1186 |
},
|
| 1187 |
"test_results": {
|
| 1188 |
"passed": 0,
|
|
|
|
| 1204 |
},
|
| 1205 |
"reward": 1.0,
|
| 1206 |
"reward_breakdown": {
|
| 1207 |
+
"format_compliance": 0.2,
|
| 1208 |
+
"hypothesis_quality": 0.2,
|
| 1209 |
+
"localization": 0.2,
|
| 1210 |
+
"fix_quality": 0.3,
|
| 1211 |
+
"semantic_similarity": 0.1,
|
| 1212 |
+
"efficiency_potential": 0.0
|
| 1213 |
},
|
| 1214 |
"test_results": {
|
| 1215 |
"passed": 4,
|
|
|
|
| 1231 |
},
|
| 1232 |
"reward": 1.0,
|
| 1233 |
"reward_breakdown": {
|
| 1234 |
+
"format_compliance": 0.2,
|
| 1235 |
+
"hypothesis_quality": 0.2,
|
| 1236 |
+
"localization": 0.2,
|
| 1237 |
+
"fix_quality": 0.3,
|
| 1238 |
+
"semantic_similarity": 0.1,
|
| 1239 |
+
"efficiency_potential": 0.0
|
| 1240 |
},
|
| 1241 |
"test_results": {
|
| 1242 |
"passed": 4,
|
|
|
|
| 1258 |
},
|
| 1259 |
"reward": 1.0,
|
| 1260 |
"reward_breakdown": {
|
| 1261 |
+
"format_compliance": 0.2,
|
| 1262 |
+
"hypothesis_quality": 0.2,
|
| 1263 |
+
"localization": 0.2,
|
| 1264 |
+
"fix_quality": 0.3,
|
| 1265 |
+
"semantic_similarity": 0.1,
|
| 1266 |
+
"efficiency_potential": 0.0
|
| 1267 |
},
|
| 1268 |
"test_results": {
|
| 1269 |
"passed": 4,
|
|
|
|
| 1285 |
},
|
| 1286 |
"reward": 1.0,
|
| 1287 |
"reward_breakdown": {
|
| 1288 |
+
"format_compliance": 0.2,
|
| 1289 |
+
"hypothesis_quality": 0.2,
|
| 1290 |
+
"localization": 0.2,
|
| 1291 |
+
"fix_quality": 0.3,
|
| 1292 |
+
"semantic_similarity": 0.1,
|
| 1293 |
+
"efficiency_potential": 0.0
|
| 1294 |
},
|
| 1295 |
"test_results": {
|
| 1296 |
"passed": 4,
|
|
|
|
| 1312 |
},
|
| 1313 |
"reward": -0.5,
|
| 1314 |
"reward_breakdown": {
|
| 1315 |
+
"format_compliance": 0.2,
|
| 1316 |
+
"hypothesis_quality": 0.0,
|
| 1317 |
+
"localization": 0.0,
|
| 1318 |
+
"fix_quality": 0.0,
|
| 1319 |
+
"semantic_similarity": 0.0,
|
| 1320 |
+
"efficiency_potential": 0.0
|
| 1321 |
},
|
| 1322 |
"test_results": {
|
| 1323 |
"passed": 0,
|
|
|
|
| 1339 |
},
|
| 1340 |
"reward": 1.0,
|
| 1341 |
"reward_breakdown": {
|
| 1342 |
+
"format_compliance": 0.2,
|
| 1343 |
+
"hypothesis_quality": 0.2,
|
| 1344 |
+
"localization": 0.2,
|
| 1345 |
+
"fix_quality": 0.3,
|
| 1346 |
+
"semantic_similarity": 0.1,
|
| 1347 |
+
"efficiency_potential": 0.0
|
| 1348 |
},
|
| 1349 |
"test_results": {
|
| 1350 |
"passed": 4,
|
|
|
|
| 1366 |
},
|
| 1367 |
"reward": 1.0,
|
| 1368 |
"reward_breakdown": {
|
| 1369 |
+
"format_compliance": 0.2,
|
| 1370 |
+
"hypothesis_quality": 0.2,
|
| 1371 |
+
"localization": 0.2,
|
| 1372 |
+
"fix_quality": 0.3,
|
| 1373 |
+
"semantic_similarity": 0.1,
|
| 1374 |
+
"efficiency_potential": 0.0
|
| 1375 |
},
|
| 1376 |
"test_results": {
|
| 1377 |
"passed": 4,
|
|
|
|
| 1393 |
},
|
| 1394 |
"reward": 1.0,
|
| 1395 |
"reward_breakdown": {
|
| 1396 |
+
"format_compliance": 0.2,
|
| 1397 |
+
"hypothesis_quality": 0.2,
|
| 1398 |
+
"localization": 0.2,
|
| 1399 |
+
"fix_quality": 0.3,
|
| 1400 |
+
"semantic_similarity": 0.1,
|
| 1401 |
+
"efficiency_potential": 0.0
|
| 1402 |
},
|
| 1403 |
"test_results": {
|
| 1404 |
"passed": 4,
|
|
|
|
| 1420 |
},
|
| 1421 |
"reward": 1.0,
|
| 1422 |
"reward_breakdown": {
|
| 1423 |
+
"format_compliance": 0.2,
|
| 1424 |
+
"hypothesis_quality": 0.2,
|
| 1425 |
+
"localization": 0.2,
|
| 1426 |
+
"fix_quality": 0.3,
|
| 1427 |
+
"semantic_similarity": 0.1,
|
| 1428 |
+
"efficiency_potential": 0.0
|
| 1429 |
},
|
| 1430 |
"test_results": {
|
| 1431 |
"passed": 4,
|
|
|
|
| 1447 |
},
|
| 1448 |
"reward": -0.5,
|
| 1449 |
"reward_breakdown": {
|
| 1450 |
+
"format_compliance": 0.2,
|
| 1451 |
+
"hypothesis_quality": 0.0,
|
| 1452 |
+
"localization": 0.0,
|
| 1453 |
+
"fix_quality": 0.0,
|
| 1454 |
+
"semantic_similarity": 0.0,
|
| 1455 |
+
"efficiency_potential": 0.0
|
| 1456 |
},
|
| 1457 |
"test_results": {
|
| 1458 |
"passed": 0,
|
|
|
|
| 1474 |
},
|
| 1475 |
"reward": 1.0,
|
| 1476 |
"reward_breakdown": {
|
| 1477 |
+
"format_compliance": 0.2,
|
| 1478 |
+
"hypothesis_quality": 0.2,
|
| 1479 |
+
"localization": 0.2,
|
| 1480 |
+
"fix_quality": 0.3,
|
| 1481 |
+
"semantic_similarity": 0.1,
|
| 1482 |
+
"efficiency_potential": 0.0
|
| 1483 |
},
|
| 1484 |
"test_results": {
|
| 1485 |
"passed": 4,
|
|
|
|
| 1501 |
},
|
| 1502 |
"reward": 1.0,
|
| 1503 |
"reward_breakdown": {
|
| 1504 |
+
"format_compliance": 0.2,
|
| 1505 |
+
"hypothesis_quality": 0.2,
|
| 1506 |
+
"localization": 0.2,
|
| 1507 |
+
"fix_quality": 0.3,
|
| 1508 |
+
"semantic_similarity": 0.1,
|
| 1509 |
+
"efficiency_potential": 0.0
|
| 1510 |
},
|
| 1511 |
"test_results": {
|
| 1512 |
"passed": 4,
|
|
|
|
| 1528 |
},
|
| 1529 |
"reward": 1.0,
|
| 1530 |
"reward_breakdown": {
|
| 1531 |
+
"format_compliance": 0.2,
|
| 1532 |
+
"hypothesis_quality": 0.2,
|
| 1533 |
+
"localization": 0.2,
|
| 1534 |
+
"fix_quality": 0.3,
|
| 1535 |
+
"semantic_similarity": 0.1,
|
| 1536 |
+
"efficiency_potential": 0.0
|
| 1537 |
},
|
| 1538 |
"test_results": {
|
| 1539 |
"passed": 4,
|
|
|
|
| 1555 |
},
|
| 1556 |
"reward": 1.0,
|
| 1557 |
"reward_breakdown": {
|
| 1558 |
+
"format_compliance": 0.2,
|
| 1559 |
+
"hypothesis_quality": 0.2,
|
| 1560 |
+
"localization": 0.2,
|
| 1561 |
+
"fix_quality": 0.3,
|
| 1562 |
+
"semantic_similarity": 0.1,
|
| 1563 |
+
"efficiency_potential": 0.0
|
| 1564 |
},
|
| 1565 |
"test_results": {
|
| 1566 |
"passed": 4,
|
|
|
|
| 1582 |
},
|
| 1583 |
"reward": -0.5,
|
| 1584 |
"reward_breakdown": {
|
| 1585 |
+
"format_compliance": 0.2,
|
| 1586 |
+
"hypothesis_quality": 0.0,
|
| 1587 |
+
"localization": 0.0,
|
| 1588 |
+
"fix_quality": 0.0,
|
| 1589 |
+
"semantic_similarity": 0.0,
|
| 1590 |
+
"efficiency_potential": 0.0
|
| 1591 |
},
|
| 1592 |
"test_results": {
|
| 1593 |
"passed": 0,
|
|
|
|
| 1609 |
},
|
| 1610 |
"reward": 1.0,
|
| 1611 |
"reward_breakdown": {
|
| 1612 |
+
"format_compliance": 0.2,
|
| 1613 |
+
"hypothesis_quality": 0.2,
|
| 1614 |
+
"localization": 0.2,
|
| 1615 |
+
"fix_quality": 0.3,
|
| 1616 |
+
"semantic_similarity": 0.1,
|
| 1617 |
+
"efficiency_potential": 0.0
|
| 1618 |
},
|
| 1619 |
"test_results": {
|
| 1620 |
"passed": 4,
|
|
|
|
| 1636 |
},
|
| 1637 |
"reward": 1.0,
|
| 1638 |
"reward_breakdown": {
|
| 1639 |
+
"format_compliance": 0.2,
|
| 1640 |
+
"hypothesis_quality": 0.2,
|
| 1641 |
+
"localization": 0.2,
|
| 1642 |
+
"fix_quality": 0.3,
|
| 1643 |
+
"semantic_similarity": 0.1,
|
| 1644 |
+
"efficiency_potential": 0.0
|
| 1645 |
},
|
| 1646 |
"test_results": {
|
| 1647 |
"passed": 4,
|
|
|
|
| 1663 |
},
|
| 1664 |
"reward": 1.0,
|
| 1665 |
"reward_breakdown": {
|
| 1666 |
+
"format_compliance": 0.2,
|
| 1667 |
+
"hypothesis_quality": 0.2,
|
| 1668 |
+
"localization": 0.2,
|
| 1669 |
+
"fix_quality": 0.3,
|
| 1670 |
+
"semantic_similarity": 0.1,
|
| 1671 |
+
"efficiency_potential": 0.0
|
| 1672 |
},
|
| 1673 |
"test_results": {
|
| 1674 |
"passed": 4,
|
|
|
|
| 1690 |
},
|
| 1691 |
"reward": 1.0,
|
| 1692 |
"reward_breakdown": {
|
| 1693 |
+
"format_compliance": 0.2,
|
| 1694 |
+
"hypothesis_quality": 0.2,
|
| 1695 |
+
"localization": 0.2,
|
| 1696 |
+
"fix_quality": 0.3,
|
| 1697 |
+
"semantic_similarity": 0.1,
|
| 1698 |
+
"efficiency_potential": 0.0
|
| 1699 |
},
|
| 1700 |
"test_results": {
|
| 1701 |
"passed": 4,
|
|
|
|
| 1717 |
},
|
| 1718 |
"reward": -0.5,
|
| 1719 |
"reward_breakdown": {
|
| 1720 |
+
"format_compliance": 0.2,
|
| 1721 |
+
"hypothesis_quality": 0.0,
|
| 1722 |
+
"localization": 0.0,
|
| 1723 |
+
"fix_quality": 0.0,
|
| 1724 |
+
"semantic_similarity": 0.0,
|
| 1725 |
+
"efficiency_potential": 0.0
|
| 1726 |
},
|
| 1727 |
"test_results": {
|
| 1728 |
"passed": 0,
|
|
|
|
| 1744 |
},
|
| 1745 |
"reward": 1.0,
|
| 1746 |
"reward_breakdown": {
|
| 1747 |
+
"format_compliance": 0.2,
|
| 1748 |
+
"hypothesis_quality": 0.2,
|
| 1749 |
+
"localization": 0.2,
|
| 1750 |
+
"fix_quality": 0.3,
|
| 1751 |
+
"semantic_similarity": 0.1,
|
| 1752 |
+
"efficiency_potential": 0.0
|
| 1753 |
},
|
| 1754 |
"test_results": {
|
| 1755 |
"passed": 4,
|
|
|
|
| 1771 |
},
|
| 1772 |
"reward": 1.0,
|
| 1773 |
"reward_breakdown": {
|
| 1774 |
+
"format_compliance": 0.2,
|
| 1775 |
+
"hypothesis_quality": 0.2,
|
| 1776 |
+
"localization": 0.2,
|
| 1777 |
+
"fix_quality": 0.3,
|
| 1778 |
+
"semantic_similarity": 0.1,
|
| 1779 |
+
"efficiency_potential": 0.0
|
| 1780 |
},
|
| 1781 |
"test_results": {
|
| 1782 |
"passed": 4,
|
|
|
|
| 1798 |
},
|
| 1799 |
"reward": 1.0,
|
| 1800 |
"reward_breakdown": {
|
| 1801 |
+
"format_compliance": 0.2,
|
| 1802 |
+
"hypothesis_quality": 0.2,
|
| 1803 |
+
"localization": 0.2,
|
| 1804 |
+
"fix_quality": 0.3,
|
| 1805 |
+
"semantic_similarity": 0.1,
|
| 1806 |
+
"efficiency_potential": 0.0
|
| 1807 |
},
|
| 1808 |
"test_results": {
|
| 1809 |
"passed": 4,
|
|
|
|
| 1825 |
},
|
| 1826 |
"reward": 1.0,
|
| 1827 |
"reward_breakdown": {
|
| 1828 |
+
"format_compliance": 0.2,
|
| 1829 |
+
"hypothesis_quality": 0.2,
|
| 1830 |
+
"localization": 0.2,
|
| 1831 |
+
"fix_quality": 0.3,
|
| 1832 |
+
"semantic_similarity": 0.1,
|
| 1833 |
+
"efficiency_potential": 0.0
|
| 1834 |
},
|
| 1835 |
"test_results": {
|
| 1836 |
"passed": 4,
|
|
|
|
| 1852 |
},
|
| 1853 |
"reward": -0.5,
|
| 1854 |
"reward_breakdown": {
|
| 1855 |
+
"format_compliance": 0.2,
|
| 1856 |
+
"hypothesis_quality": 0.0,
|
| 1857 |
+
"localization": 0.0,
|
| 1858 |
+
"fix_quality": 0.0,
|
| 1859 |
+
"semantic_similarity": 0.0,
|
| 1860 |
+
"efficiency_potential": 0.0
|
| 1861 |
},
|
| 1862 |
"test_results": {
|
| 1863 |
"passed": 0,
|
|
|
|
| 1879 |
},
|
| 1880 |
"reward": 1.0,
|
| 1881 |
"reward_breakdown": {
|
| 1882 |
+
"format_compliance": 0.2,
|
| 1883 |
+
"hypothesis_quality": 0.2,
|
| 1884 |
+
"localization": 0.2,
|
| 1885 |
+
"fix_quality": 0.3,
|
| 1886 |
+
"semantic_similarity": 0.1,
|
| 1887 |
+
"efficiency_potential": 0.0
|
| 1888 |
},
|
| 1889 |
"test_results": {
|
| 1890 |
"passed": 4,
|
|
|
|
| 1906 |
},
|
| 1907 |
"reward": -0.5,
|
| 1908 |
"reward_breakdown": {
|
| 1909 |
+
"format_compliance": 0.2,
|
| 1910 |
+
"hypothesis_quality": 0.0,
|
| 1911 |
+
"localization": 0.0,
|
| 1912 |
+
"fix_quality": 0.0,
|
| 1913 |
+
"semantic_similarity": 0.0,
|
| 1914 |
+
"efficiency_potential": 0.0
|
| 1915 |
},
|
| 1916 |
"test_results": {
|
| 1917 |
"passed": 0,
|
|
|
|
| 1935 |
},
|
| 1936 |
"reward": 1.0,
|
| 1937 |
"reward_breakdown": {
|
| 1938 |
+
"format_compliance": 0.2,
|
| 1939 |
+
"hypothesis_quality": 0.2,
|
| 1940 |
+
"localization": 0.2,
|
| 1941 |
+
"fix_quality": 0.3,
|
| 1942 |
+
"semantic_similarity": 0.1,
|
| 1943 |
+
"efficiency_potential": 0.0
|
| 1944 |
},
|
| 1945 |
"test_results": {
|
| 1946 |
"passed": 4,
|
|
|
|
| 1962 |
},
|
| 1963 |
"reward": -0.5,
|
| 1964 |
"reward_breakdown": {
|
| 1965 |
+
"format_compliance": 0.2,
|
| 1966 |
+
"hypothesis_quality": 0.0,
|
| 1967 |
+
"localization": 0.0,
|
| 1968 |
+
"fix_quality": 0.0,
|
| 1969 |
+
"semantic_similarity": 0.0,
|
| 1970 |
+
"efficiency_potential": 0.0
|
| 1971 |
},
|
| 1972 |
"test_results": {
|
| 1973 |
"passed": 0,
|
|
|
|
| 1989 |
},
|
| 1990 |
"reward": 1.0,
|
| 1991 |
"reward_breakdown": {
|
| 1992 |
+
"format_compliance": 0.2,
|
| 1993 |
+
"hypothesis_quality": 0.2,
|
| 1994 |
+
"localization": 0.2,
|
| 1995 |
+
"fix_quality": 0.3,
|
| 1996 |
+
"semantic_similarity": 0.1,
|
| 1997 |
+
"efficiency_potential": 0.0
|
| 1998 |
},
|
| 1999 |
"test_results": {
|
| 2000 |
"passed": 4,
|
|
|
|
| 2016 |
},
|
| 2017 |
"reward": -0.5,
|
| 2018 |
"reward_breakdown": {
|
| 2019 |
+
"format_compliance": 0.2,
|
| 2020 |
+
"hypothesis_quality": 0.0,
|
| 2021 |
+
"localization": 0.0,
|
| 2022 |
+
"fix_quality": 0.0,
|
| 2023 |
+
"semantic_similarity": 0.0,
|
| 2024 |
+
"efficiency_potential": 0.0
|
| 2025 |
},
|
| 2026 |
"test_results": {
|
| 2027 |
"passed": 0,
|
|
|
|
| 2043 |
},
|
| 2044 |
"reward": 1.0,
|
| 2045 |
"reward_breakdown": {
|
| 2046 |
+
"format_compliance": 0.2,
|
| 2047 |
+
"hypothesis_quality": 0.2,
|
| 2048 |
+
"localization": 0.2,
|
| 2049 |
+
"fix_quality": 0.3,
|
| 2050 |
+
"semantic_similarity": 0.1,
|
| 2051 |
+
"efficiency_potential": 0.0
|
| 2052 |
},
|
| 2053 |
"test_results": {
|
| 2054 |
"passed": 4,
|
|
|
|
| 2070 |
},
|
| 2071 |
"reward": -0.5,
|
| 2072 |
"reward_breakdown": {
|
| 2073 |
+
"format_compliance": 0.2,
|
| 2074 |
+
"hypothesis_quality": 0.0,
|
| 2075 |
+
"localization": 0.0,
|
| 2076 |
+
"fix_quality": 0.0,
|
| 2077 |
+
"semantic_similarity": 0.0,
|
| 2078 |
+
"efficiency_potential": 0.0
|
| 2079 |
},
|
| 2080 |
"test_results": {
|
| 2081 |
"passed": 0,
|
|
|
|
| 2097 |
},
|
| 2098 |
"reward": 1.0,
|
| 2099 |
"reward_breakdown": {
|
| 2100 |
+
"format_compliance": 0.2,
|
| 2101 |
+
"hypothesis_quality": 0.2,
|
| 2102 |
+
"localization": 0.2,
|
| 2103 |
+
"fix_quality": 0.3,
|
| 2104 |
+
"semantic_similarity": 0.1,
|
| 2105 |
+
"efficiency_potential": 0.0
|
| 2106 |
},
|
| 2107 |
"test_results": {
|
| 2108 |
"passed": 4,
|
|
|
|
| 2124 |
},
|
| 2125 |
"reward": -0.5,
|
| 2126 |
"reward_breakdown": {
|
| 2127 |
+
"format_compliance": 0.2,
|
| 2128 |
+
"hypothesis_quality": 0.0,
|
| 2129 |
+
"localization": 0.0,
|
| 2130 |
+
"fix_quality": 0.0,
|
| 2131 |
+
"semantic_similarity": 0.0,
|
| 2132 |
+
"efficiency_potential": 0.0
|
| 2133 |
},
|
| 2134 |
"test_results": {
|
| 2135 |
"passed": 0,
|
|
|
|
| 2151 |
},
|
| 2152 |
"reward": 1.0,
|
| 2153 |
"reward_breakdown": {
|
| 2154 |
+
"format_compliance": 0.2,
|
| 2155 |
+
"hypothesis_quality": 0.2,
|
| 2156 |
+
"localization": 0.2,
|
| 2157 |
+
"fix_quality": 0.3,
|
| 2158 |
+
"semantic_similarity": 0.1,
|
| 2159 |
+
"efficiency_potential": 0.0
|
| 2160 |
},
|
| 2161 |
"test_results": {
|
| 2162 |
"passed": 4,
|
|
|
|
| 2178 |
},
|
| 2179 |
"reward": -0.5,
|
| 2180 |
"reward_breakdown": {
|
| 2181 |
+
"format_compliance": 0.2,
|
| 2182 |
+
"hypothesis_quality": 0.0,
|
| 2183 |
+
"localization": 0.0,
|
| 2184 |
+
"fix_quality": 0.0,
|
| 2185 |
+
"semantic_similarity": 0.0,
|
| 2186 |
+
"efficiency_potential": 0.0
|
| 2187 |
},
|
| 2188 |
"test_results": {
|
| 2189 |
"passed": 0,
|
|
|
|
| 2205 |
},
|
| 2206 |
"reward": -0.5,
|
| 2207 |
"reward_breakdown": {
|
| 2208 |
+
"format_compliance": 0.2,
|
| 2209 |
+
"hypothesis_quality": 0.0,
|
| 2210 |
+
"localization": 0.0,
|
| 2211 |
+
"fix_quality": 0.0,
|
| 2212 |
+
"semantic_similarity": 0.0,
|
| 2213 |
+
"efficiency_potential": 0.0
|
| 2214 |
},
|
| 2215 |
"test_results": {
|
| 2216 |
"passed": 0,
|
|
|
|
| 2232 |
},
|
| 2233 |
"reward": -0.5,
|
| 2234 |
"reward_breakdown": {
|
| 2235 |
+
"format_compliance": 0.2,
|
| 2236 |
+
"hypothesis_quality": 0.0,
|
| 2237 |
+
"localization": 0.0,
|
| 2238 |
+
"fix_quality": 0.0,
|
| 2239 |
+
"semantic_similarity": 0.0,
|
| 2240 |
+
"efficiency_potential": 0.0
|
| 2241 |
},
|
| 2242 |
"test_results": {
|
| 2243 |
"passed": 0,
|
|
|
|
| 2259 |
},
|
| 2260 |
"reward": 1.0,
|
| 2261 |
"reward_breakdown": {
|
| 2262 |
+
"format_compliance": 0.2,
|
| 2263 |
+
"hypothesis_quality": 0.2,
|
| 2264 |
+
"localization": 0.2,
|
| 2265 |
+
"fix_quality": 0.3,
|
| 2266 |
+
"semantic_similarity": 0.1,
|
| 2267 |
+
"efficiency_potential": 0.0
|
| 2268 |
},
|
| 2269 |
"test_results": {
|
| 2270 |
"passed": 4,
|
|
|
|
| 2286 |
},
|
| 2287 |
"reward": -0.5,
|
| 2288 |
"reward_breakdown": {
|
| 2289 |
+
"format_compliance": 0.2,
|
| 2290 |
+
"hypothesis_quality": 0.0,
|
| 2291 |
+
"localization": 0.0,
|
| 2292 |
+
"fix_quality": 0.0,
|
| 2293 |
+
"semantic_similarity": 0.0,
|
| 2294 |
+
"efficiency_potential": 0.0
|
| 2295 |
},
|
| 2296 |
"test_results": {
|
| 2297 |
"passed": 0,
|
|
|
|
| 2313 |
},
|
| 2314 |
"reward": 1.0,
|
| 2315 |
"reward_breakdown": {
|
| 2316 |
+
"format_compliance": 0.2,
|
| 2317 |
+
"hypothesis_quality": 0.2,
|
| 2318 |
+
"localization": 0.2,
|
| 2319 |
+
"fix_quality": 0.3,
|
| 2320 |
+
"semantic_similarity": 0.1,
|
| 2321 |
+
"efficiency_potential": 0.0
|
| 2322 |
},
|
| 2323 |
"test_results": {
|
| 2324 |
"passed": 4,
|
|
|
|
| 2340 |
},
|
| 2341 |
"reward": -0.5,
|
| 2342 |
"reward_breakdown": {
|
| 2343 |
+
"format_compliance": 0.2,
|
| 2344 |
+
"hypothesis_quality": 0.0,
|
| 2345 |
+
"localization": 0.0,
|
| 2346 |
+
"fix_quality": 0.0,
|
| 2347 |
+
"semantic_similarity": 0.0,
|
| 2348 |
+
"efficiency_potential": 0.0
|
| 2349 |
},
|
| 2350 |
"test_results": {
|
| 2351 |
"passed": 0,
|
|
|
|
| 2367 |
},
|
| 2368 |
"reward": 1.0,
|
| 2369 |
"reward_breakdown": {
|
| 2370 |
+
"format_compliance": 0.2,
|
| 2371 |
+
"hypothesis_quality": 0.2,
|
| 2372 |
+
"localization": 0.2,
|
| 2373 |
+
"fix_quality": 0.3,
|
| 2374 |
+
"semantic_similarity": 0.1,
|
| 2375 |
+
"efficiency_potential": 0.0
|
| 2376 |
},
|
| 2377 |
"test_results": {
|
| 2378 |
"passed": 4,
|
|
|
|
| 2394 |
},
|
| 2395 |
"reward": -0.5,
|
| 2396 |
"reward_breakdown": {
|
| 2397 |
+
"format_compliance": 0.2,
|
| 2398 |
+
"hypothesis_quality": 0.0,
|
| 2399 |
+
"localization": 0.0,
|
| 2400 |
+
"fix_quality": 0.0,
|
| 2401 |
+
"semantic_similarity": 0.0,
|
| 2402 |
+
"efficiency_potential": 0.0
|
| 2403 |
},
|
| 2404 |
"test_results": {
|
| 2405 |
"passed": 0,
|
|
|
|
| 2421 |
},
|
| 2422 |
"reward": 1.0,
|
| 2423 |
"reward_breakdown": {
|
| 2424 |
+
"format_compliance": 0.2,
|
| 2425 |
+
"hypothesis_quality": 0.2,
|
| 2426 |
+
"localization": 0.2,
|
| 2427 |
+
"fix_quality": 0.3,
|
| 2428 |
+
"semantic_similarity": 0.1,
|
| 2429 |
+
"efficiency_potential": 0.0
|
| 2430 |
},
|
| 2431 |
"test_results": {
|
| 2432 |
"passed": 4,
|
|
|
|
| 2448 |
},
|
| 2449 |
"reward": -0.5,
|
| 2450 |
"reward_breakdown": {
|
| 2451 |
+
"format_compliance": 0.2,
|
| 2452 |
+
"hypothesis_quality": 0.0,
|
| 2453 |
+
"localization": 0.0,
|
| 2454 |
+
"fix_quality": 0.0,
|
| 2455 |
+
"semantic_similarity": 0.0,
|
| 2456 |
+
"efficiency_potential": 0.0
|
| 2457 |
},
|
| 2458 |
"test_results": {
|
| 2459 |
"passed": 0,
|
images/gradio UI.png
ADDED
|
Git LFS Details
|
images/hypothesis_quality.png
ADDED
|
Git LFS Details
|
images/localize.png
ADDED
|
Git LFS Details
|
images/penalty.png
ADDED
|
Git LFS Details
|
images/semantic.png
ADDED
|
Git LFS Details
|
inference.py
CHANGED
|
@@ -1,14 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
AgentDebuggerEnv Baseline Inference Script
|
| 3 |
-
==========================================
|
| 4 |
-
Baseline evaluation script for testing agent performance in the
|
| 5 |
-
AgentDebugger environment.
|
| 6 |
-
|
| 7 |
-
System Configuration:
|
| 8 |
-
- API_BASE_URL: LLM API endpoint
|
| 9 |
-
- MODEL_NAME: Model identifier for evaluation
|
| 10 |
-
- HF_TOKEN: Authentication token
|
| 11 |
-
"""
|
| 12 |
|
| 13 |
import os
|
| 14 |
import json
|
|
@@ -18,7 +7,7 @@ import random
|
|
| 18 |
from openai import OpenAI, APIError, RateLimitError, APIConnectionError, APITimeoutError
|
| 19 |
import requests
|
| 20 |
|
| 21 |
-
|
| 22 |
API_BASE_URL = os.environ.get("API_BASE_URL", "https://router.huggingface.co/v1")
|
| 23 |
MODEL_NAME = os.environ.get("MODEL_NAME", "meta-llama/Llama-3.1-70B-Instruct")
|
| 24 |
HF_TOKEN = os.environ.get("HF_TOKEN") or os.environ.get("OPENAI_API_KEY", "")
|
|
@@ -66,10 +55,9 @@ Guidelines:
|
|
| 66 |
- For concurrent tasks, ensure atomic operations and proper synchronization.
|
| 67 |
"""
|
| 68 |
|
| 69 |
-
|
| 70 |
|
| 71 |
def get_completion(messages: list, model: str = MODEL_NAME, max_retries: int = 5) -> str:
|
| 72 |
-
"""Gets LLM completion with exponential backoff and retry logic."""
|
| 73 |
for attempt in range(max_retries):
|
| 74 |
try:
|
| 75 |
completion = client.chat.completions.create(
|
|
@@ -77,7 +65,7 @@ def get_completion(messages: list, model: str = MODEL_NAME, max_retries: int = 5
|
|
| 77 |
messages=messages,
|
| 78 |
max_tokens=1200,
|
| 79 |
temperature=0.2,
|
| 80 |
-
timeout=60.0
|
| 81 |
)
|
| 82 |
return completion.choices[0].message.content
|
| 83 |
except (RateLimitError, APIConnectionError, APITimeoutError) as e:
|
|
@@ -87,7 +75,7 @@ def get_completion(messages: list, model: str = MODEL_NAME, max_retries: int = 5
|
|
| 87 |
print(f" [!] API Error ({type(e).__name__}). Retrying in {wait_time:.1f}s... (Attempt {attempt+1}/{max_retries})")
|
| 88 |
time.sleep(wait_time)
|
| 89 |
except APIError as e:
|
| 90 |
-
|
| 91 |
print(f" [!] OpenAI API Error: {e}")
|
| 92 |
if attempt == max_retries - 1:
|
| 93 |
return ""
|
|
@@ -99,22 +87,21 @@ def get_completion(messages: list, model: str = MODEL_NAME, max_retries: int = 5
|
|
| 99 |
|
| 100 |
|
| 101 |
def parse_action(raw: str) -> dict:
|
| 102 |
-
"""Parse LLM response to action dict. Handle markdown code blocks."""
|
| 103 |
raw = raw.strip()
|
| 104 |
-
|
| 105 |
raw = re.sub(r'^```(?:json)?\s*', '', raw, flags=re.MULTILINE)
|
| 106 |
raw = re.sub(r'\s*```$', '', raw, flags=re.MULTILINE)
|
| 107 |
try:
|
| 108 |
return json.loads(raw)
|
| 109 |
except json.JSONDecodeError:
|
| 110 |
-
|
| 111 |
match = re.search(r'\{.*\}', raw, re.DOTALL)
|
| 112 |
if match:
|
| 113 |
try:
|
| 114 |
return json.loads(match.group())
|
| 115 |
except json.JSONDecodeError:
|
| 116 |
pass
|
| 117 |
-
|
| 118 |
return {
|
| 119 |
"action_type": "give_up",
|
| 120 |
"final_diagnosis": f"Failed to parse response: {raw[:200]}"
|
|
@@ -149,7 +136,7 @@ def build_step_message(obs: dict, reward: dict, info: dict) -> str:
|
|
| 149 |
|
| 150 |
if last_attempt and last_attempt.get("execution_output"):
|
| 151 |
output = last_attempt["execution_output"]
|
| 152 |
-
|
| 153 |
if len(output) > 1500:
|
| 154 |
output = output[:750] + "\n...[truncated]...\n" + output[-750:]
|
| 155 |
msg += f"\nNEW TEST OUTPUT:\n{output}\n"
|
|
@@ -163,14 +150,13 @@ def build_step_message(obs: dict, reward: dict, info: dict) -> str:
|
|
| 163 |
|
| 164 |
|
| 165 |
def run_episode(task_id: str) -> dict:
|
| 166 |
-
"""Run one complete debugging episode. Returns result dict."""
|
| 167 |
|
| 168 |
-
|
| 169 |
reset_resp = requests.post(f"{ENV_BASE_URL}/reset", json={"task_id": task_id}, timeout=60)
|
| 170 |
reset_resp.raise_for_status()
|
| 171 |
obs = reset_resp.json()
|
| 172 |
|
| 173 |
-
|
| 174 |
print(f"\n[START] task={task_id}", flush=True)
|
| 175 |
print(f" Description: {obs['task_description'][:100]}...", flush=True)
|
| 176 |
|
|
@@ -197,14 +183,14 @@ def run_episode(task_id: str) -> dict:
|
|
| 197 |
action = parse_action(raw)
|
| 198 |
except Exception as e:
|
| 199 |
print(f" [β] Failed to get response from LLM after retries: {e}")
|
| 200 |
-
|
| 201 |
action = {
|
| 202 |
"action_type": "give_up",
|
| 203 |
"final_diagnosis": f"Inference system failure: {str(e)}"
|
| 204 |
}
|
| 205 |
raw = json.dumps(action)
|
| 206 |
|
| 207 |
-
|
| 208 |
step_resp = requests.post(f"{ENV_BASE_URL}/step", json=action, timeout=60)
|
| 209 |
step_resp.raise_for_status()
|
| 210 |
result = step_resp.json()
|
|
@@ -215,10 +201,10 @@ def run_episode(task_id: str) -> dict:
|
|
| 215 |
info = result["info"]
|
| 216 |
last_result = result
|
| 217 |
|
| 218 |
-
|
| 219 |
print(f" [STEP {obs['step_number']}] Action: {action.get('action_type')} | Tests: {obs['tests_passed']}/{obs['tests_total']} | Reward: {reward['step_reward']:+.3f}", flush=True)
|
| 220 |
|
| 221 |
-
|
| 222 |
step_msg = build_step_message(obs, reward, info)
|
| 223 |
messages.append({"role": "assistant", "content": raw})
|
| 224 |
messages.append({"role": "user", "content": step_msg})
|
|
@@ -239,7 +225,7 @@ def run_episode(task_id: str) -> dict:
|
|
| 239 |
"final_action_type": action.get("action_type", "unknown")
|
| 240 |
}
|
| 241 |
|
| 242 |
-
|
| 243 |
print(f"[END] task={task_id} score={result['grader_score']} steps={result['steps_taken']}", flush=True)
|
| 244 |
|
| 245 |
return result
|
|
@@ -248,7 +234,7 @@ def run_episode(task_id: str) -> dict:
|
|
| 248 |
def main():
|
| 249 |
print("AgentDebuggerEnv β Baseline Inference")
|
| 250 |
|
| 251 |
-
|
| 252 |
has_token = bool(HF_TOKEN and len(HF_TOKEN) > 5)
|
| 253 |
masked_token = f"{HF_TOKEN[:4]}...{HF_TOKEN[-4:]}" if has_token else "MISSING"
|
| 254 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import os
|
| 3 |
import json
|
|
|
|
| 7 |
from openai import OpenAI, APIError, RateLimitError, APIConnectionError, APITimeoutError
|
| 8 |
import requests
|
| 9 |
|
| 10 |
+
|
| 11 |
API_BASE_URL = os.environ.get("API_BASE_URL", "https://router.huggingface.co/v1")
|
| 12 |
MODEL_NAME = os.environ.get("MODEL_NAME", "meta-llama/Llama-3.1-70B-Instruct")
|
| 13 |
HF_TOKEN = os.environ.get("HF_TOKEN") or os.environ.get("OPENAI_API_KEY", "")
|
|
|
|
| 55 |
- For concurrent tasks, ensure atomic operations and proper synchronization.
|
| 56 |
"""
|
| 57 |
|
| 58 |
+
|
| 59 |
|
| 60 |
def get_completion(messages: list, model: str = MODEL_NAME, max_retries: int = 5) -> str:
|
|
|
|
| 61 |
for attempt in range(max_retries):
|
| 62 |
try:
|
| 63 |
completion = client.chat.completions.create(
|
|
|
|
| 65 |
messages=messages,
|
| 66 |
max_tokens=1200,
|
| 67 |
temperature=0.2,
|
| 68 |
+
timeout=60.0
|
| 69 |
)
|
| 70 |
return completion.choices[0].message.content
|
| 71 |
except (RateLimitError, APIConnectionError, APITimeoutError) as e:
|
|
|
|
| 75 |
print(f" [!] API Error ({type(e).__name__}). Retrying in {wait_time:.1f}s... (Attempt {attempt+1}/{max_retries})")
|
| 76 |
time.sleep(wait_time)
|
| 77 |
except APIError as e:
|
| 78 |
+
|
| 79 |
print(f" [!] OpenAI API Error: {e}")
|
| 80 |
if attempt == max_retries - 1:
|
| 81 |
return ""
|
|
|
|
| 87 |
|
| 88 |
|
| 89 |
def parse_action(raw: str) -> dict:
|
|
|
|
| 90 |
raw = raw.strip()
|
| 91 |
+
|
| 92 |
raw = re.sub(r'^```(?:json)?\s*', '', raw, flags=re.MULTILINE)
|
| 93 |
raw = re.sub(r'\s*```$', '', raw, flags=re.MULTILINE)
|
| 94 |
try:
|
| 95 |
return json.loads(raw)
|
| 96 |
except json.JSONDecodeError:
|
| 97 |
+
|
| 98 |
match = re.search(r'\{.*\}', raw, re.DOTALL)
|
| 99 |
if match:
|
| 100 |
try:
|
| 101 |
return json.loads(match.group())
|
| 102 |
except json.JSONDecodeError:
|
| 103 |
pass
|
| 104 |
+
|
| 105 |
return {
|
| 106 |
"action_type": "give_up",
|
| 107 |
"final_diagnosis": f"Failed to parse response: {raw[:200]}"
|
|
|
|
| 136 |
|
| 137 |
if last_attempt and last_attempt.get("execution_output"):
|
| 138 |
output = last_attempt["execution_output"]
|
| 139 |
+
|
| 140 |
if len(output) > 1500:
|
| 141 |
output = output[:750] + "\n...[truncated]...\n" + output[-750:]
|
| 142 |
msg += f"\nNEW TEST OUTPUT:\n{output}\n"
|
|
|
|
| 150 |
|
| 151 |
|
| 152 |
def run_episode(task_id: str) -> dict:
|
|
|
|
| 153 |
|
| 154 |
+
|
| 155 |
reset_resp = requests.post(f"{ENV_BASE_URL}/reset", json={"task_id": task_id}, timeout=60)
|
| 156 |
reset_resp.raise_for_status()
|
| 157 |
obs = reset_resp.json()
|
| 158 |
|
| 159 |
+
|
| 160 |
print(f"\n[START] task={task_id}", flush=True)
|
| 161 |
print(f" Description: {obs['task_description'][:100]}...", flush=True)
|
| 162 |
|
|
|
|
| 183 |
action = parse_action(raw)
|
| 184 |
except Exception as e:
|
| 185 |
print(f" [β] Failed to get response from LLM after retries: {e}")
|
| 186 |
+
|
| 187 |
action = {
|
| 188 |
"action_type": "give_up",
|
| 189 |
"final_diagnosis": f"Inference system failure: {str(e)}"
|
| 190 |
}
|
| 191 |
raw = json.dumps(action)
|
| 192 |
|
| 193 |
+
|
| 194 |
step_resp = requests.post(f"{ENV_BASE_URL}/step", json=action, timeout=60)
|
| 195 |
step_resp.raise_for_status()
|
| 196 |
result = step_resp.json()
|
|
|
|
| 201 |
info = result["info"]
|
| 202 |
last_result = result
|
| 203 |
|
| 204 |
+
|
| 205 |
print(f" [STEP {obs['step_number']}] Action: {action.get('action_type')} | Tests: {obs['tests_passed']}/{obs['tests_total']} | Reward: {reward['step_reward']:+.3f}", flush=True)
|
| 206 |
|
| 207 |
+
|
| 208 |
step_msg = build_step_message(obs, reward, info)
|
| 209 |
messages.append({"role": "assistant", "content": raw})
|
| 210 |
messages.append({"role": "user", "content": step_msg})
|
|
|
|
| 225 |
"final_action_type": action.get("action_type", "unknown")
|
| 226 |
}
|
| 227 |
|
| 228 |
+
|
| 229 |
print(f"[END] task={task_id} score={result['grader_score']} steps={result['steps_taken']}", flush=True)
|
| 230 |
|
| 231 |
return result
|
|
|
|
| 234 |
def main():
|
| 235 |
print("AgentDebuggerEnv β Baseline Inference")
|
| 236 |
|
| 237 |
+
|
| 238 |
has_token = bool(HF_TOKEN and len(HF_TOKEN) > 5)
|
| 239 |
masked_token = f"{HF_TOKEN[:4]}...{HF_TOKEN[-4:]}" if has_token else "MISSING"
|
| 240 |
|
scratch/data_tier2.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
t2_bugs = [
|
| 2 |
-
|
| 3 |
{
|
| 4 |
"id": "t2_004", "difficulty": 2, "bug_type": "wrong_loop_termination", "function_name": "find_first_positive",
|
| 5 |
"buggy_code": "def find_first_positive(nums):\n i = 0\n while i < len(nums) - 1:\n if nums[i] > 0:\n return nums[i]\n i += 1\n return -1",
|
|
@@ -49,7 +49,7 @@ t2_bugs = [
|
|
| 49 |
"initial_error": "AssertionError: expected [[1,2],[3]], got [[1,2]]", "bug_location": {"function": "get_chunks", "line_start": 4},
|
| 50 |
"test_cases": [{"input": [[1, 2, 3], 2], "expected_output": [[1, 2], [3]]}, {"input": [[1, 2], 2], "expected_output": [[1, 2]]}, {"input": [[1, 2, 3, 4], 2], "expected_output": [[1, 2], [3, 4]]}, {"input": [[], 2], "expected_output": []}]
|
| 51 |
},
|
| 52 |
-
|
| 53 |
{
|
| 54 |
"id": "t2_011", "difficulty": 2, "bug_type": "incorrect_accumulation", "function_name": "sum_even_numbers",
|
| 55 |
"buggy_code": "def sum_even_numbers(nums):\n total = 1\n for n in nums:\n if n % 2 == 0:\n total += n\n return total",
|
|
@@ -99,7 +99,7 @@ t2_bugs = [
|
|
| 99 |
"initial_error": "AssertionError: expected 2, got 1", "bug_location": {"function": "count_negatives", "line_start": 2},
|
| 100 |
"test_cases": [{"input": [[1, -1, 2, -2]], "expected_output": 2}, {"input": [[1, 2, 3]], "expected_output": 0}, {"input": [[-1, -2, -3]], "expected_output": 3}, {"input": [[]], "expected_output": 0}]
|
| 101 |
},
|
| 102 |
-
|
| 103 |
{
|
| 104 |
"id": "t2_018", "difficulty": 2, "bug_type": "wrong_conditional_branch", "function_name": "classify_number",
|
| 105 |
"buggy_code": "def classify_number(n):\n if n > 0:\n return 'positive'\n elif n < 0:\n return 'negative'\n elif n == 0:\n return 'negative'",
|
|
@@ -149,7 +149,7 @@ t2_bugs = [
|
|
| 149 |
"initial_error": "AssertionError: expected 4, got 3", "bug_location": {"function": "get_quadrant", "line_start": 6},
|
| 150 |
"test_cases": [{"input": [1, 1], "expected_output": 1}, {"input": [-1, 1], "expected_output": 2}, {"input": [-1, -1], "expected_output": 3}, {"input": [1, -1], "expected_output": 4}]
|
| 151 |
},
|
| 152 |
-
|
| 153 |
{
|
| 154 |
"id": "t2_025", "difficulty": 2, "bug_type": "wrong_variable", "function_name": "merge_arrays",
|
| 155 |
"buggy_code": "def merge_arrays(a, b):\n res = a + b\n res.sort()\n return a",
|
|
|
|
| 1 |
t2_bugs = [
|
| 2 |
+
|
| 3 |
{
|
| 4 |
"id": "t2_004", "difficulty": 2, "bug_type": "wrong_loop_termination", "function_name": "find_first_positive",
|
| 5 |
"buggy_code": "def find_first_positive(nums):\n i = 0\n while i < len(nums) - 1:\n if nums[i] > 0:\n return nums[i]\n i += 1\n return -1",
|
|
|
|
| 49 |
"initial_error": "AssertionError: expected [[1,2],[3]], got [[1,2]]", "bug_location": {"function": "get_chunks", "line_start": 4},
|
| 50 |
"test_cases": [{"input": [[1, 2, 3], 2], "expected_output": [[1, 2], [3]]}, {"input": [[1, 2], 2], "expected_output": [[1, 2]]}, {"input": [[1, 2, 3, 4], 2], "expected_output": [[1, 2], [3, 4]]}, {"input": [[], 2], "expected_output": []}]
|
| 51 |
},
|
| 52 |
+
|
| 53 |
{
|
| 54 |
"id": "t2_011", "difficulty": 2, "bug_type": "incorrect_accumulation", "function_name": "sum_even_numbers",
|
| 55 |
"buggy_code": "def sum_even_numbers(nums):\n total = 1\n for n in nums:\n if n % 2 == 0:\n total += n\n return total",
|
|
|
|
| 99 |
"initial_error": "AssertionError: expected 2, got 1", "bug_location": {"function": "count_negatives", "line_start": 2},
|
| 100 |
"test_cases": [{"input": [[1, -1, 2, -2]], "expected_output": 2}, {"input": [[1, 2, 3]], "expected_output": 0}, {"input": [[-1, -2, -3]], "expected_output": 3}, {"input": [[]], "expected_output": 0}]
|
| 101 |
},
|
| 102 |
+
|
| 103 |
{
|
| 104 |
"id": "t2_018", "difficulty": 2, "bug_type": "wrong_conditional_branch", "function_name": "classify_number",
|
| 105 |
"buggy_code": "def classify_number(n):\n if n > 0:\n return 'positive'\n elif n < 0:\n return 'negative'\n elif n == 0:\n return 'negative'",
|
|
|
|
| 149 |
"initial_error": "AssertionError: expected 4, got 3", "bug_location": {"function": "get_quadrant", "line_start": 6},
|
| 150 |
"test_cases": [{"input": [1, 1], "expected_output": 1}, {"input": [-1, 1], "expected_output": 2}, {"input": [-1, -1], "expected_output": 3}, {"input": [1, -1], "expected_output": 4}]
|
| 151 |
},
|
| 152 |
+
|
| 153 |
{
|
| 154 |
"id": "t2_025", "difficulty": 2, "bug_type": "wrong_variable", "function_name": "merge_arrays",
|
| 155 |
"buggy_code": "def merge_arrays(a, b):\n res = a + b\n res.sort()\n return a",
|
scratch/data_tier3.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
t3_bugs = [
|
| 2 |
-
|
| 3 |
{
|
| 4 |
"id": "t3_003", "difficulty": 3, "bug_type": "wrong_argument_order", "function_name": "process_user",
|
| 5 |
"buggy_code": "def format_name(first, last):\n return f'{last}, {first}'\n\ndef process_user(first_name, last_name):\n return format_name(last_name, first_name)",
|
|
@@ -42,7 +42,7 @@ t3_bugs = [
|
|
| 42 |
"initial_error": "AssertionError: expected 8, got 9", "bug_location": {"function": "power_wrapper", "line_start": 5},
|
| 43 |
"test_cases": [{"input": [2, 3], "expected_output": 8}, {"input": [3, 2], "expected_output": 9}, {"input": [5, 2], "expected_output": 25}, {"input": [2, 4], "expected_output": 16}]
|
| 44 |
},
|
| 45 |
-
|
| 46 |
{
|
| 47 |
"id": "t3_009", "difficulty": 3, "bug_type": "state_not_reset", "function_name": "get_unique_items",
|
| 48 |
"buggy_code": "seen = set()\ndef filter_unique(items):\n res = []\n for item in items:\n if item not in seen:\n seen.add(item)\n res.append(item)\n return res\n\ndef get_unique_items(items):\n return filter_unique(items)",
|
|
@@ -85,7 +85,7 @@ t3_bugs = [
|
|
| 85 |
"initial_error": "AssertionError: state leak between calls", "bug_location": {"function": "log_error", "line_start": 3},
|
| 86 |
"test_cases": [{"input": [["e1"]], "expected_output": ["e1"]}, {"input": [["e2"]], "expected_output": ["e2"]}, {"input": [["e3", "e4"]], "expected_output": ["e3", "e4"]}, {"input": [["e5"]], "expected_output": ["e5"]}]
|
| 87 |
},
|
| 88 |
-
|
| 89 |
{
|
| 90 |
"id": "t3_015", "difficulty": 3, "bug_type": "missing_edge_case", "function_name": "process_data",
|
| 91 |
"buggy_code": "def get_first(lst):\n return lst[0]\n\ndef process_data(data):\n if not data:\n return None\n return [get_first(d) for d in data]",
|
|
|
|
| 1 |
t3_bugs = [
|
| 2 |
+
|
| 3 |
{
|
| 4 |
"id": "t3_003", "difficulty": 3, "bug_type": "wrong_argument_order", "function_name": "process_user",
|
| 5 |
"buggy_code": "def format_name(first, last):\n return f'{last}, {first}'\n\ndef process_user(first_name, last_name):\n return format_name(last_name, first_name)",
|
|
|
|
| 42 |
"initial_error": "AssertionError: expected 8, got 9", "bug_location": {"function": "power_wrapper", "line_start": 5},
|
| 43 |
"test_cases": [{"input": [2, 3], "expected_output": 8}, {"input": [3, 2], "expected_output": 9}, {"input": [5, 2], "expected_output": 25}, {"input": [2, 4], "expected_output": 16}]
|
| 44 |
},
|
| 45 |
+
|
| 46 |
{
|
| 47 |
"id": "t3_009", "difficulty": 3, "bug_type": "state_not_reset", "function_name": "get_unique_items",
|
| 48 |
"buggy_code": "seen = set()\ndef filter_unique(items):\n res = []\n for item in items:\n if item not in seen:\n seen.add(item)\n res.append(item)\n return res\n\ndef get_unique_items(items):\n return filter_unique(items)",
|
|
|
|
| 85 |
"initial_error": "AssertionError: state leak between calls", "bug_location": {"function": "log_error", "line_start": 3},
|
| 86 |
"test_cases": [{"input": [["e1"]], "expected_output": ["e1"]}, {"input": [["e2"]], "expected_output": ["e2"]}, {"input": [["e3", "e4"]], "expected_output": ["e3", "e4"]}, {"input": [["e5"]], "expected_output": ["e5"]}]
|
| 87 |
},
|
| 88 |
+
|
| 89 |
{
|
| 90 |
"id": "t3_015", "difficulty": 3, "bug_type": "missing_edge_case", "function_name": "process_data",
|
| 91 |
"buggy_code": "def get_first(lst):\n return lst[0]\n\ndef process_data(data):\n if not data:\n return None\n return [get_first(d) for d in data]",
|
scratch/fix_all.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
|
| 4 |
-
|
| 5 |
sys.path.append(os.path.abspath('.'))
|
| 6 |
|
| 7 |
from data.generate_bugs import TIER1_BUGS, TIER2_BUGS, TIER3_BUGS
|
|
@@ -34,7 +34,7 @@ for b in TIER1_BUGS:
|
|
| 34 |
for b in TIER2_BUGS:
|
| 35 |
if b["id"] == "t2_003":
|
| 36 |
for t in b["test_cases"]:
|
| 37 |
-
|
| 38 |
while len(t["input"]) == 1 and isinstance(t["input"][0], list) and len(t["input"][0]) == 2:
|
| 39 |
t["input"] = t["input"][0]
|
| 40 |
if len(t["input"]) == 2 and not isinstance(t["input"][0], list) and not isinstance(t["input"], tuple):
|
|
@@ -55,10 +55,10 @@ for b in TIER2_BUGS:
|
|
| 55 |
for b in TIER3_BUGS:
|
| 56 |
if b["id"] == "t3_002":
|
| 57 |
for t in b["test_cases"]:
|
| 58 |
-
|
| 59 |
while len(t["input"]) == 1 and isinstance(t["input"][0], list):
|
| 60 |
t["input"] = t["input"][0]
|
| 61 |
-
|
| 62 |
t["input"] = [t["input"]]
|
| 63 |
elif b["id"] == "t3_007":
|
| 64 |
b["buggy_code"] = b["buggy_code"].replace("calc_area(height, width)", "calc_area(height, height)")
|
|
|
|
| 1 |
import os
|
| 2 |
import sys
|
| 3 |
|
| 4 |
+
|
| 5 |
sys.path.append(os.path.abspath('.'))
|
| 6 |
|
| 7 |
from data.generate_bugs import TIER1_BUGS, TIER2_BUGS, TIER3_BUGS
|
|
|
|
| 34 |
for b in TIER2_BUGS:
|
| 35 |
if b["id"] == "t2_003":
|
| 36 |
for t in b["test_cases"]:
|
| 37 |
+
|
| 38 |
while len(t["input"]) == 1 and isinstance(t["input"][0], list) and len(t["input"][0]) == 2:
|
| 39 |
t["input"] = t["input"][0]
|
| 40 |
if len(t["input"]) == 2 and not isinstance(t["input"][0], list) and not isinstance(t["input"], tuple):
|
|
|
|
| 55 |
for b in TIER3_BUGS:
|
| 56 |
if b["id"] == "t3_002":
|
| 57 |
for t in b["test_cases"]:
|
| 58 |
+
|
| 59 |
while len(t["input"]) == 1 and isinstance(t["input"][0], list):
|
| 60 |
t["input"] = t["input"][0]
|
| 61 |
+
|
| 62 |
t["input"] = [t["input"]]
|
| 63 |
elif b["id"] == "t3_007":
|
| 64 |
b["buggy_code"] = b["buggy_code"].replace("calc_area(height, width)", "calc_area(height, height)")
|
scratch/gen_t1_base.py
CHANGED
|
@@ -80,7 +80,7 @@ funcs = [
|
|
| 80 |
}
|
| 81 |
]
|
| 82 |
|
| 83 |
-
|
| 84 |
bug_id_counter = 9
|
| 85 |
for f in funcs:
|
| 86 |
for i in range(2):
|
|
@@ -95,12 +95,12 @@ for f in funcs:
|
|
| 95 |
"bug_location": {"function": f["name"], "line_start": 2}
|
| 96 |
}
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
t1_bugs.append(bug)
|
| 101 |
bug_id_counter += 1
|
| 102 |
|
| 103 |
-
|
| 104 |
for i in range(2):
|
| 105 |
bug = {
|
| 106 |
"id": f"t1_{bug_id_counter:03d}",
|
|
|
|
| 80 |
}
|
| 81 |
]
|
| 82 |
|
| 83 |
+
|
| 84 |
bug_id_counter = 9
|
| 85 |
for f in funcs:
|
| 86 |
for i in range(2):
|
|
|
|
| 95 |
"bug_location": {"function": f["name"], "line_start": 2}
|
| 96 |
}
|
| 97 |
|
| 98 |
+
|
| 99 |
+
|
| 100 |
t1_bugs.append(bug)
|
| 101 |
bug_id_counter += 1
|
| 102 |
|
| 103 |
+
|
| 104 |
for i in range(2):
|
| 105 |
bug = {
|
| 106 |
"id": f"t1_{bug_id_counter:03d}",
|
scratch/merge.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import sys
|
| 2 |
import os
|
| 3 |
|
| 4 |
-
|
| 5 |
sys.path.append(os.path.abspath('.'))
|
| 6 |
|
| 7 |
from data.generate_bugs import TIER1_BUGS as T1_OLD
|
|
@@ -16,7 +16,7 @@ t1_all = T1_OLD + t1_bugs
|
|
| 16 |
t2_all = T2_OLD + t2_bugs
|
| 17 |
t3_all = T3_OLD + t3_bugs
|
| 18 |
|
| 19 |
-
|
| 20 |
print(f"Tier 1: {len(t1_all)}")
|
| 21 |
print(f"Tier 2: {len(t2_all)}")
|
| 22 |
print(f"Tier 3: {len(t3_all)}")
|
|
@@ -32,12 +32,12 @@ def pretty_list(lst, name):
|
|
| 32 |
lines.append(f' "{k}": (')
|
| 33 |
for line in v.split('\n'):
|
| 34 |
lines.append(f' {repr(line + "\\n")}')
|
| 35 |
-
lines[-1] = lines[-1][:-4] + "'" + lines[-1][-3:]
|
| 36 |
-
|
| 37 |
-
|
| 38 |
pass
|
| 39 |
|
| 40 |
-
|
| 41 |
with open("data/generate_bugs.py", "w", encoding="utf-8") as f:
|
| 42 |
f.write('"""\n')
|
| 43 |
f.write('AgentDebuggerEnv β Bug Dataset Generator\n\n')
|
|
@@ -55,7 +55,7 @@ with open("data/generate_bugs.py", "w", encoding="utf-8") as f:
|
|
| 55 |
f.write('import json\n')
|
| 56 |
f.write('import os\n\n')
|
| 57 |
|
| 58 |
-
|
| 59 |
import pprint
|
| 60 |
|
| 61 |
def dump_var(name, val):
|
|
@@ -71,9 +71,9 @@ with open("data/generate_bugs.py", "w", encoding="utf-8") as f:
|
|
| 71 |
f.write(' with open(path, "w") as f:\n')
|
| 72 |
f.write(' for bug in bugs:\n')
|
| 73 |
f.write(' f.write(json.dumps(bug) + "\\n")\n')
|
| 74 |
-
f.write(' print(f"Tier {path[-12]}: {len(bugs)}")\n')
|
| 75 |
-
|
| 76 |
-
|
| 77 |
f.write('\n\n')
|
| 78 |
f.write('if __name__ == "__main__":\n')
|
| 79 |
f.write(' os.makedirs("data", exist_ok=True)\n')
|
|
|
|
| 1 |
import sys
|
| 2 |
import os
|
| 3 |
|
| 4 |
+
|
| 5 |
sys.path.append(os.path.abspath('.'))
|
| 6 |
|
| 7 |
from data.generate_bugs import TIER1_BUGS as T1_OLD
|
|
|
|
| 16 |
t2_all = T2_OLD + t2_bugs
|
| 17 |
t3_all = T3_OLD + t3_bugs
|
| 18 |
|
| 19 |
+
|
| 20 |
print(f"Tier 1: {len(t1_all)}")
|
| 21 |
print(f"Tier 2: {len(t2_all)}")
|
| 22 |
print(f"Tier 3: {len(t3_all)}")
|
|
|
|
| 32 |
lines.append(f' "{k}": (')
|
| 33 |
for line in v.split('\n'):
|
| 34 |
lines.append(f' {repr(line + "\\n")}')
|
| 35 |
+
lines[-1] = lines[-1][:-4] + "'" + lines[-1][-3:]
|
| 36 |
+
|
| 37 |
+
|
| 38 |
pass
|
| 39 |
|
| 40 |
+
|
| 41 |
with open("data/generate_bugs.py", "w", encoding="utf-8") as f:
|
| 42 |
f.write('"""\n')
|
| 43 |
f.write('AgentDebuggerEnv β Bug Dataset Generator\n\n')
|
|
|
|
| 55 |
f.write('import json\n')
|
| 56 |
f.write('import os\n\n')
|
| 57 |
|
| 58 |
+
|
| 59 |
import pprint
|
| 60 |
|
| 61 |
def dump_var(name, val):
|
|
|
|
| 71 |
f.write(' with open(path, "w") as f:\n')
|
| 72 |
f.write(' for bug in bugs:\n')
|
| 73 |
f.write(' f.write(json.dumps(bug) + "\\n")\n')
|
| 74 |
+
f.write(' print(f"Tier {path[-12]}: {len(bugs)}")\n')
|
| 75 |
+
|
| 76 |
+
|
| 77 |
f.write('\n\n')
|
| 78 |
f.write('if __name__ == "__main__":\n')
|
| 79 |
f.write(' os.makedirs("data", exist_ok=True)\n')
|
server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
| 1 |
+
|
| 2 |
+
|
server/app.py
CHANGED
|
@@ -1,14 +1,8 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Server Entry Point for AgentDebuggerEnv
|
| 3 |
-
========================================
|
| 4 |
-
Main entry point to start the FastAPI server for the AgentDebugger environment.
|
| 5 |
-
"""
|
| 6 |
|
| 7 |
import uvicorn
|
| 8 |
from env.server import app
|
| 9 |
|
| 10 |
def main():
|
| 11 |
-
"""Main execution function to run the FastAPI server."""
|
| 12 |
uvicorn.run(app, host="0.0.0.0", port=8000, workers=1)
|
| 13 |
|
| 14 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import uvicorn
|
| 3 |
from env.server import app
|
| 4 |
|
| 5 |
def main():
|
|
|
|
| 6 |
uvicorn.run(app, host="0.0.0.0", port=8000, workers=1)
|
| 7 |
|
| 8 |
if __name__ == "__main__":
|
server/models.py
CHANGED
|
@@ -1,10 +1,5 @@
|
|
| 1 |
-
"""
|
| 2 |
-
server/models.py β Re-exports structured agent types for training scripts.
|
| 3 |
-
All core types live in env/models.py; this module exposes them under the
|
| 4 |
-
`server` namespace so training/train_grpo.py can import without path changes.
|
| 5 |
-
"""
|
| 6 |
|
| 7 |
-
from env.models import (
|
| 8 |
StructuredAgentOutput,
|
| 9 |
parse_agent_output,
|
| 10 |
VALID_ACTIONS,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
+
from env.models import (
|
| 3 |
StructuredAgentOutput,
|
| 4 |
parse_agent_output,
|
| 5 |
VALID_ACTIONS,
|
server/reward_calculator.py
CHANGED
|
@@ -1,17 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
DebugRewardCalculator β Multi-component reward system for AgentDebuggerEnv.
|
| 3 |
-
|
| 4 |
-
Reward taxonomy follows:
|
| 5 |
-
- Masud et al. (2026) "Reward Engineering for RL in Software Tasks"
|
| 6 |
-
β Uses their execution-based + process-based + semantic similarity taxonomy
|
| 7 |
-
- Ibrahim et al. (2024) "Comprehensive Overview of Reward Engineering and Shaping"
|
| 8 |
-
β Uses potential-based shaping for efficiency component to preserve policy invariance
|
| 9 |
-
|
| 10 |
-
Design principle: GRPO learns by comparing completions WITHIN a group.
|
| 11 |
-
Relative reward differences matter more than absolute values.
|
| 12 |
-
Therefore: be generous with partial credit so the model gets differentiated signal
|
| 13 |
-
even when nothing fully works.
|
| 14 |
-
"""
|
| 15 |
|
| 16 |
import difflib
|
| 17 |
import re
|
|
@@ -22,34 +8,17 @@ from server.models import StructuredAgentOutput
|
|
| 22 |
|
| 23 |
@dataclass
|
| 24 |
class RewardBreakdown:
|
| 25 |
-
format_compliance: float
|
| 26 |
-
hypothesis_quality: float
|
| 27 |
-
localization: float
|
| 28 |
-
fix_quality: float
|
| 29 |
-
semantic_similarity: float
|
| 30 |
-
efficiency_potential: float
|
| 31 |
penalties: float
|
| 32 |
total: float
|
| 33 |
|
| 34 |
|
| 35 |
class DebugRewardCalculator:
|
| 36 |
-
"""
|
| 37 |
-
Reward weights (must sum to 1.0 excluding penalties):
|
| 38 |
-
format_compliance: 0.10 β fires every turn, drives early curve movement
|
| 39 |
-
hypothesis_quality: 0.20 β process-based, independent of fix success
|
| 40 |
-
localization: 0.15 β did agent find the right place?
|
| 41 |
-
fix_quality: 0.35 β execution-based, primary terminal signal (sparse)
|
| 42 |
-
semantic_similarity: 0.10 β how close to canonical fix?
|
| 43 |
-
efficiency_potential: 0.10 β potential-based shaping across turns
|
| 44 |
-
|
| 45 |
-
IMPORTANT NOTE ON SPARSITY vs DENSITY:
|
| 46 |
-
The fix_quality reward (0.35) is sparse β it only fires when tests pass.
|
| 47 |
-
The format, hypothesis, localization rewards are dense β they fire every turn.
|
| 48 |
-
This combination is intentional: dense rewards carry gradient signal while the
|
| 49 |
-
model is still learning to fix bugs; sparse rewards dominate once it gets good.
|
| 50 |
-
This directly implements Ibrahim et al.'s recommendation to combine reward
|
| 51 |
-
shaping with terminal rewards to solve the sparse reward problem.
|
| 52 |
-
"""
|
| 53 |
|
| 54 |
MAX_TURNS = 5
|
| 55 |
|
|
@@ -60,36 +29,14 @@ class DebugRewardCalculator:
|
|
| 60 |
test_results: dict,
|
| 61 |
turn_number: int,
|
| 62 |
) -> RewardBreakdown:
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
agent_output: parsed structured output from the agent
|
| 68 |
-
ground_truth: {
|
| 69 |
-
"bug_function": str, # name of function containing the bug
|
| 70 |
-
"bug_line": int, # line number of the bug
|
| 71 |
-
"bug_type": str, # category of bug
|
| 72 |
-
"canonical_fix_code": str, # the correct minimal fix
|
| 73 |
-
}
|
| 74 |
-
test_results: {
|
| 75 |
-
"passed": int,
|
| 76 |
-
"failed": int,
|
| 77 |
-
"total": int,
|
| 78 |
-
"newly_broken": int, # tests that passed before but fail after fix
|
| 79 |
-
}
|
| 80 |
-
turn_number: 0-indexed turn number within the episode
|
| 81 |
-
|
| 82 |
-
Returns:
|
| 83 |
-
RewardBreakdown with total and all component scores
|
| 84 |
-
"""
|
| 85 |
-
|
| 86 |
-
# ββ COMPONENT 1: FORMAT COMPLIANCE ββββββββββββββββββββββββββββββββ
|
| 87 |
-
# This fires EVERY turn. Gives the model early training signal before
|
| 88 |
-
# it learns to fix bugs. Drives curve movement in first 50-100 steps.
|
| 89 |
if agent_output.valid:
|
| 90 |
format_score = 0.10
|
| 91 |
else:
|
| 92 |
-
|
| 93 |
fields_present = sum([
|
| 94 |
len(agent_output.observation) > 5,
|
| 95 |
len(agent_output.hypothesis) > 10,
|
|
@@ -98,48 +45,48 @@ class DebugRewardCalculator:
|
|
| 98 |
"request_context", "give_up"},
|
| 99 |
len(agent_output.detail) > 0,
|
| 100 |
])
|
| 101 |
-
format_score = -0.25 + (fields_present * 0.04)
|
| 102 |
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
hypothesis_score = 0.0
|
| 108 |
hypothesis = agent_output.hypothesis
|
| 109 |
|
| 110 |
if len(hypothesis.split()) >= 20:
|
| 111 |
-
hypothesis_score += 0.05
|
| 112 |
|
| 113 |
-
|
| 114 |
if re.search(r'[`\'"<>!=+\-*/]', hypothesis):
|
| 115 |
hypothesis_score += 0.05
|
| 116 |
|
| 117 |
-
|
| 118 |
if re.search(r'\bline\s+\d+\b|\b\d+\b', hypothesis):
|
| 119 |
hypothesis_score += 0.05
|
| 120 |
|
| 121 |
-
|
| 122 |
obs_words = set(agent_output.observation.lower().split())
|
| 123 |
hyp_words = set(hypothesis.lower().split())
|
| 124 |
overlap = len(obs_words & hyp_words) / max(len(obs_words), 1)
|
| 125 |
if overlap > 0.15:
|
| 126 |
hypothesis_score += 0.05
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
| 130 |
if agent_output.action == "propose_fix":
|
| 131 |
tests_pass = test_results.get("passed", 0) == test_results.get("total", 1)
|
| 132 |
if agent_output.confidence == "high" and tests_pass:
|
| 133 |
-
hypothesis_score += 0.05
|
| 134 |
elif agent_output.confidence == "high" and not tests_pass:
|
| 135 |
-
hypothesis_score -= 0.05
|
| 136 |
elif agent_output.confidence == "low" and tests_pass:
|
| 137 |
-
hypothesis_score += 0.02
|
| 138 |
|
| 139 |
hypothesis_score = max(0.0, min(hypothesis_score, 0.20))
|
| 140 |
|
| 141 |
-
|
| 142 |
-
|
| 143 |
localization_score = 0.0
|
| 144 |
bug_function = ground_truth.get("bug_function", "").lower()
|
| 145 |
bug_line = str(ground_truth.get("bug_line", -1))
|
|
@@ -154,9 +101,9 @@ class DebugRewardCalculator:
|
|
| 154 |
|
| 155 |
localization_score = min(localization_score, 0.15)
|
| 156 |
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
total_tests = test_results.get("total", 0)
|
| 161 |
passed_tests = test_results.get("passed", 0)
|
| 162 |
fix_score = 0.0
|
|
@@ -164,18 +111,18 @@ class DebugRewardCalculator:
|
|
| 164 |
if total_tests > 0 and agent_output.action == "propose_fix":
|
| 165 |
pass_rate = passed_tests / total_tests
|
| 166 |
if pass_rate == 1.0:
|
| 167 |
-
fix_score = 0.35
|
| 168 |
elif pass_rate >= 0.75:
|
| 169 |
-
fix_score = 0.20
|
| 170 |
elif pass_rate >= 0.50:
|
| 171 |
-
fix_score = 0.12
|
| 172 |
elif pass_rate > 0.0:
|
| 173 |
-
fix_score = 0.05
|
| 174 |
-
|
| 175 |
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
semantic_score = 0.0
|
| 180 |
proposed = agent_output.detail
|
| 181 |
canonical = ground_truth.get("canonical_fix_code", "")
|
|
@@ -188,36 +135,36 @@ class DebugRewardCalculator:
|
|
| 188 |
semantic_score = 0.05
|
| 189 |
elif similarity >= 0.40:
|
| 190 |
semantic_score = 0.02
|
| 191 |
-
|
| 192 |
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
remaining_turns = self.MAX_TURNS - turn_number
|
| 199 |
-
efficiency_potential = 0.02 * remaining_turns
|
| 200 |
|
| 201 |
-
|
| 202 |
penalties = 0.0
|
| 203 |
|
| 204 |
-
|
| 205 |
if test_results.get("newly_broken", 0) > 0:
|
| 206 |
penalties -= 0.20
|
| 207 |
|
| 208 |
-
|
| 209 |
if agent_output.action == "give_up":
|
| 210 |
penalties -= 0.15
|
| 211 |
|
| 212 |
-
|
| 213 |
if agent_output.action == "invalid":
|
| 214 |
penalties -= 0.10
|
| 215 |
|
| 216 |
-
|
| 217 |
if not agent_output.valid:
|
| 218 |
penalties -= 0.10
|
| 219 |
|
| 220 |
-
|
| 221 |
raw_total = (
|
| 222 |
format_score
|
| 223 |
+ hypothesis_score
|
|
@@ -228,7 +175,7 @@ class DebugRewardCalculator:
|
|
| 228 |
+ penalties
|
| 229 |
)
|
| 230 |
|
| 231 |
-
|
| 232 |
total = max(raw_total, -0.5)
|
| 233 |
|
| 234 |
return RewardBreakdown(
|
|
@@ -243,11 +190,6 @@ class DebugRewardCalculator:
|
|
| 243 |
)
|
| 244 |
|
| 245 |
def compute_episode_reward(self, trajectory: list[dict]) -> float:
|
| 246 |
-
"""
|
| 247 |
-
Aggregate turn rewards across an episode.
|
| 248 |
-
Uses 0.9 discount factor β later turns worth slightly less.
|
| 249 |
-
Adds solve bonus if bug was fixed before max turns.
|
| 250 |
-
"""
|
| 251 |
if not trajectory:
|
| 252 |
return 0.0
|
| 253 |
|
|
@@ -258,7 +200,7 @@ class DebugRewardCalculator:
|
|
| 258 |
total += discount * turn["reward"].total
|
| 259 |
discount *= 0.9
|
| 260 |
|
| 261 |
-
|
| 262 |
solved = any(t["reward"].fix_quality >= 0.35 for t in trajectory)
|
| 263 |
if solved:
|
| 264 |
total += 0.20
|
|
@@ -266,7 +208,6 @@ class DebugRewardCalculator:
|
|
| 266 |
return round(total, 4)
|
| 267 |
|
| 268 |
def get_reward_breakdown_for_logging(self, trajectory: list[dict]) -> dict:
|
| 269 |
-
"""Returns per-component averages across episode for W&B logging."""
|
| 270 |
if not trajectory:
|
| 271 |
return {}
|
| 272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import difflib
|
| 3 |
import re
|
|
|
|
| 8 |
|
| 9 |
@dataclass
|
| 10 |
class RewardBreakdown:
|
| 11 |
+
format_compliance: float
|
| 12 |
+
hypothesis_quality: float
|
| 13 |
+
localization: float
|
| 14 |
+
fix_quality: float
|
| 15 |
+
semantic_similarity: float
|
| 16 |
+
efficiency_potential: float
|
| 17 |
penalties: float
|
| 18 |
total: float
|
| 19 |
|
| 20 |
|
| 21 |
class DebugRewardCalculator:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
MAX_TURNS = 5
|
| 24 |
|
|
|
|
| 29 |
test_results: dict,
|
| 30 |
turn_number: int,
|
| 31 |
) -> RewardBreakdown:
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
if agent_output.valid:
|
| 37 |
format_score = 0.10
|
| 38 |
else:
|
| 39 |
+
|
| 40 |
fields_present = sum([
|
| 41 |
len(agent_output.observation) > 5,
|
| 42 |
len(agent_output.hypothesis) > 10,
|
|
|
|
| 45 |
"request_context", "give_up"},
|
| 46 |
len(agent_output.detail) > 0,
|
| 47 |
])
|
| 48 |
+
format_score = -0.25 + (fields_present * 0.04)
|
| 49 |
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
hypothesis_score = 0.0
|
| 55 |
hypothesis = agent_output.hypothesis
|
| 56 |
|
| 57 |
if len(hypothesis.split()) >= 20:
|
| 58 |
+
hypothesis_score += 0.05
|
| 59 |
|
| 60 |
+
|
| 61 |
if re.search(r'[`\'"<>!=+\-*/]', hypothesis):
|
| 62 |
hypothesis_score += 0.05
|
| 63 |
|
| 64 |
+
|
| 65 |
if re.search(r'\bline\s+\d+\b|\b\d+\b', hypothesis):
|
| 66 |
hypothesis_score += 0.05
|
| 67 |
|
| 68 |
+
|
| 69 |
obs_words = set(agent_output.observation.lower().split())
|
| 70 |
hyp_words = set(hypothesis.lower().split())
|
| 71 |
overlap = len(obs_words & hyp_words) / max(len(obs_words), 1)
|
| 72 |
if overlap > 0.15:
|
| 73 |
hypothesis_score += 0.05
|
| 74 |
|
| 75 |
+
|
| 76 |
+
|
| 77 |
if agent_output.action == "propose_fix":
|
| 78 |
tests_pass = test_results.get("passed", 0) == test_results.get("total", 1)
|
| 79 |
if agent_output.confidence == "high" and tests_pass:
|
| 80 |
+
hypothesis_score += 0.05
|
| 81 |
elif agent_output.confidence == "high" and not tests_pass:
|
| 82 |
+
hypothesis_score -= 0.05
|
| 83 |
elif agent_output.confidence == "low" and tests_pass:
|
| 84 |
+
hypothesis_score += 0.02
|
| 85 |
|
| 86 |
hypothesis_score = max(0.0, min(hypothesis_score, 0.20))
|
| 87 |
|
| 88 |
+
|
| 89 |
+
|
| 90 |
localization_score = 0.0
|
| 91 |
bug_function = ground_truth.get("bug_function", "").lower()
|
| 92 |
bug_line = str(ground_truth.get("bug_line", -1))
|
|
|
|
| 101 |
|
| 102 |
localization_score = min(localization_score, 0.15)
|
| 103 |
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
|
| 107 |
total_tests = test_results.get("total", 0)
|
| 108 |
passed_tests = test_results.get("passed", 0)
|
| 109 |
fix_score = 0.0
|
|
|
|
| 111 |
if total_tests > 0 and agent_output.action == "propose_fix":
|
| 112 |
pass_rate = passed_tests / total_tests
|
| 113 |
if pass_rate == 1.0:
|
| 114 |
+
fix_score = 0.35
|
| 115 |
elif pass_rate >= 0.75:
|
| 116 |
+
fix_score = 0.20
|
| 117 |
elif pass_rate >= 0.50:
|
| 118 |
+
fix_score = 0.12
|
| 119 |
elif pass_rate > 0.0:
|
| 120 |
+
fix_score = 0.05
|
| 121 |
+
|
| 122 |
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
|
| 126 |
semantic_score = 0.0
|
| 127 |
proposed = agent_output.detail
|
| 128 |
canonical = ground_truth.get("canonical_fix_code", "")
|
|
|
|
| 135 |
semantic_score = 0.05
|
| 136 |
elif similarity >= 0.40:
|
| 137 |
semantic_score = 0.02
|
| 138 |
+
|
| 139 |
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
|
| 145 |
remaining_turns = self.MAX_TURNS - turn_number
|
| 146 |
+
efficiency_potential = 0.02 * remaining_turns
|
| 147 |
|
| 148 |
+
|
| 149 |
penalties = 0.0
|
| 150 |
|
| 151 |
+
|
| 152 |
if test_results.get("newly_broken", 0) > 0:
|
| 153 |
penalties -= 0.20
|
| 154 |
|
| 155 |
+
|
| 156 |
if agent_output.action == "give_up":
|
| 157 |
penalties -= 0.15
|
| 158 |
|
| 159 |
+
|
| 160 |
if agent_output.action == "invalid":
|
| 161 |
penalties -= 0.10
|
| 162 |
|
| 163 |
+
|
| 164 |
if not agent_output.valid:
|
| 165 |
penalties -= 0.10
|
| 166 |
|
| 167 |
+
|
| 168 |
raw_total = (
|
| 169 |
format_score
|
| 170 |
+ hypothesis_score
|
|
|
|
| 175 |
+ penalties
|
| 176 |
)
|
| 177 |
|
| 178 |
+
|
| 179 |
total = max(raw_total, -0.5)
|
| 180 |
|
| 181 |
return RewardBreakdown(
|
|
|
|
| 190 |
)
|
| 191 |
|
| 192 |
def compute_episode_reward(self, trajectory: list[dict]) -> float:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
if not trajectory:
|
| 194 |
return 0.0
|
| 195 |
|
|
|
|
| 200 |
total += discount * turn["reward"].total
|
| 201 |
discount *= 0.9
|
| 202 |
|
| 203 |
+
|
| 204 |
solved = any(t["reward"].fix_quality >= 0.35 for t in trajectory)
|
| 205 |
if solved:
|
| 206 |
total += 0.20
|
|
|
|
| 208 |
return round(total, 4)
|
| 209 |
|
| 210 |
def get_reward_breakdown_for_logging(self, trajectory: list[dict]) -> dict:
|
|
|
|
| 211 |
if not trajectory:
|
| 212 |
return {}
|
| 213 |
|
tests/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
|
|
|
|
| 1 |
+
|
tests/test_environment.py
CHANGED
|
@@ -1,6 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Tests for the core environment β reset, step, state.
|
| 3 |
-
"""
|
| 4 |
|
| 5 |
import pytest
|
| 6 |
from env.environment import DebuggerEnvironment
|
|
@@ -12,7 +9,7 @@ def env():
|
|
| 12 |
return DebuggerEnvironment()
|
| 13 |
|
| 14 |
|
| 15 |
-
|
| 16 |
|
| 17 |
def test_reset_easy_returns_observation(env):
|
| 18 |
obs = env.reset("easy")
|
|
@@ -49,7 +46,7 @@ def test_reset_invalid_task_raises(env):
|
|
| 49 |
|
| 50 |
def test_reset_clears_previous_state(env):
|
| 51 |
env.reset("easy")
|
| 52 |
-
|
| 53 |
action = Action(
|
| 54 |
action_type="submit_fix",
|
| 55 |
fixed_code="def binary_search(arr, target): return -1",
|
|
@@ -57,14 +54,14 @@ def test_reset_clears_previous_state(env):
|
|
| 57 |
)
|
| 58 |
env.step(action)
|
| 59 |
|
| 60 |
-
|
| 61 |
obs = env.reset("easy")
|
| 62 |
assert obs["step_number"] == 0
|
| 63 |
assert obs["previous_attempts"] == []
|
| 64 |
assert obs["attempts_remaining"] == 5
|
| 65 |
|
| 66 |
|
| 67 |
-
|
| 68 |
|
| 69 |
def test_step_submit_fix_without_hypothesis(env):
|
| 70 |
env.reset("easy")
|
|
@@ -133,8 +130,8 @@ def test_step_query_context_second_costs(env):
|
|
| 133 |
action_type="query_context",
|
| 134 |
query_type="error_explanation",
|
| 135 |
)
|
| 136 |
-
env.step(action)
|
| 137 |
-
result = env.step(action)
|
| 138 |
assert result["reward"]["step_reward"] == -0.05
|
| 139 |
|
| 140 |
|
|
@@ -173,7 +170,7 @@ def test_step_invalid_query_type(env):
|
|
| 173 |
assert result["info"]["error"] is not None
|
| 174 |
|
| 175 |
|
| 176 |
-
|
| 177 |
|
| 178 |
def test_state_before_reset(env):
|
| 179 |
state = env.state()
|
|
@@ -203,7 +200,7 @@ def test_state_after_step(env):
|
|
| 203 |
assert len(state["all_hypotheses"]) == 1
|
| 204 |
|
| 205 |
|
| 206 |
-
|
| 207 |
|
| 208 |
def test_attempts_exhausted(env):
|
| 209 |
env.reset("easy")
|
|
@@ -215,10 +212,10 @@ def test_attempts_exhausted(env):
|
|
| 215 |
)
|
| 216 |
result = env.step(action)
|
| 217 |
|
| 218 |
-
|
| 219 |
assert result["done"] is True or result["observation"]["attempts_remaining"] == 0
|
| 220 |
|
| 221 |
-
|
| 222 |
if not result["done"]:
|
| 223 |
action = Action(
|
| 224 |
action_type="submit_fix",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import pytest
|
| 3 |
from env.environment import DebuggerEnvironment
|
|
|
|
| 9 |
return DebuggerEnvironment()
|
| 10 |
|
| 11 |
|
| 12 |
+
|
| 13 |
|
| 14 |
def test_reset_easy_returns_observation(env):
|
| 15 |
obs = env.reset("easy")
|
|
|
|
| 46 |
|
| 47 |
def test_reset_clears_previous_state(env):
|
| 48 |
env.reset("easy")
|
| 49 |
+
|
| 50 |
action = Action(
|
| 51 |
action_type="submit_fix",
|
| 52 |
fixed_code="def binary_search(arr, target): return -1",
|
|
|
|
| 54 |
)
|
| 55 |
env.step(action)
|
| 56 |
|
| 57 |
+
|
| 58 |
obs = env.reset("easy")
|
| 59 |
assert obs["step_number"] == 0
|
| 60 |
assert obs["previous_attempts"] == []
|
| 61 |
assert obs["attempts_remaining"] == 5
|
| 62 |
|
| 63 |
|
| 64 |
+
|
| 65 |
|
| 66 |
def test_step_submit_fix_without_hypothesis(env):
|
| 67 |
env.reset("easy")
|
|
|
|
| 130 |
action_type="query_context",
|
| 131 |
query_type="error_explanation",
|
| 132 |
)
|
| 133 |
+
env.step(action)
|
| 134 |
+
result = env.step(action)
|
| 135 |
assert result["reward"]["step_reward"] == -0.05
|
| 136 |
|
| 137 |
|
|
|
|
| 170 |
assert result["info"]["error"] is not None
|
| 171 |
|
| 172 |
|
| 173 |
+
|
| 174 |
|
| 175 |
def test_state_before_reset(env):
|
| 176 |
state = env.state()
|
|
|
|
| 200 |
assert len(state["all_hypotheses"]) == 1
|
| 201 |
|
| 202 |
|
| 203 |
+
|
| 204 |
|
| 205 |
def test_attempts_exhausted(env):
|
| 206 |
env.reset("easy")
|
|
|
|
| 212 |
)
|
| 213 |
result = env.step(action)
|
| 214 |
|
| 215 |
+
|
| 216 |
assert result["done"] is True or result["observation"]["attempts_remaining"] == 0
|
| 217 |
|
| 218 |
+
|
| 219 |
if not result["done"]:
|
| 220 |
action = Action(
|
| 221 |
action_type="submit_fix",
|
tests/test_graders.py
CHANGED
|
@@ -1,16 +1,12 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Tests for graders β determinism and range validation.
|
| 3 |
-
"""
|
| 4 |
|
| 5 |
import pytest
|
| 6 |
from env.graders import get_grader
|
| 7 |
from env.tasks.registry import get_task
|
| 8 |
|
| 9 |
|
| 10 |
-
|
| 11 |
|
| 12 |
def _make_dummy_attempts(n=2, tests_passed=3, tests_total=8):
|
| 13 |
-
"""Create dummy attempt data for testing."""
|
| 14 |
return [
|
| 15 |
{
|
| 16 |
"attempt_number": i + 1,
|
|
@@ -27,7 +23,6 @@ def _make_dummy_attempts(n=2, tests_passed=3, tests_total=8):
|
|
| 27 |
|
| 28 |
|
| 29 |
def test_easy_grader_deterministic():
|
| 30 |
-
"""Same input to easy grader must produce same output."""
|
| 31 |
grader = get_grader("easy")
|
| 32 |
task = get_task("easy")
|
| 33 |
attempts = _make_dummy_attempts(2, tests_passed=7, tests_total=8)
|
|
@@ -39,7 +34,6 @@ def test_easy_grader_deterministic():
|
|
| 39 |
|
| 40 |
|
| 41 |
def test_medium_grader_deterministic():
|
| 42 |
-
"""Same input to medium grader must produce same output."""
|
| 43 |
grader = get_grader("medium")
|
| 44 |
task = get_task("medium")
|
| 45 |
attempts = _make_dummy_attempts(3, tests_passed=6, tests_total=10)
|
|
@@ -51,10 +45,9 @@ def test_medium_grader_deterministic():
|
|
| 51 |
|
| 52 |
|
| 53 |
def test_hard_grader_deterministic():
|
| 54 |
-
"""Same input to hard grader must produce same output (excluding concurrent test randomness)."""
|
| 55 |
grader = get_grader("hard")
|
| 56 |
task = get_task("hard")
|
| 57 |
-
|
| 58 |
attempts = _make_dummy_attempts(2, tests_passed=8, tests_total=8)
|
| 59 |
hypotheses = ["race condition in increment"]
|
| 60 |
|
|
@@ -63,11 +56,10 @@ def test_hard_grader_deterministic():
|
|
| 63 |
assert score1 == score2, f"Hard grader not deterministic: {score1} != {score2}"
|
| 64 |
|
| 65 |
|
| 66 |
-
|
| 67 |
|
| 68 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 69 |
def test_grader_range_with_zero_attempts(task_id):
|
| 70 |
-
"""Grader with zero attempts should return a score in [0.0, 1.0]."""
|
| 71 |
grader = get_grader(task_id)
|
| 72 |
task = get_task(task_id)
|
| 73 |
score = grader.score(task, [], 0, task["tests_total"], 0, task["max_attempts"], [])
|
|
@@ -76,7 +68,6 @@ def test_grader_range_with_zero_attempts(task_id):
|
|
| 76 |
|
| 77 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 78 |
def test_grader_range_with_perfect_score(task_id):
|
| 79 |
-
"""Grader with all tests passing should return a score in [0.0, 1.0]."""
|
| 80 |
grader = get_grader(task_id)
|
| 81 |
task = get_task(task_id)
|
| 82 |
tests_total = task["tests_total"]
|
|
@@ -89,7 +80,6 @@ def test_grader_range_with_perfect_score(task_id):
|
|
| 89 |
|
| 90 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 91 |
def test_grader_range_with_all_failures(task_id):
|
| 92 |
-
"""Grader with no tests passing should return a score in [0.0, 1.0]."""
|
| 93 |
grader = get_grader(task_id)
|
| 94 |
task = get_task(task_id)
|
| 95 |
tests_total = task["tests_total"]
|
|
@@ -99,10 +89,9 @@ def test_grader_range_with_all_failures(task_id):
|
|
| 99 |
assert 0.0 <= score <= 1.0, f"{task_id} grader out of range: {score}"
|
| 100 |
|
| 101 |
|
| 102 |
-
|
| 103 |
|
| 104 |
def test_easy_dummy_agent_low_score():
|
| 105 |
-
"""A dummy agent submitting 'pass' should score < 0.15."""
|
| 106 |
grader = get_grader("easy")
|
| 107 |
task = get_task("easy")
|
| 108 |
attempts = [
|
|
@@ -123,7 +112,6 @@ def test_easy_dummy_agent_low_score():
|
|
| 123 |
|
| 124 |
|
| 125 |
def test_easy_perfect_agent_high_score():
|
| 126 |
-
"""A perfect agent should score > 0.85 on easy."""
|
| 127 |
grader = get_grader("easy")
|
| 128 |
task = get_task("easy")
|
| 129 |
attempts = [
|
|
@@ -143,7 +131,6 @@ def test_easy_perfect_agent_high_score():
|
|
| 143 |
|
| 144 |
|
| 145 |
def test_medium_red_herring_low_score():
|
| 146 |
-
"""Agent that only fixes authenticate_user should score < 0.30 on hypothesis."""
|
| 147 |
grader = get_grader("medium")
|
| 148 |
task = get_task("medium")
|
| 149 |
attempts = _make_dummy_attempts(3, tests_passed=6, tests_total=10)
|
|
@@ -153,5 +140,5 @@ def test_medium_red_herring_low_score():
|
|
| 153 |
"Fix authenticate_user to return True for valid users",
|
| 154 |
]
|
| 155 |
score = grader.score(task, attempts, 6, 10, 3, 7, hypotheses)
|
| 156 |
-
|
| 157 |
assert score < 0.60, f"Red herring agent scored too high on medium: {score}"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import pytest
|
| 3 |
from env.graders import get_grader
|
| 4 |
from env.tasks.registry import get_task
|
| 5 |
|
| 6 |
|
| 7 |
+
|
| 8 |
|
| 9 |
def _make_dummy_attempts(n=2, tests_passed=3, tests_total=8):
|
|
|
|
| 10 |
return [
|
| 11 |
{
|
| 12 |
"attempt_number": i + 1,
|
|
|
|
| 23 |
|
| 24 |
|
| 25 |
def test_easy_grader_deterministic():
|
|
|
|
| 26 |
grader = get_grader("easy")
|
| 27 |
task = get_task("easy")
|
| 28 |
attempts = _make_dummy_attempts(2, tests_passed=7, tests_total=8)
|
|
|
|
| 34 |
|
| 35 |
|
| 36 |
def test_medium_grader_deterministic():
|
|
|
|
| 37 |
grader = get_grader("medium")
|
| 38 |
task = get_task("medium")
|
| 39 |
attempts = _make_dummy_attempts(3, tests_passed=6, tests_total=10)
|
|
|
|
| 45 |
|
| 46 |
|
| 47 |
def test_hard_grader_deterministic():
|
|
|
|
| 48 |
grader = get_grader("hard")
|
| 49 |
task = get_task("hard")
|
| 50 |
+
|
| 51 |
attempts = _make_dummy_attempts(2, tests_passed=8, tests_total=8)
|
| 52 |
hypotheses = ["race condition in increment"]
|
| 53 |
|
|
|
|
| 56 |
assert score1 == score2, f"Hard grader not deterministic: {score1} != {score2}"
|
| 57 |
|
| 58 |
|
| 59 |
+
|
| 60 |
|
| 61 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 62 |
def test_grader_range_with_zero_attempts(task_id):
|
|
|
|
| 63 |
grader = get_grader(task_id)
|
| 64 |
task = get_task(task_id)
|
| 65 |
score = grader.score(task, [], 0, task["tests_total"], 0, task["max_attempts"], [])
|
|
|
|
| 68 |
|
| 69 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 70 |
def test_grader_range_with_perfect_score(task_id):
|
|
|
|
| 71 |
grader = get_grader(task_id)
|
| 72 |
task = get_task(task_id)
|
| 73 |
tests_total = task["tests_total"]
|
|
|
|
| 80 |
|
| 81 |
@pytest.mark.parametrize("task_id", ["easy", "medium", "hard"])
|
| 82 |
def test_grader_range_with_all_failures(task_id):
|
|
|
|
| 83 |
grader = get_grader(task_id)
|
| 84 |
task = get_task(task_id)
|
| 85 |
tests_total = task["tests_total"]
|
|
|
|
| 89 |
assert 0.0 <= score <= 1.0, f"{task_id} grader out of range: {score}"
|
| 90 |
|
| 91 |
|
| 92 |
+
|
| 93 |
|
| 94 |
def test_easy_dummy_agent_low_score():
|
|
|
|
| 95 |
grader = get_grader("easy")
|
| 96 |
task = get_task("easy")
|
| 97 |
attempts = [
|
|
|
|
| 112 |
|
| 113 |
|
| 114 |
def test_easy_perfect_agent_high_score():
|
|
|
|
| 115 |
grader = get_grader("easy")
|
| 116 |
task = get_task("easy")
|
| 117 |
attempts = [
|
|
|
|
| 131 |
|
| 132 |
|
| 133 |
def test_medium_red_herring_low_score():
|
|
|
|
| 134 |
grader = get_grader("medium")
|
| 135 |
task = get_task("medium")
|
| 136 |
attempts = _make_dummy_attempts(3, tests_passed=6, tests_total=10)
|
|
|
|
| 140 |
"Fix authenticate_user to return True for valid users",
|
| 141 |
]
|
| 142 |
score = grader.score(task, attempts, 6, 10, 3, 7, hypotheses)
|
| 143 |
+
|
| 144 |
assert score < 0.60, f"Red herring agent scored too high on medium: {score}"
|
tests/test_integration.py
CHANGED
|
@@ -1,27 +1,19 @@
|
|
| 1 |
-
"""
|
| 2 |
-
AgentDebuggerEnv β Integration Tests
|
| 3 |
-
====================================
|
| 4 |
-
Verifies the full episode lifecycle: reset -> step -> end.
|
| 5 |
-
Assumes the server is available via the DebuggerEnvironment class directly
|
| 6 |
-
(testing the logic, not the HTTP layer which is just a thin wrapper).
|
| 7 |
-
"""
|
| 8 |
|
| 9 |
import pytest
|
| 10 |
from env.environment import DebuggerEnvironment
|
| 11 |
from env.models import Action
|
| 12 |
|
| 13 |
def test_full_episode_easy():
|
| 14 |
-
"""Test a full successful episode on the 'easy' task."""
|
| 15 |
env = DebuggerEnvironment()
|
| 16 |
|
| 17 |
-
|
| 18 |
obs = env.reset("easy")
|
| 19 |
assert obs["task_id"] == "easy"
|
| 20 |
assert obs["done"] is False
|
| 21 |
assert obs["tests_passed"] < obs["tests_total"]
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
ground_truth_code = """
|
| 26 |
def binary_search(arr, target):
|
| 27 |
left, right = 0, len(arr) - 1
|
|
@@ -43,13 +35,12 @@ def binary_search(arr, target):
|
|
| 43 |
|
| 44 |
result = env.step(action)
|
| 45 |
|
| 46 |
-
|
| 47 |
assert result["done"] is True
|
| 48 |
assert result["observation"]["tests_passed"] == result["observation"]["tests_total"]
|
| 49 |
assert result["reward"]["grader_score"] > 0.80
|
| 50 |
|
| 51 |
def test_query_hint_system():
|
| 52 |
-
"""Test the newly added hint system."""
|
| 53 |
env = DebuggerEnvironment()
|
| 54 |
env.reset("hard")
|
| 55 |
|
|
@@ -60,20 +51,16 @@ def test_query_hint_system():
|
|
| 60 |
|
| 61 |
result = env.step(action)
|
| 62 |
assert "concurrent threads" in result["info"]["query_result"]
|
| 63 |
-
assert result["reward"]["step_reward"] == 0.0
|
| 64 |
|
| 65 |
def test_hard_grader_consensus():
|
| 66 |
-
"""
|
| 67 |
-
Test that the hard grader runs multiple times.
|
| 68 |
-
(We mock execute_code to simulate flakiness).
|
| 69 |
-
"""
|
| 70 |
from unittest.mock import patch
|
| 71 |
from env.graders.grader_hard import HardGrader
|
| 72 |
|
| 73 |
grader = HardGrader()
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
with patch("env.graders.grader_hard.execute_code") as mock_exec:
|
| 78 |
mock_exec.side_effect = [
|
| 79 |
("CONCURRENT PASS", False, 100),
|
|
@@ -93,10 +80,10 @@ def test_hard_grader_consensus():
|
|
| 93 |
hypotheses=["race condition"]
|
| 94 |
)
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
assert score == 0.75
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import pytest
|
| 3 |
from env.environment import DebuggerEnvironment
|
| 4 |
from env.models import Action
|
| 5 |
|
| 6 |
def test_full_episode_easy():
|
|
|
|
| 7 |
env = DebuggerEnvironment()
|
| 8 |
|
| 9 |
+
|
| 10 |
obs = env.reset("easy")
|
| 11 |
assert obs["task_id"] == "easy"
|
| 12 |
assert obs["done"] is False
|
| 13 |
assert obs["tests_passed"] < obs["tests_total"]
|
| 14 |
|
| 15 |
+
|
| 16 |
+
|
| 17 |
ground_truth_code = """
|
| 18 |
def binary_search(arr, target):
|
| 19 |
left, right = 0, len(arr) - 1
|
|
|
|
| 35 |
|
| 36 |
result = env.step(action)
|
| 37 |
|
| 38 |
+
|
| 39 |
assert result["done"] is True
|
| 40 |
assert result["observation"]["tests_passed"] == result["observation"]["tests_total"]
|
| 41 |
assert result["reward"]["grader_score"] > 0.80
|
| 42 |
|
| 43 |
def test_query_hint_system():
|
|
|
|
| 44 |
env = DebuggerEnvironment()
|
| 45 |
env.reset("hard")
|
| 46 |
|
|
|
|
| 51 |
|
| 52 |
result = env.step(action)
|
| 53 |
assert "concurrent threads" in result["info"]["query_result"]
|
| 54 |
+
assert result["reward"]["step_reward"] == 0.0
|
| 55 |
|
| 56 |
def test_hard_grader_consensus():
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
from unittest.mock import patch
|
| 58 |
from env.graders.grader_hard import HardGrader
|
| 59 |
|
| 60 |
grader = HardGrader()
|
| 61 |
|
| 62 |
+
|
| 63 |
+
|
| 64 |
with patch("env.graders.grader_hard.execute_code") as mock_exec:
|
| 65 |
mock_exec.side_effect = [
|
| 66 |
("CONCURRENT PASS", False, 100),
|
|
|
|
| 80 |
hypotheses=["race condition"]
|
| 81 |
)
|
| 82 |
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
|
| 89 |
assert score == 0.75
|
tests/test_sandbox.py
CHANGED
|
@@ -1,14 +1,9 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Tests for the code execution sandbox.
|
| 3 |
-
All 5 tests are required by the hackathon spec.
|
| 4 |
-
"""
|
| 5 |
|
| 6 |
import pytest
|
| 7 |
from env.sandbox import execute_code
|
| 8 |
|
| 9 |
|
| 10 |
def test_timeout_enforcement():
|
| 11 |
-
"""Code with infinite loop must return timed_out=True within ~11 seconds."""
|
| 12 |
code = "while True: pass"
|
| 13 |
output, timed_out, elapsed_ms = execute_code(code, "")
|
| 14 |
assert timed_out is True
|
|
@@ -16,21 +11,18 @@ def test_timeout_enforcement():
|
|
| 16 |
|
| 17 |
|
| 18 |
def test_os_import_blocked():
|
| 19 |
-
"""os module must be blocked β cannot execute system commands."""
|
| 20 |
code = "import os; os.system('echo pwned')"
|
| 21 |
output, timed_out, _ = execute_code(code, "")
|
| 22 |
assert "BLOCKED" in output or "blocked" in output.lower()
|
| 23 |
|
| 24 |
|
| 25 |
def test_sys_import_blocked():
|
| 26 |
-
"""sys module must be blocked."""
|
| 27 |
code = "import sys; sys.exit(0)"
|
| 28 |
output, _, _ = execute_code(code, "")
|
| 29 |
assert "blocked" in output.lower() or "import" in output.lower()
|
| 30 |
|
| 31 |
|
| 32 |
def test_clean_code_runs():
|
| 33 |
-
"""Clean, safe code with tests must execute correctly."""
|
| 34 |
code = "def add(a, b): return a + b"
|
| 35 |
test = "assert add(2, 3) == 5\nprint('PASSED')"
|
| 36 |
output, timed_out, _ = execute_code(code, test)
|
|
@@ -39,17 +31,15 @@ def test_clean_code_runs():
|
|
| 39 |
|
| 40 |
|
| 41 |
def test_syntax_error_returns_output():
|
| 42 |
-
"""Code with syntax errors should return the SyntaxError, not crash."""
|
| 43 |
code = "def broken(: pass"
|
| 44 |
output, timed_out, _ = execute_code(code, "")
|
| 45 |
assert "SyntaxError" in output
|
| 46 |
assert timed_out is False
|
| 47 |
|
| 48 |
|
| 49 |
-
|
| 50 |
|
| 51 |
def test_subprocess_import_blocked():
|
| 52 |
-
"""subprocess module must be blocked."""
|
| 53 |
code = "import subprocess; subprocess.run(['echo', 'pw' + 'ned'])"
|
| 54 |
output, _, _ = execute_code(code, "")
|
| 55 |
assert "pwned" not in output
|
|
@@ -57,7 +47,6 @@ def test_subprocess_import_blocked():
|
|
| 57 |
|
| 58 |
|
| 59 |
def test_threading_blocked_by_default():
|
| 60 |
-
"""threading must be blocked unless allow_threading=True."""
|
| 61 |
code = "import threading; print('thread ' + 'imported')"
|
| 62 |
output, _, _ = execute_code(code, "")
|
| 63 |
assert "thread imported" not in output
|
|
@@ -65,14 +54,12 @@ def test_threading_blocked_by_default():
|
|
| 65 |
|
| 66 |
|
| 67 |
def test_threading_allowed_when_flagged():
|
| 68 |
-
"""threading must be allowed when allow_threading=True."""
|
| 69 |
code = "import threading; print('thread imported')"
|
| 70 |
output, _, _ = execute_code(code, "", allow_threading=True)
|
| 71 |
assert "thread imported" in output
|
| 72 |
|
| 73 |
|
| 74 |
def test_from_import_blocked():
|
| 75 |
-
"""'from os import path' style imports must also be blocked."""
|
| 76 |
code = "from os import path; print('pw' + 'ned')"
|
| 77 |
output, _, _ = execute_code(code, "")
|
| 78 |
assert "pwned" not in output
|
|
@@ -80,14 +67,13 @@ def test_from_import_blocked():
|
|
| 80 |
|
| 81 |
|
| 82 |
def test_no_state_leak_between_executions():
|
| 83 |
-
"""Each execution must be completely isolated β no shared state."""
|
| 84 |
code1 = "shared_var = 42"
|
| 85 |
output1, _, _ = execute_code(code1, "print('set')")
|
| 86 |
assert "set" in output1
|
| 87 |
|
| 88 |
code2 = ""
|
| 89 |
test2 = "try:\\n print(shared_var)\\nexcept NameError:\\n print('ISOLATED')"
|
| 90 |
-
|
| 91 |
code2_test = "try:\n print(shared_var)\nexcept NameError:\n print('ISOLATED')"
|
| 92 |
output2, _, _ = execute_code("", code2_test)
|
| 93 |
assert "ISOLATED" in output2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import pytest
|
| 3 |
from env.sandbox import execute_code
|
| 4 |
|
| 5 |
|
| 6 |
def test_timeout_enforcement():
|
|
|
|
| 7 |
code = "while True: pass"
|
| 8 |
output, timed_out, elapsed_ms = execute_code(code, "")
|
| 9 |
assert timed_out is True
|
|
|
|
| 11 |
|
| 12 |
|
| 13 |
def test_os_import_blocked():
|
|
|
|
| 14 |
code = "import os; os.system('echo pwned')"
|
| 15 |
output, timed_out, _ = execute_code(code, "")
|
| 16 |
assert "BLOCKED" in output or "blocked" in output.lower()
|
| 17 |
|
| 18 |
|
| 19 |
def test_sys_import_blocked():
|
|
|
|
| 20 |
code = "import sys; sys.exit(0)"
|
| 21 |
output, _, _ = execute_code(code, "")
|
| 22 |
assert "blocked" in output.lower() or "import" in output.lower()
|
| 23 |
|
| 24 |
|
| 25 |
def test_clean_code_runs():
|
|
|
|
| 26 |
code = "def add(a, b): return a + b"
|
| 27 |
test = "assert add(2, 3) == 5\nprint('PASSED')"
|
| 28 |
output, timed_out, _ = execute_code(code, test)
|
|
|
|
| 31 |
|
| 32 |
|
| 33 |
def test_syntax_error_returns_output():
|
|
|
|
| 34 |
code = "def broken(: pass"
|
| 35 |
output, timed_out, _ = execute_code(code, "")
|
| 36 |
assert "SyntaxError" in output
|
| 37 |
assert timed_out is False
|
| 38 |
|
| 39 |
|
| 40 |
+
|
| 41 |
|
| 42 |
def test_subprocess_import_blocked():
|
|
|
|
| 43 |
code = "import subprocess; subprocess.run(['echo', 'pw' + 'ned'])"
|
| 44 |
output, _, _ = execute_code(code, "")
|
| 45 |
assert "pwned" not in output
|
|
|
|
| 47 |
|
| 48 |
|
| 49 |
def test_threading_blocked_by_default():
|
|
|
|
| 50 |
code = "import threading; print('thread ' + 'imported')"
|
| 51 |
output, _, _ = execute_code(code, "")
|
| 52 |
assert "thread imported" not in output
|
|
|
|
| 54 |
|
| 55 |
|
| 56 |
def test_threading_allowed_when_flagged():
|
|
|
|
| 57 |
code = "import threading; print('thread imported')"
|
| 58 |
output, _, _ = execute_code(code, "", allow_threading=True)
|
| 59 |
assert "thread imported" in output
|
| 60 |
|
| 61 |
|
| 62 |
def test_from_import_blocked():
|
|
|
|
| 63 |
code = "from os import path; print('pw' + 'ned')"
|
| 64 |
output, _, _ = execute_code(code, "")
|
| 65 |
assert "pwned" not in output
|
|
|
|
| 67 |
|
| 68 |
|
| 69 |
def test_no_state_leak_between_executions():
|
|
|
|
| 70 |
code1 = "shared_var = 42"
|
| 71 |
output1, _, _ = execute_code(code1, "print('set')")
|
| 72 |
assert "set" in output1
|
| 73 |
|
| 74 |
code2 = ""
|
| 75 |
test2 = "try:\\n print(shared_var)\\nexcept NameError:\\n print('ISOLATED')"
|
| 76 |
+
|
| 77 |
code2_test = "try:\n print(shared_var)\nexcept NameError:\n print('ISOLATED')"
|
| 78 |
output2, _, _ = execute_code("", code2_test)
|
| 79 |
assert "ISOLATED" in output2
|
training/train_grpo.py
CHANGED
|
@@ -1,22 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
AgentDebuggerEnv β GRPO Training Script
|
| 3 |
-
Model: Qwen2.5-Coder-7B-Instruct (float16/bfloat16 + LoRA, no quantization)
|
| 4 |
-
Algorithm: GRPO (Group Relative Policy Optimization) via HuggingFace TRL
|
| 5 |
-
GPU: auto-detected at runtime (A100/H100 β bfloat16+large batch, T4/V100 β float16+small batch)
|
| 6 |
-
|
| 7 |
-
Usage:
|
| 8 |
-
# Local reward sanity-check (no GPU, no model loading):
|
| 9 |
-
python training/train_grpo.py --test-local
|
| 10 |
-
|
| 11 |
-
# Test run (Colab/GPU, 10 steps):
|
| 12 |
-
python training/train_grpo.py --test
|
| 13 |
-
|
| 14 |
-
# Full training run:
|
| 15 |
-
python training/train_grpo.py
|
| 16 |
-
|
| 17 |
-
# Resume from checkpoint:
|
| 18 |
-
python training/train_grpo.py --resume ./checkpoints/checkpoint-400
|
| 19 |
-
"""
|
| 20 |
|
| 21 |
import os
|
| 22 |
import sys
|
|
@@ -28,7 +9,7 @@ import tempfile
|
|
| 28 |
import shutil
|
| 29 |
from importlib import metadata
|
| 30 |
|
| 31 |
-
|
| 32 |
parser = argparse.ArgumentParser()
|
| 33 |
parser.add_argument("--test", action="store_true", help="Run 10 steps for testing (Colab/GPU)")
|
| 34 |
parser.add_argument("--test-local", action="store_true", dest="test_local",
|
|
@@ -40,15 +21,15 @@ parser.add_argument("--max_steps", type=int, default=500)
|
|
| 40 |
args = parser.parse_args()
|
| 41 |
|
| 42 |
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
if not args.test_local:
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
import importlib.util, importlib
|
| 53 |
_needs_cuda_torch = True
|
| 54 |
if importlib.util.find_spec("torch") is not None:
|
|
@@ -84,7 +65,7 @@ if not args.test_local:
|
|
| 84 |
sys.exit(1)
|
| 85 |
print("Dependencies installed.", flush=True)
|
| 86 |
|
| 87 |
-
|
| 88 |
if not args.test_local:
|
| 89 |
import torch
|
| 90 |
import wandb
|
|
@@ -115,13 +96,13 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
| 115 |
from server.reward_calculator import DebugRewardCalculator
|
| 116 |
from server.models import parse_agent_output
|
| 117 |
|
| 118 |
-
|
| 119 |
MODEL_NAME = "Qwen/Qwen2.5-Coder-3B-Instruct"
|
| 120 |
HF_REPO = "shashaank0707/AgentDebugger-trained"
|
| 121 |
MAX_STEPS = (10 if args.test else args.max_steps) - args.step_offset
|
| 122 |
CHECKPOINT_DIR = "./checkpoints"
|
| 123 |
|
| 124 |
-
|
| 125 |
WANDB_API_KEY = os.environ.get("WANDB_API_KEY", "") if not args.test_local else ""
|
| 126 |
HF_TOKEN = os.environ.get("HF_TOKEN")
|
| 127 |
|
|
@@ -139,7 +120,7 @@ if WANDB_API_KEY:
|
|
| 139 |
}
|
| 140 |
)
|
| 141 |
|
| 142 |
-
|
| 143 |
SYSTEM_PROMPT = """You are an expert Python debugger. You reason through bugs systematically.
|
| 144 |
|
| 145 |
You MUST respond in EXACTLY this format β no exceptions, no extra text:
|
|
@@ -156,7 +137,7 @@ Rules:
|
|
| 156 |
- If proposing a fix, DETAIL must contain the complete function, not just the changed line
|
| 157 |
- Give up only if you have exhausted all reasonable hypotheses"""
|
| 158 |
|
| 159 |
-
|
| 160 |
def load_bugs(tier: int) -> list[dict]:
|
| 161 |
path = f"data/bugs_tier{tier}.jsonl"
|
| 162 |
if not os.path.exists(path):
|
|
@@ -184,7 +165,6 @@ def bug_to_prompt(bug: dict) -> str:
|
|
| 184 |
)
|
| 185 |
|
| 186 |
def _run_fix(proposed_code: str, bug: dict) -> dict:
|
| 187 |
-
"""Safely run proposed fix with subprocess timeout."""
|
| 188 |
test_cases = bug.get("test_cases", [])
|
| 189 |
func_name = bug.get("function_name", "")
|
| 190 |
if not proposed_code or not test_cases or not func_name:
|
|
@@ -200,7 +180,7 @@ def _run_fix(proposed_code: str, bug: dict) -> dict:
|
|
| 200 |
f" r={func_name}({args_str})\n"
|
| 201 |
f" print('PASS' if r=={repr(test['expected_output'])} else 'FAIL')\n"
|
| 202 |
f"except Exception as e:\n"
|
| 203 |
-
f" print(f'ERROR: {
|
| 204 |
)
|
| 205 |
try:
|
| 206 |
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
@@ -216,7 +196,7 @@ def _run_fix(proposed_code: str, bug: dict) -> dict:
|
|
| 216 |
|
| 217 |
return {"passed": passed, "failed": len(test_cases) - passed, "total": len(test_cases), "newly_broken": 0}
|
| 218 |
|
| 219 |
-
|
| 220 |
MOCK_GOOD = """
|
| 221 |
OBSERVATION: The loop condition on line 4 uses <= instead of
|
| 222 |
HYPOTHESIS: This causes an off-by-one error because Python lists are
|
|
@@ -241,7 +221,7 @@ I think there might be a bug somewhere in the code.
|
|
| 241 |
Let me try fixing it.
|
| 242 |
"""
|
| 243 |
|
| 244 |
-
|
| 245 |
if args.test_local:
|
| 246 |
print("=" * 60)
|
| 247 |
print("LOCAL TEST MODE β no model loaded, testing reward function only")
|
|
@@ -295,9 +275,9 @@ if args.test_local:
|
|
| 295 |
print("\nLOCAL TEST PASSED")
|
| 296 |
sys.exit(0)
|
| 297 |
|
| 298 |
-
|
| 299 |
_gpu_vram_gb = 0
|
| 300 |
-
_is_ampere_plus = False
|
| 301 |
if torch.cuda.is_available():
|
| 302 |
_props = torch.cuda.get_device_properties(0)
|
| 303 |
_gpu_vram_gb = _props.total_memory / 1e9
|
|
@@ -308,30 +288,30 @@ if torch.cuda.is_available():
|
|
| 308 |
|
| 309 |
COMPUTE_DTYPE = torch.bfloat16 if _is_ampere_plus else torch.float16
|
| 310 |
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
if _gpu_vram_gb >= 70:
|
| 314 |
_batch = 8
|
| 315 |
-
_grad_accum = 1
|
| 316 |
-
_num_gen = 8
|
| 317 |
_max_comp = 256
|
| 318 |
_lora_r = 16
|
| 319 |
-
elif _gpu_vram_gb >= 40:
|
| 320 |
_batch = 4
|
| 321 |
-
_grad_accum = 2
|
| 322 |
-
_num_gen = 4
|
| 323 |
_max_comp = 256
|
| 324 |
_lora_r = 16
|
| 325 |
-
elif _gpu_vram_gb >= 20:
|
| 326 |
_batch = 2
|
| 327 |
_grad_accum = 4
|
| 328 |
-
_num_gen = 2
|
| 329 |
_max_comp = 192
|
| 330 |
_lora_r = 8
|
| 331 |
-
else:
|
| 332 |
_batch = 2
|
| 333 |
_grad_accum = 4
|
| 334 |
-
_num_gen = 2
|
| 335 |
_max_comp = 160
|
| 336 |
_lora_r = 8
|
| 337 |
|
|
@@ -339,9 +319,9 @@ print(f"Training config: batch={_batch} grad_accum={_grad_accum} "
|
|
| 339 |
f"num_gen={_num_gen} max_comp={_max_comp} lora_r={_lora_r} "
|
| 340 |
f"dtype={COMPUTE_DTYPE}")
|
| 341 |
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
print(f"Loading {MODEL_NAME} in {COMPUTE_DTYPE}...")
|
| 346 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
|
| 347 |
tokenizer.pad_token = tokenizer.eos_token
|
|
@@ -374,23 +354,20 @@ model.enable_input_require_grads()
|
|
| 374 |
model.gradient_checkpointing_enable()
|
| 375 |
print(f"Trainable params: {model.num_parameters(only_trainable=True):,}")
|
| 376 |
|
| 377 |
-
|
| 378 |
def _select_runtime_device(model) -> str:
|
| 379 |
-
"""
|
| 380 |
-
Pick the safest generation device without forcing CUDA init on broken drivers.
|
| 381 |
-
"""
|
| 382 |
def _cuda_usable() -> bool:
|
| 383 |
try:
|
| 384 |
if not torch.cuda.is_available():
|
| 385 |
return False
|
| 386 |
-
|
| 387 |
_ = torch.zeros(1, device="cuda")
|
| 388 |
return True
|
| 389 |
except Exception as e:
|
| 390 |
print(f"WARNING: CUDA initialization failed ({e}). Falling back to CPU.")
|
| 391 |
return False
|
| 392 |
|
| 393 |
-
|
| 394 |
try:
|
| 395 |
model_device = str(next(model.parameters()).device)
|
| 396 |
if model_device.startswith("cuda") and not _cuda_usable():
|
|
@@ -399,7 +376,7 @@ def _select_runtime_device(model) -> str:
|
|
| 399 |
except Exception:
|
| 400 |
pass
|
| 401 |
|
| 402 |
-
|
| 403 |
if _cuda_usable():
|
| 404 |
return "cuda"
|
| 405 |
return "cpu"
|
|
@@ -408,14 +385,10 @@ def _select_runtime_device(model) -> str:
|
|
| 408 |
RUNTIME_DEVICE = _select_runtime_device(model)
|
| 409 |
print(f"Using generation/training runtime device: {RUNTIME_DEVICE}")
|
| 410 |
|
| 411 |
-
|
| 412 |
calculator = DebugRewardCalculator()
|
| 413 |
|
| 414 |
def reward_fn(completions: list[str], prompts: list[str], **kwargs) -> list[float]:
|
| 415 |
-
"""
|
| 416 |
-
GRPO reward function. Called on groups of completions for the same prompt.
|
| 417 |
-
GRPO learns from RELATIVE differences within each group.
|
| 418 |
-
"""
|
| 419 |
rewards = []
|
| 420 |
bugs_raw = kwargs.get("bug_metadata", [{}] * len(completions))
|
| 421 |
bugs = [json.loads(b) if isinstance(b, str) else b for b in bugs_raw]
|
|
@@ -424,7 +397,7 @@ def reward_fn(completions: list[str], prompts: list[str], **kwargs) -> list[floa
|
|
| 424 |
try:
|
| 425 |
agent_output = parse_agent_output(completion)
|
| 426 |
|
| 427 |
-
|
| 428 |
test_results = {"passed": 0, "failed": 0, "total": 0, "newly_broken": 0}
|
| 429 |
if agent_output.action == "propose_fix" and bug:
|
| 430 |
test_results = _run_fix(agent_output.detail, bug)
|
|
@@ -452,7 +425,7 @@ def reward_fn(completions: list[str], prompts: list[str], **kwargs) -> list[floa
|
|
| 452 |
|
| 453 |
return rewards
|
| 454 |
|
| 455 |
-
|
| 456 |
def run_baseline(n: int = 20) -> dict:
|
| 457 |
print("\nRunning baseline evaluation on UNTRAINED model...")
|
| 458 |
model.eval()
|
|
@@ -481,12 +454,12 @@ def run_baseline(n: int = 20) -> dict:
|
|
| 481 |
baseline = run_baseline()
|
| 482 |
model.train()
|
| 483 |
|
| 484 |
-
|
| 485 |
def make_dataset(step: int) -> Dataset:
|
| 486 |
bugs = get_bugs_for_step(step)
|
| 487 |
return Dataset.from_list([{"prompt": bug_to_prompt(b), "bug_metadata": json.dumps(b)} for b in bugs])
|
| 488 |
|
| 489 |
-
|
| 490 |
config = GRPOConfig(
|
| 491 |
output_dir=CHECKPOINT_DIR,
|
| 492 |
max_steps=MAX_STEPS,
|
|
@@ -499,7 +472,7 @@ config = GRPOConfig(
|
|
| 499 |
max_completion_length=_max_comp,
|
| 500 |
temperature=0.9,
|
| 501 |
logging_steps=5,
|
| 502 |
-
save_steps=25,
|
| 503 |
save_strategy="steps",
|
| 504 |
report_to="wandb" if WANDB_API_KEY else "none",
|
| 505 |
)
|
|
@@ -512,7 +485,7 @@ trainer = GRPOTrainer(
|
|
| 512 |
processing_class=tokenizer,
|
| 513 |
)
|
| 514 |
|
| 515 |
-
|
| 516 |
class CurriculumCallback(TrainerCallback):
|
| 517 |
def on_step_end(self, callback_args, state, control, **kwargs):
|
| 518 |
step = state.global_step + args.step_offset
|
|
@@ -524,15 +497,14 @@ class CurriculumCallback(TrainerCallback):
|
|
| 524 |
|
| 525 |
trainer.add_callback(CurriculumCallback())
|
| 526 |
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
HUB_PUSH_EVERY = 50
|
| 533 |
|
| 534 |
class CheckpointPushCallback(TrainerCallback):
|
| 535 |
-
"""Push LoRA adapter to HF Hub every HUB_PUSH_EVERY steps."""
|
| 536 |
|
| 537 |
def on_step_end(self, callback_args, state, control, **kwargs):
|
| 538 |
step = state.global_step + args.step_offset
|
|
@@ -553,28 +525,28 @@ class CheckpointPushCallback(TrainerCallback):
|
|
| 553 |
private=True,
|
| 554 |
commit_message=f"tokenizer checkpoint-step-{step}",
|
| 555 |
)
|
| 556 |
-
|
| 557 |
with open("./last_hub_push.txt", "w") as _f:
|
| 558 |
_f.write(str(step))
|
| 559 |
print(f"[HubPush] β Step {step} pushed to HF Hub.", flush=True)
|
| 560 |
if WANDB_API_KEY:
|
| 561 |
wandb.log({"hub/last_pushed_step": step})
|
| 562 |
except Exception as e:
|
| 563 |
-
|
| 564 |
print(f"[HubPush] WARNING: push failed at step {step}: {e}", flush=True)
|
| 565 |
|
| 566 |
-
if not args.test:
|
| 567 |
trainer.add_callback(CheckpointPushCallback())
|
| 568 |
print(f"HF Hub checkpoint push enabled every {HUB_PUSH_EVERY} steps β {HF_REPO}-checkpoints")
|
| 569 |
else:
|
| 570 |
print("[TEST MODE] Hub checkpoint push disabled.")
|
| 571 |
|
| 572 |
-
|
| 573 |
print(f"\nStarting GRPO training. Max steps: {MAX_STEPS}")
|
| 574 |
print(f"Baseline solve rate: {baseline['solve_rate']:.1%} β target: >60% after training")
|
| 575 |
trainer.train(resume_from_checkpoint=args.resume)
|
| 576 |
|
| 577 |
-
|
| 578 |
model.eval()
|
| 579 |
bugs = load_bugs(1)[:20]
|
| 580 |
post_rewards = []
|
|
@@ -602,7 +574,7 @@ if WANDB_API_KEY:
|
|
| 602 |
wandb.log({"final/solve_rate": post_solve_rate, "final/improvement": post_solve_rate - baseline["solve_rate"]})
|
| 603 |
wandb.finish()
|
| 604 |
|
| 605 |
-
|
| 606 |
model.save_pretrained("./final_model")
|
| 607 |
tokenizer.save_pretrained("./final_model")
|
| 608 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
|
| 2 |
import os
|
| 3 |
import sys
|
|
|
|
| 9 |
import shutil
|
| 10 |
from importlib import metadata
|
| 11 |
|
| 12 |
+
|
| 13 |
parser = argparse.ArgumentParser()
|
| 14 |
parser.add_argument("--test", action="store_true", help="Run 10 steps for testing (Colab/GPU)")
|
| 15 |
parser.add_argument("--test-local", action="store_true", dest="test_local",
|
|
|
|
| 21 |
args = parser.parse_args()
|
| 22 |
|
| 23 |
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
|
| 28 |
if not args.test_local:
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
|
| 33 |
import importlib.util, importlib
|
| 34 |
_needs_cuda_torch = True
|
| 35 |
if importlib.util.find_spec("torch") is not None:
|
|
|
|
| 65 |
sys.exit(1)
|
| 66 |
print("Dependencies installed.", flush=True)
|
| 67 |
|
| 68 |
+
|
| 69 |
if not args.test_local:
|
| 70 |
import torch
|
| 71 |
import wandb
|
|
|
|
| 96 |
from server.reward_calculator import DebugRewardCalculator
|
| 97 |
from server.models import parse_agent_output
|
| 98 |
|
| 99 |
+
|
| 100 |
MODEL_NAME = "Qwen/Qwen2.5-Coder-3B-Instruct"
|
| 101 |
HF_REPO = "shashaank0707/AgentDebugger-trained"
|
| 102 |
MAX_STEPS = (10 if args.test else args.max_steps) - args.step_offset
|
| 103 |
CHECKPOINT_DIR = "./checkpoints"
|
| 104 |
|
| 105 |
+
|
| 106 |
WANDB_API_KEY = os.environ.get("WANDB_API_KEY", "") if not args.test_local else ""
|
| 107 |
HF_TOKEN = os.environ.get("HF_TOKEN")
|
| 108 |
|
|
|
|
| 120 |
}
|
| 121 |
)
|
| 122 |
|
| 123 |
+
|
| 124 |
SYSTEM_PROMPT = """You are an expert Python debugger. You reason through bugs systematically.
|
| 125 |
|
| 126 |
You MUST respond in EXACTLY this format β no exceptions, no extra text:
|
|
|
|
| 137 |
- If proposing a fix, DETAIL must contain the complete function, not just the changed line
|
| 138 |
- Give up only if you have exhausted all reasonable hypotheses"""
|
| 139 |
|
| 140 |
+
|
| 141 |
def load_bugs(tier: int) -> list[dict]:
|
| 142 |
path = f"data/bugs_tier{tier}.jsonl"
|
| 143 |
if not os.path.exists(path):
|
|
|
|
| 165 |
)
|
| 166 |
|
| 167 |
def _run_fix(proposed_code: str, bug: dict) -> dict:
|
|
|
|
| 168 |
test_cases = bug.get("test_cases", [])
|
| 169 |
func_name = bug.get("function_name", "")
|
| 170 |
if not proposed_code or not test_cases or not func_name:
|
|
|
|
| 180 |
f" r={func_name}({args_str})\n"
|
| 181 |
f" print('PASS' if r=={repr(test['expected_output'])} else 'FAIL')\n"
|
| 182 |
f"except Exception as e:\n"
|
| 183 |
+
f" print(f'ERROR: { e} ')\n"
|
| 184 |
)
|
| 185 |
try:
|
| 186 |
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
|
|
|
| 196 |
|
| 197 |
return {"passed": passed, "failed": len(test_cases) - passed, "total": len(test_cases), "newly_broken": 0}
|
| 198 |
|
| 199 |
+
|
| 200 |
MOCK_GOOD = """
|
| 201 |
OBSERVATION: The loop condition on line 4 uses <= instead of
|
| 202 |
HYPOTHESIS: This causes an off-by-one error because Python lists are
|
|
|
|
| 221 |
Let me try fixing it.
|
| 222 |
"""
|
| 223 |
|
| 224 |
+
|
| 225 |
if args.test_local:
|
| 226 |
print("=" * 60)
|
| 227 |
print("LOCAL TEST MODE β no model loaded, testing reward function only")
|
|
|
|
| 275 |
print("\nLOCAL TEST PASSED")
|
| 276 |
sys.exit(0)
|
| 277 |
|
| 278 |
+
|
| 279 |
_gpu_vram_gb = 0
|
| 280 |
+
_is_ampere_plus = False
|
| 281 |
if torch.cuda.is_available():
|
| 282 |
_props = torch.cuda.get_device_properties(0)
|
| 283 |
_gpu_vram_gb = _props.total_memory / 1e9
|
|
|
|
| 288 |
|
| 289 |
COMPUTE_DTYPE = torch.bfloat16 if _is_ampere_plus else torch.float16
|
| 290 |
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
if _gpu_vram_gb >= 70:
|
| 294 |
_batch = 8
|
| 295 |
+
_grad_accum = 1
|
| 296 |
+
_num_gen = 8
|
| 297 |
_max_comp = 256
|
| 298 |
_lora_r = 16
|
| 299 |
+
elif _gpu_vram_gb >= 40:
|
| 300 |
_batch = 4
|
| 301 |
+
_grad_accum = 2
|
| 302 |
+
_num_gen = 4
|
| 303 |
_max_comp = 256
|
| 304 |
_lora_r = 16
|
| 305 |
+
elif _gpu_vram_gb >= 20:
|
| 306 |
_batch = 2
|
| 307 |
_grad_accum = 4
|
| 308 |
+
_num_gen = 2
|
| 309 |
_max_comp = 192
|
| 310 |
_lora_r = 8
|
| 311 |
+
else:
|
| 312 |
_batch = 2
|
| 313 |
_grad_accum = 4
|
| 314 |
+
_num_gen = 2
|
| 315 |
_max_comp = 160
|
| 316 |
_lora_r = 8
|
| 317 |
|
|
|
|
| 319 |
f"num_gen={_num_gen} max_comp={_max_comp} lora_r={_lora_r} "
|
| 320 |
f"dtype={COMPUTE_DTYPE}")
|
| 321 |
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
|
| 325 |
print(f"Loading {MODEL_NAME} in {COMPUTE_DTYPE}...")
|
| 326 |
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
|
| 327 |
tokenizer.pad_token = tokenizer.eos_token
|
|
|
|
| 354 |
model.gradient_checkpointing_enable()
|
| 355 |
print(f"Trainable params: {model.num_parameters(only_trainable=True):,}")
|
| 356 |
|
| 357 |
+
|
| 358 |
def _select_runtime_device(model) -> str:
|
|
|
|
|
|
|
|
|
|
| 359 |
def _cuda_usable() -> bool:
|
| 360 |
try:
|
| 361 |
if not torch.cuda.is_available():
|
| 362 |
return False
|
| 363 |
+
|
| 364 |
_ = torch.zeros(1, device="cuda")
|
| 365 |
return True
|
| 366 |
except Exception as e:
|
| 367 |
print(f"WARNING: CUDA initialization failed ({e}). Falling back to CPU.")
|
| 368 |
return False
|
| 369 |
|
| 370 |
+
|
| 371 |
try:
|
| 372 |
model_device = str(next(model.parameters()).device)
|
| 373 |
if model_device.startswith("cuda") and not _cuda_usable():
|
|
|
|
| 376 |
except Exception:
|
| 377 |
pass
|
| 378 |
|
| 379 |
+
|
| 380 |
if _cuda_usable():
|
| 381 |
return "cuda"
|
| 382 |
return "cpu"
|
|
|
|
| 385 |
RUNTIME_DEVICE = _select_runtime_device(model)
|
| 386 |
print(f"Using generation/training runtime device: {RUNTIME_DEVICE}")
|
| 387 |
|
| 388 |
+
|
| 389 |
calculator = DebugRewardCalculator()
|
| 390 |
|
| 391 |
def reward_fn(completions: list[str], prompts: list[str], **kwargs) -> list[float]:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 392 |
rewards = []
|
| 393 |
bugs_raw = kwargs.get("bug_metadata", [{}] * len(completions))
|
| 394 |
bugs = [json.loads(b) if isinstance(b, str) else b for b in bugs_raw]
|
|
|
|
| 397 |
try:
|
| 398 |
agent_output = parse_agent_output(completion)
|
| 399 |
|
| 400 |
+
|
| 401 |
test_results = {"passed": 0, "failed": 0, "total": 0, "newly_broken": 0}
|
| 402 |
if agent_output.action == "propose_fix" and bug:
|
| 403 |
test_results = _run_fix(agent_output.detail, bug)
|
|
|
|
| 425 |
|
| 426 |
return rewards
|
| 427 |
|
| 428 |
+
|
| 429 |
def run_baseline(n: int = 20) -> dict:
|
| 430 |
print("\nRunning baseline evaluation on UNTRAINED model...")
|
| 431 |
model.eval()
|
|
|
|
| 454 |
baseline = run_baseline()
|
| 455 |
model.train()
|
| 456 |
|
| 457 |
+
|
| 458 |
def make_dataset(step: int) -> Dataset:
|
| 459 |
bugs = get_bugs_for_step(step)
|
| 460 |
return Dataset.from_list([{"prompt": bug_to_prompt(b), "bug_metadata": json.dumps(b)} for b in bugs])
|
| 461 |
|
| 462 |
+
|
| 463 |
config = GRPOConfig(
|
| 464 |
output_dir=CHECKPOINT_DIR,
|
| 465 |
max_steps=MAX_STEPS,
|
|
|
|
| 472 |
max_completion_length=_max_comp,
|
| 473 |
temperature=0.9,
|
| 474 |
logging_steps=5,
|
| 475 |
+
save_steps=25,
|
| 476 |
save_strategy="steps",
|
| 477 |
report_to="wandb" if WANDB_API_KEY else "none",
|
| 478 |
)
|
|
|
|
| 485 |
processing_class=tokenizer,
|
| 486 |
)
|
| 487 |
|
| 488 |
+
|
| 489 |
class CurriculumCallback(TrainerCallback):
|
| 490 |
def on_step_end(self, callback_args, state, control, **kwargs):
|
| 491 |
step = state.global_step + args.step_offset
|
|
|
|
| 497 |
|
| 498 |
trainer.add_callback(CurriculumCallback())
|
| 499 |
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
|
| 505 |
+
HUB_PUSH_EVERY = 50
|
| 506 |
|
| 507 |
class CheckpointPushCallback(TrainerCallback):
|
|
|
|
| 508 |
|
| 509 |
def on_step_end(self, callback_args, state, control, **kwargs):
|
| 510 |
step = state.global_step + args.step_offset
|
|
|
|
| 525 |
private=True,
|
| 526 |
commit_message=f"tokenizer checkpoint-step-{step}",
|
| 527 |
)
|
| 528 |
+
|
| 529 |
with open("./last_hub_push.txt", "w") as _f:
|
| 530 |
_f.write(str(step))
|
| 531 |
print(f"[HubPush] β Step {step} pushed to HF Hub.", flush=True)
|
| 532 |
if WANDB_API_KEY:
|
| 533 |
wandb.log({"hub/last_pushed_step": step})
|
| 534 |
except Exception as e:
|
| 535 |
+
|
| 536 |
print(f"[HubPush] WARNING: push failed at step {step}: {e}", flush=True)
|
| 537 |
|
| 538 |
+
if not args.test:
|
| 539 |
trainer.add_callback(CheckpointPushCallback())
|
| 540 |
print(f"HF Hub checkpoint push enabled every {HUB_PUSH_EVERY} steps β {HF_REPO}-checkpoints")
|
| 541 |
else:
|
| 542 |
print("[TEST MODE] Hub checkpoint push disabled.")
|
| 543 |
|
| 544 |
+
|
| 545 |
print(f"\nStarting GRPO training. Max steps: {MAX_STEPS}")
|
| 546 |
print(f"Baseline solve rate: {baseline['solve_rate']:.1%} β target: >60% after training")
|
| 547 |
trainer.train(resume_from_checkpoint=args.resume)
|
| 548 |
|
| 549 |
+
|
| 550 |
model.eval()
|
| 551 |
bugs = load_bugs(1)[:20]
|
| 552 |
post_rewards = []
|
|
|
|
| 574 |
wandb.log({"final/solve_rate": post_solve_rate, "final/improvement": post_solve_rate - baseline["solve_rate"]})
|
| 575 |
wandb.finish()
|
| 576 |
|
| 577 |
+
|
| 578 |
model.save_pretrained("./final_model")
|
| 579 |
tokenizer.save_pretrained("./final_model")
|
| 580 |
|
uv.lock
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
validator.py
CHANGED
|
@@ -1,14 +1,4 @@
|
|
| 1 |
-
|
| 2 |
-
"""
|
| 3 |
-
AgentDebuggerEnv β Pre-Submission Validator
|
| 4 |
-
============================================
|
| 5 |
-
Checks for all hard requirements of the Meta + HF Hackathon:
|
| 6 |
-
- Mandatory Environment Variables
|
| 7 |
-
- OpenEnv Spec Compliance (health, reset, step, state)
|
| 8 |
-
- Inference Script Format & Logging
|
| 9 |
-
- Dockerfile Correctness
|
| 10 |
-
- openenv.yaml Presence
|
| 11 |
-
"""
|
| 12 |
|
| 13 |
import os
|
| 14 |
import sys
|
|
@@ -17,7 +7,7 @@ import requests
|
|
| 17 |
import yaml
|
| 18 |
import re
|
| 19 |
|
| 20 |
-
|
| 21 |
ENV_BASE_URL = os.environ.get("ENV_BASE_URL", "http://localhost:8000")
|
| 22 |
API_BASE_URL = os.environ.get("API_BASE_URL")
|
| 23 |
MODEL_NAME = os.environ.get("MODEL_NAME")
|
|
@@ -74,7 +64,7 @@ def check_yaml():
|
|
| 74 |
def check_endpoints():
|
| 75 |
log_info(f"Checking Endpoints at {ENV_BASE_URL}...")
|
| 76 |
|
| 77 |
-
|
| 78 |
try:
|
| 79 |
resp = requests.get(f"{ENV_BASE_URL}/health", timeout=5)
|
| 80 |
if resp.status_code == 200:
|
|
@@ -86,7 +76,7 @@ def check_endpoints():
|
|
| 86 |
log_fail(f"Could not connect to /health: {e}")
|
| 87 |
return False
|
| 88 |
|
| 89 |
-
|
| 90 |
try:
|
| 91 |
resp = requests.post(f"{ENV_BASE_URL}/reset", json={"task_id": "easy"}, timeout=5)
|
| 92 |
if resp.status_code == 200:
|
|
@@ -109,7 +99,7 @@ def check_inference_script():
|
|
| 109 |
with open("inference.py", 'r') as f:
|
| 110 |
content = f.read()
|
| 111 |
|
| 112 |
-
|
| 113 |
patterns = {
|
| 114 |
"[START]": r"\[START\] task=",
|
| 115 |
"[STEP]": r"\[STEP .+\] Action:",
|
|
@@ -137,7 +127,7 @@ def main():
|
|
| 137 |
success &= check_yaml()
|
| 138 |
success &= check_inference_script()
|
| 139 |
|
| 140 |
-
|
| 141 |
try:
|
| 142 |
if not check_endpoints():
|
| 143 |
log_info("Skipping further endpoint checks as server is unreachable.")
|
|
|
|
| 1 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import os
|
| 4 |
import sys
|
|
|
|
| 7 |
import yaml
|
| 8 |
import re
|
| 9 |
|
| 10 |
+
|
| 11 |
ENV_BASE_URL = os.environ.get("ENV_BASE_URL", "http://localhost:8000")
|
| 12 |
API_BASE_URL = os.environ.get("API_BASE_URL")
|
| 13 |
MODEL_NAME = os.environ.get("MODEL_NAME")
|
|
|
|
| 64 |
def check_endpoints():
|
| 65 |
log_info(f"Checking Endpoints at {ENV_BASE_URL}...")
|
| 66 |
|
| 67 |
+
|
| 68 |
try:
|
| 69 |
resp = requests.get(f"{ENV_BASE_URL}/health", timeout=5)
|
| 70 |
if resp.status_code == 200:
|
|
|
|
| 76 |
log_fail(f"Could not connect to /health: {e}")
|
| 77 |
return False
|
| 78 |
|
| 79 |
+
|
| 80 |
try:
|
| 81 |
resp = requests.post(f"{ENV_BASE_URL}/reset", json={"task_id": "easy"}, timeout=5)
|
| 82 |
if resp.status_code == 200:
|
|
|
|
| 99 |
with open("inference.py", 'r') as f:
|
| 100 |
content = f.read()
|
| 101 |
|
| 102 |
+
|
| 103 |
patterns = {
|
| 104 |
"[START]": r"\[START\] task=",
|
| 105 |
"[STEP]": r"\[STEP .+\] Action:",
|
|
|
|
| 127 |
success &= check_yaml()
|
| 128 |
success &= check_inference_script()
|
| 129 |
|
| 130 |
+
|
| 131 |
try:
|
| 132 |
if not check_endpoints():
|
| 133 |
log_info("Skipping further endpoint checks as server is unreachable.")
|