Skip to content

Fix docs build failures - #8

Merged
bxyu-nvidia merged 9 commits into
mainfrom
bxyu/fix-docs-failures
Sep 5, 2025
Merged

Fix docs build failures#8
bxyu-nvidia merged 9 commits into
mainfrom
bxyu/fix-docs-failures

Conversation

@bxyu-nvidia

Copy link
Copy Markdown
Contributor

No description provided.

Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Brian Yu <bxyu@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 5, 2025

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.

@bxyu-nvidia

Copy link
Copy Markdown
Contributor Author

/ok to test 1484034

Signed-off-by: Brian Yu <bxyu@nvidia.com>
@bxyu-nvidia

Copy link
Copy Markdown
Contributor Author

/ok to test de995fc

@bxyu-nvidia
bxyu-nvidia merged commit a23ed37 into main Sep 5, 2025
5 checks passed
@bxyu-nvidia
bxyu-nvidia deleted the bxyu/fix-docs-failures branch September 5, 2025 21:07
kbhardwaj-nvidia pushed a commit that referenced this pull request Sep 5, 2025
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: Khushi Bhardwaj <kbhardwaj@nvidia.com>
soares-f pushed a commit that referenced this pull request Sep 8, 2025
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: soares-f <soarescmsa@gmail.com>
soares-f pushed a commit that referenced this pull request Sep 15, 2025
Signed-off-by: Brian Yu <bxyu@nvidia.com>
Signed-off-by: soares-f <soarescmsa@gmail.com>
abubakaria56 pushed a commit to abubakaria56/Gym that referenced this pull request Mar 2, 2026
Signed-off-by: Brian Yu <bxyu@nvidia.com>
abubakaria56 pushed a commit to abubakaria56/Gym that referenced this pull request Mar 2, 2026
Signed-off-by: Brian Yu <bxyu@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 16, 2026
Supersedes #1510; covers epic #1205 friction #8 + #12 and issues #1488,
#1489, #1490 in one place:

- #1488: missing config_paths entry -> ConfigPathNotFoundError (names entry +
  searched locations).
- #1490: malformed (non-list) config_paths -> MalformedConfigPathsError with
  the expected Hydra list syntax.
- #1489: zero configured servers -> NoServerInstancesError, raised in
  RunHelper.start() before Ray (covers ng_run AND e2e_rollout_collection).

All three subclass a new ConfigError base. A CLI decorator
(exit_cleanly_on_config_error) on run()/e2e_rollout_collection() turns any
ConfigError into a clean, rich-escaped message + exit 1 with NO traceback
(the explicit ask in #1488/#1489), while keeping them ordinary exceptions so
ng_validate (#1599) can still catch and format them. Zero-server check uses
validated server instances, not a raw key count.

Tests: deterministic tmp_path-based path-error tests (both-locations, dedup,
absolute), malformed-config_paths, zero-server, and the decorator
(ConfigError -> clean exit; non-ConfigError propagates).

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 17, 2026
Ports #1609 onto the unified gym CLI (#1434). Covers epic #1205 friction
#8 + #12 and issues #1488/#1489/#1490:

- #1488: missing config_paths entry -> ConfigPathNotFoundError
- #1490: malformed (non-list) config_paths -> MalformedConfigPathsError
- #1489: zero configured servers -> NoServerInstancesError, in RunHelper.start()
  before Ray (covers env run + eval run / e2e)

All subclass ConfigError; a cli/env.py decorator (exit_cleanly_on_config_error,
also applied to e2e_rollout_collection in cli/eval.py) turns them into a clean,
rich-escaped message + exit 1, no traceback. Targets martas/1434.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 17, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
Builds on the environment registry: --env resolves a name to its config via
resolve_environment_config_paths and merges it with any --config into a single
+config_paths, so an environment can be run by name instead of an internal path
(epic #1205 friction #8 / FEP-1022). Model flags pass through; an unknown name
exits cleanly with the registry's 'did you mean?' message. Pair --env with
--config / --model-* for the model the environment references.

env run becomes a callable router target (_env_run); config-only behavior is
unchanged.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 22, 2026
Add nemo_gym.suite_manager: a suite is a named list of environment names that
expands to the config_paths needed to run them together, so a multi-environment
sweep becomes a single --suite <name> instead of an 80+ entry config_paths.

- discover_suites(): built-in suites under nemo_gym/suites/ + user suites under
  ~/.config/nemo_gym/suites/ (user shadows built-in of the same name).
- resolve_suite_config_paths(): expands a suite to ordered, de-duplicated
  config_paths via the environment registry, with fast-fail on unknown suite
  (did-you-mean), empty suite, and unknown environment (annotated with the suite).

Resolution-safe (only reads configs, no interpolation/servers), mirroring the
registry. Built-in suites (ultra_v3/reasoning/coding) ship as the corresponding
environments are migrated into environments/; the CLI wiring (gym list suites,
gym run --suite) is deferred to align with the unified CLI.

Implements the M4 core (epic #1205, friction #8).

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 23, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Add nemo_gym.suite_manager: a suite is a named list of environment names that
expands to the config_paths needed to run them together, so a multi-environment
sweep becomes a single --suite <name> instead of an 80+ entry config_paths.

- discover_suites(): built-in suites under nemo_gym/suites/ + user suites under
  ~/.config/nemo_gym/suites/ (user shadows built-in of the same name).
- resolve_suite_config_paths(): expands a suite to ordered, de-duplicated
  config_paths via the environment registry, with fast-fail on unknown suite
  (did-you-mean), empty suite, and unknown environment (annotated with the suite).

Resolution-safe (only reads configs, no interpolation/servers), mirroring the
registry. Built-in suites (ultra_v3/reasoning/coding) ship as the corresponding
environments are migrated into environments/; the CLI wiring (gym list suites,
gym run --suite) is deferred to align with the unified CLI.

Implements the M4 core (epic #1205, friction #8).

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Builds on the environment registry: --env resolves a name to its config via
resolve_environment_config_paths and merges it with any --config into a single
+config_paths, so an environment can be run by name instead of an internal path
(epic #1205 friction #8 / FEP-1022). Model flags pass through; an unknown name
exits cleanly with the registry's 'did you mean?' message. Pair --env with
--config / --model-* for the model the environment references.

env run becomes a callable router target (_env_run); config-only behavior is
unchanged.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Add nemo_gym.suite_manager: a suite is a named list of environment names that
expands to the config_paths needed to run them together, so a multi-environment
sweep becomes a single --suite <name> instead of an 80+ entry config_paths.

- discover_suites(): built-in suites under nemo_gym/suites/ + user suites under
  ~/.config/nemo_gym/suites/ (user shadows built-in of the same name).
- resolve_suite_config_paths(): expands a suite to ordered, de-duplicated
  config_paths via the environment registry, with fast-fail on unknown suite
  (did-you-mean), empty suite, and unknown environment (annotated with the suite).

Resolution-safe (only reads configs, no interpolation/servers), mirroring the
registry. Built-in suites (ultra_v3/reasoning/coding) ship as the corresponding
environments are migrated into environments/; the CLI wiring (gym list suites,
gym run --suite) is deferred to align with the unified CLI.

Implements the M4 core (epic #1205, friction #8).

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Builds on the environment registry: --env resolves a name to its config via
resolve_environment_config_paths and merges it with any --config into a single
+config_paths, so an environment can be run by name instead of an internal path
(epic #1205 friction #8 / FEP-1022). Model flags pass through; an unknown name
exits cleanly with the registry's 'did you mean?' message. Pair --env with
--config / --model-* for the model the environment references.

env run becomes a callable router target (_env_run); config-only behavior is
unchanged.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Add nemo_gym.suite_manager: a suite is a named list of environment names that
expands to the config_paths needed to run them together, so a multi-environment
sweep becomes a single --suite <name> instead of an 80+ entry config_paths.

- discover_suites(): built-in suites under nemo_gym/suites/ + user suites under
  ~/.config/nemo_gym/suites/ (user shadows built-in of the same name).
- resolve_suite_config_paths(): expands a suite to ordered, de-duplicated
  config_paths via the environment registry, with fast-fail on unknown suite
  (did-you-mean), empty suite, and unknown environment (annotated with the suite).

Resolution-safe (only reads configs, no interpolation/servers), mirroring the
registry. Built-in suites (ultra_v3/reasoning/coding) ship as the corresponding
environments are migrated into environments/; the CLI wiring (gym list suites,
gym run --suite) is deferred to align with the unified CLI.

Implements the M4 core (epic #1205, friction #8).

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 24, 2026
Builds on the environment registry: --env resolves a name to its config via
resolve_environment_config_paths and merges it with any --config into a single
+config_paths, so an environment can be run by name instead of an internal path
(epic #1205 friction #8 / FEP-1022). Model flags pass through; an unknown name
exits cleanly with the registry's 'did you mean?' message. Pair --env with
--config / --model-* for the model the environment references.

env run becomes a callable router target (_env_run); config-only behavior is
unchanged.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 25, 2026
Ports #1609 onto the shared CLI base (martas/1434 + uv pin + concurrency).
Covers epic #1205 friction #8 + #12 and issues #1488/#1489/#1490:
ConfigPathNotFoundError, MalformedConfigPathsError, NoServerInstancesError
(all ConfigError); fail-fast guard in RunHelper.start(); exit_cleanly_on_config_error
decorator on run()/e2e_rollout_collection() -> clean message, no traceback.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 25, 2026
…hs (#1205 #8/#12; #1488/#1489/#1490) (#1609)

## What

One coherent fix for the three `config_paths` failure modes, all failing
fast with a **clean message and no traceback**:

| Issue | Bad input | Before | After |
|-------|-----------|--------|-------|
| [#1488](#1488) | typo'd /
missing path | 7-frame `FileNotFoundError` | `Error: config_paths entry
'...' was not found. Looked in: ...` |
| [#1490](#1490) | scalar
instead of list | raw Pydantic `ValidationError` (+pydantic.dev URL) |
`Error: 'config_paths' must be a list of paths ...` |
| [#1489](#1489) | empty /
omitted (zero servers) | Ray starts, hangs until SIGTERM | `Error: No
server instances are configured ...` before Ray |

## How

- New `ConfigError` base in `config_types.py`;
`ConfigPathNotFoundError`, `MalformedConfigPathsError`,
`NoServerInstancesError` (and the existing `ServerRefNotFoundError`)
inherit it. They stay ordinary exceptions, so `ng_validate` (#1599,
`except Exception`) can still catch and format them.
- `load_extra_config_paths` wraps `OmegaConf.load` (#1488); `parse()`
wraps `ta.validate_python` (#1490).
- `raise_on_no_server_instances` (validated server-instance check, not a
raw key count) runs in **`RunHelper.start()`** before `initialize_ray()`
— covers both run and `e2e_rollout_collection` (#1489).
- A CLI decorator `exit_cleanly_on_config_error` converts any
`ConfigError` to a rich-escaped message + `exit 1`, **no traceback**.
Unexpected errors still propagate unchanged.

## Supersedes #1510

Consolidates [#1510](#1510):
typed exceptions `ng_validate` can catch/format (a bare `SystemExit`
would escape it), a validated zero-server check, the guard in `start()`
so `e2e` is covered, and deterministic tests.

## Tests

`test_global_config.py`: path-not-found (both-locations / dedup /
absolute), malformed config_paths, zero-server (raise + pass).
`test_cli.py`: the decorator (ConfigError → clean exit; non-ConfigError
propagates unchanged; success passes through). 67/67
`test_global_config`+`test_cli` pass; ruff + pre-commit clean.

---------

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 25, 2026
…s/ by name

Epic #1205 friction #8 (FEP-1022) / RFC milestone M2 keystone. New
nemo_gym/registry.py:
- discover_environments(): map name -> EnvironmentEntry for every
  environments/<name>/config.yaml (name = dir), with best-effort description/
  domain read WITHOUT resolving interpolations/secrets.
- resolve_environment_config_paths(name): the run-by-name primitive — returns
  the env's config_paths, with a difflib 'did you mean?' on unknown names.

Self-contained config-layer module (no CLI/router changes); the foundation for
'gym list' enumerating environments and run-by-name. CLI wiring is a follow-up
to coordinate with the unified-CLI epic (#1434). 100% covered.

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
wprazuch added a commit that referenced this pull request Jun 25, 2026
… / M2) (#1635)

## What

The **M2 keystone** — discover environments by name from the CLI:

**1. `nemo_gym/registry.py` (new) — discovery only**
- `discover_environments()` → name → `EnvironmentEntry` for every
[`environments/<name>/config.yaml`](https://github.com/NVIDIA-NeMo/Gym/tree/main/environments)
(name = dir), with `description`/`domain` read **without resolving
interpolations/secrets** (a config referencing an unset key is still
discoverable — no crash).

**2. `gym list environments` (CLI wiring)**
- `list_environments()` in `cli/env.py` renders discovered environments
(name / domain / description) as a table, or `--json` for programmatic
use — matching `gym list benchmarks` / `gym list agents` (#1671).
Registered in the `gym` router; the `list` group is no longer
"benchmarks only".

```
$ gym list environments
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Environment         ┃ Domain ┃ Description                                   ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ workplace_assistant │ agent  │ Workplace assistant multi-step tool-using env │
└─────────────────────┴────────┴───────────────────────────────────────────────┘
$ gym list environments --json
[{"name": "workplace_assistant", "domain": "agent", "description": "..."}, ...]
```

## Why

Epic [#1205](#1205) friction 8.
Directly answers the reviewer asks for "`gym list` by environment name".
The `environments/` layout was live but unconsumed in code; this
surfaces it in the CLI.

## Alignment with the unified CLI (#1434)

Run-by-**name** for environments is already provided by the unified
CLI's generic **`--environment`** asset selector (on `gym env start` /
`gym eval run`, with `--search-dir` and `name/flavor` support). So this
registry is intentionally **discovery-only** — an earlier
`resolve_environment_config_paths` was removed as a duplicate of that
selector. `gym list environments` is the piece the asset selectors don't
provide.

## Tests

`test_registry.py` (discovery: name/metadata, missing dir, malformed
YAML tolerance, unset-secret tolerance, real-repo discovery) +
`test_cli.py` / `test_cli_main.py` (`list_environments` table / empty /
`--json` output + router dispatch incl. `--json`). Smoke-tested `gym
list environments [--json]` end-to-end. ruff + pre-commit clean.

---------

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
ritaneves pushed a commit that referenced this pull request Jun 25, 2026
…hs (#1205 #8/#12; #1488/#1489/#1490) (#1609)

## What

One coherent fix for the three `config_paths` failure modes, all failing
fast with a **clean message and no traceback**:

| Issue | Bad input | Before | After |
|-------|-----------|--------|-------|
| [#1488](#1488) | typo'd /
missing path | 7-frame `FileNotFoundError` | `Error: config_paths entry
'...' was not found. Looked in: ...` |
| [#1490](#1490) | scalar
instead of list | raw Pydantic `ValidationError` (+pydantic.dev URL) |
`Error: 'config_paths' must be a list of paths ...` |
| [#1489](#1489) | empty /
omitted (zero servers) | Ray starts, hangs until SIGTERM | `Error: No
server instances are configured ...` before Ray |

## How

- New `ConfigError` base in `config_types.py`;
`ConfigPathNotFoundError`, `MalformedConfigPathsError`,
`NoServerInstancesError` (and the existing `ServerRefNotFoundError`)
inherit it. They stay ordinary exceptions, so `ng_validate` (#1599,
`except Exception`) can still catch and format them.
- `load_extra_config_paths` wraps `OmegaConf.load` (#1488); `parse()`
wraps `ta.validate_python` (#1490).
- `raise_on_no_server_instances` (validated server-instance check, not a
raw key count) runs in **`RunHelper.start()`** before `initialize_ray()`
— covers both run and `e2e_rollout_collection` (#1489).
- A CLI decorator `exit_cleanly_on_config_error` converts any
`ConfigError` to a rich-escaped message + `exit 1`, **no traceback**.
Unexpected errors still propagate unchanged.

## Supersedes #1510

Consolidates [#1510](#1510):
typed exceptions `ng_validate` can catch/format (a bare `SystemExit`
would escape it), a validated zero-server check, the guard in `start()`
so `e2e` is covered, and deterministic tests.

## Tests

`test_global_config.py`: path-not-found (both-locations / dedup /
absolute), malformed config_paths, zero-server (raise + pass).
`test_cli.py`: the decorator (ConfigError → clean exit; non-ConfigError
propagates unchanged; success passes through). 67/67
`test_global_config`+`test_cli` pass; ruff + pre-commit clean.

---------

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
Signed-off-by: Rita Fernandes Neves <rfernandesne@nvidia.com>
ritaneves pushed a commit that referenced this pull request Jun 25, 2026
… / M2) (#1635)

## What

The **M2 keystone** — discover environments by name from the CLI:

**1. `nemo_gym/registry.py` (new) — discovery only**
- `discover_environments()` → name → `EnvironmentEntry` for every
[`environments/<name>/config.yaml`](https://github.com/NVIDIA-NeMo/Gym/tree/main/environments)
(name = dir), with `description`/`domain` read **without resolving
interpolations/secrets** (a config referencing an unset key is still
discoverable — no crash).

**2. `gym list environments` (CLI wiring)**
- `list_environments()` in `cli/env.py` renders discovered environments
(name / domain / description) as a table, or `--json` for programmatic
use — matching `gym list benchmarks` / `gym list agents` (#1671).
Registered in the `gym` router; the `list` group is no longer
"benchmarks only".

```
$ gym list environments
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Environment         ┃ Domain ┃ Description                                   ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ workplace_assistant │ agent  │ Workplace assistant multi-step tool-using env │
└─────────────────────┴────────┴───────────────────────────────────────────────┘
$ gym list environments --json
[{"name": "workplace_assistant", "domain": "agent", "description": "..."}, ...]
```

## Why

Epic [#1205](#1205) friction 8.
Directly answers the reviewer asks for "`gym list` by environment name".
The `environments/` layout was live but unconsumed in code; this
surfaces it in the CLI.

## Alignment with the unified CLI (#1434)

Run-by-**name** for environments is already provided by the unified
CLI's generic **`--environment`** asset selector (on `gym env start` /
`gym eval run`, with `--search-dir` and `name/flavor` support). So this
registry is intentionally **discovery-only** — an earlier
`resolve_environment_config_paths` was removed as a duplicate of that
selector. `gym list environments` is the piece the asset selectors don't
provide.

## Tests

`test_registry.py` (discovery: name/metadata, missing dir, malformed
YAML tolerance, unset-secret tolerance, real-repo discovery) +
`test_cli.py` / `test_cli_main.py` (`list_environments` table / empty /
`--json` output + router dispatch incl. `--json`). Smoke-tested `gym
list environments [--json]` end-to-end. ruff + pre-commit clean.

---------

Signed-off-by: Wojciech Prazuch <wprazuch@nvidia.com>
Signed-off-by: Rita Fernandes Neves <rfernandesne@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant