fix(model_switch): group custom_providers by endpoint in /model picker (#9210)#14505
Merged
Conversation
#9210) Multiple custom_providers entries sharing the same base_url + api_key are now grouped into a single picker row. A local Ollama host with per-model display names ("Ollama — GLM 5.1", "Ollama — Qwen3-coder", "Ollama — Kimi K2", "Ollama — MiniMax M2.7") previously produced four near-duplicate picker rows that differed only by suffix; now it appears as one "Ollama" row with four models. Key changes: - Grouping key changed from slug-by-name to (base_url, api_key). Names frequently differ per model while the endpoint stays the same. - When the grouped endpoint matches current_base_url, the row's slug is set to current_provider so picker-driven switches route through the live credential pipeline (no re-resolution needed). - Per-model suffix is stripped from the display name ("Ollama — X" → "Ollama") via em-dash / " - " separators. - Two groups with different api_keys at the same base_url (or otherwise colliding on cleaned name) are disambiguated with a numeric suffix (custom:openai, custom:openai-2) so both stay visible. - current_base_url parameter plumbed through both gateway call sites. Existing #8216, #11499, #13509 regressions covered (dict/list shapes of models:, section-3/section-4 dedup, normalized list-format entries). Salvaged from @davidvv's PR #9210 — the underlying code had diverged ~1400 commits since that PR was opened, so this is a reconstruction of the same approach on current main rather than a clean cherry-pick. Authorship preserved via --author on this commit. Closes #9210
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four
custom_providers:entries pointing at the same Ollama host with per-model display names ("Ollama — GLM 5.1", "Ollama — Qwen3-coder", ...) now collapse into one "Ollama" picker row with four models instead of four near-duplicate rows.Salvaged from @davidvv's PR #9210. The code had diverged ~1400 commits since that PR was opened, so this is a reconstruction of the same approach on current main rather than a clean cherry-pick — authorship preserved via
--authoron the substantive commit.Changes
hermes_cli/model_switch.py: grouping key changed from slug-by-name to(base_url, api_key). Per-model suffix stripped from display name ("Ollama — X" → "Ollama"). When grouped endpoint matchescurrent_base_url, the row's slug becomescurrent_providerso picker-driven switches route through the live credential pipeline.gateway/run.py:current_base_urlplumbed through bothlist_authenticated_providers()call sites.custom:openai,custom:openai-2) so both stay visible.tests/hermes_cli/test_model_switch_custom_providers.py: 5 new tests covering grouping,current_base_url/is_currentwiring, distinct-endpoints-stay-separate, same-url-different-keys disambiguation, grouped total_models accounting.Validation
current_base_urlmatches groupis_current=False, opaque slugis_current=True, slug=current_providercustom:openai,custom:openai-2)Regression coverage preserved: #8216 (models dict), #11499 (
providers:+ compat dedup), #13509 (list-format models via normalize) all still work — verified E2E.Tests:
tests/hermes_cli/test_model_switch_custom_providers.py13/13 passing. Broadertests/hermes_cli/2575 passing + 1 unrelated failure (test_tips.py::test_max_length_reasonable — not my code).tests/gateway/model-related 34/34 passing.Closes #9210