summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-01-08 21:55:37 -0800
committerFrank <[email protected]>2026-01-09 01:32:00 -0500
commit07dc1f8ecc8fd7f7d5f6ec4e097e93465d4f6b6b (patch)
treeccddc277b02bf817c489d7b9fb62b7abe31e52c0
parent445c8631a242c64a3856daca8c21eeff48b7f2d0 (diff)
downloadopencode-07dc1f8ecc8fd7f7d5f6ec4e097e93465d4f6b6b.tar.gz
opencode-07dc1f8ecc8fd7f7d5f6ec4e097e93465d4f6b6b.zip
fix: model dialog issue when searching for models in fav/recents list, also ensure that deprecated models dont appear in list (#7429)
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx134
-rw-r--r--packages/opencode/src/provider/provider.ts1
2 files changed, 69 insertions, 66 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx
index 50cf43896..71a7d22b8 100644
--- a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx
@@ -33,76 +33,82 @@ export function DialogModel(props: { providerID?: string }) {
const options = createMemo(() => {
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 recentList = showExtra()
+ const recentList = showSections
? recents.filter(
(item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID),
)
: []
- const favoriteOptions = favorites.flatMap((item) => {
- const provider = sync.data.provider.find((x) => x.id === item.providerID)
- if (!provider) return []
- const model = provider.models[item.modelID]
- if (!model) return []
- return [
- {
- key: item,
- value: {
- providerID: provider.id,
- 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(
- {
+ const favoriteOptions = showSections
+ ? favorites.flatMap((item) => {
+ const provider = sync.data.provider.find((x) => x.id === item.providerID)
+ if (!provider) return []
+ const model = provider.models[item.modelID]
+ if (!model) return []
+ return [
+ {
+ key: item,
+ value: {
providerID: provider.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 provider = sync.data.provider.find((x) => x.id === item.providerID)
- if (!provider) return []
- const model = provider.models[item.modelID]
- if (!model) return []
- return [
- {
- key: item,
- value: {
- providerID: provider.id,
- 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(
- {
+ const recentOptions = showSections
+ ? recentList.flatMap((item) => {
+ const provider = sync.data.provider.find((x) => x.id === item.providerID)
+ if (!provider) return []
+ const model = provider.models[item.modelID]
+ if (!model) return []
+ return [
+ {
+ key: item,
+ value: {
providerID: provider.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(
sync.data.provider,
@@ -145,6 +151,7 @@ export function DialogModel(props: { providerID?: string }) {
}
}),
filter((x) => {
+ if (!showSections) return true
const value = x.value
const inFavorites = favorites.some(
(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
- if (q) {
- const filteredFavorites = fuzzysort.go(q, favoriteOptions, { keys: ["title"] }).map((x) => x.obj)
- const filteredRecents = fuzzysort
- .go(q, recentOptions, { keys: ["title"] })
- .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]
+ // Search shows a single merged list (favorites inline)
+ if (needle) {
+ const filteredProviders = fuzzysort.go(needle, providerOptions, { keys: ["title", "category"] }).map((x) => x.obj)
+ const filteredPopular = fuzzysort.go(needle, popularProviders, { keys: ["title"] }).map((x) => x.obj)
+ return [...filteredProviders, ...filteredPopular]
}
return [...favoriteOptions, ...recentOptions, ...providerOptions, ...popularProviders]
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index 9f14b5464..9b01eae9e 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -852,6 +852,7 @@ export namespace Provider {
if (modelID === "gpt-5-chat-latest" || (providerID === "openrouter" && modelID === "openai/gpt-5-chat"))
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 (
(configProvider?.blacklist && configProvider.blacklist.includes(modelID)) ||
(configProvider?.whitelist && !configProvider.whitelist.includes(modelID))