UNPKG

@agentdao/core

Version:

Core functionality, skills, and ready-made UI components for AgentDAO - Web3 subscriptions, content generation, social media, help support, live chat, RSS fetching, web search, and agent pricing integration

332 lines (331 loc) 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LiveChatSkill = void 0; class LiveChatSkill { constructor(config) { this.chats = new Map(); this.onlineUsers = new Map(); if (!config.ai?.apiKey) { throw new Error('No OpenAI API key provided. Please add your key in Settings > API Keys.'); } this.config = config; } async startChat(userId, context) { const chatId = this.generateChatId(); const chat = { id: chatId, userId, context, messages: [], participants: [userId], startTime: new Date(), status: 'active' }; this.chats.set(chatId, chat); // Add user to online users this.onlineUsers.set(userId, { id: userId, username: userId, online: true, lastSeen: new Date() }); console.log(`Started chat ${chatId} for user ${userId}`); return chatId; } async sendMessage(chatId, message, sender) { const chat = this.chats.get(chatId); if (!chat) { throw new Error(`Chat ${chatId} not found`); } // Moderate message if enabled if (this.config.moderation.enabled) { const moderationResult = await this.moderateMessage(message); if (!moderationResult.isAppropriate) { throw new Error(`Message blocked: ${moderationResult.reason}`); } } const chatMessage = { id: this.generateMessageId(), chatId, sender, content: message, messageType: 'text', timestamp: new Date(), read: false }; // Add message to chat chat.messages.push(chatMessage); this.chats.set(chatId, chat); // Update user's last seen const user = this.onlineUsers.get(sender); if (user) { user.lastSeen = new Date(); this.onlineUsers.set(sender, user); } return chatMessage; } async endChat(chatId) { const chat = this.chats.get(chatId); if (!chat) { throw new Error(`Chat ${chatId} not found`); } const endTime = new Date(); const duration = endTime.getTime() - chat.startTime.getTime(); const summary = { chatId, userId: chat.userId, startTime: chat.startTime, endTime, messageCount: chat.messages.length, participants: chat.participants, duration }; // Clean up chat this.chats.delete(chatId); return summary; } async joinChat(chatId, userId) { const chat = this.chats.get(chatId); if (!chat) { return false; } if (!chat.participants.includes(userId)) { chat.participants.push(userId); this.chats.set(chatId, chat); } // Update user status this.onlineUsers.set(userId, { id: userId, username: userId, online: true, lastSeen: new Date() }); return true; } async leaveChat(chatId, userId) { const chat = this.chats.get(chatId); if (!chat) { return false; } chat.participants = chat.participants.filter((id) => id !== userId); this.chats.set(chatId, chat); // Update user status const user = this.onlineUsers.get(userId); if (user) { user.online = false; user.lastSeen = new Date(); this.onlineUsers.set(userId, user); } return true; } async getOnlineUsers(chatId) { const chat = this.chats.get(chatId); if (!chat) { return []; } return chat.participants .map((userId) => this.onlineUsers.get(userId)) .filter((user) => user && user.online); } async uploadFile(chatId, file, userId) { const chat = this.chats.get(chatId); if (!chat) { throw new Error(`Chat ${chatId} not found`); } // This would typically upload to cloud storage const fileUrl = await this.uploadToStorage(file); const fileMessage = { id: this.generateMessageId(), chatId, fileName: file.name, fileUrl, fileSize: file.size, fileType: file.type, uploadedBy: userId, timestamp: new Date() }; // Add file message to chat const chatMessage = { id: fileMessage.id, chatId, sender: userId, content: `Uploaded: ${file.name}`, messageType: 'file', timestamp: fileMessage.timestamp, read: false, metadata: { fileUrl: fileMessage.fileUrl, fileSize: fileMessage.fileSize, fileName: fileMessage.fileName } }; chat.messages.push(chatMessage); this.chats.set(chatId, chat); return fileMessage; } async downloadFile(fileId) { // This would retrieve file from storage console.log(`Downloading file: ${fileId}`); return null; } async moderateMessage(message) { if (!this.config.moderation.enabled) { return { isAppropriate: true, confidence: 1.0, action: 'allow' }; } // Check for profanity if enabled if (this.config.moderation.profanityFilter) { const profanityResult = await this.checkProfanity(message); if (!profanityResult.isAppropriate) { return { isAppropriate: false, confidence: profanityResult.confidence, flaggedWords: profanityResult.flaggedWords, reason: 'Profanity detected', action: this.config.moderation.autoBlock ? 'block' : 'flag' }; } } // Check for spam if enabled if (this.config.moderation.spamDetection) { const spamResult = await this.checkSpam(message); if (!spamResult.isAppropriate) { return { isAppropriate: false, confidence: spamResult.confidence, reason: 'Spam detected', action: this.config.moderation.autoBlock ? 'block' : 'flag' }; } } return { isAppropriate: true, confidence: 0.9, action: 'allow' }; } async blockUser(chatId, userId, reason) { const chat = this.chats.get(chatId); if (!chat) { return false; } // Remove user from chat chat.participants = chat.participants.filter((id) => id !== userId); this.chats.set(chatId, chat); // Update user status const user = this.onlineUsers.get(userId); if (user) { user.online = false; this.onlineUsers.set(userId, user); } console.log(`Blocked user ${userId} from chat ${chatId}: ${reason}`); return true; } async getChatAnalytics(chatId) { const chat = this.chats.get(chatId); if (!chat) { throw new Error(`Chat ${chatId} not found`); } const messages = chat.messages; const totalMessages = messages.length; const participants = chat.participants.length; // Calculate average response time let totalResponseTime = 0; let responseCount = 0; for (let i = 1; i < messages.length; i++) { const currentMessage = messages[i]; const previousMessage = messages[i - 1]; if (currentMessage.sender !== previousMessage.sender) { const responseTime = currentMessage.timestamp.getTime() - previousMessage.timestamp.getTime(); totalResponseTime += responseTime; responseCount++; } } const averageResponseTime = responseCount > 0 ? totalResponseTime / responseCount : 0; const duration = new Date().getTime() - chat.startTime.getTime(); return { chatId, totalMessages, participants, averageResponseTime, duration }; } async getMessageHistory(chatId, limit = 50) { const chat = this.chats.get(chatId); if (!chat) { return []; } return chat.messages.slice(-limit); } // Private helper methods async uploadToStorage(file) { try { // Check if cloud storage is configured if (!this.config.storage || !this.config.storage.endpoint) { throw new Error('No storage endpoint configured for file uploads. Please configure a storage endpoint to use this feature.'); } // Upload to configured cloud storage const formData = new FormData(); formData.append('file', file); formData.append('filename', file.name); formData.append('contentType', file.type); const response = await fetch(this.config.storage.endpoint, { method: 'POST', headers: { ...(this.config.storage.apiKey ? { 'Authorization': `Bearer ${this.config.storage.apiKey}` } : {}) }, body: formData }); if (response.ok) { const data = await response.json(); return data.url; } else { throw new Error(`File upload failed: ${response.statusText}`); } } catch (error) { console.error('File upload failed:', error); throw new Error(`Failed to upload file: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async checkProfanity(message) { // This would use a profanity detection service or API const profanityWords = this.config.moderation.filters; const messageLower = message.toLowerCase(); const flaggedWords = profanityWords.filter(word => messageLower.includes(word.toLowerCase())); return { isAppropriate: flaggedWords.length === 0, confidence: flaggedWords.length > 0 ? 0.8 : 0.9, flaggedWords, action: flaggedWords.length > 0 ? 'flag' : 'allow' }; } async checkSpam(message) { // This would use spam detection logic const spamIndicators = [ /buy now/i, /click here/i, /free money/i, /make money fast/i, /lottery winner/i ]; const isSpam = spamIndicators.some(pattern => pattern.test(message)); return { isAppropriate: !isSpam, confidence: isSpam ? 0.7 : 0.9, action: isSpam ? 'flag' : 'allow' }; } generateChatId() { return `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } generateMessageId() { return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } } exports.LiveChatSkill = LiveChatSkill;