fix: remove redundant provider label concatenation in _deduplicate_model_ids - #1511
fix: remove redundant provider label concatenation in _deduplicate_model_ids#1511lost9999 wants to merge 1 commit into
Conversation
…del_ids The _deduplicate_model_ids function appended provider names to model labels during deduplication, causing garbled labels like 'Deepseek V4 Flash (Xiaomi) (Ollama) (HuggingFace)' when multiple providers exposed models with the same name. This patch removes the label concatenation logic while preserving the model ID deduplication (prefixing with @provider_id:). The label should reflect the model's own metadata, not accumulated provider names. Fixes garbled model labels in WebUI model list when multiple providers have overlapping model names.
v0.50.277 — model-picker shared-reference fix (supersedes #1511)
|
Thank you @lost9999 for filing this — your bug report was the seed for v0.50.277, shipped via release #1515. Closing this PR but only because the same fix shipped at a different layer, and Why we landed the fix differentlyI traced the bug from first principles before merging. The dedup function in I wrote a Python repro and tested three theories:
The shared-reference scenario reproduces the exact symptom. I then traced the 5 group-build paths in
So when (for example) Ollama, HuggingFace, and a custom OpenAI-compat endpoint all auto-detect together, all three groups point to the SAME list with the SAME dicts inside. When dedup mutates those dicts to add The hidden bug your PR would not have fixedRemoving the label-suffix logic in Your symptom report (label clutter) was the visible tip of a deeper iceberg (silent mis-routing). The proper fix has to be at the assignment site, not the dedup function. What shipped
Single-parenthetical disambiguation in labels is retained because the composer chip at 4 regression tests in 3925 → 3929 tests passing. Why this matters for youIf you have multiple unconfigured auto-detected providers in your config, this release fixes silent model-routing. Pre-fix, selecting a duplicate model under any group routed the request to the alphabetical-first provider regardless of which group you clicked. Post-fix, requests route to the correct provider. You may notice your model selections behave differently after upgrading — that's the routing being correct, not a regression. Thanks again for the report. The fix wouldn't have happened without your symptom description. |
…dup bleed-across (nesquena#1511 root cause) Supersedes contributor PR nesquena#1511 (lost9999), which removed the label-suffix logic in _deduplicate_model_ids() but left the underlying shared-reference bug intact — IDs would still be silently corrupted across provider groups, just with cleaner-looking labels. ## Bug shape When multiple unconfigured providers (Ollama / HuggingFace / custom endpoints / Google Gemini CLI / Xiaomi / etc.) all fell through to the 'else' branch in api/config.py:get_models_grouped() that ends with: groups.append({..., "models": auto_detected_models}) every group ended up sharing the SAME list reference AND the SAME dicts inside. When _deduplicate_model_ids() then mutated those dicts to add @provider_id: prefixes and provider-name parentheticals, the changes were applied to every group that referenced the same dict. Visible symptom: user 'vishnu' reported the dropdown showing 'Deepseek V4 Flash (Xiaomi) (Ollama) (HuggingFace) (Google-Gemini-Cli)' on every group. Hidden symptom (worse): the 'id' field collapsed to '@XiaoMi:deepseek-v4-flash' on every group too, so clicking the entry under any group routed the request to Xiaomi. ## Fix api/config.py:2078 — wrap auto_detected_models in copy.deepcopy() at the groups.append site so each group gets its own independent dicts. The existing _deduplicate_model_ids() logic is correct and unchanged; the bug was in the assignment site, not the dedup function. The single-parenthetical disambiguation in labels is retained because the composer chip (composer-model-label) shows the model label without the optgroup header context — 'Deepseek V4 Flash (Ollama)' is more useful than ambiguous 'Deepseek V4 Flash' there. ## Tests tests/test_issue1511_dedup_shared_reference.py — 3 new tests: - test_groups_have_independent_model_lists: structural invariant pin - test_unconfigured_providers_no_shared_dedup_bleed: end-to-end against the corrected code path; verifies each group gets its own @provider_id: prefix and exactly ONE provider parenthetical per disambiguated label - test_shared_reference_pre_fix_demonstrates_corruption: documents the broken state that motivated the fix Full suite: 3925 → 3928 passing (+3 new, 0 regressions). Co-authored-by: lost9999 <56498264+lost9999@users.noreply.github.com>
v0.50.277 — model-picker shared-reference fix (supersedes nesquena#1511)
Problem
When multiple providers expose models with the same name (e.g., DeepSeek V4 Flash is available from Xiaomi, Ollama, HuggingFace, etc.), the
_deduplicate_model_ids()function appends the provider name to the model label for every duplicate found. This results in garbled labels like:Deepseek V4 Flash (Xiaomi) (Ollama) (HuggingFace) (Google-Gemini-Cli)The label should reflect the model's own metadata, not accumulate provider names.
Root Cause
In
api/config.py, the_deduplicate_model_idsfunction (around line 945) appends(provider_name)tomodel["label"]when deduplicating models with the same name. Since the function iterates across all provider groups and appends the label for every match, models exposed by many providers get increasingly garbled labels.Fix
Remove the label concatenation logic entirely. The ID deduplication (prefixing with
@provider_id:) is preserved — it's the correct way to differentiate same-named models from different providers. The label should be left as-is from the model's own metadata.Before
After
Testing
/api/modelsreturns clean labels with no accumulated provider suffixes