diff --git a/llm/cli.py b/llm/cli.py index 3517fd871..4133ccf15 100644 --- a/llm/cli.py +++ b/llm/cli.py @@ -2497,7 +2497,11 @@ def render_model_with_options(model_id, *, async_=False): ) @click.option("model_ids", "-m", "--model", help="Specific model IDs", multiple=True) def models_list(options, async_, schemas, tools, query, model_ids): - "List available models" + """List available models. + + Some plugins only register their models after an API key is configured. + Run 'llm keys set' to store API keys for installed model providers. + """ models_that_have_shown_options = set() for model_with_aliases in get_models_with_aliases(): if async_ and not model_with_aliases.async_model: diff --git a/tests/test_llm.py b/tests/test_llm.py index 825ca4f3c..3cf644422 100644 --- a/tests/test_llm.py +++ b/tests/test_llm.py @@ -523,6 +523,14 @@ def test_llm_models_options(user_path): assert "AsyncMockModel (async): mock" not in result.output +def test_llm_models_help_mentions_api_keys(): + runner = CliRunner() + result = runner.invoke(cli, ["models", "list", "--help"]) + assert result.exit_code == 0 + assert "Some plugins only register their models after an API key" in result.output + assert "llm keys set" in result.output + + def test_prompt_options_shows_selected_model_options(user_path): runner = CliRunner() result = runner.invoke(cli, ["-m", "gpt-5.5", "--options"], catch_exceptions=False)