/** * Test script to verify Groq API integration for weather descriptions */ const apiKey = process.env.GROQ_API_KEY if (!apiKey || apiKey.trim() === "") { console.error("ERROR: GROQ_API_KEY is not set or empty") console.error("Please check your .env file") console.error("Add: GROQ_API_KEY=your_api_key_here") process.exit(1) } console.log(`API Key found (length: ${apiKey.length}, starts with: ${apiKey.substring(0, 10)}...)`) // Sample weather data const sampleWeatherData = { condition: "PartlyCloudy", temperature: 18, feelsLike: 16, humidity: 0.65, windSpeed: 15, precipitationChance: 0.3, uvIndex: 6, daytimeCondition: "MostlyCloudy", isNighttime: false, } // Build the same prompt that the real code uses function buildWeatherPrompt(weatherData: typeof sampleWeatherData): string { let laterConditions = "" // If it's nighttime, mention tomorrow's weather if (weatherData.isNighttime && (weatherData as any).tomorrowCondition) { laterConditions = `\n\nTomorrow's forecast: - Condition: ${(weatherData as any).tomorrowCondition} - High: ${(weatherData as any).tomorrowHighTemp ? Math.round((weatherData as any).tomorrowHighTemp) : "N/A"}°C - Low: ${(weatherData as any).tomorrowLowTemp ? Math.round((weatherData as any).tomorrowLowTemp) : "N/A"}°C ${(weatherData as any).tomorrowPrecipitationChance ? `- Precipitation chance: ${Math.round((weatherData as any).tomorrowPrecipitationChance * 100)}%` : ""}` } // Otherwise, mention changes later today else if (weatherData.daytimeCondition || (weatherData as any).overnightCondition) { laterConditions = `\n- Later today: ${weatherData.daytimeCondition || (weatherData as any).overnightCondition}` } return `Generate a concise, natural weather description for a dashboard. Keep it under 25 words. Current conditions: - Condition: ${weatherData.condition} - Feels like: ${Math.round(weatherData.feelsLike)}°C - Humidity: ${Math.round(weatherData.humidity * 100)}% - Wind speed: ${Math.round(weatherData.windSpeed)} km/h ${weatherData.precipitationChance ? `- Precipitation chance: ${Math.round(weatherData.precipitationChance * 100)}%` : ""} - UV index: ${weatherData.uvIndex}${laterConditions} Requirements: - Be conversational and friendly - Focus on what matters most (condition, any warnings) - DO NOT mention the current temperature - it will be displayed separately - CRITICAL: If it's nighttime and tomorrow's forecast is provided, PRIORITIZE tomorrow's weather (e.g., "Cool night. Tomorrow will be partly cloudy with a high of 10°C.") - If it's daytime and conditions change later, mention it (e.g., "turning cloudy later", "clearing up tonight") - Tomorrow's temperature is OK to mention - Mention feels-like only if significantly different (>3°C) and explain WHY (e.g., "due to wind", "due to humidity") - Include precipitation chance if >30% - For wind: Use descriptive terms (calm, light, moderate, strong, extreme) - NEVER use specific km/h numbers - For UV: Use descriptive terms (low, moderate, high, very high, extreme) - NEVER use specific numbers - Warn about extreme conditions (very hot/cold, high UV, strong winds) - Use natural language, not technical jargon - NO emojis - One or two short sentences maximum Example good outputs (DAYTIME): - "Partly cloudy and pleasant. Light winds make it comfortable." - "Clear skies, but feels hotter. High UV - wear sunscreen." - "Mostly sunny, turning cloudy later. Comfortable conditions." - "Rainy with 70% chance of more rain. Bring an umbrella." - "Feels much colder due to strong winds. Bundle up." - "Cloudy and mild, clearing up tonight." - "Feels warmer due to humidity. Stay hydrated." Example good outputs (NIGHTTIME - focus on tomorrow): - "Cool night. Tomorrow will be sunny and warm with a high of 24°C." - "Clear skies. Expect partly cloudy skies tomorrow, high of 10°C." - "Chilly night. Tomorrow brings rain with a high of 15°C." - "Mild evening. Tomorrow will be hot and sunny, reaching 32°C." Example BAD outputs (avoid these): - "Mostly clear at 7°C, feels like 0°C due to the 21 km/h wind." ❌ (don't mention current temp, don't use specific wind speed) - "Sunny at 28°C with UV index of 9." ❌ (don't mention current temp, don't use specific UV number) - "Temperature is 22°C with 65% humidity." ❌ (don't mention current temp, too technical) Generate description:` } const prompt = buildWeatherPrompt(sampleWeatherData) console.log("\n=== Sending request to Groq API ===\n") console.log("URL:", "https://api.groq.com/openai/v1/chat/completions") console.log("Model:", "openai/gpt-oss-120b") console.log("\nPrompt length:", prompt.length, "characters") console.log("\nFirst 500 chars of prompt:") console.log(prompt.substring(0, 500)) console.log("...\n") const requestBody = { model: "openai/gpt-oss-120b", messages: [ { role: "user", content: prompt, }, ], temperature: 0.7, max_tokens: 1000, top_p: 0.95, } try { console.log("Making API request...\n") const response = await fetch( "https://api.groq.com/openai/v1/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}`, }, body: JSON.stringify(requestBody), } ) console.log("=== Response Status ===") console.log(`Status: ${response.status} ${response.statusText}`) console.log(`OK: ${response.ok}`) if (!response.ok) { const errorText = await response.text() console.log("\n=== Error Response Body ===") console.log(errorText) try { const errorJson = JSON.parse(errorText) console.log("\n=== Parsed Error JSON ===") console.log(JSON.stringify(errorJson, null, 2)) } catch { // Not JSON, that's fine } process.exit(1) } const data = await response.json() console.log("\n=== Full API Response ===") console.log(JSON.stringify(data, null, 2)) console.log("\n=== Extracting Response Text ===") const description = data.choices?.[0]?.message?.content?.trim() || "" if (!description) { console.error("ERROR: Response text is empty!") console.log("Response structure:") console.log("- choices exists:", !!data.choices) console.log("- choices[0] exists:", !!data.choices?.[0]) console.log("- message exists:", !!data.choices?.[0]?.message) console.log("- content exists:", !!data.choices?.[0]?.message?.content) process.exit(1) } console.log("\n=== Weather Description ===") console.log(description) console.log("\n=== Description Length ===") console.log(description.length, "characters") console.log(description.split(" ").length, "words") console.log("\n✅ Test completed successfully!") } catch (error) { console.error("\n=== Request Failed ===") console.error(error) if (error instanceof Error) { console.error("Error message:", error.message) console.error("Error stack:", error.stack) } process.exit(1) }