chore: Remove unused grok and meta-chat API routes
Some checks are pending
CI / build (18.x) (push) Waiting to run
CI / build (20.x) (push) Waiting to run

This commit is contained in:
Khoa.vo 2026-01-07 19:50:03 +07:00
parent e8978bb086
commit 072c7adf89
3 changed files with 0 additions and 366 deletions

View file

@ -1,54 +0,0 @@
import { NextRequest, NextResponse } from 'next/server';
const CRAWL_SERVICE_URL = 'http://127.0.0.1:8000';
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { message, history } = body;
console.log(`[Grok Debug API] Incoming body:`, JSON.stringify(body, null, 2));
const proxyPayload = {
message,
history: history || [],
cookies: body.cookies || null,
user_agent: body.userAgent || null
};
console.log(`[Grok Debug API] Proxy payload:`, JSON.stringify(proxyPayload, null, 2));
const response = await fetch(`${CRAWL_SERVICE_URL}/grok/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(proxyPayload),
});
if (!response.ok) {
const errorText = await response.text();
console.error(`[Grok Debug API] Service error: ${response.status} ${errorText}`);
try {
// Try to parse detailed JSON error from FastAPI
const errorJson = JSON.parse(errorText);
return NextResponse.json(errorJson, { status: response.status });
} catch {
// Fallback to text
return NextResponse.json(
{ error: `Service error: ${response.status} - ${errorText}` },
{ status: response.status }
);
}
}
const data = await response.json();
return NextResponse.json(data);
} catch (error: any) {
console.error('[Grok Debug API] Internal error:', error);
return NextResponse.json(
{ error: error.message || 'Internal Server Error' },
{ status: 500 }
);
}
}

View file

@ -1,104 +0,0 @@
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<string, string> = {
'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 }
);
}
}

View file

@ -1,208 +0,0 @@
import { NextRequest, NextResponse } from 'next/server';
import { MetaAIClient } from '@/lib/providers/meta-client';
/**
* Meta AI Chat API
* Uses MetaAIClient directly (GraphQL-based) for Llama 3 chat
* No external Crawl4AI service needed
*/
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { message, history, metaCookies } = body;
if (!message) {
return NextResponse.json({ error: "Message is required" }, { status: 400 });
}
if (!metaCookies) {
return NextResponse.json(
{ error: "Meta AI cookies required. Configure in Settings." },
{ status: 401 }
);
}
console.log(`[Meta Chat] Message: "${message.substring(0, 50)}..."`);
// Use MetaAIClient to send chat message
// The Meta AI API is primarily designed for image generation,
// but we can use it for text chat by not prefixing with "Imagine"
const client = new MetaAIClient({ cookies: metaCookies });
// For chat, we need to initialize session and send via GraphQL
// Since MetaAIClient.generate() adds "Imagine" prefix for images,
// we'll create a direct chat method or adapt the prompt
// Send message directly - the response will contain text, not images
const chatPrompt = message; // Don't add "Imagine" prefix for chat
try {
// Use the internal sendPrompt mechanism via generate
// But we'll extract the text response instead of images
const response = await sendMetaChatMessage(client, chatPrompt, metaCookies);
return NextResponse.json({ response });
} catch (chatError: any) {
// If the direct approach fails, provide helpful error
throw new Error(chatError.message || "Failed to get response from Meta AI");
}
} catch (error: any) {
console.error('[Meta Chat] Error:', error);
const msg = error.message || "";
const isAuthError = msg.includes("401") || msg.includes("cookies") ||
msg.includes("expired") || msg.includes("Login");
return NextResponse.json(
{ error: error.message || 'Internal Server Error' },
{ status: isAuthError ? 401 : 500 }
);
}
}
/**
* Send a chat message to Meta AI and extract text response
*/
async function sendMetaChatMessage(client: MetaAIClient, message: string, cookies: string): Promise<string> {
const META_AI_BASE = "https://www.meta.ai";
const GRAPHQL_ENDPOINT = `${META_AI_BASE}/api/graphql/`;
// Normalize cookies from JSON array to string format
const normalizedCookies = normalizeCookies(cookies);
// First we need to get session tokens
const sessionResponse = await fetch(META_AI_BASE, {
headers: {
"Cookie": normalizedCookies,
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
}
});
const html = await sessionResponse.text();
// Extract LSD token
const lsdMatch = html.match(/\"LSD\",\[\],\{\"token\":\"([^\"]+)\"/) ||
html.match(/\"lsd\":\"([^\"]+)\"/) ||
html.match(/name=\"lsd\" value=\"([^\"]+)\"/);
const lsd = lsdMatch?.[1] || '';
// Extract access token
const tokenMatch = html.match(/\"accessToken\":\"([^\"]+)\"/);
const accessToken = tokenMatch?.[1];
if (html.includes('login_form') || html.includes('login_page')) {
throw new Error("Meta AI: Cookies expired. Please update in Settings.");
}
// Send chat message
const variables = {
message: {
text: message,
content_type: "TEXT"
},
source: "PDT_CHAT_INPUT",
external_message_id: Math.random().toString(36).substring(2) + Date.now().toString(36)
};
const body = new URLSearchParams({
fb_api_caller_class: "RelayModern",
fb_api_req_friendly_name: "useAbraSendMessageMutation",
variables: JSON.stringify(variables),
doc_id: "7783822248314888",
...(lsd && { lsd }),
});
const response = await fetch(GRAPHQL_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": normalizedCookies,
"Origin": META_AI_BASE,
"Referer": `${META_AI_BASE}/`,
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Accept": "application/json",
"Accept-Language": "en-US,en;q=0.9",
...(accessToken && { "Authorization": `OAuth ${accessToken}` })
},
body: body.toString()
});
// Get response text first
const responseText = await response.text();
// Check if response is HTML (error page)
if (responseText.trim().startsWith('<') || responseText.includes('<!DOCTYPE')) {
console.error('[Meta Chat] Received HTML instead of JSON:', responseText.substring(0, 200));
if (responseText.includes('login') || responseText.includes('checkpoint')) {
throw new Error("Meta AI: Cookies expired or account requires verification. Please update cookies in Settings.");
}
throw new Error("Meta AI: Service returned an error page. Please try again later.");
}
if (!response.ok) {
console.error('[Meta Chat] Response not OK:', response.status, responseText.substring(0, 200));
throw new Error(`Meta AI Error: ${response.status}`);
}
// Parse JSON response
let data;
try {
data = JSON.parse(responseText);
} catch (e) {
console.error('[Meta Chat] Failed to parse JSON:', responseText.substring(0, 200));
throw new Error("Meta AI: Invalid response format. Please try again.");
}
// Extract text response from the GraphQL response
const messageData = data?.data?.node?.bot_response_message ||
data?.data?.xabraAIPreviewMessageSendMutation?.message;
// Check for GraphQL errors
if (data?.errors) {
console.error('[Meta Chat] GraphQL errors:', JSON.stringify(data.errors));
throw new Error("Meta AI: Request failed. " + (data.errors[0]?.message || "Unknown error"));
}
const textResponse = messageData?.text ||
messageData?.snippet ||
messageData?.message_text ||
"I'm sorry, I couldn't generate a response.";
return textResponse;
}
/**
* Normalize cookies from JSON array format to header string format
* Handles: [{name: "foo", value: "bar"}, ...] -> "foo=bar; ..."
*/
function normalizeCookies(cookies: string): string {
if (!cookies) return '';
try {
const trimmed = cookies.trim();
// Check if it's JSON array
if (trimmed.startsWith('[')) {
const parsed = JSON.parse(trimmed);
if (Array.isArray(parsed)) {
return parsed
.map((c: any) => `${c.name}=${c.value}`)
.join('; ');
}
}
// Check if it's JSON object with multiple arrays (merged cookies)
if (trimmed.startsWith('{')) {
const parsed = JSON.parse(trimmed);
// If it's an object, iterate values
const entries = Object.entries(parsed)
.map(([k, v]) => `${k}=${v}`)
.join('; ');
return entries;
}
} catch (e) {
// Not JSON, assume it's already a string format
}
return cookies;
}