151 lines
4.9 KiB
PHP
Executable File
151 lines
4.9 KiB
PHP
Executable File
<?php
|
|
// hamid-engine.php — Moteur IA multi-provider avec cascade failover
|
|
// Version 1.1 - Fix DB structure issues
|
|
|
|
require_once __DIR__ . '/db-connect.php';
|
|
|
|
function getProviders() {
|
|
$pdo = getDB();
|
|
|
|
// Vérifier d'abord les tables existantes
|
|
$tables = [
|
|
'hamid_providers' => 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)
|
|
|