> 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.global_config

## Module Contents

### Classes

| Name                                                                                   | Description                                                               |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| [`GlobalConfigDictParser`](#nemo_gym-global_config-GlobalConfigDictParser)             | -                                                                         |
| [`GlobalConfigDictParserConfig`](#nemo_gym-global_config-GlobalConfigDictParserConfig) | -                                                                         |
| [`_AgentInstance`](#nemo_gym-global_config-_AgentInstance)                             | A top-level agent instance, with its single agent type already unwrapped. |

### Functions

| Name                                                                                                                     | Description                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`_apply_verbosity`](#nemo_gym-global_config-_apply_verbosity)                                                           | Set logging to DEBUG when `verbose` is in the config. Runs in the CLI process and, because the                                                        |
| [`_find_open_port_using_range`](#nemo_gym-global_config-_find_open_port_using_range)                                     | -                                                                                                                                                     |
| [`_load_config_yaml`](#nemo_gym-global_config-_load_config_yaml)                                                         | `OmegaConf.load`, converting a YAML syntax error into a clean `ConfigError` naming file + line/column.                                                |
| [`_nemo_gym_openai_requirement`](#nemo_gym-global_config-_nemo_gym_openai_requirement)                                   | Return nemo-gym's own openai requirement string (name plus specifier, as declared in its metadata).                                                   |
| [`_openai_version_matches_nemo_gym_constraint`](#nemo_gym-global_config-_openai_version_matches_nemo_gym_constraint)     | True when `version` satisfies nemo-gym's own openai requirement.                                                                                      |
| [`agents_by_resources_server`](#nemo_gym-global_config-agents_by_resources_server)                                       | Invert the agent -> resources\_server edges of a merged config.                                                                                       |
| [`agents_without_environment_server_deprecation`](#nemo_gym-global_config-agents_without_environment_server_deprecation) | Explain the deprecation and how to migrate, with the exact config to add for each agent.                                                              |
| [`allowed_agents_for`](#nemo_gym-global_config-allowed_agents_for)                                                       | The agent types `resources_server_name` declares support for, or None when it declares none.                                                          |
| [`allowed_model_types_for`](#nemo_gym-global_config-allowed_model_types_for)                                             | The model adapter types `resources_server_name` declares support for, or None when unrestricted.                                                      |
| [`dataset_agent_pins`](#nemo_gym-global_config-dataset_agent_pins)                                                       | Distinct dataset-level `agent:` pins declared by one server instance, in declaration order.                                                           |
| [`find_open_port`](#nemo_gym-global_config-find_open_port)                                                               | -                                                                                                                                                     |
| [`format_almost_server_warning`](#nemo_gym-global_config-format_almost_server_warning)                                   | Format user-friendly warning. Union literal errors are consolidated.                                                                                  |
| [`get_first_server_config_dict`](#nemo_gym-global_config-get_first_server_config_dict)                                   | -                                                                                                                                                     |
| [`get_global_config_dict`](#nemo_gym-global_config-get_global_config_dict)                                               | This function provides a handle to the global configuration dict `global_config_dict`. We try to have one source of truth for everything in NeMo gym. |
| [`get_hf_token`](#nemo_gym-global_config-get_hf_token)                                                                   | -                                                                                                                                                     |
| [`label_runs`](#nemo_gym-global_config-label_runs)                                                                       | Label each run key by its agent's name when that name identifies exactly one run, else by the key.                                                    |
| [`legacy_environment_server_block`](#nemo_gym-global_config-legacy_environment_server_block)                             | The legacy\_agent environment server config that relays to one agent.                                                                                 |
| [`legacy_environment_server_name`](#nemo_gym-global_config-legacy_environment_server_name)                               | Name an agent's legacy\_agent relay after its environment, as the migration script does.                                                              |
| [`maybe_get_global_config_dict`](#nemo_gym-global_config-maybe_get_global_config_dict)                                   | The global config dict when this process already has one; never triggers a CLI parse.                                                                 |
| [`model_type_for`](#nemo_gym-global_config-model_type_for)                                                               | The single model adapter type hosted by `model_server_name`, or None when it cannot be determined.                                                    |
| [`pairing_override_enabled`](#nemo_gym-global_config-pairing_override_enabled)                                           | True when a declared agent/model compatibility guard has been explicitly waived.                                                                      |
| [`resolve_dataset_agent`](#nemo_gym-global_config-resolve_dataset_agent)                                                 | Resolve the agent that runs a dataset declared by `declaring_instance_name`.                                                                          |
| [`rollout_agent_label`](#nemo_gym-global_config-rollout_agent_label)                                                     | Name the agent that acted in one rollout, for per-rollout output such as trajectories and debug lines.                                                |
| [`rollout_run_key`](#nemo_gym-global_config-rollout_run_key)                                                             | Identify what ran a rollout, for grouping: its Environment Server.                                                                                    |
| [`rollout_run_labels`](#nemo_gym-global_config-rollout_run_labels)                                                       | Label each `rollout_run_key` for reports, the same way rollout collection labels aggregate metrics.                                                   |
| [`set_global_config_dict`](#nemo_gym-global_config-set_global_config_dict)                                               | -                                                                                                                                                     |
| [`translate_interpolation_error`](#nemo_gym-global_config-translate_interpolation_error)                                 | Same class of user error as an unset '???' (see raise\_on\_missing\_values), reported the same way                                                    |

### Data

[`AGENT_REF_KEY_NAME`](#nemo_gym-global_config-AGENT_REF_KEY_NAME)

[`AGENT_SERVER_REF_KEY_NAME`](#nemo_gym-global_config-AGENT_SERVER_REF_KEY_NAME)

[`AGENT_SERVER_TYPE_KEY_NAME`](#nemo_gym-global_config-AGENT_SERVER_TYPE_KEY_NAME)

[`ALLOWED_AGENTS_KEY_NAME`](#nemo_gym-global_config-ALLOWED_AGENTS_KEY_NAME)

[`ALLOWED_MODEL_TYPES_KEY_NAME`](#nemo_gym-global_config-ALLOWED_MODEL_TYPES_KEY_NAME)

[`ALLOW_OPENAI_VERSION_SKEW_KEY_NAME`](#nemo_gym-global_config-ALLOW_OPENAI_VERSION_SKEW_KEY_NAME)

[`ALLOW_UNSUPPORTED_PAIRING_ENV_VAR_NAME`](#nemo_gym-global_config-ALLOW_UNSUPPORTED_PAIRING_ENV_VAR_NAME)

[`ALLOW_UNSUPPORTED_PAIRING_KEY_NAME`](#nemo_gym-global_config-ALLOW_UNSUPPORTED_PAIRING_KEY_NAME)

[`ATTEMPT_INDEX_KEY_NAME`](#nemo_gym-global_config-ATTEMPT_INDEX_KEY_NAME)

[`CACHE_DIR_KEY_NAME`](#nemo_gym-global_config-CACHE_DIR_KEY_NAME)

[`COMPONENT_NAME_KEY_NAME`](#nemo_gym-global_config-COMPONENT_NAME_KEY_NAME)

[`CONFIG_PATHS_KEY_NAME`](#nemo_gym-global_config-CONFIG_PATHS_KEY_NAME)

[`COPY_KEY_NAME`](#nemo_gym-global_config-COPY_KEY_NAME)

[`DEFAULT_HEAD_SERVER_PORT`](#nemo_gym-global_config-DEFAULT_HEAD_SERVER_PORT)

[`DEFAULT_HOST_KEY_NAME`](#nemo_gym-global_config-DEFAULT_HOST_KEY_NAME)

[`DELETE_KEY_KEY_NAME`](#nemo_gym-global_config-DELETE_KEY_KEY_NAME)

[`DISALLOWED_PORTS_KEY_NAME`](#nemo_gym-global_config-DISALLOWED_PORTS_KEY_NAME)

[`DRY_RUN_KEY_NAME`](#nemo_gym-global_config-DRY_RUN_KEY_NAME)

[`ENTRYPOINT_KEY_NAME`](#nemo_gym-global_config-ENTRYPOINT_KEY_NAME)

[`ENVIRONMENT_ROUTING_MODE_KEY_NAME`](#nemo_gym-global_config-ENVIRONMENT_ROUTING_MODE_KEY_NAME)

[`ENVIRONMENT_SERVER_NAME_KEY_NAME`](#nemo_gym-global_config-ENVIRONMENT_SERVER_NAME_KEY_NAME)

[`ENVIRONMENT_SERVER_ROUTES_KEY_NAME`](#nemo_gym-global_config-ENVIRONMENT_SERVER_ROUTES_KEY_NAME)

[`ENVIRONMENT_SERVER_STAMP_KEY_NAME`](#nemo_gym-global_config-ENVIRONMENT_SERVER_STAMP_KEY_NAME)

[`ENVIRONMENT_SERVER_TYPE_KEY_NAME`](#nemo_gym-global_config-ENVIRONMENT_SERVER_TYPE_KEY_NAME)

[`ERROR_ON_AGENT_WITHOUT_ENVIRONMENT_SERVER_KEY_NAME`](#nemo_gym-global_config-ERROR_ON_AGENT_WITHOUT_ENVIRONMENT_SERVER_KEY_NAME)

[`EXPECTED_NUM_ROLLOUTS_KEY_NAME`](#nemo_gym-global_config-EXPECTED_NUM_ROLLOUTS_KEY_NAME)

[`HEAD_SERVER_DEPS_KEY_NAME`](#nemo_gym-global_config-HEAD_SERVER_DEPS_KEY_NAME)

[`HEAD_SERVER_KEY_NAME`](#nemo_gym-global_config-HEAD_SERVER_KEY_NAME)

[`HF_TOKEN_KEY_NAME`](#nemo_gym-global_config-HF_TOKEN_KEY_NAME)

[`INHERIT_FROM_KEY_NAME`](#nemo_gym-global_config-INHERIT_FROM_KEY_NAME)

[`JSON_OUTPUT_KEY_NAME`](#nemo_gym-global_config-JSON_OUTPUT_KEY_NAME)

[`LEGACY_ENVIRONMENT_SERVER_SUFFIX`](#nemo_gym-global_config-LEGACY_ENVIRONMENT_SERVER_SUFFIX)

[`MISSING_NUM_ROLLOUTS_KEY_NAME`](#nemo_gym-global_config-MISSING_NUM_ROLLOUTS_KEY_NAME)

[`MODEL_CALL_CAPTURE_DIR_KEY_NAME`](#nemo_gym-global_config-MODEL_CALL_CAPTURE_DIR_KEY_NAME)

[`MODEL_ENDPOINT_READINESS_TIMEOUT_KEY_NAME`](#nemo_gym-global_config-MODEL_ENDPOINT_READINESS_TIMEOUT_KEY_NAME)

[`MODEL_SERVER_TYPE_KEY_NAME`](#nemo_gym-global_config-MODEL_SERVER_TYPE_KEY_NAME)

[`NEMO_GYM_CONFIG_DICT_ENV_VAR_NAME`](#nemo_gym-global_config-NEMO_GYM_CONFIG_DICT_ENV_VAR_NAME)

[`NEMO_GYM_CONFIG_PATH_ENV_VAR_NAME`](#nemo_gym-global_config-NEMO_GYM_CONFIG_PATH_ENV_VAR_NAME)

[`NEMO_GYM_LOG_DIR_KEY_NAME`](#nemo_gym-global_config-NEMO_GYM_LOG_DIR_KEY_NAME)

[`NEMO_GYM_RESERVED_TOP_LEVEL_KEYS`](#nemo_gym-global_config-NEMO_GYM_RESERVED_TOP_LEVEL_KEYS)

[`NUM_ROLLOUTS_KEY_NAME`](#nemo_gym-global_config-NUM_ROLLOUTS_KEY_NAME)

[`OBSERVABILITY_ENABLED_KEY_NAME`](#nemo_gym-global_config-OBSERVABILITY_ENABLED_KEY_NAME)

[`PIP_INSTALL_VERBOSE_KEY_NAME`](#nemo_gym-global_config-PIP_INSTALL_VERBOSE_KEY_NAME)

[`POLICY_API_KEY_KEY_NAME`](#nemo_gym-global_config-POLICY_API_KEY_KEY_NAME)

[`POLICY_BASE_URL_KEY_NAME`](#nemo_gym-global_config-POLICY_BASE_URL_KEY_NAME)

[`POLICY_MODEL_KEY_NAME`](#nemo_gym-global_config-POLICY_MODEL_KEY_NAME)

[`POLICY_MODEL_NAME_KEY_NAME`](#nemo_gym-global_config-POLICY_MODEL_NAME_KEY_NAME)

[`PORT_RANGE_HIGH_KEY_NAME`](#nemo_gym-global_config-PORT_RANGE_HIGH_KEY_NAME)

[`PORT_RANGE_LOW_KEY_NAME`](#nemo_gym-global_config-PORT_RANGE_LOW_KEY_NAME)

[`PYTHON_VERSION_KEY_NAME`](#nemo_gym-global_config-PYTHON_VERSION_KEY_NAME)

[`QUERY_KEY_NAME`](#nemo_gym-global_config-QUERY_KEY_NAME)

[`RAY_HEAD_NODE_ADDRESS_KEY_NAME`](#nemo_gym-global_config-RAY_HEAD_NODE_ADDRESS_KEY_NAME)

[`RESOURCES_SERVER_TYPE_KEY_NAME`](#nemo_gym-global_config-RESOURCES_SERVER_TYPE_KEY_NAME)

[`RESPONSES_CREATE_PARAMS_KEY_NAME`](#nemo_gym-global_config-RESPONSES_CREATE_PARAMS_KEY_NAME)

[`RESPONSE_KEY_NAME`](#nemo_gym-global_config-RESPONSE_KEY_NAME)

[`RESULTS_DIR_KEY_NAME`](#nemo_gym-global_config-RESULTS_DIR_KEY_NAME)

[`REWARD_KEY_NAME`](#nemo_gym-global_config-REWARD_KEY_NAME)

[`ROLLOUT_ID_KEY_NAME`](#nemo_gym-global_config-ROLLOUT_ID_KEY_NAME)

[`ROLLOUT_INDEX_KEY_NAME`](#nemo_gym-global_config-ROLLOUT_INDEX_KEY_NAME)

[`ROLLOUT_INFOS_KEY_NAME`](#nemo_gym-global_config-ROLLOUT_INFOS_KEY_NAME)

[`SERVER_SPINUP_TIMEOUT_SECONDS_KEY_NAME`](#nemo_gym-global_config-SERVER_SPINUP_TIMEOUT_SECONDS_KEY_NAME)

[`SKILLS_REF_KEY_NAME`](#nemo_gym-global_config-SKILLS_REF_KEY_NAME)

[`SKIP_VENV_IF_PRESENT_KEY_NAME`](#nemo_gym-global_config-SKIP_VENV_IF_PRESENT_KEY_NAME)

[`SKIP_VERIFICATION_KEY_NAME`](#nemo_gym-global_config-SKIP_VERIFICATION_KEY_NAME)

[`SKIP_VERIFICATION_REWARD_KEY_NAME`](#nemo_gym-global_config-SKIP_VERIFICATION_REWARD_KEY_NAME)

[`TASK_INDEX_KEY_NAME`](#nemo_gym-global_config-TASK_INDEX_KEY_NAME)

[`TASK_SOURCE_KEY_NAME`](#nemo_gym-global_config-TASK_SOURCE_KEY_NAME)

[`TOKEN_ID_CAPTURE_BLOCK`](#nemo_gym-global_config-TOKEN_ID_CAPTURE_BLOCK)

[`USE_ABSOLUTE_IP`](#nemo_gym-global_config-USE_ABSOLUTE_IP)

[`UVICORN_TIMEOUT_WORKER_HEALTHCHECK`](#nemo_gym-global_config-UVICORN_TIMEOUT_WORKER_HEALTHCHECK)

[`UV_CACHE_DIR_KEY_NAME`](#nemo_gym-global_config-UV_CACHE_DIR_KEY_NAME)

[`UV_LOCK_TIMEOUT_KEY_NAME`](#nemo_gym-global_config-UV_LOCK_TIMEOUT_KEY_NAME)

[`UV_PIP_SET_PYTHON_KEY_NAME`](#nemo_gym-global_config-UV_PIP_SET_PYTHON_KEY_NAME)

[`UV_VENV_DIR_KEY_NAME`](#nemo_gym-global_config-UV_VENV_DIR_KEY_NAME)

[`VERBOSE_KEY_NAME`](#nemo_gym-global_config-VERBOSE_KEY_NAME)

[`_COMPOSED_AGENT_CARRY_OVER_KEYS`](#nemo_gym-global_config-_COMPOSED_AGENT_CARRY_OVER_KEYS)

[`_GLOBAL_CONFIG_DICT`](#nemo_gym-global_config-_GLOBAL_CONFIG_DICT)

[`_MISSING_REF`](#nemo_gym-global_config-_MISSING_REF)

[`logger`](#nemo_gym-global_config-logger)

[`ray_version`](#nemo_gym-global_config-ray_version)

### API

```python
class nemo_gym.global_config.GlobalConfigDictParser()
```

**Bases:** `BaseModel`

```python
nemo_gym.global_config.GlobalConfigDictParser._agent_instances(
    global_config_dict: omegaconf.DictConfig
) -> typing.List[nemo_gym.global_config._AgentInstance]
```

Return every top-level agent instance in the config.

```python
nemo_gym.global_config.GlobalConfigDictParser._apply_held_agent_override(
    held_agent_overrides: typing.Optional[omegaconf.DictConfig],
    name: str,
    agent_type: str,
    composed: omegaconf.DictConfig
) -> None
```

staticmethod

Merge the override held for `name` onto the composed agent, in place, after the bindings.

```python
nemo_gym.global_config.GlobalConfigDictParser._carry_over_agent_bindings(
    original: omegaconf.DictConfig,
    composed: omegaconf.DictConfig
) -> None
```

staticmethod

Move the environment's bindings onto the composed agent config, in place.

A binding left explicitly unset is carried over still unset, so it is reported rather than
silently resolving to whatever the incoming agent happens to declare. It needs its own branch
because OmegaConf reports a '???' value as absent.

```python
nemo_gym.global_config.GlobalConfigDictParser._composed_instance_name(
    target: nemo_gym.global_config._AgentInstance,
    agent_type: str
) -> str
```

staticmethod

Rename the instance after swapping the agent.

Substituting the trailing agent type keeps the environment prefix that makes the name readable
(`gpqa_mcqa_simple_agent` -> `gpqa_mcqa_hermes_agent`); names not ending in their agent type just
gain the suffix. Safe because routing resolves `task_source` through the resources server edge,
not through this name.

```python
nemo_gym.global_config.GlobalConfigDictParser._composed_instance_names(
    config_dict: omegaconf.DictConfig
) -> set
```

The instance names composition will produce, worked out before it runs.

```python
nemo_gym.global_config.GlobalConfigDictParser._front_agents_without_environment_server(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Give every agent an environment server, since rollout collection reaches agents only through one.

Runs after composition, so every agent left is one a run can dispatch to.
An agent that no environment server names gets a generated `legacy_agent` relay.
The relay is the same block that scripts/add\_legacy\_agent\_environment\_servers.py declares.
One deprecation warning lists every generated relay and how to declare it.
This keeps configs written before environment servers running.
With `error_on_agent_without_environment_server` set, such an agent is an error instead.

Only agents with no environment server are touched.
A generated relay therefore never makes an agent's routing ambiguous, and no existing reference is rewritten.

```python
nemo_gym.global_config.GlobalConfigDictParser._hold_back_composed_agent_overrides(
    cli_global_config_dict: omegaconf.DictConfig,
    config_dict: omegaconf.DictConfig
) -> omegaconf.DictConfig
```

Take command line overrides naming an instance composition is about to create out of the dict.

That instance does not exist yet, so merging them now would build a partial server beside it.
Returned to be applied to the composed agent instead.

```python
nemo_gym.global_config.GlobalConfigDictParser._is_unbound_agent(
    server_config: omegaconf.DictConfig
) -> bool
```

True when the agent declares a `resources_server` but leaves its name unset, marking it a swap source.

```python
nemo_gym.global_config.GlobalConfigDictParser._model_server_reference(
    server_config: omegaconf.DictConfig
) -> typing.Optional[omegaconf.DictConfig]
```

staticmethod

The agent's `model_server` block, or None when it declares none.

```python
nemo_gym.global_config.GlobalConfigDictParser._raise_on_name_collision(
    global_config_dict: omegaconf.DictConfig,
    renames: dict,
    source_name: str
) -> None
```

staticmethod

```python
nemo_gym.global_config.GlobalConfigDictParser._raise_on_outdated_routing(
    global_config_dict: omegaconf.DictConfig,
    renames: typing.Dict[str, str]
) -> None
```

staticmethod

Reject routing that sends rows to an instance the swap renamed away.

Destinations name a server that has to exist: `agent_name`, `agent_map` values and `fan_out`
entries. Their keys are matching bases read off the data, so those may name the old instance.

```python
nemo_gym.global_config.GlobalConfigDictParser._raise_on_unapplied_agent_overrides(
    held_agent_overrides: typing.Optional[omegaconf.DictConfig],
    composed_names: set
) -> None
```

staticmethod

Report held overrides that named an instance composition did not produce.

```python
nemo_gym.global_config.GlobalConfigDictParser._raise_on_unsupported_pairing(
    global_config_dict: omegaconf.DictConfig,
    source: nemo_gym.global_config._AgentInstance,
    targets: typing.List[nemo_gym.global_config._AgentInstance]
) -> None
```

Reject swapping `source` onto any target whose resources server does not declare support for it.

Compatibility is declared verifier-side because that is where it is known: an environment's author
knows which harnesses score their task correctly, while a generic harness cannot know that for every
environment. A server that declares nothing accepts any harness.

```python
nemo_gym.global_config.GlobalConfigDictParser._recursive_index_dict_using_path(
    dict_config: omegaconf.DictConfig,
    path: typing.List[str]
) -> omegaconf.DictConfig | object
```

```python
nemo_gym.global_config.GlobalConfigDictParser._recursively_swap_keys(
    dict_config: omegaconf.DictConfig
) -> None
```

```python
nemo_gym.global_config.GlobalConfigDictParser._recursively_swap_keys_helper(
    dict_config: omegaconf.DictConfig,
    original_dict_config: omegaconf.DictConfig,
    frozen_dict_config: omegaconf.DictConfig
) -> None
```

```python
nemo_gym.global_config.GlobalConfigDictParser._resources_server_reference(
    server_config: omegaconf.DictConfig
) -> typing.Optional[omegaconf.DictConfig]
```

staticmethod

The agent's `resources_server` block, or None when it declares none.

Selected rather than indexed because a self-contained agent omits the key, which a struct-mode
config rejects outright.

```python
nemo_gym.global_config.GlobalConfigDictParser._retarget_environment_servers(
    global_config_dict: omegaconf.DictConfig,
    renames: dict[str, str]
) -> None
```

staticmethod

Point each environment server at the agent composition put in place of the one it named.

The server is named after the environment, not the agent, so a swap leaves its own name
alone and only its `agent_server` reference has to follow.

```python
nemo_gym.global_config.GlobalConfigDictParser._route_rows_stamped_before_the_swap(
    global_config_dict: omegaconf.DictConfig,
    renames: typing.Dict[str, str]
) -> None
```

staticmethod

Map the pre-swap instance name onto the composed one, for rows stamped before it happened.

Only a matching base is added, so a route the user declared still wins.

```python
nemo_gym.global_config.GlobalConfigDictParser._runs_against_a_resources_server(
    server_config: omegaconf.DictConfig
) -> bool
```

True when the agent has a task to hand over, so another agent can take its place.

Self-contained agents own their environment and declare no `resources_server`; swapping one out
would leave the incoming agent with nothing to bind to.

```python
nemo_gym.global_config.GlobalConfigDictParser._walk_missing_value_paths(
    node,
    prefix: str = ''
) -> typing.List[str]
```

```python
nemo_gym.global_config.GlobalConfigDictParser.apply_legacy_agent_aliases(
    global_config_dict: omegaconf.DictConfig
) -> None
```

staticmethod

Route legacy reasoning-gym agent names to their canonical instances.

```python
nemo_gym.global_config.GlobalConfigDictParser.collect_missing_value_paths(
    config: omegaconf.DictConfig
) -> typing.List[str]
```

Return the dotted paths of every unset (OmegaConf '???') leaf, without raising.

We convert to a plain container with `resolve=False, throw_on_missing=False` so that
neither MISSING values nor unresolved interpolations (`$&#123;...&#125;`) cause an exception — then
walk the plain structure. Iterating or indexing the live DictConfig would raise.

```python
nemo_gym.global_config.GlobalConfigDictParser.compose_unbound_agent(
    global_config_dict: omegaconf.DictConfig,
    held_agent_overrides: typing.Optional[omegaconf.DictConfig] = None
) -> None
```

Rehost every other agent instance on the config's unbound agent, then drop that agent.

`held_agent_overrides` are command line overrides keyed by the name each instance is renamed to.

```python
nemo_gym.global_config.GlobalConfigDictParser.detect_and_report_almost_servers(
    global_config_dict: omegaconf.DictConfig
) -> typing.List[typing.Tuple[str, pydantic.ValidationError]]
```

```python
nemo_gym.global_config.GlobalConfigDictParser.filter_for_server_instance_configs(
    global_config_dict: omegaconf.DictConfig
) -> typing.List[nemo_gym.config_types.ServerInstanceConfig]
```

```python
nemo_gym.global_config.GlobalConfigDictParser.load_extra_config_paths(
    config_paths: typing.List[str]
) -> typing.Tuple[typing.List[str], typing.List[omegaconf.DictConfig]]
```

Returns the new total config\_paths and the extra configs, ordered for merging.

Two rules decide precedence:

* A config named in another config's `config_paths` is *inner*. The config
  that pulled it in overrides it, however deep the nesting goes.
* Configs listed together are siblings, in the order they were listed. A later
  sibling overrides an earlier one, and so does everything it pulled in.

The returned configs are ordered so that a left-to-right `OmegaConf.merge`
produces both rules: the include tree flattened so that a config follows
everything it pulled in, with each subtree kept contiguous.

```python
nemo_gym.global_config.GlobalConfigDictParser.parse(
    parse_config: typing.Optional[nemo_gym.global_config.GlobalConfigDictParserConfig] = None
) -> omegaconf.DictConfig
```

```python
nemo_gym.global_config.GlobalConfigDictParser.parse_global_config_dict_from_cli() -> omegaconf.DictConfig
```

```python
nemo_gym.global_config.GlobalConfigDictParser.parse_no_environment(
    initial_global_config_dict: typing.Optional[omegaconf.DictConfig] = None
) -> omegaconf.DictConfig
```

```python
nemo_gym.global_config.GlobalConfigDictParser.raise_on_missing_values(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Fail fast with one actionable error listing every unset '???' value.

Without this, the first unset value surfaces deep in the run pipeline as an opaque
omegaconf MissingMandatoryValue, one field at a time and with no override guidance.

```python
nemo_gym.global_config.GlobalConfigDictParser.raise_on_no_server_instances(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Fail fast if a run has no server instances to start.

Without this, `gym env start` with an empty/omitted `config_paths` starts the head server and Ray
and then hangs with nothing to run. We catch it before Ray initialises with an actionable
message instead.

```python
nemo_gym.global_config.GlobalConfigDictParser.raise_on_unsupported_model_pairings(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Reject resource/model bindings that explicitly disallow the selected model adapter.

This runs while parsing the merged config, before Ray or any server subprocess starts. A resources
server opts in with `allowed_model_types`; existing configs that do not declare it stay unrestricted.

```python
nemo_gym.global_config.GlobalConfigDictParser.validate_and_populate_defaults(
    server_instance_configs: typing.List[nemo_gym.config_types.ServerInstanceConfig],
    default_host: str,
    port_range_low: int,
    port_range_high: int,
    initial_disallowed_ports: typing.Optional[typing.List[int]] = None,
    skip_verification: typing.Optional[bool] = None,
    skip_verification_reward: typing.Optional[float] = None,
    probe_ports: bool = True
) -> typing.List[int]
```

```python
class nemo_gym.global_config.GlobalConfigDictParserConfig()
```

**Bases:** `BaseModel`

**`NO_MODEL_GLOBAL_CONFIG_DICT`** `DictConfig`

---

**`dotenv_path`** `Optional[Path] = None`

---

**`hide_secrets`** `bool = False`

---

**`initial_global_config_dict`** `Optional[DictConfig] = None`

---

**`model_config`** `= ConfigDict(arbitrary_types_allowed=True)`

---

**`offline`** `bool = False`

---

**`skip_load_from_cli`** `bool = False`

---

**`skip_load_from_dotenv`** `bool = False`

---

```python
class nemo_gym.global_config._AgentInstance(
    name: str,
    agent_type: str,
    server_config: omegaconf.DictConfig
)
```

Dataclass

A top-level agent instance, with its single agent type already unwrapped.

**`agent_type`** `str`

---

**`name`** `str`

---

**`server_config`** `DictConfig`

---

```python
nemo_gym.global_config._apply_verbosity(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Set logging to DEBUG when `verbose` is in the config. Runs in the CLI process and, because the
config dict is forwarded to every spun-up server, in each server process too.

```python
nemo_gym.global_config._find_open_port_using_range(
    disallowed_ports: typing.List[int],
    port_range_low: int,
    port_range_high: int,
    max_retries: int = 50
) -> int
```

```python
nemo_gym.global_config._load_config_yaml(
    config_path
)
```

`OmegaConf.load`, converting a YAML syntax error into a clean `ConfigError` naming file + line/column.

`FileNotFoundError` is left to propagate so callers can report a missing-path error themselves.

```python
nemo_gym.global_config._nemo_gym_openai_requirement() -> typing.Optional[str]
```

Return nemo-gym's own openai requirement string (name plus specifier, as declared in its metadata).

Returns `None` when the requirement cannot be determined (nemo-gym not
installed as a distribution, `packaging` unavailable, only marker'd
requirements found).

```python
nemo_gym.global_config._openai_version_matches_nemo_gym_constraint(
    version: str
) -> bool
```

True when `version` satisfies nemo-gym's own openai requirement.

head\_server\_deps normally pins the parent process's openai version into every
sub-venv for consistency. When the parent environment ships an openai release
outside nemo-gym's own constraint (e.g. the base image preinstalls a newer
openai than nemo-gym's cap allows), that pin makes every
sub-venv resolution unsatisfiable — and the dry-run prefetch then bakes
venvs that contain nothing but pip. The parser uses this to fail fast (or,
with the explicit opt-in, to fall back to nemo-gym's own resolution) instead
of emitting an impossible pin. Returns True (preserving the original
pin-the-parent behavior) when the constraint cannot be determined.

```python
nemo_gym.global_config.agents_by_resources_server(
    global_config_dict: omegaconf.DictConfig
) -> typing.Dict[str, typing.List[str]]
```

Invert the agent -> resources\_server edges of a merged config.

Returns \{resources server instance name: \[agent instance names referencing it]}. This is the
lookup that routes task\_source-stamped rows to an agent (and, transitionally, lets collate
dual-stamp a legacy agent\_ref). Template placeholders (`name: ???`) and malformed blocks are
skipped: they are not routable candidates.

```python
nemo_gym.global_config.agents_without_environment_server_deprecation(
    generated: typing.Mapping[str, str]
) -> str
```

Explain the deprecation and how to migrate, with the exact config to add for each agent.

```python
nemo_gym.global_config.allowed_agents_for(
    global_config_dict: omegaconf.DictConfig,
    resources_server_name: typing.Optional[str]
) -> typing.Optional[typing.List[str]]
```

The agent types `resources_server_name` declares support for, or None when it declares none.

A bare string is accepted as a single entry: an `++...allowed_agents=name` override arrives before the
server model is validated, and iterating it would read the name as its characters.

```python
nemo_gym.global_config.allowed_model_types_for(
    global_config_dict: omegaconf.DictConfig,
    resources_server_name: typing.Optional[str]
) -> typing.Optional[typing.List[str]]
```

The model adapter types `resources_server_name` declares support for, or None when unrestricted.

```python
nemo_gym.global_config.dataset_agent_pins(
    global_config_dict: omegaconf.DictConfig,
    instance_name: str
) -> typing.List[str]
```

Distinct dataset-level `agent:` pins declared by one server instance, in declaration order.

```python
nemo_gym.global_config.find_open_port(
    disallowed_ports: typing.Optional[typing.List[int]] = None,
    max_retries: int = 50
) -> int
```

```python
nemo_gym.global_config.format_almost_server_warning(
    server_name: str,
    error: pydantic.ValidationError
) -> str
```

Format user-friendly warning. Union literal errors are consolidated.
Union discriminator noise is filtered out. Explanation:
Pydantic validation is quirky- it will report all failures in the union if any union member fails. Example:
If an agent server contains an invalid license, it will not only show the error for the invalid license in ResponsesAPIAgentServerInstanceConfig, but also missing values for ResponsesAPIModelServerInstanceConfig `responses_api_models` and ResourcesServerInstanceConfig `resources_servers`.

```python
nemo_gym.global_config.get_first_server_config_dict(
    global_config_dict: omegaconf.DictConfig,
    top_level_path: str
) -> omegaconf.DictConfig
```

```python
nemo_gym.global_config.get_global_config_dict(
    global_config_dict_parser_config: typing.Optional[nemo_gym.global_config.GlobalConfigDictParserConfig] = None,
    global_config_dict_parser_cls: typing.Type[nemo_gym.global_config.GlobalConfigDictParser] = GlobalConfigDictParser
) -> omegaconf.DictConfig
```

This function provides a handle to the global configuration dict `global_config_dict`. We try to have one source of truth for everything in NeMo gym.
This config is resolved once and only once, immediately on a run command.

On first initialization, the global config dict will be loaded from the following sources in order of priority (later items are higher priority):

1. Configuration yamls specified in `config_paths` parameter.
2. Configuration (usually sensitive values like API keys, etc) from a local `.env.yaml` file.
3. Command line argument configuration.

Validation is performed on the passed in configs:

1. If a host or port is not provided for a server, defaults will be provided. Ports are resolved by the OS.
2. If there are server reference configs, the respective server names and types will be validated against the remainder of the config.

Then, the global config dict will be cached and reused.

If this function is run by a child server of the main proc, that child will have been spun up with an environment variable with key NEMO\_GYM\_CONFIG\_DICT\_ENV\_VAR\_NAME. The config dict will be read directly off this variable, cached, and returned with no additional validation.

```python
nemo_gym.global_config.get_hf_token() -> typing.Optional[str]
```

```python
nemo_gym.global_config.label_runs(
    agent_by_key: typing.Mapping[str, typing.Optional[str]]
) -> typing.Dict[str, str]
```

Label each run key by its agent's name when that name identifies exactly one run, else by the key.

A run with one Environment Server per agent keeps its agent's name, so existing labels do not change.
Every run of an agent that several Environment Servers front is labelled by its own Environment Server.
A label that would still repeat, because one server's name equals another run's agent name, also falls back
to the key. The result depends only on the mapping, not on its order, and every label is unique.

```python
nemo_gym.global_config.legacy_environment_server_block(
    agent_name: str
) -> dict[str, typing.Any]
```

The legacy\_agent environment server config that relays to one agent.

```python
nemo_gym.global_config.legacy_environment_server_name(
    agent_name: str,
    agent_type: str
) -> str
```

Name an agent's legacy\_agent relay after its environment, as the migration script does.

The agent type, or else a trailing `_agent`, is stripped from the agent name.
For example, `workplace_assistant_simple_agent` becomes `workplace_assistant_environment_server`.
The name then stays the same when the agent is swapped for another type.

```python
nemo_gym.global_config.maybe_get_global_config_dict() -> typing.Optional[omegaconf.DictConfig]
```

The global config dict when this process already has one; never triggers a CLI parse.

Returns the cached dict, or the one the parent injected via
NEMO\_GYM\_CONFIG\_DICT (caching it), or None in a bare process. Library code
that only wants to *consult* the config should use this instead of
`get_global_config_dict`, which falls through to a full CLI/hydra parse.

```python
nemo_gym.global_config.model_type_for(
    global_config_dict: omegaconf.DictConfig,
    model_server_name: typing.Optional[str]
) -> typing.Optional[str]
```

The single model adapter type hosted by `model_server_name`, or None when it cannot be determined.

```python
nemo_gym.global_config.pairing_override_enabled(
    global_config_dict: omegaconf.DictConfig
) -> bool
```

True when a declared agent/model compatibility guard has been explicitly waived.

```python
nemo_gym.global_config.resolve_dataset_agent(
    global_config_dict: omegaconf.DictConfig,
    declaring_instance_name: str,
    pin: typing.Optional[str] = None
) -> str
```

Resolve the agent that runs a dataset declared by `declaring_instance_name`.

Single source of truth for dataset -> agent routing, shared by benchmark discovery,
preparation, manifest validation, and rollout dispatch, so they can never disagree.
First hit wins:

1. `pin` (the dataset's `agent:` key) — validated: it must name the declaring agent
   itself, or an agent referencing the declaring resources server. Anything else is a hard
   error, never a silent re-route (rows carry only the declaring instance name).
2. The declaring agent block itself.
3. The unique agent referencing the declaring resources server; zero or 2+ is a hard error.

```python
nemo_gym.global_config.rollout_agent_label(
    row: typing.Mapping[str, typing.Any]
) -> typing.Optional[str]
```

Name the agent that acted in one rollout, for per-rollout output such as trajectories and debug lines.

Rows without an `agent_ref`, such as episode rows, use their Environment Server.

```python
nemo_gym.global_config.rollout_run_key(
    row: typing.Mapping[str, typing.Any]
) -> typing.Optional[str]
```

Identify what ran a rollout, for grouping: its Environment Server.

Records written before rollout collection stamped the Environment Server fall back to their agent.

```python
nemo_gym.global_config.rollout_run_labels(
    rows: typing.Iterable[typing.Mapping[str, typing.Any]]
) -> typing.Dict[str, str]
```

Label each `rollout_run_key` for reports, the same way rollout collection labels aggregate metrics.

See `label_runs`. A row without an `agent_ref` is labelled by its Environment Server.

```python
nemo_gym.global_config.set_global_config_dict(
    global_config_dict_parser_config: typing.Optional[nemo_gym.global_config.GlobalConfigDictParserConfig] = None,
    global_config_dict_parser_cls: typing.Type[nemo_gym.global_config.GlobalConfigDictParser] = GlobalConfigDictParser
) -> None
```

```python
nemo_gym.global_config.translate_interpolation_error(
    e: omegaconf.errors.InterpolationResolutionError
) -> nemo_gym.config_types.ConfigInterpolationError
```

Same class of user error as an unset '???' (see raise\_on\_missing\_values), reported the same way
instead of letting omegaconf's traceback reach the top level. Covers both a missing `$&#123;key&#125;`
(InterpolationKeyError) and a failing resolver such as `$&#123;oc.env:VAR&#125;`, which carries its own
message and so is passed through as-is.

```python
nemo_gym.global_config.AGENT_REF_KEY_NAME = 'agent_ref'
```

```python
nemo_gym.global_config.AGENT_SERVER_REF_KEY_NAME = 'agent_server'
```

```python
nemo_gym.global_config.AGENT_SERVER_TYPE_KEY_NAME = 'responses_api_agents'
```

```python
nemo_gym.global_config.ALLOWED_AGENTS_KEY_NAME = 'allowed_agents'
```

```python
nemo_gym.global_config.ALLOWED_MODEL_TYPES_KEY_NAME = 'allowed_model_types'
```

```python
nemo_gym.global_config.ALLOW_OPENAI_VERSION_SKEW_KEY_NAME = 'allow_openai_version_skew'
```

```python
nemo_gym.global_config.ALLOW_UNSUPPORTED_PAIRING_ENV_VAR_NAME = 'NEMO_GYM_ALLOW_UNSUPPORTED_PAIRING'
```

```python
nemo_gym.global_config.ALLOW_UNSUPPORTED_PAIRING_KEY_NAME = 'allow_unsupported_pairing'
```

```python
nemo_gym.global_config.ATTEMPT_INDEX_KEY_NAME = '_ng_attempt_index'
```

```python
nemo_gym.global_config.CACHE_DIR_KEY_NAME = 'cache_dir'
```

```python
nemo_gym.global_config.COMPONENT_NAME_KEY_NAME = 'component_name'
```

```python
nemo_gym.global_config.CONFIG_PATHS_KEY_NAME = 'config_paths'
```

```python
nemo_gym.global_config.COPY_KEY_NAME = '_copy'
```

```python
nemo_gym.global_config.DEFAULT_HEAD_SERVER_PORT = 11000
```

```python
nemo_gym.global_config.DEFAULT_HOST_KEY_NAME = 'default_host'
```

```python
nemo_gym.global_config.DELETE_KEY_KEY_NAME = '_delete_key'
```

```python
nemo_gym.global_config.DISALLOWED_PORTS_KEY_NAME = 'disallowed_ports'
```

```python
nemo_gym.global_config.DRY_RUN_KEY_NAME = 'dry_run'
```

```python
nemo_gym.global_config.ENTRYPOINT_KEY_NAME = 'entrypoint'
```

```python
nemo_gym.global_config.ENVIRONMENT_ROUTING_MODE_KEY_NAME = 'environment_routing_mode'
```

```python
nemo_gym.global_config.ENVIRONMENT_SERVER_NAME_KEY_NAME = 'environment_server_name'
```

```python
nemo_gym.global_config.ENVIRONMENT_SERVER_ROUTES_KEY_NAME = 'environment_server_routes'
```

```python
nemo_gym.global_config.ENVIRONMENT_SERVER_STAMP_KEY_NAME = '_ng_environment_server'
```

```python
nemo_gym.global_config.ENVIRONMENT_SERVER_TYPE_KEY_NAME = 'environment_servers'
```

```python
nemo_gym.global_config.ERROR_ON_AGENT_WITHOUT_ENVIRONMENT_SERVER_KEY_NAME = 'error_on_agent_without_environment_server'
```

```python
nemo_gym.global_config.EXPECTED_NUM_ROLLOUTS_KEY_NAME = 'expected_num_rollouts'
```

```python
nemo_gym.global_config.HEAD_SERVER_DEPS_KEY_NAME = 'head_server_deps'
```

```python
nemo_gym.global_config.HEAD_SERVER_KEY_NAME = 'head_server'
```

```python
nemo_gym.global_config.HF_TOKEN_KEY_NAME = 'hf_token'
```

```python
nemo_gym.global_config.INHERIT_FROM_KEY_NAME = '_inherit_from'
```

```python
nemo_gym.global_config.JSON_OUTPUT_KEY_NAME = 'json'
```

```python
nemo_gym.global_config.LEGACY_ENVIRONMENT_SERVER_SUFFIX = '_environment_server'
```

```python
nemo_gym.global_config.MISSING_NUM_ROLLOUTS_KEY_NAME = 'missing_num_rollouts'
```

```python
nemo_gym.global_config.MODEL_CALL_CAPTURE_DIR_KEY_NAME = 'model_call_capture_dir'
```

```python
nemo_gym.global_config.MODEL_ENDPOINT_READINESS_TIMEOUT_KEY_NAME = 'model_endpoint_readiness_timeout_seconds'
```

```python
nemo_gym.global_config.MODEL_SERVER_TYPE_KEY_NAME = 'responses_api_models'
```

```python
nemo_gym.global_config.NEMO_GYM_CONFIG_DICT_ENV_VAR_NAME = 'NEMO_GYM_CONFIG_DICT'
```

```python
nemo_gym.global_config.NEMO_GYM_CONFIG_PATH_ENV_VAR_NAME = 'NEMO_GYM_CONFIG_PATH'
```

```python
nemo_gym.global_config.NEMO_GYM_LOG_DIR_KEY_NAME = 'nemo_gym_log_dir'
```

```python
nemo_gym.global_config.NEMO_GYM_RESERVED_TOP_LEVEL_KEYS = [CONFIG_PATHS_KEY_NAME, ENTRYPOINT_KEY_NAME, DEFAULT_HOST_KEY_NAME, HEAD_SERVER_...
```

```python
nemo_gym.global_config.NUM_ROLLOUTS_KEY_NAME = 'num_rollouts'
```

```python
nemo_gym.global_config.OBSERVABILITY_ENABLED_KEY_NAME = 'observability_enabled'
```

```python
nemo_gym.global_config.PIP_INSTALL_VERBOSE_KEY_NAME = 'pip_install_verbose'
```

```python
nemo_gym.global_config.POLICY_API_KEY_KEY_NAME = 'policy_api_key'
```

```python
nemo_gym.global_config.POLICY_BASE_URL_KEY_NAME = 'policy_base_url'
```

```python
nemo_gym.global_config.POLICY_MODEL_KEY_NAME = 'policy_model'
```

```python
nemo_gym.global_config.POLICY_MODEL_NAME_KEY_NAME = 'policy_model_name'
```

```python
nemo_gym.global_config.PORT_RANGE_HIGH_KEY_NAME = 'port_range_high'
```

```python
nemo_gym.global_config.PORT_RANGE_LOW_KEY_NAME = 'port_range_low'
```

```python
nemo_gym.global_config.PYTHON_VERSION_KEY_NAME = 'python_version'
```

```python
nemo_gym.global_config.QUERY_KEY_NAME = 'query'
```

```python
nemo_gym.global_config.RAY_HEAD_NODE_ADDRESS_KEY_NAME = 'ray_head_node_address'
```

```python
nemo_gym.global_config.RESOURCES_SERVER_TYPE_KEY_NAME = 'resources_servers'
```

```python
nemo_gym.global_config.RESPONSES_CREATE_PARAMS_KEY_NAME = 'responses_create_params'
```

```python
nemo_gym.global_config.RESPONSE_KEY_NAME = 'response'
```

```python
nemo_gym.global_config.RESULTS_DIR_KEY_NAME = 'results_dir'
```

```python
nemo_gym.global_config.REWARD_KEY_NAME = 'reward'
```

```python
nemo_gym.global_config.ROLLOUT_ID_KEY_NAME = '_ng_rollout_id'
```

```python
nemo_gym.global_config.ROLLOUT_INDEX_KEY_NAME = '_ng_rollout_index'
```

```python
nemo_gym.global_config.ROLLOUT_INFOS_KEY_NAME = 'rollout_infos'
```

```python
nemo_gym.global_config.SERVER_SPINUP_TIMEOUT_SECONDS_KEY_NAME = 'server_spinup_timeout_seconds'
```

```python
nemo_gym.global_config.SKILLS_REF_KEY_NAME = 'skills_ref'
```

```python
nemo_gym.global_config.SKIP_VENV_IF_PRESENT_KEY_NAME = 'skip_venv_if_present'
```

```python
nemo_gym.global_config.SKIP_VERIFICATION_KEY_NAME = 'skip_verification'
```

```python
nemo_gym.global_config.SKIP_VERIFICATION_REWARD_KEY_NAME = 'skip_verification_reward'
```

```python
nemo_gym.global_config.TASK_INDEX_KEY_NAME = '_ng_task_index'
```

```python
nemo_gym.global_config.TASK_SOURCE_KEY_NAME = 'task_source'
```

```python
nemo_gym.global_config.TOKEN_ID_CAPTURE_BLOCK = 'token_id_capture'
```

```python
nemo_gym.global_config.USE_ABSOLUTE_IP = 'use_absolute_ip'
```

```python
nemo_gym.global_config.UVICORN_TIMEOUT_WORKER_HEALTHCHECK = 'uvicorn_timeout_worker_healthcheck'
```

```python
nemo_gym.global_config.UV_CACHE_DIR_KEY_NAME = 'uv_cache_dir'
```

```python
nemo_gym.global_config.UV_LOCK_TIMEOUT_KEY_NAME = 'uv_lock_timeout_seconds'
```

```python
nemo_gym.global_config.UV_PIP_SET_PYTHON_KEY_NAME = 'uv_pip_set_python'
```

```python
nemo_gym.global_config.UV_VENV_DIR_KEY_NAME = 'uv_venv_dir'
```

```python
nemo_gym.global_config.VERBOSE_KEY_NAME = 'verbose'
```

```python
nemo_gym.global_config._COMPOSED_AGENT_CARRY_OVER_KEYS = ('resources_server', 'model_server', 'datasets')
```

```python
nemo_gym.global_config._GLOBAL_CONFIG_DICT = None
```

```python
nemo_gym.global_config._MISSING_REF = object()
```

```python
nemo_gym.global_config.logger = logging.getLogger(__name__)
```

```python
nemo_gym.global_config.ray_version = distribution_version('ray')
```