setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (Exception $e) { echo json_encode(['error' => 'DB connection failed']); exit; } $action = $_GET['action'] ?? $_POST['action'] ?? 'status'; // ==================== KNOWN AI PROVIDERS ==================== $KNOWN_PROVIDERS = [ 'groq' => [ 'name' => 'Groq', 'type' => 'free', 'endpoint' => 'https://api.groq.com/openai/v1/chat/completions', 'models' => ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant'], 'rate_limit' => '30 req/min', 'signup' => 'https://console.groq.com' ], 'cerebras' => [ 'name' => 'Cerebras', 'type' => 'free', 'endpoint' => 'https://api.cerebras.ai/v1/chat/completions', 'models' => ['llama3.1-8b', 'llama3.1-70b'], 'rate_limit' => '30 req/min', 'signup' => 'https://cloud.cerebras.ai' ], 'sambanova' => [ 'name' => 'SambaNova', 'type' => 'free', 'endpoint' => 'https://api.sambanova.ai/v1/chat/completions', 'models' => ['Meta-Llama-3.1-8B-Instruct', 'Meta-Llama-3.1-70B-Instruct'], 'rate_limit' => '10 req/min', 'signup' => 'https://cloud.sambanova.ai' ], 'together' => [ 'name' => 'Together AI', 'type' => 'free_trial', 'endpoint' => 'https://api.together.xyz/v1/chat/completions', 'models' => ['meta-llama/Llama-3-70b-chat-hf'], 'rate_limit' => '$25 free credit', 'signup' => 'https://api.together.xyz' ], 'deepseek' => [ 'name' => 'DeepSeek', 'type' => 'cheap', 'endpoint' => 'https://api.deepseek.com/chat/completions', 'models' => ['deepseek-chat', 'deepseek-coder'], 'rate_limit' => '$0.14/1M tokens', 'signup' => 'https://platform.deepseek.com' ], 'mistral' => [ 'name' => 'Mistral', 'type' => 'free_trial', 'endpoint' => 'https://api.mistral.ai/v1/chat/completions', 'models' => ['mistral-large-latest', 'codestral-latest'], 'rate_limit' => '€5 free credit', 'signup' => 'https://console.mistral.ai' ], 'cohere' => [ 'name' => 'Cohere', 'type' => 'free_trial', 'endpoint' => 'https://api.cohere.ai/v1/chat', 'models' => ['command-r-plus', 'command-r'], 'rate_limit' => '1000 req/month free', 'signup' => 'https://dashboard.cohere.com' ], 'gemini' => [ 'name' => 'Google Gemini', 'type' => 'free', 'endpoint' => 'https://generativelanguage.googleapis.com/v1beta/models', 'models' => ['gemini-1.5-flash', 'gemini-2.0-flash-exp'], 'rate_limit' => '60 req/min', 'signup' => 'https://aistudio.google.com' ], 'claude' => [ 'name' => 'Anthropic Claude', 'type' => 'paid', 'endpoint' => 'https://api.anthropic.com/v1/messages', 'models' => ['claude-3-5-sonnet-20241022'], 'rate_limit' => 'Pay per use', 'signup' => 'https://console.anthropic.com' ], 'openai' => [ 'name' => 'OpenAI', 'type' => 'paid', 'endpoint' => 'https://api.openai.com/v1/chat/completions', 'models' => ['gpt-4o', 'gpt-4o-mini'], 'rate_limit' => 'Pay per use', 'signup' => 'https://platform.openai.com' ], 'fireworks' => [ 'name' => 'Fireworks AI', 'type' => 'free_trial', 'endpoint' => 'https://api.fireworks.ai/inference/v1/chat/completions', 'models' => ['accounts/fireworks/models/llama-v3-70b-instruct'], 'rate_limit' => '$1 free credit', 'signup' => 'https://fireworks.ai' ], 'openrouter' => [ 'name' => 'OpenRouter', 'type' => 'free_trial', 'endpoint' => 'https://openrouter.ai/api/v1/chat/completions', 'models' => ['auto'], 'rate_limit' => 'Variable', 'signup' => 'https://openrouter.ai' ] ]; // ==================== ACTIONS ==================== switch ($action) { case 'status': echo json_encode([ 'status' => 'online', 'known_providers' => count($KNOWN_PROVIDERS), 'last_discovery' => date('Y-m-d H:i:s'), 'next_check' => date('Y-m-d H:i:s', strtotime('+4 hours')) ]); break; case 'list_known': echo json_encode(['success' => true, 'providers' => $KNOWN_PROVIDERS]); break; case 'list_discovered': try { $stmt = $db->query("SELECT * FROM admin.ai_providers_discovered ORDER BY priority ASC"); $providers = $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : []; echo json_encode(['success' => true, 'providers' => $providers]); } catch (Exception $e) { echo json_encode(['success' => true, 'providers' => [], 'note' => 'Table may not exist']); } break; case 'auto_discover': // Simuler découverte de nouvelles IA (à implémenter avec web scraping) $discovered = []; $newProviders = [ 'hyperbolic' => ['name' => 'Hyperbolic', 'type' => 'free', 'endpoint' => 'https://api.hyperbolic.xyz/v1/chat/completions'], 'lepton' => ['name' => 'Lepton AI', 'type' => 'free', 'endpoint' => 'https://api.lepton.ai/v1/chat/completions'], 'novita' => ['name' => 'Novita AI', 'type' => 'free', 'endpoint' => 'https://api.novita.ai/v3/openai/chat/completions'] ]; foreach ($newProviders as $key => $provider) { if (!isset($KNOWN_PROVIDERS[$key])) { $discovered[] = $provider; // Log discovery try { $stmt = $db->prepare("INSERT INTO admin.ai_discovery_logs (action, provider_name, result) VALUES ('discover', ?, 'New provider found')"); $stmt->execute([$key]); } catch (Exception $e) {} } } echo json_encode([ 'success' => true, 'discovered' => count($discovered), 'new_providers' => $discovered, 'timestamp' => date('Y-m-d H:i:s') ]); break; case 'test_all': $results = []; foreach (array_keys($KNOWN_PROVIDERS) as $provider) { $results[$provider] = ['status' => 'pending', 'tested_at' => date('Y-m-d H:i:s')]; } // Log test try { $stmt = $db->prepare("INSERT INTO admin.ai_discovery_logs (action, provider_name, result) VALUES ('test_all', 'all', ?)"); $stmt->execute([json_encode(['tested' => count($results)])]); } catch (Exception $e) {} echo json_encode(['success' => true, 'results' => $results]); break; case 'test_provider': $provider = $_POST['provider'] ?? $_GET['provider'] ?? ''; if (empty($provider)) { echo json_encode(['error' => 'Provider required']); break; } // Test via hamid-api $ch = curl_init('http://127.0.0.1:5821/hamid-api.php'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(['message' => 'Test ping', 'provider' => $provider]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_TIMEOUT => 30 ]); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $success = $httpCode === 200 && $result; // Log test try { $stmt = $db->prepare("INSERT INTO admin.ai_discovery_logs (action, provider_name, result) VALUES ('test', ?, ?)"); $stmt->execute([$provider, $success ? 'success' : 'failed']); } catch (Exception $e) {} echo json_encode([ 'success' => $success, 'provider' => $provider, 'response' => json_decode($result, true), 'tested_at' => date('Y-m-d H:i:s') ]); break; case 'integrate': $provider = $_POST['provider'] ?? ''; $apiKey = $_POST['api_key'] ?? ''; if (empty($provider) || empty($apiKey)) { echo json_encode(['error' => 'Provider and API key required']); break; } try { $stmt = $db->prepare("INSERT INTO admin.ai_providers_discovered (name, display_name, type, api_key, status, integrated_at) VALUES (?, ?, 'free', ?, 'active', NOW()) ON CONFLICT (name) DO UPDATE SET api_key = ?, status = 'active', integrated_at = NOW()"); $stmt->execute([$provider, $KNOWN_PROVIDERS[$provider]['name'] ?? $provider, $apiKey, $apiKey]); // Log integration $stmt = $db->prepare("INSERT INTO admin.ai_discovery_logs (action, provider_name, result) VALUES ('integrate', ?, 'success')"); $stmt->execute([$provider]); echo json_encode(['success' => true, 'message' => "Provider $provider integrated"]); } catch (Exception $e) { echo json_encode(['error' => $e->getMessage()]); } break; case 'logs': try { $stmt = $db->query("SELECT * FROM admin.ai_discovery_logs ORDER BY created_at DESC LIMIT 100"); $logs = $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : []; echo json_encode(['success' => true, 'logs' => $logs]); } catch (Exception $e) { echo json_encode(['success' => true, 'logs' => [], 'note' => 'Table may not exist']); } break; default: echo json_encode(['error' => 'Unknown action', 'available' => ['status', 'list_known', 'list_discovered', 'auto_discover', 'test_all', 'test_provider', 'integrate', 'logs']]); }