'success', 'sim_slug' => $simSlug, 'subject' => $subjectSlug, 'file_path' => $targetFile, 'url' => $relativeUrl, 'byte_size' => strlen($htmlCode) ]; } /** * Build the prompt for Gemini. */ private static function buildSimulationPrompt(string $lessonMarkdown, string $subjectSlug, string $simSlug): string { return << [ [ 'parts' => [ ['text' => $prompt] ] ] ], 'generationConfig' => [ 'temperature' => 0.2, 'maxOutputTokens' => 8192 ] ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_TIMEOUT => 90 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || !$response) { // Fallback to gemini-1.5-flash return self::callGeminiFallback($apiKey, $prompt); } $resData = json_decode($response, true); $text = $resData['candidates'][0]['content']['parts'][0]['text'] ?? ''; if (empty($text)) { throw new \RuntimeException("استجابة غير صالحة من Gemini."); } return $text; } private static function callGeminiFallback(string $apiKey, string $prompt): string { $model = Env::get('GEMINI_MODEL') ?: 'gemini-flash-lite-latest'; $url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}"; $payload = [ 'contents' => [ [ 'parts' => [ ['text' => $prompt] ] ] ], 'generationConfig' => [ 'temperature' => 0.2, 'maxOutputTokens' => 8192 ] ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_TIMEOUT => 90 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || !$response) { throw new \RuntimeException("فشل استدعاء Gemini API (HTTP {$httpCode})"); } $resData = json_decode($response, true); return $resData['candidates'][0]['content']['parts'][0]['text'] ?? ''; } private static function resolveGeminiKey(): ?string { if (!empty($_ENV['GEMINI_KEY'])) return $_ENV['GEMINI_KEY']; if (!empty(getenv('GEMINI_KEY'))) return getenv('GEMINI_KEY'); // Check backend/.env $envPath = __DIR__ . '/../../.env'; if (file_exists($envPath)) { $lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { if (str_starts_with(trim($line), 'GEMINI_KEY=')) { return trim(substr(trim($line), 15), '"\' '); } } } return null; } }