fix: skip thinking parts in Gemini vision response + extract JSON from any position
gemini-3.x models return thinking blocks with thought:true flag in parts[].
Filter those out so only actual response text is used.
Also extract the first {...} JSON object from the text so stray content
before or after (like '040825') doesn't break parsing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
bd93ef2029
commit
5c15f9f3fe
@@ -77,9 +77,12 @@ class GeminiVisionService
|
||||
$inputTokens = $response->json('usageMetadata.promptTokenCount', 0);
|
||||
$outputTokens = $response->json('usageMetadata.candidatesTokenCount', 0);
|
||||
|
||||
// Collect text from ALL parts (newer models may put JSON in parts[1] if thinking is in parts[0])
|
||||
// Skip thought parts (gemini-3.x thinking blocks), only keep actual response text
|
||||
$parts = $response->json('candidates.0.content.parts', []);
|
||||
$text = implode("\n", array_column(array_filter($parts, fn($p) => isset($p['text'])), 'text'));
|
||||
$text = implode("\n", array_column(
|
||||
array_filter($parts, fn($p) => isset($p['text']) && empty($p['thought'])),
|
||||
'text'
|
||||
));
|
||||
|
||||
Log::info('[Gemini Vision] raw response: ' . substr($text, 0, 500));
|
||||
|
||||
@@ -129,7 +132,13 @@ PROMPT;
|
||||
|
||||
private function parseRespuesta(string $text): ?array
|
||||
{
|
||||
$text = trim(preg_replace('/```json\s*|\s*```/', '', $text));
|
||||
// Strip markdown fences
|
||||
$text = preg_replace('/```json\s*|\s*```/', '', $text);
|
||||
// Extract the first JSON object found anywhere in the text
|
||||
if (preg_match('/\{.*\}/s', $text, $m)) {
|
||||
$text = $m[0];
|
||||
}
|
||||
$text = trim($text);
|
||||
$json = json_decode($text, true);
|
||||
|
||||
if (! is_array($json) || isset($json['error'])) {
|
||||
|
||||
Reference in New Issue
Block a user