const GROQ_API_KEY = process.env.GROQ_API_KEY; const OLLAMA_URL = process.env.OLLAMA_URL || 'http://localhost:11434'; const GROQ_MODEL = process.env.GROQ_MODEL || 'llama-3.3-70b-versatile'; const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'llama3.2:3b'; async function callAI(prompt) { if (GROQ_API_KEY) { const res = await fetch('https://api.groq.com/openai/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${GROQ_API_KEY}` }, body: JSON.stringify({ model: GROQ_MODEL, messages: [{ role: 'user', content: prompt }], temperature: 0.8, max_tokens: 4096 }), }); if (res.ok) { const data = await res.json(); return data.choices[0].message.content; } console.warn('Groq failed, falling back to Ollama...'); } const res = await fetch(`${OLLAMA_URL}/api/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: OLLAMA_MODEL, prompt, stream: false }), }); if (!res.ok) throw new Error('Both Groq and Ollama failed.'); return (await res.json()).response; } function parseJSON(text) { try { return JSON.parse(text.trim()); } catch { const m = text.match(/\{[\s\S]*\}/); if (m) return JSON.parse(m[0]); throw new Error('Failed to parse AI response'); } } async function roastCode(code, language) { const prompt = `You are "Chef CodeRamsay" - a Gordon Ramsay-style code reviewer who is also a world-class security researcher, performance engineer, and clean-code evangelist. You roast bad code with sharp wit, creative insults, and dramatic reactions. But you ALSO provide deep, genuinely expert-level analysis. LANGUAGE: ${language || "auto-detect"} CODE TO REVIEW: \`\`\` ${code} \`\`\` Perform a COMPREHENSIVE code review covering ALL of these areas: 1. SECURITY VULNERABILITIES: Check for SQL injection, XSS, CSRF, hardcoded secrets/API keys, insecure deserialization, path traversal, command injection, insecure random, missing input validation, and any OWASP Top 10 issues. 2. PERFORMANCE ANALYSIS: Evaluate time complexity (Big O), memory usage, unnecessary loops or re-renders, N+1 queries, inefficient data structures, missing caching opportunities, blocking operations. 3. BEST PRACTICES PER LANGUAGE: Evaluate naming conventions, error handling patterns, proper use of language idioms, type safety, documentation, consistent style, SOLID principles adherence. 4. CODE SMELLS with severity: Identify code smells like long methods, god classes, magic numbers, deep nesting, code duplication, feature envy, shotgun surgery, etc. Rate each as info/warning/critical. 5. CLEAN CODE SCORE: Rate based on Robert C. Martin Clean Code principles - meaningful names, small functions, single responsibility, DRY, no side effects, command-query separation, etc. Score 0-100. 6. MAINTAINABILITY INDEX: Score 0-100 based on cyclomatic complexity, lines of code, coupling, cohesion, and readability. 7. TEST COVERAGE SUGGESTIONS: What unit tests, integration tests, and edge case tests should be written for this code? 8. DEPENDENCY/IMPORT ANALYSIS: Are imports used? Are there missing imports? Are there better alternatives to current dependencies? Any circular dependencies? 9. OVERALL LETTER GRADE: Rate A+ through F with justification. Return ONLY valid JSON (no markdown, no backticks): { "language": "", "overallScore": <1-100>, "letterGrade": "", "roastLevel": "", "openingRoast": "", "securityAnalysis": { "score": <0-100>, "vulnerabilities": [ {"type": "", "severity": "", "description": "", "location": "", "fix": "", "roast": ""} ], "summary": "<1-2 sentence security summary>" }, "performanceAnalysis": { "score": <0-100>, "timeComplexity": "", "spaceComplexity": "", "issues": [ {"issue": "", "impact": "", "suggestion": ""} ], "summary": "<1-2 sentence performance summary>" }, "bestPractices": { "score": <0-100>, "violations": [ {"practice": "", "severity": "", "description": "
", "fix": ""} ] }, "codeSmells": [ {"smell": "", "severity": "", "location": "", "description": ""} ], "cleanCodeScore": <0-100>, "cleanCodeBreakdown": { "meaningfulNames": <0-10>, "smallFunctions": <0-10>, "singleResponsibility": <0-10>, "dryPrinciple": <0-10>, "errorHandling": <0-10>, "readability": <0-10>, "formatting": <0-10>, "comments": <0-10>, "noSideEffects": <0-10>, "testability": <0-10> }, "maintainabilityIndex": <0-100>, "testSuggestions": [ {"type": "", "description": "", "priority": ""} ], "dependencyAnalysis": { "unusedImports": [""], "missingImports": [""], "suggestions": [""] }, "issues": [ {"line": "", "roast": "", "fix": "", "severity": ""} ], "rewrittenCode": "", "closingRoast": "", "wouldHire": "" } IMPORTANT: Return ONLY the JSON object. No markdown formatting, no backticks, no explanation outside the JSON.`; const text = await callAI(prompt); return parseJSON(text); } module.exports = { roastCode };