feat(models): let people hide models they never use - #85
Merged
Conversation
A gateway provider reports 300-600 models and the picker lists every connected provider at once, so choosing a model means scrolling past hundreds you will never run. Pinning promotes a few to the top; it does nothing about the length of the list underneath. This is the other half. Settings gains a Models section: one collapsible row per provider with a count, a search box, per-model Hide/Unhide, and Hide all / Show all scoped to whatever the search is filtering - so "gpt" + Hide all hides those matches rather than silently wiping the catalog. Stored as a DENY-list, not an allow-list. Catalogs grow under us (a provider ships a model, a plan gains access to one), and an allow-list would withhold everything new until the user came back and ticked it. Connecting a provider still means "everything it offers", minus what you explicitly removed. Hiding is display-only: it never touches a session's stored model, so a session already on a hidden model keeps running it. Taking something out of a menu must not silently reroute work already using it. Details worth knowing: - Hiding also unpins, in SQL and in the store. A pinned+hidden model would otherwise sit at the top of the very list it was removed from, and modelRows drops hidden pins too so the intermediate state can't render. - The filter runs over all three picker sections, not just the catalog. Recents are usage history and keep listing a model after it is hidden, so a model hidden right after being used would keep reappearing under Latest. - An empty picker now distinguishes "you hid everything" (with a link to Settings) from "models.dev failed". Telling someone their network is broken when they hid the models themselves sends them debugging nothing. - The Settings list is windowed on a fixed row height: an expanded provider is 600 rows, which is exactly the mount cost ModelPicker already exists to avoid. - Row actions sit on the RIGHT, in the same column as Hide all / Show all, with an always-visible label. A hover-only affordance on a 600-row list is something you have to hunt for. hiddenModels is a Set of `provider:model` rather than the array shape pinnedModels uses: it is only ever asked "is THIS model hidden?", once per row over a long list, and carries no order worth preserving. Tests: 5 checks over buildModelRows (hidden in no section, per-provider keying, a fully hidden provider drops its header, omitting the set changes nothing) and 6 against the real DB (hide unpins, idempotent, bulk replace stays scoped to its provider).
# Conflicts: # src/main/db/migrations.ts # src/renderer/src/components/ModelPicker.tsx # src/renderer/src/lib/store.ts # src/renderer/src/routes/Settings.tsx
The v22 assertions replayed the ladder up to MIGRATIONS.length - 1, which assumed the Exa-key DELETE was the last rung. The hidden_models migration now sits on top of it, so the replay stopped one step too early and the DELETE never ran.
FreddyJD
approved these changes
Aug 30, 2026
Collaborator
|
Thank you for the change! |
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.
A gateway provider reports 300-600 models and the picker lists every connected provider at once, so choosing a model means scrolling past hundreds you will never run. Pinning promotes a few to the top; it does nothing about the length of the list underneath. This is the other half.
Settings gains a Models section: one collapsible row per provider with a count, a search box, per-model Hide/Unhide, and Hide all / Show all scoped to whatever the search is filtering - so "gpt" + Hide all hides those matches rather than silently wiping the catalog.
Stored as a DENY-list, not an allow-list. Catalogs grow under us (a provider ships a model, a plan gains access to one), and an allow-list would withhold everything new until the user came back and ticked it. Connecting a provider still means "everything it offers", minus what you explicitly removed.
Hiding is display-only: it never touches a session's stored model, so a session already on a hidden model keeps running it. Taking something out of a menu must not silently reroute work already using it.
Details worth knowing:
hiddenModels is a Set of
provider:modelrather than the array shape pinnedModels uses: it is only ever asked "is THIS model hidden?", once per row over a long list, and carries no order worth preserving.Tests: 5 checks over buildModelRows (hidden in no section, per-provider keying, a fully hidden provider drops its header, omitting the set changes nothing) and 6 against the real DB (hide unpins, idempotent, bulk replace stays scoped to its provider).