diff --git a/backend-server/groq-backend.js b/backend-server/groq-backend.js index a39429f..37a3689 100644 --- a/backend-server/groq-backend.js +++ b/backend-server/groq-backend.js @@ -5,8 +5,9 @@ import cmd from 'cmd-promise'; import cors from 'cors'; import cheerio from 'cheerio'; import llamaTokenizer from 'llama-tokenizer-js'; -import googleIt from 'google-it'; +import fetch from 'node-fetch'; import Groq from 'groq-sdk'; +import googleIt from 'google-it'; // Constants and initialization const app = express(); @@ -137,15 +138,108 @@ async function handleIPPlugin(ipAddr, ip, conversationHistory) { } } +// Function to handle What Servers plugin +async function handleWhatServersPlugin(ip, conversationHistory) { + try { + const response = await fetch(`https://api.my-mc.link/list_all_servers/${process.env.PATH_KEY}/`, { + headers: { + 'x-my-mc-auth': process.env.API_KEY + } + }); + const data = await response.json(); + + if (data.success) { + let responseMessage = 'The Current Minecraft Servers online within the My-MC.link P2P JUMP Node System are listed below:\n'; + + for (const server of data.servers) { + responseMessage += `Name: ${server.serverName}\nGame Version: ${server.gameVersion}\nMOTD: ${server.motd}\nOnline: ${server.online}\n`; + } + + conversationHistory[ip].push({ role: 'assistant', content: responseMessage }); + console.log(`${getTimestamp()} [INFO] Processed server information request.`); + } else { + console.error(`${getTimestamp()} [ERROR] Failed to fetch server information.`); + } + } catch (error) { + console.error(`${getTimestamp()} [ERROR] Failed to fetch server information: `, error); + } +} + +// Function to handle My-MC.Plugin +async function handleMyMcPlugin(ip, conversationHistory) { + try { + const response = await fetch('https://my-mc.link/wiki.json'); + const data = await response.json(); + + if (data) { + let responseMessage = 'My-MC.Link Wiki:\n'; + for (const key in data) { + responseMessage += `${key}: ${data[key]}\n`; + } + + conversationHistory[ip].push({ role: 'assistant', content: responseMessage }); + console.log(`${getTimestamp()} [INFO] Processed My-MC.Link wiki request.`); + } else { + console.error(`${getTimestamp()} [ERROR] Failed to fetch My-MC.Link wiki information.`); + } + } catch (error) { + console.error(`${getTimestamp()} [ERROR] Error fetching My-MC.Link wiki: `, error); + } +} + +// Search plugin function +async function handleSearchPlugin(searchQuery, ip, conversationHistory) { + const options = { + query: searchQuery, + limit: 5, + disableConsole: true + }; + + try { + const results = await googleIt(options); + let searchResponse = `Search Query: ${searchQuery}\nTop Google search results:\n`; + let scrapedContent = ''; + + for (let i = 0; i < results.length; i++) { + const result = results[i]; + searchResponse += `${i + 1}. ${result.title} - ${result.link}\n`; + + try { + const scrapeResult = await scrapeWebPage(result.link, 800); + searchResponse += `Scraped Data: ${scrapeResult}\n`; + scrapedContent += `Scraped Data from ${result.link}:\n${scrapeResult}\n`; + } catch (scrapeErr) { + console.error(`${getTimestamp()} [ERROR] Failed to scrape URL: ${result.link}`, scrapeErr); + searchResponse += `Failed to scrape URL: ${result.link}\n`; + scrapedContent += `Failed to scrape URL: ${result.link}\n`; + } + } + + const lastMessageIndex = conversationHistory[ip].length - 1; + if (lastMessageIndex >= 0) { + conversationHistory[ip][lastMessageIndex].content += "\nYou scraped these results, generate a detailed report, Also provide the list of the scraped URLs in your report. \n" + searchResponse; + console.log(`${getTimestamp()} [INFO] Processed search query: ${searchQuery}.`); + } else { + console.error(`${getTimestamp()} [ERROR] Conversation history is unexpectedly empty for: ${ip}`); + } + + if (scrapedContent) { + conversationHistory[ip].push({ + role: 'assistant', + content: scrapedContent + }); + console.log(`${getTimestamp()} [INFO] Added scraped content to conversation history for: ${ip}`); + } + } catch (err) { + console.error(`${getTimestamp()} [ERROR] Failed to perform Google search: ${searchQuery}`, err); + } +} + // Main chat handler app.post('/api/v1/chat', async (req, res) => { const startTime = Date.now(); const ip = req.clientIp; -// if (isProcessing) { -// return res.status(429).json({ message: "System is busy processing another request, try again later" }); -// } - isProcessing = true; try { @@ -154,33 +248,50 @@ app.post('/api/v1/chat', async (req, res) => { trimConversationHistory(ip); const pluginTasks = []; + const processedIPs = new Set(); // To avoid duplicate IP processing + const processedURLs = new Set(); // To avoid duplicate URL processing // Check for IPs in user message and process them const ipRegex = /(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)/g; const ipAddresses = userMessage.match(ipRegex); if (ipAddresses) { for (const ipAddr of ipAddresses) { - pluginTasks.push(handleIPPlugin(ipAddr, ip, conversationHistory)); + if (!processedIPs.has(ipAddr)) { + pluginTasks.push(handleIPPlugin(ipAddr, ip, conversationHistory)); + processedIPs.add(ipAddr); // Mark IP as processed + } } } // Check for URLs and scrape them - const urls = userMessage.match(/(https?:\/\/[^\s]+)/g); + const urlRegex = /(https?:\/\/[^\s]+)/g; + const urls = userMessage.match(urlRegex); if (urls) { for (const url of urls) { - pluginTasks.push(scrapeWebPage(url).then(content => { - if (content) { - conversationHistory[ip].push({ role: 'assistant', content }); - } - })); + if (!processedURLs.has(url)) { + pluginTasks.push(scrapeWebPage(url).then(content => { + if (content) { + conversationHistory[ip].push({ role: 'assistant', content }); + } + })); + processedURLs.add(url); // Mark URL as processed + } } } + // Search Plugin + const searchRegex = /\b[Ss]earch\s+(.+)\b/; + const searchMatch = userMessage.match(searchRegex); + if (searchMatch) { + const searchQuery = searchMatch[1]; + console.log(`${getTimestamp()} [INFO] Detected search query in user message: ${searchQuery}`); + pluginTasks.push(handleSearchPlugin(searchQuery, ip, conversationHistory)); + } + await Promise.all(pluginTasks); const completion = await groq.chat.completions.create({ messages: conversationHistory[ip], - //model: "llama3-8b-8192" model: "llama-3.2-3b-preview" }); @@ -189,7 +300,7 @@ app.post('/api/v1/chat', async (req, res) => { res.json(assistantMessage); } catch (error) { - console.error(`${getTimestamp()} [ERROR] An error occurred`, error); + console.error(`${getTimestamp()} [ERROR] An error occurred: `, error); res.status(500).json({ message: "An error occurred", error: error.message }); } finally { isProcessing = false; @@ -199,14 +310,14 @@ app.post('/api/v1/chat', async (req, res) => { } }); -// Endpoint to restart core service +// Restart core service app.post('/api/v1/restart-core', (req, res) => { console.log(`${getTimestamp()} [INFO] Restarting core service`); - cmd(`docker restart llama-gpu-server`).then(out => { + cmd('docker restart llama-gpu-server').then(out => { console.log(`${getTimestamp()} [INFO] Core service restarted`); res.json(out.stdout); }).catch(err => { - console.error(`${getTimestamp()} [ERROR] Failed to restart core service`, err); + console.error(`${getTimestamp()} [ERROR] Failed to restart core service: `, err); res.status(500).json({ message: "An error occurred while restarting the core service", error: err.message @@ -214,7 +325,7 @@ app.post('/api/v1/restart-core', (req, res) => { }); }); -// Endpoint to reset conversation history +// Reset conversation history app.post('/api/v1/reset-conversation', (req, res) => { const ip = req.clientIp; console.log(`${getTimestamp()} [INFO] Resetting conversation history for: ${ip}`); @@ -228,7 +339,7 @@ app.post('/api/v1/reset-conversation', (req, res) => { res.json({ message: "Conversation history reset for: " + ip }); }); -// Get conversation history for debugging purposes +// Get conversation history for debugging app.get('/api/v1/conversation-history', (req, res) => { const ip = req.clientIp; console.log(`${getTimestamp()} [INFO] Fetching conversation history for: ${ip}`);