apiKey = ChatConfig::get('gemini_api_key', ''); } /** * Detecta la intención del texto del usuario y la mapea a una acción del sistema. * Retorna ['action' => string, 'data' => array] o null si no se puede detectar. */ public function detectar(string $texto): ?array { if (! $this->apiKey || ChatConfig::get('gemini_habilitado', '0') !== '1') { return null; } $prompt = $this->buildPrompt($texto); try { $response = Http::withHeaders(['Content-Type' => 'application/json']) ->timeout(8) ->post("{$this->apiUrl}?key={$this->apiKey}", [ 'contents' => [['parts' => [['text' => $prompt]]]], 'generationConfig' => [ 'temperature' => 0.1, 'maxOutputTokens' => 100, ], ]); if (! $response->successful()) { Log::warning('[Gemini Intent] API error: ' . $response->body()); return null; } $text = $response->json('candidates.0.content.parts.0.text', ''); return $this->parseRespuesta($text); } catch (\Throwable $e) { Log::warning('[Gemini Intent] Excepcion: ' . $e->getMessage()); return null; } } private function buildPrompt(string $texto): string { $promptExtra = ChatConfig::get('gemini_prompt_extra', ''); return << 'menu.principal', 'data' => []]; } return [ 'action' => $json['action'], 'data' => is_array($json['data'] ?? null) ? $json['data'] : [], ]; } }