Skip to content

Commit 8327014

Browse files
authored
Preparation to hide free MiniMax and deprecated auto models (#1166)
2 parents f0d5aab + f997861 commit 8327014

6 files changed

Lines changed: 24 additions & 56 deletions

File tree

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
temporarilyUnavailableResponse,
3737
usageLimitExceededResponse,
3838
wrapInSafeNextResponse,
39+
forbiddenFreeModelResponse,
3940
} from '@/lib/llm-proxy-helpers';
4041
import { getBalanceAndOrgSettings } from '@/lib/organizations/organization-usage';
4142
import { ENABLE_TOOL_REPAIR, repairTools } from '@/lib/tool-calling';
@@ -64,7 +65,7 @@ import {
6465
import { handleRequestLogging } from '@/lib/handleRequestLogging';
6566
import { customLlmRequest } from '@/lib/custom-llm/customLlmRequest';
6667
import { normalizeModelId } from '@/lib/model-utils';
67-
import { isRateLimitedToDeath } from '@/lib/rate-limited-models';
68+
import { isForbiddenFreeModel } from '@/lib/forbidden-free-models';
6869
import { isActiveReviewPromo } from '@/lib/code-reviews/core/constants';
6970
import { applyResolvedAutoModel, isKiloAutoModel } from '@/lib/kilo-auto-model';
7071
import { fixOpenCodeDuplicateReasoning } from '@/lib/providers/fixOpenCodeDuplicateReasoning';
@@ -318,13 +319,16 @@ export async function POST(request: NextRequest): Promise<NextResponseType<unkno
318319
return temporarilyUnavailableResponse();
319320
}
320321

321-
if (isDeadFreeModel(originalModelIdLowerCased)) {
322-
console.warn(`User requested discontinued free model ${originalModelIdLowerCased}; rejecting.`);
323-
return alphaPeriodEndedResponse();
324-
}
325-
326-
if (isRateLimitedToDeath(originalModelIdLowerCased)) {
327-
return modelDoesNotExistResponse();
322+
if (
323+
isDeadFreeModel(originalModelIdLowerCased) ||
324+
(!autoModel && isForbiddenFreeModel(originalModelIdLowerCased))
325+
) {
326+
console.warn(`User requested forbidden free model ${originalModelIdLowerCased}; rejecting.`);
327+
if (isRooCodeBasedClient(fraudHeaders)) {
328+
return alphaPeriodEndedResponse();
329+
} else {
330+
return forbiddenFreeModelResponse();
331+
}
328332
}
329333

330334
// Extract properties for usage context
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 429s.
66
*/
77

8-
const rateLimitedToDeathModelIds: ReadonlySet<string> = new Set([
8+
const forbiddenFreeModelIds: ReadonlySet<string> = new Set([
99
'arcee-ai/trinity-mini:free',
1010
'cognitivecomputations/dolphin-mistral-24b-venice-edition:free',
1111
'deepseek/deepseek-r1-0528:free',
@@ -32,6 +32,6 @@ const rateLimitedToDeathModelIds: ReadonlySet<string> = new Set([
3232
'z-ai/glm-4.5-air:free',
3333
]);
3434

35-
export function isRateLimitedToDeath(modelId: string): boolean {
36-
return rateLimitedToDeathModelIds.has(modelId);
35+
export function isForbiddenFreeModel(modelId: string): boolean {
36+
return forbiddenFreeModelIds.has(modelId);
3737
}

src/lib/llm-proxy-helpers.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import type {
3131
PromptInfo,
3232
} from '@/lib/processUsage.types';
3333
import { getMaxTokens } from '@/lib/providers/openrouter/request-helpers';
34+
import { KILO_AUTO_BALANCED_MODEL, KILO_AUTO_FREE_MODEL } from '@/lib/kilo-auto-model';
3435

3536
// FIM suffix markers for tracking purposes - used to wrap suffix in a fake system prompt format
3637
// This allows FIM requests to be tracked consistently with chat requests
@@ -183,6 +184,11 @@ export function modelNotAllowedResponse() {
183184
);
184185
}
185186

187+
export function forbiddenFreeModelResponse() {
188+
const error = `This is not a free model. Please use ${KILO_AUTO_BALANCED_MODEL.id} for affordable inference or ${KILO_AUTO_FREE_MODEL.id} for limited free inference.`;
189+
return NextResponse.json({ error, message: error }, { status: 404 });
190+
}
191+
186192
export function modelDoesNotExistResponse() {
187193
return NextResponse.json(
188194
{

src/lib/providers/morph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const morph_warp_grep_free_model: KiloFreeModel = {
77
'A code search subagent that finds relevant code in a separate context window — no embeddings, no indexing.',
88
context_length: 256000,
99
max_completion_tokens: 32000,
10-
status: 'public',
10+
status: 'hidden',
1111
flags: [],
1212
gateway: 'morph',
1313
internal_id: 'morph-warp-grep-v2',

src/lib/providers/openrouter/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import { errorExceptInTest } from '@/lib/utils.server';
99
import { captureException, captureMessage } from '@sentry/nextjs';
1010
import { convertFromKiloModel } from '@/lib/providers/kilo-free-model';
11-
import { isRateLimitedToDeath } from '@/lib/rate-limited-models';
11+
import { isForbiddenFreeModel } from '@/lib/forbidden-free-models';
1212
import {
1313
getModelSettings,
1414
getOpenCodeSettings,
@@ -60,8 +60,7 @@ function enhancedModelList(models: OpenRouterModel[]) {
6060
const enhancedModels = models
6161
.filter(
6262
(model: OpenRouterModel) =>
63-
!kiloFreeModels.some(m => m.public_id === model.id && m.status !== 'disabled') &&
64-
!isRateLimitedToDeath(model.id)
63+
!kiloFreeModels.some(m => m.public_id === model.id) && !isForbiddenFreeModel(model.id)
6564
)
6665
.concat(
6766
kiloFreeModels.filter(m => m.status === 'public').map(model => convertFromKiloModel(model))

src/tests/openrouter-models-sorting.approved.json

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -741,47 +741,6 @@
741741
"default_parameters": {},
742742
"isFree": true
743743
},
744-
{
745-
"id": "morph-warp-grep-v2",
746-
"canonical_slug": "morph-warp-grep-v2",
747-
"hugging_face_id": "",
748-
"name": "Morph: WarpGrep V2",
749-
"created": 1756238927,
750-
"description": "A code search subagent that finds relevant code in a separate context window — no embeddings, no indexing.",
751-
"context_length": 256000,
752-
"architecture": {
753-
"modality": "text->text",
754-
"input_modalities": [
755-
"text"
756-
],
757-
"output_modalities": [
758-
"text"
759-
],
760-
"tokenizer": "Other",
761-
"instruct_type": null
762-
},
763-
"pricing": {
764-
"prompt": "0.0000000",
765-
"completion": "0.0000000",
766-
"request": "0",
767-
"image": "0",
768-
"web_search": "0",
769-
"internal_reasoning": "0"
770-
},
771-
"top_provider": {
772-
"context_length": 256000,
773-
"max_completion_tokens": 32000,
774-
"is_moderated": false
775-
},
776-
"per_request_limits": null,
777-
"supported_parameters": [
778-
"max_tokens",
779-
"temperature",
780-
"tools"
781-
],
782-
"default_parameters": {},
783-
"isFree": true
784-
},
785744
{
786745
"id": "x-ai/grok-code-fast-1:optimized:free",
787746
"canonical_slug": "x-ai/grok-code-fast-1:optimized:free",

0 commit comments

Comments
 (0)