import { NextRequest, NextResponse } from 'next/server'; /** * Grok Image Generation API * Uses xLmiler/grok2api_python backend with OpenAI-compatible format */ export async function POST(req: NextRequest) { try { const body = await req.json(); const { prompt, numImages = 1, grokApiUrl, apiKey, sso } = body; if (!prompt) { return NextResponse.json({ error: "Prompt is required" }, { status: 400 }); } if (!grokApiUrl) { return NextResponse.json({ error: "Grok API URL not configured" }, { status: 400 }); } console.log(`[Grok Image] Generating ${numImages} image(s) for: "${prompt.substring(0, 50)}..."`); // Call xLmiler backend using OpenAI-compatible format const headers: Record = { 'Content-Type': 'application/json', }; if (apiKey) { headers['Authorization'] = `Bearer ${apiKey}`; } const response = await fetch(`${grokApiUrl}/v1/chat/completions`, { method: 'POST', headers, body: JSON.stringify({ model: 'grok-4-imageGen', messages: [ { role: 'user', content: prompt } ], // The xLmiler backend handles image generation via chat completions }) }); if (!response.ok) { const errorText = await response.text(); console.error('[Grok Image] Error:', response.status, errorText); return NextResponse.json( { error: `Grok API Error: ${response.status} - ${errorText.substring(0, 200)}` }, { status: response.status } ); } const data = await response.json(); console.log('[Grok Image] Response:', JSON.stringify(data, null, 2).substring(0, 500)); // Extract image URLs from the response // xLmiler returns images in the message content or as markdown images const content = data.choices?.[0]?.message?.content || ''; // Parse image URLs from markdown format: ![...](url) or direct URLs const imageUrls: string[] = []; // Match markdown image syntax const mdImageRegex = /!\[.*?\]\((https?:\/\/[^\s)]+)\)/g; let match; while ((match = mdImageRegex.exec(content)) !== null) { imageUrls.push(match[1]); } // Also match direct URLs const urlRegex = /https:\/\/[^\s"'<>]+\.(png|jpg|jpeg|webp|gif)/gi; while ((match = urlRegex.exec(content)) !== null) { if (!imageUrls.includes(match[0])) { imageUrls.push(match[0]); } } // Return images in our standard format const images = imageUrls.slice(0, numImages).map(url => ({ url, prompt, model: 'grok-4-imageGen' })); if (images.length === 0) { // Return the raw content for debugging return NextResponse.json({ error: "No images found in response", rawContent: content.substring(0, 500) }, { status: 500 }); } return NextResponse.json({ images }); } catch (error: any) { console.error('[Grok Image] Error:', error); return NextResponse.json( { error: error.message || 'Generation failed' }, { status: 500 } ); } }