From 77aa2e7e16e26c78e5e92de2195e6e781a273e53 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:19:22 +0000 Subject: [PATCH 1/8] fix: support provider ignore for Vercel routing Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- .../ai-gateway/providers/vercel/index.test.ts | 32 ++++++++++++ .../lib/ai-gateway/providers/vercel/index.ts | 52 +++++++++++++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts index 5efa239edc..42d85037bd 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts @@ -1,6 +1,7 @@ import { describe, it, expect } from '@jest/globals'; import { getAnthropicProviderOptionsForVercel, + getVercelInferenceProvidersExcludingIgnored, hasCompatibleVercelInferenceProvider, passesVercelRoutingPercentage, } from '@/lib/ai-gateway/providers/vercel'; @@ -73,6 +74,37 @@ describe('hasCompatibleVercelInferenceProvider', () => { }); }); +describe('getVercelInferenceProvidersExcludingIgnored', () => { + it('returns available providers minus translated ignored providers', () => { + expect( + getVercelInferenceProvidersExcludingIgnored(['amazon-bedrock'], undefined, [ + 'anthropic', + 'bedrock', + 'vertex', + ]) + ).toEqual(['anthropic', 'vertex']); + }); + + it('intersects the available providers with only before excluding ignored providers', () => { + expect( + getVercelInferenceProvidersExcludingIgnored( + ['google-vertex'], + ['amazon-bedrock', 'google-vertex', 'openai'], + ['anthropic', 'bedrock', 'vertex'] + ) + ).toEqual(['bedrock']); + }); + + it('returns an empty list when all available providers are ignored', () => { + expect( + getVercelInferenceProvidersExcludingIgnored(['anthropic', 'amazon-bedrock'], undefined, [ + 'anthropic', + 'bedrock', + ]) + ).toEqual([]); + }); +}); + describe('passesVercelRoutingPercentage', () => { it('never passes at 0% and always passes at 100%', () => { for (let seed = 0; seed < 1_000; seed++) { diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index 9df72efcea..8512d89ced 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -52,6 +52,21 @@ export function hasCompatibleVercelInferenceProvider( ); } +export function getVercelInferenceProvidersExcludingIgnored( + ignoredProviders: string[], + onlyProviders: string[] | undefined, + vercelInferenceProviders: string[] +) { + const ignored = new Set(ignoredProviders.map(openRouterToVercelInferenceProviderId)); + const only = onlyProviders + ? new Set(onlyProviders.map(openRouterToVercelInferenceProviderId)) + : null; + + return vercelInferenceProviders.filter( + provider => !ignored.has(provider) && (!only || only.has(provider)) + ); +} + export function passesVercelRoutingPercentage(randomSeed: string, routingPercentage: number) { const routingSeed = 'vercel_routing_' + randomSeed; const wholePercentageBucket = getRandomNumber(routingSeed, 100); @@ -66,13 +81,6 @@ export async function shouldRouteToVercel( request: GatewayRequest, randomSeed: string ) { - if ((request.body.provider?.ignore?.length ?? 0) > 0) { - console.debug( - '[shouldRouteToVercel] not routing to Vercel because of unsupported provider options' - ); - return false; - } - if (!kiloExclusiveModel?.flags.includes('vercel-routing') && isDeepseekModel(requestedModel)) { // https://kilo-code.slack.com/archives/C0A4SA041DE/p1781743079721409 console.debug( @@ -97,11 +105,35 @@ export async function shouldRouteToVercel( return false; } - const only = request.body.provider?.only; - if (only) { + const provider = request.body.provider; + const only = provider?.only; + const ignore = provider?.ignore; + if (only || ignore?.length) { const vercelInferenceProviders = await getCachedVercelInferenceProviderIdsForModel(vercelModelId); - if (!hasCompatibleVercelInferenceProvider(only, vercelInferenceProviders)) { + + if (ignore?.length) { + if (!vercelInferenceProviders) { + console.debug( + '[shouldRouteToVercel] not routing to Vercel because inference provider data is unavailable' + ); + return false; + } + + const effectiveOnly = getVercelInferenceProvidersExcludingIgnored( + ignore, + only, + vercelInferenceProviders + ); + if (effectiveOnly.length === 0) { + console.debug( + '[shouldRouteToVercel] no inference providers remain after applying provider preferences' + ); + return false; + } + + provider.only = effectiveOnly; + } else if (only && !hasCompatibleVercelInferenceProvider(only, vercelInferenceProviders)) { console.debug( '[shouldRouteToVercel] none of the requested inference providers are available on Vercel' ); From 891ed38c99e6653717dc4d3f8dc17654364a1b66 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:22:33 +0000 Subject: [PATCH 2/8] fix: narrow Vercel provider options Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- apps/web/src/lib/ai-gateway/providers/vercel/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index 8512d89ced..ec6baf10bb 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -106,9 +106,8 @@ export async function shouldRouteToVercel( } const provider = request.body.provider; - const only = provider?.only; - const ignore = provider?.ignore; - if (only || ignore?.length) { + if (provider && (provider.only || provider.ignore?.length)) { + const { only, ignore } = provider; const vercelInferenceProviders = await getCachedVercelInferenceProviderIdsForModel(vercelModelId); From b69cce7b30cd4e1c8cdb0a7928bd73779062597e Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:51:16 +0000 Subject: [PATCH 3/8] fix: enforce provider ignore in Vercel transform Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- .../ai-gateway/providers/vercel/index.test.ts | 22 +++++++++++++++++++ .../lib/ai-gateway/providers/vercel/index.ts | 5 ++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts index 42d85037bd..756fddd698 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect } from '@jest/globals'; import { + applyVercelSettings, getAnthropicProviderOptionsForVercel, getVercelInferenceProvidersExcludingIgnored, hasCompatibleVercelInferenceProvider, @@ -105,6 +106,27 @@ describe('getVercelInferenceProvidersExcludingIgnored', () => { }); }); +describe('applyVercelSettings', () => { + it('emits only non-ignored providers in the Vercel gateway options', () => { + const request: GatewayRequest = { + kind: 'chat_completions', + body: { + model: 'anthropic/claude-sonnet-4.5', + messages: [{ role: 'user', content: 'hello' }], + provider: { + only: ['anthropic', 'amazon-bedrock'], + ignore: ['amazon-bedrock'], + }, + }, + }; + + applyVercelSettings('anthropic/claude-sonnet-4.5', request, null); + + expect(request.body.providerOptions?.gateway?.only).toEqual(['anthropic']); + expect(request.body.provider).toBeUndefined(); + }); +}); + describe('passesVercelRoutingPercentage', () => { it('never passes at 0% and always passes at 100%', () => { for (let seed = 0; seed < 1_000; seed++) { diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index ec6baf10bb..abc41c8954 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -145,9 +145,12 @@ export async function shouldRouteToVercel( function convertProviderOptions(requestToMutate: GatewayRequest): VercelProviderConfig { const provider = requestToMutate.body.provider; + const ignored = new Set(provider?.ignore?.map(openRouterToVercelInferenceProviderId)); return { gateway: { - only: provider?.only?.map(p => openRouterToVercelInferenceProviderId(p)), + only: provider?.only + ?.map(openRouterToVercelInferenceProviderId) + .filter(providerId => !ignored.has(providerId)), order: provider?.order?.map(p => openRouterToVercelInferenceProviderId(p)), zeroDataRetention: provider?.zdr, disallowPromptTraining: provider?.data_collection === 'deny' || undefined, From bd1dc186a9789de198a27a9233b6646b46d641c2 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:54:28 +0000 Subject: [PATCH 4/8] refactor: keep Vercel routing side-effect free --- .../providers/provider-definitions.ts | 2 +- .../ai-gateway/providers/vercel/index.test.ts | 24 ++++++++++++-- .../lib/ai-gateway/providers/vercel/index.ts | 31 +++++++++++++------ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/provider-definitions.ts b/apps/web/src/lib/ai-gateway/providers/provider-definitions.ts index 6588d1ec04..b151f2a5ae 100644 --- a/apps/web/src/lib/ai-gateway/providers/provider-definitions.ts +++ b/apps/web/src/lib/ai-gateway/providers/provider-definitions.ts @@ -75,7 +75,7 @@ export default { apiKey: getEnvVariable('VERCEL_AI_GATEWAY_API_KEY'), supportedChatApis: ['chat_completions', 'messages', 'responses'], async transformRequest(context) { - applyVercelSettings(context.model, context.request, context.userByok); + await applyVercelSettings(context.model, context.request, context.userByok); }, }, } as const satisfies Record; diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts index 756fddd698..a2d2719192 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from '@jest/globals'; +import { describe, it, expect, jest } from '@jest/globals'; import { applyVercelSettings, getAnthropicProviderOptionsForVercel, @@ -8,6 +8,16 @@ import { } from '@/lib/ai-gateway/providers/vercel'; import { getRandomNumber } from '@/lib/ai-gateway/getRandomNumber'; import type { GatewayRequest } from '@/lib/ai-gateway/providers/openrouter/types'; +import { getCachedVercelInferenceProviderIdsForModel } from '@/lib/ai-gateway/providers/gateway-models-cache'; + +jest.mock('@/lib/ai-gateway/providers/gateway-models-cache', () => ({ + getCachedVercelInferenceProviderIdsForModel: jest.fn(), + getVercelModelsFromRedis: jest.fn(), +})); + +const mockGetCachedVercelInferenceProviderIdsForModel = jest.mocked( + getCachedVercelInferenceProviderIdsForModel +); describe('getAnthropicProviderOptionsForVercel', () => { it('maps chat completion verbosity to Anthropic effort', () => { @@ -107,7 +117,12 @@ describe('getVercelInferenceProvidersExcludingIgnored', () => { }); describe('applyVercelSettings', () => { - it('emits only non-ignored providers in the Vercel gateway options', () => { + it('emits only available non-ignored providers without changing provider.only', async () => { + mockGetCachedVercelInferenceProviderIdsForModel.mockResolvedValue([ + 'anthropic', + 'bedrock', + 'vertex', + ]); const request: GatewayRequest = { kind: 'chat_completions', body: { @@ -120,9 +135,12 @@ describe('applyVercelSettings', () => { }, }; - applyVercelSettings('anthropic/claude-sonnet-4.5', request, null); + const provider = request.body.provider; + + await applyVercelSettings('anthropic/claude-sonnet-4.5', request, null); expect(request.body.providerOptions?.gateway?.only).toEqual(['anthropic']); + expect(provider?.only).toEqual(['anthropic', 'amazon-bedrock']); expect(request.body.provider).toBeUndefined(); }); }); diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index abc41c8954..2bc5eea509 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -130,8 +130,6 @@ export async function shouldRouteToVercel( ); return false; } - - provider.only = effectiveOnly; } else if (only && !hasCompatibleVercelInferenceProvider(only, vercelInferenceProviders)) { console.debug( '[shouldRouteToVercel] none of the requested inference providers are available on Vercel' @@ -143,14 +141,29 @@ export async function shouldRouteToVercel( return true; } -function convertProviderOptions(requestToMutate: GatewayRequest): VercelProviderConfig { +async function convertProviderOptions( + requestToMutate: GatewayRequest +): Promise { const provider = requestToMutate.body.provider; - const ignored = new Set(provider?.ignore?.map(openRouterToVercelInferenceProviderId)); + let only = provider?.only?.map(openRouterToVercelInferenceProviderId); + + if (provider?.ignore?.length) { + const vercelInferenceProviders = await getCachedVercelInferenceProviderIdsForModel( + requestToMutate.body.model + ); + if (!vercelInferenceProviders) { + throw new Error('Vercel inference provider data became unavailable during request transform'); + } + only = getVercelInferenceProvidersExcludingIgnored( + provider.ignore, + provider.only, + vercelInferenceProviders + ); + } + return { gateway: { - only: provider?.only - ?.map(openRouterToVercelInferenceProviderId) - .filter(providerId => !ignored.has(providerId)), + only, order: provider?.order?.map(p => openRouterToVercelInferenceProviderId(p)), zeroDataRetention: provider?.zdr, disallowPromptTraining: provider?.data_collection === 'deny' || undefined, @@ -214,7 +227,7 @@ export function getVercelInferenceProviderConfigForUserByok( return [key, list]; } -export function applyVercelSettings( +export async function applyVercelSettings( requestedModel: string, requestToMutate: GatewayRequest, userByok: BYOKResult[] | null @@ -241,7 +254,7 @@ export function applyVercelSettings( }, }; } else { - requestToMutate.body.providerOptions = convertProviderOptions(requestToMutate); + requestToMutate.body.providerOptions = await convertProviderOptions(requestToMutate); } if (requestToMutate.body.providerOptions) { From 0f89d4da94c6d33397fb6ed3568179d408634020 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:59:22 +0000 Subject: [PATCH 5/8] fix: pass mapped model to Vercel transform --- .../src/lib/ai-gateway/providers/vercel/index.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index 2bc5eea509..61b48d5fb9 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -142,15 +142,15 @@ export async function shouldRouteToVercel( } async function convertProviderOptions( - requestToMutate: GatewayRequest + requestToMutate: GatewayRequest, + vercelModelId: string ): Promise { const provider = requestToMutate.body.provider; let only = provider?.only?.map(openRouterToVercelInferenceProviderId); if (provider?.ignore?.length) { - const vercelInferenceProviders = await getCachedVercelInferenceProviderIdsForModel( - requestToMutate.body.model - ); + const vercelInferenceProviders = + await getCachedVercelInferenceProviderIdsForModel(vercelModelId); if (!vercelInferenceProviders) { throw new Error('Vercel inference provider data became unavailable during request transform'); } @@ -232,7 +232,8 @@ export async function applyVercelSettings( requestToMutate: GatewayRequest, userByok: BYOKResult[] | null ) { - requestToMutate.body.model = mapModelIdToVercel(requestedModel); + const vercelModelId = mapModelIdToVercel(requestedModel); + requestToMutate.body.model = vercelModelId; if (userByok) { if (userByok.length === 0) { @@ -254,7 +255,10 @@ export async function applyVercelSettings( }, }; } else { - requestToMutate.body.providerOptions = await convertProviderOptions(requestToMutate); + requestToMutate.body.providerOptions = await convertProviderOptions( + requestToMutate, + vercelModelId + ); } if (requestToMutate.body.providerOptions) { From 11d623604532c07580e2e09036e1cb7ffd8acb09 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:11:32 +0000 Subject: [PATCH 6/8] test: isolate Vercel provider conversion --- .../ai-gateway/providers/vercel/index.test.ts | 29 ++++--------------- .../lib/ai-gateway/providers/vercel/index.ts | 15 +++++----- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts index a2d2719192..e0877f1bc0 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.test.ts @@ -1,6 +1,6 @@ -import { describe, it, expect, jest } from '@jest/globals'; +import { describe, it, expect } from '@jest/globals'; import { - applyVercelSettings, + convertProviderOptions, getAnthropicProviderOptionsForVercel, getVercelInferenceProvidersExcludingIgnored, hasCompatibleVercelInferenceProvider, @@ -8,16 +8,6 @@ import { } from '@/lib/ai-gateway/providers/vercel'; import { getRandomNumber } from '@/lib/ai-gateway/getRandomNumber'; import type { GatewayRequest } from '@/lib/ai-gateway/providers/openrouter/types'; -import { getCachedVercelInferenceProviderIdsForModel } from '@/lib/ai-gateway/providers/gateway-models-cache'; - -jest.mock('@/lib/ai-gateway/providers/gateway-models-cache', () => ({ - getCachedVercelInferenceProviderIdsForModel: jest.fn(), - getVercelModelsFromRedis: jest.fn(), -})); - -const mockGetCachedVercelInferenceProviderIdsForModel = jest.mocked( - getCachedVercelInferenceProviderIdsForModel -); describe('getAnthropicProviderOptionsForVercel', () => { it('maps chat completion verbosity to Anthropic effort', () => { @@ -116,13 +106,8 @@ describe('getVercelInferenceProvidersExcludingIgnored', () => { }); }); -describe('applyVercelSettings', () => { - it('emits only available non-ignored providers without changing provider.only', async () => { - mockGetCachedVercelInferenceProviderIdsForModel.mockResolvedValue([ - 'anthropic', - 'bedrock', - 'vertex', - ]); +describe('convertProviderOptions', () => { + it('emits only available non-ignored providers without changing provider.only', () => { const request: GatewayRequest = { kind: 'chat_completions', body: { @@ -136,12 +121,10 @@ describe('applyVercelSettings', () => { }; const provider = request.body.provider; + const providerOptions = convertProviderOptions(request, ['anthropic', 'bedrock', 'vertex']); - await applyVercelSettings('anthropic/claude-sonnet-4.5', request, null); - - expect(request.body.providerOptions?.gateway?.only).toEqual(['anthropic']); + expect(providerOptions.gateway?.only).toEqual(['anthropic']); expect(provider?.only).toEqual(['anthropic', 'amazon-bedrock']); - expect(request.body.provider).toBeUndefined(); }); }); diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index 61b48d5fb9..e31c9d9667 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -141,16 +141,14 @@ export async function shouldRouteToVercel( return true; } -async function convertProviderOptions( +export function convertProviderOptions( requestToMutate: GatewayRequest, - vercelModelId: string -): Promise { + vercelInferenceProviders: string[] | null +): VercelProviderConfig { const provider = requestToMutate.body.provider; let only = provider?.only?.map(openRouterToVercelInferenceProviderId); if (provider?.ignore?.length) { - const vercelInferenceProviders = - await getCachedVercelInferenceProviderIdsForModel(vercelModelId); if (!vercelInferenceProviders) { throw new Error('Vercel inference provider data became unavailable during request transform'); } @@ -255,9 +253,12 @@ export async function applyVercelSettings( }, }; } else { - requestToMutate.body.providerOptions = await convertProviderOptions( + const vercelInferenceProviders = requestToMutate.body.provider?.ignore?.length + ? await getCachedVercelInferenceProviderIdsForModel(vercelModelId) + : null; + requestToMutate.body.providerOptions = convertProviderOptions( requestToMutate, - vercelModelId + vercelInferenceProviders ); } From 128136f4e68696275e87122bb22ce172c79edcad Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:38:23 +0000 Subject: [PATCH 7/8] refactor: derive Vercel provider only immutably Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- .../lib/ai-gateway/providers/vercel/index.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index e31c9d9667..e4ba9208ee 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -146,18 +146,16 @@ export function convertProviderOptions( vercelInferenceProviders: string[] | null ): VercelProviderConfig { const provider = requestToMutate.body.provider; - let only = provider?.only?.map(openRouterToVercelInferenceProviderId); - - if (provider?.ignore?.length) { - if (!vercelInferenceProviders) { - throw new Error('Vercel inference provider data became unavailable during request transform'); - } - only = getVercelInferenceProvidersExcludingIgnored( - provider.ignore, - provider.only, - vercelInferenceProviders - ); + if (provider?.ignore?.length && !vercelInferenceProviders) { + throw new Error('Vercel inference provider data became unavailable during request transform'); } + const only = provider?.ignore?.length + ? getVercelInferenceProvidersExcludingIgnored( + provider.ignore, + provider.only, + vercelInferenceProviders + ) + : provider?.only?.map(openRouterToVercelInferenceProviderId); return { gateway: { From aed7572657825eb82f378880fae241fb3b4d7ef4 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:43:15 +0000 Subject: [PATCH 8/8] fix: narrow immutable Vercel provider selection Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- .../lib/ai-gateway/providers/vercel/index.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts index e4ba9208ee..c9676d8038 100644 --- a/apps/web/src/lib/ai-gateway/providers/vercel/index.ts +++ b/apps/web/src/lib/ai-gateway/providers/vercel/index.ts @@ -146,16 +146,19 @@ export function convertProviderOptions( vercelInferenceProviders: string[] | null ): VercelProviderConfig { const provider = requestToMutate.body.provider; - if (provider?.ignore?.length && !vercelInferenceProviders) { - throw new Error('Vercel inference provider data became unavailable during request transform'); - } - const only = provider?.ignore?.length - ? getVercelInferenceProvidersExcludingIgnored( - provider.ignore, - provider.only, - vercelInferenceProviders - ) - : provider?.only?.map(openRouterToVercelInferenceProviderId); + const only = (() => { + if (!provider?.ignore?.length) { + return provider?.only?.map(openRouterToVercelInferenceProviderId); + } + if (!vercelInferenceProviders) { + throw new Error('Vercel inference provider data became unavailable during request transform'); + } + return getVercelInferenceProvidersExcludingIgnored( + provider.ignore, + provider.only, + vercelInferenceProviders + ); + })(); return { gateway: {