import { tool } from 'ai'; import { z } from "zod"; import { ScrapingBeeClient } from 'scrapingbee'; import { setTimeout } from 'node:timers/promises'; const apiKey = process.env.SCRAPING_BEE; const client = new ScrapingBeeClient(apiKey); const headers = { 'accept': 'application/json, text/plain, */*', 'accept-language': 'en-US,en;q=0.9', 'content-type': 'application/json', 'origin': 'https://app.repoanalyzer.io', 'priority': 'u=1, i', 'referer': 'https://app.repoanalyzer.io/', 'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Linux"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site', 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36' }; const submitAnalysisRequest = async (inputUrl) => { const submitData = JSON.stringify({ input: inputUrl, ds: false }); const urlSubmit = 'https://lb.repoanalyzer.io/analysis/queue'; try { const queueResponse = await client.post({ url: urlSubmit, headers: headers, data: submitData }); const queueJson = JSON.parse(queueResponse.data); // //console.log("Queue Response Body:", queueJson); if (queueJson.requestId) { const requestId = queueJson.requestId; // //console.log(`Request ID: ${requestId}`); const resultUrl = `https://lb.repoanalyzer.io/analysis/result/${requestId}`; let pollingAttempts = 0; while (pollingAttempts < 10) { pollingAttempts++; const pollResponse = await client.get({ url: resultUrl, headers: headers }); const pollJson = JSON.parse(pollResponse.data); //console.log("Poll Response Body:", pollJson); //console.log(`Current status: ${pollJson.status}`); if (pollJson.status === 'completed') { if (pollJson.result.repository.analysis && Array.isArray(pollJson.result.repository.analysis.reasons)) { const filteredReasons = pollJson.result.repository.analysis.reasons.filter(reason => !["AI analysis failed", "Using default risk assessment", "Manual review recommended", "Automated analysis unavailable"].includes(reason) ); pollJson.result.repository.analysis.reasons = filteredReasons; } //console.log("Analysis completed. Result:", JSON.stringify(pollJson.result, null, 2)); return JSON.stringify(pollJson.result); } else if (pollJson.status === 'queued' || pollJson.status === 'processing') { //console.log(`Analysis is still ${pollJson.status}. Retrying in 5 seconds...`); await setTimeout(5000); } else { //console.log("Unexpected status:", pollJson.status); break; } } } else { throw new Error("Failed to get github details. Please try again later") } } catch (error) { if (error.response) { //console.log("Error Response Body:", error.response.data); } else { //console.log("Error Message:", error.message); } throw new Error("Failed to get github details. Please try again later") } }; export const getAnalyzeRepoTool = (userId, chatId,responseId, dataStream) => tool({ description: "Submits a GitHub repository URL for analysis and retrieves the results after processing.", parameters: z.object({ inputUrl: z.string().url().describe("The GitHub repository URL to analyze"), }), execute: async ({ inputUrl }) => { try { console.log(`${userId} ${chatId} called analyzeRepoTool with inputUrl: ${inputUrl}`); const analysisResults = await submitAnalysisRequest(inputUrl); if(analysisResults){ dataStream.writeMessageAnnotation({ id: responseId, tool_type: 'github', content: inputUrl, }); } return JSON.stringify({analysisResults}); } catch (error) { console.error(`Error occurred while analyzing the repo: ${error.message}`); return 'Failed to analyze the repository.'; } }, });