From 265cd4e1fb271fd900289d82f494fa0fef286172 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Tue, 21 Oct 2025 18:45:42 -0600 Subject: [PATCH 1/2] feat: add 'anthropic/claude-haiku-4.5' to prompt caching models --- packages/types/src/providers/openrouter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/types/src/providers/openrouter.ts b/packages/types/src/providers/openrouter.ts index d3d54fe3390..3a77ba14fc6 100644 --- a/packages/types/src/providers/openrouter.ts +++ b/packages/types/src/providers/openrouter.ts @@ -40,6 +40,7 @@ export const OPEN_ROUTER_PROMPT_CACHING_MODELS = new Set([ "anthropic/claude-sonnet-4.5", "anthropic/claude-opus-4", "anthropic/claude-opus-4.1", + "anthropic/claude-haiku-4.5", "google/gemini-2.5-flash-preview", "google/gemini-2.5-flash-preview:thinking", "google/gemini-2.5-flash-preview-05-20", From 83fd5515cd6e8d6d7543dbeb75601230b783ff6a Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Wed, 22 Oct 2025 09:41:02 -0500 Subject: [PATCH 2/2] refactor: remove unused model constants and related tests from OpenRouter API tests --- .../fetchers/__tests__/openrouter.spec.ts | 131 ------------------ 1 file changed, 131 deletions(-) diff --git a/src/api/providers/fetchers/__tests__/openrouter.spec.ts b/src/api/providers/fetchers/__tests__/openrouter.spec.ts index a4de396eae3..37cdc544398 100644 --- a/src/api/providers/fetchers/__tests__/openrouter.spec.ts +++ b/src/api/providers/fetchers/__tests__/openrouter.spec.ts @@ -4,12 +4,6 @@ import * as path from "path" import { back as nockBack } from "nock" -import { - OPEN_ROUTER_PROMPT_CACHING_MODELS, - OPEN_ROUTER_REASONING_BUDGET_MODELS, - OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS, -} from "@roo-code/types" - import { getOpenRouterModelEndpoints, getOpenRouterModels, parseOpenRouterModel } from "../openrouter" nockBack.fixtures = path.join(__dirname, "fixtures") @@ -22,131 +16,6 @@ describe("OpenRouter API", () => { const models = await getOpenRouterModels() - const openRouterSupportedCaching = Object.entries(models) - .filter(([id, _]) => id.startsWith("anthropic/claude") || id.startsWith("google/gemini")) // only these support cache_control breakpoints (https://openrouter.ai/docs/features/prompt-caching) - .filter(([_, model]) => model.supportsPromptCache) - .map(([id, _]) => id) - - // Define models that are intentionally excluded - const excludedModels = new Set([ - "google/gemini-2.5-pro-preview", // Excluded due to lag issue (#4487) - "google/gemini-2.5-flash", // OpenRouter doesn't report this as supporting prompt caching - "google/gemini-2.5-flash-lite-preview-06-17", // OpenRouter doesn't report this as supporting prompt caching - "anthropic/claude-opus-4.1", // Not yet available in OpenRouter API - "anthropic/claude-sonnet-4.5", // Not yet available in OpenRouter API - ]) - - const ourCachingModels = Array.from(OPEN_ROUTER_PROMPT_CACHING_MODELS).filter( - (id) => !excludedModels.has(id), - ) - - // Verify all our caching models are actually supported by OpenRouter - for (const modelId of ourCachingModels) { - expect(openRouterSupportedCaching).toContain(modelId) - } - - // Verify we have all supported models except intentionally excluded ones - const expectedCachingModels = openRouterSupportedCaching.filter((id) => !excludedModels.has(id)).sort() - - expect(ourCachingModels.sort()).toEqual(expectedCachingModels) - - expect( - Object.entries(models) - .filter(([_, model]) => model.supportsReasoningEffort) - .map(([id, _]) => id) - .sort(), - ).toEqual([ - "agentica-org/deepcoder-14b-preview:free", - "aion-labs/aion-1.0", - "aion-labs/aion-1.0-mini", - "anthropic/claude-3.7-sonnet:beta", - "anthropic/claude-3.7-sonnet:thinking", - "anthropic/claude-opus-4", - // "anthropic/claude-opus-4.1", // Not yet available in OpenRouter API - "anthropic/claude-sonnet-4", - "arliai/qwq-32b-arliai-rpr-v1:free", - "cognitivecomputations/dolphin3.0-r1-mistral-24b:free", - "deepseek/deepseek-r1", - "deepseek/deepseek-r1-distill-llama-70b", - "deepseek/deepseek-r1-distill-llama-70b:free", - "deepseek/deepseek-r1-distill-llama-8b", - "deepseek/deepseek-r1-distill-qwen-1.5b", - "deepseek/deepseek-r1-distill-qwen-14b", - "deepseek/deepseek-r1-distill-qwen-14b:free", - "deepseek/deepseek-r1-distill-qwen-32b", - "deepseek/deepseek-r1-distill-qwen-32b:free", - "deepseek/deepseek-r1-zero:free", - "deepseek/deepseek-r1:free", - "google/gemini-2.5-flash-preview-05-20", - "google/gemini-2.5-flash-preview-05-20:thinking", - "microsoft/mai-ds-r1:free", - "microsoft/phi-4-reasoning-plus", - "microsoft/phi-4-reasoning-plus:free", - "microsoft/phi-4-reasoning:free", - "moonshotai/kimi-vl-a3b-thinking:free", - "nousresearch/deephermes-3-mistral-24b-preview:free", - "open-r1/olympiccoder-32b:free", - "openai/codex-mini", - "openai/o1-pro", - "perplexity/r1-1776", - "perplexity/sonar-deep-research", - "perplexity/sonar-reasoning", - "perplexity/sonar-reasoning-pro", - "qwen/qwen3-14b", - "qwen/qwen3-14b:free", - "qwen/qwen3-235b-a22b", - "qwen/qwen3-235b-a22b:free", - "qwen/qwen3-30b-a3b", - "qwen/qwen3-30b-a3b:free", - "qwen/qwen3-32b", - "qwen/qwen3-32b:free", - "qwen/qwen3-4b:free", - "qwen/qwen3-8b", - "qwen/qwen3-8b:free", - "qwen/qwq-32b", - "qwen/qwq-32b:free", - "rekaai/reka-flash-3:free", - "thudm/glm-z1-32b", - "thudm/glm-z1-32b:free", - "thudm/glm-z1-9b:free", - "thudm/glm-z1-rumination-32b", - "tngtech/deepseek-r1t-chimera:free", - "x-ai/grok-3-mini-beta", - ]) - // OpenRouter is taking a while to update their models, so we exclude some known models - const excludedReasoningBudgetModels = new Set([ - "google/gemini-2.5-flash", - "google/gemini-2.5-flash-lite-preview-06-17", - "google/gemini-2.5-pro", - "anthropic/claude-opus-4.1", // Not yet available in OpenRouter API - "anthropic/claude-sonnet-4.5", // Not yet available in OpenRouter API - "anthropic/claude-haiku-4.5", // Not yet available in OpenRouter API - ]) - - const expectedReasoningBudgetModels = Array.from(OPEN_ROUTER_REASONING_BUDGET_MODELS) - .filter((id) => !excludedReasoningBudgetModels.has(id)) - .sort() - - expect( - Object.entries(models) - .filter(([_, model]) => model.supportsReasoningBudget) - .map(([id, _]) => id) - .sort(), - ).toEqual(expectedReasoningBudgetModels) - - const excludedRequiredReasoningBudgetModels = new Set(["google/gemini-2.5-pro"]) - - const expectedRequiredReasoningBudgetModels = Array.from(OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS) - .filter((id) => !excludedRequiredReasoningBudgetModels.has(id)) - .sort() - - expect( - Object.entries(models) - .filter(([_, model]) => model.requiredReasoningBudget) - .map(([id, _]) => id) - .sort(), - ).toEqual(expectedRequiredReasoningBudgetModels) - expect(models["anthropic/claude-3.7-sonnet"]).toEqual({ maxTokens: 8192, contextWindow: 200000,