Update available models to current option set

This commit is contained in:
Mike Thicke 2026-05-14 16:27:28 -04:00
parent 86960b51d7
commit 3aa38db57b
3 changed files with 57 additions and 56 deletions

View file

@ -189,8 +189,8 @@ describe("ModelRegistry", () => {
it("returns model by ID", () => {
const plugin = createMockPlugin({ apiKeys: { openai: "sk-1" } });
const registry = ModelRegistry.getInstance(plugin);
const model = registry.getModel("openai:gpt-4o");
expect(model.id).toBe("openai:gpt-4o");
const model = registry.getModel("openai:gpt-5.4-mini");
expect(model.id).toBe("openai:gpt-5.4-mini");
expect(model.provider).toBe("openai");
});

View file

@ -60,12 +60,13 @@ function createMockPlugin(
): CoIntelligencePlugin {
const app = new App();
app.secretStorage.setSecret(API_KEY_SECRET_IDS.openai, "sk-test");
app.secretStorage.setSecret(API_KEY_SECRET_IDS.perplexity, "pplx-test");
return {
app,
settings: {
defaultFolder: "coi",
defaultModel: "",
renamingModel: "openai:gpt-4o" as ModelId,
renamingModel: "openai:gpt-5.4-mini" as ModelId,
systemPromptFolder: "coi/prompts",
defaultSystemPromptNote: "",
...settings,
@ -91,7 +92,7 @@ describe("generateChatResponse", () => {
it("calls streamText with the correct model", async () => {
const request: ChatRequest = {
requestID: "test-1",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [{ role: "user", content: "Hello" }],
};
await generateChatResponse(request, registry);
@ -106,7 +107,7 @@ describe("generateChatResponse", () => {
it("includes system prompt when provided", async () => {
const request: ChatRequest = {
requestID: "test-2",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [{ role: "user", content: "Hello" }],
systemPrompt: "You are a pirate.",
};
@ -121,7 +122,7 @@ describe("generateChatResponse", () => {
it("appends web search instructions when webSearch is true", async () => {
const request: ChatRequest = {
requestID: "test-3",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [{ role: "user", content: "Latest news" }],
webSearch: true,
};
@ -136,7 +137,7 @@ describe("generateChatResponse", () => {
it("appends context to system prompt when provided", async () => {
const request: ChatRequest = {
requestID: "test-4",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [{ role: "user", content: "Hello" }],
context: [{ title: "Note A", content: "Important info" }],
};
@ -149,10 +150,10 @@ describe("generateChatResponse", () => {
});
it("disables web search for models that don't support it", async () => {
// o1 has toggleWebSearch: false
// perplexity:sonar has toggleWebSearch: false (Perplexity is always web-grounded)
const request: ChatRequest = {
requestID: "test-5",
modelId: "openai:o1",
modelId: "perplexity:sonar",
messages: [{ role: "user", content: "Hello" }],
webSearch: true,
};
@ -176,7 +177,7 @@ describe("cancelChatResponse", () => {
it("cancels an active request", async () => {
const request: ChatRequest = {
requestID: "cancel-test",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [{ role: "user", content: "Hello" }],
};
await generateChatResponse(request, registry);
@ -187,7 +188,7 @@ describe("cancelChatResponse", () => {
it("does nothing for unknown request ID", () => {
const request: ChatRequest = {
requestID: "nonexistent",
modelId: "openai:gpt-4o",
modelId: "openai:gpt-5.4-mini",
messages: [],
};
// Should not throw
@ -204,7 +205,7 @@ describe("generateChatTitle", () => {
});
it("generates a title from messages", async () => {
const plugin = createMockPlugin({ renamingModel: "openai:gpt-4o" as ModelId });
const plugin = createMockPlugin({ renamingModel: "openai:gpt-5.4-mini" as ModelId });
ModelRegistry.getInstance(plugin);
const messages = [
@ -231,7 +232,7 @@ describe("generateChatTitle", () => {
text: "Title/with\\bad:chars",
} as never);
const plugin = createMockPlugin({ renamingModel: "openai:gpt-4o" as ModelId });
const plugin = createMockPlugin({ renamingModel: "openai:gpt-5.4-mini" as ModelId });
ModelRegistry.getInstance(plugin);
const messages = [{ role: "user" as const, content: "Hello" }];
@ -246,7 +247,7 @@ describe("generateChatTitle", () => {
text: "A".repeat(100),
} as never);
const plugin = createMockPlugin({ renamingModel: "openai:gpt-4o" as ModelId });
const plugin = createMockPlugin({ renamingModel: "openai:gpt-5.4-mini" as ModelId });
ModelRegistry.getInstance(plugin);
const messages = [{ role: "user" as const, content: "Hello" }];
@ -258,7 +259,7 @@ describe("generateChatTitle", () => {
it("returns empty string on generation error", async () => {
vi.mocked(generateText).mockRejectedValueOnce(new Error("API error"));
const plugin = createMockPlugin({ renamingModel: "openai:gpt-4o" as ModelId });
const plugin = createMockPlugin({ renamingModel: "openai:gpt-5.4-mini" as ModelId });
ModelRegistry.getInstance(plugin);
const messages = [{ role: "user" as const, content: "Hello" }];

View file

@ -84,91 +84,83 @@ export class ModelRegistry {
private updateAvailableModels(initializedProviders: string[]): void {
const allModels: Model[] = [
{
id: "openai:gpt-4o",
id: "openai:gpt-5.5",
provider: "openai",
name: "OpenAI GPT-4o",
name: "OpenAI GPT-5.5",
renaming: true,
toggleWebSearch: true,
streaming: true,
},
{
id: "openai:gpt-4.1",
id: "openai:gpt-5.4",
provider: "openai",
name: "OpenAI GPT-4.1",
name: "OpenAI GPT-5.4",
renaming: true,
toggleWebSearch: true,
streaming: true,
},
{
id: "openai:gpt-4.1-nano",
id: "openai:gpt-5.4-mini",
provider: "openai",
name: "OpenAI GPT-4.1 Nano",
name: "OpenAI GPT-5.4 Mini",
renaming: true,
toggleWebSearch: true,
streaming: true,
},
{
id: "openai:gpt-4.1-mini",
id: "openai:gpt-5.4-nano",
provider: "openai",
name: "OpenAI GPT-4.1 Mini",
name: "OpenAI GPT-5.4 Nano",
renaming: true,
toggleWebSearch: true,
streaming: true,
},
{
id: "openai:o1",
provider: "openai",
name: "OpenAI O1",
renaming: false,
toggleWebSearch: false,
streaming: true,
},
{
id: "openai:o3",
provider: "openai",
name: "OpenAI O3",
renaming: false,
toggleWebSearch: false,
streaming: true,
},
{
id: "anthropic:claude-4-sonnet-20250514",
id: "anthropic:claude-opus-4-7",
provider: "anthropic",
name: "Anthropic Claude 4 Sonnet",
renaming: true,
name: "Anthropic Claude Opus 4.7",
renaming: false,
toggleWebSearch: false,
streaming: true,
},
{
id: "anthropic:claude-4-opus-20250514",
id: "anthropic:claude-sonnet-4-6",
provider: "anthropic",
name: "Anthropic Claude 4 Opus",
renaming: false,
name: "Anthropic Claude Sonnet 4.6",
renaming: true,
toggleWebSearch: false,
streaming: true,
},
{
id: "google:gemini-2.0-flash",
id: "anthropic:claude-haiku-4-5-20251001",
provider: "anthropic",
name: "Anthropic Claude Haiku 4.5",
renaming: true,
toggleWebSearch: false,
streaming: true,
},
{
id: "google:gemini-3.1-pro-preview",
provider: "google",
name: "Google Gemini 2.0 Flash",
name: "Google Gemini 3.1 Pro Preview",
renaming: false,
toggleWebSearch: true,
streaming: true,
},
{
id: "google:gemini-2.5-flash-preview-04-17",
id: "google:gemini-3-flash-preview",
provider: "google",
name: "Google Gemini 2.5 Flash Preview",
name: "Google Gemini 3 Flash Preview",
renaming: true,
toggleWebSearch: true,
streaming: true,
},
{
id: "google:gemini-2.5-pro-preview-05-06",
id: "google:gemini-3.1-flash-lite",
provider: "google",
name: "Google Gemini 2.5 Pro Preview",
name: "Google Gemini 3.1 Flash Lite",
renaming: true,
toggleWebSearch: false,
toggleWebSearch: true,
streaming: true,
},
{
@ -180,17 +172,25 @@ export class ModelRegistry {
streaming: true,
},
{
id: "perplexity:sonar-deep-research",
id: "perplexity:sonar-pro",
provider: "perplexity",
name: "Perplexity Sonar Deep Research",
name: "Perplexity Sonar Pro",
renaming: false,
toggleWebSearch: false,
streaming: true,
},
{
id: "perplexity:sonar-reasoning",
id: "perplexity:sonar-reasoning-pro",
provider: "perplexity",
name: "Perplexity Sonar Reasoning",
name: "Perplexity Sonar Reasoning Pro",
renaming: false,
toggleWebSearch: false,
streaming: true,
},
{
id: "perplexity:sonar-deep-research",
provider: "perplexity",
name: "Perplexity Sonar Deep Research",
renaming: false,
toggleWebSearch: false,
streaming: true,