import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/auth'; import { getEffectiveTier } from '@/lib/entitlements'; import { isByokProviderAllowed } from '@/lib/byok'; import { fetchLiveModelsForProvider, PROVIDER_MODEL_SUGGESTIONS, type FetchModelsResult } from '@/lib/ai/models-list'; import { VALID_PROVIDERS, type AiGatewayProvider } from '@/lib/ai/router'; // Providers that return static suggestions regardless of key const STATIC_PROVIDERS = new Set(['anthropic', 'anthropic_custom', 'custom_anthropic', 'google', 'minimax']); /** * GET /api/user/api-keys/live-models?provider=[&key=][&baseUrl=] * * - Static providers (minimax, anthropic, google): returns suggestions immediately, no key needed. * - Live providers (openai, deepseek…): requires key to fetch live from provider. */ export async function GET(request: NextRequest) { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const tier = await getEffectiveTier(session.user.id); if (tier === 'BASIC') { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }); } const { searchParams } = request.nextUrl; const provider = searchParams.get('provider') as AiGatewayProvider; const apiKey = searchParams.get('key') ?? ''; const baseUrl = searchParams.get('baseUrl') ?? undefined; if (!provider) { return NextResponse.json({ error: 'Missing provider' }, { status: 400 }); } if (!VALID_PROVIDERS.has(provider)) { return NextResponse.json({ error: 'Invalid provider' }, { status: 400 }); } if (!isByokProviderAllowed(tier, provider)) { return NextResponse.json({ error: 'Tier restricted' }, { status: 403 }); } // Static suggestion providers: return immediately without a key if (STATIC_PROVIDERS.has(provider)) { const base = provider === 'anthropic_custom' || provider === 'custom_anthropic' ? 'anthropic' : provider; const models = PROVIDER_MODEL_SUGGESTIONS[base] ?? []; return NextResponse.json({ success: true, models, fromApi: false }); } // Live providers need a key if (!apiKey || apiKey.length < 4) { return NextResponse.json({ success: true, models: PROVIDER_MODEL_SUGGESTIONS[provider] ?? [], fromApi: false }); } const result: FetchModelsResult = await fetchLiveModelsForProvider(provider, apiKey, baseUrl); return NextResponse.json({ success: true, models: result.models, fromApi: result.fromApi }); }