Repository navigation
feat(claude-code): support owned and borrowed sandbox sessions - #4745
Conversation
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
…havior Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
|
/ok to test d77400b |
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
|
/ok to test d859b91 |
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
|
/ok to test ef18b3a |
yaoyu-33
left a comment
There was a problem hiding this comment.
Thanks for the follow-up, @lafrancef. Both earlier threads are addressed at ef18b3af5a58: close now waits for captured-artifact parsing, and metadata.agent_timeout_sec is honored with the configured ceiling. This brings claude_code_agent in line with the other sandboxed harnesses; nothing here is blocking.
Before merge
- The branch conflicts with
maininscripts/add_legacy_agent_environment_servers.pyand its test.mainaddedkilocode_agentand astirrup_agentearly return, so the merged set should keep both alongsideclaude_code_agent. Could you rebase?
Inline comments: four risks (the --agent-type swap migration note, the API key reaching the sandbox with a Gym model server, the shared /tmp host cache as the trust anchor, and serialized host hashing plus per-seed upload copies), plus two small notes (the cancelled outcome and a weak 409 test assertion).
PR description
- Could the body list the exact local test and
pre-commitcommands run, and the commit the live smoke run used?
Local check at ef18b3af5a58: responses_api_agents/claude_code_agent/tests 149 passed; tests/unit_tests/test_add_legacy_agent_environment_servers.py 48 passed.
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
|
/ok to test 11ccc88 |
marta-sd
left a comment
There was a problem hiding this comment.
All comments were addressed so I'm approving
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/39570394529 |
Run Claude Code in agent-owned or borrowed sandboxes through the existing agent-session API. Configure
sandbox_provider,sandbox_config, and an exactclaude_code_version, or supplySandboxAccesswhen seeding a session. The agent README and YAML document setup and supported inputs.The adapter follows the other sandboxed harnesses:
ClaudeCodeAgentowns session hooks and dispatch, whileClaudeCodeSandboxSessiondelegates supervision and release toSandboxSession. Native stdout, stderr, and runtime identity have separate artifacts. Interrupted activations report a cancelled sandbox outcome. Close waits for cleanup and captured-artifact parsing within bounds, retaining native observations when close overlaps parsing; it also returns observations if no activation ran. Repeating the same activation returns its result; a different request receives 409.Runtime setup works without sandbox internet access. Gym downloads the native release for the sandbox's architecture/libc into the current user's owned, mode-0700
~/.cache/nemo_gym/claudedirectory. Verified file identities are memoized within each worker; changed files are reverified. Compressed transfers share a four-chunk limit across sessions, staging at most 4 MiB per worker instead of a full archive per seed. The sandbox verifies the decompressed SHA-256 and version before atomically installing a shared, versioned runtime. Subsequent seeds in the same sandbox verify and reuse it without uploading the binary; sandboxes without a verified runtime receive the transfer. An offline Gym host can setsandbox_local_executable_path; a binary already in the sandbox can usesandbox_executable_path. Either supplied-binary option requiressandbox_executable_sha256. The worker scripts support Linux Python 3.8+.Local prompt handling, explicit
skills_ref, command options, and subprocess behavior are preserved. Configuredskills.pathfallback applies only to sandbox sessions. In sandbox sessions usingmodel_server, both Anthropic authentication variables use placeholders; the configured direct credential stays on the Gym host. The local setup-timing change is intentional: host CLI installation happens on first local use, rather than server startup, to avoid installing an unused host CLI on sandbox-only servers. Concurrent local setup shares one attempt, and failures can be retried.Sandbox inputs accept a single user text prompt, optionally preceded by a system message.
metadata.agent_timeout_secsets a per-task execution budget capped by the configuredtimeout; other metadata keys receive 422. History, developer/assistant messages, and requestinstructionsreceive 422 rather than being discarded. The harness implementation is underresponses_api_agents/claude_code_agent/. The config migration script also recognizes Claude Code's unbound native template, preserving legacy wrappers for resource-bound local configurations; regression tests cover both forms and inherited bindings. The default YAML selects native composition, so legacy--resources-server X --agent-type claude_code_agentswap configurations must explicitly restoreresources_server: {type: resources_servers, name: "???"}on the agent. Existing bound recipes keep their bindings.nemo_gym/is unchanged. No separate issue is needed for this focused harness capability.Live validation on
11ccc88f8b28used Claude Code 2.1.108 and gpt-4.1-mini in a borrowed OpenSandbox through the standard EnvironmentServer → Resources → Agent → verifier flow. With sandbox egress denied, runtime setup used host-staged bytes and model traffic used a test-only file-transfer relay to Gym's model server. A request carrying a 90-second task budget completed with native exit 0; independent repair checks improved from 2/8 to 8/8 (reward 1), with 8 native observation records and no gaps. Checked the staged input uses placeholder proxy credentials, the host cache is private, and the native binary and compressed archive are each hashed once across reseeding. Verified agent close before grading, runtime reuse without re-upload, unused-session close observations, and resource teardown.Validation
Commands run against the same revision:
The focused suite passed 211 tests (52 migration and 159 Claude Code); isolated
ng_testpassed all 159 Claude Code tests. Pre-commit passed locally and on Linux; the private guardword catalog was unavailable, so that scan was skipped.CI-equivalent core and sandbox commands on Linux:
Core: 9,304 passed, 28 skipped. Sandbox: 928 passed, 6 skipped. Combined coverage: 95.14%, above the checkout's 95% gate.
Full server suite:
Both shards exited 1; all 236 modules were attempted. After isolated reruns, 213 modules passed. The remaining 23 were blocked during dependency installation (21 GitHub HTTP 503 responses and two PyTorch CDN connection resets), so full-suite success is not claimed.