mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-17 09:41:58 +00:00
The Anthropic picker returned the live /v1/models dump verbatim whenever credentials were configured. Anthropic's API lags newly-routed curated aliases (e.g. claude-fable-5, reachable on Anthropic before the models endpoint enumerates it), so the curated entry vanished from the picker. Merge curated _PROVIDER_MODELS["anthropic"] with the live catalog — curated first, live-only appended, deduped — mirroring the OpenAI curated-merge path. Live failure / no creds falls back to curated verbatim.
58 lines
2.6 KiB
Python
58 lines
2.6 KiB
Python
"""Regression tests for the Anthropic model-picker dropping curated aliases.
|
|
|
|
Bug — newly-routed curated aliases vanished on a native Anthropic setup
|
|
``provider_model_ids("anthropic")`` returned the live ``/v1/models`` dump
|
|
verbatim whenever Anthropic credentials were configured. Anthropic's API
|
|
lags behind freshly-routed aliases (e.g. ``claude-fable-5``, which is
|
|
reachable on Anthropic before the models endpoint enumerates it), so the
|
|
curated entry disappeared from the picker. The picker now merges the
|
|
curated ``_PROVIDER_MODELS["anthropic"]`` list with the live catalog —
|
|
curated entries first, live-only models appended, deduped — mirroring the
|
|
OpenAI curated-merge philosophy.
|
|
"""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from hermes_cli import models as M
|
|
|
|
|
|
def test_anthropic_curated_alias_survives_when_live_omits_it():
|
|
"""A curated alias missing from /v1/models still surfaces (first)."""
|
|
curated = M._PROVIDER_MODELS["anthropic"]
|
|
assert "claude-fable-5" in curated # sanity: the alias is curated
|
|
|
|
# Live catalog the API would actually return — no fable-5.
|
|
live = ["claude-opus-4-8", "claude-sonnet-4-6", "claude-haiku-4-5-20251001"]
|
|
with patch.object(M, "_fetch_anthropic_models", return_value=live):
|
|
result = M.provider_model_ids("anthropic")
|
|
|
|
assert "claude-fable-5" in result
|
|
# Curated order is preserved at the front.
|
|
assert result[:len(curated)] == list(curated)
|
|
|
|
|
|
def test_anthropic_merge_dedupes_overlap_and_appends_live_only():
|
|
"""Models in both lists appear once; live-only models are appended."""
|
|
live = [
|
|
"claude-opus-4-8", # overlaps curated
|
|
"claude-sonnet-4-6", # overlaps curated
|
|
"claude-future-9-99", # live-only, not curated
|
|
]
|
|
with patch.object(M, "_fetch_anthropic_models", return_value=live):
|
|
result = M.provider_model_ids("anthropic")
|
|
|
|
# No duplicates introduced by the merge.
|
|
assert result.count("claude-opus-4-8") == 1
|
|
# Live-only entry is preserved (discovery still works for unknown models).
|
|
assert "claude-future-9-99" in result
|
|
# Curated entries lead, live-only trails.
|
|
assert result.index("claude-fable-5") < result.index("claude-future-9-99")
|
|
|
|
|
|
def test_anthropic_falls_back_to_curated_when_live_unavailable():
|
|
"""No creds / live failure -> curated list verbatim (alias still present)."""
|
|
with patch.object(M, "_fetch_anthropic_models", return_value=None):
|
|
result = M.provider_model_ids("anthropic")
|
|
|
|
assert result == list(M._PROVIDER_MODELS["anthropic"])
|
|
assert "claude-fable-5" in result
|