diff --git a/apps/web/src/app/api/openrouter/[...path]/route.ts b/apps/web/src/app/api/openrouter/[...path]/route.ts index d2b1bf7b0..9352326ac 100644 --- a/apps/web/src/app/api/openrouter/[...path]/route.ts +++ b/apps/web/src/app/api/openrouter/[...path]/route.ts @@ -28,9 +28,11 @@ import { isDeadFreeModel, isExcludedForFeature, isKiloExclusiveFreeModel, - isKiloExclusiveModelRequiringDataCollection, } from '@/lib/ai-gateway/models'; -import { isFreeModel } from '@/lib/ai-gateway/is-free-model'; +import { + hasBestEffortGuessDataCollectionRequirement, + isFreeModel, +} from '@/lib/ai-gateway/is-free-model'; import { accountForMicrodollarUsage, captureProxyError, @@ -554,17 +556,8 @@ export async function POST(request: NextRequest): Promise { (await isPublicIdExperimented(model ?? '')) ); } + +export async function hasBestEffortGuessDataCollectionRequirement(model: string): Promise { + return ( + (await isFreeModel(model)) || + kiloExclusiveModels.some( + candidate => + candidate.public_id === model && + candidate.status !== 'disabled' && + candidate.flags.includes('requires-data-collection') + ) + ); +} diff --git a/apps/web/src/lib/ai-gateway/models.test.ts b/apps/web/src/lib/ai-gateway/models.test.ts index f0992fb19..774c96dc8 100644 --- a/apps/web/src/lib/ai-gateway/models.test.ts +++ b/apps/web/src/lib/ai-gateway/models.test.ts @@ -1,11 +1,6 @@ import { describe, test, expect } from '@jest/globals'; -import { - autoFreeModels, - findKiloExclusiveModel, - kiloExclusiveModels, - isKiloExclusiveModelRequiringDataCollection, -} from './models'; -import { isFreeModel } from './is-free-model'; +import { autoFreeModels, findKiloExclusiveModel, kiloExclusiveModels } from './models'; +import { hasBestEffortGuessDataCollectionRequirement, isFreeModel } from './is-free-model'; import { getInferenceProvider } from './providers/kilo-exclusive-model'; import { claude_opus_4_7_stealth_model, @@ -75,18 +70,6 @@ describe('isFreeModel', () => { expect(claude_opus_4_6_stealth_model.public_id).toBe('stealth/claude-opus-4.6'); }); - test('requires data collection for paid training-enabled offerings', () => { - expect( - isKiloExclusiveModelRequiringDataCollection(claude_opus_4_7_stealth_model.public_id) - ).toBe(true); - expect( - isKiloExclusiveModelRequiringDataCollection(claude_sonnet_4_6_stealth_model.public_id) - ).toBe(true); - expect( - isKiloExclusiveModelRequiringDataCollection(claude_opus_4_6_stealth_model.public_id) - ).toBe(true); - }); - test('all Kilo exclusive models should have either no pricing or valid ordered pricing tiers', () => { for (const model of kiloExclusiveModels) { if (model.pricing) { @@ -186,3 +169,27 @@ describe('isFreeModel', () => { }); }); }); + +describe('hasBestEffortGuessDataCollectionRequirement', () => { + test('requires data collection for paid training-enabled offerings', async () => { + expect( + await hasBestEffortGuessDataCollectionRequirement(claude_opus_4_7_stealth_model.public_id) + ).toBe(true); + expect( + await hasBestEffortGuessDataCollectionRequirement(claude_sonnet_4_6_stealth_model.public_id) + ).toBe(true); + expect( + await hasBestEffortGuessDataCollectionRequirement(claude_opus_4_6_stealth_model.public_id) + ).toBe(true); + }); + + test('requires data collection for free models', async () => { + expect(await hasBestEffortGuessDataCollectionRequirement('openrouter/free')).toBe(true); + }); + + test('does not require data collection for regular paid models', async () => { + expect(await hasBestEffortGuessDataCollectionRequirement('anthropic/claude-sonnet-4')).toBe( + false + ); + }); +}); diff --git a/apps/web/src/lib/ai-gateway/models.ts b/apps/web/src/lib/ai-gateway/models.ts index 7864ae115..37b1b8cf0 100644 --- a/apps/web/src/lib/ai-gateway/models.ts +++ b/apps/web/src/lib/ai-gateway/models.ts @@ -93,15 +93,6 @@ export const kiloExclusiveModels = [ stepfun_37_flash_free_model, ] as KiloExclusiveModel[]; -export function isKiloExclusiveModelRequiringDataCollection(model: string): boolean { - return kiloExclusiveModels.some( - m => - m.public_id === model && - m.status !== 'disabled' && - (!m.pricing || m.flags.includes('requires-data-collection')) - ); -} - export function isKiloStealthModel(model: string): boolean { return kiloExclusiveModels.some(m => m.public_id === model && m.flags.includes('stealth')); }