Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions hermes_cli/model_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,7 @@ def list_authenticated_providers(
refresh: bool = False,
probe_custom_providers: bool = True,
probe_current_custom_provider: bool = False,
for_picker: bool = False,
) -> List[dict]:
"""Detect which providers have credentials and list their curated models.

Expand Down Expand Up @@ -1843,6 +1844,20 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool:
try:
if _credential_pool_is_usable(hermes_slug):
has_creds = True
elif for_picker:
# For the interactive /model picker, also show providers
# whose credential pool has entries but all are temporarily
# rate-limited. Rate limits are per-model for many
# providers (e.g. Google Gemini) — switching to a different
# model under the same provider may work even when all keys
# are in cooldown.
try:
from agent.credential_pool import load_pool
_pool = load_pool(hermes_slug)
if _pool.has_credentials():
has_creds = True
except Exception:
pass
except Exception as exc:
logger.debug("Credential pool check failed for %s: %s", hermes_slug, exc)
# Fallback: check external credential files directly.
Expand Down Expand Up @@ -2488,6 +2503,7 @@ def list_picker_providers(
custom_providers=custom_providers,
max_models=max_models,
current_model=current_model,
for_picker=True,
)
if include_moa:
providers = _prepend_moa_picker_provider(providers, current_provider=current_provider)
Expand Down
19 changes: 19 additions & 0 deletions tests/hermes_cli/test_authenticated_providers_exhausted_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,22 @@ def test_opaque_legacy_pool_value_stays_visible(monkeypatch):
)

assert _credential_pool_is_usable("opencode-go", raw_pool_present=True)


def test_picker_shows_exhausted_pool_provider(monkeypatch):
"""The interactive picker must include providers whose credential pool
entries are all exhausted, so the user can still switch to a different
model under the same provider."""
from hermes_cli.model_switch import list_picker_providers

_patch_opencode_pool(monkeypatch, available=False)
providers = list_picker_providers(
current_provider="alibaba",
user_providers={},
custom_providers=[],
)
slugs = [p["slug"] for p in providers]
assert "opencode-go" in slugs, (
"Picker must show exhausted-pool providers so the user can select "
"a different model under the same provider"
)
Loading