/** * AI Service Factory * * Provider selection (priority order): * 1. VITE_AI_PROVIDER=openrouter → OpenRouterAIService (requires VITE_OPENROUTER_API_KEY) * 2. VITE_AI_PROVIDER=mock → MockAIService (deterministic, no API key required) * 3. VITE_USE_REAL_AI=true → OpenRouterAIService (legacy flag, requires VITE_OPENROUTER_API_KEY) * 4. (default) → MockAIService * * If VITE_AI_PROVIDER=openrouter but VITE_OPENROUTER_API_KEY is missing, the factory * logs a warning and falls back to MockAIService — never silently fails. * * Optional: VITE_OPENROUTER_MODEL controls which model OpenRouter uses. * Default: anthropic/claude-3-5-haiku */ import { MockAIService } from './mock/MockAIService' import { OpenRouterAIService } from './openrouter/OpenRouterAIService' import type { IAIService } from './IAIService' function resolveProvider(): IAIService { const provider = import.meta.env.VITE_AI_PROVIDER as string | undefined const legacyRealAI = import.meta.env.VITE_USE_REAL_AI === 'true' const apiKey = import.meta.env.VITE_OPENROUTER_API_KEY as string | undefined const wantsOpenRouter = provider === 'openrouter' || (legacyRealAI && !provider) if (wantsOpenRouter) { if (!apiKey) { console.warn( '[aiService] OpenRouter selected but VITE_OPENROUTER_API_KEY is missing — falling back to MockAIService.', 'Set VITE_AI_PROVIDER=mock to suppress this warning.', ) return MockAIService } return OpenRouterAIService } return MockAIService } export const aiService: IAIService = resolveProvider() export { MockAIService, OpenRouterAIService } export type { IAIService }