diff --git a/src/lib/aiProviders.ts b/src/lib/aiProviders.ts new file mode 100644 index 0000000..588e737 --- /dev/null +++ b/src/lib/aiProviders.ts @@ -0,0 +1,74 @@ +export type AIProvider = 'pollinations' | 'gpt-oss' | 'custom'; + +export interface AIProviderConfig { + id: AIProvider; + name: string; + description: string; + endpoint: string; + requiresAuth: boolean; + apiKey?: string; + model?: string; + allowsCustomKey?: boolean; +} + +const getGptOssApiKey = (): string | undefined => { + return import.meta.env?.VITE_GPT_OSS_API_KEY || + process.env.VITE_GPT_OSS_API_KEY || + process.env.NEXT_PUBLIC_GPT_OSS_API_KEY; +}; + +export const AI_PROVIDERS: AIProviderConfig[] = [ + { + id: 'pollinations', + name: 'Pollinations.ai', + description: 'Free, no login required', + endpoint: 'https://text.pollinations.ai/openai', + requiresAuth: false, + model: 'openai', + }, + { + id: 'gpt-oss', + name: 'GPT-OSS-20B', + description: 'Alternative model (requires API key)', + endpoint: 'https://api.pawan.krd/gpt-oss-20b/v1/chat/completions', + requiresAuth: true, + get apiKey() { + return getGptOssApiKey(); + }, + model: 'gpt-oss-20b', + }, + { + id: 'custom', + name: 'Custom API', + description: 'Use your own OpenAI-compatible API', + endpoint: '', + requiresAuth: true, + allowsCustomKey: true, + model: '', + }, +]; + +export const getProvider = (id: AIProvider): AIProviderConfig => { + const provider = AI_PROVIDERS.find(p => p.id === id) || AI_PROVIDERS[0]; + + if (id === 'custom') { + const stored = localStorage.getItem(CUSTOM_API_STORAGE_KEY); + if (stored) { + try { + const customConfig = JSON.parse(stored); + return { + ...provider, + endpoint: customConfig.endpoint || '', + apiKey: customConfig.apiKey || undefined, + model: customConfig.model || '', + }; + } catch { + return provider; + } + } + } + + return provider; +}; + +export const CUSTOM_API_STORAGE_KEY = 'ai-chat-custom-api';