encryption = $encryption; } /** * {@inheritDoc} */ public function complete( string $prompt, int $max_tokens = 600 ): string { $api_key = $this->get_api_key(); if ( empty( $api_key ) ) { throw new AIProviderException( esc_html__( 'OpenAI API key is not configured.', 'ai-discoverability-kit' ) ); } $body = array( 'model' => self::MODEL, 'max_tokens' => $max_tokens, 'temperature' => 0.7, 'messages' => array( array( 'role' => 'system', 'content' => 'You are an expert ecommerce copywriter for WooCommerce stores.', ), array( 'role' => 'user', 'content' => $prompt, ), ), ); $response = wp_remote_post( self::ENDPOINT, array( 'timeout' => 45, 'headers' => array( 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json', ), 'body' => wp_json_encode( $body ), ) ); if ( is_wp_error( $response ) ) { throw new AIProviderException( esc_html( $response->get_error_message() ) ); } $status = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status ) { $error_msg = $body['error']['message'] ?? __( 'Unknown OpenAI API error.', 'ai-discoverability-kit' ); throw new AIProviderException( esc_html( $error_msg ) ); } return trim( $body['choices'][0]['message']['content'] ?? '' ); } /** * {@inheritDoc} */ public function validate_api_key(): bool { $api_key = $this->get_api_key(); if ( empty( $api_key ) ) { return false; } try { $response = wp_remote_get( 'https://api.openai.com/v1/models', // phpcs:ignore PluginCheck.CodeAnalysis.AIProvider.DirectIntegration -- BYOK integration; WP AI Client requires WP 7.0, this plugin supports WP 6.4+. array( 'timeout' => 15, 'headers' => array( 'Authorization' => 'Bearer ' . $api_key, ), ) ); if ( is_wp_error( $response ) ) { return false; } return 200 === wp_remote_retrieve_response_code( $response ); } catch ( \Exception $e ) { return false; } } /** * {@inheritDoc} */ public function get_provider_name(): string { return 'openai'; } /** * {@inheritDoc} */ public function estimate_cost_usd( int $input_tokens, int $output_tokens ): float { return ( $input_tokens / 1000 * self::INPUT_COST_PER_1K ) + ( $output_tokens / 1000 * self::OUTPUT_COST_PER_1K ); } /** * Get the decrypted API key. * * @return string Decrypted API key, or empty string if not set. */ private function get_api_key(): string { $encrypted = get_option( 'aicommerce_openai_api_key', '' ); if ( empty( $encrypted ) ) { return ''; } return $this->encryption->decrypt( $encrypted ); } }