This commit is contained in:
2026-09-12 12:51:20 +02:00
parent a514eb6521
commit 364fd776c4
+112 -6
View File
@@ -138,10 +138,38 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
$payload['generationConfig']['responseMimeType'] = 'application/json'; $payload['generationConfig']['responseMimeType'] = 'application/json';
} }
// Geef de sleutel zowel in de URL (?key=) als in de x-goog-api-key header mee voor proxy-ondersteuning $cleanModel = preg_replace('#^models/#', '', $model);
$endpoint = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key=" . urlencode($apiKey);
$response = fociz_http_request($endpoint, [ // Bepaal fallback volgorde van endpoints/versies voor maximale compatibiliteit met alle Google AI Studio accounts
$candidateUrls = [];
if (str_contains($cleanModel, '1.5-flash')) {
$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/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-002:generateContent";
} elseif (str_contains($cleanModel, '1.5-pro')) {
$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: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 {
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/{$cleanModel}:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1/models/{$cleanModel}:generateContent";
$candidateUrls[] = "https://generativelanguage.googleapis.com/v1beta/models/{$cleanModel}-latest:generateContent";
}
$response = null;
$lastError = null;
$successfulModel = $cleanModel;
foreach ($candidateUrls as $baseUrl) {
$endpoint = $baseUrl . '?key=' . urlencode($apiKey);
$res = fociz_http_request($endpoint, [
'method' => 'POST', 'method' => 'POST',
'headers' => [ 'headers' => [
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
@@ -151,7 +179,85 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
'timeout' => 20, 'timeout' => 20,
]); ]);
if ($response['status'] !== 200 || empty($response['json']['candidates'][0]['content']['parts'][0]['text'])) { if ($res['status'] === 200 && !empty($res['json']['candidates'][0]['content']['parts'][0]['text'])) {
$response = $res;
if (preg_match('#/models/([^:]+)#', $baseUrl, $mName)) {
$successfulModel = $mName[1];
}
break;
}
// Als het een model-not-found 404 fout is, probeer de volgende kandidaat
$msg = $res['json']['error']['message'] ?? ($res['error'] ?? '');
$lastError = $msg;
if ($res['status'] === 404 || str_contains($msg, 'not found') || str_contains($msg, 'not supported')) {
continue;
}
// Bij andere fouten (zoals ongeldige sleutel 400/403) direct stoppen
$response = $res;
break;
}
// Als alle directe kandidaten een 404 gaven, probeer dynamisch via ListModels een passend gemini model te vinden
if (!$response && ($lastError && (str_contains($lastError, 'not found') || str_contains($lastError, 'not supported')))) {
$listUrl = "https://generativelanguage.googleapis.com/v1beta/models?key=" . urlencode($apiKey);
$listRes = fociz_http_request($listUrl, [
'method' => 'GET',
'headers' => ['x-goog-api-key' => $apiKey],
'timeout' => 10,
]);
if ($listRes['status'] === 200 && !empty($listRes['json']['models'])) {
$availModels = [];
foreach ($listRes['json']['models'] as $mItem) {
$mMethods = $mItem['supportedGenerationMethods'] ?? [];
if (in_array('generateContent', $mMethods, true)) {
$mClean = preg_replace('#^models/#', '', $mItem['name'] ?? '');
if ($mClean) $availModels[] = $mClean;
}
}
// Zoek een passend gemini model
$fallbackModel = null;
foreach ($availModels as $am) {
if (str_contains($am, 'flash')) {
$fallbackModel = $am;
break;
}
}
if (!$fallbackModel) {
foreach ($availModels as $am) {
if (str_contains($am, 'gemini')) {
$fallbackModel = $am;
break;
}
}
}
if ($fallbackModel) {
$dynEndpoint = "https://generativelanguage.googleapis.com/v1beta/models/{$fallbackModel}:generateContent?key=" . urlencode($apiKey);
$dynRes = fociz_http_request($dynEndpoint, [
'method' => 'POST',
'headers' => [
'Content-Type' => 'application/json',
'x-goog-api-key' => $apiKey,
],
'body' => $payload,
'timeout' => 20,
]);
if ($dynRes['status'] === 200 && !empty($dynRes['json']['candidates'][0]['content']['parts'][0]['text'])) {
$response = $dynRes;
$successfulModel = $fallbackModel;
} else {
$response = $dynRes;
}
}
}
}
if (!$response || $response['status'] !== 200 || empty($response['json']['candidates'][0]['content']['parts'][0]['text'])) {
$errMsg = null; $errMsg = null;
if (!empty($response['json']['error']['message'])) { if (!empty($response['json']['error']['message'])) {
$errMsg = $response['json']['error']['message']; $errMsg = $response['json']['error']['message'];
@@ -160,7 +266,7 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
} elseif (!empty($response['body'])) { } elseif (!empty($response['body'])) {
$errMsg = "Gemini fout (HTTP {$response['status']}): " . strip_tags(substr((string)$response['body'], 0, 200)); $errMsg = "Gemini fout (HTTP {$response['status']}): " . strip_tags(substr((string)$response['body'], 0, 200));
} else { } else {
$errMsg = "Gemini API aanroep mislukt (HTTP {$response['status']})"; $errMsg = $lastError ?: "Gemini API aanroep mislukt";
} }
error_log("fociz_ai_chat_gemini fout: {$errMsg}"); error_log("fociz_ai_chat_gemini fout: {$errMsg}");
return [ return [
@@ -191,7 +297,7 @@ function fociz_ai_chat_gemini(array $messages, array $options, array $aiSettings
'success' => true, 'success' => true,
'content' => $cleanContent, 'content' => $cleanContent,
'json' => $parsedJson, 'json' => $parsedJson,
'model' => $model, 'model' => $successfulModel,
'provider' => 'gemini', 'provider' => 'gemini',
]; ];
} }