resolveSession($request, $categoryId); // ── Jawab soalan melalui RAG ────────────────────────────────────── try { $result = $this->ragService->ask($question, $categoryId); } catch (RuntimeException $e) { $this->logFailedAttempt($session, $question, $categoryId, $e); throw $e; } // ── Log secara async (jangan tangguh response) ──────────────────── LogChatInteractionJob::dispatch( $session->session_token, auth()->id(), $categoryId, $question, $result['answer'], $result['sources'], $result['context_chunks'], $result['model_used'], $result['tokens_used'], $result['response_time'], $result['has_answer'], ); return [ 'answer' => $result['answer'], 'has_answer' => $result['has_answer'], 'sources' => $result['sources'], 'session_token' => $session->session_token, ]; } private function resolveSession(Request $request, ?int $categoryId): ChatSession { $token = $request->session()->get('chat_session_token'); if ($token) { $session = ChatSession::where('session_token', $token)->first(); if ($session) { return $session; } } // Buat sesi baru $session = ChatSession::create([ 'user_id' => auth()->id(), 'category_id' => $categoryId, 'ip_address' => $request->ip(), 'user_agent' => $request->userAgent(), ]); $request->session()->put('chat_session_token', $session->session_token); return $session; } private function logFailedAttempt( ChatSession $session, string $question, ?int $categoryId, RuntimeException $exception ): void { Log::warning('Chatbot request failed before AI response', [ 'chat_session_id' => $session->id, 'category_id' => $categoryId, 'question' => mb_substr($question, 0, 200), 'error' => $exception->getMessage(), 'previous' => $exception->getPrevious()?->getMessage(), ]); try { ChatLog::create([ 'chat_session_id' => $session->id, 'user_id' => auth()->id(), 'category_id' => $categoryId, 'question' => $question, 'answer' => 'Perkhidmatan AI tidak tersedia pada masa ini. Sila cuba sebentar lagi.', 'sources_used' => [], 'context_chunks' => [], 'model_used' => config('ollama.chat_model'), 'tokens_used' => null, 'response_time' => null, 'has_answer' => false, 'is_flagged' => true, ]); $session->update(['last_activity_at' => now()]); } catch (Throwable $logException) { Log::error('Failed to persist failed chatbot request', [ 'chat_session_id' => $session->id, 'error' => $logException->getMessage(), ]); } } }