api_client = $api_client; $this->prompt_manager = $prompt_manager; } /** * Fine-tune text for better audio generation. * * @param string $text Text to fine-tune. * @return array Result with fine-tuned text and usage data. * * @throws \Exception When ChatGPT API quota is exceeded. * @throws \Exception When ChatGPT API key is invalid. * @throws \Exception When text processing fails. */ public function fine_tune_text( $text ) { if ( ! $this->api_client ) { accessibility_audio_tts_debug_log( 'ChatGPT API client not available - skipping text optimization', true ); return array( 'success' => true, 'text' => $text, 'optimized' => false, 'usage' => null, ); } try { $result = $this->process_with_chatgpt( $text ); if ( isset( $result['error'] ) ) { throw new \Exception( $result['error'] ); } return array( 'success' => true, 'text' => $result['text'], 'optimized' => true, 'usage' => $result['usage'] ?? null, 'tokens' => $result['tokens'] ?? array( 'input' => $result['usage']['prompt_tokens'] ?? 0, 'output' => $result['usage']['completion_tokens'] ?? 0, 'total' => $result['usage']['total_tokens'] ?? 0, ), ); } catch ( \Exception $e ) { $error_message = $e->getMessage(); // Handle specific error types. if ( 'CHATGPT_QUOTA_EXCEEDED' === $error_message ) { throw new \Exception( 'CHATGPT_QUOTA_EXCEEDED' ); } elseif ( 'CHATGPT_INVALID_API_KEY' === $error_message ) { throw new \Exception( 'CHATGPT_INVALID_API_KEY' ); } accessibility_audio_tts_debug_log( 'Text fine-tuning error: ' . $error_message, true ); throw $e; } } /** * Process text with ChatGPT API. * * @param string $text Text to process. * @return array Result with processed text and usage data. * * @throws \Exception When API request fails. */ private function process_with_chatgpt( $text ) { accessibility_audio_tts_debug_log( '[ChatGPT_Text_Processor] Processing text with length: ' . strlen( $text ), true ); // Get the prompt to use. $prompt = $this->prompt_manager ? $this->prompt_manager->get_active_prompt() : ''; // Make the API call. $response = $this->api_client->make_request( $text, $prompt ); if ( ! $response['success'] ) { // Check for specific error types. if ( 'CHATGPT_QUOTA_EXCEEDED' === $response['error'] ) { throw new \Exception( 'CHATGPT_QUOTA_EXCEEDED' ); } elseif ( 'CHATGPT_INVALID_API_KEY' === $response['error'] ) { throw new \Exception( 'CHATGPT_INVALID_API_KEY' ); } throw new \Exception( esc_html( $response['error'] ?? 'Unknown API error' ) ); } // Clean up the response text. $fine_tuned_text = $this->remove_meta_commentary( $response['content'] ); return array( 'text' => $fine_tuned_text, 'usage' => $response['usage'], 'tokens' => $response['tokens'] ?? null, ); } /** * Test text processing with sample text. * * @return array Test result. */ public function test_processing() { if ( ! $this->api_client ) { return array( 'success' => false, 'error' => 'API client not available', ); } // Test with universal TTS optimization challenges (dates, times, numbers). $test_text = 'Meeting scheduled for 15:30 on 12/10/2024. Dr. Smith will present results from Q1-Q3 (2023).'; $result = $this->fine_tune_text( $test_text ); // Handle array response from fine_tune_text. if ( is_array( $result ) && isset( $result['success'] ) ) { if ( $result['success'] && $result['optimized'] ) { return array( 'success' => true, 'message' => 'Text processing successful', 'test_result' => $result['text'], 'optimization_status' => 'Text optimization successful', 'tokens_used' => $result['tokens'] ?? null, ); } elseif ( $result['success'] && ! $result['optimized'] ) { return array( 'success' => false, 'error' => 'API not configured or invalid', ); } else { return array( 'success' => false, 'error' => 'Processing test failed', ); } } elseif ( is_string( $result ) && $result !== $test_text ) { // Backward compatibility if fine_tune_text returns string. return array( 'success' => true, 'message' => 'Text processing successful', 'test_result' => $result, 'optimization_status' => 'Text optimization successful', ); } else { return array( 'success' => false, 'error' => 'Processing failed or returned unchanged text', ); } } /** * Removes meta-commentary that ChatGPT might add despite instructions. * * @param string $text Text to clean. * @return string Cleaned text. */ private function remove_meta_commentary( $text ) { // Common meta-commentary patterns to remove - BE EXTREMELY AGGRESSIVE! $meta_patterns = array( // Beginning patterns. '/^(Here is the optimized version:?|Here\'s the optimized text:?|Here is the optimized text:?)\s*/i', '/^(The text has been optimized:?|This text is ready for TTS:?|Text is ready for TTS:?)\s*/i', '/^(I have optimized the text:?|The following text has been processed:?|I\'ve optimized the text:?)\s*/i', '/^(Optimized text:?|TTS-ready text:?|Optimized version:?)\s*/i', '/^(Below is the optimized version:?|The optimized version is:?|Here\'s the result:?)\s*/i', '/^(The optimized text is:?|Optimized:?|Ready for TTS:?)\s*/i', '/^(Text optimization:?|For TTS:?|TTS version:?)\s*/i', // End patterns. '/(This text has been optimized for natural TTS pronunciation\.?)\s*$/i', '/(The text is now ready for text-to-speech\.?|Text is now ready for TTS\.?)\s*$/i', '/(Text optimization complete\.?|Optimization complete\.?)\s*$/i', '/(Ready for TTS\.?|TTS ready\.?|Optimized for speech\.?)\s*$/i', '/(This version is optimized\.?|Optimized version complete\.?)\s*$/i', // Middle patterns. '/\[Optimized for TTS\]/i', '/\(Optimized\)/i', '/\[TTS Ready\]/i', '/\(Ready for TTS\)/i', // Any line that is ONLY meta-commentary. '/^(Optimized|Ready|TTS|Complete|Done)\.?\s*$/i', // ChatGPT sometimes adds these. '/^(Sure, here\'s|Certainly, here\'s|Of course, here\'s)\s*/i', ); $cleaned_text = $text; // Remove meta-commentary patterns. foreach ( $meta_patterns as $pattern ) { $cleaned_text = preg_replace( $pattern, '', $cleaned_text ); } // Remove leading/trailing whitespace. $cleaned_text = trim( $cleaned_text ); // If we removed something significant, log it for debugging. if ( strlen( $cleaned_text ) < strlen( $text ) * 0.9 ) { accessibility_audio_tts_debug_log( '[ChatGPT_Text_Processor] Removed meta-commentary from ChatGPT response', true ); accessibility_audio_tts_debug_log( '[ChatGPT_Text_Processor] Original length: ' . strlen( $text ) . ', Cleaned length: ' . strlen( $cleaned_text ), true ); } return $cleaned_text; } }