Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 240 lines 8.6 kB view raw
1#!/usr/bin/env node 2 3import { MongoClient } from 'mongodb'; 4 5// ANSI color codes 6const colors = { 7 reset: '\x1b[0m', 8 bright: '\x1b[1m', 9 red: '\x1b[31m', 10 green: '\x1b[32m', 11 yellow: '\x1b[33m', 12 blue: '\x1b[34m', 13 magenta: '\x1b[35m', 14 cyan: '\x1b[36m', 15 gray: '\x1b[90m', 16}; 17 18// MongoDB connection details 19const MONGODB_CONNECTION_STRING = process.env.MONGODB_CONNECTION_STRING; 20const MONGODB_NAME = process.env.MONGODB_NAME || 'aesthetic'; 21const COLLECTION_NAME = 'chat-system'; 22 23// Moderation prompt - explicit URL handling 24const MODERATION_PROMPT = `Rate this chat message as PG-13 appropriate or not. 25 26ALWAYS REPLY 't' FOR URLS AND LINKS (even if they contain words like "live", "lyt", etc.) 27 28Block if message contains: sexual content, body functions, profanity, violence, drugs, hate speech. 29Allow: URLs (https://, http://), links, normal conversation. 30 31Reply with one letter: t (appropriate) or f (inappropriate) 32 33Message: "`; 34 35async function testMessage(message) { 36 const startTime = Date.now(); 37 38 try { 39 const response = await fetch('http://localhost:11434/api/generate', { 40 method: 'POST', 41 headers: { 'Content-Type': 'application/json' }, 42 body: JSON.stringify({ 43 model: 'gemma2:2b', 44 prompt: MODERATION_PROMPT + '"' + message + '"', 45 stream: true, 46 options: { 47 num_ctx: 256, 48 temperature: 0, 49 num_predict: 5, // Just t or f 50 } 51 }) 52 }); 53 54 let fullResponse = ''; 55 const reader = response.body.getReader(); 56 const decoder = new TextDecoder(); 57 58 process.stdout.write(` ${colors.gray}`); 59 60 while (true) { 61 const { done, value } = await reader.read(); 62 if (done) break; 63 64 const chunk = decoder.decode(value); 65 const lines = chunk.split('\n').filter(line => line.trim()); 66 67 for (const line of lines) { 68 try { 69 const json = JSON.parse(line); 70 if (json.response) { 71 fullResponse += json.response; 72 process.stdout.write(json.response); 73 } 74 } catch (e) { 75 // Skip invalid JSON lines 76 } 77 } 78 } 79 80 process.stdout.write(`${colors.reset}\n`); 81 82 const latency = Date.now() - startTime; 83 const response_clean = fullResponse.toLowerCase().trim(); 84 85 // Extract decision - simple t or f 86 let cleanedResponse = response_clean; 87 if (cleanedResponse.includes('</think>')) { 88 cleanedResponse = cleanedResponse.split('</think>')[1]?.trim() || cleanedResponse; 89 } 90 91 let decision = ''; 92 93 // Find t or f 94 if (cleanedResponse.startsWith('t')) { 95 decision = 't'; 96 } else if (cleanedResponse.startsWith('f')) { 97 decision = 'f'; 98 } else if (cleanedResponse.includes(' t')) { 99 decision = 't'; 100 } else if (cleanedResponse.includes(' f')) { 101 decision = 'f'; 102 } 103 104 // Show the full response as "sentiment" for debugging 105 const displayResponse = cleanedResponse.substring(0, 60); 106 console.log(` ${colors.cyan}[${displayResponse}]${colors.reset} ${colors.gray}${decision || 'unknown'}${colors.reset}`); 107 108 // Check decision 109 let outcome = 'error'; 110 if (decision === 't') { 111 outcome = 'pass'; 112 } else if (decision === 'f') { 113 outcome = 'fail'; 114 } 115 116 return { outcome, latency, response: fullResponse, sentiment: cleanedResponse }; 117 } catch (error) { 118 const latency = Date.now() - startTime; 119 console.error(`\n${colors.red}Error testing message: ${error.message}${colors.reset}`); 120 return { outcome: 'error', rationale: error.message, latency }; 121 } 122} 123 124async function main() { 125 const limit = parseInt(process.argv[2]) || 50; 126 const continuous = process.argv.includes('--continuous') || process.argv.includes('-c'); 127 128 console.log(`${colors.cyan}${colors.bright}Connecting to MongoDB...${colors.reset}`); 129 const client = new MongoClient(MONGODB_CONNECTION_STRING); 130 131 try { 132 await client.connect(); 133 console.log(`${colors.green}Connected to MongoDB${colors.reset}`); 134 135 const db = client.db(MONGODB_NAME); 136 const collection = db.collection(COLLECTION_NAME); 137 138 let offset = 0; 139 let totalPassCount = 0; 140 let totalFailCount = 0; 141 let totalErrorCount = 0; 142 let failedMessages = []; 143 144 do { 145 console.log(`\n${colors.magenta}${colors.bright}Fetching ${limit} messages (offset: ${offset}) from ${COLLECTION_NAME}...${colors.reset}\n`); 146 const messages = await collection 147 .find({ text: { $exists: true, $ne: '' } }) 148 .sort({ when: -1 }) 149 .skip(offset) 150 .limit(limit) 151 .toArray(); 152 153 if (messages.length === 0) { 154 console.log(`${colors.yellow}No more messages to test${colors.reset}`); 155 break; 156 } 157 158 console.log(`${colors.blue}Found ${messages.length} messages to test${colors.reset}\n`); 159 console.log(colors.gray + '='.repeat(80) + colors.reset); 160 161 let passCount = 0; 162 let failCount = 0; 163 let errorCount = 0; 164 165 for (const [index, msg] of messages.entries()) { 166 const messageText = msg.text || ''; 167 const timestamp = msg.when ? new Date(msg.when).toISOString() : 'unknown'; 168 const user = msg.user || 'anonymous'; 169 170 console.log(`\n${colors.blue}[${offset + index + 1}] ${colors.gray}${timestamp}${colors.reset}`); 171 console.log(`${colors.cyan}Message: "${messageText}"${colors.reset}`); 172 173 const result = await testMessage(messageText); 174 175 const latencyMs = result.latency || 0; 176 const latencyColor = latencyMs < 1000 ? colors.green : latencyMs < 3000 ? colors.yellow : colors.red; 177 178 if (result.outcome === 'pass') { 179 passCount++; 180 console.log(`${colors.green}${colors.bright}✅ PASS${colors.reset} ${latencyColor}⏱️ ${latencyMs}ms${colors.reset}`); 181 } else if (result.outcome === 'fail') { 182 failCount++; 183 console.log(`${colors.red}${colors.bright}❌ FAIL${colors.reset} ${latencyColor}⏱️ ${latencyMs}ms${colors.reset}`); 184 failedMessages.push({ messageText, rationale: result.sentiment || 'N/A', user, timestamp }); 185 } else { 186 errorCount++; 187 console.log(`${colors.yellow}${colors.bright}⚠️ ERROR${colors.reset} ${latencyColor}⏱️ ${latencyMs}ms${colors.reset}`); 188 } 189 190 console.log(colors.gray + '-'.repeat(80) + colors.reset); 191 } 192 193 totalPassCount += passCount; 194 totalFailCount += failCount; 195 totalErrorCount += errorCount; 196 197 console.log(`\n${colors.magenta}Batch Summary:${colors.reset}`); 198 console.log(`${colors.green}✅ Passed: ${passCount}${colors.reset}`); 199 console.log(`${colors.red}❌ Failed: ${failCount}${colors.reset}`); 200 console.log(`${colors.yellow}⚠️ Errors: ${errorCount}${colors.reset}`); 201 202 offset += limit; 203 204 if (continuous && messages.length === limit) { 205 console.log(`\n${colors.cyan}Continuing to next batch...${colors.reset}`); 206 await new Promise(resolve => setTimeout(resolve, 1000)); 207 } else { 208 break; 209 } 210 211 } while (continuous); 212 213 console.log('\n' + colors.bright + colors.magenta + '='.repeat(80) + colors.reset); 214 console.log(`${colors.bright}${colors.magenta}FINAL SUMMARY:${colors.reset}`); 215 console.log(`Total messages tested: ${offset}`); 216 console.log(`${colors.green}${colors.bright}✅ Passed: ${totalPassCount}${colors.reset}`); 217 console.log(`${colors.red}${colors.bright}❌ Failed: ${totalFailCount}${colors.reset}`); 218 console.log(`${colors.yellow}${colors.bright}⚠️ Errors: ${totalErrorCount}${colors.reset}`); 219 220 if (failedMessages.length > 0) { 221 console.log(`\n${colors.red}${colors.bright}FAILED MESSAGES (${failedMessages.length}):${colors.reset}`); 222 for (const [i, fail] of failedMessages.entries()) { 223 console.log(`\n${colors.red}${i + 1}.${colors.reset} ${colors.gray}${fail.timestamp}${colors.reset}`); 224 console.log(` ${colors.cyan}"${fail.messageText}"${colors.reset}`); 225 console.log(` ${colors.yellow}${fail.rationale}${colors.reset}`); 226 } 227 } 228 229 console.log('\n' + colors.magenta + '='.repeat(80) + colors.reset); 230 231 } catch (error) { 232 console.error(`${colors.red}Error: ${error.message}${colors.reset}`); 233 process.exit(1); 234 } finally { 235 await client.close(); 236 console.log(`\n${colors.green}Disconnected from MongoDB${colors.reset}`); 237 } 238} 239 240main();