apiLogger->send('gemini', 'POST', $url, fn () => Http::timeout(15) ->withQueryParameters(['key' => $apiKey]) ->post($url, [ 'contents' => [[ 'parts' => [['text' => $this->defaultPrompt($priceList)]], ]], 'generationConfig' => [ 'responseMimeType' => 'application/json', 'responseSchema' => [ 'type' => 'OBJECT', 'properties' => [ 'direction' => [ 'type' => 'STRING', 'enum' => ['rising', 'falling', 'flat'], ], 'confidence' => ['type' => 'INTEGER'], 'reasoning' => ['type' => 'STRING'], ], 'required' => ['direction', 'confidence', 'reasoning'], ], ], ])); if (! $response->successful()) { Log::error(self::class.': request failed', ['status' => $response->status()]); return null; } $text = $response->json('candidates.0.content.parts.0.text') ?? ''; $data = json_decode($text, true); if (! isset($data['direction'], $data['confidence'], $data['reasoning'])) { Log::error(self::class.': unexpected response format', ['text' => $text]); return null; } return $data; } }