client = new Client(['timeout' => 30]); } public function sendMessage(string $message, UserTypeEnum $userType, array $history = []): string { $apiKey = config('services.gemini.api_key'); $contents = $this->buildContents($history, $message); $payload = [ 'systemInstruction' => [ 'parts' => [['text' => $this->loadContext($userType)]], ], 'contents' => $contents, 'generationConfig' => [ 'temperature' => 0.4, 'maxOutputTokens' => 512, ], ]; try { $response = $this->client->post(self::API_URL . '?key=' . $apiKey, [ 'json' => $payload, ]); $data = json_decode($response->getBody()->getContents(), true); return $data['candidates'][0]['content']['parts'][0]['text'] ?? __('chatbot.error_response'); } catch (GuzzleException $e) { Log::error('Gemini API error', ['error' => $e->getMessage()]); return __('chatbot.error_response'); } } private function buildContents(array $history, string $newMessage): array { $contents = []; foreach ($history as $entry) { $role = $entry['role'] === 'model' ? 'model' : 'user'; $contents[] = [ 'role' => $role, 'parts' => [['text' => $entry['text']]], ]; } $contents[] = [ 'role' => 'user', 'parts' => [['text' => $newMessage]], ]; return $contents; } private function loadContext(UserTypeEnum $userType): string { $restrictionsFile = resource_path('chatbot/restricoes.md'); $restrictions = file_exists($restrictionsFile) ? file_get_contents($restrictionsFile) : ''; $contextFile = match ($userType) { UserTypeEnum::CLIENT => resource_path('chatbot/context_cliente.txt'), UserTypeEnum::PROVIDER => resource_path('chatbot/context_prestador.txt'), default => resource_path('chatbot/context_cliente.txt'), }; $context = file_exists($contextFile) ? file_get_contents($contextFile) : ''; return $restrictions . "\n\n" . $context; } }