diff --git a/nemo_gym/cli/env.py b/nemo_gym/cli/env.py index df1075ab40..59b0c19b46 100644 --- a/nemo_gym/cli/env.py +++ b/nemo_gym/cli/env.py @@ -1145,9 +1145,12 @@ def pip_list(): # pragma: no cover && source .venv/bin/activate \\ && {pip_list_cmd}""" - print(f" Package list for: {config.entrypoint}") - print(f"Virtual environment: {venv_path.absolute()}") - print("-" * 72) + # Only in the default human view: an explicit --format (json, freeze) is meant to be piped, so stdout + # must carry nothing but `uv pip list` output. + if not config.format: + print(f" Package list for: {config.entrypoint}") + print(f"Virtual environment: {venv_path.absolute()}") + print("-" * 72) proc = run_command(command, dir_path) return_code = proc.wait() diff --git a/nemo_gym/cli/models.py b/nemo_gym/cli/models.py index bdd7d7414b..24eb6845d8 100644 --- a/nemo_gym/cli/models.py +++ b/nemo_gym/cli/models.py @@ -35,7 +35,7 @@ def _inspect_model(name: str, models: dict, global_config_dict) -> None: - """Render the ``gym list models `` inspect view for one model (thin: no usage example). + """Render the ``gym list models `` inspect view for one model. ``name`` may be a bare model or a ``/`` token; a valid flavor renders the model's (main) inspection. @@ -51,6 +51,7 @@ def _inspect_model(name: str, models: dict, global_config_dict) -> None: name=name, type_noun="model", details={"config": str(entry.config_path.resolve())}, + usage=f"gym env start --resources-server example_single_tool_call --model-type {name}", ) @@ -73,8 +74,9 @@ def list_models() -> None: _inspect_model(name, models, global_config_dict) return - # One row per passable `--model-type` value: `model` is the token, `model_group` its model. - rows = [{"model": entry.name, "model_group": entry.model_group} for entry in models.values()] + # One row per passable `--model-type` value: `model` is the token, `model_group` its model. `name` carries + # the same value as `model` so every component type keys its rows on `name` (`model` kept for compatibility). + rows = [{"name": entry.name, "model": entry.name, "model_group": entry.model_group} for entry in models.values()] # `gym search models ` reuses this command, narrowing to rows matching the token or its model. query = global_config_dict.get(QUERY_KEY_NAME) diff --git a/tests/unit_tests/test_cli_models.py b/tests/unit_tests/test_cli_models.py index 99232c275f..46b7aa4259 100644 --- a/tests/unit_tests/test_cli_models.py +++ b/tests/unit_tests/test_cli_models.py @@ -86,9 +86,9 @@ def test_json_output_is_per_variant_rows(self, capsys) -> None: list_models() payload = json.loads(capsys.readouterr().out) expected = [ - {"model": "my_model", "model_group": "my_model"}, - {"model": "my_model/some_other_flavor", "model_group": "my_model"}, - {"model": "another_model", "model_group": "another_model"}, + {"name": "my_model", "model": "my_model", "model_group": "my_model"}, + {"name": "my_model/some_other_flavor", "model": "my_model/some_other_flavor", "model_group": "my_model"}, + {"name": "another_model", "model": "another_model", "model_group": "another_model"}, ] assert len(payload) == len(expected) for row in expected: @@ -106,7 +106,7 @@ def test_inspect_model_by_name(self, capsys) -> None: out = capsys.readouterr().out assert "The my_model model" in out assert f"config: {_MODELS['my_model'].config_path.resolve()}" in out - assert "Usage example:" not in out # thin view + assert "Usage example:" in out def test_inspect_model_by_flavor_token(self, capsys) -> None: # A `/` token inspects that flavor's config.