'Silakan tulis pertanyaan Anda terlebih dahulu.'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } try { ensureSupportSchema(); $faqs = []; try { $stmt = db()->query('SELECT keywords, answer FROM faqs ORDER BY id ASC'); $faqs = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: []; } catch (Throwable $faqError) { error_log('FAQ Load Error: ' . $faqError->getMessage()); } $faqReply = findFaqReply($faqs, $message); if ($faqReply !== '') { try { $stmt = db()->prepare('INSERT INTO messages (user_message, ai_response) VALUES (:user_message, :ai_response)'); $stmt->bindValue(':user_message', $message); $stmt->bindValue(':ai_response', $faqReply); $stmt->execute(); } catch (Throwable $saveError) { error_log('DB Save Error: ' . $saveError->getMessage()); } echo json_encode(['reply' => $faqReply], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } $knowledgeBase = "Berikut knowledge base website ini: "; if ($faqs === []) { $knowledgeBase .= "- Belum ada FAQ khusus yang dikonfigurasi. "; } else { foreach ($faqs as $faq) { $knowledgeBase .= 'Q: ' . ($faq['keywords'] ?? '') . " "; $knowledgeBase .= 'A: ' . ($faq['answer'] ?? '') . " --- "; } } $systemPrompt = "Anda adalah asisten AI yang ramah untuk website ini. " . "Gunakan knowledge base bila jawabannya tersedia. " . "Jika pertanyaan tidak ada di knowledge base, bantu secara umum dan jelaskan dengan singkat. " . "Jawab singkat, jelas, dan profesional dalam Bahasa Indonesia. " . $knowledgeBase; $response = LocalAIApi::createResponse( [ 'input' => [ ['role' => 'system', 'content' => $systemPrompt], ['role' => 'user', 'content' => $message], ], ], [ 'poll_interval' => 2, 'poll_timeout' => 45, ] ); if (!empty($response['success'])) { $aiReply = LocalAIApi::extractText($response); if ($aiReply === '') { $decoded = LocalAIApi::decodeJsonFromResponse($response); if ($decoded) { $aiReply = json_encode($decoded, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } } if ($aiReply === '') { $aiReply = 'Pesan Anda sudah diterima, tetapi balasan otomatis belum tersedia saat ini.'; } try { $stmt = db()->prepare('INSERT INTO messages (user_message, ai_response) VALUES (:user_message, :ai_response)'); $stmt->bindValue(':user_message', $message); $stmt->bindValue(':ai_response', $aiReply); $stmt->execute(); } catch (Throwable $saveError) { error_log('DB Save Error: ' . $saveError->getMessage()); } echo json_encode(['reply' => $aiReply], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } error_log('AI Error: ' . ($response['error'] ?? 'Unknown')); $fallbackReply = 'Saya belum bisa membalas otomatis saat ini. Silakan coba lagi sebentar lagi.'; try { $stmt = db()->prepare('INSERT INTO messages (user_message, ai_response) VALUES (:user_message, :ai_response)'); $stmt->bindValue(':user_message', $message); $stmt->bindValue(':ai_response', $fallbackReply); $stmt->execute(); } catch (Throwable $saveError) { error_log('DB Save Error: ' . $saveError->getMessage()); } echo json_encode(['reply' => $fallbackReply], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } catch (Throwable $error) { error_log('Chat Error: ' . $error->getMessage()); echo json_encode(['reply' => 'Terjadi kesalahan internal. Silakan coba lagi.'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); }