import { NextResponse } from 'next/server' import OpenAI from 'openai' type LlmProvider = 'openai' | 'openrouter' function getProvider(): LlmProvider { const configured = (process.env.LLM_PROVIDER ?? '').toLowerCase() if (configured === 'openrouter') return 'openrouter' if (configured === 'openai') return 'openai' return process.env.OPENROUTER_API_KEY ? 'openrouter' : 'openai' } function createClient(provider: LlmProvider) { if (provider === 'openrouter') { const apiKey = process.env.OPENROUTER_API_KEY || '' return new OpenAI({ apiKey, baseURL: process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1', defaultHeaders: { ...(process.env.OPENROUTER_SITE_URL ? { 'HTTP-Referer': process.env.OPENROUTER_SITE_URL } : {}), ...(process.env.OPENROUTER_APP_NAME ? { 'X-Title': process.env.OPENROUTER_APP_NAME } : {}), }, }) } return new OpenAI({ apiKey: process.env.OPENAI_API_KEY || '', }) } function getModel(provider: LlmProvider): string { if (provider === 'openrouter') { return process.env.OPENROUTER_MODEL || 'minimax/minimax-m2.5' } return process.env.OPENAI_MODEL || 'gpt-5-mini' } function hasApiKey(provider: LlmProvider): boolean { if (provider === 'openrouter') return !!process.env.OPENROUTER_API_KEY return !!process.env.OPENAI_API_KEY } async function generateText({ provider, model, systemMessage, prompt, }: { provider: LlmProvider model: string systemMessage: string prompt: string }) { const client = createClient(provider) const completion = await client.chat.completions.create({ model, messages: [ { role: 'system', content: systemMessage }, { role: 'user', content: prompt }, ], }) return completion.choices[0]?.message?.content || '' } export async function POST(req: Request) { try { const { prompt, type, format } = await req.json() const primaryProvider = getProvider() const primaryModel = getModel(primaryProvider) if (!prompt) { return NextResponse.json({ error: 'Prompt is required' }, { status: 400 }) } let systemMessage = '' if (type === 'news') { systemMessage = `Du bist ein erfahrener Newsletter- und PR-Experte für eine Innung (Handwerksverband). Deine Aufgabe ist es, professionelle, ansprechende und informative News-Beiträge zu schreiben. Achte auf eine klare Struktur, eine einladende Tonalität und hohe inhaltliche Qualität. Das gewünschte Ausgabeformat ist: ${format === 'markdown' ? 'Markdown' : 'Einfacher unformatierter Text'}.` } else if (type === 'stelle') { systemMessage = `Du bist ein erfahrener HR- und Recruiting-Experte für das Handwerk. Deine Aufgabe ist es, attraktive und präzise Stellenanzeigen (Lehrlingsbörse / Jobbörse) zu verfassen. Die Stellenanzeige soll Begeisterung wecken und klar die Aufgaben sowie Anforderungen kommunizieren. Das gewünschte Ausgabeformat ist: ${format === 'markdown' ? 'Markdown' : 'Einfacher unformatierter Text'}.` } else { systemMessage = `Du bist ein hilfreicher KI-Assistent. Antworte immer auf Deutsch.` } const attempts: Array<{ provider: LlmProvider; model: string; reason: string }> = [] if (hasApiKey(primaryProvider)) { attempts.push({ provider: primaryProvider, model: primaryModel, reason: 'primary', }) } // Fallback requested: if primary fails, try OpenAI GPT-5 mini when OPENAI_API_KEY is present. if (primaryProvider !== 'openai' && hasApiKey('openai')) { attempts.push({ provider: 'openai', model: 'gpt-5-mini', reason: 'fallback_openai', }) } if (attempts.length === 0) { return NextResponse.json( { error: 'No AI provider key configured (OPENROUTER_API_KEY or OPENAI_API_KEY).' }, { status: 500 } ) } let lastError: any = null for (const attempt of attempts) { try { const text = await generateText({ provider: attempt.provider, model: attempt.model, systemMessage, prompt, }) return NextResponse.json({ text, provider: attempt.provider, model: attempt.model, fallbackUsed: attempt.reason !== 'primary', }) } catch (error: any) { lastError = error console.error('AI attempt failed:', { provider: attempt.provider, model: attempt.model, message: error?.message, }) } } return NextResponse.json( { error: lastError?.message || 'All AI providers failed' }, { status: 500 } ) } catch (error: any) { console.error('AI Generate Error:', error) return NextResponse.json( { error: error?.message || 'Internal Server Error' }, { status: 500 } ) } }