import { getServerConfig } from "@/lib/config"; import { requestLocale } from "@/lib/http-guard"; import { clientKey, rateLimit, rateLimitResponse } from "@/lib/rate-limit"; import { providerListModels } from "@/lib/openai-compat"; import { resolveModelTarget } from "@/lib/providers-server"; /** * Lists the models a cloud provider offers to the browser's key — the same * listing the chat picker and the Settings rows show. The key travels in the * request headers and is never stored. */ export async function GET(request: Request) { const locale = requestLocale(request); const config = getServerConfig(); const limit = rateLimit(`providers:${clientKey(request)}`, config.rateLimits.health, config.rateLimits.windowMs); if (!limit.allowed) return rateLimitResponse(limit, locale); const resolved = resolveModelTarget(config, request, locale); if ("error" in resolved) { return Response.json({ error: resolved.error.message, kind: resolved.error.kind }, { status: resolved.error.status }); } if (resolved.target.kind !== "provider") { return Response.json({ error: "Pick a provider to list its models.", kind: "bad_provider" }, { status: 400 }); } try { const models = await providerListModels(resolved.target.target, config.healthTimeoutMs * 2); return Response.json({ provider: resolved.target.provider, models }, { headers: { "Cache-Control": "no-store" } }); } catch (error) { const message = error instanceof Error ? error.message : "Could not list the models."; const kind = (error as { kind?: string }).kind ?? "unknown"; console.error("[api/providers]", kind, message); return Response.json({ error: message, kind }, { status: 502, headers: { "Cache-Control": "no-store" } }); } }