30) { return true; } // If we're within cooldown period and have made too many requests, deny if (self::$requestCounter >= 5 && $timeSinceLastRequest < 60) { return false; } // Otherwise, allow return true; } /** * Make a request to the OpenAI API */ public static function makeRequest($messages, $model = 'gpt-3.5-turbo', $temperature = 0.7) { // Get API key from config or environment $apiKey = defined('OPENAI_API_KEY') ? OPENAI_API_KEY : getenv('OPENAI_API_KEY'); if (!$apiKey) { throw new Exception("OpenAI API key not configured"); } // Check rate limiting $currentTime = time(); $timeSinceLastRequest = $currentTime - self::$lastRequestTime; // Add some randomness to avoid all workers hitting API at exactly the same time $jitter = mt_rand(0, 2); // If we need to wait, delay the request if (self::$requestCounter > 0 && $timeSinceLastRequest < self::$defaultCooldown) { $sleepTime = self::$defaultCooldown - $timeSinceLastRequest + $jitter; // Log the wait if (function_exists('log_message')) { log_message("Rate limiting: Waiting {$sleepTime}s before next request"); } // Wait sleep($sleepTime); } // Prepare request data $data = [ 'model' => $model, 'messages' => $messages, 'temperature' => $temperature, 'max_tokens' => 1000 ]; // Initialize curl $ch = curl_init('https://api.openai.com/v1/chat/completions'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ]); // Execute request $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); // Update rate limit tracking self::$lastRequestTime = time(); self::$requestCounter++; // Log the request for debugging if (function_exists('log_message')) { log_message("Made OpenAI request (counter: " . self::$requestCounter . "), HTTP code: " . $httpCode); } // Handle errors if ($error) { throw new Exception("cURL error: " . $error); } if ($httpCode !== 200) { // Parse the response to see if it contains rate limit information $responseData = json_decode($response, true); if (isset($responseData['error'])) { $errorMessage = $responseData['error']['message'] ?? 'Unknown API error'; // Check for rate limit errors if (strpos($errorMessage, 'rate limit') !== false || $httpCode === 429) { throw new Exception("OpenAI API rate limit exceeded: " . $errorMessage); } throw new Exception("OpenAI API error: " . $errorMessage); } throw new Exception("OpenAI API HTTP error: " . $httpCode); } // Parse and return the response content $responseData = json_decode($response, true); if (!isset($responseData['choices'][0]['message']['content'])) { throw new Exception("Unexpected response format from OpenAI API"); } return $responseData['choices'][0]['message']['content']; } } ?>