false, 'ai_providers' => false ]; foreach ($tables as $table => &$exists) { try { $stmt = $pdo->query("SELECT 1 FROM admin.$table LIMIT 1"); $exists = true; } catch (Exception $e) { $exists = false; } } // Construire la requête selon les tables disponibles if ($tables['hamid_providers'] && $tables['ai_providers']) { // Les deux tables existent - merger $sql = " SELECT DISTINCT ON (name) COALESCE(hp.provider_name, ap.name) as name, COALESCE(hp.api_url, ap.api_url) as api_url, COALESCE(hp.api_key, ap.api_key) as api_key, COALESCE(hp.model, ap.model, 'llama-3.1-70b') as model, COALESCE(hp.priority, ap.priority, 10) as priority, COALESCE(hp.is_active, ap.is_active, true) as is_active FROM admin.hamid_providers hp FULL OUTER JOIN admin.ai_providers ap ON LOWER(hp.provider_name) = LOWER(ap.name) WHERE COALESCE(hp.is_active, ap.is_active, true) = true ORDER BY name, priority ASC "; } elseif ($tables['hamid_providers']) { // Seulement hamid_providers $sql = " SELECT COALESCE(provider_name, name) as name, api_url, api_key, COALESCE(model, 'llama-3.1-70b') as model, COALESCE(priority, 10) as priority, COALESCE(is_active, true) as is_active FROM admin.hamid_providers WHERE COALESCE(is_active, true) = true ORDER BY priority ASC "; } elseif ($tables['ai_providers']) { // Seulement ai_providers $sql = " SELECT name, api_url, api_key, COALESCE(model, 'llama-3.1-70b') as model, COALESCE(priority, 10) as priority, COALESCE(is_active, true) as is_active FROM admin.ai_providers WHERE COALESCE(is_active, true) = true ORDER BY priority ASC "; } else { // Aucune table - fallback return []; } $stmt = $pdo->query($sql); return $stmt->fetchAll(PDO::FETCH_ASSOC); } function hamidAsk($prompt, $context = [], $preferredProvider = null) { $providers = getProviders(); // Si pas de providers dans DB, utiliser Ollama local if (empty($providers)) { $providers = [[ 'name' => 'Ollama-Local', 'api_url' => 'http://127.0.0.1:11434/api/chat', 'api_key' => '', 'model' => 'llama3.1:8b', 'priority' => 99, 'is_active' => true ]]; } // Si provider préféré, le mettre en premier if ($preferredProvider) { usort($providers, function($a, $b) use ($preferredProvider) { if (strtolower($a['name']) === strtolower($preferredProvider)) return -1; if (strtolower($b['name']) === strtolower($preferredProvider)) return 1; return ($a['priority'] ?? 10) - ($b['priority'] ?? 10); }); } // Toujours essayer Ollama local en dernier recours $providers[] = [ 'name' => 'Ollama-Local', 'api_url' => 'http://127.0.0.1:11434/api/chat', 'api_key' => '', 'model' => 'llama3.1:8b', 'priority' => 99, 'is_active' => true ]; foreach ($providers as $provider) { if ((empty($provider['api_key']) || $provider['api_key'] === 'EMPTY') && $provider['name'] !== 'Ollama-Local') { continue; } if (isset($provider['is_active']) && !$provider['is_active']) { continue; } $start = microtime(true); try { $response = callProvider($provider, $prompt, $context); $latency = round((microtime(true) - $start) * 1000); // Log succès logRequest($provider['name'], $prompt, $response, $latency, true); return [ 'response' => $response, 'provider' => $provider['name'], 'latency_ms' => $latency, 'error' => false ]; } catch (Exception $e) { logRequest($provider['name'], $prompt, $e->getMessage(), 0, false); continue; } } return [ 'response' => 'Tous les providers IA sont indisponibles.', 'provider' => 'none', 'error' => true ]; } // ... (le reste des fonctions callProvider, callOpenAICompatible, etc. reste le même)