UNPKG

saksh-wallet

Version:

A Node.js library for managing user wallets, including functionalities for crediting, debiting, and converting currencies, as well as retrieving balances and transaction reports.

163 lines (138 loc) 6.53 kB
const EventEmitter = require('events'); const mongoose = require('mongoose'); const Transaction = require('./models/Transaction'); const WalletUser = require('./models/WalletUser'); const RecurringPayment = require('./models/RecurringPayment'); const { Configuration, OpenAIApi } = require('openai'); class SakshAIReporting extends EventEmitter { constructor(userModel = WalletUser, transactionModel = Transaction) { super(); this.User = userModel; this.Transaction = transactionModel; } /** * Set the Gemini AI key and initialize OpenAI configuration. * @param {String} gemini_ai_key - The API key for Gemini AI. * @param {String} aimodel - The AI model to use. * @param {Number} max_tokens - The maximum number of tokens for the AI response. */ async sakshGeminiAIKey(gemini_ai_key, aimodel, max_tokens) { const configuration = new Configuration({ gemini_ai_key }); this.aimodel = aimodel; this.max_tokens = max_tokens; this.openai = new OpenAIApi(configuration); this.emit('aiKeySet', { gemini_ai_key, aimodel, max_tokens }); } /** * Generate a summary for the given transactions using OpenAI. * @param {Array} transactions - List of transactions to summarize. * @returns {String} - The generated summary. */ async sakshGenerateReportSummary(transactions) { const transactionDetails = transactions.map(tx => { return `On ${tx.date.toDateString()}, ${tx.type} of ${tx.amount} ${tx.currency} for ${tx.description}.`; }).join(' '); const prompt = `Generate a summary for the following transactions: ${transactionDetails}`; const response = await this.openai.createCompletion({ model: this.aimodel, prompt: prompt, max_tokens: this.max_tokens, }); const summary = response.data.choices[0].text.trim(); this.emit('reportSummaryGenerated', { transactions, summary }); return summary; } /** * Handle user query by generating and executing a MongoDB query. * @param {String} query - The user's query. * @returns {Object} - The query result and summary. */ async sakshHandleUserQuery(query) { const prompt = `You are an AI assistant. The user asked: "${query}". Based on the user's query, generate a MongoDB query to fetch the relevant data from the database.`; const response = await this.openai.createCompletion({ model: this.aimodel, prompt: prompt, max_tokens: this.max_tokens, }); const mongoQuery = response.data.choices[0].text.trim(); // Execute the generated MongoDB query let result; try { result = await eval(mongoQuery); // Be cautious with eval } catch (error) { this.emit('queryExecutionFailed', { query, error }); throw new Error('Failed to execute MongoDB query: ' + error.message); } // Generate a summary of the results const summary = await this.sakshGenerateReportSummary(result); // Emit an event with the results and summary this.emit('userQueryHandled', { query, mongoQuery, result, summary }); // Return the results and summary in JSON format return { query: query, mongoQuery: mongoQuery, result: result, summary: summary }; } /** * Generate a report based on the given prompt and user ID. * @param {String} prompt - The user's prompt. * @param {String} userId - The ID of the user. * @returns {String} - The generated report. */ async sakshGenerateReport(prompt, userId) { let data; try { const aggregationPipeline = []; aggregationPipeline.push({ $match: { userId } }); if (prompt.includes('balance')) { // No additional filtering needed for balance } else if (prompt.includes('transaction')) { // Add filtering for specific transactions (optional) } else if (prompt.includes('monthly transaction') || prompt.includes('daily transaction')) { const dateMatch = prompt.match(/\d+/g); if (!dateMatch) { throw new Error('Invalid prompt format for date-based reports.'); } let startDate, endDate; if (prompt.includes('monthly')) { startDate = new Date(dateMatch[0], dateMatch[1] - 1, 1); endDate = new Date(dateMatch[0], dateMatch[1], 0, 23, 59, 59, 999); } else { // Daily startDate = new Date(dateMatch[0]); startDate.setHours(0, 0, 0, 0); endDate = new Date(dateMatch[0]); endDate.setHours(23, 59, 59, 999); } aggregationPipeline.push({ $match: { date: { $gte: startDate, $lte: endDate } } }); } else if (prompt.includes('budget')) { // Add filtering for specific categories (optional) } else { return 'Invalid prompt. Please specify "balance", "transaction", "monthly transaction", "daily transaction", or "budget".'; } data = await this.User.aggregate(aggregationPipeline); } catch (error) { console.error('Error fetching data:', error); this.emit('dataFetchFailed', { prompt, userId, error }); return 'Failed to generate report.'; } const formattedData = JSON.stringify(data); try { const response = await this.openai.createCompletion({ model: this.aimodel, prompt: `Generate a comprehensive report based on the following data:\n${formattedData}`, }); const report = response.data.choices[0].text; this.emit('reportGenerated', { prompt, userId, report }); return report; } catch (error) { console.error('Error generating report:', error); this.emit('reportGenerationFailed', { prompt, userId, error }); return 'Failed to generate report.'; } } } module.exports = SakshAIReporting;