Skip to content

/model picker: Recent and Favorites rows don't show which provider they belong to, so selecting one silently switches provider #840

Description

@PierrunoYT

Version / branch / commit

main @ d37de92 (zero 0.6.0)

OS and environment

Windows 11 / PowerShell / Go 1.26.5

Summary

In the /model picker, rows under the Recent and Favorites groups show only the model name ÔÇö the provider that owns the row is not displayed anywhere. Selecting such a row can silently switch the active provider, which is a change with real billing consequences (subscription vs. metered API key), and there is no indication of that before you press Enter.

Steps to reproduce

  1. Have two saved providers that both offer the same or similar model IDs ÔÇö e.g. chatgpt (Plus/Pro OAuth subscription) and openai (API key).
  2. Open /model.
  3. Pick a model from the Recent group.

Expected behavior

Each row makes its owning provider visible before selection, so it is clear whether you are picking chatgpt ┬À gpt-5.x or openai ┬À gpt-5.x. Provider-grouped rows already get this for free via the group header; Recent/Favorites should not lose it.

Actual behavior

Recent/Favorites rows are labeled with the model only. Two rows for the same model ID from two different providers render identically and are indistinguishable. Choosing one switches the provider silently, and you only find out afterwards from the small Switched to <provider> ┬À <model> recap line ÔÇö easy to miss.

In my case this meant picking a gpt-5.6 row and unknowingly landing on the metered openai API-key provider instead of my ChatGPT subscription, which then failed with a "no credits remaining" error.

Where this comes from

pickerItem already carries the owning provider in OwnerProvider (internal/tui/picker.go:45), and it is used for two things:

  • cross-group de-duplication ÔÇö pickerItemDedupKey (picker.go:443) deliberately keys Recent/Favorites rows by provider + model precisely because "the same model id can be offered by multiple providers ... and those are distinct, independently selectable rows";
  • the selection action ÔÇö model.go:4215 switches provider when OwnerProvider differs from the active one.

But OwnerProvider is never rendered. Row labels are built from the model alone:

  • modelPickerRecentItem ÔåÆ providerModelPickerItem(...) / registryModelPickerItem(...), Label: modelPickerDisplayName(model.ID, model.Description) (picker.go:519-575)
  • the fallback row at picker.go:543 likewise uses modelPickerDisplayName(modelID, "")

For provider-grouped rows the provider is conveyed by the group header (modelPickerProviderGroup, picker.go:349), but Recent and Favorites use the literal group names "Recent"/"Favorites", so that channel is gone. The result is that the picker knowingly keeps two distinct rows that look identical to the user.

Suggested fix

Render OwnerProvider on rows whose group doesn't already identify the provider (Recent, Favorites) ÔÇö e.g. a chatgpt ┬À gpt-5.6-sol label, or the provider shown as row meta / a right-aligned tag. Highlighting when a highlighted row would change the active provider (and not just the model) would make the billing-relevant switch obvious before Enter rather than after.

Related

Same underlying confusion as #839, from the UI side rather than the discovery side.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions