130 lines
3.8 KiB
TypeScript
130 lines
3.8 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { MetaCrawlClient } from '@/lib/providers/meta-crawl-client';
|
|
|
|
/**
|
|
* API Route: /api/meta-crawl
|
|
*
|
|
* Proxies image generation requests to the Crawl4AI Python service
|
|
* which uses browser automation to interact with Meta AI.
|
|
*/
|
|
|
|
const client = new MetaCrawlClient();
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const body = await req.json();
|
|
// Support both numImages (camelCase) and num_images (snake_case)
|
|
const { prompt, cookies, numImages, num_images, async = false } = body;
|
|
const imageCount = num_images || numImages || 4;
|
|
|
|
if (!prompt) {
|
|
return NextResponse.json(
|
|
{ error: "Prompt is required" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
if (!cookies) {
|
|
return NextResponse.json(
|
|
{ error: "Meta AI cookies are required. Please configure in settings." },
|
|
{ status: 401 }
|
|
);
|
|
}
|
|
|
|
// Check if service is healthy
|
|
const isHealthy = await client.healthCheck();
|
|
if (!isHealthy) {
|
|
return NextResponse.json(
|
|
{ error: "Crawl4AI service is not available. Please try again later." },
|
|
{ status: 503 }
|
|
);
|
|
}
|
|
|
|
if (async) {
|
|
// Async mode: return task_id for polling
|
|
const taskId = await client.generateAsync(prompt, cookies, imageCount);
|
|
return NextResponse.json({
|
|
success: true,
|
|
task_id: taskId
|
|
});
|
|
}
|
|
|
|
// Sync mode: wait for completion
|
|
console.log(`[MetaCrawl API] Generating images for: "${prompt.substring(0, 50)}..."`);
|
|
|
|
const images = await client.generate(prompt, cookies, imageCount);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
images: images.map(img => ({
|
|
url: img.url,
|
|
data: img.data,
|
|
prompt: img.prompt,
|
|
model: img.model
|
|
}))
|
|
});
|
|
|
|
} catch (error: any) {
|
|
console.error("[MetaCrawl API] Error:", error);
|
|
return NextResponse.json(
|
|
{ error: error.message || "Image generation failed" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GET /api/meta-crawl?task_id=xxx
|
|
*
|
|
* Get status of an async generation task
|
|
*/
|
|
export async function GET(req: NextRequest) {
|
|
const taskId = req.nextUrl.searchParams.get('task_id');
|
|
|
|
if (!taskId) {
|
|
// Return rate limit status
|
|
try {
|
|
const status = await client.getRateLimitStatus();
|
|
return NextResponse.json(status);
|
|
} catch {
|
|
return NextResponse.json({ error: "Service not available" }, { status: 503 });
|
|
}
|
|
}
|
|
|
|
try {
|
|
const status = await client.getTaskStatus(taskId);
|
|
return NextResponse.json(status);
|
|
} catch (error: any) {
|
|
return NextResponse.json(
|
|
{ error: error.message },
|
|
{ status: error.message === 'Task not found' ? 404 : 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DELETE /api/meta-crawl?task_id=xxx
|
|
*
|
|
* Clean up a completed task
|
|
*/
|
|
export async function DELETE(req: NextRequest) {
|
|
const taskId = req.nextUrl.searchParams.get('task_id');
|
|
|
|
if (!taskId) {
|
|
return NextResponse.json({ error: "task_id is required" }, { status: 400 });
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(`${process.env.CRAWL4AI_URL || 'http://localhost:8000'}/status/${taskId}`, {
|
|
method: 'DELETE'
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return NextResponse.json({ error: "Failed to delete task" }, { status: response.status });
|
|
}
|
|
|
|
return NextResponse.json({ deleted: true });
|
|
} catch (error: any) {
|
|
return NextResponse.json({ error: error.message }, { status: 500 });
|
|
}
|
|
}
|