Repository navigation
Conversation
This was referenced Oct 31, 2026
pthombre
force-pushed
the
pranav/envckpt-10-opencode-in-place
branch
from
October 31, 2026 19:53
7725780 to
a3b18a2
Compare
pthombre
force-pushed
the
pranav/envckpt-10-opencode-in-place
branch
from
November 2, 2026 06:16
a3b18a2 to
744b51c
Compare
This was referenced Nov 2, 2026
pthombre
force-pushed
the
pranav/envckpt-10-opencode-in-place
branch
from
November 3, 2026 03:22
744b51c to
4bcb151
Compare
pthombre
force-pushed
the
pranav/envckpt-10-opencode-in-place
branch
from
November 3, 2026 06:40
4bcb151 to
15099f2
Compare
… keep processes On a provider whose snapshots keep the sandbox's processes (`snapshot_keeps_processes`, AgentENV), a checkpointed OpenCode session now runs its supervisor in hold mode and calls the model through the model relay in the sandbox (`sandbox_model_relay_port`, default 18431); without Python 3.6+ in the image the runner falls back to the direct model URL. Other providers launch exactly as before. After a crash, the re-bind checks the restored launch (`check_restored`): when its supervisor, held pause and relay survived, or the launch had already ended, the activation points the relay at the replacement attempt's model URL (endpoint generation + 1) before it continues the pause, and takes the launch over with `SandboxSession.adopt`, so the call the checkpoint cut is re-sent byte for byte and nothing is relaunched. Otherwise the launch is abandoned (killed, nothing continued) and relaunched from the saved conversation as before; a failed take-over falls back the same way. The bookmark carries `keeps_processes` and `relay_gen`. WARNING lines `OpenCode resumed in place:`, `OpenCode cannot resume in place:` and `OpenCode abandoned a restored launch:` count the outcomes. Adds benchmarks/swebench/verified/opencode_sessions_agentenv.yaml and documents the path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@nvidia.com>
…es in place On a sandbox whose snapshots keep processes, session setup stops and masks the image's time daemons, and the restore re-bind's first command sets the wall clock back to the held pause's wall clock plus the uptime since: the provider sets a resumed sandbox's clock to the host's, so without this a restore on a later day shows the jump in `date`, in new files' modification times and in OpenCode's date. Files written between the resume and the rewind get the rewound time. A clock that cannot be set, or a rewind that fails, is logged and the restore goes on. `restore_sandbox_clock` (default true) turns it off. Logs `OpenCode restored the sandbox clock:` or `OpenCode left the sandbox clock:` at WARNING. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@nvidia.com>
…k only when it froze OpenCode freezes during a checkpoint's pause when it keeps the sandbox clock (`restore_sandbox_clock`, `checkpoint_freeze_wait_seconds`, default 2 s), so nothing of it runs on the clock a restore jumps forward. After a restore it rewinds only when that pause froze the launch; otherwise it logs `OpenCode left the sandbox clock: ... reason not_frozen` and leaves the provider's clock, so a conversation can never be scrambled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@nvidia.com>
…n, and log them at INFO Some task images have no Python 3.6 or later. The model relay cannot run there, so every launch runs without it and a restore cannot continue it in place: it is relaunched from its saved conversation (7% of resumed launches in one 16-node job). That was only visible as a WARNING at restore time. - At seed, a process-keeping session checks once for the relay's Python, as the runner looks for it, and records it with the session's checkpoint (`relay_python`). Without one it logs a single WARNING naming the session, the task and the sandbox: its launches cannot resume in place after a restore. - On restore, `relay_unavailable` for such a session reports "no Python in the image". - `relay_unavailable` and `relay_gone` are expected outcomes and are logged at INFO, with the abandonment that follows. Every other reason (`adopt_failed`, `supervisor_gone`, `identity_mismatch`, `pause_mismatch`) stays a WARNING. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Pranav Thombre <pthombre@nvidia.com>
pthombre
force-pushed
the
pranav/envckpt-10-opencode-in-place
branch
from
November 5, 2026 20:07
15099f2 to
abf7b47
Compare
This branch has not been deployed
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.
What changed and why
On OpenSandbox, a crash restore relaunches OpenCode from its saved conversation (#5268). On AgentENV, whose snapshots keep the sandbox's processes (#5410), the restored sandbox is still running OpenCode mid-task. #5411 and #5412 added the pieces to hold it through a checkpoint and take it over after a restore. This PR wires them into the OpenCode agent, so a restored OpenCode session continues in place: its next model call reaches the new job's model server, and nothing is relaunched.
At launch (only when
snapshot_keeps_processes)restore_sandbox_clockon (the default), the hold also freezes OpenCode, its tools and the relay at each checkpoint (waiting up tocheckpoint_freeze_wait_seconds), so nothing runs on the clock a restore jumps forward.sandbox_model_relay_port. If the image has no Python, it uses the direct model URL and that session relaunches on restore.relay_unavailableas "no Python in the image".keeps_processes,relay_genandrelay_python.Other providers launch exactly as before.
After a crash (the re-bind)
check_restoredchecks that the restored launch's supervisor is alive with the same identity, still holding the pause, with its relay up.rewind_clock) only when the held pause froze the launch, re-points the relay at the new model URL with a higher generation, continues the pause, and takes the launch over withSandboxSession.adopt. The relay re-sends the cut call, and OpenCode sees only a slow model call. A launch that had already ended is collected the same way.Each outcome is logged so a run can count it.
relay_unavailableandrelay_goneare expected and logged at INFO; a launch resumed in place, every other reason a launch cannot resume, and the clock decision are logged at WARNING.Settings
sandbox_model_relay_portrestore_sandbox_clocktruecheckpoint_freeze_wait_seconds2.0Also adds a SWE-bench Verified benchmark config for OpenCode sessions on AgentENV, and docs for both restore paths.
How it works
flowchart TD CK["checkpoint: hold pause N and freeze,<br/>relay holds model calls,<br/>AgentENV memory snapshot"] --> CR["crash, new job: fork from snapshot,<br/>environment server re-seeds, agent re-binds"] CR --> KP{"bookmark keeps processes?"} KP -->|"no"| RL["relaunch from saved conversation<br/>(as on OpenSandbox)"] KP -->|"yes"| CHK{"check_restored"} CHK -->|"RestoredLaunch"| CL["rewind clock if the pause froze"] CL --> EP["re-point relay: new model URL,<br/>generation plus 1"] EP --> AD["continue pause N, adopt launch"] AD --> OK["OpenCode continues in place,<br/>cut call re-sent byte for byte"] AD -->|"take-over fails"| AB CHK -->|"NotResumable"| AB["abandon launch (KILL, no CONT)"] AB --> RLWhere this sits in the stack
This stack checkpoints environment-server episodes whose agent harness runs in a sandbox the resources server lends. PRs 1 to 7 add it for OpenCode and SWE-bench on OpenSandbox. PRs 8 to 11 add AgentENV (E2B API, VM memory snapshots), where a restored sandbox still runs the harness's processes, so OpenCode continues in place instead of being relaunched, with the sandbox's clock kept continuous. Each PR's diff shows only that PR's change.
Issue
No tracking issue exists. This finishes AgentENV in-place resume for OpenCode, the harness used in SWE training.
Validation
main: the stack's suites pass, and two 16-node AgentENV RL training runs of the rebased stack, a checkpoint run and a restore from its checkpoint, commit every checkpoint with no sandbox loss; the restore resumes in place every held session whose image can run the model relay. Every restored session took the expected path: those with the relay resumed in place, and those whose images have no Python were relaunched from their saved conversation, each named at seed.Compatibility
restore_sandbox_clock: falseto hold without freezing and leave the clock as AgentENV sets it.keeps_processes,relay_genandrelay_python. Older bookmarks restore through the relaunch path.🤖 Generated with Claude Code