mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-10 19:23:21 +00:00
fix(tui): keep model search order stable (#40753)
This commit is contained in:
parent
73581b3c3b
commit
56c33e84a3
2 changed files with 22 additions and 11 deletions
|
|
@ -7,12 +7,14 @@ import { DialogVariant } from "./dialog-variant"
|
|||
import * as fuzzysort from "fuzzysort"
|
||||
import { useConnected } from "./use-connected"
|
||||
import { useData } from "../context/data"
|
||||
import { modelPreferenceKey } from "../model-preference"
|
||||
|
||||
export function DialogModel(props: { providerID?: string }) {
|
||||
const local = useLocal()
|
||||
const data = useData()
|
||||
const dialog = useDialog()
|
||||
const [query, setQuery] = createSignal("")
|
||||
const favoritePriority = new Set(local.model.favorite().map(modelPreferenceKey))
|
||||
|
||||
const connected = useConnected()
|
||||
const providers = createMemo(() => new Map((data.location.provider.list() ?? []).map((item) => [item.id, item])))
|
||||
|
|
@ -63,14 +65,14 @@ export function DialogModel(props: { providerID?: string }) {
|
|||
.filter((model) => (props.providerID ? model.providerID === props.providerID : true))
|
||||
.map((model) => {
|
||||
const provider = providers().get(model.providerID)
|
||||
const favorite = favorites.some((item) => item.providerID === model.providerID && item.modelID === model.id)
|
||||
const key = modelPreferenceKey({ providerID: model.providerID, modelID: model.id })
|
||||
const favorite = favorites.some((item) => modelPreferenceKey(item) === key)
|
||||
return {
|
||||
value: { providerID: model.providerID, modelID: model.id },
|
||||
providerID: model.providerID,
|
||||
providerName: provider?.name ?? model.providerID,
|
||||
title: model.name,
|
||||
releaseDate: model.time.released,
|
||||
favorite,
|
||||
description: favorite ? "(Favorite)" : undefined,
|
||||
category: connected() ? (provider?.name ?? model.providerID) : undefined,
|
||||
footer: free(model) ? "Free" : undefined,
|
||||
|
|
@ -98,6 +100,7 @@ export function DialogModel(props: { providerID?: string }) {
|
|||
if (needle) {
|
||||
return prioritizeFavorites(
|
||||
fuzzysort.go(needle, modelOptions, { keys: ["title", "category"] }).map((item) => item.obj),
|
||||
favoritePriority,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -162,8 +165,13 @@ export function DialogModel(props: { providerID?: string }) {
|
|||
)
|
||||
}
|
||||
|
||||
export function prioritizeFavorites<T extends { favorite: boolean }>(options: T[]) {
|
||||
return options.toSorted((a, b) => Number(b.favorite) - Number(a.favorite))
|
||||
export function prioritizeFavorites<T extends { value: { providerID: string; modelID: string } }>(
|
||||
options: T[],
|
||||
favorites: Set<string>,
|
||||
) {
|
||||
return options.toSorted(
|
||||
(a, b) => Number(favorites.has(modelPreferenceKey(b.value))) - Number(favorites.has(modelPreferenceKey(a.value))),
|
||||
)
|
||||
}
|
||||
|
||||
export function sortModelOptions<
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@ import { describe, expect, test } from "bun:test"
|
|||
import { prioritizeFavorites, sortModelOptions } from "../../../../src/component/dialog-model"
|
||||
|
||||
describe("prioritizeFavorites", () => {
|
||||
test("moves favorites first while preserving fuzzy result order", () => {
|
||||
const prioritized = prioritizeFavorites([
|
||||
{ title: "Best match", favorite: false },
|
||||
{ title: "Favorite match", favorite: true },
|
||||
{ title: "Second best match", favorite: false },
|
||||
{ title: "Second favorite match", favorite: true },
|
||||
])
|
||||
test("uses the favorite order captured when the dialog opened", () => {
|
||||
const prioritized = prioritizeFavorites(
|
||||
[
|
||||
{ title: "Best match", value: { providerID: "test", modelID: "best" } },
|
||||
{ title: "Favorite match", value: { providerID: "test", modelID: "favorite" } },
|
||||
{ title: "Second best match", value: { providerID: "test", modelID: "second-best" } },
|
||||
{ title: "Second favorite match", value: { providerID: "test", modelID: "second-favorite" } },
|
||||
],
|
||||
new Set(["test/favorite", "test/second-favorite"]),
|
||||
)
|
||||
|
||||
expect(prioritized.map((model) => model.title)).toEqual([
|
||||
"Favorite match",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue