Skip to navigation

nemo_gym.agent_utils.process_supervisor

View as Markdown

Standalone Linux process supervisor to upload beside a sandboxed harness.

Uses only the standard library; Gym need not be installed in the task sandbox. The receipt confirms termination independently of the harness result. On forced stop, newly adopted children are also drained, including tools in other sessions. Detached services adopted before stopping remain for verification. Natural exit only drains the harness group: orphaned services and unfinished detached tools cannot be distinguished without cooperation from the harness.

Module Contents

Classes

NameDescription
CleanupReceiptOutcome after bounded harness termination.

Functions

NameDescription
_child_pidsRead this single-threaded subreaper’s current children.
_group_has_live_processes-
_positive_seconds-
_reap_process_groupDrain the group and, on forced stop, newly adopted tools within one budget.
_superviseStop the harness and forced-stop tools; preserve earlier detached services.
exec_timeoutReserve TERM grace, direct-process reaping, and process-group reaping.
mainRun COMMAND and atomically write its cleanup receipt outside the task workdir.

Data

CLEANUP_PHASE_COUNT

DEFAULT_CLEANUP_TIMEOUT

API

class nemo_gym.agent_utils.process_supervisor.CleanupReceipt

Bases: typing.TypedDict

Outcome after bounded harness termination.

cleanup_confirmed means no live harness-group members remain. Forced stops also drain newly adopted children. Previously adopted detached services remain until the owner closes the sandbox; this is not a sandbox-empty check.

cleanup_confirmed
bool
error
str | None
return_code
int | None
timed_out
bool
nemo_gym.agent_utils.process_supervisor._child_pids() -> set[int]

Read this single-threaded subreaper’s current children.

nemo_gym.agent_utils.process_supervisor._group_has_live_processes(
pgid: int
) -> bool
nemo_gym.agent_utils.process_supervisor._positive_seconds(
value: str
) -> float
nemo_gym.agent_utils.process_supervisor._reap_process_group(
pgid: int,
timeout: float,
preserved_children: set[int] | None = None
) -> None

Drain the group and, on forced stop, newly adopted tools within one budget.

nemo_gym.agent_utils.process_supervisor._supervise(
command: list[str],
timeout: float,
cleanup_timeout: float = DEFAULT_CLEANUP_TIMEOUT,
stop_path: pathlib.Path | None = None

Stop the harness and forced-stop tools; preserve earlier detached services.

nemo_gym.agent_utils.process_supervisor.exec_timeout(
timeout: float,
cleanup_timeout: float = DEFAULT_CLEANUP_TIMEOUT
) -> float

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.

nemo_gym.agent_utils.process_supervisor.main() -> int

Run COMMAND and atomically write its cleanup receipt outside the task workdir.

nemo_gym.agent_utils.process_supervisor.CLEANUP_PHASE_COUNT = 3
nemo_gym.agent_utils.process_supervisor.DEFAULT_CLEANUP_TIMEOUT = 10.0