feat(providers): implement real API key validation with OpenRouter support

- Replace mock API key validation with actual API calls to verify keys
- Add validateApiKeyWithProvider() with provider-specific implementations
- Support Anthropic, OpenAI, Google, and OpenRouter validation
- Add OpenRouter as a new provider option in setup wizard and settings
- Fix setup page to call real validation instead of mock length check
- Allow validation during setup before provider is saved
- Return user-friendly error messages instead of raw API errors
This commit is contained in:
Haze
2026-02-06 01:25:33 +08:00
Unverified
parent af76b28286
commit 4431d2ba1d
7 changed files with 422 additions and 42 deletions

View File

@@ -31,6 +31,7 @@ const providerTypes = [
{ id: 'anthropic', name: 'Anthropic', icon: '🤖', placeholder: 'sk-ant-api03-...' },
{ id: 'openai', name: 'OpenAI', icon: '💚', placeholder: 'sk-proj-...' },
{ id: 'google', name: 'Google', icon: '🔷', placeholder: 'AIza...' },
{ id: 'openrouter', name: 'OpenRouter', icon: '🌐', placeholder: 'sk-or-v1-...' },
{ id: 'ollama', name: 'Ollama', icon: '🦙', placeholder: 'Not required' },
{ id: 'custom', name: 'Custom', icon: '⚙️', placeholder: 'API key...' },
];

View File

@@ -77,6 +77,7 @@ const providers: Provider[] = [
{ id: 'anthropic', name: 'Anthropic', model: 'Claude', icon: '🤖', placeholder: 'sk-ant-...' },
{ id: 'openai', name: 'OpenAI', model: 'GPT-4', icon: '💚', placeholder: 'sk-...' },
{ id: 'google', name: 'Google', model: 'Gemini', icon: '🔷', placeholder: 'AI...' },
{ id: 'openrouter', name: 'OpenRouter', model: 'Multi-Model', icon: '🌐', placeholder: 'sk-or-...' },
];
// Channel types
@@ -593,18 +594,26 @@ function ProviderContent({
setValidating(true);
setKeyValid(null);
// Simulate API key validation
await new Promise((resolve) => setTimeout(resolve, 1500));
// Basic validation - just check format
const isValid = apiKey.length > 10;
setKeyValid(isValid);
setValidating(false);
if (isValid) {
toast.success('API key validated successfully');
} else {
toast.error('Invalid API key format');
try {
// Call real API validation
const result = await window.electron.ipcRenderer.invoke(
'provider:validateKey',
selectedProvider,
apiKey
) as { valid: boolean; error?: string };
setKeyValid(result.valid);
if (result.valid) {
toast.success('API key validated successfully');
} else {
toast.error(result.error || 'Invalid API key');
}
} catch (error) {
setKeyValid(false);
toast.error('Validation failed: ' + String(error));
} finally {
setValidating(false);
}
};

View File

@@ -10,7 +10,7 @@ import { create } from 'zustand';
export interface ProviderConfig {
id: string;
name: string;
type: 'anthropic' | 'openai' | 'google' | 'ollama' | 'custom';
type: 'anthropic' | 'openai' | 'google' | 'openrouter' | 'ollama' | 'custom';
baseUrl?: string;
model?: string;
enabled: boolean;