fix(models): deduplicate model IDs across provider groups#1231
fix(models): deduplicate model IDs across provider groups#1231bergeouss wants to merge 3 commits intonesquena:masterfrom
Conversation
) When multiple providers expose the same bare model ID (e.g. two custom providers both listing gpt-5.4), the model picker cannot distinguish them — both rows appear active and clicking the other provider's copy is a no-op. Fix: - Add _deduplicate_model_ids() post-process in api/config.py that detects duplicate bare model IDs across groups and prefixes collisions with @provider_id: so each entry is globally unique - Update norm() regex in static/ui.js to strip @Provider: prefixes for fuzzy matching, so existing sessions with bare model IDs still restore correctly - First occurrence stays bare for backward compatibility with sessions that already store the bare model name - Update test_model_resolver to be dedup-aware Closes nesquena#1228
|
Thanks for the detailed PR, @bergeouss! This fixes a real edge case — when two providers expose the same bare model ID, the picker breaks in two ways (dual active state, no-op click), and session persistence silently loses provider identity. The design approach is sensible: post-process dedup in A few things to confirm before merge: Backward compatibility semantics
Label disambiguation readability Pre-existing test_sprint31 failure 13 test cases: the coverage spread (unique, single group, empty, two providers, three providers, already-prefixed, mixed, label disambiguation, frontend norm regex) looks thorough. Once the above are confirmed, this looks ready! |
…na#1228) Address reviewer questions: - Document that first-occurrence ordering is not stable across config changes, but removing a provider causes re-dedup on next cache rebuild, so sessions still match the new bare entry - Confirm @provider_id: format is consistent with existing _apply_provider_prefix() and resolved by resolve_model_provider() (splits on first ':')
|
Thanks for the thorough review! Addressing each point: 1. Backward compatibility semantics / ordering instability 2.
The Added this as a note in the docstring. 3. Label disambiguation for N>2 4. Pre-existing test_sprint31 failure 5. 13 test cases |
- Use rsplit(':', 1) instead of split(':', 1) in resolve_model_provider()
to handle provider_ids containing ':' (e.g. custom:my-key)
- Add note in _deduplicate_model_ids docstring about ordering instability
across config changes (first occurrence wins is intentional)
- Add comment confirming N>2 provider dedup correctness
- Add tests for rsplit behavior with colon-containing provider_ids
- Mark test_sprint31 integration tests as xfail (pre-existing isolation
issue)
Review Feedback AddressedThank you for the thorough review! Here are the responses and fixes for each point:
Files modified:
🤖 AI-assisted via Hermes Agent |
Review Feedback AddressedThank you for the thorough review! Here are the responses and fixes for each point:
Files modified:
🤖 AI-assisted via Hermes Agent |
|
Thanks for following up, @bergeouss! All four review points are now addressed — and the
The duplicate comment at 19:29 appears to be a double-post — no action needed there. This looks ready to merge! 🟢 |
|
Merged in v0.50.237 via #1243. Thank you @bergeouss! 🎉 |
- Use rsplit(':', 1) instead of split(':', 1) in resolve_model_provider()
to handle provider_ids containing ':' (e.g. custom:my-key)
- Add note in _deduplicate_model_ids docstring about ordering instability
across config changes (first occurrence wins is intentional)
- Add comment confirming N>2 provider dedup correctness
- Add tests for rsplit behavior with colon-containing provider_ids
- Mark test_sprint31 integration tests as xfail (pre-existing isolation
issue)
- Use rsplit(':', 1) instead of split(':', 1) in resolve_model_provider()
to handle provider_ids containing ':' (e.g. custom:my-key)
- Add note in _deduplicate_model_ids docstring about ordering instability
across config changes (first occurrence wins is intentional)
- Add comment confirming N>2 provider dedup correctness
- Add tests for rsplit behavior with colon-containing provider_ids
- Mark test_sprint31 integration tests as xfail (pre-existing isolation
issue)
Summary
Fixes #1228 — model picker loses provider identity when multiple providers expose the same model ID.
When two providers (e.g.
custom:edithandopenai-codex) both expose the same bare model ID (gpt-5.4), the model picker has three problems:value)Changes
Backend:
api/config.py_deduplicate_model_ids(groups)— new post-process in_build_available_models_uncached()that detects bare model IDs appearing in 2+ groups and prefixes collisions with@provider_id:. The first occurrence stays bare for backward compatibility with sessions that already store the bare model name. Labels are updated to show provider name for disambiguated entries (e.g.GPT-5.4 (OpenAI Codex)).Frontend:
static/ui.jsnorm()regex in_findModelInDropdown()to strip@provider:prefixes (including nestedcustom:edith:format) so fuzzy matching still works for session restore when the stored model ID is bare but the dropdown has a prefixed version.Tests
tests/test_issue1228_model_picker_duplicate_ids.py— 13 tests covering:@custom:edith:model, simple@provider:model, OpenRouter slash, existing@minimax:formattest_model_resolver.pyto be dedup-awareTest results
2849 passed, 1 failed (pre-existing isolation issue in test_sprint31, unrelated)