Files

1 line
8.2 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "adhaghani/antiturnitin", "files": {"app/api/analyze/route.ts": {"d7f3b5e5cbc37599bfd8d6f4af1b9284be7ef008": {"t": 1785745574.7405577, "n": 3857, "h": "757a0cdb53f29d1a", "c": "import { NextRequest, NextResponse } from \"next/server\";\n\nconst SYSTEM_PROMPT = `You are an expert linguistic analyzer. Evaluate the following text for 'Perplexity' and 'Burstiness'.\n- Perplexity measures the randomness and unpredictability of word choices. AI-generated text tends to have low perplexity (predictable, formulaic patterns). Human text has higher, more natural variability.\n- Burstiness measures variation in sentence structure and length. Human writing typically has high burstiness (mixing long complex sentences with short punchy ones). AI text tends toward uniform sentence patterns.\n\nReturn ONLY a valid JSON object (no markdown formatting, no code fences) with exactly this structure:\n{\n \"human_score\": <number 0-100, where 100 = most human-like>,\n \"burstiness_analysis\": \"<brief 1-2 sentence assessment of sentence variation>\",\n \"perplexity_analysis\": \"<brief 1-2 sentence assessment of word predictability>\",\n \"improvement_tips\": [\"<specific actionable tip 1>\", \"<specific actionable tip 2>\", \"<specific actionable tip 3>\"]\n}`;\n\nexport async function POST(request: NextRequest) {\n try {\n const { text } = await request.json();\n\n if (!text || typeof text !== \"string\" || text.trim().length === 0) {\n return NextResponse.json({ error: \"Text is required\" }, { status: 400 });\n }\n\n if (text.trim().length < 50) {\n return NextResponse.json(\n {\n error:\n \"Text must be at least 50 characters for a meaningful analysis\",\n },\n { status: 400 },\n );\n }\n\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return NextResponse.json(\n { error: \"Server configuration error\" },\n { status: 500 },\n );\n }\n\n const response = await fetch(\n \"https://api.deepseek.com/v1/chat/completions\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: \"deepseek-v4-pro\",\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: text.trim() },\n ],\n temperature: 0.1,\n max_tokens: 4000,\n }),\n },\n );\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n console.error(`DeepSeek API error ${response.status}:`, errorBody);\n return NextResponse.json(\n { error: `Analysis service returned an error (${response.status})` },\n { status: response.status },\n );\n }\n\n const data = await response.json();\n const content: string | undefined = data.choices?.[0]?.message?.content;\n\n if (!content) {\n console.error(\"DeepSeek returned empty content:\", data);\n return NextResponse.json(\n { error: \"No analysis returned from the service\" },\n { status: 500 },\n );\n }\n\n // DeepSeek may wrap JSON in markdown code fences — extract the raw JSON\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n console.error(\"Failed to extract JSON from DeepSeek response:\", content);\n return NextResponse.json(\n { error: \"Failed to parse analysis result\" },\n { status: 500 },\n );\n }\n\n const analysis = JSON.parse(jsonMatch[0]) as {\n human_score: number;\n burstiness_analysis: string;\n perplexity_analysis: string;\n improvement_tips: string[];\n };\n\n // Clamp human_score to 0–100 range as a safety net\n analysis.human_score = Math.max(\n 0,\n Math.min(100, Math.round(analysis.human_score)),\n );\n\n return NextResponse.json(analysis);\n } catch (error) {\n console.error(\"Analyze route error:\", error);\n return NextResponse.json(\n { error: \"Internal server error\" },\n { status: 500 },\n );\n }\n}\n"}, "ddd38f4b7ec20e30cb29e8ac632ffb45cdef613e": {"t": 1785754384.9115207, "n": 3857, "h": "8ee5dabf188722aa", "c": "import { NextRequest, NextResponse } from \"next/server\";\n\nconst SYSTEM_PROMPT = `You are an expert linguistic analyzer. Evaluate the following text for 'Perplexity' and 'Burstiness'.\n- Perplexity measures the randomness and unpredictability of word choices. AI-generated text tends to have low perplexity (predictable, formulaic patterns). Human text has higher, more natural variability.\n- Burstiness measures variation in sentence structure and length. Human writing typically has high burstiness (mixing long complex sentences with short punchy ones). AI text tends toward uniform sentence patterns.\n\nReturn ONLY a valid JSON object (no markdown formatting, no code fences) with exactly this structure:\n{\n \"human_score\": <number 0-100, where 100 = most human-like>,\n \"burstiness_analysis\": \"<brief 1-2 sentence assessment of sentence variation>\",\n \"perplexity_analysis\": \"<brief 1-2 sentence assessment of word predictability>\",\n \"improvement_tips\": [\"<specific actionable tip 1>\", \"<specific actionable tip 2>\", \"<specific actionable tip 3>\"]\n}`;\n\nexport async function POST(request: NextRequest) {\n try {\n const { text } = await request.json();\n\n if (!text || typeof text !== \"string\" || text.trim().length === 0) {\n return NextResponse.json({ error: \"Text is required\" }, { status: 400 });\n }\n\n if (text.trim().length < 50) {\n return NextResponse.json(\n {\n error:\n \"Text must be at least 50 characters for a meaningful analysis\",\n },\n { status: 400 },\n );\n }\n\n const apiKey = process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n return NextResponse.json(\n { error: \"Server configuration error\" },\n { status: 500 },\n );\n }\n\n const response = await fetch(\n \"https://api.deepseek.com/v1/chat/completions\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: \"deepseek-v4-pro\",\n messages: [\n { role: \"system\", content: SYSTEM_PROMPT },\n { role: \"user\", content: text.trim() },\n ],\n temperature: 0.1,\n max_tokens: 1000,\n }),\n },\n );\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n console.error(`DeepSeek API error ${response.status}:`, errorBody);\n return NextResponse.json(\n { error: `Analysis service returned an error (${response.status})` },\n { status: response.status },\n );\n }\n\n const data = await response.json();\n const content: string | undefined = data.choices?.[0]?.message?.content;\n\n if (!content) {\n console.error(\"DeepSeek returned empty content:\", data);\n return NextResponse.json(\n { error: \"No analysis returned from the service\" },\n { status: 500 },\n );\n }\n\n // DeepSeek may wrap JSON in markdown code fences — extract the raw JSON\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n console.error(\"Failed to extract JSON from DeepSeek response:\", content);\n return NextResponse.json(\n { error: \"Failed to parse analysis result\" },\n { status: 500 },\n );\n }\n\n const analysis = JSON.parse(jsonMatch[0]) as {\n human_score: number;\n burstiness_analysis: string;\n perplexity_analysis: string;\n improvement_tips: string[];\n };\n\n // Clamp human_score to 0–100 range as a safety net\n analysis.human_score = Math.max(\n 0,\n Math.min(100, Math.round(analysis.human_score)),\n );\n\n return NextResponse.json(analysis);\n } catch (error) {\n console.error(\"Analyze route error:\", error);\n return NextResponse.json(\n { error: \"Internal server error\" },\n { status: 500 },\n );\n }\n}\n"}}}}