Skip to content

Commit 8d5cdea

Browse files
refactor(gateway): centralize free model response rewrites (#3641)
* refactor(gateway): centralize free model response rewrites * style(gateway): format response rewrite helper --------- Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
1 parent 4279d4a commit 8d5cdea

2 files changed

Lines changed: 39 additions & 24 deletions

File tree

apps/web/src/app/api/openrouter/[...path]/route.ts

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import {
2828
isDeadFreeModel,
2929
isExcludedForFeature,
3030
isKiloExclusiveFreeModel,
31-
isKiloStealthModel,
3231
isKiloExclusiveModelRequiringDataCollection,
3332
} from '@/lib/ai-gateway/models';
3433
import { isFreeModel } from '@/lib/ai-gateway/is-free-model';
@@ -57,11 +56,7 @@ import {
5756
import { ProxyErrorType } from '@/lib/proxy-error-types';
5857
import { getBalanceAndOrgSettings } from '@/lib/organizations/organization-usage';
5958
import { isDataCollectionExplicitlyDisallowed } from '@/lib/ai-gateway/providers/openrouter/types';
60-
import {
61-
rewriteFreeModelResponse_ChatCompletions,
62-
rewriteFreeModelResponse_Messages,
63-
rewriteFreeModelResponse_Responses,
64-
} from '@/lib/rewriteModelResponse';
59+
import { rewriteFreeModelResponse } from '@/lib/rewriteModelResponse';
6560
import {
6661
createAnonymousContext,
6762
isAnonymousContext,
@@ -799,24 +794,14 @@ export async function POST(request: NextRequest): Promise<NextResponseType<unkno
799794
}
800795
}
801796

802-
const isFreeModelRequiringCostRemoval =
803-
(effectiveProviderContext.provider.id === 'openrouter' ||
804-
effectiveProviderContext.provider.id === 'vercel') &&
805-
isKiloExclusiveFreeModel(effectiveModelIdLowerCased);
806-
const isStealthModelRequiringNameRemoval =
807-
effectiveProviderContext.provider.id !== 'martian' &&
808-
isKiloStealthModel(effectiveModelIdLowerCased);
809-
810-
if (isFreeModelRequiringCostRemoval || isStealthModelRequiringNameRemoval) {
811-
if (requestBodyParsed.kind === 'chat_completions') {
812-
return rewriteFreeModelResponse_ChatCompletions(response, effectiveModelIdLowerCased);
813-
}
814-
if (requestBodyParsed.kind === 'responses') {
815-
return rewriteFreeModelResponse_Responses(response, effectiveModelIdLowerCased);
816-
}
817-
if (requestBodyParsed.kind === 'messages') {
818-
return rewriteFreeModelResponse_Messages(response, effectiveModelIdLowerCased);
819-
}
797+
const rewrittenResponse = await rewriteFreeModelResponse(
798+
response,
799+
effectiveModelIdLowerCased,
800+
effectiveProviderContext.provider.id,
801+
requestBodyParsed.kind
802+
);
803+
if (rewrittenResponse) {
804+
return rewrittenResponse;
820805
}
821806

822807
return wrapInSafeNextResponse(response);

apps/web/src/lib/rewriteModelResponse.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { isKiloExclusiveFreeModel, isKiloStealthModel } from '@/lib/ai-gateway/models';
2+
import type { GatewayRequest } from '@/lib/ai-gateway/providers/openrouter/types';
3+
import type { ProviderId } from '@/lib/ai-gateway/providers/types';
14
import { getOutputHeaders } from '@/lib/ai-gateway/llm-proxy-helpers';
25
import type { ChatCompletionChunk, OpenRouterUsage } from '@/lib/ai-gateway/processUsage.types';
36
import type { EventSourceMessage } from 'eventsource-parser';
@@ -338,3 +341,30 @@ export async function rewriteFreeModelResponse_Responses(response: Response, mod
338341
headers,
339342
});
340343
}
344+
345+
export async function rewriteFreeModelResponse(
346+
response: Response,
347+
model: string,
348+
providerId: ProviderId,
349+
kind: GatewayRequest['kind']
350+
): Promise<NextResponse | null> {
351+
const isFreeModelRequiringCostRemoval =
352+
(providerId === 'openrouter' || providerId === 'vercel') && isKiloExclusiveFreeModel(model);
353+
const isStealthModelRequiringNameRemoval = providerId !== 'martian' && isKiloStealthModel(model);
354+
355+
if (!isFreeModelRequiringCostRemoval && !isStealthModelRequiringNameRemoval) {
356+
return null;
357+
}
358+
359+
if (kind === 'chat_completions') {
360+
return rewriteFreeModelResponse_ChatCompletions(response, model);
361+
}
362+
if (kind === 'responses') {
363+
return rewriteFreeModelResponse_Responses(response, model);
364+
}
365+
if (kind === 'messages') {
366+
return rewriteFreeModelResponse_Messages(response, model);
367+
}
368+
369+
return null;
370+
}

0 commit comments

Comments
 (0)