Benjamin-eecs/openrsi-commit-runtime-assets
0168
1"""Run the native commit_runtime pipeline over one corpus repository, locally.2 3This is the launch path the proposal cites (Repo2RLEnv cli.py line 355):4 pipeline = pipeline_cls(gen_input, options, bootstrap=bootstrap_result)5with the prebaked BootstrapResult and the LocalSandbox adapter installed.6 7Usage:8 python -m r2e_local.driver --repo owner/name --sha <pinned> \9 --mirror assets/repos/owner__name --sandbox assets/sandboxes/owner__name \10 --bootstrap assets/bootstrap/owner__name/bootstrap.json \11 --out assets/heldout/owner__name \12 [--llm gemini/gemini-2.5-flash --llm-key-env GEMINI_API_KEY] [--opt key=value ...]13"""14 15from __future__ import annotations16 17import argparse18import json19import logging20import sys21import time22from pathlib import Path23 24from repo2rlenv.spec.input import (25 AuthSpec,26 BootstrapSpec,27 GenerationInput,28 LLMSpec,29 OutputSpec,30 PipelineName,31 PipelineSpec,32 RepoSpec,33)34from repo2rlenv.spec.options import CommitRuntimeOptions35 36from .pipeline import LocalCommitRuntimePipeline, install_hooks, load_bootstrap37 38 39def _parse_opts(items: list[str]) -> dict:40 out: dict = {}41 for item in items:42 k, _, v = item.partition("=")43 if v.lower() in ("true", "false"):44 out[k] = v.lower() == "true"45 elif v.isdigit():46 out[k] = int(v)47 else:48 try:49 out[k] = float(v)50 except ValueError:51 out[k] = v52 return out53 54 55def main(argv: list[str] | None = None) -> int:56 ap = argparse.ArgumentParser()57 ap.add_argument("--repo", required=True, help="owner/name")58 ap.add_argument("--sha", required=True, help="pinned commit")59 ap.add_argument("--mirror", required=True, type=Path)60 ap.add_argument("--sandbox", required=True, type=Path)61 ap.add_argument("--bootstrap", required=True, type=Path)62 ap.add_argument("--out", required=True, type=Path)63 ap.add_argument("--llm", default=None, help="provider/model; omit to disable synthesis")64 ap.add_argument("--llm-key-env", default=None)65 ap.add_argument("--llm-endpoint", default=None)66 ap.add_argument("--opt", action="append", default=[], help="CommitRuntimeOptions field=value")67 ap.add_argument("-v", "--verbose", action="store_true")68 args = ap.parse_args(argv)69 70 logging.basicConfig(71 level=logging.DEBUG if args.verbose else logging.INFO,72 format="%(asctime)s %(levelname)s %(name)s: %(message)s",73 stream=sys.stderr,74 )75 76 github_url = f"https://github.com/{args.repo}"77 install_hooks({github_url: args.mirror.resolve()})78 79 llm = None80 if args.llm:81 provider, _, model = args.llm.partition("/")82 llm = LLMSpec(83 provider=provider,84 model=model,85 api_key_env=args.llm_key_env,86 endpoint=args.llm_endpoint,87 )88 89 opts = CommitRuntimeOptions(**_parse_opts(args.opt))90 if args.llm is None and opts.synthesize_with_llm:91 # Shipped default is synthesize_with_llm=True; with no LLM the pipeline92 # falls back to the commit message (commit_runtime.py _build_instruction).93 logging.getLogger(__name__).warning("no --llm given: instructions use commit text")94 95 gen_input = GenerationInput(96 repo=RepoSpec(url=github_url, ref=args.sha, access="public"),97 pipeline=PipelineSpec(name=PipelineName.COMMIT_RUNTIME, recipe="native"),98 llm=llm,99 output=OutputSpec(destination="local", org="commit-runtime", dataset_name="tasks"),100 bootstrap=BootstrapSpec(enabled=False),101 auth=AuthSpec(github_token_env="R2E_UNUSED_TOKEN", use_gh_cli=False, use_hf_cli=False),102 )103 bootstrap = load_bootstrap(args.bootstrap)104 105 pipeline = LocalCommitRuntimePipeline(106 gen_input, opts, bootstrap=bootstrap, sandbox_dir=args.sandbox.resolve()107 )108 events: list[dict] = []109 pipeline.set_progress_callback(110 lambda name, outcome, reason="": events.append(111 {"t": time.time(), "name": name, "outcome": outcome, "reason": reason}112 )113 )114 115 t0 = time.time()116 result = pipeline.run(args.out.resolve())117 elapsed = time.time() - t0118 119 summary = {120 "repo": args.repo,121 "sha": args.sha,122 "candidates": result.candidates,123 "emitted": result.emitted,124 "skipped": result.skipped,125 "skip_reasons": result.skip_reasons,126 "options": opts.model_dump() if hasattr(opts, "model_dump") else vars(opts),127 "llm": llm.qualified_name if llm else None,128 "llm_cost_usd": round(getattr(pipeline, "_llm_cost_usd", 0.0), 6),129 "elapsed_sec": round(elapsed, 1),130 "events": events,131 }132 args.out.mkdir(parents=True, exist_ok=True)133 (args.out / "result.json").write_text(json.dumps(summary, indent=2))134 print(135 json.dumps(136 {k: summary[k] for k in ("repo", "candidates", "emitted", "skipped", "skip_reasons", "elapsed_sec", "llm_cost_usd")}137 )138 )139 return 0140 141 142if __name__ == "__main__":143 raise SystemExit(main())144 