import OpenAI from 'openai' import { prisma } from './prisma' // OpenAI client singleton with lazy initialization const globalForOpenAI = globalThis as unknown as { openai: OpenAI | undefined openaiInitialized: boolean } /** * Get OpenAI API key from SystemSettings */ async function getOpenAIApiKey(): Promise { try { const setting = await prisma.systemSettings.findUnique({ where: { key: 'openai_api_key' }, }) return setting?.value || process.env.OPENAI_API_KEY || null } catch { // Fall back to env var if database isn't available return process.env.OPENAI_API_KEY || null } } /** * Create OpenAI client instance */ async function createOpenAIClient(): Promise { const apiKey = await getOpenAIApiKey() if (!apiKey) { console.warn('OpenAI API key not configured') return null } return new OpenAI({ apiKey, }) } /** * Get the OpenAI client singleton * Returns null if API key is not configured */ export async function getOpenAI(): Promise { if (globalForOpenAI.openaiInitialized) { return globalForOpenAI.openai || null } const client = await createOpenAIClient() if (process.env.NODE_ENV !== 'production') { globalForOpenAI.openai = client || undefined globalForOpenAI.openaiInitialized = true } return client } /** * Check if OpenAI is configured and available */ export async function isOpenAIConfigured(): Promise { const apiKey = await getOpenAIApiKey() return !!apiKey } /** * Test OpenAI connection */ export async function testOpenAIConnection(): Promise<{ success: boolean error?: string model?: string }> { try { const client = await getOpenAI() if (!client) { return { success: false, error: 'OpenAI API key not configured', } } // Simple test request const response = await client.chat.completions.create({ model: 'gpt-4o-mini', messages: [{ role: 'user', content: 'Hello' }], max_tokens: 5, }) return { success: true, model: response.model, } } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', } } } // Default models for different use cases export const AI_MODELS = { ASSIGNMENT: 'gpt-4o', // Best for complex reasoning QUICK: 'gpt-4o-mini', // Faster, cheaper for simple tasks } as const