From 658df6a69ba46e027e050d6ec5e57aa937860f63 Mon Sep 17 00:00:00 2001 From: Christiaan Arnoldus Date: Fri, 20 Feb 2026 18:29:21 +0100 Subject: [PATCH] Allow all recommended model for Vercel routing --- src/lib/providers/anthropic.ts | 4 -- .../openrouter/inference-provider-id.ts | 12 ++++-- src/lib/providers/vercel.ts | 39 ++++++------------- 3 files changed, 19 insertions(+), 36 deletions(-) diff --git a/src/lib/providers/anthropic.ts b/src/lib/providers/anthropic.ts index 921ba5685..21118f9eb 100644 --- a/src/lib/providers/anthropic.ts +++ b/src/lib/providers/anthropic.ts @@ -35,10 +35,6 @@ export function isHaikuModel(requestedModel: string) { return requestedModel.startsWith('anthropic/claude-haiku'); } -export function isOpusModel(requestedModel: string) { - return requestedModel.startsWith('anthropic/claude-opus'); -} - type ReadFileParametersSchema = { properties?: { files?: { diff --git a/src/lib/providers/openrouter/inference-provider-id.ts b/src/lib/providers/openrouter/inference-provider-id.ts index 60253ddab..e39477936 100644 --- a/src/lib/providers/openrouter/inference-provider-id.ts +++ b/src/lib/providers/openrouter/inference-provider-id.ts @@ -1,6 +1,7 @@ import * as z from 'zod'; export const OpenRouterInferenceProviderIdSchema = z.enum([ + 'alibaba', 'amazon-bedrock', 'anthropic', 'arcee-ai', @@ -46,7 +47,7 @@ export const UserByokProviderIdSchema = VercelUserByokInferenceProviderIdSchema. export type UserByokProviderId = z.infer; -export const VercelNonUserByokInferenceProviderIdSchema = z.enum(['bedrock', 'vertex']); +export const VercelNonUserByokInferenceProviderIdSchema = z.enum(['alibaba', 'bedrock', 'vertex']); export const VercelInferenceProviderIdSchema = VercelUserByokInferenceProviderIdSchema.or( VercelNonUserByokInferenceProviderIdSchema @@ -81,19 +82,22 @@ const modelPrefixToVercelInferenceProviderMapping = { openai: VercelUserByokInferenceProviderIdSchema.enum.openai, minimax: VercelUserByokInferenceProviderIdSchema.enum.minimax, mistralai: VercelUserByokInferenceProviderIdSchema.enum.mistral, + qwen: VercelNonUserByokInferenceProviderIdSchema.enum.alibaba, 'x-ai': VercelUserByokInferenceProviderIdSchema.enum.xai, 'z-ai': VercelUserByokInferenceProviderIdSchema.enum.zai, -} as Record; +} as Record; export function inferUserByokProviderForModel(model: string): UserByokProviderId | null { return model.startsWith('mistralai/codestral') ? AutocompleteUserByokProviderIdSchema.enum.codestral - : inferVercelFirstPartyInferenceProviderForModel(model); + : (VercelUserByokInferenceProviderIdSchema.safeParse( + inferVercelFirstPartyInferenceProviderForModel(model) + ).data ?? null); } export function inferVercelFirstPartyInferenceProviderForModel( model: string -): VercelUserByokInferenceProviderId | null { +): VercelInferenceProviderId | null { return model.startsWith('openai/gpt-oss') ? null : (modelPrefixToVercelInferenceProviderMapping[model.split('/')[0]] ?? null); diff --git a/src/lib/providers/vercel.ts b/src/lib/providers/vercel.ts index 2798cd0c5..fa3bbb36d 100644 --- a/src/lib/providers/vercel.ts +++ b/src/lib/providers/vercel.ts @@ -1,8 +1,7 @@ import type { BYOKResult } from '@/lib/byok'; -import { kiloFreeModels } from '@/lib/models'; -import { isAnthropicModel, isOpusModel } from '@/lib/providers/anthropic'; +import { kiloFreeModels, preferredModels } from '@/lib/models'; +import { isAnthropicModel } from '@/lib/providers/anthropic'; import { getGatewayErrorRate } from '@/lib/providers/gateway-error-rate'; -import { minimax_m21_free_model, minimax_m25_free_model } from '@/lib/providers/minimax'; import { AutocompleteUserByokProviderIdSchema, inferVercelFirstPartyInferenceProviderForModel, @@ -15,7 +14,6 @@ import type { VercelInferenceProviderConfig, VercelProviderConfig, } from '@/lib/providers/openrouter/types'; -import { zai_glm47_free_model, zai_glm5_free_model } from '@/lib/providers/zai'; import * as crypto from 'crypto'; // EMERGENCY SWITCH @@ -24,24 +22,6 @@ import * as crypto from 'crypto'; // Only use when OpenRouter is down and automatic failover is not working adequately. const ENABLE_UNIVERSAL_VERCEL_ROUTING = false; -const VERCEL_ROUTING_ALLOW_LIST = [ - 'arcee-ai/trinity-large-preview:free', - 'google/gemini-3-pro-preview', - 'google/gemini-3-flash-preview', - minimax_m21_free_model.public_id, - 'minimax/minimax-m2.1', - minimax_m25_free_model.public_id, - 'minimax/minimax-m2.5', - 'openai/gpt-5.2', - 'openai/gpt-5.2-codex', - 'x-ai/grok-code-fast-1', - zai_glm47_free_model.public_id, - 'z-ai/glm-4.7', - zai_glm5_free_model.public_id, - 'z-ai/glm-5', - // TODO: test and add anthropic, kat-coder, kimi, mistral, qwen models -]; - const ERROR_RATE_THRESHOLD = 0.5; function getRandomNumberLessThan100(randomSeed: string) { @@ -79,13 +59,18 @@ export async function shouldRouteToVercel( return false; } - if (ENABLE_UNIVERSAL_VERCEL_ROUTING && isOpenRouterModel(requestedModel)) { + if (!isOpenRouterModel(requestedModel)) { + console.debug(`[shouldRouteToVercel] model not available on the gateways`); + return false; + } + + if (ENABLE_UNIVERSAL_VERCEL_ROUTING) { console.debug(`[shouldRouteToVercel] universal Vercel routing is enabled`); return true; } - if (!VERCEL_ROUTING_ALLOW_LIST.includes(requestedModel)) { - console.debug(`[shouldRouteToVercel] model not on the allow list for Vercel routing`); + if (!preferredModels.includes(requestedModel)) { + console.debug(`[shouldRouteToVercel] only recommended models are tested for Vercel routing`); return false; } @@ -110,10 +95,8 @@ function convertProviderOptions( const vercelModelIdMapping = { 'arcee-ai/trinity-large-preview:free': 'arcee-ai/trinity-large-preview', - 'google/gemini-3-flash-preview': 'google/gemini-3-flash', 'mistralai/codestral-2508': 'mistral/codestral', 'mistralai/devstral-2512': 'mistral/devstral-2', - 'mistralai/devstral-2512:free': 'mistral/devstral-2', } as Record; export function applyVercelSettings( @@ -170,7 +153,7 @@ export function applyVercelSettings( requestToMutate.providerOptions = convertProviderOptions(requestToMutate.provider); } - if (isOpusModel(requestedModel) && requestToMutate.providerOptions && requestToMutate.verbosity) { + if (requestToMutate.providerOptions && requestToMutate.verbosity) { requestToMutate.providerOptions.anthropic = { effort: requestToMutate.verbosity, };