ソースを参照

feat(tui): prioritize favorite model search results (#40049)

Kit Langton 2 週間 前
コミット
e872bd3c8f

+ 10 - 4
packages/tui/src/component/dialog-model.tsx

@@ -63,15 +63,15 @@ 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)
           return {
             value: { providerID: model.providerID, modelID: model.id },
             providerID: model.providerID,
             providerName: provider?.name ?? model.providerID,
             title: model.name,
             releaseDate: model.time.released,
-            description: favorites.some((item) => item.providerID === model.providerID && item.modelID === model.id)
-              ? "(Favorite)"
-              : undefined,
+            favorite,
+            description: favorite ? "(Favorite)" : undefined,
             category: connected() ? (provider?.name ?? model.providerID) : undefined,
             footer: free(model) ? "Free" : undefined,
             onSelect() {
@@ -96,7 +96,9 @@ export function DialogModel(props: { providerID?: string }) {
     )
 
     if (needle) {
-      return fuzzysort.go(needle, modelOptions, { keys: ["title", "category"] }).map((item) => item.obj)
+      return prioritizeFavorites(
+        fuzzysort.go(needle, modelOptions, { keys: ["title", "category"] }).map((item) => item.obj),
+      )
     }
 
     return [...favoriteOptions, ...recentOptions, ...modelOptions]
@@ -160,6 +162,10 @@ 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 sortModelOptions<
   T extends { providerID?: string; providerName?: string; releaseDate: string | number; title: string },
 >(options: T[]) {

+ 19 - 1
packages/tui/test/cli/cmd/tui/model-options.test.ts

@@ -1,5 +1,23 @@
 import { describe, expect, test } from "bun:test"
-import { sortModelOptions } from "../../../../src/component/dialog-model"
+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 },
+    ])
+
+    expect(prioritized.map((model) => model.title)).toEqual([
+      "Favorite match",
+      "Second favorite match",
+      "Best match",
+      "Second best match",
+    ])
+  })
+})
 
 describe("sortModelOptions", () => {
   test("orders opencode models before other providers", () => {