Files
oh-my-pi/packages/coding-agent/test/model-selector-role-badge-thinking.test.ts
T
roboompandcan1357 294f0067d0 fix(tui): refreshed model tabs by provider id
Separated model selector provider tab labels from provider ids so human-readable labels like Ollama Cloud refresh and filter the underlying ollama-cloud models.

Fixes #1153
2026-05-25 12:25:12 +02:00

162 lines
4.7 KiB
TypeScript

import { beforeAll, describe, expect, test, vi } from "bun:test";
import { getBundledModel, type Model } from "@oh-my-pi/pi-ai";
import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
import { ModelSelectorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/model-selector";
import { getThemeByName, setThemeInstance } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
import type { TUI } from "@oh-my-pi/pi-tui";
function normalizeRenderedText(text: string): string {
return (
text
// strip ANSI escapes
.replace(/\x1b\[[0-9;]*m/g, "")
// collapse whitespace
.replace(/\s+/g, " ")
.trim()
);
}
function createSelector(model: Model, settings: Settings): ModelSelectorComponent {
const modelRegistry = {
getAll: () => [model],
getDiscoverableProviders: () => [],
getCanonicalModels: () => [],
resolveCanonicalModel: () => undefined,
} as unknown as ModelRegistry;
const ui = {
requestRender: vi.fn(),
} as unknown as TUI;
return new ModelSelectorComponent(
ui,
model,
settings,
modelRegistry,
[{ model, thinkingLevel: "off" }],
() => {},
() => {},
);
}
function createOllamaCloudModel(id: string): Model {
return {
id,
name: "DeepSeek V4 Pro",
api: "ollama-chat",
provider: "ollama-cloud",
baseUrl: "https://ollama.com",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1_000_000,
maxTokens: 8192,
};
}
let testTheme = await getThemeByName("dark");
function installTestTheme(): void {
if (!testTheme) {
throw new Error("Failed to load dark theme for ModelSelector tests");
}
setThemeInstance(testTheme);
}
describe("ModelSelector role badge thinking display", () => {
beforeAll(async () => {
testTheme = await getThemeByName("dark");
if (!testTheme) {
throw new Error("Failed to load dark theme for ModelSelector tests");
}
});
test("shows custom roles from cycleOrder/modelRoles and honors built-in metadata overrides", async () => {
installTestTheme();
const model = getBundledModel("anthropic", "claude-sonnet-4-5");
if (!model) throw new Error("Expected bundled model anthropic/claude-sonnet-4-5");
const settings = Settings.isolated({
cycleOrder: ["smol", "custom-fast", "default"],
modelRoles: {
default: `${model.provider}/${model.id}`,
"custom-fast": `${model.provider}/${model.id}:low`,
smol: `${model.provider}/${model.id}`,
},
modelTags: {
smol: { name: "Quick", color: "error" },
},
});
const selector = createSelector(model, settings);
await Bun.sleep(0);
installTestTheme();
const rendered = normalizeRenderedText(selector.render(220).join("\n"));
expect(rendered).toContain("custom-fast (low)");
expect(rendered).toContain("SMOL (inherit)");
selector.handleInput("\n");
installTestTheme();
const menuRendered = normalizeRenderedText(selector.render(220).join("\n"));
expect(menuRendered).toContain("Set as custom-fast");
expect(menuRendered).toContain("Set as SMOL (Quick)");
});
test("refreshes Ollama Cloud using provider id instead of tab label", async () => {
installTestTheme();
const settings = Settings.isolated({});
const discoveredModel = createOllamaCloudModel("deepseek-v4-pro");
let availableModels: Model[] = [];
const refreshProvider = vi.fn(async (providerId: string) => {
if (providerId === "ollama-cloud") {
availableModels = [discoveredModel];
}
});
const modelRegistry = {
getAll: () => availableModels,
refresh: vi.fn(async () => {}),
refreshProvider,
getError: () => undefined,
getAvailable: () => availableModels,
getDiscoverableProviders: () => ["ollama-cloud"],
getCanonicalModels: () => [],
resolveCanonicalModel: () => undefined,
getProviderDiscoveryState: () => ({
provider: "ollama-cloud",
status: "idle",
optional: false,
stale: false,
models: [],
}),
} as unknown as ModelRegistry;
const ui = {
requestRender: vi.fn(),
} as unknown as TUI;
const selector = new ModelSelectorComponent(
ui,
undefined,
settings,
modelRegistry,
[],
() => {},
() => {},
);
await Bun.sleep(0);
installTestTheme();
const initialRendered = normalizeRenderedText(selector.render(220).join("\n"));
expect(initialRendered).toContain("OLLAMA CLOUD");
selector.handleInput("\t");
selector.handleInput("\t");
await Bun.sleep(0);
installTestTheme();
expect(refreshProvider).toHaveBeenCalledWith("ollama-cloud");
const rendered = normalizeRenderedText(selector.render(220).join("\n"));
expect(rendered).toContain("deepseek-v4-pro");
expect(rendered).not.toContain("Provider has not been refreshed yet");
});
});