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.7, max_tokens: 8000 }), }); 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. Set GROQ_API_KEY or start Ollama.'); 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 validateIdea(idea, targetAudience, monetization) { const prompt = `You are a world-class startup advisor, venture capital analyst, and market strategist with 20+ years of experience evaluating startup ideas for top-tier VCs (Sequoia, a16z, Y Combinator). You have deep expertise in TAM/SAM/SOM estimation, competitive analysis, financial modeling, and go-to-market strategy. Evaluate this startup idea with the rigor and depth of a Series A due diligence report. STARTUP IDEA: ${idea} TARGET AUDIENCE: ${targetAudience || 'Not specified'} MONETIZATION: ${monetization || 'Not specified'} Return ONLY valid JSON with this EXACT structure (no markdown, no code blocks, just raw JSON): { "ideaName": "", "oneLiner": "", "overallScore": <1-100 integer>, "verdict": "", "verdictExplanation": "<3-4 sentences explaining the verdict with specific reasoning>", "marketSizing": { "tam": "", "tamReasoning": "", "sam": "", "samReasoning": "", "som": "", "somReasoning": "", "marketGrowthRate": "", "marketTrend": "", "timing": "", "timingNote": "" }, "competitorAnalysis": { "directCompetitors": [ {"name": "", "funding": "", "strength": "", "weakness": "", "marketShare": ""} ], "indirectCompetitors": [ {"name": "", "howTheyCompete": "", "threat": ""} ], "potentialCompetitors": [ {"name": "", "likelihood": "", "timeframe": ""} ], "competitiveAdvantage": "", "moatPossibility": "", "moatStrategy": "" }, "revenueModel": { "primaryModel": "", "pricingStrategy": "", "projectedRevenue": { "year1": "", "year2": "", "year3": "" }, "unitEconomics": { "ltv": "", "cac": "", "ltvCacRatio": "", "paybackPeriod": "", "grossMargin": "" }, "breakEvenTimeline": "" }, "swotAnalysis": { "strengths": ["", "", ""], "weaknesses": ["", "", ""], "opportunities": ["", "", ""], "threats": ["", "", ""] }, "goToMarket": { "phase1": {"name": "Launch (Month 1-3)", "strategy": "", "channels": ["", ""], "targetMetric": "", "budget": ""}, "phase2": {"name": "Growth (Month 4-8)", "strategy": "", "channels": ["", ""], "targetMetric": "", "budget": ""}, "phase3": {"name": "Scale (Month 9-12)", "strategy": "", "channels": ["", ""], "targetMetric": "", "budget": ""}, "viralPotential": "", "viralMechanism": "", "earlyAdopters": "" }, "fundingAssessment": { "currentStage": "", "readiness": "", "recommendedRaise": "", "valuationRange": "", "keyMilestonesNeeded": ["", "", ""], "investorFit": ["", ""], "pitchStrength": "" }, "feasibility": { "technicalComplexity": "", "technicalNote": "", "timeToMVP": "", "estimatedCost": "", "teamNeeded": ["", "", ""], "biggestTechnicalRisk": "
", "techStack": "" }, "riskMatrix": [ {"risk": "", "category": "", "probability": "", "impact": "", "severity": "", "mitigation": ""} ], "pivotSuggestions": [ {"pivot": "", "reasoning": "", "effort": ""} ], "similarSuccesses": [ {"company": "", "similarity": "", "outcome": "", "lessonToApply": ""} ], "ninetyDayPlan": [ {"week": "Week 1-2", "action": "", "deliverable": "", "goal": ""}, {"week": "Week 3-4", "action": "", "deliverable": "", "goal": ""}, {"week": "Week 5-6", "action": "", "deliverable": "", "goal": ""}, {"week": "Week 7-8", "action": "", "deliverable": "", "goal": ""}, {"week": "Week 9-10", "action": "", "deliverable": "", "goal": ""}, {"week": "Week 11-12", "action": "", "deliverable": "", "goal": ""} ], "pitchDeckOutline": [ {"slide": 1, "title": "Problem", "content": ""}, {"slide": 2, "title": "Solution", "content": ""}, {"slide": 3, "title": "Market Size", "content": ""}, {"slide": 4, "title": "Product", "content": ""}, {"slide": 5, "title": "Business Model", "content": ""}, {"slide": 6, "title": "Traction", "content": ""}, {"slide": 7, "title": "Competition", "content": ""}, {"slide": 8, "title": "Team", "content": ""}, {"slide": 9, "title": "Financials", "content": ""}, {"slide": 10, "title": "The Ask", "content": ""} ] } CRITICAL INSTRUCTIONS: - Return ONLY raw JSON. No markdown. No code blocks. No explanatory text. - Every field must be filled with substantive, specific content (no generic placeholders). - Dollar figures should be realistic and well-reasoned. - Competitor names should be real companies when possible. - The 90-day plan should be actionable and specific. - Risk matrix should have 4-6 risks covering market, technical, financial, and operational categories. - Include 3+ direct competitors, 2+ indirect competitors, and 2+ potential competitors. - Pivot suggestions should have 2-3 options. - Similar successes should reference 3+ real companies.`; const text = await callAI(prompt); return parseJSON(text); } module.exports = { validateIdea };