Merge pull request 'AI fix' (#65) from dev into main

Reviewed-on: #65
This commit was merged in pull request #65.
This commit is contained in:
2026-09-12 11:01:08 +00:00
2 changed files with 30 additions and 16 deletions
+4 -3
View File
@@ -1144,9 +1144,10 @@ require_once __DIR__ . '/includes/header.php';
<label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">AI Provider & Model</label> <label class="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1.5">AI Provider & Model</label>
<select name="ai_model" id="admin_ai_model" class="w-full bg-slate-50 dark:bg-[#0c0f17] border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500"> <select name="ai_model" id="admin_ai_model" class="w-full bg-slate-50 dark:bg-[#0c0f17] border border-slate-300 dark:border-slate-800 rounded-xl px-3 py-2 text-slate-900 dark:text-white text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500">
<optgroup label="Google Gemini (Aanbevolen)"> <optgroup label="Google Gemini (Aanbevolen)">
<option value="gemini-1.5-pro" <?= ($aiSettings['ai_model'] === 'gemini-1.5-pro' || empty($aiSettings['ai_model']) || $aiSettings['ai_model'] === 'gemini') ? 'selected' : '' ?>>Google Gemini 1.5 Pro (Aanbevolen & Slim)</option> <option value="gemini-3.6-flash" <?= ($aiSettings['ai_model'] === 'gemini-3.6-flash' || empty($aiSettings['ai_model']) || $aiSettings['ai_model'] === 'gemini') ? 'selected' : '' ?>>Google Gemini 3.6 Flash (Aanbevolen, Snel & Nieuwste)</option>
<option value="gemini-2.0-flash" <?= $aiSettings['ai_model'] === 'gemini-2.0-flash' ? 'selected' : '' ?>>Google Gemini 2.0 Flash (Snel & Modern)</option> <option value="gemini-1.5-pro" <?= $aiSettings['ai_model'] === 'gemini-1.5-pro' ? 'selected' : '' ?>>Google Gemini 1.5 Pro (Slim & Uitgebreid)</option>
<option value="gemini-1.5-flash" <?= $aiSettings['ai_model'] === 'gemini-1.5-flash' ? 'selected' : '' ?>>Google Gemini 1.5 Flash (Lichtgewicht)</option> <option value="gemini-2.0-flash" <?= $aiSettings['ai_model'] === 'gemini-2.0-flash' ? 'selected' : '' ?>>Google Gemini 2.0 Flash</option>
<option value="gemini-1.5-flash" <?= $aiSettings['ai_model'] === 'gemini-1.5-flash' ? 'selected' : '' ?>>Google Gemini 1.5 Flash</option>
</optgroup> </optgroup>
<optgroup label="OpenAI"> <optgroup label="OpenAI">
<option value="gpt-4o-mini" <?= $aiSettings['ai_model'] === 'gpt-4o-mini' ? 'selected' : '' ?>>OpenAI GPT-4o-mini</option> <option value="gpt-4o-mini" <?= $aiSettings['ai_model'] === 'gpt-4o-mini' ? 'selected' : '' ?>>OpenAI GPT-4o-mini</option>
+26 -13
View File
@@ -142,32 +142,35 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
// Bepaal fallback volgorde van endpoints/versies voor maximale compatibiliteit met alle Google AI Studio accounts // Bepaal fallback volgorde van endpoints/versies voor maximale compatibiliteit met alle Google AI Studio accounts
$candidateUrls = []; $candidateUrls = [];
if (str_contains($cleanModel, '1.5-flash')) { if (str_contains($cleanModel, '3.6-flash')) {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-3.6-flash:generateContent";
} elseif (str_contains($cleanModel, '2.0-flash')) {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent";
} elseif (str_contains($cleanModel, '1.5-flash')) {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-flash:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-001:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-001:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-002:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-002:generateContent";
} elseif (str_contains($cleanModel, '1.5-pro')) { } elseif (str_contains($cleanModel, '1.5-pro')) {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-pro:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-pro:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-001:generateContent";
} elseif (str_contains($cleanModel, '2.0-flash')) {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/gemini-2.0-flash:generateContent";
} else { } else {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/{$cleanModel}:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/{$cleanModel}:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.6-flash:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/{$cleanModel}:generateContent"; $candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/{$cleanModel}:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/{$cleanModel}-latest:generateContent";
} }
$response = null; $response = null;
$lastError = null; $lastError = null;
$successfulModel = $cleanModel; $successfulModel = $cleanModel;
foreach ($candidateUrls as $baseUrl) { for ($i = 0; $i < count($candidateUrls); $i++) {
$baseUrl = $candidateUrls[$i];
$endpoint = $baseUrl . '?key=' . urlencode($apiKey); $endpoint = $baseUrl . '?key=' . urlencode($apiKey);
$res = fociz_http_request($endpoint, [ $res = fociz_http_request($endpoint, [
'method' => 'POST', 'method' => 'POST',
@@ -187,14 +190,24 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
break; break;
} }
// Als het een model-not-found 404 fout is, probeer de volgende kandidaat
$msg = $res['json']['error']['message'] ?? ($res['error'] ?? ''); $msg = $res['json']['error']['message'] ?? ($res['error'] ?? '');
$lastError = $msg; $lastError = $msg;
if ($res['status'] === 404 || str_contains($msg, 'not found') || str_contains($msg, 'not supported')) {
// Als Google in de foutmelding direct een nieuwer model aanbeveelt (bv. "use models/gemini-3.6-flash")
if (preg_match('#use (?:models/)?(gemini-[a-zA-Z0-9\.\-_]+)#i', $msg, $recMatch)) {
$recModel = $recMatch[1];
$recUrl = "https://generativelanguage.googleapis.com/v1beta/models/{$recModel}:generateContent";
if (!in_array($recUrl, $candidateUrls, true)) {
$candidateUrls[] = $recUrl;
}
}
// Als het model niet gevonden is, niet meer beschikbaar is of deprecated is, probeer de volgende kandidaat
if ($res['status'] === 404 || str_contains($msg, 'not found') || str_contains($msg, 'not supported') || str_contains($msg, 'no longer available') || str_contains($msg, 'deprecated')) {
continue; continue;
} }
// Bij andere fouten (zoals ongeldige sleutel 400/403) direct stoppen // Bij autorisatiefouten (zoals ongeldige API key 400/403) direct stoppen
$response = $res; $response = $res;
break; break;
} }