Skip to content

feat(agent): run OpenCode in task sandboxes - #3639

Merged
yaoyu-33 merged 57 commits into
NVIDIA-NeMo:mainfrom
yaoyu-33:codex/opencode-native-sessions
Oct 10, 2026
Merged

yaoyu-33 merged 57 commits into
NVIDIA-NeMo:mainfrom
yaoyu-33:codex/opencode-native-sessions

Conversation

@yaoyu-33

@yaoyu-33 yaoyu-33 commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

What / expected

Add sandbox sessions to opencode_agent using the shared execute/close lifecycle. An agent session runs OpenCode in a borrowed or agent-owned sandbox; no session uses the local CLI. Close confirms cleanup before Resources verifies. Invalid/closed sessions never fall back to the host.

  • Include fix(opencode): share runtime pin and observability patch #4288's shared runtime pin and model-call attribution plugin in both paths.
  • Keep failure artifacts and cleanup observations; cap combined diagnostics at 16k characters. Local installation is off-loop and retryable even after all waiters cancel; sandbox ripgrep provisioning is best-effort.
  • Remove the unshipped execution selector, old-adapter bridge and obsolete cookie. Session requests use an explicit supported-field contract.

Existing opencode_sandboxed_agent benchmarks, recipes and allowlists stay unchanged; only four required PATH-quoting fixes remain in that adapter. Shared-helper/fixture cleanup is tracked in #4306.

Compatibility / concerns

The shipped YAML now selects ${policy_model_name} through Gym, removing the fixed nvinf provider/model example. Removed local example keys (openai_api_key, openai_base_url, env, workspace_root, system_prompt, extra_args, concurrency) remain configurable class fields. thinking now defaults to true, timeout changes 900 → 10800s, and resources_server: null means local /run needs an explicit binding. Install/close budgets are 600/60s; owned sandboxes need an explicit provider.

Local prompt compatibility is preserved; sandbox instructions use a separate file. Sandbox env, custom command and extra_args are rejected. Default permissions apply locally too; subagents are enabled here but remain disabled in the old benchmark profile. These differences can affect scores. One worker; eval-only, with training token capture off by default. No new benchmark baseline is claimed.

Missing system rg warns and falls back to OpenCode's on-demand download; required runtime prerequisites still fail explicitly. Offline images should preinstall ripgrep. A separately identified input-upload permission issue for non-root Docker with controller umask 077 remains outside this fix; the model smokes below use a root image.

Validation

Current head: 5cfdbae0d6167fb055342a5ad2faf89e261975f8; merged main f128d43d3. The conflict with #4172 retains its opencode db VACUUM INTO snapshot and our quoted PATH.

Pytest selection: both OpenCode agent suites, responses_api_models/vllm_model/tests, and core test_sandbox_session, test_sandbox_supervisor_client, test_agent_sessions, test_agent_session_retries, test_add_legacy_agent_environment_servers, test_global_config, plus test_ray_opt_out, test_server_utils and telemetry/test_config after merging main. Run with --import-mode=importlib -q -o addopts='' -o log_cli=false; Linux exclusions are named below.

  • macOS/Python 3.13.14 after merge: 1,382 passed / 43 skips (39 platform/runtime; four optional nemo.lens integration tests). Final all-file pre-commit and whitespace checks pass. The initial restricted pre-merge run could not bind a test port; permitted reruns pass without exclusions.
  • Linux/Python 3.13.14 after merge: 1,419 passed / 4 skipped / 2 deselected, including real Linux process-supervision, installer and Node plugin tests. Skipped: optional nemo.lens integration. Excluded: the previously reproduced vLLM endpoint-mtime failures (test_publish_rebinds_clients_and_clears_sessions, test_unpublished_endpoint_grace_lifecycle); those unchanged model files match main. Canonical isolated gym env test and core-wide coverage were not rerun.
  • New regressions reproduce 11 pre-fix Linux installer failures (uncached/cached, non-root, no package manager, apt/apk failures), the cancelled-waiter retry failure and oversized combined diagnostics. The fixed focused Linux suite passes 55 tests; 502 and capture errors share the same bound without duplicating stderr.
  • Regression checks against the merge-only pre-fix snapshot reproduce plugin/input, diagnostics, cleanup-observation and synchronous-parser defects; the future-field check also fails before the allow-list fix.
  • Smoke: real OpenCode 1.17.11, nvidia/nemotron-3-super-120b-a12b, Docker sandbox and stock math verifier. On runtime candidate 68fd15170, owned and borrowed episodes both score 1, retain tools/nonzero usage, carry message-ID headers on all three model calls, and confirm cleanup before verification. The owned driver required fixture/capture-path corrections; evidence was retained and the successful episode was audited without a score-driven rerun.
  • Post-merge borrowed smoke also passes: reward 1, 3/3 correlated model calls, 24,214 tokens, tool-written answer, paired tool output, retained observations and confirmed cleanup before verification. Resources destroys the borrowed sandbox; task-scoped inventory is empty after the run. The earlier pre-merge smoke also passed (24,262 tokens); neither was rerun for score selection.
  • These are bounded functional checks, not SWE-Pro accuracy validation. Full current-head CI and maintainer approval remain separate gates; no CI trust-gate authorization is implied.
Earlier benchmark evidence (not rerun on this head)

At da85bf9ef (documentation-only follow-up 52d8e12df), the HSG SWE-Pro smoke completed official grading with reward 0, 161/178 tests passed. The model hit its output limit without producing a patch. Existing direct/local and borrowed-sandbox smoke evidence remains revision-pinned in the PR history; it is not a score baseline for this revision.

@yaoyu-33 yaoyu-33 added feature New capabilities, enhancements, or enablement work area:agent Agent harnesses and Responses API agent behavior labels Sep 22, 2026
@copy-pr-bot

copy-pr-bot Bot commented Sep 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@yaoyu-33
yaoyu-33 force-pushed the codex/opencode-native-sessions branch from 2636190 to 50d1f6b Compare September 23, 2026 01:34
@yaoyu-33 yaoyu-33 changed the title feat(agent): run OpenCode in native task sandbox sessions feat(agent): support native OpenCode in its canonical package Sep 23, 2026
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

@yaoyu-33
yaoyu-33 force-pushed the codex/opencode-native-sessions branch from a0e5ab9 to 07be62c Compare September 23, 2026 21:24
@yaoyu-33
yaoyu-33 force-pushed the codex/hermes-swe-pro-validation branch from 00db9de to b5a692e Compare September 23, 2026 21:24
lafrancef added a commit that referenced this pull request Sep 30, 2026
…r stack

Rebase the TB4 full-swapping integration onto main 17add3c, including
mini-SWE refactor #3680 and the merged EnvironmentServer replacement stack
#3717, #3718, #3720, #3721, and #3722.

Adapt native OpenCode session support from #3639 (dce7f83) and Hermes
session hardening from #3554 (6dc9c53). Keep existing legacy entrypoints.

Add optional resource-resolved task context, caller-assigned native TB4
sessions, a generic swappable profile, and lifecycle-audited CPU/GPU/Compose
smokes. Preserve the mini-SWE CLI/Responses flow while supervising all
agent descendants before verification. Honor task users and limits, select
sandbox-compatible bootstrap binaries, and avoid an unnecessary root UID
switch when preparing the already-executable TB4 verifier.

Bind native TB4 close to the merged HTTP hook and confirm destruction,
allowing retries after provider deletion failures. Route Hermes iteration-limit
summaries through its regular request formatter, preserving reasoning, history,
and request settings without leaking internal Responses IDs into chat requests.

Signed-off-by: Frederic Lafrance <flafrance@nvidia.com>
@yaoyu-33

yaoyu-33 commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor Author

Why this follow-up is needed in #3639:

  • The native adapter required PTY, which blocked the local Docker path. It now uses ordinary exec.
  • Native execution ignored the existing max_output_tokens setting. Context and output limits now stay separate, so reducing the output cap does not also shrink the model's context window.
  • An exec timeout is not proof that the harness stopped inside the container. We now require confirmed descendant cleanup before exporting results and allowing verification; uncertain cleanup remains retryable.
  • SWE-Pro task images include older Python and musl environments. The installer/runner now supports these without unpublished runtime patches.

The earlier 600-second timeout occurred on main's separate opencode_sandboxed_agent path: the whole install/run command timed out, and the OpenCode process remained alive during transcript export. This PR does not modify that main adapter.

The saved NodeBB trace explains why separating the limits matters: 31 automatic compactions, about 297 seconds in completed compaction messages, 144 file reads, and no edit/write/apply-patch calls. The old 32768 shared-cap workaround also shrank the context: OpenCode 1.17.11's default compaction threshold becomes 32768 - 20000 = 12768 tokens. Repeated compaction and re-reading—not one hung tool—consumed the run budget. The new smoke keeps context at 262144 with a separate 32768 output cap; simply increasing the timeout would not address that configuration problem.

Validation at ca4106447: 254 OpenCode tests + 118 lifecycle/provider tests passed. A fresh Docker smoke on the selected OpenLibrary task returned reward 1, with the required test passing and cleanup completed. This is a different task from the timed-out NodeBB run—not evidence that NodeBB now finishes or that full-benchmark parity is established.

@yaoyu-33

yaoyu-33 commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 3250e4350 (cleanup guard/tests) and a28db47cf (prompt-preparation guidance).

  • Cleanup: skip transcript snapshots when descendant cleanup is unconfirmed; verification stays blocked. The detached-child regression failed before the fix and passes now. A real 20s timeout retained partial output and completed cleanup before verification.
  • Reward-zero root cause: the old NodeBB example sent only problem_statement, omitting requirements and interface. The materializer did not drop them—they were absent from the original prompt. The existing render_prompt builder already handles all three fields.
  • Corrected-prompt smoke: same NodeBB task, model, image, verifier and 600s harness budget; reward 1, 300/300 tests passed, including all 3 target fixes and 288 preservation tests. 393.85s, 0 compactions, 7,748-byte patch applied. No reference solution or failed-test hints were supplied; captured input matches the full prepared prompt. Owned resources cleaned up.

Validation: 375 Linux tests passed; local 245 passed / 30 Linux-only skipped; all-file pre-commit passed; Fern 0 errors / 1 warning. The final documentation commit leaves the tested runtime unchanged.

The handoff HTML now includes the exact full-prompt preparation command, source pin, result and smoke-only limits. Keeping draft: single-task evidence is not a full baseline, and the existing base-branch conflicts/full CI still need follow-up.

Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>

@ananthsub ananthsub left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough follow-up. I checked all 20 threads against the new code, and each one is resolved:

  • The rebase onto #4288 is clean, with one version pin and the observability plugin uploaded into sandbox sessions.
  • The execution_mode setting, the legacy_sandbox bridge, the obsolete cookie check and the remote_* fields are removed.
  • Defaults and names now match Pi and Codex.
  • Request validation is an allow-list, failures keep their artifacts and stderr.log, and the off-loop parse and install are covered by tests.

The shared-helper cleanup is tracked in #4306. The OpenCode tests pass locally on Linux.

One new issue comes from this round: the ripgrep check in the installer is now a hard requirement, so setup fails on non-root images without rg, and on RHEL-family root images. That one is inline and should be fixed before merge. The other two inline comments are nits.

Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

yaoyu-33 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 5cfdbae

Preserve both OpenCode and OpenClaw composition tests. No OpenCode runtime or retained permission candidate changes.

Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
@yaoyu-33

Copy link
Copy Markdown
Contributor Author

/ok to test 8bba306

@yaoyu-33
yaoyu-33 added this pull request to the merge queue Oct 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/38069955548

This branch was previously deployed

1 inactive deployment
public — 8bba3061 Deployed Oct 10, 2026 by copy-pr-bot[bot] via release / finalize / notify #4995
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:agent Agent harnesses and Responses API agent behavior complexity:high Cross-component or shared-contract change with a large review surface feature New capabilities, enhancements, or enablement work needs-review PR is ready for code review and waiting on a reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants