MaybeLogMessage($message); $url = "https://api.openai.com/v1/chat/completions"; if($apiKey == '') $apiKey = $this->GetAPIKey(); // Make the API request using WordPress HTTP API $response = \wp_remote_post($url, [ 'headers' => [ 'Authorization' => 'Bearer ' . $apiKey, 'Content-Type' => 'application/json', ], 'body' => json_encode( [ "model" => "gpt-4o-mini", "messages" => $this->PrepareMessages($message), "max_tokens" => 1000, 'response_format' => [ 'type' => 'json_object' ] ]), 'timeout' => 60 ]); // Check if the request failed if (is_wp_error($response)) { throw new FriendlyException($response->get_error_message()); } // Get HTTP response code $httpCode = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); $decodedBody = json_decode($body, true); // Convert JSON response to array // If the API returns an error message, use it $errorMessage = Sanitizer::GetStringValueFromPath($decodedBody, ['error', 'message'], 'Invalid API Key'); // Check if API Key is valid (OpenAI should return 200 for valid keys) if ($httpCode !== 200) { throw new FriendlyException("The api key does not seems to be a valid OpenAI api key error: " . $errorMessage); } $choices = Sanitizer::GetValueFromPath($decodedBody, ['choices'], null); if($choices == null) throw new FriendlyException("There was no response, please try again"); $content = $choices[0]['message']['content']; LogManager::LogDebug("OpenAI Response:\r\n" . $content); return $content; } public function GetModelName() { return 'openai'; } /** * Convert the internal message format into OpenAI's chat format. * When a message carries file attachments (a 'parts' array produced by * AIGeneratorBase::CreateMessageWithFiles), turn it into OpenAI's multimodal * content array so images (screenshots) are sent for vision. Text-only * messages keep their plain string content. */ private function PrepareMessages($messages) { $prepared = []; foreach ($messages as $message) { $role = is_object($message) ? (isset($message->role) ? $message->role : 'user') : (isset($message['role']) ? $message['role'] : 'user'); $content = is_object($message) ? (isset($message->content) ? $message->content : '') : (isset($message['content']) ? $message['content'] : ''); $parts = is_object($message) ? (isset($message->parts) ? $message->parts : null) : (isset($message['parts']) ? $message['parts'] : null); if (empty($parts) || !is_array($parts)) { $prepared[] = ['role' => $role, 'content' => $content]; continue; } $contentParts = []; foreach ($parts as $part) { $part = (array) $part; if (isset($part['text'])) { $contentParts[] = ['type' => 'text', 'text' => (string) $part['text']]; } else if (isset($part['inlineData'])) { $inline = (array) $part['inlineData']; $mimeType = isset($inline['mimeType']) ? $inline['mimeType'] : 'image/png'; $data = isset($inline['data']) ? $inline['data'] : ''; if ($data === '') { continue; } $contentParts[] = [ 'type' => 'image_url', 'image_url' => ['url' => 'data:' . $mimeType . ';base64,' . $data] ]; } } if (empty($contentParts)) { $prepared[] = ['role' => $role, 'content' => $content]; } else { $prepared[] = ['role' => $role, 'content' => $contentParts]; } } return $prepared; } }