prepare("SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1"); $stmt->execute([$table]); $cache[$table] = (bool)$stmt->fetchColumn(); } catch (Throwable $e) { $cache[$table] = false; } return $cache[$table]; } function chatColumnExists(string $table, string $column): bool { static $cache = []; $cacheKey = strtolower($table . '.' . $column); if (array_key_exists($cacheKey, $cache)) { return $cache[$cacheKey]; } try { $stmt = db()->prepare("SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ? LIMIT 1"); $stmt->execute([$table, $column]); $cache[$cacheKey] = (bool)$stmt->fetchColumn(); } catch (Throwable $e) { $cache[$cacheKey] = false; } return $cache[$cacheKey]; } function chatFetchFaqs(): array { if (!chatTableExists('faqs') || !chatColumnExists('faqs', 'keywords') || !chatColumnExists('faqs', 'answer')) { return []; } $stmt = db()->query("SELECT keywords, answer FROM faqs"); return $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : []; } function chatStoreMessage(string $userMessage, string $aiResponse): void { if (!chatTableExists('messages') || !chatColumnExists('messages', 'user_message') || !chatColumnExists('messages', 'ai_response')) { return; } try { $stmt = db()->prepare("INSERT INTO messages (user_message, ai_response) VALUES (?, ?)"); $stmt->execute([$userMessage, $aiResponse]); } catch (Throwable $e) { error_log('DB Save Error: ' . $e->getMessage()); } } $input = json_decode(file_get_contents('php://input'), true); $message = $input['message'] ?? ''; if (empty($message)) { echo json_encode(['reply' => "I didn't catch that. Could you repeat?"]); exit; } try { $faqs = chatFetchFaqs(); $knowledgeBase = ''; if ($faqs !== []) { $knowledgeBase = "Here is the knowledge base for this website: "; foreach ($faqs as $faq) { $knowledgeBase .= "Q: " . ($faq['keywords'] ?? '') . " A: " . ($faq['answer'] ?? '') . " --- "; } } $systemPrompt = "You are a helpful, friendly AI assistant for this website. " . "Use the provided Knowledge Base to answer user questions accurately. " . "If the answer is found in the Knowledge Base, rephrase it naturally. " . "If the answer is NOT in the Knowledge Base, use your general knowledge to help, " . "but politely mention that you don't have specific information about that if it seems like a site-specific question. " . "Keep answers concise and professional. " . $knowledgeBase; $response = LocalAIApi::createResponse([ 'input' => [ ['role' => 'system', 'content' => $systemPrompt], ['role' => 'user', 'content' => $message], ], ]); if (!empty($response['success'])) { $aiReply = LocalAIApi::extractText($response); chatStoreMessage($message, $aiReply); echo json_encode(['reply' => $aiReply]); } else { error_log('AI Error: ' . ($response['error'] ?? 'Unknown')); echo json_encode(['reply' => "I'm having trouble connecting to my brain right now. Please try again later."]); } } catch (Throwable $e) { error_log('Chat Error: ' . $e->getMessage()); echo json_encode(['reply' => 'An internal error occurred.']); }