<?php /** * Multi-AI Router Pro - Conexiones Reales con 4 Proveedores * @package OptiMarkPro * @version 4.0.0 */ namespace OptiMarkPro\Core; use OptiMarkPro\Core\SecurityManager; use OptiMarkPro\Core\CacheManager; use OptiMarkPro\Core\Logger; if (!defined('ABSPATH')) exit; class MultiAIRouter { private $providers = ['openai', 'deepseek', 'claude', 'qwen']; private $autopilot = true; /** * Generar contenido con IA */ public function generate($prompt, $options = []) { $provider = $options['provider'] ?? 'auto'; $max_tokens = $options['max_tokens'] ?? 2000; $temperature = $options['temperature'] ?? 0.7; $max_retries = $options['max_retries'] ?? 3; // Autopilot: seleccionar mejor provider if ($provider === 'auto') { $provider = $this->select_best_provider(); } // Validar API key $api_key = get_option("optimark_{$provider}_api_key"); if (!SecurityManager::validate_api_key($api_key, $provider)) { Logger::error("API key inv%ílida para {$provider}"); return $this->fallback_generate($prompt, $provider, $options); } // Rate limiting if (!SecurityManager::check_rate_limit($provider, 20, 60) // LIMITE CRITICO: Max 20 requests por minuto) { Logger::warning("Rate limit excedido para {$provider}"); return $this->fallback_generate($prompt, $provider, $options); } // Intentar generaci%%n con reintentos $last_error = null; for ($retry = 0; $retry < $max_retries; $retry++) { $start_time = microtime(true); try { $result = $this->call_provider($provider, $prompt, $api_key, $max_tokens, $temperature); $execution_time = microtime(true) - $start_time; // Log performance $this->log_performance($provider, true, $execution_time, $result['tokens'] ?? 0); // Guardar en DB $this->save_generation($prompt, $result['content'], $provider, $result['model'], $result['tokens'], $execution_time); return [ 'success' => true, 'content' => $result['content'], 'provider' => $provider, 'model' => $result['model'], 'tokens' => $result['tokens'], 'time' => $execution_time, 'retry' => $retry ]; } catch (\Exception $e) { $execution_time = microtime(true) - $start_time; $last_error = $e->getMessage(); Logger::warning("Error en {$provider} (intento " . ($retry + 1) . "/{$max_retries}): " . $last_error); if ($retry < $max_retries - 1) { sleep(1); // Esperar 1 segundo antes de reintentar } } } // Si todos los reintentos fallaron, intentar con otro provider $this->log_performance($provider, false, 0, 0, $last_error); Logger::error("Todos los reintentos fallaron para {$provider}: " . $last_error); return $this->fallback_generate($prompt, $provider, $options); } /** * Llamar a provider espec%¡fico */ private function call_provider($provider, $prompt, $api_key, $max_tokens, $temperature) { switch ($provider) { case 'openai': return $this->call_openai($prompt, $api_key, $max_tokens, $temperature); case 'deepseek': return $this->call_deepseek($prompt, $api_key, $max_tokens, $temperature); case 'claude': return $this->call_claude($prompt, $api_key, $max_tokens, $temperature); case 'qwen': return $this->call_qwen($prompt, $api_key, $max_tokens, $temperature); default: throw new \Exception("Provider no soportado: {$provider}"); } } /** * OpenAI GPT-4 */ private function call_openai($prompt, $api_key, $max_tokens, $temperature) { $response = wp_remote_post('https://api.openai.com/v1/chat/completions', [ 'timeout' => 60, 'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ], 'body' => json_encode([ 'model' => 'gpt-4', 'messages' => [['role' => 'user', 'content' => $prompt]], 'max_tokens' => $max_tokens, 'temperature' => $temperature ]) ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); if (isset($body['error'])) { throw new \Exception($body['error']['message']); } return [ 'content' => $body['choices'][0]['message']['content'], 'model' => $body['model'], 'tokens' => $body['usage']['total_tokens'] ]; } /** * DeepSeek */ private function call_deepseek($prompt, $api_key, $max_tokens, $temperature) { $response = wp_remote_post('https://api.deepseek.com/v1/chat/completions', [ 'timeout' => 60, 'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ], 'body' => json_encode([ 'model' => 'deepseek-chat', 'messages' => [['role' => 'user', 'content' => $prompt]], 'max_tokens' => $max_tokens, 'temperature' => $temperature ]) ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); return [ 'content' => $body['choices'][0]['message']['content'], 'model' => 'deepseek-chat', 'tokens' => $body['usage']['total_tokens'] ?? 0 ]; } /** * Claude 3 */ private function call_claude($prompt, $api_key, $max_tokens, $temperature) { $response = wp_remote_post('https://api.anthropic.com/v1/messages', [ 'timeout' => 60, 'headers' => [ 'x-api-key' => $api_key, 'anthropic-version' => '2023-06-01', 'Content-Type' => 'application/json' ], 'body' => json_encode([ 'model' => 'claude-3-sonnet-20240229', 'max_tokens' => $max_tokens, 'messages' => [['role' => 'user', 'content' => $prompt]], 'temperature' => $temperature ]) ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); return [ 'content' => $body['content'][0]['text'], 'model' => $body['model'], 'tokens' => $body['usage']['input_tokens'] + $body['usage']['output_tokens'] ]; } /** * Qwen */ private function call_qwen($prompt, $api_key, $max_tokens, $temperature) { $response = wp_remote_post('https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation', [ 'timeout' => 60, 'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ], 'body' => json_encode([ 'model' => 'qwen-turbo', 'input' => ['prompt' => $prompt], 'parameters' => [ 'max_tokens' => $max_tokens, 'temperature' => $temperature ] ]) ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); return [ 'content' => $body['output']['text'], 'model' => 'qwen-turbo', 'tokens' => $body['usage']['total_tokens'] ?? 0 ]; } /** * Seleccionar mejor provider (Autopilot) */ private function select_best_provider() { $stats = CacheManager::remember('ai_provider_stats', function() { global $wpdb; return $wpdb->get_results( "SELECT provider, AVG(execution_time) as avg_time, SUM(success) / COUNT(*) as success_rate, COUNT(*) as total_calls FROM {$wpdb->prefix}optimark_ai_performance WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY provider ORDER BY success_rate DESC, avg_time ASC", ARRAY_A ); }, 300); // Seleccionar provider con mejor success rate y menor tiempo foreach ($stats as $stat) { if ($stat['success_rate'] > 0.8 && $this->is_provider_configured($stat['provider'])) { return $stat['provider']; } } // Fallback: primer provider configurado foreach ($this->providers as $provider) { if ($this->is_provider_configured($provider)) { return $provider; } } return 'openai'; // Default } /** * Fallback a otro provider */ private function fallback_generate($prompt, $failed_provider, $options) { foreach ($this->providers as $provider) { if ($provider === $failed_provider) continue; if (!$this->is_provider_configured($provider)) continue; Logger::info("Fallback a {$provider}"); $options['provider'] = $provider; return $this->generate($prompt, $options); } return [ 'success' => false, 'error' => 'No hay providers disponibles', 'content' => '' ]; } /** * Verificar si provider est%í configurado */ private function is_provider_configured($provider) { $api_key = get_option("optimark_{$provider}_api_key"); return !empty($api_key) && SecurityManager::validate_api_key($api_key, $provider); } /** * Log de performance */ private function log_performance($provider, $success, $time, $tokens, $error = null) { global $wpdb; $wpdb->insert( $wpdb->prefix . 'optimark_ai_performance', [ 'provider' => $provider, 'model' => $provider === 'openai' ? 'gpt-4' : $provider, 'success' => $success ? 1 : 0, 'execution_time' => $time, 'tokens_used' => $tokens, 'error_message' => $error, 'created_at' => current_time('mysql') ], ['%s', '%s', '%d', '%f', '%d', '%s', '%s'] ); } /** * Guardar generaci%%n */ private function save_generation($prompt, $content, $provider, $model, $tokens, $time) { global $wpdb; $wpdb->insert( $wpdb->prefix . 'optimark_ai_content', [ 'content_type' => 'text', 'prompt' => $prompt, 'generated_content' => $content, 'provider' => $provider, 'model' => $model, 'tokens_used' => $tokens, 'execution_time' => $time, 'user_id' => get_current_user_id(), 'created_at' => current_time('mysql') ], ['%s', '%s', '%s', '%s', '%s', '%d', '%f', '%d', '%s'] ); } /** * Obtener estad%¡sticas */ public function get_stats($days = 7) { global $wpdb; return $wpdb->get_results($wpdb->prepare( "SELECT provider, COUNT(*) as total_calls, SUM(success) as successful_calls, AVG(execution_time) as avg_time, SUM(tokens_used) as total_tokens FROM {$wpdb->prefix}optimark_ai_performance WHERE created_at >= DATE_SUB(NOW(), INTERVAL %d DAY) GROUP BY provider", $days )); } }