> This page is for version Main (default).
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# nemo_gym.agents.utils

Run harness processes inside task sandboxes under a shared supervisor.

The harness adapter installs its runtime, stages activation input, and parses
harness output. SandboxSession uploads the supervisor, runs and stops the harness
process, collects artifacts, and releases the sandbox. The supervisor client
implements the shell protocol over session control files. All three run on the
agent server.

Only process_supervisor.sh, harness_runner.sh and install_python_runtime.sh are copied
from this package into the task sandbox; they need bash, not Python. The supervisor
enforces deadlines, stops the harness process group and writes its termination receipt.
A forced stop also kills the harness's descendants in other groups and processes that
inherited its marker; processes that had left the harness before the stop, and detached
processes after a natural exit, remain for the sandbox owner to stop. Core sandbox APIs
and providers live in `nemo_gym.sandbox`.

## Submodules

* **[`nemo_gym.agents.utils.ordered_operations`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/ordered_operations)**
* **[`nemo_gym.agents.utils.sandbox_network`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/sandbox_network)**
* **[`nemo_gym.agents.utils.sandbox_observation`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/sandbox_observation)**
* **[`nemo_gym.agents.utils.sandbox_python`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/sandbox_python)**
* **[`nemo_gym.agents.utils.sandbox_session`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/sandbox_session)**
* **[`nemo_gym.agents.utils.supervisor_client`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/supervisor_client)**
* **[`nemo_gym.agents.utils.task_timeout`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/task_timeout)**
* **[`nemo_gym.agents.utils.verify_call`](/nemo/gym/nemo-gym/nemo_gym/agents/utils/verify_call)**

## Package Contents

### Functions

| Name                                                                                        | Description                                                                                       |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| [`lifecycle_observation`](#nemo_gym-agents-utils-sandbox_observation-lifecycle_observation) | The owner's observation of one created sandbox, or None when there is no AsyncSandbox to observe. |

### API

```python
nemo_gym.agents.utils.lifecycle_observation(
    sandbox: nemo_gym.sandbox.api.AsyncSandbox | None,
    role: typing.Literal['agent', 'verifier', 'environment']
) -> dict[str, typing.Any] | None
```

The owner's observation of one created sandbox, or None when there is no AsyncSandbox to observe.

`outcome` is `sandbox_error` only when every provider close failed; otherwise it stays `unknown`: a
confirmed teardown says nothing about the command or the grade. Cleanup failures stay listed after a retry,
with the first as `error_type`. Resource usage and remote lifetime are never estimated.