Skip to content

fix(models): merge live API results with curated static catalog in generic provider path - #46857

Merged
kshitijk4poor merged 3 commits into
NousResearch:mainfrom
liuhao1024:fix/model-picker-merge-live-static
Jun 16, 2026
Merged

fix(models): merge live API results with curated static catalog in generic provider path#46857
kshitijk4poor merged 3 commits into
NousResearch:mainfrom
liuhao1024:fix/model-picker-merge-live-static

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

Merges live API model results with the static curated catalog in the generic profile-based provider path, so models that a provider's live /v1/models endpoint omits (stale cache, partial rollout) still appear in the /model picker.

Related Issue

Fixes #46850

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • hermes_cli/models.py: Generalized the kimi-coding live+curated merge pattern to all providers in the generic profile-based path. Live entries come first (provider's preferred order), then curated-only entries are appended with case-insensitive dedup.
  • tests/hermes_cli/test_models_dev_preferred_merge.py: Updated existing kimi-coding test to reflect live-first ordering.
  • tests/hermes_cli/test_provider_live_curated_merge.py: New test file covering the merge behavior — live+curated merge, no duplicates, case-insensitive dedup, empty curated fallback.

How to Test

  1. Run pytest tests/hermes_cli/test_provider_live_curated_merge.py -v — all 5 tests should pass
  2. Run pytest tests/hermes_cli/test_models_dev_preferred_merge.py -v — all tests should pass
  3. Run pytest tests/hermes_cli/test_model_validation.py -v — all tests should pass

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Code Intelligence

  • Analyzed: hermes_cli/models.py::provider_model_ids (generic profile-based path, lines 2370-2382)
  • Blast radius: LOW — change is isolated to the generic live-fetch merge path; special-cased providers (openrouter, codex, nous, anthropic, etc.) are unaffected
  • Related patterns: _merge_with_models_dev (models.dev merge), kimi-coding merge (existing pattern generalized)

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels Jun 15, 2026
@liyishuai

Copy link
Copy Markdown

Looking forward to have this fix merged.

@potatogim

Copy link
Copy Markdown

Thanks for tackling #46850 — the live+curated merge in provider_model_ids() looks useful for the picker path.

One gap I can still reproduce on this PR branch: direct model switching still fails because validate_requested_model() probes fetch_api_models() directly and does not reuse the merged provider_model_ids() result.

Minimal repro with the live Z.AI listing simulated as ['glm-5.1', 'glm-5']:

from unittest.mock import patch
from hermes_cli.models import validate_requested_model
from hermes_cli.model_switch import switch_model

live = ['glm-5.1', 'glm-5']

with patch('hermes_cli.models.fetch_api_models', return_value=live):
    validate_requested_model(
        'glm-5.2',
        'zai',
        api_key='dummy',
        base_url='https://api.z.ai/api/coding/paas/v4',
    )
# => {'accepted': False, 'persist': False, ...}

with patch('hermes_cli.models.fetch_api_models', return_value=live):
    switch_model(
        'glm-5.2',
        current_provider='zai',
        current_model='glm-5.1',
        current_base_url='https://api.z.ai/api/coding/paas/v4',
        current_api_key='dummy',
        explicit_provider='zai',
    )
# => success=False, "Model `glm-5.2` was not found..."

So this PR appears to fix visibility in the picker/listing path, but /model glm-5.2 --provider zai can still be rejected when the live /models endpoint omits GLM-5.2.

A small follow-up in validate_requested_model() may be needed: when the live listing is non-empty but omits the requested model, accept it if it is present in the static curated catalog for the normalized provider, and add a switch_model() regression test for this path. That would cover both the picker and direct slash-command flows without relying on the provider's stale /models endpoint.

…neric provider path

When a provider's live /v1/models endpoint returns a stale or incomplete
list (e.g. Z.AI missing glm-5.2), the generic profile-based code path
returned only the live results, silently dropping curated models.

Generalize the kimi-coding merge pattern to all providers: live entries
come first (provider's preferred order), then curated-only entries are
appended with case-insensitive dedup. This ensures models that the live
endpoint omits still appear in /model picker.

Fixes NousResearch#46850
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
@liuhao1024
liuhao1024 force-pushed the fix/model-picker-merge-live-static branch from 2e020cb to ee7b8a4 Compare June 16, 2026 08:24
@liuhao1024

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed repro, @potatogim. You're right — validate_requested_model() probes fetch_api_models() directly and doesn't benefit from the curated merge.

Fixed in the latest commit: when the live /v1/models listing omits a model that exists in the curated catalog, validate_requested_model() now accepts it with a note instead of rejecting. The check is scoped to the "live responded but model not listed" path — models found in the live API are accepted directly without the curated lookup.

Three regression tests added covering:

  • Model in curated but not live → accepted
  • Model in neither → rejected
  • Model in live → accepted directly (no curated check needed)

…ure-catalog helper in validation

The generic live+curated merge (commit 630b438) seeded the merged list
from live results, demoting curated-only models below live ones. That
regressed NousResearch#46309, which deliberately surfaces the newest curated model
(kimi-k2.7-code) FIRST in the native picker even when the live /models
listing lags. Restore curated-first ordering: curated entries lead (in
catalog order), live-only entries are appended for discovery. This keeps
the NousResearch#46850 fix (zai glm-5.2 now appears) without the kimi regression.

Also switch the validate_requested_model curated fallback (commit
ee7b8a4) from provider_model_ids() — which triggers a second, uncached
live /models fetch with its own 8s timeout and may resolve different
credentials than the api_key/base_url just probed — to the pure-catalog
helper _model_in_provider_catalog(). Membership is checked against the
shipped catalog only, with no extra network call.

Tests: restore the curated-first assertion in
test_kimi_coding_live_catalog_does_not_hide_curated_k2_7_code; update
the new merge tests to curated-first semantics; de-circularize the
validation fallback tests to patch _PROVIDER_MODELS (the real source)
instead of mocking the function under test.
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Thanks for this — the live+curated merge is the right fix for #46850, and generalizing it past the kimi-only special case is a good call. I pushed one follow-up commit (maintainerCanModify) that I'd like your eyes on:

Restored curated-first ordering. The merge seeded the list from live (live-first), which demoted curated-only models below live ones. That regresses #46309 — that PR deliberately surfaces the newest curated model (kimi-k2.7-code) first in the native picker even when the live /models listing lags inference. With live-first, kimi-coding returned ['kimi-k2.6', 'kimi-k2.7-code', ...]. I switched to curated-first (curated leads in catalog order, live-only appended for discovery), which keeps your zai/glm-5.2 fix — glm-5.2 still surfaces, now at the top where the newest model belongs — without the kimi regression.

Validation fallback uses the pure-catalog helper. The validate_requested_model fallback called provider_model_ids(), which fires a second, uncached live /models fetch (its own 8s timeout) after fetch_api_models() already ran in the same call — and can resolve different credentials than the api_key/base_url just probed. Swapped it to _model_in_provider_catalog() (membership against the shipped catalog only, no network), matching how that helper is used elsewhere in the file.

Tests: restored the original curated-first assertion in test_kimi_coding_live_catalog_does_not_hide_curated_k2_7_code; updated the new merge tests to curated-first semantics; de-circularized the validation fallback tests to patch _PROVIDER_MODELS (the real source) instead of mocking the function under test; and added test_curated_fallback_is_scoped_to_the_current_provider to lock in that the catalog fallback keys on the current provider only (a model in another provider's catalog — e.g. an OpenRouter-only id — still rejects on zai).

Verified locally: 102 tests pass; zai surfaces glm-5.2 first, kimi k2.7-code is first again, glm-5.2 validates while unknown / cross-provider models still reject. Merging once CI is green — let me know if you'd prefer to take it differently.

@kshitijk4poor
kshitijk4poor enabled auto-merge June 16, 2026 17:56
@kshitijk4poor
kshitijk4poor merged commit 17251e8 into NousResearch:main Jun 16, 2026
34 checks passed
alanbratu pushed a commit to alanbratu/hermes-agent that referenced this pull request Jun 17, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
al3xar pushed a commit to al3xar/hermes-agent that referenced this pull request Jun 17, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…r-merge-live-static

fix(models): merge live API results with curated static catalog in generic provider path
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…r-merge-live-static

fix(models): merge live API results with curated static catalog in generic provider path
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…r-merge-live-static

fix(models): merge live API results with curated static catalog in generic provider path
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…r-merge-live-static

fix(models): merge live API results with curated static catalog in generic provider path
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…hen live API omits model

When live /v1/models responds but omits a model that exists in the
curated static catalog, validate_requested_model now accepts it with
a note instead of rejecting. This covers the /model slash-command path
(the picker path was already fixed in the parent commit).

Addresses review feedback from potatogim on NousResearch#46857.
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…r-merge-live-static

fix(models): merge live API results with curated static catalog in generic provider path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/model picker omits unlisted models that are callable (zai / glm-5.2)

5 participants