feat(agents): sandbox-bound CLI agents (Codex, Claude Code, custom) with capture + in-box SWE-bench grading - #1611
Closed
Glorf wants to merge 1 commit into
Closed
Conversation
Glorf
force-pushed
the
feat/sandbox-cli-agents
branch
from
June 16, 2026 13:33
341ccfa to
a78c462
Compare
Contributor
|
🌿 Preview your docs: https://nvidia-preview-feat-sandbox-cli-agents.docs.buildwithfern.com/nemo/gym Here are the markdown pages you've updated: |
Glorf
force-pushed
the
feat/sandbox-cli-agents
branch
2 times, most recently
from
June 16, 2026 15:46
91638b6 to
4776ebd
Compare
Glorf
requested review from
adil-a,
ananthsub,
bxyu-nvidia and
cmunley1
and removed request for
bxyu-nvidia and
cmunley1
June 16, 2026 16:02
Glorf
force-pushed
the
feat/sandbox-cli-agents
branch
from
June 22, 2026 11:27
4776ebd to
1b91177
Compare
…ith capture + SWE-bench/Terminal-Bench grading Adds a reusable layer for running CLI coding agents *inside* a Gym sandbox and collecting RL-ready trajectories, built on the sandbox provider + adapter framework. Benchmark-agnostic: only task metadata + the grader change. SandboxCliAgent (nemo_gym/sandbox_cli_agent.py) - Owns the whole per-rollout lifecycle: start a sandbox, stand up a per-rollout capture proxy, install + run the CLI in-box, collect the git patch, assemble the trajectory, and grade. Subclasses supply only a thin seam (build_launch + parse_stdout); adding an agent is a small subclass or YAML. Agents - codex_swe_agent: Codex (Responses wire) as a thin subclass. - claude_code_swe_agent: Claude Code (Messages wire) via the translate_anthropic interceptor so it runs against any OpenAI-compatible backend; reuses claude_code_agent's stream-json parser. - custom_agent: manifest-driven (YAML-only) onboarding. Adapters (sandbox-bound, not model-bound) - capture interceptor + CaptureStore: durable, session-keyed JSONL of model exchanges (token-ids when the backend is a Gym model server); trajectory assembly for chat + responses wires. choose_trajectory prefers a well-formed (paired tool calls) trajectory, so codex's streamed-response capture and claude's duplicate-call redundancy both fall back to the CLI's clean stdout. - translate_anthropic interceptor: Anthropic Messages <-> OpenAI Chat. In-box grading (the only benchmark-specific seam) - SWE-bench: the official swebench harness (make_test_spec eval_script + get_eval_report), like mini_swe_agent_2. - Terminal-Bench / Harbor: per-task public docker_image (auto_mirrored), stage the task's tests, run test.sh, read the verifier reward file. - Fallback: a lightweight pytest membership grader for a custom eval_command. Runnable under ng_run / ng_collect_rollouts; per-agent + per-task examples and a Terminal-Bench example row are in the agent READMEs/data. Agents install nemo-gym[sandbox,sandbox-ecs] (editable) + swebench. Validated on real ECS Fargate: - SWE-bench Verified: golden -> 1.0, no-patch -> 0.0; Codex + Claude Code each solve real instances; 10 diverse repos via ng_run + ng_collect_rollouts. - Terminal-Bench 2.0 (Harbor): across 5 tasks x Codex + Claude Code — multiple solves (reward 1.0 via the verifier reward file), grader discriminates, and trajectories are healthy (paired tool calls) for both agents. Unit-tested: grader, image-tag mapping, SWE-bench instance reconstruction, Harbor grading, trajectory selection, capture assembly, Anthropic<->OpenAI translation. Note: stacked on the sandbox provider PR (feat/ecs-fargate-sandbox) and the adapter framework PR (feat/adapter-base); review/merge after them. Signed-off-by: Michal Bien <mbien@nvidia.com>
Glorf
force-pushed
the
feat/sandbox-cli-agents
branch
from
June 22, 2026 12:52
1b91177 to
c397ffd
Compare
Contributor
Author
|
Superseded by an upstream-head PR so it can join the GitHub stack (fork-head PRs can't be stacked). |
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A reusable layer for running CLI coding agents inside a Gym sandbox and collecting RL-ready trajectories, on the sandbox-provider + adapter framework. Benchmark-agnostic — only the task metadata and the grader change.
SandboxCliAgentowns the per-rollout lifecycle: start a sandbox -> per-rollout capture proxy -> install + run the CLI in-box -> collect the git patch -> assemble the trajectory -> grade. A new agent is a ~30-line subclass or a YAML manifest.codex_swe_agent(Responses wire),claude_code_swe_agent(Messages wire via thetranslate_anthropicinterceptor -> any OpenAI-compatible backend),custom_agent(manifest-driven).captureproxy keyed to asession_id; the in-box*_BASE_URLpoints at it; torn down on exit.CaptureStorewrites durable per-session JSONL (token-ids on a Gym model server).choose_trajectoryprefers a well-formed (paired tool calls) trajectory, so both codex and Claude Code produce healthy trajectories.swebenchharness; Terminal-Bench / Harbor by staging the task's tests, runningtest.sh, and reading the verifier reward file; lightweight pytest membership fallback.How to run
Per agent — start the agent server, then drive a dataset (swap
codex_swe_agentforclaude_code_swe_agent/custom_agent):Per task — only
responses_create_params.metadatadiffers:metadata.instance_dict(repo, version, base_commit, test_patch, FAIL_TO_PASS, PASS_TO_PASS); image resolves__->_1776_; graded by the swebench harness. Example:responses_api_agents/codex_swe_agent/data/example.jsonl.metadata.docker_image(public, auto-mirrored to ECR) +metadata.harbor_tests({"/tests/test.sh": "...", "/tests/test_outputs.py": "..."}); graded by runningtest.shand reading the verifier reward file. Example:responses_api_agents/codex_swe_agent/data/terminal_bench_example.jsonl.Build full datasets: SWE-bench via HF
princeton-nlp/SWE-bench_Verified; Terminal-Bench viaharbor datasets download terminal-bench@2.0(each task'sinstruction.md+task.tomldocker_image+tests/). See the agent READMEs for the full per-agent/per-task matrix.Validated on real ECS Fargate
ng_run+ng_collect_rollouts.Dependencies (stacked PRs)
Stacked on the open base PRs below — its diff includes their changes until they land on
main, so review/merge after them. Opened as a draft for that reason.Sandbox
Glorf:feat/ecs-fargate-sandbox)Adapters / interceptors
Glorf:feat/adapter-base)Related interceptor families on the same
feat/adapter-base(siblings, not required here): caching Glorf/Gym#2, observability Glorf/Gym#3, request-rewriting Glorf/Gym#4.Test plan
uv run pytest tests/unit_tests/test_sandbox_cli_agent.py tests/unit_tests/test_adapter_capture.py tests/unit_tests/test_adapter_translate_anthropic.py responses_api_agents/codex_swe_agent/tests responses_api_agents/claude_code_swe_agent/tests responses_api_agents/custom_agent/tests