feat: switch chatbot from Gemini to Groq (llama-3.3-70b, 14400 RPD free)

This commit is contained in:
ssbg04 committed 2026-06-05 23:39:24 +08:00
1 parent 6727361c6e
commit 0c0977a220
4 files changed
+64 -78

No files matched your search

+32 -45
View File
@@ -25,10 +25,11 @@ $_SESSION['chat_requests'][] = $now;
// Load DB connection which also loads environment variables
require_once __DIR__ . '/../config/db.php';
$apiKey = $_ENV['GEMINI_API_KEY'] ?? getenv('GEMINI_API_KEY') ?? '';
// Load Groq API key (free tier: 14,400 req/day)
$apiKey = $_ENV['GROQ_API_KEY'] ?? getenv('GROQ_API_KEY') ?? '';
if (empty($apiKey)) {
http_response_code(500);
echo json_encode(['error' => 'API Key configuration is missing. Please configure GEMINI_API_KEY in your .env file.']);
echo json_encode(['error' => 'API Key configuration is missing. Please set GROQ_API_KEY in your .env file.']);
exit;
}
@@ -121,49 +122,32 @@ $systemPrompt .= "3. If asked about contact options or hiring, point them to his
$systemPrompt .= "4. Do not make up facts or external projects not listed in the context. If you don't know the answer, politely invite the user to contact Cris directly.\n";
$systemPrompt .= "5. Format your output using simple markdown (like bolding or bullet points) to make it readable.\n";
// Map chat history
// Map chat history and prepend system instructions to the first user message
$contents = [];
$firstMsgPrepended = false;
// Build Groq messages array (OpenAI-compatible format)
// System prompt goes in its own 'system' role message
$messages = [
['role' => 'system', 'content' => $systemPrompt]
];
// Append chat history
if (isset($inputData['history']) && is_array($inputData['history']) && !empty($inputData['history'])) {
foreach ($inputData['history'] as $index => $msg) {
foreach ($inputData['history'] as $msg) {
if (isset($msg['role']) && isset($msg['text'])) {
$role = ($msg['role'] === 'user') ? 'user' : 'model';
$text = $msg['text'];
// Prepend system prompt to the first user message in history
if (!$firstMsgPrepended && $role === 'user') {
$text = "System Context & Instructions:\n" . $systemPrompt . "\n\nUser Message: " . $text;
$firstMsgPrepended = true;
}
$contents[] = [
'role' => $role,
'parts' => [['text' => $text]]
];
$role = ($msg['role'] === 'user') ? 'user' : 'assistant';
$messages[] = ['role' => $role, 'content' => $msg['text']];
}
}
}
// Add the current user message (prepend system instructions if history was empty)
$currentUserText = $userMessage;
if (!$firstMsgPrepended) {
$currentUserText = "System Context & Instructions:\n" . $systemPrompt . "\n\nUser Message: " . $userMessage;
}
// Add the current user message
$messages[] = ['role' => 'user', 'content' => $userMessage];
$contents[] = [
'role' => 'user',
'parts' => [['text' => $currentUserText]]
];
// Setup request body without systemInstruction key
// Groq request payload (OpenAI-compatible)
$requestPayload = [
'contents' => $contents,
'generationConfig' => [
'temperature' => 0.7,
'maxOutputTokens' => 800
]
'model' => 'llama-3.3-70b-versatile', // 14,400 RPD free
'messages' => $messages,
'temperature' => 0.7,
'max_tokens' => 800,
'stream' => false
];
// Guard: cURL must be available
@@ -173,15 +157,18 @@ if (!function_exists('curl_init')) {
exit;
}
// Call Gemini API via cURL
// gemini-2.0-flash-lite: highest free-tier quota (1,500 req/day)
$url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=" . urlencode($apiKey);
// Call Groq API via cURL (OpenAI-compatible endpoint)
// Model: llama-3.3-70b-versatile — free tier, 14,400 req/day
$url = 'https://api.groq.com/openai/v1/chat/completions';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestPayload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
]);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
@@ -200,18 +187,18 @@ curl_close($ch);
if ($httpCode !== 200) {
http_response_code($httpCode);
$errorDetails = json_decode($response, true);
$errMsg = isset($errorDetails['error']['message']) ? $errorDetails['error']['message'] : 'Failed to retrieve response from Gemini.';
echo json_encode(['error' => $errMsg, 'raw' => $response]);
$errMsg = isset($errorDetails['error']['message']) ? $errorDetails['error']['message'] : 'Failed to retrieve response from Groq.';
echo json_encode(['error' => $errMsg]);
exit;
}
$responseData = json_decode($response, true);
$reply = '';
if (isset($responseData['candidates'][0]['content']['parts'][0]['text'])) {
$reply = $responseData['candidates'][0]['content']['parts'][0]['text'];
if (isset($responseData['choices'][0]['message']['content'])) {
$reply = $responseData['choices'][0]['message']['content'];
} else {
http_response_code(502);
echo json_encode(['error' => 'Invalid response structure from Gemini API.', 'raw' => $responseData]);
echo json_encode(['error' => 'Invalid response structure from Groq API.', 'raw' => $responseData]);
exit;
}