From 42e9c9a309c0bf5514b7e0af18910acf2f46b80f Mon Sep 17 00:00:00 2001 From: ravindra-bruno Date: Wed, 24 Jun 2026 13:52:44 +0530 Subject: [PATCH] =?UTF-8?q?fix(ai):=20validate=20provider=20keys=20via=20/?= =?UTF-8?q?v1/models=20instead=20of=20a=20generatio=E2=80=A6=20(#8340)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/bruno-electron/src/ipc/ai/index.js | 23 ++++++++++--------- .../bruno-electron/src/ipc/ai/providers.js | 12 ++++++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/bruno-electron/src/ipc/ai/index.js b/packages/bruno-electron/src/ipc/ai/index.js index c1c2b3d08..0cdc7ae37 100644 --- a/packages/bruno-electron/src/ipc/ai/index.js +++ b/packages/bruno-electron/src/ipc/ai/index.js @@ -4,7 +4,6 @@ const { getPreferences } = require('../../store/preferences'); const { aiKeyStore } = require('../../store/ai-keys'); const { PROVIDERS, - MODEL_DEFINITIONS, listProviders, listModels, getModel, @@ -107,18 +106,20 @@ const registerAiIpc = (mainWindow) => { return { ok: false, error: `${PROVIDERS[providerId].label} is disabled` }; } - const probeModel = Object.entries(MODEL_DEFINITIONS) - .find(([, def]) => def.provider === providerId); - if (!probeModel) { - return { ok: false, error: `No models registered for ${providerId}` }; - } - try { - const model = resolveModel(probeModel[0]); - await generateText({ model, prompt: 'ping', maxOutputTokens: 1 }); - return { ok: true }; + const res = await PROVIDERS[providerId].validateApiKey({ apiKey }); + if (res.ok) { + return { ok: true }; + } + if (res.status === 401 || res.status === 403) { + return { ok: false, error: 'Invalid API key' }; + } + if (res.status === 429) { + return { ok: false, error: 'Rate limited — try again in a moment' }; + } + return { ok: false, error: `Could not verify key (HTTP ${res.status})` }; } catch (err) { - return { ok: false, error: err.message || 'Connection failed' }; + return { ok: false, error: 'Could not reach provider. Check your network connection.' }; } }); diff --git a/packages/bruno-electron/src/ipc/ai/providers.js b/packages/bruno-electron/src/ipc/ai/providers.js index 0a74d1d34..5fe945ec8 100644 --- a/packages/bruno-electron/src/ipc/ai/providers.js +++ b/packages/bruno-electron/src/ipc/ai/providers.js @@ -7,14 +7,22 @@ const PROVIDERS = { label: 'OpenAI', apiKeyPlaceholder: 'sk-...', apiKeyHelpUrl: 'https://platform.openai.com/api-keys', - createSdk: ({ apiKey }) => createOpenAI({ apiKey }) + createSdk: ({ apiKey }) => createOpenAI({ apiKey }), + validateApiKey: ({ apiKey }) => fetch('https://api.openai.com/v1/models', { + headers: { Authorization: `Bearer ${apiKey}` }, + signal: AbortSignal.timeout(10000) + }) }, anthropic: { id: 'anthropic', label: 'Anthropic', apiKeyPlaceholder: 'sk-ant-...', apiKeyHelpUrl: 'https://console.anthropic.com/settings/keys', - createSdk: ({ apiKey }) => createAnthropic({ apiKey }) + createSdk: ({ apiKey }) => createAnthropic({ apiKey }), + validateApiKey: ({ apiKey }) => fetch('https://api.anthropic.com/v1/models', { + headers: { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' }, + signal: AbortSignal.timeout(10000) + }) } };