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:
@@ -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]
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user