fix: probe live Nous inference API for models missing from curated pi… - #32075
fix: probe live Nous inference API for models missing from curated pi…#32075Masalale wants to merge 1 commit into
Conversation
|
The feature is genuinely useful — merging live free-tier variants (
So opening the model picker now blocks up to 5s on a network round-trip (and the full 5s every time the endpoint is slow/unreachable), where before it was instant. That's a UX regression on a hot path. Two clean options: (1) cache the live result module-level with a short TTL — there's already an |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Extends get_curated_nous_model_ids() to probe the live Nous /v1/models endpoint and merge any additional model IDs into the curated list, with corresponding test updates to mock out network calls.
Changes:
- Adds live API probe in
get_curated_nous_model_idsto discover models not in the static catalog, filtering out non-agentic Hermes variants. - Normalizes base URL to avoid duplicate
/v1in path. - Updates existing tests to patch
urllib.request.urlopenso the new network call doesn't reach out during tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| hermes_cli/models.py | Merges live /v1/models results into curated Nous model list. |
| tests/hermes_cli/test_model_catalog.py | Patches urlopen in existing tests to isolate from network. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| f"{api_root}/v1/models", | ||
| headers={"Accept": "application/json", "User-Agent": "HermesAgent/1.0"}, | ||
| ) | ||
| with urlopen(req, timeout=5) as resp: |
| # Skip non-agentic Nous Hermes models | ||
| low = mid.lower() | ||
| if "hermes" in low and ("/hermes-4" in low or "/hermes-3" in low): | ||
| continue |
| except Exception: | ||
| pass |
| if live_ids: | ||
| existing = set(curated) |
4ae497a to
cc22f99
Compare
|
@hclsys good catch — caching is now in place. Extracted the live probe into Repeated picker opens: 2.7s first call → 0.0033s cached (~800x). On network failure the cache is not evicted (stale data is better than no data). On cache hit, we re-merge with the current curated base so a concurrent catalog update does not get masked until TTL expiry. The commit was force-pushed to the same branch. |
cc22f99 to
8261069
Compare
…cker When the static model catalog is stale, models actually served by the Nous Portal (e.g. free-tier variants like deepseek/deepseek-v4-flash:free) were missing from the /model picker. Fix by probing GET /v1/models on the live inference endpoint and merging any new IDs into the curated list. Nous Research's own Hermes foundation models (hermes-3/hermes-4) are filtered out — they're served on the Portal but aren't useful inference-picker options. - 120s TTL cache prevents a network round-trip on every picker open. - On network failure the cache is preserved (stale > no data). - Cache-hit path is O(1) — no re-merge against the (stable within a session) curated list. - Tests mock urlopen so they're network-free; one new success-path test (TestNousLiveProbe.test_probe_merges_and_caches) covers the merge logic and the cache reuse.
2c93fcc to
0931ae9
Compare
|
Thanks for addressing stale Nous model discovery and for incorporating the cache feedback. Problems
Suggested changes
Automated hermes-sweeper review. |
What does this PR do?
When you open the
/modelpicker and select Nous Portal, certainmodels that the API actually serves were missing from the list.
For example,
deepseek/deepseek-v4-flash:free(a free-tier model)was nowhere to be found even though the API happily serves it.
Why? The model list came from a static catalog — a file shipped
with Hermes and updated periodically. Any model that didn't make it
into that file was invisible.
The fix: When building the model list, we now also probe the
live Nous inference API (
GET /v1/models) for extra models.The static catalog still comes first (so nothing changes for models
already in it), and any new models found via the live API are merged
in via
_merge_model_lists(). Nous Hermes foundation models(e.g.
nousresearch/hermes-4) are filtered out — they're servedon the Portal but aren't useful inference-picker options.
Caching: The live result is cached for 2 minutes (
_NOUS_LIVE_CACHE_TTL = 120)so the picker stays fast on repeated opens. Cache-hit path is O(1) —
no redundant iteration. On network failure the cache is preserved
(stale data is better than no data).
Test coverage: Two new tests cover the success path (merge logic
and cache reuse) alongside the existing network-failure fallback tests.
Related Issue
Fixes a gap where free-tier variants like
deepseek/deepseek-v4-flash:freewere missing from the
/modelpicker even though they work perfectlyon the API.
Type of Change
Changes Made
hermes_cli/models.py:_is_nous_hermes_model()— filter for non-agentic Nous Hermes models_merge_model_lists()— merges additionals into base list, deduping_probe_nous_live_api()— live probe with 120s TTL cacheget_curated_nous_model_ids()now delegates to_probe_nous_live_api()tests/hermes_cli/test_model_catalog.py:urlopen(network-free)TestNousLiveProbe— success-path tests for merge + cacheHow to Test
hermes model→ select Nous Portaldeepseek/deepseek-v4-flash:freeshould appearChecklist
Code
python -m pytest tests/hermes_cli/test_model_catalog.py tests/hermes_cli/test_models.py -qand all tests pass (30 + 76 = 106)Documentation & Housekeeping
Technical notes for reviewers
_resolve_nous_pricing_credentials()is used to get the API base URL;it's safe — returns a default on auth failure (so unauthenticated users
still get the probe).
(list[str], float)stored as a module global withtime.monotonic()for the timestamp. On miss the fresh result replaces it._is_nous_hermes_model) matcheshermes-3andhermes-4patterns — these are Nous Research's own foundation models thatHermes itself can't use as an inference provider.