fix: use v1 API for Gemini 2.5+/3.x models; show real error + generateContent filter
- GeminiIntentService/VisionService: auto-select v1 for 2.5+ models, v1beta for older - probarGemini: tries v1 then v1beta, shows actual API error message, filters model list to only those supporting generateContent so the user sees usable options Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
aa57f64e4f
commit
54736a8742
@@ -99,48 +99,57 @@ class ShowConfiguracionChat extends Component
|
||||
return;
|
||||
}
|
||||
|
||||
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent";
|
||||
// Try v1 first (newer models), fall back to v1beta
|
||||
$apiVersions = ['v1', 'v1beta'];
|
||||
$lastError = '';
|
||||
|
||||
try {
|
||||
$inicio = microtime(true);
|
||||
$response = Http::timeout(15)
|
||||
->withHeaders(['Content-Type' => 'application/json'])
|
||||
->post("{$url}?key={$key}", [
|
||||
foreach ($apiVersions as $ver) {
|
||||
$url = "https://generativelanguage.googleapis.com/{$ver}/models/{$model}:generateContent";
|
||||
|
||||
try {
|
||||
$inicio = microtime(true);
|
||||
$body = [
|
||||
'contents' => [['parts' => [['text' => 'Responde solo "ok"']]]],
|
||||
'generationConfig' => ['maxOutputTokens' => 5, 'temperature' => 0],
|
||||
...(preg_match('/gemini-(2\.5|3[\.\d]*)/', $model)
|
||||
? ['thinkingConfig' => ['thinkingBudget' => 0]]
|
||||
: []),
|
||||
]);
|
||||
|
||||
$ms = (int) ((microtime(true) - $inicio) * 1000);
|
||||
$data = $response->json();
|
||||
|
||||
if (! $response->successful() || isset($data['error'])) {
|
||||
$apiMsg = $data['error']['message'] ?? ('HTTP ' . $response->status());
|
||||
|
||||
// Listar modelos disponibles para ayudar a elegir el correcto
|
||||
$lista = Http::timeout(10)
|
||||
->get("https://generativelanguage.googleapis.com/v1beta/models?key={$key}");
|
||||
|
||||
if ($lista->successful()) {
|
||||
$nombres = collect($lista->json('models', []))
|
||||
->filter(fn ($m) => str_contains($m['name'] ?? '', 'gemini'))
|
||||
->pluck('name')
|
||||
->map(fn ($n) => str_replace('models/', '', $n))
|
||||
->values()->implode(', ');
|
||||
$this->geminiResult = "❌ Modelo \"{$model}\" no disponible. Modelos en tu cuenta: {$nombres}";
|
||||
} else {
|
||||
$this->geminiResult = "❌ Error: {$apiMsg}";
|
||||
];
|
||||
if (preg_match('/gemini-(2\.5|3[\.\d]*)/', $model)) {
|
||||
$body['thinkingConfig'] = ['thinkingBudget' => 0];
|
||||
}
|
||||
return;
|
||||
|
||||
$response = Http::timeout(15)
|
||||
->withHeaders(['Content-Type' => 'application/json'])
|
||||
->post("{$url}?key={$key}", $body);
|
||||
|
||||
$ms = (int) ((microtime(true) - $inicio) * 1000);
|
||||
$data = $response->json();
|
||||
|
||||
if ($response->successful() && ! isset($data['error'])) {
|
||||
$texto = $data['candidates'][0]['content']['parts'][0]['text'] ?? '(sin texto)';
|
||||
$this->geminiResult = "✅ Gemini OK — modelo: {$model} ({$ver}) — {$ms}ms — respuesta: \"{$texto}\"";
|
||||
return;
|
||||
}
|
||||
|
||||
$lastError = "[{$ver}] " . ($data['error']['message'] ?? 'HTTP ' . $response->status());
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$lastError = "[{$ver}] " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$texto = $data['candidates'][0]['content']['parts'][0]['text'] ?? '(sin texto)';
|
||||
$this->geminiResult = "✅ Gemini OK — modelo: {$model} — ({$ms}ms) — respuesta: \"{$texto}\"";
|
||||
// Ambas versiones fallaron — listar modelos disponibles
|
||||
$lista = Http::timeout(10)
|
||||
->get("https://generativelanguage.googleapis.com/v1beta/models?key={$key}");
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$this->geminiResult = '❌ No se pudo conectar con Gemini: ' . $e->getMessage();
|
||||
if ($lista->successful()) {
|
||||
$nombres = collect($lista->json('models', []))
|
||||
->filter(fn ($m) => str_contains($m['name'] ?? '', 'gemini'))
|
||||
->filter(fn ($m) => in_array('generateContent', $m['supportedGenerationMethods'] ?? []))
|
||||
->pluck('name')
|
||||
->map(fn ($n) => str_replace('models/', '', $n))
|
||||
->values()->implode(', ');
|
||||
$this->geminiResult = "❌ Error: {$lastError} — Modelos con generateContent: {$nombres}";
|
||||
} else {
|
||||
$this->geminiResult = "❌ Error: {$lastError}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@ class GeminiIntentService
|
||||
{
|
||||
$this->apiKey = ChatConfig::get('gemini_api_key', '');
|
||||
$this->model = ChatConfig::get('gemini_model', 'gemini-2.0-flash');
|
||||
$this->apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/{$this->model}:generateContent";
|
||||
// v1 for newer models, v1beta as fallback
|
||||
$ver = preg_match('/gemini-(2\.5|3[\.\d]*)/', $this->model) ? 'v1' : 'v1beta';
|
||||
$this->apiUrl = "https://generativelanguage.googleapis.com/{$ver}/models/{$this->model}:generateContent";
|
||||
}
|
||||
|
||||
private function buildRequest(array $contents, array $genConfig = []): array
|
||||
|
||||
@@ -18,7 +18,8 @@ class GeminiVisionService
|
||||
{
|
||||
$this->apiKey = ChatConfig::get('gemini_api_key', '');
|
||||
$this->model = ChatConfig::get('gemini_model', 'gemini-2.0-flash');
|
||||
$this->apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/{$this->model}:generateContent";
|
||||
$ver = preg_match('/gemini-(2\.5|3[\.\d]*)/', $this->model) ? 'v1' : 'v1beta';
|
||||
$this->apiUrl = "https://generativelanguage.googleapis.com/{$ver}/models/{$this->model}:generateContent";
|
||||
}
|
||||
|
||||
private function buildRequest(array $contents, array $genConfig = []): array
|
||||
|
||||
Reference in New Issue
Block a user