From 1a8367ada43873c255d800406f03abd009122718 Mon Sep 17 00:00:00 2001 From: Prakhar Pandey Date: Mon, 13 Jul 2026 23:07:01 +0530 Subject: [PATCH] fix: gate OpenRouter connection on the authenticated /models/user endpoint OpenRouter's public /api/v1/models returned the full catalog even with an invalid key, so Settings showed Connected while the model call failed with Missing Authentication header. With a key present we now fetch the account-scoped /models/user with the Bearer token, so a bad key surfaces as an error instead of a false Connected; no key keeps the public preview. Other providers untouched. Note: unlike the rest of this PR, this touches core (models.ts). --- apps/x/packages/core/src/models/models.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/x/packages/core/src/models/models.ts b/apps/x/packages/core/src/models/models.ts index c14452aa..0396c301 100644 --- a/apps/x/packages/core/src/models/models.ts +++ b/apps/x/packages/core/src/models/models.ts @@ -259,8 +259,20 @@ export async function listModelsForProvider( url = `https://generativelanguage.googleapis.com/v1beta/models?key=${apiKey ?? ""}`; break; case "openrouter": - url = "https://openrouter.ai/api/v1/models"; - if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`; + // /api/v1/models is a public catalog — it returns the full + // list even with an invalid/absent key, so listing it can't + // tell a bad key from a good one (a false "Connected"). When + // a key is given, hit the account-scoped /models/user behind + // Bearer auth instead: a bad key 401s here and the shared + // throw below surfaces it. Same OpenAI-shaped { data:[{id}] } + // response, so the parse path is unchanged. No key → keep the + // public catalog so an unconfigured provider can still preview. + if (apiKey) { + url = "https://openrouter.ai/api/v1/models/user"; + headers["Authorization"] = `Bearer ${apiKey}`; + } else { + url = "https://openrouter.ai/api/v1/models"; + } break; case "ollama": url = `${(baseURL ?? "http://localhost:11434").replace(/\/$/, "")}/api/tags`;