fix(gemini): no registry fallback — show 0 models when no API keys exist

Removed hardcoded registry fallback for Gemini in dashboard, catalog,
and v1beta endpoints. Without synced models (no API keys), Gemini shows
nothing. Hardcoded entries are always removed from v1beta regardless
of sync result.
This commit is contained in:
Chris Staley
2026-04-02 12:12:57 -06:00
parent 8ed091703f
commit b4e674aeb0
3 changed files with 36 additions and 41 deletions

View File

@@ -875,8 +875,8 @@ export default function ProviderDetailPage() {
(APIKEY_PROVIDERS as any)[providerId];
const isOAuth = !!(FREE_PROVIDERS as any)[providerId] || !!(OAUTH_PROVIDERS as any)[providerId];
const registryModels = getModelsByProviderId(providerId);
// For Gemini: use synced API models if available, otherwise fall back to registry
const models = providerId === "gemini" && syncedAvailableModels.length > 0
// For Gemini: always use synced API models (empty if no keys added yet)
const models = providerId === "gemini"
? syncedAvailableModels
: registryModels;
const providerAlias = getProviderAlias(providerId);

View File

@@ -255,30 +255,28 @@ export async function getUnifiedModelsResponse(
const registryEntry = REGISTRY[alias] || REGISTRY[canonicalProviderId];
const defaultContextLength = registryEntry?.defaultContextLength;
// Skip hardcoded Gemini models if synced models are available
// For Gemini: use synced API models exclusively (no hardcoded fallback)
if (alias === "gemini") {
try {
const syncedModels = await getSyncedAvailableModels("gemini");
if (syncedModels.length > 0) {
for (const sm of syncedModels) {
const aliasId = `gemini/${sm.id}`;
if (getModelIsHidden("gemini", sm.id)) continue;
models.push({
id: aliasId,
object: "model",
created: timestamp,
owned_by: "gemini",
permission: [],
root: sm.id,
parent: null,
...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}),
});
}
continue; // Skip hardcoded models for this provider
for (const sm of syncedModels) {
const aliasId = `gemini/${sm.id}`;
if (getModelIsHidden("gemini", sm.id)) continue;
models.push({
id: aliasId,
object: "model",
created: timestamp,
owned_by: "gemini",
permission: [],
root: sm.id,
parent: null,
...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}),
});
}
} catch {
// Fall through to hardcoded models
// No synced models — show nothing for Gemini
}
continue; // Always skip hardcoded models for Gemini
}
for (const model of providerModels) {

View File

@@ -37,31 +37,28 @@ export async function GET() {
}
}
// Gemini: replace hardcoded entries with synced models when available
// Gemini: always replace hardcoded entries with synced models (no fallback)
// Always remove hardcoded gemini entries — even if sync returns empty
for (let i = models.length - 1; i >= 0; i--) {
if (typeof (models[i] as any).name === "string" && (models[i] as any).name.startsWith("models/gemini/")) {
models.splice(i, 1);
}
}
try {
const syncedGeminiModels = await getSyncedAvailableModels("gemini");
if (syncedGeminiModels.length > 0) {
// Remove all hardcoded gemini entries (non-consecutive, so filter instead of splice)
for (let i = models.length - 1; i >= 0; i--) {
if (typeof (models[i] as any).name === "string" && (models[i] as any).name.startsWith("models/gemini/")) {
models.splice(i, 1);
}
}
// Add synced models
for (const m of syncedGeminiModels) {
models.push({
name: `models/gemini/${m.id}`,
displayName: m.name || m.id,
...(typeof m.description === "string" ? { description: m.description } : {}),
supportedGenerationMethods: ["generateContent"],
inputTokenLimit: typeof m.inputTokenLimit === "number" ? m.inputTokenLimit : 128000,
outputTokenLimit: typeof m.outputTokenLimit === "number" ? m.outputTokenLimit : 8192,
...(m.supportsThinking === true ? { thinking: true } : {}),
});
}
for (const m of syncedGeminiModels) {
models.push({
name: `models/gemini/${m.id}`,
displayName: m.name || m.id,
...(typeof m.description === "string" ? { description: m.description } : {}),
supportedGenerationMethods: ["generateContent"],
inputTokenLimit: typeof m.inputTokenLimit === "number" ? m.inputTokenLimit : 128000,
outputTokenLimit: typeof m.outputTokenLimit === "number" ? m.outputTokenLimit : 8192,
...(m.supportsThinking === true ? { thinking: true } : {}),
});
}
} catch {
// Non-critical
// No synced models — Gemini shows nothing
}
// Custom models (use stored metadata from provider APIs)