nemo_gym.discovery

View as Markdown

Shared component-discovery helpers: which roots to scan for a component, how to resolve name collisions across them, and how to read a component’s (domain, description).

Lives below the per-component registries (registry.py, benchmarks.py, agent_registry.py) so they can share it without depending on each other. Reads configs only; never starts servers.

Module Contents

Functions

NameDescription
_parse_no_environment_tolerating_unset_valuesparse_no_environment for listing: fill unset ??? and undefined ${...} values (runtime-only
_scan_servers_for_metadataBest-effort (domain, description) from a config mapping: the first of each found across all
discover_componentsRun dir_scanning_fn on subdir of every :func:component_search_roots root and merge the results.
iter_server_configsYield (group_key, server_name, server_config) for every server across all instances in a config.
merge_by_nameMerge per-root name -> entry mappings; earlier roots win on a collision (user shadows built-in),
read_config_metadataShared (domain, description) reader for an environment or benchmark config. Two passes, because

Data

_SERVER_GROUP_KEYS

_T

_UNSET_VALUE_PLACEHOLDER

API

nemo_gym.discovery._parse_no_environment_tolerating_unset_values(
initial_config_dict: omegaconf.DictConfig
) -> omegaconf.DictConfig

parse_no_environment for listing: fill unset ??? and undefined ${...} values (runtime-only things like API keys/endpoints) with a placeholder so the config still resolves enough to identify the component. Never mutates the input; errors other than those two propagate.

nemo_gym.discovery._scan_servers_for_metadata(
container
) -> typing.Tuple[typing.Optional[str], typing.Optional[str]]

Best-effort (domain, description) from a config mapping: the first of each found across all server groups. Never raises.

nemo_gym.discovery.discover_components(
subdir: str,
dir_scanning_fn: typing.Callable[[Path], typing.Dict[str, nemo_gym.discovery._T]]
) -> typing.Dict[str, nemo_gym.discovery._T]

Run dir_scanning_fn on subdir of every :func:component_search_roots root and merge the results.

The shared body of discover_environments/discover_agents/discover_models/ discover_benchmarks: each passes its <type>/ subdir and a single-directory scan function, and gets user-shadows-built-in merging (via :func:merge_by_name) for free.

nemo_gym.discovery.iter_server_configs(
container
)

Yield (group_key, server_name, server_config) for every server across all instances in a config.

Walks a loaded config mapping (each top-level instance -> its resources_servers/ responses_api_agents/responses_api_models group -> each server). Defensive against malformed shapes, so it never raises. The shared primitive behind metadata reads and the inspect deep-parse.

nemo_gym.discovery.merge_by_name(
per_root: typing.Iterable[typing.Dict[str, nemo_gym.discovery._T]]
) -> typing.Dict[str, nemo_gym.discovery._T]

Merge per-root name -> entry mappings; earlier roots win on a collision (user shadows built-in), matching :func:component_search_roots precedence. Insertion order preserved.

nemo_gym.discovery.read_config_metadata(
config_path: pathlib.Path
) -> typing.Tuple[typing.Optional[str], typing.Optional[str]]

Shared (domain, description) reader for an environment or benchmark config. Two passes, because the two declare metadata differently:

  1. Raw (non-resolving) scan — environment configs declare it inline, and this is safe even though they reference servers defined elsewhere (resolving in isolation would raise).
  2. Resolving fallback for whatever’s still unset — benchmark configs inherit it via config_paths/_inherit_from. Tolerates unset runtime values; on failure keeps the raw result.

Never raises: an unreadable/unresolvable config yields (None, None).

nemo_gym.discovery._SERVER_GROUP_KEYS = ('resources_servers', 'responses_api_agents', 'responses_api_models')
nemo_gym.discovery._T = TypeVar('_T')
nemo_gym.discovery._UNSET_VALUE_PLACEHOLDER = '__unset_for_listing__'