Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """Live RR test β run RR against a real benchmark trace and observe behavior. | |
| Instruments the sandbox to print every code execution and its output, | |
| giving full visibility into how the RR iterates. | |
| Usage: | |
| uv run python test_rr_live.py | |
| uv run python test_rr_live.py --task 12 | |
| uv run python test_rr_live.py --all-failed | |
| """ | |
| import argparse | |
| import json | |
| import logging | |
| import os | |
| import sys | |
| import time | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| from ace.steps.rr_step import RRStep, RRConfig, TraceSandbox | |
| from ace.core.sandbox import ExecutionResult | |
| from ace.core.context import ACEStepContext, SkillbookView | |
| from ace.core.skillbook import Skillbook | |
| # ββ Config ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| MODEL = os.getenv( | |
| "ACE_MODEL", "bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0" | |
| ) | |
| TRACES_FILE = Path( | |
| "ace-eval/results/e2e/run_7f757d765ba5/benchmark/traces.json" | |
| ) | |
| # Only show RR-level logs, not every HTTP request | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s %(name)-30s | %(message)s", | |
| datefmt="%H:%M:%S", | |
| ) | |
| for lib in ( | |
| "LiteLLM", "litellm", "httpx", "httpcore", "urllib3", | |
| "botocore", "boto3", "pydantic_ai", | |
| ): | |
| logging.getLogger(lib).setLevel(logging.WARNING) | |
| # ββ Sandbox instrumentation βββββββββββββββββββββββββββββββββββββββββββββ | |
| _orig_execute = TraceSandbox.execute | |
| _iteration_counter = 0 | |
| def _instrumented_execute(self, code: str, timeout: float = 30.0) -> ExecutionResult: | |
| global _iteration_counter | |
| _iteration_counter += 1 | |
| n = _iteration_counter | |
| print(f"\n{'β' * 70}") | |
| print(f" EXECUTE_CODE (iteration {n})") | |
| print(f"{'β' * 70}") | |
| for i, line in enumerate(code.strip().splitlines(), 1): | |
| print(f" {i:3d} β {line}") | |
| print(f"{'β' * 70}") | |
| start = time.time() | |
| result = _orig_execute(self, code, timeout) | |
| elapsed = time.time() - start | |
| if result.stdout: | |
| out = result.stdout.strip() | |
| lines = out.splitlines() | |
| if len(lines) > 40: | |
| for line in lines[:30]: | |
| print(f" out β {line}") | |
| print(f" out β ... ({len(lines) - 30} more lines)") | |
| else: | |
| for line in lines: | |
| print(f" out β {line}") | |
| if result.stderr: | |
| for line in result.stderr.strip().splitlines(): | |
| print(f" err β {line}") | |
| if result.exception: | |
| print(f" EXC β {type(result.exception).__name__}: {result.exception}") | |
| if result.final_value is not None: | |
| print(f" FIN β FINAL() called with keys: {list(result.final_value.keys()) if isinstance(result.final_value, dict) else type(result.final_value).__name__}") | |
| print(f" [{elapsed:.2f}s]") | |
| return result | |
| TraceSandbox.execute = _instrumented_execute | |
| # ββ Helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def load_traces() -> dict: | |
| with open(TRACES_FILE) as f: | |
| return json.load(f) | |
| def get_failed_tasks(data: dict) -> list[tuple[str, dict]]: | |
| failed = [] | |
| for task_id, entry in data.items(): | |
| trial = entry["trials"][0] | |
| if trial["reward"] == 0.0: | |
| failed.append((task_id, trial["trace"])) | |
| return failed | |
| def run_rr_on_trace(task_id: str, trace: dict) -> None: | |
| global _iteration_counter | |
| _iteration_counter = 0 | |
| print(f"\n{'=' * 70}") | |
| print(f" Task {task_id} | reward=0.0 | {trace.get('outcome', '?')}") | |
| print(f"{'=' * 70}") | |
| print(f" Question: {trace['question'][:200]}") | |
| print(f" Feedback: {trace['feedback'][:200]}") | |
| print(f" Answer: {str(trace.get('answer', ''))[:200]}") | |
| print(f" Reasoning: {len(trace.get('reasoning', ''))} chars") | |
| print(f" Messages: {len(trace.get('messages', []))} entries") | |
| print() | |
| rr = RRStep( | |
| MODEL, | |
| config=RRConfig( | |
| max_requests=20, | |
| max_output_chars=10_000, | |
| ), | |
| ) | |
| ctx = ACEStepContext( | |
| trace=trace, | |
| skillbook=SkillbookView(Skillbook()), | |
| ) | |
| start = time.time() | |
| result_ctx = rr(ctx) | |
| elapsed = time.time() - start | |
| print(f"\n{'=' * 70}") | |
| print(f" RESULT (task {task_id}, {elapsed:.1f}s, {_iteration_counter} code executions)") | |
| print(f"{'=' * 70}") | |
| if not result_ctx.reflections: | |
| print(" No reflections produced!") | |
| return | |
| r = result_ctx.reflections[0] | |
| print(f"\n Reasoning:\n {r.reasoning[:600]}") | |
| print(f"\n Key insight:\n {r.key_insight}") | |
| if r.error_identification: | |
| print(f"\n Error identification:\n {r.error_identification}") | |
| if r.root_cause_analysis: | |
| print(f"\n Root cause:\n {r.root_cause_analysis}") | |
| if r.correct_approach: | |
| print(f"\n Correct approach:\n {r.correct_approach[:400]}") | |
| # Print raw metadata | |
| raw = r.raw or {} | |
| usage = raw.get("usage", {}) | |
| rr_trace = raw.get("rr_trace", {}) | |
| print(f"\n Metadata:") | |
| print(f" Tokens: {usage.get('input_tokens', '?')} in / {usage.get('output_tokens', '?')} out") | |
| print(f" LLM requests: {usage.get('requests', '?')}") | |
| print(f" Tool iterations: {rr_trace.get('total_iterations', '?')}") | |
| print(f" Timed out: {rr_trace.get('timed_out', '?')}") | |
| print() | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Live RR test") | |
| parser.add_argument("--task", type=str, help="Specific task ID to analyze") | |
| parser.add_argument( | |
| "--all-failed", action="store_true", help="Run on all failed tasks" | |
| ) | |
| args = parser.parse_args() | |
| data = load_traces() | |
| failed = get_failed_tasks(data) | |
| print(f"Loaded {len(data)} tasks, {len(failed)} failed") | |
| print(f"Failed task IDs: {[t[0] for t in failed]}") | |
| print(f"Model: {MODEL}") | |
| if args.task: | |
| if args.task not in data: | |
| print(f"Task {args.task} not found. Available: {list(data.keys())}") | |
| sys.exit(1) | |
| trace = data[args.task]["trials"][0]["trace"] | |
| run_rr_on_trace(args.task, trace) | |
| elif args.all_failed: | |
| for task_id, trace in failed: | |
| run_rr_on_trace(task_id, trace) | |
| else: | |
| if not failed: | |
| print("No failed tasks found!") | |
| sys.exit(1) | |
| task_id, trace = failed[0] | |
| run_rr_on_trace(task_id, trace) | |
| if __name__ == "__main__": | |
| main() | |