- Prioritized fuzzy match quality over the most-recently-used model order when filtering the model browser. - Added bucketing to match scores to ensure stable sorting when match quality is identical. - Added unit tests to verify that exact query matches take precedence over the MRU model.
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import type { Model } from "@oh-my-pi/pi-ai";
|
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
|
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
|
import {
|
|
buildBrowserItems,
|
|
ModelBrowser,
|
|
sortModelItems,
|
|
} from "@oh-my-pi/pi-coding-agent/modes/components/model-browser";
|
|
|
|
function makeModel(provider: string, id: string): Model {
|
|
return buildModel({
|
|
id,
|
|
name: id,
|
|
api: "ollama-chat",
|
|
provider,
|
|
baseUrl: "https://example.com",
|
|
reasoning: false,
|
|
input: ["text"],
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
contextWindow: 128_000,
|
|
maxTokens: 1024,
|
|
});
|
|
}
|
|
|
|
/** Browser preloaded with `models`, MRU-sorted like the hub does on sync. */
|
|
function makeBrowser(models: Model[], mruOrder: string[]): ModelBrowser {
|
|
const browser = new ModelBrowser(Settings.isolated({}));
|
|
const items = buildBrowserItems(models);
|
|
sortModelItems(items, { mruOrder });
|
|
browser.setMruOrder(mruOrder);
|
|
browser.setItems(items);
|
|
return browser;
|
|
}
|
|
|
|
describe("ModelBrowser search ranking", () => {
|
|
test("an exact query match outranks the MRU model", () => {
|
|
// Regression: with gpt-5.6-sol as the active (MRU) model, typing
|
|
// "gpt-5.5" must select gpt-5.5, not keep the MRU pinned on top.
|
|
const browser = makeBrowser(
|
|
[
|
|
makeModel("openai-codex", "gpt-5.6-sol"),
|
|
makeModel("openai-codex", "gpt-5.6-luna"),
|
|
makeModel("openai-codex", "gpt-5.5"),
|
|
makeModel("openai-codex", "gpt-5.4"),
|
|
],
|
|
["openai-codex/gpt-5.6-sol", "openai-codex/gpt-5.6-luna"],
|
|
);
|
|
|
|
browser.setQuery("gpt-5.5");
|
|
|
|
expect(browser.getSelected()?.selector).toBe("openai-codex/gpt-5.5");
|
|
});
|
|
|
|
test("MRU breaks ties between equally good matches", () => {
|
|
// Same model id under two providers: match quality is identical, so
|
|
// the recently used provider must win over alphabetical order.
|
|
const browser = makeBrowser([makeModel("g0i", "gpt-5.5"), makeModel("zenmux", "gpt-5.5")], ["zenmux/gpt-5.5"]);
|
|
|
|
browser.setQuery("gpt-5.5");
|
|
|
|
expect(browser.getSelected()?.selector).toBe("zenmux/gpt-5.5");
|
|
});
|
|
});
|