From ba7f69a5298faf652621ff9a0b660b392f041cea Mon Sep 17 00:00:00 2001 From: Roo Code Date: Fri, 18 Jul 2025 12:03:54 +0000 Subject: [PATCH] feat: add image support for moonshotai/kimi-k2:free model - Add OPEN_ROUTER_IMAGE_SUPPORT_MODELS set to handle models with image support not correctly reported by OpenRouter API - Update parseOpenRouterModel to check hardcoded image support models - Add test coverage for image support functionality Fixes #5877 --- packages/types/src/providers/openrouter.ts | 5 +++++ .../providers/fetchers/__tests__/openrouter.spec.ts | 10 ++++++++++ src/api/providers/fetchers/openrouter.ts | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/types/src/providers/openrouter.ts b/packages/types/src/providers/openrouter.ts index bbdbc7e732..446efa2919 100644 --- a/packages/types/src/providers/openrouter.ts +++ b/packages/types/src/providers/openrouter.ts @@ -88,3 +88,8 @@ export const OPEN_ROUTER_REASONING_BUDGET_MODELS = new Set([ "anthropic/claude-3.7-sonnet:thinking", "google/gemini-2.5-flash-preview-05-20:thinking", ]) + +// Models that support image input but may not be correctly reported by OpenRouter API +export const OPEN_ROUTER_IMAGE_SUPPORT_MODELS = new Set([ + "moonshotai/kimi-k2:free", +]) diff --git a/src/api/providers/fetchers/__tests__/openrouter.spec.ts b/src/api/providers/fetchers/__tests__/openrouter.spec.ts index f0ebead30f..4d2462384f 100644 --- a/src/api/providers/fetchers/__tests__/openrouter.spec.ts +++ b/src/api/providers/fetchers/__tests__/openrouter.spec.ts @@ -9,6 +9,7 @@ import { OPEN_ROUTER_COMPUTER_USE_MODELS, OPEN_ROUTER_REASONING_BUDGET_MODELS, OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS, + OPEN_ROUTER_IMAGE_SUPPORT_MODELS, } from "@roo-code/types" import { getOpenRouterModelEndpoints, getOpenRouterModels } from "../openrouter" @@ -148,6 +149,15 @@ describe("OpenRouter API", () => { .sort(), ).toEqual(expectedRequiredReasoningBudgetModels) + // Test image support for hardcoded models + expect( + Object.entries(models) + .filter(([_, model]) => model.supportsImages) + .map(([id, _]) => id) + .filter((id) => OPEN_ROUTER_IMAGE_SUPPORT_MODELS.has(id)) + .sort(), + ).toEqual(Array.from(OPEN_ROUTER_IMAGE_SUPPORT_MODELS).sort()) + expect(models["anthropic/claude-3.7-sonnet"]).toEqual({ maxTokens: 8192, contextWindow: 200000, diff --git a/src/api/providers/fetchers/openrouter.ts b/src/api/providers/fetchers/openrouter.ts index 027f8c54fb..97957a36b7 100644 --- a/src/api/providers/fetchers/openrouter.ts +++ b/src/api/providers/fetchers/openrouter.ts @@ -7,6 +7,7 @@ import { OPEN_ROUTER_COMPUTER_USE_MODELS, OPEN_ROUTER_REASONING_BUDGET_MODELS, OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS, + OPEN_ROUTER_IMAGE_SUPPORT_MODELS, anthropicModels, } from "@roo-code/types" @@ -193,7 +194,7 @@ export const parseOpenRouterModel = ({ const modelInfo: ModelInfo = { maxTokens: maxTokens || Math.ceil(model.context_length * 0.2), contextWindow: model.context_length, - supportsImages: modality?.includes("image") ?? false, + supportsImages: modality?.includes("image") ?? OPEN_ROUTER_IMAGE_SUPPORT_MODELS.has(id) ?? false, supportsPromptCache, inputPrice: parseApiPrice(model.pricing?.prompt), outputPrice: parseApiPrice(model.pricing?.completion),