fix: searchable, grouped model picker for large cloud provider lists#1002
fix: searchable, grouped model picker for large cloud provider lists#1002gabrielste1n wants to merge 5 commits into
Conversation
OpenAI-compatible providers like OpenRouter expose 300-400 models, which the custom-provider panel rendered as a single flat, unsearchable list — no way to find a model, no grouping, and no visible selection. - Add SearchableModelList: search filter, grouping by provider prefix, virtualized rows (@tanstack/react-virtual), and a pinned "Selected" group so the active model is always visible. - OpenAICompatiblePanel switches to it above 12 models; smaller lists keep the plain list. - Extract a reusable ModelCard from ModelCardList and add an opt-in truncateDescription so long descriptions ellipsize instead of overflowing. - Add i18n keys across all locales. Closes #999
The group header already names the provider, so drop the "provider/" prefix from each row's label (openai/gpt-5.5 -> gpt-5.5) and show the provider's icon instead, matching the built-in provider cards. - Add getRemoteProviderIcon() resolving a remote prefix to our existing icons, with aliases (google -> gemini, meta-llama -> llama, mistralai -> mistral, x-ai -> xai) and "~"-variant normalization; unknown providers keep the globe. - Merge "~"-prefixed variant groups into their base provider group. The OpenRouter /models response carries no icon field, so icons are derived locally from the provider prefix.
Add OpenRouter as its own top-level cloud provider tab (before Custom) so users no longer have to use the Custom field. It reuses the OpenAI-compatible panel pinned to OpenRouter's endpoint and persists as the existing custom provider + base URL, so it needs no inference/secret/IPC changes; the searchable/grouped model list and per-row provider icons apply automatically. The panel gains lockedBaseUrl (hide the endpoint editor) and a get-key link. Tag outbound partner links (BYOK key pages, HuggingFace model pages) with OpenWhispr UTM attribution via a shared GetApiKeyLink component and a withUtm helper. withUtm only touches http(s) URLs and never overwrites an existing utm_source, so OS-setting/mailto links and Corti's existing tag stay intact.
|
Took a careful pass over this. The feature itself is clean. Most of what I found is edge-case polish, plus one credential-routing thing I'd fix before merge. Worth fixingThe API key gets sent to the wrong provider when you switch between the OpenRouter and Custom tabs. Both tabs render the same A non-conformant endpoint can take down the whole control panel. UX papercuts in the new list
Smaller stuff
|
Problem
OpenAI-compatible providers like OpenRouter expose 300–400 models. The custom-provider panel rendered them as a single flat, unsearchable list — no way to find a model, no grouping, long descriptions overflowed, and there was no visible indication of which model was selected. (Fixes #999)
Changes
SearchableModelListused byOpenAICompatiblePanelwhen a provider returns more than 12 models:/:anthropic,meta-llama, …), with per-group counts; ungrouped ids fall into "Other"@tanstack/react-virtual(already a dependency) so 400 models stay smoothModelCardfromModelCardListso both the plain and virtualized lists render identical cards; added an opt-intruncateDescriptionso long descriptions ellipsize instead of overflowingNon-breaking
ModelCardListcallers pass notruncateDescription→ identical rendered outputVerification
tsc --noEmit,eslint,prettier --check, andi18n:checkall passmainmerged in; clean (no conflicts)Follow-up commits
OpenRouter as a top-level provider
OpenRouter is now its own provider tab (before Custom) so users don't have to use the Custom field. It reuses the OpenAI-compatible panel pinned to OpenRouter's endpoint and persists as the existing
customprovider + base URL — identical to manually configuring Custom with OpenRouter's URL, so there are no inference / secret / IPC changes. The searchable, grouped list and per-row provider icons apply automatically. The panel gainedlockedBaseUrl(hide the endpoint editor when the URL is fixed) and a "Get an API key" link. The Custom tab is unchanged.UTM attribution on partner links
Outbound links to partner sites (BYOK key pages, HuggingFace model pages) are now UTM-tagged so those companies can attribute the traffic to OpenWhispr, via a shared
GetApiKeyLinkcomponent and awithUtmhelper.withUtmonly toucheshttp(s)URLs and never overwrites an existingutm_source, so OS-setting/mailto:links and Corti's pre-existing tag are left intact. Own-site links (*.openwhispr.com) are deliberately not tagged.