Files
9router/src/app/api/v1beta/models/route.js
nguyenha935 dae69a3916 fix(gemini): support native TTS generateContent endpoint
Pass Gemini AUDIO/TTS generateContent requests through to Google's native
v1beta endpoint instead of converting to chat, with per-credential fallback
(504 timeout, 502 fetch failure). Accept client keys from Bearer,
x-goog-api-key, or ?key= while forwarding only the configured Gemini
credential upstream. Expose native v1beta model names and rewrites, and add
Gemini 3.1 Flash TTS to the catalogs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 10:50:13 +07:00

63 lines
1.7 KiB
JavaScript

import { PROVIDER_MODELS } from "@/shared/constants/models";
/**
* Handle CORS preflight
*/
export async function OPTIONS() {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "*"
}
});
}
/**
* GET /v1beta/models - Gemini compatible models list
* Returns models in Gemini API format
*/
export async function GET() {
try {
const models = [];
const seen = new Set();
function addModel({ name, displayName, description, methods = ["generateContent"] }) {
if (seen.has(name)) return;
seen.add(name);
models.push({
name,
displayName,
description,
supportedGenerationMethods: methods,
inputTokenLimit: 128000,
outputTokenLimit: 8192,
});
}
for (const [provider, providerModels] of Object.entries(PROVIDER_MODELS)) {
for (const model of providerModels) {
addModel({
name: `models/${provider}/${model.id}`,
displayName: model.name || model.id,
description: `${provider} model: ${model.name || model.id}`,
});
if (provider === "gemini") {
addModel({
name: `models/${model.id}`,
displayName: model.name || model.id,
description: `Gemini model: ${model.name || model.id}`,
methods: ["generateContent", "streamGenerateContent"],
});
}
}
}
return Response.json({ models });
} catch (error) {
console.log("Error fetching models:", error);
return Response.json({ error: { message: error.message } }, { status: 500 });
}
}