fix(picker): browse views skip the non-language tail

The catalog browse views are a way to find a model to talk to, but 445 of
the 8,849 live rows are image, embedding, video, speech, transcription,
reranking or realtime models. They crowded the roster between the chat
models a user was looking for. Measured in the live
models-dev-catalog.json: image 181, embedding 82, video 69, speech 42,
transcription 38, reranking 17, realtime 16 against 8 chat rows.

The picker now carries the offering's `type` into its row metadata and
the Catalog, New, Coding, Cheap and LongContext views skip non-language
rows. The Configured view is untouched -- a route the user already set up
must stay visible -- and an active search bypasses the gate, so typing an
image model's id still reaches it.

Verified: cargo check -p codewhale-tui --locked green (12.87s, one E0063
for the new field fixed first); cargo test -p codewhale-tui --lib --locked
model_picker:: -> 33 passed, 0 failed, 15354 filtered out, 98.7s.
This commit is contained in:
CodeWhale Bot committed 2026-10-23 08:44:29 -07:00
1 parent 660672a0b6
commit 799546d179
1 file changed
+16 -1
+16 -1
View File
@@ -397,6 +397,7 @@ struct EffectivePickerMetadata {
vision: SupportState,
pricing: PickerPricing,
source: Option<CatalogSource>,
model_type: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
@@ -3286,6 +3287,7 @@ fn fit_meta_chips(chips: &[String], width: usize) -> String {
fn model_row_visible_in_view(row: &ModelPickerRow, view: ModelListView) -> bool {
match view {
ModelListView::Configured => model_row_visible_by_default(row),
ModelListView::Catalog if model_is_non_language(row) => false,
ModelListView::Catalog => true,
ModelListView::New
| ModelListView::Coding
@@ -3293,11 +3295,20 @@ fn model_row_visible_in_view(row: &ModelPickerRow, view: ModelListView) -> bool
| ModelListView::LongContext => {
// Discoverability views browse the full lake but hide the synthetic
// `auto` row — it is not a catalog offering.
row.provider.is_some() || row.id != "auto"
(row.provider.is_some() || row.id != "auto") && !model_is_non_language(row)
}
}
}
fn model_is_non_language(row: &ModelPickerRow) -> bool {
matches!(
row.metadata.model_type.as_deref(),
Some(
"image" | "embedding" | "video" | "speech" | "transcription" | "reranking" | "realtime"
)
)
}
/// Whether a model row shows up without the user typing a search query:
/// `auto` and every row placed in a default-view section (#6533). The rest of
/// every roster, the active one included, is one search or ⇧A away.
@@ -3663,6 +3674,7 @@ fn effective_picker_metadata_with_codex(
.is_none_or(|meta| meta.reasoning.is_none()),
declared_input_price: None,
source: None,
model_type: None,
};
};
@@ -3858,6 +3870,9 @@ fn effective_picker_metadata_with_codex(
},
declared_input_price: None,
source: card.map(|card| card.source),
model_type: offering
.as_ref()
.and_then(|offering| offering.model_type.clone()),
}
}