nemo_gym.agents.utils.supervisor_client
nemo_gym.agents.utils.supervisor_client
Controller-side transport for the shared sandbox process supervisor.
Session ownership and cancellation live in sandbox_session.py; output parsing stays with the adapter. Unlike process_supervisor.sh, this module is not uploaded to the task sandbox.
Session control files (all paths are relative to session_dir):
Agents in the task sandbox often clean up with pkill -f python3, pkill python3 or
killall python3. These must not stop the supervisor or a runner, which would end the
harness. The supervisor and the shared harness runner are bash scripts, so their names
never mention python; a harness argv that runs its own python (Hermes, NOOA, Stirrup) still
appears in the supervisor’s command line. Gym stops the supervisor through the stop file,
which does not depend on these names.
supervisor.pid holds the PID that executes the supervisor. When the provider did not
make the launch shell a process group leader, that process starts the supervisor in a new
group, passes TERM on to it and exits with its status.
Module Contents
Classes
Functions
Data
API
Bases: typing.TypedDict
Outcome after bounded harness termination, as written by process_supervisor.sh.
cleanup_confirmed means no live harness-group members remain. After a forced
stop it also means that no process the stop reached still runs: the harness’s
descendants, including tools in their own sessions, and processes that inherited
the harness’s NEMO_GYM_SUPERVISOR marker without having left the harness
before the stop. Processes that left the harness before the stop, and a process
that left between two scans without the marker, remain until the owner closes the
sandbox; this is not a sandbox-empty check. return_code is the shell status:
128+N for a harness killed by signal N, and 126 or 127 when the command could not
be run.
Seconds as the supervisor parses them: fixed-point, at least one centisecond.
Reserve TERM grace, direct-process reaping, and process-group reaping.
The extra 30 seconds cover startup, polling, and receipt I/O beyond those bounded cleanup phases. Keep their count shared with the controller budget.
The harness boundary’s failure for a negative cleanup receipt.
Its event names the harness but not the receipt’s text, which stays in str() and on receipt
(runtime evidence for teardown, not part of the serialized event).
Whether error reports that a harness’s termination was not confirmed.
Require positive cleanup evidence, tolerating malformed optional diagnostics.
Remove adapter-owned files after cleanup, keeping delayed launches fenced.
Retire the directory atomically before unlinking its claim. Otherwise a delayed launch could win the claim while recursive deletion is in progress. A failed removal leaves the retired path available for a close retry.
Fence a pending launch or require explicit supervisor acknowledgement before teardown.
A stop that wins the launch claim writes the same receipt shape as the supervisor, with no return code because no harness process ran.
Fence delayed launches and run a harness command under the shared supervisor.
The supervisor needs only bash. Check that bash can parse it before claiming a launch: a failed bootstrap cannot write a cleanup receipt. Supervisor and harness diagnostics share output.log. The supervisor leaves the provider’s process group and stops the harness group, and after a forced stop the processes it reached; the sandbox owner stops services that left the harness earlier. Stops reach the supervisor through the stop file, not a signal, so the harness keeps the default TERM disposition.
Return the per-cleanup-phase and provider execution deadlines.
Divide the close budget across TERM grace, direct-process and group reaping. The provider deadline reserves all phases after the harness timeout, plus 30 seconds for startup, polling, and receipt I/O.