Squashed 'third_party/pi/' content from commit d981de122
git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
This commit is contained in:
106
packages/coding-agent/test/model-selector.test.ts
Normal file
106
packages/coding-agent/test/model-selector.test.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { setKeybindings, type TUI } from "@earendil-works/pi-tui";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { KeybindingsManager } from "../src/core/keybindings.ts";
|
||||
import { ModelSelectorComponent } from "../src/modes/interactive/components/model-selector.ts";
|
||||
import { initTheme } from "../src/modes/interactive/theme/theme.ts";
|
||||
import { stripAnsi } from "../src/utils/ansi.ts";
|
||||
import { createHarness, type Harness } from "./suite/harness.ts";
|
||||
|
||||
function createFakeTui(): TUI {
|
||||
return { requestRender: () => {} } as unknown as TUI;
|
||||
}
|
||||
|
||||
describe("model selector", () => {
|
||||
let harness: Harness | undefined;
|
||||
|
||||
beforeAll(() => {
|
||||
initTheme("dark");
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
setKeybindings(new KeybindingsManager());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
harness?.cleanup();
|
||||
harness = undefined;
|
||||
});
|
||||
|
||||
it("keeps the current model marked while browsing", async () => {
|
||||
harness = await createHarness({
|
||||
models: [
|
||||
{ id: "current-model", name: "Current Model", reasoning: true },
|
||||
{ id: "browsed-model", name: "Browsed Model", reasoning: true },
|
||||
],
|
||||
});
|
||||
const currentModel = harness.getModel("current-model")!;
|
||||
const selector = new ModelSelectorComponent(
|
||||
createFakeTui(),
|
||||
currentModel,
|
||||
harness.session.modelRuntime,
|
||||
[],
|
||||
() => {},
|
||||
() => {},
|
||||
);
|
||||
|
||||
const getModelRow = (id: string): string | undefined =>
|
||||
stripAnsi(selector.render(120).join("\n"))
|
||||
.split("\n")
|
||||
.find((line) => line.includes(`${id} [`))
|
||||
?.trimEnd();
|
||||
|
||||
expect(getModelRow("current-model")).toBe(`→ ✓ current-model [${currentModel.provider}]`);
|
||||
selector.handleInput("\x1b[B");
|
||||
expect(getModelRow("current-model")).toBe(` ✓ current-model [${currentModel.provider}]`);
|
||||
expect(getModelRow("browsed-model")).toBe(`→ browsed-model [${currentModel.provider}]`);
|
||||
selector.dispose();
|
||||
});
|
||||
|
||||
it("uses the configured save binding", async () => {
|
||||
setKeybindings(new KeybindingsManager({ "app.models.save": "ctrl+r" }));
|
||||
harness = await createHarness();
|
||||
const currentModel = harness.getModel()!;
|
||||
const saveDefault = vi.fn();
|
||||
const selector = new ModelSelectorComponent(
|
||||
createFakeTui(),
|
||||
currentModel,
|
||||
harness.session.modelRuntime,
|
||||
[],
|
||||
() => {},
|
||||
() => {},
|
||||
undefined,
|
||||
saveDefault,
|
||||
);
|
||||
|
||||
expect(stripAnsi(selector.render(120).join("\n"))).toContain("Ctrl+R to set as default");
|
||||
selector.handleInput("\x13");
|
||||
expect(saveDefault).not.toHaveBeenCalled();
|
||||
selector.handleInput("\x12");
|
||||
expect(saveDefault).toHaveBeenCalledWith(currentModel);
|
||||
});
|
||||
|
||||
it("lists every catalog that failed to refresh", async () => {
|
||||
harness = await createHarness();
|
||||
vi.spyOn(harness.session.modelRuntime, "refresh").mockResolvedValue({
|
||||
aborted: false,
|
||||
errors: new Map([
|
||||
["openai", new Error("unavailable")],
|
||||
["anthropic", new Error("unavailable")],
|
||||
]),
|
||||
});
|
||||
|
||||
const selector = new ModelSelectorComponent(
|
||||
createFakeTui(),
|
||||
harness.getModel(),
|
||||
harness.session.modelRuntime,
|
||||
[],
|
||||
() => {},
|
||||
() => {},
|
||||
);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
const rendered = stripAnsi(selector.render(120).join("\n"));
|
||||
expect(rendered).toContain("Could not refresh 2 model catalogs (openai, anthropic); showing cached models.");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user