getRegisteredProviderIds() as $provider_id ) { if ( \WordPress\AiClient\AiClient::isConfigured( $provider_id ) ) { return true; } } } catch ( \Throwable $e ) { return false; } return false; } private static function generate_via_chatgpt( array $context ): ?string { $api_key = trim( (string) \Academy\Helper::get_settings( 'chatgpt_api_key', '' ) ); $model = \Academy\Helper::get_settings( 'chatgpt_model', 'gpt-3.5-turbo' ); $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', array( 'timeout' => 20, // phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout -- LLM completions routinely take >3s. 'headers' => array( 'Content-Type' => 'application/json', 'Authorization' => "Bearer {$api_key}", ), 'body' => wp_json_encode( array( 'model' => $model, 'messages' => array( array( 'role' => 'system', 'content' => self::system_instruction(), ), array( 'role' => 'user', 'content' => self::build_user_prompt( $context ), ), ), ) ), ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { return null; } $body = json_decode( wp_remote_retrieve_body( $response ), true ); $text = trim( (string) ( $body['choices'][0]['message']['content'] ?? '' ) ); return '' !== $text ? $text : null; } private static function generate_via_wp_ai_client( array $context ): ?string { try { $result = \WordPress\AiClient\AiClient::prompt( self::build_user_prompt( $context ) ) ->usingSystemInstruction( self::system_instruction() ) ->generateTextResult(); $text = trim( $result->toText() ); return '' !== $text ? $text : null; } catch ( \Throwable $e ) { return null; } } private static function system_instruction(): string { return 'You are a supportive tutor giving a student brief feedback on one quiz question they just answered. ' . 'In 2-3 short sentences: say whether they got it right, explain why in simple terms, and if they got it ' . 'wrong, briefly point them toward the correct idea without being condescending. Respond in plaintext, ' . 'no markdown, no headings.'; } private static function build_user_prompt( array $context ): string { $lines = array( 'Question: ' . $context['question'], "Student's answer: " . $context['given_answer'], ); if ( ! empty( $context['correct_answer'] ) ) { $lines[] = 'Correct answer: ' . $context['correct_answer']; } $lines[] = 'The student answered this ' . ( $context['is_correct'] ? 'correctly' : 'incorrectly' ) . '.'; return implode( "\n", $lines ); } }