vanishingradient commited on
Commit
e819bd7
·
verified ·
1 Parent(s): 488f5fc

Add deepagents_rl package sources

Browse files
Files changed (1) hide show
  1. src/deepagents_rl/train/swe_env.py +113 -11
src/deepagents_rl/train/swe_env.py CHANGED
@@ -19,6 +19,24 @@ from pathlib import Path
19
  from typing import Any, Callable
20
 
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def _result_to_str(obj: Any) -> str:
23
  if obj is None:
24
  return ""
@@ -97,9 +115,26 @@ def grade_patch_remote(
97
  "model_patch": model_patch or "",
98
  "timeout_s": timeout_s,
99
  }
 
 
 
 
 
 
 
100
  resp = requests.post(f"{base}/grade", headers=headers, json=payload, timeout=timeout_s + 60)
 
101
  resp.raise_for_status()
102
- return resp.json()
 
 
 
 
 
 
 
 
 
103
 
104
 
105
  def _traced_tool(method: Callable[..., str]) -> Callable[..., str]:
@@ -175,10 +210,25 @@ class DeepAgentSWEEnv:
175
  kwargs: dict[str, Any],
176
  ) -> str:
177
  payload = _truncate({"args": list(args), "kwargs": kwargs})
 
 
 
 
 
 
 
178
  lf = self._lf
179
  if lf is None or self._root is None:
180
- out = method(self, *args, **kwargs)
 
 
 
181
  self._tool_calls.append({"name": name, "input": payload, "output": _truncate(out)})
 
 
 
 
 
182
  return out
183
 
184
  with lf.start_as_current_observation(
@@ -189,18 +239,22 @@ class DeepAgentSWEEnv:
189
  "rollout_id": self._rollout_id,
190
  "instance_id": self._task.get("instance_id"),
191
  "harness": "deepagents-swe-grpo",
 
192
  },
193
  ) as span:
194
  try:
195
  out = method(self, *args, **kwargs)
196
  span.update(output=_truncate(out))
197
- self._tool_calls.append({"name": name, "input": payload, "output": _truncate(out)})
198
- return out
199
  except Exception as e: # noqa: BLE001
200
- err = f"TOOL_ERROR: {type(e).__name__}: {e}"
201
- span.update(output=err, level="ERROR")
202
- self._tool_calls.append({"name": name, "input": payload, "output": err})
203
- return err
 
 
 
 
 
204
 
205
  def reset(self, **kwargs: Any) -> None:
206
  """Materialize repo sandbox from a SWE Lite row. Prompt stays on the dataset."""
@@ -223,6 +277,14 @@ class DeepAgentSWEEnv:
223
  else kwargs.get("pass_to_pass_json")
224
  )
225
 
 
 
 
 
 
 
 
 
226
  if not instance_id or not repo or not base_commit:
227
  raise ValueError(
228
  f"DeepAgentSWEEnv.reset requires instance_id/repo/base_commit; got keys={list(kwargs)}"
@@ -252,6 +314,7 @@ class DeepAgentSWEEnv:
252
  self._trace_id = ""
253
 
254
  lf = self._ensure_langfuse()
 
255
  if lf is not None:
256
  try:
257
  self._root_cm = lf.start_as_current_observation(
@@ -282,12 +345,14 @@ class DeepAgentSWEEnv:
282
  )
283
  self._root = self._root_cm.__enter__()
284
  self._trace_id = lf.get_current_trace_id() or ""
 
285
  except Exception as e: # noqa: BLE001
286
- print(f"[langfuse] start rollout failed: {e}")
287
  self._root_cm = None
288
  self._root = None
289
 
290
  def _materialize() -> None:
 
291
  self._sandbox_parent = Path(
292
  tempfile.mkdtemp(prefix=f"darl_grpo_{instance_id[:40]}_")
293
  )
@@ -298,6 +363,7 @@ class DeepAgentSWEEnv:
298
  virtual_mode=True,
299
  timeout=60,
300
  )
 
301
 
302
  if lf is not None and self._root is not None:
303
  with lf.start_as_current_observation(
@@ -309,6 +375,13 @@ class DeepAgentSWEEnv:
309
  span.update(output={"sandbox": str(self._sandbox)})
310
  else:
311
  _materialize()
 
 
 
 
 
 
 
312
  return None
313
 
314
  def _cleanup(self) -> None:
@@ -423,23 +496,39 @@ class DeepAgentSWEEnv:
423
  lf = self._lf
424
  reward = 0.0
425
  report: dict[str, Any] = {}
 
 
 
 
 
 
426
 
427
  def _grade() -> float:
428
  nonlocal report
429
  if self._sandbox is None:
430
  report = {"error": "no_sandbox", "reward_total": 0.0}
 
431
  return 0.0
432
 
433
  from deepagents_rl.harness.repo import git_diff_patch
434
 
435
  try:
 
436
  model_patch = git_diff_patch(self._sandbox)
 
 
 
 
 
 
437
  except Exception as e: # noqa: BLE001
438
  report = {"error": f"git_diff_failed: {e}"}
 
439
  return 0.0
440
 
441
  if not model_patch.strip():
442
  report = {"error": "empty_model_patch", "reward_total": 0.0}
 
443
  return 0.0
444
 
445
  try:
@@ -456,6 +545,7 @@ class DeepAgentSWEEnv:
456
  "error": f"grader_failed: {e}",
457
  "traceback": traceback.format_exc()[-1500:],
458
  }
 
459
  return 0.0
460
 
461
  return float(report.get("reward_total") or 0.0)
@@ -513,6 +603,16 @@ class DeepAgentSWEEnv:
513
 
514
  self._last_report = report
515
  self._last_reward = reward
 
 
 
 
 
 
 
 
 
 
516
 
517
  # W&B: one point per completed rollout (train + ckpt eval)
518
  try:
@@ -532,10 +632,12 @@ class DeepAgentSWEEnv:
532
  "rollout/grader_error": str(report.get("error") or ""),
533
  }
534
  )
535
- except Exception:
536
- pass
 
537
 
538
  self._end_trace()
 
539
  return reward
540
 
541
 
 
19
  from typing import Any, Callable
20
 
21
 
22
+ def _vlog(msg: str, **fields: Any) -> None:
23
+ """Always-on verbose progress (Kaggle logs + local stderr)."""
24
+ extra = ""
25
+ if fields:
26
+ try:
27
+ extra = " | " + json.dumps(fields, default=str)[:1200]
28
+ except Exception:
29
+ extra = f" | {fields!r}"[:1200]
30
+ line = f"[darl] {msg}{extra}"
31
+ print(line, flush=True)
32
+ try:
33
+ from deepagents_rl.observability.logging import step
34
+
35
+ step("swe_env", msg, **fields)
36
+ except Exception:
37
+ pass
38
+
39
+
40
  def _result_to_str(obj: Any) -> str:
41
  if obj is None:
42
  return ""
 
115
  "model_patch": model_patch or "",
116
  "timeout_s": timeout_s,
117
  }
118
+ _vlog(
119
+ "grader.POST /grade",
120
+ url=base,
121
+ instance_id=instance_id,
122
+ patch_bytes=len((model_patch or "").encode("utf-8")),
123
+ timeout_s=timeout_s,
124
+ )
125
  resp = requests.post(f"{base}/grade", headers=headers, json=payload, timeout=timeout_s + 60)
126
+ _vlog("grader.response", status=resp.status_code, body_preview=(resp.text or "")[:400])
127
  resp.raise_for_status()
128
+ data = resp.json()
129
+ _vlog(
130
+ "grader.result",
131
+ instance_id=instance_id,
132
+ reward_total=data.get("reward_total"),
133
+ resolution=data.get("resolution"),
134
+ resolved=data.get("resolved"),
135
+ error=data.get("error"),
136
+ )
137
+ return data
138
 
139
 
140
  def _traced_tool(method: Callable[..., str]) -> Callable[..., str]:
 
210
  kwargs: dict[str, Any],
211
  ) -> str:
212
  payload = _truncate({"args": list(args), "kwargs": kwargs})
213
+ n = len(self._tool_calls) + 1
214
+ _vlog(
215
+ f"tool[{n}].begin {name}",
216
+ instance_id=self._task.get("instance_id"),
217
+ rollout_id=self._rollout_id,
218
+ input=payload,
219
+ )
220
  lf = self._lf
221
  if lf is None or self._root is None:
222
+ try:
223
+ out = method(self, *args, **kwargs)
224
+ except Exception as e: # noqa: BLE001
225
+ out = f"TOOL_ERROR: {type(e).__name__}: {e}"
226
  self._tool_calls.append({"name": name, "input": payload, "output": _truncate(out)})
227
+ _vlog(
228
+ f"tool[{n}].end {name}",
229
+ output_preview=str(out)[:500],
230
+ output_chars=len(str(out)),
231
+ )
232
  return out
233
 
234
  with lf.start_as_current_observation(
 
239
  "rollout_id": self._rollout_id,
240
  "instance_id": self._task.get("instance_id"),
241
  "harness": "deepagents-swe-grpo",
242
+ "tool_index": n,
243
  },
244
  ) as span:
245
  try:
246
  out = method(self, *args, **kwargs)
247
  span.update(output=_truncate(out))
 
 
248
  except Exception as e: # noqa: BLE001
249
+ out = f"TOOL_ERROR: {type(e).__name__}: {e}"
250
+ span.update(output=out, level="ERROR")
251
+ self._tool_calls.append({"name": name, "input": payload, "output": _truncate(out)})
252
+ _vlog(
253
+ f"tool[{n}].end {name}",
254
+ output_preview=str(out)[:500],
255
+ output_chars=len(str(out)),
256
+ )
257
+ return out
258
 
259
  def reset(self, **kwargs: Any) -> None:
260
  """Materialize repo sandbox from a SWE Lite row. Prompt stays on the dataset."""
 
277
  else kwargs.get("pass_to_pass_json")
278
  )
279
 
280
+ _vlog(
281
+ "env.reset.begin",
282
+ instance_id=instance_id,
283
+ repo=repo,
284
+ base_commit=(base_commit[:12] if base_commit else ""),
285
+ keys=list(kwargs.keys())[:30],
286
+ )
287
+
288
  if not instance_id or not repo or not base_commit:
289
  raise ValueError(
290
  f"DeepAgentSWEEnv.reset requires instance_id/repo/base_commit; got keys={list(kwargs)}"
 
314
  self._trace_id = ""
315
 
316
  lf = self._ensure_langfuse()
317
+ _vlog("env.reset.langfuse", enabled=lf is not None)
318
  if lf is not None:
319
  try:
320
  self._root_cm = lf.start_as_current_observation(
 
345
  )
346
  self._root = self._root_cm.__enter__()
347
  self._trace_id = lf.get_current_trace_id() or ""
348
+ _vlog("env.reset.langfuse_trace", trace_id=self._trace_id)
349
  except Exception as e: # noqa: BLE001
350
+ _vlog("env.reset.langfuse_failed", error=str(e))
351
  self._root_cm = None
352
  self._root = None
353
 
354
  def _materialize() -> None:
355
+ _vlog("env.reset.materialize", repo=repo, base_commit=base_commit[:12])
356
  self._sandbox_parent = Path(
357
  tempfile.mkdtemp(prefix=f"darl_grpo_{instance_id[:40]}_")
358
  )
 
363
  virtual_mode=True,
364
  timeout=60,
365
  )
366
+ _vlog("env.reset.sandbox_ready", sandbox=str(self._sandbox))
367
 
368
  if lf is not None and self._root is not None:
369
  with lf.start_as_current_observation(
 
375
  span.update(output={"sandbox": str(self._sandbox)})
376
  else:
377
  _materialize()
378
+ _vlog(
379
+ "env.reset.done",
380
+ instance_id=instance_id,
381
+ rollout_id=self._rollout_id,
382
+ n_f2p=len(fail_to_pass),
383
+ n_p2p=len(pass_to_pass),
384
+ )
385
  return None
386
 
387
  def _cleanup(self) -> None:
 
496
  lf = self._lf
497
  reward = 0.0
498
  report: dict[str, Any] = {}
499
+ _vlog(
500
+ "env.get_reward.begin",
501
+ instance_id=self._task.get("instance_id"),
502
+ n_tool_calls=len(self._tool_calls),
503
+ tools_used=[c.get("name") for c in self._tool_calls],
504
+ )
505
 
506
  def _grade() -> float:
507
  nonlocal report
508
  if self._sandbox is None:
509
  report = {"error": "no_sandbox", "reward_total": 0.0}
510
+ _vlog("env.get_reward.no_sandbox")
511
  return 0.0
512
 
513
  from deepagents_rl.harness.repo import git_diff_patch
514
 
515
  try:
516
+ _vlog("env.get_reward.git_diff")
517
  model_patch = git_diff_patch(self._sandbox)
518
+ _vlog(
519
+ "env.get_reward.patch",
520
+ patch_bytes=len(model_patch.encode("utf-8")),
521
+ empty=not bool(model_patch.strip()),
522
+ preview=model_patch[:300],
523
+ )
524
  except Exception as e: # noqa: BLE001
525
  report = {"error": f"git_diff_failed: {e}"}
526
+ _vlog("env.get_reward.git_diff_failed", error=str(e))
527
  return 0.0
528
 
529
  if not model_patch.strip():
530
  report = {"error": "empty_model_patch", "reward_total": 0.0}
531
+ _vlog("env.get_reward.empty_patch")
532
  return 0.0
533
 
534
  try:
 
545
  "error": f"grader_failed: {e}",
546
  "traceback": traceback.format_exc()[-1500:],
547
  }
548
+ _vlog("env.get_reward.grader_failed", error=str(e))
549
  return 0.0
550
 
551
  return float(report.get("reward_total") or 0.0)
 
603
 
604
  self._last_report = report
605
  self._last_reward = reward
606
+ _vlog(
607
+ "env.get_reward.done",
608
+ instance_id=self._task.get("instance_id"),
609
+ reward_total=reward,
610
+ pass_frac=report.get("pass_frac"),
611
+ resolution=report.get("resolution"),
612
+ resolved=report.get("resolved"),
613
+ error=report.get("error"),
614
+ n_tool_calls=len(self._tool_calls),
615
+ )
616
 
617
  # W&B: one point per completed rollout (train + ckpt eval)
618
  try:
 
632
  "rollout/grader_error": str(report.get("error") or ""),
633
  }
634
  )
635
+ _vlog("env.get_reward.wandb_logged")
636
+ except Exception as e: # noqa: BLE001
637
+ _vlog("env.get_reward.wandb_failed", error=str(e))
638
 
639
  self._end_trace()
640
+ _vlog("env.get_reward.trace_closed", trace_id=self._trace_id)
641
  return reward
642
 
643