mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(cli): non-zero /model counts for native OpenAI and direct API rows
This commit is contained in:
parent
7f26cea390
commit
4a51ab61eb
3 changed files with 84 additions and 0 deletions
|
|
@ -1240,6 +1240,15 @@ def list_authenticated_providers(
|
||||||
if m and m not in models_list:
|
if m and m not in models_list:
|
||||||
models_list.append(m)
|
models_list.append(m)
|
||||||
|
|
||||||
|
# Official OpenAI API rows in providers: often have base_url but no
|
||||||
|
# explicit models: dict — avoid a misleading zero count in /model.
|
||||||
|
if not models_list:
|
||||||
|
url_lower = str(api_url).strip().lower()
|
||||||
|
if "api.openai.com" in url_lower:
|
||||||
|
fb = curated.get("openai") or []
|
||||||
|
if fb:
|
||||||
|
models_list = list(fb)
|
||||||
|
|
||||||
# Try to probe /v1/models if URL is set (but don't block on it)
|
# Try to probe /v1/models if URL is set (but don't block on it)
|
||||||
# For now just show what we know from config
|
# For now just show what we know from config
|
||||||
results.append({
|
results.append({
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,18 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
||||||
"openai/gpt-5.4-pro",
|
"openai/gpt-5.4-pro",
|
||||||
"openai/gpt-5.4-nano",
|
"openai/gpt-5.4-nano",
|
||||||
],
|
],
|
||||||
|
# Native OpenAI Chat Completions (api.openai.com). Used by /model counts and
|
||||||
|
# provider_model_ids fallback when /v1/models is unavailable.
|
||||||
|
"openai": [
|
||||||
|
"gpt-5.4",
|
||||||
|
"gpt-5.4-mini",
|
||||||
|
"gpt-5-mini",
|
||||||
|
"gpt-5.3-codex",
|
||||||
|
"gpt-5.2-codex",
|
||||||
|
"gpt-4.1",
|
||||||
|
"gpt-4o",
|
||||||
|
"gpt-4o-mini",
|
||||||
|
],
|
||||||
"openai-codex": _codex_curated_models(),
|
"openai-codex": _codex_curated_models(),
|
||||||
"copilot-acp": [
|
"copilot-acp": [
|
||||||
"copilot-acp",
|
"copilot-acp",
|
||||||
|
|
@ -1748,6 +1760,17 @@ def provider_model_ids(provider: Optional[str], *, force_refresh: bool = False)
|
||||||
live = fetch_ollama_cloud_models(force_refresh=force_refresh)
|
live = fetch_ollama_cloud_models(force_refresh=force_refresh)
|
||||||
if live:
|
if live:
|
||||||
return live
|
return live
|
||||||
|
if normalized == "openai":
|
||||||
|
api_key = os.getenv("OPENAI_API_KEY", "").strip()
|
||||||
|
if api_key:
|
||||||
|
base_raw = os.getenv("OPENAI_BASE_URL", "").strip().rstrip("/")
|
||||||
|
base = base_raw or "https://api.openai.com/v1"
|
||||||
|
try:
|
||||||
|
live = fetch_api_models(api_key, base)
|
||||||
|
if live:
|
||||||
|
return live
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
if normalized == "custom":
|
if normalized == "custom":
|
||||||
base_url = _get_custom_base_url()
|
base_url = _get_custom_base_url()
|
||||||
if base_url:
|
if base_url:
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,58 @@ def test_list_authenticated_providers_dict_models_dedupe_with_default(monkeypatc
|
||||||
assert user_prov["models"].count("model-a") == 1
|
assert user_prov["models"].count("model-a") == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_openai_native_curated_catalog_is_non_empty():
|
||||||
|
"""Regression: built-in openai must have a static catalog for picker totals."""
|
||||||
|
from hermes_cli.models import _PROVIDER_MODELS
|
||||||
|
|
||||||
|
assert _PROVIDER_MODELS.get("openai")
|
||||||
|
assert len(_PROVIDER_MODELS["openai"]) >= 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_authenticated_providers_openai_built_in_nonzero_total(monkeypatch):
|
||||||
|
"""Built-in openai row must not report total_models=0 when creds exist."""
|
||||||
|
monkeypatch.setenv("OPENAI_API_KEY", "sk-test")
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"agent.models_dev.fetch_models_dev",
|
||||||
|
lambda: {"openai": {"env": ["OPENAI_API_KEY"]}},
|
||||||
|
)
|
||||||
|
monkeypatch.setattr("hermes_cli.providers.HERMES_OVERLAYS", {})
|
||||||
|
|
||||||
|
providers = list_authenticated_providers(
|
||||||
|
current_provider="",
|
||||||
|
current_base_url="",
|
||||||
|
user_providers={},
|
||||||
|
custom_providers=[],
|
||||||
|
max_models=50,
|
||||||
|
)
|
||||||
|
row = next((p for p in providers if p.get("slug") == "openai"), None)
|
||||||
|
assert row is not None
|
||||||
|
assert row["total_models"] > 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_authenticated_providers_user_openai_official_url_fallback(monkeypatch):
|
||||||
|
"""User providers: api.openai.com with no models list uses native curated fallback."""
|
||||||
|
monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {})
|
||||||
|
monkeypatch.setattr("hermes_cli.providers.HERMES_OVERLAYS", {})
|
||||||
|
|
||||||
|
user_providers = {
|
||||||
|
"openai-direct": {
|
||||||
|
"name": "OpenAI Direct",
|
||||||
|
"api": "https://api.openai.com/v1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
providers = list_authenticated_providers(
|
||||||
|
current_provider="",
|
||||||
|
current_base_url="",
|
||||||
|
user_providers=user_providers,
|
||||||
|
custom_providers=[],
|
||||||
|
max_models=50,
|
||||||
|
)
|
||||||
|
row = next((p for p in providers if p.get("slug") == "openai-direct"), None)
|
||||||
|
assert row is not None
|
||||||
|
assert row["total_models"] > 0
|
||||||
|
|
||||||
|
|
||||||
def test_list_authenticated_providers_fallback_to_default_only(monkeypatch):
|
def test_list_authenticated_providers_fallback_to_default_only(monkeypatch):
|
||||||
"""When no models array is provided, should fall back to default_model."""
|
"""When no models array is provided, should fall back to default_model."""
|
||||||
monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {})
|
monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue