fix(tui): preserve model release ordering in search (#47183)

Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot]
2026-09-03 23:18:09 -05:00
committed by GitHub
parent ffac1c5b11
commit c907d2ba27
2 changed files with 33 additions and 5 deletions
+18 -5
View File
@@ -99,11 +99,15 @@ export function DialogModel(props: { providerID?: string }) {
return false
return true
}),
connected(),
)
if (needle) {
return prioritizeFavorites(
fuzzysort.go(needle, modelOptions, { keys: ["title", "category"] }).map((item) => item.obj),
sortModelOptions(
fuzzysort.go(needle, modelOptions, { keys: ["title", "category"] }).map((item) => item.obj),
false,
),
favoritePriority,
)
}
@@ -179,15 +183,24 @@ export function prioritizeFavorites<T extends { value: { providerID: string; mod
}
export function sortModelOptions<
T extends { providerID?: string; providerName?: string; releaseDate: string | number; title: string },
>(options: T[]) {
T extends {
providerID?: string
providerName?: string
releaseDate: string | number
title: string
footer?: string
},
>(options: T[], grouped = true) {
return options.toSorted((a, b) => {
const provider = Number(a.providerID !== "opencode") - Number(b.providerID !== "opencode")
const provider = grouped ? Number(a.providerID !== "opencode") - Number(b.providerID !== "opencode") : 0
if (provider !== 0) return provider
const name = (a.providerName ?? "").localeCompare(b.providerName ?? "")
const name = grouped ? (a.providerName ?? "").localeCompare(b.providerName ?? "") : 0
if (name !== 0) return name
const free = Number(b.footer === "Free") - Number(a.footer === "Free")
if (free !== 0) return free
const release = Number(b.releaseDate) - Number(a.releaseDate)
if (release !== 0) return release
@@ -1,4 +1,5 @@
import { describe, expect, test } from "bun:test"
import { go } from "fuzzysort"
import { prioritizeFavorites, sortModelOptions } from "../../../../src/component/dialog-model"
describe("prioritizeFavorites", () => {
@@ -23,6 +24,20 @@ describe("prioritizeFavorites", () => {
})
describe("sortModelOptions", () => {
test.each(["browse", "search", "provider"])("orders %s results free-first, then newest-first", (mode) => {
const options = [
{ providerID: "opencode", title: "Claude Haiku 3", releaseDate: 1 },
{ providerID: "anthropic", title: "Claude Haiku 4.5", releaseDate: 2 },
{ providerID: "anthropic", title: "Claude Haiku Free", releaseDate: 0, footer: "Free" },
].map((item) => ({ ...item, providerID: mode === "provider" ? "anthropic" : item.providerID }))
const matches = mode === "search" ? go("haik", options, { key: "title" }).map((item) => item.obj) : options
expect(sortModelOptions(matches, mode === "provider").map((item) => item.title)).toEqual([
"Claude Haiku Free",
"Claude Haiku 4.5",
"Claude Haiku 3",
])
})
test("orders opencode models before other providers", () => {
const sorted = sortModelOptions([
{ providerID: "openai", providerName: "OpenAI", releaseDate: 3, title: "GPT 5" },