From 3aa38db57b58320fd16beed3f64bd512a6f2dd73 Mon Sep 17 00:00:00 2001 From: Mike Thicke Date: Thu, 14 May 2026 16:27:28 -0400 Subject: [PATCH] Update available models to current option set --- src/services/__tests__/model-registry.test.ts | 4 +- src/services/__tests__/model-service.test.ts | 27 +++--- src/services/model-registry.ts | 82 +++++++++---------- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/services/__tests__/model-registry.test.ts b/src/services/__tests__/model-registry.test.ts index a06bad7..f249d1c 100644 --- a/src/services/__tests__/model-registry.test.ts +++ b/src/services/__tests__/model-registry.test.ts @@ -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"); }); diff --git a/src/services/__tests__/model-service.test.ts b/src/services/__tests__/model-service.test.ts index 63d9768..0be4610 100644 --- a/src/services/__tests__/model-service.test.ts +++ b/src/services/__tests__/model-service.test.ts @@ -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" }]; diff --git a/src/services/model-registry.ts b/src/services/model-registry.ts index f3b7583..d9ad834 100644 --- a/src/services/model-registry.ts +++ b/src/services/model-registry.ts @@ -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,