fix: model dialog issue when searching for models in fav/recents list, also ensure that deprecated models dont appear in list (#7429)

This commit is contained in:
Aiden Cline
2026-01-08 21:55:37 -08:00
committed by Frank
parent 445c8631a2
commit 07dc1f8ecc
2 changed files with 69 additions and 66 deletions

View File

@@ -33,76 +33,82 @@ export function DialogModel(props: { providerID?: string }) {
const options = createMemo(() => { const options = createMemo(() => {
const q = query() const q = query()
const favorites = showExtra() ? local.model.favorite() : [] const needle = q.trim()
const showSections = showExtra() && needle.length === 0
const favorites = connected() ? local.model.favorite() : []
const recents = local.model.recent() const recents = local.model.recent()
const recentList = showExtra() const recentList = showSections
? recents.filter( ? recents.filter(
(item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID), (item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID),
) )
: [] : []
const favoriteOptions = favorites.flatMap((item) => { const favoriteOptions = showSections
const provider = sync.data.provider.find((x) => x.id === item.providerID) ? favorites.flatMap((item) => {
if (!provider) return [] const provider = sync.data.provider.find((x) => x.id === item.providerID)
const model = provider.models[item.modelID] if (!provider) return []
if (!model) return [] const model = provider.models[item.modelID]
return [ if (!model) return []
{ return [
key: item, {
value: { key: item,
providerID: provider.id, value: {
modelID: model.id,
},
title: model.name ?? item.modelID,
description: provider.name,
category: "Favorites",
disabled: provider.id === "opencode" && model.id.includes("-nano"),
footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
onSelect: () => {
dialog.clear()
local.model.set(
{
providerID: provider.id, providerID: provider.id,
modelID: model.id, modelID: model.id,
}, },
{ recent: true }, title: model.name ?? item.modelID,
) description: provider.name,
}, category: "Favorites",
}, disabled: provider.id === "opencode" && model.id.includes("-nano"),
] footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
}) onSelect: () => {
dialog.clear()
local.model.set(
{
providerID: provider.id,
modelID: model.id,
},
{ recent: true },
)
},
},
]
})
: []
const recentOptions = recentList.flatMap((item) => { const recentOptions = showSections
const provider = sync.data.provider.find((x) => x.id === item.providerID) ? recentList.flatMap((item) => {
if (!provider) return [] const provider = sync.data.provider.find((x) => x.id === item.providerID)
const model = provider.models[item.modelID] if (!provider) return []
if (!model) return [] const model = provider.models[item.modelID]
return [ if (!model) return []
{ return [
key: item, {
value: { key: item,
providerID: provider.id, value: {
modelID: model.id,
},
title: model.name ?? item.modelID,
description: provider.name,
category: "Recent",
disabled: provider.id === "opencode" && model.id.includes("-nano"),
footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
onSelect: () => {
dialog.clear()
local.model.set(
{
providerID: provider.id, providerID: provider.id,
modelID: model.id, modelID: model.id,
}, },
{ recent: true }, title: model.name ?? item.modelID,
) description: provider.name,
}, category: "Recent",
}, disabled: provider.id === "opencode" && model.id.includes("-nano"),
] footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
}) onSelect: () => {
dialog.clear()
local.model.set(
{
providerID: provider.id,
modelID: model.id,
},
{ recent: true },
)
},
},
]
})
: []
const providerOptions = pipe( const providerOptions = pipe(
sync.data.provider, sync.data.provider,
@@ -145,6 +151,7 @@ export function DialogModel(props: { providerID?: string }) {
} }
}), }),
filter((x) => { filter((x) => {
if (!showSections) return true
const value = x.value const value = x.value
const inFavorites = favorites.some( const inFavorites = favorites.some(
(item) => item.providerID === value.providerID && item.modelID === value.modelID, (item) => item.providerID === value.providerID && item.modelID === value.modelID,
@@ -177,16 +184,11 @@ export function DialogModel(props: { providerID?: string }) {
) )
: [] : []
// Apply fuzzy filtering to each section separately, maintaining section order // Search shows a single merged list (favorites inline)
if (q) { if (needle) {
const filteredFavorites = fuzzysort.go(q, favoriteOptions, { keys: ["title"] }).map((x) => x.obj) const filteredProviders = fuzzysort.go(needle, providerOptions, { keys: ["title", "category"] }).map((x) => x.obj)
const filteredRecents = fuzzysort const filteredPopular = fuzzysort.go(needle, popularProviders, { keys: ["title"] }).map((x) => x.obj)
.go(q, recentOptions, { keys: ["title"] }) return [...filteredProviders, ...filteredPopular]
.map((x) => x.obj)
.slice(0, 5)
const filteredProviders = fuzzysort.go(q, providerOptions, { keys: ["title", "category"] }).map((x) => x.obj)
const filteredPopular = fuzzysort.go(q, popularProviders, { keys: ["title"] }).map((x) => x.obj)
return [...filteredFavorites, ...filteredRecents, ...filteredProviders, ...filteredPopular]
} }
return [...favoriteOptions, ...recentOptions, ...providerOptions, ...popularProviders] return [...favoriteOptions, ...recentOptions, ...providerOptions, ...popularProviders]

View File

@@ -852,6 +852,7 @@ export namespace Provider {
if (modelID === "gpt-5-chat-latest" || (providerID === "openrouter" && modelID === "openai/gpt-5-chat")) if (modelID === "gpt-5-chat-latest" || (providerID === "openrouter" && modelID === "openai/gpt-5-chat"))
delete provider.models[modelID] delete provider.models[modelID]
if (model.status === "alpha" && !Flag.OPENCODE_ENABLE_EXPERIMENTAL_MODELS) delete provider.models[modelID] if (model.status === "alpha" && !Flag.OPENCODE_ENABLE_EXPERIMENTAL_MODELS) delete provider.models[modelID]
if (model.status === "deprecated") delete provider.models[modelID]
if ( if (
(configProvider?.blacklist && configProvider.blacklist.includes(modelID)) || (configProvider?.blacklist && configProvider.blacklist.includes(modelID)) ||
(configProvider?.whitelist && !configProvider.whitelist.includes(modelID)) (configProvider?.whitelist && !configProvider.whitelist.includes(modelID))